Skip to content

Commit

Permalink
Apply lint rules
Browse files Browse the repository at this point in the history
That's a big commit, but that's a necessary measures.
Starting with this commit, all project is under mypy and ruff.
Each commit is being checked by pre-commit with all-files option.
  • Loading branch information
koldakov committed Mar 4, 2024
1 parent 187d64a commit 74a5026
Show file tree
Hide file tree
Showing 35 changed files with 358 additions and 337 deletions.
11 changes: 6 additions & 5 deletions alembic/versions/1353be8a56b8_initial_project_structure.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,18 @@
Revises: d413d1284339
Create Date: 2023-12-02 18:33:01.171361
"""
from typing import Sequence, Union
from collections.abc import Sequence

from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import postgresql

from alembic import op

# revision identifiers, used by Alembic.
revision: str = "1353be8a56b8"
down_revision: Union[str, None] = "d413d1284339"
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None
down_revision: str | None = "d413d1284339"
branch_labels: str | Sequence[str] | None = None
depends_on: str | Sequence[str] | None = None


def upgrade() -> None:
Expand Down
10 changes: 5 additions & 5 deletions alembic/versions/1b86ee33d1ba_add_broadcast_number_to_episode.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,17 @@
Revises: c03e060df1b8
Create Date: 2023-12-21 21:57:04.032458
"""
from typing import Sequence, Union
from collections.abc import Sequence

from alembic import op
import sqlalchemy as sa

from alembic import op

# revision identifiers, used by Alembic.
revision: str = "1b86ee33d1ba"
down_revision: Union[str, None] = "c03e060df1b8"
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None
down_revision: str | None = "c03e060df1b8"
branch_labels: str | Sequence[str] | None = None
depends_on: str | Sequence[str] | None = None


def upgrade() -> None:
Expand Down
13 changes: 6 additions & 7 deletions alembic/versions/928d4358646c_add_image_field.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,20 @@
Revises: 1353be8a56b8
Create Date: 2023-12-08 20:58:59.382849
"""
from typing import Sequence, Union
from collections.abc import Sequence

from alembic import op
import sqlalchemy as sa
from fastapi_storages import FileSystemStorage
from fastapi_storages.integrations.sqlalchemy import ImageType
import sqlalchemy as sa

from alembic import op
from app.core import settings


# revision identifiers, used by Alembic.
revision: str = "928d4358646c"
down_revision: Union[str, None] = "1353be8a56b8"
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None
down_revision: str | None = "1353be8a56b8"
branch_labels: str | Sequence[str] | None = None
depends_on: str | Sequence[str] | None = None


def upgrade() -> None:
Expand Down
10 changes: 5 additions & 5 deletions alembic/versions/c03e060df1b8_add_production_code_to_episode.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,17 @@
Revises: 928d4358646c
Create Date: 2023-12-21 20:12:27.108201
"""
from typing import Sequence, Union
from collections.abc import Sequence

from alembic import op
import sqlalchemy as sa

from alembic import op

# revision identifiers, used by Alembic.
revision: str = "c03e060df1b8"
down_revision: Union[str, None] = "928d4358646c"
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None
down_revision: str | None = "928d4358646c"
branch_labels: str | Sequence[str] | None = None
depends_on: str | Sequence[str] | None = None


def upgrade() -> None:
Expand Down
8 changes: 4 additions & 4 deletions alembic/versions/d413d1284339_initial_revision.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@
Revises:
Create Date: 2023-11-25 19:46:49.496715
"""
from typing import Sequence, Union
from collections.abc import Sequence

revision: str = "d413d1284339"
down_revision: Union[str, None] = None
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None
down_revision: str | None = None
branch_labels: str | Sequence[str] | None = None
depends_on: str | Sequence[str] | None = None


def upgrade() -> None:
Expand Down
10 changes: 5 additions & 5 deletions alembic/versions/ee5656c8dc7f_define_user_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,16 @@
Revises: 1b86ee33d1ba
Create Date: 2024-01-21 21:40:59.557432
"""
from typing import Sequence, Union
from collections.abc import Sequence

from alembic import op
import sqlalchemy as sa

from alembic import op

revision: str = "ee5656c8dc7f"
down_revision: Union[str, None] = "1b86ee33d1ba"
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None
down_revision: str | None = "1b86ee33d1ba"
branch_labels: str | Sequence[str] | None = None
depends_on: str | Sequence[str] | None = None


def upgrade() -> None:
Expand Down
5 changes: 2 additions & 3 deletions app/core/settings.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
from pathlib import Path
from urllib.parse import ParseResult, urlparse

from typing import Any
from urllib.parse import ParseResult, urlparse

from pydantic import EmailStr, Field, PostgresDsn
from pydantic.fields import FieldInfo
Expand Down Expand Up @@ -69,7 +68,7 @@ class Settings(BaseSettings):
email: EmailSettings = email_settings

@classmethod
def settings_customise_sources(
def settings_customise_sources( # noqa: PLR0913
cls,
settings_cls: type[BaseSettings],
init_settings: PydanticBaseSettingsSource,
Expand Down
85 changes: 50 additions & 35 deletions app/graph_ql/schemas.py
Original file line number Diff line number Diff line change
@@ -1,34 +1,42 @@
from typing import Any, List
from typing import Any

import strawberry

from app.repositories.models import (
Character as CharacterModel,
)
from app.repositories.models import (
CharacterDoesNotExist,
CharacterGender,
CharacterGenderFilter,
CharacterSpecies,
CharacterSpeciesFilter,
CharacterStatus,
Episode as EpisodeModel,
CharacterStatusFilter,
EpisodeDoesNotExist,
Season as SeasonModel,
SeasonDoesNotExist,
)
from app.repositories.models import (
CharacterGenderFilter,
CharacterSpeciesFilter,
CharacterStatusFilter,
Episode as EpisodeModel,
)
from app.repositories.models import (
Season as SeasonModel,
)
from app.repositories.sessions import get_async_session_ctx
from app.services.base import EpisodeBase as EpisodeBaseSchema
from app.services.characters import Character as CharacterSchema
from app.services.episodes import (
Episode as EpisodeSchema,
)
from app.services.episodes import (
SeasonEpisode as SeasonEpisodeSchema,
)
from app.services.seasons import (
Season as SeasonSchema,
EpisodeSeason as EpisodeSeasonSchema,
)
from app.services.seasons import (
Season as SeasonSchema,
)


class BaseQueryException(Exception):
Expand All @@ -49,11 +57,11 @@ class OffsetViolation(CharacterQueryException):

@strawberry.experimental.pydantic.type(model=CharacterSchema)
class Character:
id: strawberry.auto
id: strawberry.auto # noqa: A003
name: strawberry.auto
gender: strawberry.enum(CharacterGender)
status: strawberry.enum(CharacterStatus)
species: strawberry.enum(CharacterSpecies)
gender: strawberry.enum(CharacterGender) # type: ignore
status: strawberry.enum(CharacterStatus) # type: ignore
species: strawberry.enum(CharacterSpecies) # type: ignore
created_at: strawberry.auto
image: strawberry.auto

Expand All @@ -63,7 +71,7 @@ class PageBase:
limit: int
offset: int
total: int
edges: List[Any]
edges: list[Any]

@staticmethod
def get_schema_class():
Expand All @@ -78,19 +86,16 @@ def from_params(cls, edges, limit: int, offset: int, total: int, /):
schema_class = cls.get_schema_class()
edge_class = cls.get_edge_class()
return cls(
limit=limit,
offset=offset,
total=total,
edges=[
edge_class.from_pydantic(schema_class.model_validate(edge))
for edge in edges
],
limit=limit, # type: ignore
offset=offset, # type: ignore
total=total, # type: ignore
edges=[edge_class.from_pydantic(schema_class.model_validate(edge)) for edge in edges], # type: ignore
)


@strawberry.type
class Characters(PageBase):
edges: List[Character]
edges: list[Character]

@staticmethod
def get_schema_class():
Expand Down Expand Up @@ -122,15 +127,15 @@ class Episode(EpisodeBase):

@strawberry.experimental.pydantic.type(model=EpisodeSeasonSchema)
class EpisodeSeason(EpisodeBase):
id: strawberry.auto
id: strawberry.auto # noqa: A003
name: strawberry.auto
broadcast_number: strawberry.auto
production_code: strawberry.auto


@strawberry.type
class Episodes(PageBase):
edges: List[Episode]
edges: list[Episode]

@staticmethod
def get_schema_class():
Expand All @@ -143,20 +148,18 @@ def get_edge_class():

@strawberry.experimental.pydantic.type(model=SeasonSchema)
class Season:
id: strawberry.auto
episodes: List[EpisodeSeason]
id: strawberry.auto # noqa: A003
episodes: list[EpisodeSeason]


def validate_limit(limit: int, min_: int, max_: int, /) -> None:
if not min_ <= limit <= max_:
raise LimitViolation(
f"Limit can be more than {min_} and less than {max_}"
) from None
raise LimitViolation(f"Limit can be more than {min_} and less than {max_}") from None


@strawberry.type
class Seasons(PageBase):
edges: List[Season]
edges: list[Season]

@staticmethod
def get_schema_class():
Expand All @@ -179,18 +182,22 @@ async def character(self, character_id: int) -> Character | None:
)
except CharacterDoesNotExist:
return None
return Character.from_pydantic(CharacterSchema.model_validate(character))
return Character.from_pydantic(CharacterSchema.model_validate(character)) # type: ignore

@strawberry.field()
async def characters(
async def characters( # noqa: PLR0913
self,
*,
limit: int | None = 50,
offset: int | None = 0,
gender: strawberry.enum(CharacterGenderFilter) | None = None,
status: strawberry.enum(CharacterStatusFilter) | None = None,
species: strawberry.enum(CharacterSpeciesFilter) | None = None,
gender: strawberry.enum(CharacterGenderFilter) | None = None, # type: ignore
status: strawberry.enum(CharacterStatusFilter) | None = None, # type: ignore
species: strawberry.enum(CharacterSpeciesFilter) | None = None, # type: ignore
) -> Characters:
if limit is None:
limit = 50
if offset is None:
offset = 0
# For some reason self does not work under strawberry decorator,
# so class attrs can't be used. Please find another way.
_min_l: int = 1
Expand Down Expand Up @@ -221,7 +228,7 @@ async def episode(self, episode_id: int) -> Episode | None:
)
except EpisodeDoesNotExist:
return None
return Episode.from_pydantic(EpisodeSchema.model_validate(episode))
return Episode.from_pydantic(EpisodeSchema.model_validate(episode)) # type: ignore

@strawberry.field()
async def episodes(
Expand All @@ -230,6 +237,10 @@ async def episodes(
limit: int | None = 50,
offset: int | None = 0,
) -> Episodes:
if limit is None:
limit = 50
if offset is None:
offset = 0
validate_limit(limit, 1, 50)
async with get_async_session_ctx() as session:
total: int = await CharacterModel.count(session)
Expand All @@ -249,7 +260,7 @@ async def season(self, season_id: int) -> Season | None:
season: SeasonModel = await SeasonModel.get(session, season_id)
except SeasonDoesNotExist:
return None
return Season.from_pydantic(SeasonSchema.model_validate(season))
return Season.from_pydantic(SeasonSchema.model_validate(season)) # type: ignore

@strawberry.field()
async def seasons(
Expand All @@ -258,6 +269,10 @@ async def seasons(
limit: int | None = 50,
offset: int | None = 0,
) -> Seasons:
if limit is None:
limit = 50
if offset is None:
offset = 0
validate_limit(limit, 1, 50)
async with get_async_session_ctx() as session:
total: int = await SeasonModel.count(session)
Expand Down
12 changes: 3 additions & 9 deletions app/graph_ql/tests/test_schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,13 @@


class TestLimitValidation:
def test_validate_limit_should_raise_limit_violation_when_limit_less_then_min_allowed_value(
self
):
def test_validate_limit_should_raise_limit_violation_when_limit_less_then_min_allowed_value(self):
with pytest.raises(LimitViolation):
validate_limit(0, 1, 3)

def test_validate_limit_should_raise_limit_violation_when_limit_more_then_max_allowed_value(
self
):
def test_validate_limit_should_raise_limit_violation_when_limit_more_then_max_allowed_value(self):
with pytest.raises(LimitViolation):
validate_limit(4, 1, 3)

def test_validate_limit_should_return_none_when_limit_more_then_min_value_and_less_then_max_value(
self
):
def test_validate_limit_should_return_none_when_limit_more_then_min_value_and_less_then_max_value(self):
assert validate_limit(2, 1, 3) is None
Loading

0 comments on commit 74a5026

Please sign in to comment.