Skip to content

Commit

Permalink
♻️ replace flake8, isort, ... with ruff (#17)
Browse files Browse the repository at this point in the history
  • Loading branch information
chassing authored Jun 13, 2024
1 parent 029dbf5 commit 1fbb4db
Show file tree
Hide file tree
Showing 10 changed files with 1,109 additions and 846 deletions.
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -62,5 +62,5 @@ FROM build-base-python as test-image
RUN poetry install --no-interaction --no-ansi
# install the tests
COPY --chown=app:app tests /code/tests/
COPY --chown=app:app Makefile setup.cfg /code/
COPY --chown=app:app Makefile /code/
USER app:app
14 changes: 6 additions & 8 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,15 @@ DIRS := glitchtip_jira_bridge
POETRY_RUN := poetry run --no-ansi --no-interaction

format:
$(POETRY_RUN) black $(DIRS)
$(POETRY_RUN) isort $(DIRS)
$(POETRY_RUN) ruff check
$(POETRY_RUN) ruff format
.PHONY: format

test:
$(POETRY_RUN) pytest --cov=$(DIRS) --cov-report=term-missing --cov-fail-under=95 --cov-report xml tests
$(POETRY_RUN) flake8 $(DIRS)
$(POETRY_RUN) pylint --extension-pkg-whitelist='pydantic' $(DIRS)
$(POETRY_RUN) mypy $(DIRS)
$(POETRY_RUN) black --check $(DIRS)
$(POETRY_RUN) isort --check-only $(DIRS)
$(POETRY_RUN) ruff check --no-fix
$(POETRY_RUN) ruff format --check
$(POETRY_RUN) mypy
$(POETRY_RUN) pytest -vv --cov=$(DIRS) --cov-report=term-missing --cov-report xml tests
.PHONY: test

pr-check:
Expand Down
13 changes: 9 additions & 4 deletions glitchtip_jira_bridge/backends/db.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,21 @@
datetime,
timedelta,
)
from typing import Any
from typing import TYPE_CHECKING, Any

from boto3.resources.base import ServiceResource
if TYPE_CHECKING:
from mypy_boto3_dynamodb import DynamoDBServiceResource
else:
DynamoDBServiceResource = object

from ..models import Issue


class Db:
def __init__(self, dyn_resource: ServiceResource, table_name: str) -> None:
self.table = dyn_resource.Table(table_name)
def __init__(
self, dynamodb_service_resource: DynamoDBServiceResource, table_name: str
) -> None:
self.table = dynamodb_service_resource.Table(table_name)
self.table.load()

def get(self, pk: str) -> dict | None:
Expand Down
10 changes: 5 additions & 5 deletions glitchtip_jira_bridge/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,18 @@ class Attachment(BaseModel):

@property
def labels(self) -> list[str]:
l: list[str] = []
_labels: list[str] = []
for f in self.fields or []:
match f.title.lower():
case "project":
l.append(f"project:{f.value}")
_labels.append(f"project:{f.value}")
case "release":
l.append(f"release:{f.value}")
_labels.append(f"release:{f.value}")
case "environment":
l.append(f"environment:{f.value}")
_labels.append(f"environment:{f.value}")
case _:
pass
return l
return _labels


class GlitchtipAlert(BaseModel):
Expand Down
6 changes: 3 additions & 3 deletions glitchtip_jira_bridge/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ def create_jira_ticket( # pylint: disable=too-many-arguments
log.info(f"Handling alert '{issue.text}' for '{jira_project_key}' jira project")
received_alerts.labels(jira_project_key).inc()
try:
dyn_resource = boto3.resource(
dynamodb_service_resource = boto3.resource(
"dynamodb",
endpoint_url=settings.dynamodb_url,
region_name=settings.dynamodb_aws_region,
Expand All @@ -75,14 +75,14 @@ def create_jira_ticket( # pylint: disable=too-many-arguments
),
issue_cache=IssueCache(
backend=Db(
dyn_resource=dyn_resource,
dynamodb_service_resource=dynamodb_service_resource,
table_name=settings.cache_table_name,
),
ttl=settings.cache_ttl,
),
limits=Limits(
backend=Db(
dyn_resource=dyn_resource,
dynamodb_service_resource=dynamodb_service_resource,
table_name=settings.limits_table_name,
),
limit=settings.issues_per_project_limit,
Expand Down
1,819 changes: 1,025 additions & 794 deletions poetry.lock

Large diffs are not rendered by default.

69 changes: 50 additions & 19 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,20 +21,20 @@ prometheus-fastapi-instrumentator = "^6.1.0"
[tool.poetry.group.dev.dependencies]
pytest = "^7.4.2"
mypy = "^1.5.1"
flake8 = "^6.1.0"
pylint = "^3.0.0"
black = "^23.9.1"
isort = "^5.12.0"
rich = "^13.6.0"
httpx = "^0.25.0"
pytest-cov = "^4.1.0"
pytest-mock = "^3.11.1"
types-requests = "^2.32.0.20240602"
boto3-stubs = { extras = ["dynamodb"], version = "^1.34.125" }
ruff = "^0.4.8"

[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"

[tool.mypy]
files = ["glitchtip_jira_bridge"]
plugins = "pydantic.mypy"
enable_error_code = "truthy-bool, redundant-expr"
no_implicit_optional = true
Expand All @@ -45,23 +45,54 @@ disallow_untyped_defs = true
disallow_incomplete_defs = true

[[tool.mypy.overrides]]
module = ["celery.*", "requests.*", "boto3.*"]
module = ["celery.*"]
ignore_missing_imports = true

[tool.isort]
profile = "black"
multi_line_output = 3
force_grid_wrap = 2
float_to_top = true
[tool.pytest.ini_options]
addopts = "-p no:warnings"

# Coverage configuration
[tool.coverage.run]
branch = true
omit = ["*/tests/*"]

[tool.pylint."messages control"]
disable = [
"missing-module-docstring",
"missing-class-docstring",
"missing-function-docstring",
"too-few-public-methods",
"logging-fstring-interpolation",
[tool.coverage.report]
fail_under = 95

# Ruff configuration
[tool.ruff]
line-length = 88
target-version = 'py311'
required-version = "0.4.8" # keep in sync with dev dependencies!
src = ["glitchtip_jira_bridge"]
extend-exclude = [
".local", # used by poetry in local venv
".cache", # used by poetry in local venv
]
fix = true

[tool.pytest.ini_options]
addopts = "-p no:warnings"
[tool.ruff.lint]
preview = true
# defaults are ["E4", "E7", "E9", "F"]
extend-select = [
# flake8 default rules
"E1", # preview rule
"E2", # preview rule
"W",
# isort
"I",
# pylint
"PL",
# pyupgrade
"UP",
]
ignore = [
"PLR0904", # Too many public methods
"PLR0913", # Too many arguments
"PLR0917", # Too many positional arguments
]
[tool.ruff.format]
preview = true

[tool.ruff.lint.isort]
known-first-party = ["glitchtip_jira_bridge"]
4 changes: 0 additions & 4 deletions setup.cfg

This file was deleted.

5 changes: 3 additions & 2 deletions tests/api/test_alert.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import requests
from celery import Task
from fastapi.testclient import TestClient
from pytest_mock import MockerFixture
Expand Down Expand Up @@ -47,7 +48,7 @@ def test_handle_alert(
issue_type="issue-type",
),
)
assert response.status_code == 202
assert response.status_code == requests.codes.accepted
task_mock.delay.assert_called_once_with(
"JIRA-PROJECT-KEY",
mocker.ANY,
Expand Down Expand Up @@ -94,7 +95,7 @@ def test_handle_alert_no_optional_fields(
],
),
)
assert response.status_code == 202
assert response.status_code == requests.codes.accepted
task_mock.delay.assert_called_once_with(
"JIRA-PROJECT-KEY", mocker.ANY, [], [], "Bug"
)
13 changes: 7 additions & 6 deletions tests/api/test_auth.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import requests
from fastapi.testclient import TestClient


Expand All @@ -6,25 +7,25 @@ def test_authentication_via_header(
) -> None:
for secret in config_api_key:
response = client.get("/api/v1/", headers={"Authorization": f"Bearer {secret}"})
assert response.status_code == 200
assert response.status_code == requests.codes.ok
response = client.get("/api/v1/", headers={"Authorization": "Bearer wrong"})
assert response.status_code == 401
assert response.status_code == requests.codes.unauthorized


def test_authentication_via_query_param(
config_api_key: list[str], client: TestClient
) -> None:
for secret in config_api_key:
response = client.get("/api/v1/", params={"token": secret})
assert response.status_code == 200
assert response.status_code == requests.codes.ok
response = client.get("/api/v1/", params={"token": "wrong"})
assert response.status_code == 401
assert response.status_code == requests.codes.unauthorized


def test_debug_no_authentication(config_debug: bool, client: TestClient) -> None:
response = client.get(
"/api/v1/", headers={"Authorization": "Bearer does-not-matter"}
)
assert response.status_code == 200
assert response.status_code == requests.codes.ok
response = client.get("/api/v1/")
assert response.status_code == 200
assert response.status_code == requests.codes.ok

0 comments on commit 1fbb4db

Please sign in to comment.