diff --git a/pyproject.toml b/pyproject.toml --- a/pyproject.toml +++ b/pyproject.toml @@ -9,3 +9,5 @@ ensure_newline_before_comments = true line_length = 88 force_sort_within_sections = true +known_django = 'django,rest_framework' +sections = 'FUTURE,STDLIB,THIRDPARTY,DJANGO,FIRSTPARTY,LOCALFOLDER' diff --git a/swh/web/admin/deposit.py b/swh/web/admin/deposit.py --- a/swh/web/admin/deposit.py +++ b/swh/web/admin/deposit.py @@ -3,15 +3,16 @@ # License: GNU Affero General Public License version 3, or any later version # See top-level LICENSE file for more information +import requests +from requests.auth import HTTPBasicAuth +import sentry_sdk + from django.conf import settings from django.contrib.admin.views.decorators import staff_member_required from django.core.cache import cache from django.core.paginator import Paginator from django.http import JsonResponse from django.shortcuts import render -import requests -from requests.auth import HTTPBasicAuth -import sentry_sdk from swh.web.admin.adminurls import admin_route from swh.web.config import get_config diff --git a/swh/web/api/apidoc.py b/swh/web/api/apidoc.py --- a/swh/web/api/apidoc.py +++ b/swh/web/api/apidoc.py @@ -14,9 +14,10 @@ import docutils.nodes import docutils.parsers.rst import docutils.utils -from rest_framework.decorators import api_view import sentry_sdk +from rest_framework.decorators import api_view + from swh.web.api.apiresponse import error_response, make_api_response from swh.web.api.apiurls import APIUrls from swh.web.common.utils import parse_rst diff --git a/swh/web/api/renderers.py b/swh/web/api/renderers.py --- a/swh/web/api/renderers.py +++ b/swh/web/api/renderers.py @@ -3,9 +3,10 @@ # License: GNU Affero General Public License version 3, or any later version # See top-level LICENSE file for more information -from rest_framework import renderers import yaml +from rest_framework import renderers + class YAMLRenderer(renderers.BaseRenderer): """ diff --git a/swh/web/api/throttling.py b/swh/web/api/throttling.py --- a/swh/web/api/throttling.py +++ b/swh/web/api/throttling.py @@ -6,10 +6,11 @@ from ipaddress import IPv4Network, IPv6Network, ip_address, ip_network from typing import Callable, List, TypeVar, Union +import sentry_sdk + from django.core.exceptions import ImproperlyConfigured import rest_framework from rest_framework.throttling import ScopedRateThrottle -import sentry_sdk from swh.web.config import get_config diff --git a/swh/web/api/views/utils.py b/swh/web/api/views/utils.py --- a/swh/web/api/views/utils.py +++ b/swh/web/api/views/utils.py @@ -6,10 +6,11 @@ from types import GeneratorType from typing import Any, Callable, Dict, Mapping, Optional +from typing_extensions import Protocol + from django.http import HttpRequest from rest_framework.decorators import api_view from rest_framework.response import Response -from typing_extensions import Protocol from swh.web.api.apiurls import APIUrls, api_route from swh.web.common.exc import NotFoundExc diff --git a/swh/web/auth/backends.py b/swh/web/auth/backends.py --- a/swh/web/auth/backends.py +++ b/swh/web/auth/backends.py @@ -7,12 +7,13 @@ import hashlib from typing import Any, Dict, Optional +import sentry_sdk + from django.core.cache import cache from django.http import HttpRequest from django.utils import timezone from rest_framework.authentication import BaseAuthentication from rest_framework.exceptions import AuthenticationFailed, ValidationError -import sentry_sdk from swh.web.auth.keycloak import KeycloakOpenIDConnect from swh.web.auth.models import OIDCUser diff --git a/swh/web/browse/utils.py b/swh/web/browse/utils.py --- a/swh/web/browse/utils.py +++ b/swh/web/browse/utils.py @@ -8,11 +8,12 @@ import textwrap from threading import Lock +import magic +import sentry_sdk + from django.core.cache import cache from django.utils.html import escape from django.utils.safestring import mark_safe -import magic -import sentry_sdk from swh.web.common import highlightjs, service from swh.web.common.exc import http_status_code_message diff --git a/swh/web/browse/views/content.py b/swh/web/browse/views/content.py --- a/swh/web/browse/views/content.py +++ b/swh/web/browse/views/content.py @@ -6,10 +6,11 @@ import difflib from distutils.util import strtobool +import sentry_sdk + from django.http import HttpResponse, JsonResponse from django.shortcuts import render from django.template.defaultfilters import filesizeformat -import sentry_sdk from swh.model.hashutil import hash_to_hex from swh.model.identifiers import CONTENT, DIRECTORY, RELEASE, REVISION, SNAPSHOT diff --git a/swh/web/browse/views/directory.py b/swh/web/browse/views/directory.py --- a/swh/web/browse/views/directory.py +++ b/swh/web/browse/views/directory.py @@ -5,10 +5,11 @@ import os +import sentry_sdk + from django.http import HttpResponse from django.shortcuts import redirect, render from django.template.defaultfilters import filesizeformat -import sentry_sdk from swh.model.identifiers import DIRECTORY, RELEASE, REVISION, SNAPSHOT from swh.web.browse.browseurls import browse_route diff --git a/swh/web/browse/views/release.py b/swh/web/browse/views/release.py --- a/swh/web/browse/views/release.py +++ b/swh/web/browse/views/release.py @@ -3,9 +3,10 @@ # License: GNU Affero General Public License version 3, or any later version # See top-level LICENSE file for more information -from django.shortcuts import render import sentry_sdk +from django.shortcuts import render + from swh.model.identifiers import CONTENT, DIRECTORY, RELEASE, REVISION, SNAPSHOT from swh.web.browse.browseurls import browse_route from swh.web.browse.snapshot_context import get_snapshot_context diff --git a/swh/web/common/exc.py b/swh/web/common/exc.py --- a/swh/web/common/exc.py +++ b/swh/web/common/exc.py @@ -5,11 +5,12 @@ import traceback +import sentry_sdk + from django.http import HttpResponse from django.shortcuts import render from django.utils.html import escape from django.utils.safestring import mark_safe -import sentry_sdk from swh.web.config import get_config diff --git a/swh/web/common/identifiers.py b/swh/web/common/identifiers.py --- a/swh/web/common/identifiers.py +++ b/swh/web/common/identifiers.py @@ -6,9 +6,10 @@ from typing import Any, Dict, Iterable, List, Optional, cast from urllib.parse import quote -from django.http import QueryDict from typing_extensions import TypedDict +from django.http import QueryDict + from swh.model.exceptions import ValidationError from swh.model.hashutil import hash_to_bytes from swh.model.identifiers import ( diff --git a/swh/web/common/origin_save.py b/swh/web/common/origin_save.py --- a/swh/web/common/origin_save.py +++ b/swh/web/common/origin_save.py @@ -10,13 +10,14 @@ import logging from typing import Any, Dict -from django.core.exceptions import ObjectDoesNotExist, ValidationError -from django.core.validators import URLValidator -from django.utils.html import escape from prometheus_client import Gauge import requests import sentry_sdk +from django.core.exceptions import ObjectDoesNotExist, ValidationError +from django.core.validators import URLValidator +from django.utils.html import escape + from swh.scheduler.utils import create_oneshot_task_dict from swh.web import config from swh.web.common import service diff --git a/swh/web/common/swh_templatetags.py b/swh/web/common/swh_templatetags.py --- a/swh/web/common/swh_templatetags.py +++ b/swh/web/common/swh_templatetags.py @@ -6,10 +6,11 @@ import json import re +import sentry_sdk + from django import template from django.core.serializers.json import DjangoJSONEncoder from django.utils.safestring import mark_safe -import sentry_sdk from swh.web.common.origin_save import get_savable_visit_types from swh.web.common.utils import rst_to_html diff --git a/swh/web/common/typing.py b/swh/web/common/typing.py --- a/swh/web/common/typing.py +++ b/swh/web/common/typing.py @@ -5,9 +5,10 @@ from typing import Any, Dict, List, Optional, TypeVar, Union -from django.http import QueryDict from typing_extensions import TypedDict +from django.http import QueryDict + from swh.core.api.classes import PagedResult as CorePagedResult QueryParameters = Union[Dict[str, Any], QueryDict] diff --git a/swh/web/common/utils.py b/swh/web/common/utils.py --- a/swh/web/common/utils.py +++ b/swh/web/common/utils.py @@ -8,14 +8,15 @@ from typing import Any, Dict, Optional from bs4 import BeautifulSoup -from django.http import HttpRequest, QueryDict -from django.urls import reverse as django_reverse from docutils.core import publish_parts import docutils.parsers.rst import docutils.utils from docutils.writers.html5_polyglot import HTMLTranslator, Writer from iso8601 import ParseError, parse_date from prometheus_client.registry import CollectorRegistry + +from django.http import HttpRequest, QueryDict +from django.urls import reverse as django_reverse from rest_framework.authentication import SessionAuthentication from swh.web.common.exc import BadInputExc diff --git a/swh/web/misc/badges.py b/swh/web/misc/badges.py --- a/swh/web/misc/badges.py +++ b/swh/web/misc/badges.py @@ -6,10 +6,11 @@ from base64 import b64encode from typing import Optional, cast +from pybadges import badge + from django.conf.urls import url from django.contrib.staticfiles import finders from django.http import HttpRequest, HttpResponse -from pybadges import badge from swh.model.exceptions import ValidationError from swh.model.identifiers import ( diff --git a/swh/web/misc/metrics.py b/swh/web/misc/metrics.py --- a/swh/web/misc/metrics.py +++ b/swh/web/misc/metrics.py @@ -3,9 +3,10 @@ # License: GNU Affero General Public License version 3, or any later version # See top-level LICENSE file for more information -from django.http import HttpResponse from prometheus_client.exposition import CONTENT_TYPE_LATEST, generate_latest +from django.http import HttpResponse + from swh.web.common.origin_save import compute_save_requests_metrics from swh.web.common.utils import SWH_WEB_METRICS_REGISTRY diff --git a/swh/web/misc/urls.py b/swh/web/misc/urls.py --- a/swh/web/misc/urls.py +++ b/swh/web/misc/urls.py @@ -5,12 +5,13 @@ import json +import requests +import sentry_sdk + from django.conf.urls import include, url from django.contrib.staticfiles import finders from django.http import JsonResponse from django.shortcuts import render -import requests -import sentry_sdk from swh.web.common import service from swh.web.config import get_config diff --git a/swh/web/tests/admin/test_origin_save.py b/swh/web/tests/admin/test_origin_save.py --- a/swh/web/tests/admin/test_origin_save.py +++ b/swh/web/tests/admin/test_origin_save.py @@ -5,9 +5,10 @@ from urllib.parse import unquote -from django.contrib.auth import get_user_model import pytest +from django.contrib.auth import get_user_model + from swh.web.common.models import ( SAVE_REQUEST_ACCEPTED, SAVE_REQUEST_PENDING, diff --git a/swh/web/tests/api/test_apidoc.py b/swh/web/tests/api/test_apidoc.py --- a/swh/web/tests/api/test_apidoc.py +++ b/swh/web/tests/api/test_apidoc.py @@ -6,6 +6,7 @@ import textwrap import pytest + from rest_framework.response import Response from swh.storage.exc import StorageAPIError, StorageDBError diff --git a/swh/web/tests/api/test_throttling.py b/swh/web/tests/api/test_throttling.py --- a/swh/web/tests/api/test_throttling.py +++ b/swh/web/tests/api/test_throttling.py @@ -3,11 +3,12 @@ # License: GNU Affero General Public License version 3, or any later version # See top-level LICENSE file for more information +import pytest + from django.conf.urls import url from django.contrib.auth.models import Permission, User from django.contrib.contenttypes.models import ContentType from django.test.utils import override_settings -import pytest from rest_framework.decorators import api_view from rest_framework.response import Response from rest_framework.views import APIView diff --git a/swh/web/tests/api/views/test_origin_save.py b/swh/web/tests/api/views/test_origin_save.py --- a/swh/web/tests/api/views/test_origin_save.py +++ b/swh/web/tests/api/views/test_origin_save.py @@ -5,9 +5,10 @@ from datetime import datetime, timedelta -from django.utils import timezone import pytest +from django.utils import timezone + from swh.web.common.models import ( SAVE_REQUEST_ACCEPTED, SAVE_REQUEST_PENDING, diff --git a/swh/web/tests/auth/test_api_auth.py b/swh/web/tests/auth/test_api_auth.py --- a/swh/web/tests/auth/test_api_auth.py +++ b/swh/web/tests/auth/test_api_auth.py @@ -3,9 +3,10 @@ # License: GNU Affero General Public License version 3, or any later version # See top-level LICENSE file for more information -from django.contrib.auth.models import AnonymousUser, User import pytest +from django.contrib.auth.models import AnonymousUser, User + from swh.web.auth.models import OIDCUser from swh.web.common.utils import reverse diff --git a/swh/web/tests/auth/test_backends.py b/swh/web/tests/auth/test_backends.py --- a/swh/web/tests/auth/test_backends.py +++ b/swh/web/tests/auth/test_backends.py @@ -5,9 +5,10 @@ from datetime import datetime, timedelta +import pytest + from django.conf import settings from django.contrib.auth import authenticate, get_backends -import pytest from rest_framework.exceptions import AuthenticationFailed from swh.web.auth.backends import OIDCBearerTokenAuthentication diff --git a/swh/web/tests/auth/test_middlewares.py b/swh/web/tests/auth/test_middlewares.py --- a/swh/web/tests/auth/test_middlewares.py +++ b/swh/web/tests/auth/test_middlewares.py @@ -5,9 +5,10 @@ from datetime import datetime -from django.test import modify_settings import pytest +from django.test import modify_settings + from swh.web.common.utils import reverse from .keycloak_mock import mock_keycloak diff --git a/swh/web/tests/auth/test_views.py b/swh/web/tests/auth/test_views.py --- a/swh/web/tests/auth/test_views.py +++ b/swh/web/tests/auth/test_views.py @@ -6,9 +6,10 @@ from urllib.parse import urljoin, urlparse import uuid +import pytest + from django.contrib.auth.models import AnonymousUser, User from django.http import QueryDict -import pytest from swh.web.auth.models import OIDCUser from swh.web.auth.utils import OIDC_SWH_WEB_CLIENT_ID diff --git a/swh/web/tests/browse/views/test_content.py b/swh/web/tests/browse/views/test_content.py --- a/swh/web/tests/browse/views/test_content.py +++ b/swh/web/tests/browse/views/test_content.py @@ -5,9 +5,10 @@ import random -from django.utils.html import escape from hypothesis import given +from django.utils.html import escape + from swh.model.identifiers import CONTENT, DIRECTORY, RELEASE, REVISION, SNAPSHOT from swh.web.browse.snapshot_context import process_snapshot_branches from swh.web.browse.utils import ( diff --git a/swh/web/tests/browse/views/test_directory.py b/swh/web/tests/browse/views/test_directory.py --- a/swh/web/tests/browse/views/test_directory.py +++ b/swh/web/tests/browse/views/test_directory.py @@ -5,9 +5,10 @@ import random -from django.utils.html import escape from hypothesis import given +from django.utils.html import escape + from swh.model.identifiers import DIRECTORY, RELEASE, REVISION, SNAPSHOT from swh.web.browse.snapshot_context import process_snapshot_branches from swh.web.common.identifiers import gen_swhid diff --git a/swh/web/tests/browse/views/test_origin.py b/swh/web/tests/browse/views/test_origin.py --- a/swh/web/tests/browse/views/test_origin.py +++ b/swh/web/tests/browse/views/test_origin.py @@ -7,9 +7,10 @@ import re import string -from django.utils.html import escape from hypothesis import given +from django.utils.html import escape + from swh.model.hashutil import hash_to_bytes from swh.model.identifiers import CONTENT, DIRECTORY, RELEASE, REVISION, SNAPSHOT from swh.model.model import ( diff --git a/swh/web/tests/browse/views/test_release.py b/swh/web/tests/browse/views/test_release.py --- a/swh/web/tests/browse/views/test_release.py +++ b/swh/web/tests/browse/views/test_release.py @@ -5,9 +5,10 @@ import random -from django.utils.html import escape from hypothesis import given +from django.utils.html import escape + from swh.web.common.identifiers import gen_swhid from swh.web.common.utils import format_utc_iso_date, reverse from swh.web.tests.django_asserts import assert_contains, assert_template_used diff --git a/swh/web/tests/browse/views/test_revision.py b/swh/web/tests/browse/views/test_revision.py --- a/swh/web/tests/browse/views/test_revision.py +++ b/swh/web/tests/browse/views/test_revision.py @@ -5,9 +5,10 @@ import random -from django.utils.html import escape from hypothesis import given +from django.utils.html import escape + from swh.model.identifiers import DIRECTORY, REVISION, SNAPSHOT from swh.web.common.identifiers import gen_swhid from swh.web.common.utils import format_utc_iso_date, parse_iso8601_date_to_utc, reverse diff --git a/swh/web/tests/common/test_utils.py b/swh/web/tests/common/test_utils.py --- a/swh/web/tests/common/test_utils.py +++ b/swh/web/tests/common/test_utils.py @@ -6,10 +6,11 @@ import datetime from urllib.parse import quote +import pytest + from django.conf.urls import url from django.test.utils import override_settings from django.urls.exceptions import NoReverseMatch -import pytest from swh.web.common import utils from swh.web.common.exc import BadInputExc diff --git a/swh/web/tests/conftest.py b/swh/web/tests/conftest.py --- a/swh/web/tests/conftest.py +++ b/swh/web/tests/conftest.py @@ -10,9 +10,10 @@ import sys from typing import Any, Dict, List, Optional -from django.core.cache import cache from hypothesis import HealthCheck, settings import pytest + +from django.core.cache import cache from rest_framework.test import APIClient, APIRequestFactory from swh.model.hashutil import ALGORITHMS, hash_to_bytes diff --git a/swh/web/tests/misc/test_origin_save.py b/swh/web/tests/misc/test_origin_save.py --- a/swh/web/tests/misc/test_origin_save.py +++ b/swh/web/tests/misc/test_origin_save.py @@ -5,9 +5,10 @@ from datetime import datetime -from django.test import Client import pytest +from django.test import Client + from swh.web.common.origin_save import ( SAVE_REQUEST_ACCEPTED, SAVE_TASK_NOT_YET_SCHEDULED, diff --git a/swh/web/urls.py b/swh/web/urls.py --- a/swh/web/urls.py +++ b/swh/web/urls.py @@ -4,6 +4,8 @@ # See top-level LICENSE file for more information +from django_js_reverse.views import urls_js + from django.conf import settings from django.conf.urls import ( handler400, @@ -17,7 +19,6 @@ from django.contrib.staticfiles.views import serve from django.shortcuts import render from django.views.generic.base import RedirectView -from django_js_reverse.views import urls_js from swh.web.browse.identifiers import swhid_browse from swh.web.common.exc import (