From 650c61d4c4cd8d7527673b87438f57ed84aab953 Mon Sep 17 00:00:00 2001 From: Uros Tement Date: Tue, 17 Oct 2023 14:22:52 +0200 Subject: [PATCH] Black format --- django_project_base/account/__init__.py | 2 +- .../commands/allauth_to_social_core.py | 25 ++-- django_project_base/account/urls.py | 4 +- django_project_base/base/signals.py | 4 +- django_project_base/licensing/__init__.py | 4 +- ...shed_0004_alter_licenseaccessuse_amount.py | 20 +-- django_project_base/notifications/__init__.py | 2 +- .../commands/resend_notification.py | 9 +- ...rojectbasenotification_options_and_more.py | 16 +-- django_project_base/notifications/settings.py | 7 +- django_project_base/profiling/middleware.py | 116 +++++++++--------- .../profiling/performance_base_command.py | 29 +++-- django_project_base/profiling/views.py | 49 ++++---- django_project_base/urls.py | 20 ++- example/demo_django_base/apps.py | 2 +- .../migrations/0001_initial.py | 37 ++---- .../migrations/0002_alter_project_slug.py | 9 +- ...name_alter_demoprojecttag_slug_and_more.py | 4 +- example/demo_django_base/views.py | 4 +- example/setup/asgi.py | 2 +- example/setup/wsgi.py | 2 +- tests/test_account_register.py | 44 ++++--- tests/test_auth_backends.py | 10 +- tests/test_base.py | 3 +- tests/test_models.py | 16 +-- tests/test_retrieve_holidays.py | 6 +- tests/test_role.py | 16 +-- 27 files changed, 211 insertions(+), 251 deletions(-) diff --git a/django_project_base/account/__init__.py b/django_project_base/account/__init__.py index 1f11ece9..b6763009 100644 --- a/django_project_base/account/__init__.py +++ b/django_project_base/account/__init__.py @@ -1,4 +1,4 @@ from .constants import ACCOUNT_APP_ID from .middleware import SessionMiddleware -default_app_config = '%s.apps.DjangoProjectBaseAccountsConfig' % ACCOUNT_APP_ID +default_app_config = "%s.apps.DjangoProjectBaseAccountsConfig" % ACCOUNT_APP_ID diff --git a/django_project_base/account/management/commands/allauth_to_social_core.py b/django_project_base/account/management/commands/allauth_to_social_core.py index 3bd68218..4098e10f 100644 --- a/django_project_base/account/management/commands/allauth_to_social_core.py +++ b/django_project_base/account/management/commands/allauth_to_social_core.py @@ -10,34 +10,33 @@ class Command(BaseCommand): - help = 'Migrate social login data from allauth to social_core' + help = "Migrate social login data from allauth to social_core" provider_mapping: dict = { - 'google': social_core.backends.google.GoogleOAuth2.name, - 'facebook': social_core.backends.facebook.FacebookOAuth2.name, - 'azure': social_core.backends.microsoft.MicrosoftOAuth2.name, + "google": social_core.backends.google.GoogleOAuth2.name, + "facebook": social_core.backends.facebook.FacebookOAuth2.name, + "azure": social_core.backends.microsoft.MicrosoftOAuth2.name, } def handle(self, *args, **options): - with connection.cursor() as cursor: - cursor.execute('select user_id, provider, extra_data from socialaccount_socialaccount;') + cursor.execute("select user_id, provider, extra_data from socialaccount_socialaccount;") rows: list = cursor.fetchall() for row in rows: user_id: int = row[0] provider: str = row[1] extra_data: dict = json.loads(row[2]) if row[2] else {} - user_email: Optional[str] = extra_data.get('email') or extra_data.get('mail') + user_email: Optional[str] = extra_data.get("email") or extra_data.get("mail") if user_email: new_provider: str = self.provider_mapping.get(provider) - assert new_provider, 'New social auth provider for %s is not defined' % provider + assert new_provider, "New social auth provider for %s is not defined" % provider payload = { - 'user_id': user_id, - 'provider': new_provider, + "user_id": user_id, + "provider": new_provider, } social_auth_records_exists: bool = UserSocialAuth.objects.filter(**payload).exists() if not social_auth_records_exists: - payload['uid'] = user_email - payload['extra_data'] = None + payload["uid"] = user_email + payload["extra_data"] = None UserSocialAuth.objects.create(**payload) - return 'ok' + return "ok" diff --git a/django_project_base/account/urls.py b/django_project_base/account/urls.py index 787b8054..a78a100d 100644 --- a/django_project_base/account/urls.py +++ b/django_project_base/account/urls.py @@ -3,6 +3,6 @@ from django_project_base.account.router import accounts_router, profile_router urlpatterns = [ - path('', include(accounts_router.urls)), - path('', include(profile_router.urls)), + path("", include(accounts_router.urls)), + path("", include(profile_router.urls)), ] diff --git a/django_project_base/base/signals.py b/django_project_base/base/signals.py index 617aa9f6..9d290148 100644 --- a/django_project_base/base/signals.py +++ b/django_project_base/base/signals.py @@ -5,11 +5,11 @@ def hijack_set_is_hijacked(sender, **kwargs): - cache.set(CACHE_IMPERSONATE_USER % kwargs.get('hijacked').id, True) + cache.set(CACHE_IMPERSONATE_USER % kwargs.get("hijacked").id, True) def hijack_delete_is_hijacked(sender, **kwargs): - cache.delete(CACHE_IMPERSONATE_USER % kwargs.get('hijacked').id) + cache.delete(CACHE_IMPERSONATE_USER % kwargs.get("hijacked").id) hijack_started.connect(hijack_set_is_hijacked) diff --git a/django_project_base/licensing/__init__.py b/django_project_base/licensing/__init__.py index 4375f709..702b7dcd 100644 --- a/django_project_base/licensing/__init__.py +++ b/django_project_base/licensing/__init__.py @@ -1,3 +1 @@ -default_app_config = ( - "%s.apps.DjangoProjectBaseLicensingConfig" % "django_project_base.licensing" -) +default_app_config = "%s.apps.DjangoProjectBaseLicensingConfig" % "django_project_base.licensing" diff --git a/django_project_base/licensing/migrations/0002_remove_licenseaccessuse_comment_and_more_squashed_0004_alter_licenseaccessuse_amount.py b/django_project_base/licensing/migrations/0002_remove_licenseaccessuse_comment_and_more_squashed_0004_alter_licenseaccessuse_amount.py index fc1348bd..b0a77a9a 100644 --- a/django_project_base/licensing/migrations/0002_remove_licenseaccessuse_comment_and_more_squashed_0004_alter_licenseaccessuse_amount.py +++ b/django_project_base/licensing/migrations/0002_remove_licenseaccessuse_comment_and_more_squashed_0004_alter_licenseaccessuse_amount.py @@ -22,15 +22,11 @@ class Migration(migrations.Migration): field=models.IntegerField( choices=[ ( - django_project_base.licensing.models.LicenseAccessUse.UseType[ - "USE" - ], + django_project_base.licensing.models.LicenseAccessUse.UseType["USE"], "Used access", ) ], - default=django_project_base.licensing.models.LicenseAccessUse.UseType[ - "USE" - ], + default=django_project_base.licensing.models.LicenseAccessUse.UseType["USE"], verbose_name="Type", ), ), @@ -45,21 +41,15 @@ class Migration(migrations.Migration): field=models.IntegerField( choices=[ ( - django_project_base.licensing.models.LicenseAccessUse.UseType[ - "USE" - ], + django_project_base.licensing.models.LicenseAccessUse.UseType["USE"], "Used access", ), ( - django_project_base.licensing.models.LicenseAccessUse.UseType[ - "ADMIN_USE" - ], + django_project_base.licensing.models.LicenseAccessUse.UseType["ADMIN_USE"], "Used access by admin", ), ], - default=django_project_base.licensing.models.LicenseAccessUse.UseType[ - "USE" - ], + default=django_project_base.licensing.models.LicenseAccessUse.UseType["USE"], verbose_name="Type", ), ), diff --git a/django_project_base/notifications/__init__.py b/django_project_base/notifications/__init__.py index 1ff5bfd1..bd24d3ab 100644 --- a/django_project_base/notifications/__init__.py +++ b/django_project_base/notifications/__init__.py @@ -1,3 +1,3 @@ from django_project_base.notifications.constants import NOTIFICATIONS_APP_ID -default_app_config = '%s.apps.DjangoProjectBaseNotifyConfig' % NOTIFICATIONS_APP_ID +default_app_config = "%s.apps.DjangoProjectBaseNotifyConfig" % NOTIFICATIONS_APP_ID diff --git a/django_project_base/notifications/management/commands/resend_notification.py b/django_project_base/notifications/management/commands/resend_notification.py index 64a2fdd9..c8d2bf1d 100644 --- a/django_project_base/notifications/management/commands/resend_notification.py +++ b/django_project_base/notifications/management/commands/resend_notification.py @@ -9,10 +9,11 @@ class Command(BaseCommand): help = 'Resends notification. Example: python manage.py resend_notification "178a46c2-2aa3-4a33-bad6-9af2d76f6891" 2' # noqa: E501 def add_arguments(self, parser) -> None: - parser.add_argument('notification', type=str, help='Notification identifier (uuid string).') - parser.add_argument('user', type=str, help='User identifier (user sending notification).') + parser.add_argument("notification", type=str, help="Notification identifier (uuid string).") + parser.add_argument("user", type=str, help="User identifier (user sending notification).") def handle(self, *args, **options): - Notification.resend(get_object_or_404(DjangoProjectBaseNotification, pk=str(options['notification'])), - str(options["user"])) + Notification.resend( + get_object_or_404(DjangoProjectBaseNotification, pk=str(options["notification"])), str(options["user"]) + ) return "ok" diff --git a/django_project_base/notifications/migrations/0004_alter_djangoprojectbasenotification_options_and_more.py b/django_project_base/notifications/migrations/0004_alter_djangoprojectbasenotification_options_and_more.py index fb52ed72..2af60949 100644 --- a/django_project_base/notifications/migrations/0004_alter_djangoprojectbasenotification_options_and_more.py +++ b/django_project_base/notifications/migrations/0004_alter_djangoprojectbasenotification_options_and_more.py @@ -38,28 +38,20 @@ class Migration(migrations.Migration): models.IntegerField( choices=[ ( - django_project_base.notifications.models.DeliveryReport.Status[ - "DELIVERED" - ], + django_project_base.notifications.models.DeliveryReport.Status["DELIVERED"], "Delivered", ), ( - django_project_base.notifications.models.DeliveryReport.Status[ - "NOT_DELIVERED" - ], + django_project_base.notifications.models.DeliveryReport.Status["NOT_DELIVERED"], "Not Delivered", ), ( - django_project_base.notifications.models.DeliveryReport.Status[ - "PENDING_DELIVERY" - ], + django_project_base.notifications.models.DeliveryReport.Status["PENDING_DELIVERY"], "Pending delivery", ), ], db_index=True, - default=django_project_base.notifications.models.DeliveryReport.Status[ - "PENDING_DELIVERY" - ], + default=django_project_base.notifications.models.DeliveryReport.Status["PENDING_DELIVERY"], ), ), ( diff --git a/django_project_base/notifications/settings.py b/django_project_base/notifications/settings.py index 65e8155d..7d933d10 100644 --- a/django_project_base/notifications/settings.py +++ b/django_project_base/notifications/settings.py @@ -13,9 +13,8 @@ "name": "TIME_BUFFER_FOR_CURRENT_MAINTENANCE_API_QUERY", "default": 900, "description": "When list maintenance notifications api is called with current=true in query param, " - "maintenance notification within range of now - TIME_BUFFER_FOR_CURRENT_MAINTENANCE_API_QUERY, " - "now + TIME_BUFFER_FOR_CURRENT_MAINTENANCE_API_QUERY is returned. Maintenance notification " - "cannot be created if it overlaps with annother maintenance notification in buffer.", + "maintenance notification within range of now - TIME_BUFFER_FOR_CURRENT_MAINTENANCE_API_QUERY, " + "now + TIME_BUFFER_FOR_CURRENT_MAINTENANCE_API_QUERY is returned. Maintenance notification " + "cannot be created if it overlaps with annother maintenance notification in buffer.", }, - ) diff --git a/django_project_base/profiling/middleware.py b/django_project_base/profiling/middleware.py index 8176bc72..8b656b11 100644 --- a/django_project_base/profiling/middleware.py +++ b/django_project_base/profiling/middleware.py @@ -15,14 +15,14 @@ DEFAULT_MAX_LOG_FILE_SIZE = 10000000 MAX_DATA_LOGGING_FILE_SIZE = 3000000 -MATCH_DETAIL_QUERIES = re.compile(r'(rest/\w+)/((?:[0-9a-f]{8}(?:-[0-9a-f]{4}){3}-[0-9a-f]{12})|' - r'(?:(?:[0-9a-f]{2}:){5}[0-9a-f]{2})|\d+)(/.*)?') +MATCH_DETAIL_QUERIES = re.compile( + r"(rest/\w+)/((?:[0-9a-f]{8}(?:-[0-9a-f]{4}){3}-[0-9a-f]{12})|" r"(?:(?:[0-9a-f]{2}:){5}[0-9a-f]{2})|\d+)(/.*)?" +) class CacheLock(object): - def __init__(self, name): - self.name = 'CacheLock.' + name + self.name = "CacheLock." + name def __enter__(self): while True: @@ -34,7 +34,7 @@ def __enter__(self): res = 0 if res == 1: break - time.sleep(.1) + time.sleep(0.1) def __exit__(self, exc_type, exc_val, exc_tb): cache.delete(self.name) @@ -50,12 +50,13 @@ class ProfileRequest(object): _settings: dict _profile_path: str - def __init__(self, settings: dict, process_function: callable, - process_function_args: tuple, process_function_kwargs: dict): - assert 'REQUEST_METHOD' in settings - assert 'PATH_INFO' in settings - settings.setdefault('QUERY_STRING', '') - settings.setdefault('HTTP_HOST', socket.gethostname()) + def __init__( + self, settings: dict, process_function: callable, process_function_args: tuple, process_function_kwargs: dict + ): + assert "REQUEST_METHOD" in settings + assert "PATH_INFO" in settings + settings.setdefault("QUERY_STRING", "") + settings.setdefault("HTTP_HOST", socket.gethostname()) self._settings = settings self._process_function = process_function self._process_function_args = process_function_args @@ -86,32 +87,34 @@ def _get_profiling_path(self) -> tuple: def _get_path_info(self, path: str, params: Optional[str] = None): original_path = path - path = path.strip('/') - if 'robots.txt' in path: - return 'other' - if any(x in path for x in ('.php', '.map')): - return 'other' + path = path.strip("/") + if "robots.txt" in path: + return "other" + if any(x in path for x in (".php", ".map")): + return "other" if MATCH_DETAIL_QUERIES.match(path): - return MATCH_DETAIL_QUERIES.sub('\\1\\3', path) + return MATCH_DETAIL_QUERIES.sub("\\1\\3", path) - if path.startswith('configure_site') and '&type=' in (params or ''): - pos = params.find('&type=') - return path + '/' + params[pos + 6:pos + 9] + if path.startswith("configure_site") and "&type=" in (params or ""): + pos = params.find("&type=") + return path + "/" + params[pos + 6 : pos + 9] - if getattr(settings, 'PROFILER_PATH_TRANSFORM', None): - split_module_path: list = settings.PROFILER_PATH_TRANSFORM.split('.') - module: str = '.'.join(split_module_path[:(len(split_module_path) - 1)]) + if getattr(settings, "PROFILER_PATH_TRANSFORM", None): + split_module_path: list = settings.PROFILER_PATH_TRANSFORM.split(".") + module: str = ".".join(split_module_path[: (len(split_module_path) - 1)]) method: str = split_module_path[-1] path = getattr(importlib.import_module(module), method)( - path, {'original_path': original_path, 'params': params}) + path, {"original_path": original_path, "params": params} + ) return path def _get_queries(self, response): try: - if (response == 'ok' or response.status_code == 200) and hasattr( - settings, 'PROFILER_LONG_RUNNING_TASK_THRESHOLD'): + if (response == "ok" or response.status_code == 200) and hasattr( + settings, "PROFILER_LONG_RUNNING_TASK_THRESHOLD" + ): query_list = [] for c in connections: con = connections[c] @@ -120,51 +123,56 @@ def _get_queries(self, response): _queries = filter(lambda x: x, query_list) return [q for sublist in _queries for q in sublist] except Exception as e: - return ['exception getting queries: ' + str(e)] + return ["exception getting queries: " + str(e)] def _do_profile(self, response, start_time, end_time): try: locs = locals() - if 'PATH_INFO' in self._settings: + if "PATH_INFO" in self._settings: _profiling_path: tuple = next(iter(self._get_profiling_path()), None) - path_info = _profiling_path or self._get_path_info(str(self._settings['PATH_INFO']), - str(self._settings['QUERY_STRING'])) + path_info = _profiling_path or self._get_path_info( + str(self._settings["PATH_INFO"]), str(self._settings["QUERY_STRING"]) + ) if path_info: duration = (end_time[0] - start_time[0], end_time[1] - start_time[1], end_time[2] - start_time[2]) - if hasattr(settings, 'PROFILER_LONG_RUNNING_TASK_THRESHOLD'): + if hasattr(settings, "PROFILER_LONG_RUNNING_TASK_THRESHOLD"): if duration[0] > settings.PROFILER_LONG_RUNNING_TASK_THRESHOLD: queries = self._get_queries(response) - r_data = {'timestamp': end_time[0] / 1000, 'duration': duration[0], 'queries': queries, - 'PATH_INFO': path_info} - r_data.update({i: str(self._settings[i]) - for i in ('HTTP_HOST', 'REQUEST_METHOD', 'QUERY_STRING')}) - with CacheLock('long_running_cmds'): - cache_ptr = (cache.get('long_running_cmds_pointer', -1) + 1) % 50 - cache.set('long_running_cmds_pointer', cache_ptr, timeout=86400) - cache.set('long_running_cmds_data%d' % cache_ptr, r_data, timeout=86400) - with CacheLock('last_hour_running_cmds'): - r_data = (path_info, duration[0], - duration[1], duration[2]) + r_data = { + "timestamp": end_time[0] / 1000, + "duration": duration[0], + "queries": queries, + "PATH_INFO": path_info, + } + r_data.update( + {i: str(self._settings[i]) for i in ("HTTP_HOST", "REQUEST_METHOD", "QUERY_STRING")} + ) + with CacheLock("long_running_cmds"): + cache_ptr = (cache.get("long_running_cmds_pointer", -1) + 1) % 50 + cache.set("long_running_cmds_pointer", cache_ptr, timeout=86400) + cache.set("long_running_cmds_data%d" % cache_ptr, r_data, timeout=86400) + with CacheLock("last_hour_running_cmds"): + r_data = (path_info, duration[0], duration[1], duration[2]) # get cache entries in the last 10 seconds - cache_ptr = cache.get('last_hour_running_cmds%d' % (int(time.time()) // 10), []) + cache_ptr = cache.get("last_hour_running_cmds%d" % (int(time.time()) // 10), []) cache_ptr.append(r_data) - cache.set('last_hour_running_cmds%d' % (int(time.time()) // 10), cache_ptr, timeout=3600) + cache.set("last_hour_running_cmds%d" % (int(time.time()) // 10), cache_ptr, timeout=3600) req_data = dict( - code=getattr(response, 'status_code', None), - method=self._settings['REQUEST_METHOD'], + code=getattr(response, "status_code", None), + method=self._settings["REQUEST_METHOD"], duration=duration[0], timestamp=end_time[0] / 1000, path_info=path_info, pid=os.getpid(), - raw_path_info=self._settings.get('PATH_INFO', None), + raw_path_info=self._settings.get("PATH_INFO", None), ) - files = glob.glob('/tmp/wsgi_performance.txt.*') + files = glob.glob("/tmp/wsgi_performance.txt.*") if not files: with open("/tmp/wsgi_performance.txt.1", "a") as f: f.write(json.dumps(req_data) + "\n") files = ["/tmp/wsgi_performance.txt.1"] - file_num_array = list(map(lambda r: int(r.split('.')[-1]), files)) + file_num_array = list(map(lambda r: int(r.split(".")[-1]), files)) max_file = max(file_num_array) min_file = min(file_num_array) if max_file > 3: @@ -173,18 +181,16 @@ def _do_profile(self, response, start_time, end_time): if os.path.exists("/tmp/wsgi_performance.txt.2"): os.remove("/tmp/wsgi_performance.txt.2") os.rename("/tmp/wsgi_performance.txt.%d" % max_file, "/tmp/wsgi_performance.txt.1") - os.rename("/tmp/wsgi_performance.txt.%d" % (max_file - 1), - "/tmp/wsgi_performance.txt.2") - for ff in filter(lambda f: f and int(f.split('.')[-1]) not in [1, 2], files): + os.rename("/tmp/wsgi_performance.txt.%d" % (max_file - 1), "/tmp/wsgi_performance.txt.2") + for ff in filter(lambda f: f and int(f.split(".")[-1]) not in [1, 2], files): if os.path.exists(ff): os.remove(ff) - files = glob.glob('/tmp/wsgi_performance.txt.*') + files = glob.glob("/tmp/wsgi_performance.txt.*") if not files: with open("/tmp/wsgi_performance.txt.1", "a") as f: f.write(json.dumps(req_data) + "\n") else: - if os.path.getsize( - "/tmp/wsgi_performance.txt.%d" % max_file) > MAX_DATA_LOGGING_FILE_SIZE: + if os.path.getsize("/tmp/wsgi_performance.txt.%d" % max_file) > MAX_DATA_LOGGING_FILE_SIZE: with open("/tmp/wsgi_performance.txt.%d" % (max_file + 1), "a") as f: f.write(json.dumps(req_data) + "\n") else: diff --git a/django_project_base/profiling/performance_base_command.py b/django_project_base/profiling/performance_base_command.py index 15977ecb..9b9d6713 100644 --- a/django_project_base/profiling/performance_base_command.py +++ b/django_project_base/profiling/performance_base_command.py @@ -6,20 +6,25 @@ class PerformanceCommand(BaseCommand): - def execute(self, *args, **options): - param_names: list = list(filter(lambda o: o and o not in ( - 'pythonpath', 'no_color', 'force_color', 'verbosity', 'skip_checks', 'traceback', 'settings'), options)) - command_class_data: List[str] = str(self.__class__).split('.') + param_names: list = list( + filter( + lambda o: o + and o + not in ("pythonpath", "no_color", "force_color", "verbosity", "skip_checks", "traceback", "settings"), + options, + ) + ) + command_class_data: List[str] = str(self.__class__).split(".") command_name: str = command_class_data[len(command_class_data) - 2] - name: str = '%s_%s ' % ('manage_command', command_name) + name: str = "%s_%s " % ("manage_command", command_name) for param in param_names: - name += '%s=%s ' % (param, options.get(param)) + name += "%s=%s " % (param, options.get(param)) - with ProfileRequest({ - 'REQUEST_METHOD': 'GET', - 'HTTP_HOST': '', - 'QUERY_STRING': '', - 'PATH_INFO': name - }, super().execute, args, options) as pr: + with ProfileRequest( + {"REQUEST_METHOD": "GET", "HTTP_HOST": "", "QUERY_STRING": "", "PATH_INFO": name}, + super().execute, + args, + options, + ) as pr: return pr.response diff --git a/django_project_base/profiling/views.py b/django_project_base/profiling/views.py index 2bad5bf1..71d17578 100644 --- a/django_project_base/profiling/views.py +++ b/django_project_base/profiling/views.py @@ -10,9 +10,9 @@ def app_debug_view(request): # if not getattr(request, 'user', None) or request.user.pk not in POWER_USERS: - if not getattr(request, 'user', None): + if not getattr(request, "user", None): raise PermissionError - return render(request, 'app-debug/main.html', __get_debug_data()) + return render(request, "app-debug/main.html", __get_debug_data()) def __get_debug_data(): @@ -22,7 +22,7 @@ def __get_debug_data(): requests = [] for cache_ptr in range(PROFILER_LOG_LONG_REQUESTS_COUNT): - item = cache.get('long_running_cmds_data%d' % cache_ptr) + item = cache.get("long_running_cmds_data%d" % cache_ptr) if item: requests.append(item) @@ -30,44 +30,46 @@ def __get_debug_data(): min_timestamp = time.time() for req in requests: - queries_executed: list = req.get('queries', []) or [] + queries_executed: list = req.get("queries", []) or [] num_of_queries: int = len(queries_executed) num_of_distinct_queries: int = len( - set(map(lambda d: d['sql'], filter(lambda e: isinstance(e, dict), queries_executed)))) + set(map(lambda d: d["sql"], filter(lambda e: isinstance(e, dict), queries_executed))) + ) r = lambda: random.randint(0, 255) # noqa: E731 item = dict( r_data=dict( num_of_duplicate_queries=num_of_queries - num_of_distinct_queries, num_of_queries=num_of_queries, - duration=req.get('duration'), - path_info=req.get('PATH_INFO'), - host=req.get('HTTP_HOST'), - method=req.get('REQUEST_METHOD'), - timestamp=datetime.utcfromtimestamp( - req['timestamp']).strftime('%Y-%m-%d %H:%M:%S') if req.get('timestamp') else None, - query_string=req.get('QUERY_STRING'), + duration=req.get("duration"), + path_info=req.get("PATH_INFO"), + host=req.get("HTTP_HOST"), + method=req.get("REQUEST_METHOD"), + timestamp=datetime.utcfromtimestamp(req["timestamp"]).strftime("%Y-%m-%d %H:%M:%S") + if req.get("timestamp") + else None, + query_string=req.get("QUERY_STRING"), ), db_queries=queries_executed, - color='rgba(%d, %d, %d, 0.3)' % (r(), r(), r()), + color="rgba(%d, %d, %d, 0.3)" % (r(), r(), r()), ) - item_data = item['r_data'] - totals.setdefault(item_data['path_info'], Struct(count=0, time=0, path='')) - total = totals[item_data['path_info']] + item_data = item["r_data"] + totals.setdefault(item_data["path_info"], Struct(count=0, time=0, path="")) + total = totals[item_data["path_info"]] total.count += 1 - total.time += item_data['duration'] - total.path = item_data['path_info'] - min_timestamp = min(req['timestamp'], min_timestamp) + total.time += item_data["duration"] + total.path = item_data["path_info"] + min_timestamp = min(req["timestamp"], min_timestamp) result_data.append(item) - result_data.sort(key=lambda f: f.get('r_data', {}).get('duration', 0) or 0, reverse=True) + result_data.sort(key=lambda f: f.get("r_data", {}).get("duration", 0) or 0, reverse=True) spenders = list(sorted(totals.values(), key=lambda x: x.time, reverse=True)) totals = {} for interval in range(int((time.time()) - 3600) // 10, int(time.time()) // 10 + 1): - cache_ptr = cache.get('last_hour_running_cmds%d' % interval, []) + cache_ptr = cache.get("last_hour_running_cmds%d" % interval, []) for item in cache_ptr: - totals.setdefault(item[0], Struct(count=0, wall_time=0, path='', user_time=0, sys_time=0, cpu_time=0)) + totals.setdefault(item[0], Struct(count=0, wall_time=0, path="", user_time=0, sys_time=0, cpu_time=0)) total = totals[item[0]] total.count += 1 total.wall_time += item[1] @@ -83,7 +85,8 @@ def __get_debug_data(): all_requests = list(sorted(totals.values(), key=lambda x: x.wall_time, reverse=True)) return dict( - debug_data=result_data, spenders=spenders, + debug_data=result_data, + spenders=spenders, long_running_time=int(time.time() - min_timestamp), all_requests=all_requests, ) diff --git a/django_project_base/urls.py b/django_project_base/urls.py index 64349f2f..ddc9a48c 100644 --- a/django_project_base/urls.py +++ b/django_project_base/urls.py @@ -5,19 +5,15 @@ from django_project_base.router import django_project_base_router from django_project_base.views import browser_update_script -SPECTACULAR_DEFAULTS['TITLE'] = 'Rest documentation' -SPECTACULAR_DEFAULTS['DESCRIPTION'] = 'Api documentation' -SPECTACULAR_DEFAULTS['VERSION'] = '0.0.1' -SPECTACULAR_DEFAULTS['PREPROCESSING_HOOKS'] = [ - 'django_project_base.router.filter_rest_documentation_endpoints' -] +SPECTACULAR_DEFAULTS["TITLE"] = "Rest documentation" +SPECTACULAR_DEFAULTS["DESCRIPTION"] = "Api documentation" +SPECTACULAR_DEFAULTS["VERSION"] = "0.0.1" +SPECTACULAR_DEFAULTS["PREPROCESSING_HOOKS"] = ["django_project_base.router.filter_rest_documentation_endpoints"] -SPECTACULAR_DEFAULTS['POSTPROCESSING_HOOKS'] = [ - 'django_project_base.router.postprocess_rest_documentation' -] +SPECTACULAR_DEFAULTS["POSTPROCESSING_HOOKS"] = ["django_project_base.router.postprocess_rest_documentation"] urlpatterns = [ - path('jsi18n/', JavaScriptCatalog.as_view(), name='javascript-catalog'), - re_path('browser-update/js-script', browser_update_script, name='browser-update-script'), - re_path(r'', include(django_project_base_router.urls)), + path("jsi18n/", JavaScriptCatalog.as_view(), name="javascript-catalog"), + re_path("browser-update/js-script", browser_update_script, name="browser-update-script"), + re_path(r"", include(django_project_base_router.urls)), ] diff --git a/example/demo_django_base/apps.py b/example/demo_django_base/apps.py index 6cb4f98d..c4ce69e3 100644 --- a/example/demo_django_base/apps.py +++ b/example/demo_django_base/apps.py @@ -2,4 +2,4 @@ class DemoDjangoBaseConfig(AppConfig): - name = 'example.demo_django_base' + name = "example.demo_django_base" diff --git a/example/demo_django_base/migrations/0001_initial.py b/example/demo_django_base/migrations/0001_initial.py index 7e43ecf0..9ef90b0b 100644 --- a/example/demo_django_base/migrations/0001_initial.py +++ b/example/demo_django_base/migrations/0001_initial.py @@ -40,7 +40,6 @@ def reverse_func(apps, schema_editor): pass - class Migration(migrations.Migration): initial = True @@ -77,15 +76,11 @@ class Migration(migrations.Migration): ), ( "color", - django_project_base.base.fields.HexColorField( - max_length=7, verbose_name="Color" - ), + django_project_base.base.fields.HexColorField(max_length=7, verbose_name="Color"), ), ( "icon", - models.CharField( - blank=True, max_length=10, null=True, verbose_name="Icon" - ), + models.CharField(blank=True, max_length=10, null=True, verbose_name="Icon"), ), ("content", models.CharField(blank=True, max_length=20, null=True)), ], @@ -140,9 +135,7 @@ class Migration(migrations.Migration): ), ( "logo", - models.FileField( - blank=True, null=True, upload_to="", verbose_name="Logo" - ), + models.FileField(blank=True, null=True, upload_to="", verbose_name="Logo"), ), ], options={ @@ -188,9 +181,7 @@ class Migration(migrations.Migration): ), ( "bio", - models.TextField( - blank=True, max_length=500, null=True, verbose_name="Bio" - ), + models.TextField(blank=True, max_length=500, null=True, verbose_name="Bio"), ), ( "phone_number", @@ -203,33 +194,23 @@ class Migration(migrations.Migration): ), ( "language", - models.CharField( - blank=True, max_length=10, null=True, verbose_name="Language" - ), + models.CharField(blank=True, max_length=10, null=True, verbose_name="Language"), ), ( "theme", - models.CharField( - blank=True, max_length=10, null=True, verbose_name="Theme" - ), + models.CharField(blank=True, max_length=10, null=True, verbose_name="Theme"), ), ( "avatar", - models.FileField( - blank=True, null=True, upload_to="", verbose_name="Avatar" - ), + models.FileField(blank=True, null=True, upload_to="", verbose_name="Avatar"), ), ( "reverse_full_name_order", - models.BooleanField( - blank=True, null=True, verbose_name="Reverse full name order" - ), + models.BooleanField(blank=True, null=True, verbose_name="Reverse full name order"), ), ( "delete_at", - models.DateTimeField( - blank=True, null=True, verbose_name="Delete profile at" - ), + models.DateTimeField(blank=True, null=True, verbose_name="Delete profile at"), ), ("password_invalid", models.BooleanField(default=False)), ], diff --git a/example/demo_django_base/migrations/0002_alter_project_slug.py b/example/demo_django_base/migrations/0002_alter_project_slug.py index 5d7ef27f..f6d8f554 100644 --- a/example/demo_django_base/migrations/0002_alter_project_slug.py +++ b/example/demo_django_base/migrations/0002_alter_project_slug.py @@ -4,15 +4,14 @@ class Migration(migrations.Migration): - dependencies = [ - ('demo_django_base', '0001_initial'), + ("demo_django_base", "0001_initial"), ] operations = [ migrations.AlterField( - model_name='project', - name='slug', - field=models.SlugField(max_length=80, unique=True, verbose_name='Slug'), + model_name="project", + name="slug", + field=models.SlugField(max_length=80, unique=True, verbose_name="Slug"), ), ] diff --git a/example/demo_django_base/migrations/0004_alter_demoprojecttag_name_alter_demoprojecttag_slug_and_more.py b/example/demo_django_base/migrations/0004_alter_demoprojecttag_name_alter_demoprojecttag_slug_and_more.py index 11b7251c..c05f37bf 100644 --- a/example/demo_django_base/migrations/0004_alter_demoprojecttag_name_alter_demoprojecttag_slug_and_more.py +++ b/example/demo_django_base/migrations/0004_alter_demoprojecttag_name_alter_demoprojecttag_slug_and_more.py @@ -17,9 +17,7 @@ class Migration(migrations.Migration): migrations.AlterField( model_name="demoprojecttag", name="slug", - field=models.SlugField( - allow_unicode=True, max_length=100, verbose_name="slug" - ), + field=models.SlugField(allow_unicode=True, max_length=100, verbose_name="slug"), ), migrations.AlterUniqueTogether( name="demoprojecttag", diff --git a/example/demo_django_base/views.py b/example/demo_django_base/views.py index 2ea2bcbf..9f989ea8 100644 --- a/example/demo_django_base/views.py +++ b/example/demo_django_base/views.py @@ -3,8 +3,8 @@ # Create your views here. def index_view(request): - return render(request=request, template_name='index.html') + return render(request=request, template_name="index.html") def page1_view(request): - return render(request=request, template_name='page1.html') + return render(request=request, template_name="page1.html") diff --git a/example/setup/asgi.py b/example/setup/asgi.py index 56953336..83c1dc68 100644 --- a/example/setup/asgi.py +++ b/example/setup/asgi.py @@ -11,6 +11,6 @@ from django.core.asgi import get_asgi_application -os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'demo_app.settings') +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "demo_app.settings") application = get_asgi_application() diff --git a/example/setup/wsgi.py b/example/setup/wsgi.py index c83ea2de..48156967 100644 --- a/example/setup/wsgi.py +++ b/example/setup/wsgi.py @@ -11,6 +11,6 @@ from django.core.wsgi import get_wsgi_application -os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'demo_app.settings') +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "demo_app.settings") application = get_wsgi_application() diff --git a/tests/test_account_register.py b/tests/test_account_register.py index e3860ab1..f7720ed4 100644 --- a/tests/test_account_register.py +++ b/tests/test_account_register.py @@ -15,11 +15,13 @@ def test_register_password_is_to_simillar_and_short(self): "username": "string", "first_name": "string", "last_name": "string", - "email": "user@example.com" + "email": "user@example.com", } - response = self.api_client.post('/account/register/', user, format='json') - expected_response = b'{"password":["The password is too similar to the username.","This password is too ' \ - b'short. It must contain at least 8 characters."],"non_field_errors":[]}' + response = self.api_client.post("/account/register/", user, format="json") + expected_response = ( + b'{"password":["The password is too similar to the username.","This password is too ' + b'short. It must contain at least 8 characters."],"non_field_errors":[]}' + ) self.assertEqual(response.status_code, 400) self.assertEqual(response.content, expected_response) @@ -30,11 +32,13 @@ def test_register_password_is_to_short(self): "username": "string", "first_name": "string", "last_name": "string", - "email": "user@example.com" + "email": "user@example.com", } - response = self.api_client.post('/account/register/', user, format='json') - expected_response = b'{"password":["This password is too short. It must contain at least 8 characters."],' \ - b'"non_field_errors":[]}' + response = self.api_client.post("/account/register/", user, format="json") + expected_response = ( + b'{"password":["This password is too short. It must contain at least 8 characters."],' + b'"non_field_errors":[]}' + ) self.assertEqual(response.status_code, 400) self.assertEqual(response.content, expected_response) @@ -45,9 +49,9 @@ def test_register_password_is_to_similar(self): "username": "string", "first_name": "string", "last_name": "string", - "email": "user@example.com" + "email": "user@example.com", } - response = self.api_client.post('/account/register/', user, format='json') + response = self.api_client.post("/account/register/", user, format="json") expected_response = b'{"password":["The password is too similar to the username."],"non_field_errors":[]}' self.assertEqual(response.status_code, 400) self.assertEqual(response.content, expected_response) @@ -59,11 +63,12 @@ def test_register_success(self): "username": "string", "first_name": "string", "last_name": "string", - "email": "user@example.com" + "email": "user@example.com", } - response = self.api_client.post('/account/register/', user, format='json') - expected_response = b'{"id":3,"username":"string","first_name":"string","last_name":"string",' \ - b'"email":"user@example.com"}' + response = self.api_client.post("/account/register/", user, format="json") + expected_response = ( + b'{"id":3,"username":"string","first_name":"string","last_name":"string",' b'"email":"user@example.com"}' + ) self.assertEqual(response.status_code, 201) self.assertEqual(response.content, expected_response) @@ -74,15 +79,16 @@ def test_register_success_duplicate(self): "username": "string", "first_name": "string", "last_name": "string", - "email": "user@example.com" + "email": "user@example.com", } - response = self.api_client.post('/account/register/', user, format='json') - expected_response = b'{"id":3,"username":"string","first_name":"string","last_name":"string",' \ - b'"email":"user@example.com"}' + response = self.api_client.post("/account/register/", user, format="json") + expected_response = ( + b'{"id":3,"username":"string","first_name":"string","last_name":"string",' b'"email":"user@example.com"}' + ) self.assertEqual(response.status_code, 201) self.assertEqual(response.content, expected_response) - response = self.api_client.post('/account/register/', user, format='json') + response = self.api_client.post("/account/register/", user, format="json") expected_response = b'{"username":["A user with that username already exists."]}' self.assertEqual(response.status_code, 400) self.assertEqual(response.content, expected_response) diff --git a/tests/test_auth_backends.py b/tests/test_auth_backends.py index f9429859..8b591dc5 100644 --- a/tests/test_auth_backends.py +++ b/tests/test_auth_backends.py @@ -13,18 +13,18 @@ def setUp(self): self.api_client = APIClient() def test_caching_for_bulk_update(self): - self.assertTrue(self.api_client.login(username='miha', password='mihamiha'), 'Not logged in') + self.assertTrue(self.api_client.login(username="miha", password="mihamiha"), "Not logged in") # Try to do something only superuser can - response = self.api_client.post('/account/impersonate', {'username': 'janez'}, format='json') + response = self.api_client.post("/account/impersonate", {"username": "janez"}, format="json") self.assertEqual(response.status_code, 403) self.assertIsNotNone(cache.get(USER_CACHE_KEY.format(id=1))) - UserProfile.objects.filter(username__in=['miha', 'janez']).update(is_superuser=True, is_staff=True) + UserProfile.objects.filter(username__in=["miha", "janez"]).update(is_superuser=True, is_staff=True) # I still shouldn't be able to do superuser stuff - response = self.api_client.post('/account/impersonate', {'username': 'janez'}, format='json') + response = self.api_client.post("/account/impersonate", {"username": "janez"}, format="json") self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) # Clearing cache, now Miha can do better stuff @@ -32,5 +32,5 @@ def test_caching_for_bulk_update(self): for user in staff: cache.delete(USER_CACHE_KEY.format(id=user.id)) - response = self.api_client.post('/account/impersonate', {'username': 'janez'}, format='json') + response = self.api_client.post("/account/impersonate", {"username": "janez"}, format="json") self.assertEqual(response.status_code, status.HTTP_200_OK) diff --git a/tests/test_base.py b/tests/test_base.py index add51364..007a08e6 100644 --- a/tests/test_base.py +++ b/tests/test_base.py @@ -4,9 +4,8 @@ class TestBase(TestCase): - def __login_with_user(self, user_data: dict) -> bool: - return self.api_client.login(username=user_data['username'], password=user_data['password']) + return self.api_client.login(username=user_data["username"], password=user_data["password"]) def _login_with_test_user_one(self) -> bool: return self.__login_with_user(TEST_USER_ONE_DATA) diff --git a/tests/test_models.py b/tests/test_models.py index 5b1e8e57..96ded1fb 100644 --- a/tests/test_models.py +++ b/tests/test_models.py @@ -24,20 +24,20 @@ def test_construction(self): assert UserProfile() def test_reverse_full_name_order(self): - self.assertTrue(self._login_with_test_user_two(), 'Not logged in') - response = self.api_client.get('/account/profile/current', {}, format='json') + self.assertTrue(self._login_with_test_user_two(), "Not logged in") + response = self.api_client.get("/account/profile/current", {}, format="json") self.assertEqual(response.status_code, status.HTTP_200_OK) - self.assertEqual(response.data['full_name'], 'Janez Novak') + self.assertEqual(response.data["full_name"], "Janez Novak") settings.PROFILE_REVERSE_FULL_NAME_ORDER = True - response = self.api_client.get('/account/profile/current', {}, format='json') + response = self.api_client.get("/account/profile/current", {}, format="json") self.assertEqual(response.status_code, status.HTTP_200_OK) - self.assertEqual(response.data['full_name'], 'Novak Janez') + self.assertEqual(response.data["full_name"], "Novak Janez") settings.PROFILE_REVERSE_FULL_NAME_ORDER = False - janez = UserProfile.objects.get(username='janez') + janez = UserProfile.objects.get(username="janez") janez.reverse_full_name_order = True janez.save() - response = self.api_client.get('/account/profile/current', {}, format='json') + response = self.api_client.get("/account/profile/current", {}, format="json") self.assertEqual(response.status_code, status.HTTP_200_OK) - self.assertEqual(response.data['full_name'], 'Novak Janez') + self.assertEqual(response.data["full_name"], "Novak Janez") diff --git a/tests/test_retrieve_holidays.py b/tests/test_retrieve_holidays.py index 99fe62ad..3dcae4d3 100644 --- a/tests/test_retrieve_holidays.py +++ b/tests/test_retrieve_holidays.py @@ -8,10 +8,6 @@ class RetrieveHolidaysTest(TestBase): - def test_retieve_holidays(self): - response: requests.Response = requests.get( - holidays_api_url % (datetime.datetime.now().year, 'SI'), - timeout=6 - ) + response: requests.Response = requests.get(holidays_api_url % (datetime.datetime.now().year, "SI"), timeout=6) self.assertEqual(response.status_code, status.HTTP_200_OK) diff --git a/tests/test_role.py b/tests/test_role.py index 1f10a726..b1f17e83 100644 --- a/tests/test_role.py +++ b/tests/test_role.py @@ -18,9 +18,7 @@ class TestRole(TestBase): def setUp(self): super().setUp() self.api_client = APIClient() - self.project: Model = swapper.load_model( - "django_project_base", "Project" - ).objects.create( + self.project: Model = swapper.load_model("django_project_base", "Project").objects.create( name="test-project", owner=UserProfile.objects.get(username=TEST_USER_ONE_DATA["username"]), slug="test-project-slug", @@ -34,9 +32,7 @@ def setUp(self): }, format="json", ) - self.api_client.credentials( - HTTP_AUTHORIZATION="sessionid " + response.data.get("sessionid", None) - ) + self.api_client.credentials(HTTP_AUTHORIZATION="sessionid " + response.data.get("sessionid", None)) def __create_role(self, payload: dict = {}) -> Response: return self.api_client.post( @@ -59,9 +55,7 @@ def test_create_project_role(self): def test_list_project_role(self): self.__create_role() - list_response: Response = self.api_client.get( - f"{self.url}?project={self.project.pk}" - ) + list_response: Response = self.api_client.get(f"{self.url}?project={self.project.pk}") self.assertEqual(list_response.status_code, status.HTTP_200_OK) self.assertEqual(len(list_response.json()), 1) self.assertEqual(list_response.json()[0].get("name"), self.test_role_name) @@ -95,6 +89,4 @@ def test_delete_project_role(self): role_pk: int = self.__create_role().json().get("id") delete_response: Response = self.api_client.delete(f"{self.url}/{role_pk}") self.assertEqual(delete_response.status_code, status.HTTP_204_NO_CONTENT) - self.assertEqual( - 0, len(self.api_client.get(f"{self.url}?project={self.project.pk}").json()) - ) + self.assertEqual(0, len(self.api_client.get(f"{self.url}?project={self.project.pk}").json()))