Skip to content

Commit

Permalink
chore: Update ruff lint configuration
Browse files Browse the repository at this point in the history
  • Loading branch information
jpmckinney committed Sep 16, 2024
1 parent 8ef8613 commit 5cbf482
Show file tree
Hide file tree
Showing 8 changed files with 58 additions and 100 deletions.
65 changes: 18 additions & 47 deletions backend/api/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,9 +170,7 @@ class FilterDatasetSerializer(serializers.Serializer):


class DataItemViewSet(mixins.RetrieveModelMixin, viewsets.GenericViewSet):
"""
Return OCDS data that passed or failed a check.
"""
"""Return OCDS data that passed or failed a check."""

queryset = DataItem.objects.all()
serializer_class = DataItemSerializer
Expand Down Expand Up @@ -215,28 +213,22 @@ def get_report(self, model, fields):
# https://github.com/encode/django-rest-framework/blob/2db0c0b/rest_framework/mixins.py#L35
@extend_schema(responses=DatasetSerializer)
def list(self, request, *args, **kwargs):
"""
Return all datasets with their status and filter metadata.
"""
"""Return all datasets with their status and filter metadata."""
queryset = self.get_annotated_queryset()
serializer = DatasetSerializer(queryset, many=True)
return Response(serializer.data)

# https://github.com/encode/django-rest-framework/blob/2db0c0b/rest_framework/mixins.py#L51
@extend_schema(responses=DatasetSerializer)
def retrieve(self, request, *args, **kwargs):
"""
Return the dataset with its status and filter metadata.
"""
"""Return the dataset with its status and filter metadata."""
instance = self.get_annotated_object()
serializer = DatasetSerializer(instance)
return Response(serializer.data)

@extend_schema(request=CreateDatasetSerializer, responses={202: None})
def create(self, request):
"""
Publish a message to RabbitMQ to create a dataset.
"""
"""Publish a message to RabbitMQ to create a dataset."""
serializer = CreateDatasetSerializer(data=request.data)
serializer.is_valid(raise_exception=True)
message = {
Expand All @@ -251,9 +243,7 @@ def create(self, request):
@extend_schema(request=FilterDatasetSerializer, responses={202: None})
@action(detail=True, methods=["post"])
def filter(self, request, pk=None):
"""
Publish a message to RabbitMQ to create a filtered dataset.
"""
"""Publish a message to RabbitMQ to create a filtered dataset."""
serializer = FilterDatasetSerializer(data=request.data)
serializer.is_valid(raise_exception=True)
message = {"dataset_id_original": pk, "filter_message": serializer.data}
Expand All @@ -262,18 +252,17 @@ def filter(self, request, pk=None):

@extend_schema(responses={202: None})
def destroy(self, request, pk=None):
"""
Publish a message to RabbitMQ to wipe the dataset.
"""
"""Publish a message to RabbitMQ to wipe the dataset."""
publish({"dataset_id": pk}, "wiper_init")
return Response(status=status.HTTP_202_ACCEPTED)

@extend_schema(responses={200: {"type": "object", "properties": {"id": {"type": "integer"}}}})
@action(detail=False)
def find_by_name(self, request):
"""
Return the ID of the dataset with the name given in the `name` query string parameter, as an object like
`{"id": 123}`, or `{}` if no name matches.
Return the ID of the dataset with the name given in the `name` query string parameter, as an object.
``{"id": 123}`` for example, or ``{}`` if no name matches.
"""
try:
dataset = self.get_queryset().get(name=request.query_params.get("name"))
Expand All @@ -284,25 +273,19 @@ def find_by_name(self, request):
@extend_schema(responses={200: {"type": "object"}})
@action(detail=True)
def field_level_report(self, request, pk=None):
"""
Return a report of the dataset's field-level checks.
"""
"""Return a report of the dataset's field-level checks."""
return Response(get_object_or_404(Report, dataset=pk, type="field_level_check").data)

@extend_schema(responses={200: {"type": "object"}})
@action(detail=True)
def compiled_release_level_report(self, request, pk=None):
"""
Return a report of the dataset's compiled release-level checks.
"""
"""Return a report of the dataset's compiled release-level checks."""
return Response(get_object_or_404(Report, dataset=pk, type="resource_level_check").data)

@extend_schema(responses={200: {"type": "object"}})
@action(detail=True)
def dataset_level_report(self, request, pk=None):
"""
Return a report of the dataset's dataset-level checks.
"""
"""Return a report of the dataset's dataset-level checks."""
return self.get_report(
DatasetLevelCheck,
[
Expand All @@ -315,9 +298,7 @@ def dataset_level_report(self, request, pk=None):
@extend_schema(responses={200: {"type": "object"}})
@action(detail=True)
def time_based_report(self, request, pk=None):
"""
Return a report of the dataset's time-based checks.
"""
"""Return a report of the dataset's time-based checks."""
return self.get_report(
TimeVarianceLevelCheck,
[
Expand All @@ -332,9 +313,7 @@ def time_based_report(self, request, pk=None):
@extend_schema(responses=StatusSerializer)
@action(detail=True)
def status(self, request, pk=None):
"""
Return the dataset's status, as an object like `{"phase": "CHECKED", "state": "OK"}`, or `{}` if not set.
"""
"""Return the dataset's status, as an object like `{"phase": "CHECKED", "state": "OK"}`, or `{}` if not set."""
try:
progress = self.get_object_or_404(self.get_queryset().select_related("progress")).progress
return Response({"phase": progress.phase, "state": progress.state})
Expand All @@ -344,18 +323,14 @@ def status(self, request, pk=None):
@extend_schema(responses={200: {"type": "object"}})
@action(detail=True)
def metadata(self, request, pk=None):
"""
Return the dataset's collection metadata.
"""
"""Return the dataset's collection metadata."""
meta = self.get_object_or_404(self.get_queryset().values_list("meta__collection_metadata", flat=True))
return Response(meta or {})

@extend_schema(responses={200: {"type": "object"}})
@action(detail=True)
def coverage(self, request, pk=None):
"""
Return the dataset's coverage statistics.
"""
"""Return the dataset's coverage statistics."""
self.get_object() # trigger 404 if no dataset

# The lists of fields must match the names of field-level checks in pelican-backend.
Expand Down Expand Up @@ -421,9 +396,7 @@ def coverage(self, request, pk=None):
class FieldLevelDetail(views.APIView):
@extend_schema(responses={200: {"type": "object"}})
def get(self, request, pk, name, format=None):
"""
Return a report and examples of one field-level check.
"""
"""Return a report and examples of one field-level check."""
start_time = time.time()

detail = get_object_or_404(Report, dataset=pk, type="field_level_check", data__has_key=name).data[name]
Expand All @@ -444,9 +417,7 @@ def get(self, request, pk, name, format=None):
class ResourceLevelDetail(views.APIView):
@extend_schema(responses={200: {"type": "object"}})
def get(self, request, pk, name, format=None):
"""
Return a report and examples of one compiled release-level check.
"""
"""Return a report and examples of one compiled release-level check."""
start_time = time.time()

detail = get_object_or_404(Report, dataset=pk, type="resource_level_check", data__has_key=name).data[name]
Expand Down
4 changes: 1 addition & 3 deletions backend/exporter/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,7 @@ def fill(self, full_tag: str, template_id: str) -> "TagError":
return self

def as_dict(self) -> dict[str, str | None]:
"""
Return the exception as a dictionary (e.g. to serialize as JSON for the browser).
"""
"""Return the exception as a dictionary (e.g. to serialize as JSON for the browser)."""
return {
"reason": self.reason,
"full_tag": self.full_tag,
Expand Down
4 changes: 1 addition & 3 deletions backend/exporter/graphs.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,7 @@


def build_fig(aspect_ratio):
"""
Remember to call .close() in the figure.
"""
"""Remember to call .close() in the figure."""
plt.rcdefaults()
fig, ax = plt.subplots()
fig.set_size_inches(6, 6 * aspect_ratio)
Expand Down
8 changes: 2 additions & 6 deletions backend/exporter/leaf_tags/generic.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
"""
Factories for leaf tags.
"""
"""Factories for leaf tags."""

import datetime
from typing import Any
Expand All @@ -18,9 +16,7 @@


def generate_key_leaf_tag(key: str) -> type[LeafTag]:
"""
Build a :class:`~exporter.tag.LeafTag` named ``key``, that returns the ``key`` from the context.
"""
"""Build a :class:`~exporter.tag.LeafTag` named ``key``, that returns the ``key`` from the context."""

@leaf(key)
def _tag(tag: LeafTag, data: dict[str, Any]) -> str:
Expand Down
12 changes: 3 additions & 9 deletions backend/exporter/tag.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,9 +112,7 @@ def render(self, data: dict[str, Any]) -> Any:

# Keep this class, because render()'s signature differs between LeafTag and TemplateTag.
class LeafTag(Tag):
"""
A leaf tag renders itself, using the data ("context") provided by a template tag.
"""
"""A leaf tag renders itself, using the data ("context") provided by a template tag."""

def render(self, data: dict[str, Any]) -> str | etree._Element | list[etree._Element]:
"""
Expand Down Expand Up @@ -145,9 +143,7 @@ def __init__(self, gdocs: Gdocs, dataset_id: int):
self.argument_defaults["template"] = self.default_template

def get_context(self) -> dict[str, Any]:
"""
Return the data ("context") to be provided to sub-tags.
"""
"""Return the data ("context") to be provided to sub-tags."""
return {}

def get_tags_mapping(self, texts: list[etree._Element]) -> tuple[dict[str, Tag], list[str]]:
Expand Down Expand Up @@ -410,9 +406,7 @@ def _argument(cls: builtins.type[Tag]) -> builtins.type[Tag]:


def generate_error_template_tag(message: str) -> type[TemplateTag]:
"""
Build a :class:`~exporter.tag.TemplateTag` for the error template and set the error ``message``.
"""
"""Build a :class:`~exporter.tag.TemplateTag` for the error template and set the error ``message``."""

@template("error", settings.GDOCS_TEMPLATES["DEFAULT_ERROR_TEMPLATE"], (value_tag,))
def _tag(tag: TemplateTag) -> dict[str, Any]:
Expand Down
4 changes: 1 addition & 3 deletions backend/exporter/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,7 @@ def sample_and_format(population, arguments: dict[str, Any]) -> str | list[etree


def box_image(tag, function, filename: str, *args, **kwargs) -> etree._Element:
"""
Add an image to the OpenDocument file and return an image within a frame.
"""
"""Add an image to the OpenDocument file and return an image within a frame."""
buffer, aspect_ratio = function(*args, **kwargs)

path = tag.gdocs.add_image_file(buffer, filename)
Expand Down
11 changes: 3 additions & 8 deletions backend/manage.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,9 @@
def main():
"""Run administrative tasks."""
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "core.settings")
try:
from django.core.management import execute_from_command_line
except ImportError as exc:
raise ImportError(
"Couldn't import Django. Are you sure it's installed and "
"available on your PYTHONPATH environment variable? Did you "
"forget to activate a virtual environment?"
) from exc

from django.core.management import execute_from_command_line

execute_from_command_line(sys.argv)


Expand Down
50 changes: 29 additions & 21 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,33 +10,41 @@ src = ["backend"]
[tool.ruff.lint]
select = ["ALL"]
ignore = [
"ANN", "COM", "EM",
# https://docs.astral.sh/ruff/formatter/#conflicting-lint-rules
"W191", "D206", "Q000", "Q001", "Q002", "Q003", "ISC001",
"D203", "D212", # ignore incompatible rules
"D200", "D205", # documentation preferences
"C901", "PLR091", # complexity preferences
"D1", # docstrings
"PTH", # pathlib
"A001", # Django REST framework
"A002", # tag type
"ARG001", "ARG002", "DJ008", "RUF012", "SLF001", # Django
"PLR2004", # magic values
"PLW2901", # for-loop variable
"TRY003", # error messages
"ANN", "C901", "COM812", "D203", "D212", "D415", "EM", "PERF203", "PLR091", "Q000",
"D1",
"DJ008",
"PTH",
]

[tool.ruff.lint.flake8-builtins]
builtins-ignorelist = ["copyright"]
builtins-ignorelist = ["copyright", "format", "type"]

[tool.ruff.lint.flake8-self]
extend-ignore-names = ["_meta", "_Element"]

[tool.ruff.lint.flake8-unused-arguments]
ignore-variadic-names = true

[tool.ruff.lint.per-file-ignores]
"docs/conf.py" = ["INP001"] # no __init__.py file
"docs/*" = ["D100", "INP001"]
"{*/signals,*/views,*/migrations/*}.py" = ["ARG001"]
"{*/admin,*/routers,*/views,*/commands/*}.py" = ["ARG002"]
"{*/admin,*/forms,*/models,*/routers,*/serializers,*/translation,*/migrations/*,*/tests/*}.py" = ["RUF012"]
"*/migrations/*" = ["E501"]
"*/tests/*" = [
"D", # docstring
"PLR0913", # Too many arguments to function call
"PLR2004", # Magic value used
"PT", # Django
"S101", # assert
"D", "FBT003", "INP001", "PLR2004", "PT", "S", "TRY003",
]
"*/views.py" = [
"RUF012", # djangorestframework
]
"*/exporter/*" = [
"D205",
"ARG001", # tag
"ARG002", # data
"RUF012",
"PLR2004",
"PLW2901",
"TRY003", # errors
]

[tool.coverage.run]
Expand Down

0 comments on commit 5cbf482

Please sign in to comment.