Migrate to ruff

This commit is contained in:
2023-01-07 23:49:26 +01:00
parent b58b3b4e4c
commit 09130d7905
27 changed files with 605 additions and 348 deletions

View File

@@ -6,15 +6,14 @@ repos:
hooks: hooks:
- id: black - id: black
language_version: python3.11 language_version: python3.11
- repo: https://github.com/pycqa/isort
rev: v5.11.3 - repo: https://github.com/charliermarsh/ruff-pre-commit
rev: 'v0.0.213'
hooks: hooks:
- id: isort - id: ruff
- repo: https://github.com/csachs/pyproject-flake8 args: ["--force-exclude"]
rev: v6.0.0.post1
- repo: https://github.com/crate-ci/typos
rev: v1.13.6
hooks: hooks:
- id: pyproject-flake8 - id: typos
additional_dependencies: [
'-e', 'git+https://github.com/pycqa/pyflakes@b37f91a#egg=pyflakes',
'-e', 'git+https://github.com/pycqa/pycodestyle@1063db8#egg=pycodestyle',
]

View File

@@ -1,6 +1,6 @@
from typing import Optional from typing import Optional
from fastapi import Security, HTTPException, Query, status from fastapi import HTTPException, Query, Security, status
from core.auth import default_security from core.auth import default_security
from core.config import env_config from core.config import env_config

View File

@@ -1,7 +1,7 @@
from datetime import date from datetime import date
from typing import Optional from typing import Optional
from fastapi.params import Query from fastapi import Query
from app.depends import get_allowed_langs from app.depends import get_allowed_langs

View File

@@ -4,7 +4,7 @@ from typing import Optional
import ormar import ormar
from sqlalchemy import text from sqlalchemy import text
from core.db import metadata, database from core.db import database, metadata
class BaseMeta(ormar.ModelMeta): class BaseMeta(ormar.ModelMeta):

View File

@@ -1,8 +1,7 @@
from typing import TypedDict from typing import TypedDict
from app.models import Author from app.models import Author
from app.services.common import TRGMSearchService, MeiliSearchService, GetRandomService from app.services.common import GetRandomService, MeiliSearchService, TRGMSearchService
GET_OBJECT_IDS_QUERY = """ GET_OBJECT_IDS_QUERY = """
SELECT ARRAY( SELECT ARRAY(

View File

@@ -1,14 +1,13 @@
from typing import TypedDict, Optional from typing import Optional, TypedDict
from app.models import Book as BookDB from app.models import Book as BookDB
from app.services.common import ( from app.services.common import (
TRGMSearchService,
MeiliSearchService,
GetRandomService,
BaseFilterService, BaseFilterService,
GetRandomService,
MeiliSearchService,
TRGMSearchService,
) )
GET_OBJECT_IDS_QUERY = """ GET_OBJECT_IDS_QUERY = """
SELECT ARRAY( SELECT ARRAY(
WITH filtered_books AS ( WITH filtered_books AS (

View File

@@ -2,20 +2,19 @@ import abc
import asyncio import asyncio
from concurrent.futures import ThreadPoolExecutor from concurrent.futures import ThreadPoolExecutor
from random import choice from random import choice
from typing import Optional, Generic, TypeVar, TypedDict, Union from typing import Generic, Optional, TypedDict, TypeVar, Union
import meilisearch
from databases import Database from databases import Database
from fastapi_pagination.api import resolve_params from fastapi_pagination.api import resolve_params
from fastapi_pagination.bases import AbstractParams, RawParams from fastapi_pagination.bases import AbstractParams, RawParams
import meilisearch
from ormar import Model, QuerySet from ormar import Model, QuerySet
from redis import asyncio as aioredis from redis import asyncio as aioredis
from sqlalchemy import Table from sqlalchemy import Table
from app.utils.pagination import Page, CustomPage from app.utils.pagination import CustomPage, Page
from core.config import env_config from core.config import env_config
MODEL = TypeVar("MODEL", bound=Model) MODEL = TypeVar("MODEL", bound=Model)
QUERY = TypeVar("QUERY", bound=TypedDict) QUERY = TypeVar("QUERY", bound=TypedDict)

View File

@@ -1,8 +1,7 @@
from typing import TypedDict from typing import TypedDict
from app.models import Sequence from app.models import Sequence
from app.services.common import TRGMSearchService, MeiliSearchService, GetRandomService from app.services.common import GetRandomService, MeiliSearchService, TRGMSearchService
GET_OBJECT_IDS_QUERY = """ GET_OBJECT_IDS_QUERY = """
SELECT ARRAY ( SELECT ARRAY (

View File

@@ -1,6 +1,5 @@
from app.models import Author from app.models import Author
from app.services.common import TRGMSearchService, MeiliSearchService from app.services.common import MeiliSearchService, TRGMSearchService
GET_OBJECT_IDS_QUERY = """ GET_OBJECT_IDS_QUERY = """
SELECT ARRAY( SELECT ARRAY(

View File

@@ -1,4 +1,4 @@
from typing import Protocol, TypeVar, Any, Generic, Sequence, runtime_checkable from typing import Any, Generic, Protocol, Sequence, TypeVar, runtime_checkable
from fastapi_pagination import Page, Params from fastapi_pagination import Page, Params
from fastapi_pagination.bases import AbstractParams from fastapi_pagination.bases import AbstractParams

View File

@@ -8,7 +8,6 @@ from app.views.sequence import sequence_router
from app.views.source import source_router from app.views.source import source_router
from app.views.translation import translation_router from app.views.translation import translation_router
routers = [ routers = [
source_router, source_router,
author_router, author_router,

View File

@@ -1,5 +1,4 @@
from fastapi import APIRouter, Depends, Request, HTTPException, status from fastapi import APIRouter, Depends, HTTPException, Request, status
from fastapi_pagination import Params from fastapi_pagination import Params
from fastapi_pagination.ext.ormar import paginate from fastapi_pagination.ext.ormar import paginate
@@ -13,7 +12,6 @@ from app.services.author import AuthorMeiliSearchService, GetRandomAuthorService
from app.services.translator import TranslatorMeiliSearchService from app.services.translator import TranslatorMeiliSearchService
from app.utils.pagination import CustomPage from app.utils.pagination import CustomPage
author_router = APIRouter( author_router = APIRouter(
prefix="/api/v1/authors", prefix="/api/v1/authors",
tags=["author"], tags=["author"],

View File

@@ -1,13 +1,11 @@
from fastapi import APIRouter, Depends, HTTPException, status from fastapi import APIRouter, Depends, HTTPException, status
from fastapi_pagination import Page, Params
from fastapi_pagination import Params, Page
from fastapi_pagination.ext.ormar import paginate from fastapi_pagination.ext.ormar import paginate
from app.depends import check_token from app.depends import check_token
from app.models import AuthorAnnotation as AuthorAnnotationDB from app.models import AuthorAnnotation as AuthorAnnotationDB
from app.serializers.author_annotation import AuthorAnnotation from app.serializers.author_annotation import AuthorAnnotation
author_annotation_router = APIRouter( author_annotation_router = APIRouter(
prefix="/api/v1/author_annotations", prefix="/api/v1/author_annotations",
tags=["author_annotation"], tags=["author_annotation"],

View File

@@ -1,23 +1,21 @@
from typing import Optional from typing import Optional
from fastapi import APIRouter, Depends, Request, HTTPException, status from fastapi import APIRouter, Depends, HTTPException, Request, status
from fastapi_pagination import Params from fastapi_pagination import Params
from app.depends import check_token, get_allowed_langs from app.depends import check_token, get_allowed_langs
from app.filters.book import get_book_filter from app.filters.book import get_book_filter
from app.models import Book as BookDB from app.models import Book as BookDB
from app.models import BookAnnotation as BookAnnotationDB from app.models import BookAnnotation as BookAnnotationDB
from app.serializers.book import Book, RemoteBook, BookDetail from app.serializers.book import Book, BookDetail, RemoteBook
from app.serializers.book_annotation import BookAnnotation from app.serializers.book_annotation import BookAnnotation
from app.services.book import ( from app.services.book import (
BookMeiliSearchService,
BookFilterService, BookFilterService,
BookMeiliSearchService,
GetRandomBookService, GetRandomBookService,
) )
from app.utils.pagination import CustomPage from app.utils.pagination import CustomPage
book_router = APIRouter( book_router = APIRouter(
prefix="/api/v1/books", prefix="/api/v1/books",
tags=["book"], tags=["book"],

View File

@@ -1,13 +1,11 @@
from fastapi import APIRouter, Depends, HTTPException, status from fastapi import APIRouter, Depends, HTTPException, status
from fastapi_pagination import Page, Params
from fastapi_pagination import Params, Page
from fastapi_pagination.ext.ormar import paginate from fastapi_pagination.ext.ormar import paginate
from app.depends import check_token from app.depends import check_token
from app.models import BookAnnotation as BookAnnotationDB from app.models import BookAnnotation as BookAnnotationDB
from app.serializers.book_annotation import BookAnnotation from app.serializers.book_annotation import BookAnnotation
book_annotation_router = APIRouter( book_annotation_router = APIRouter(
prefix="/api/v1/book_annotations", prefix="/api/v1/book_annotations",
tags=["book_annotation"], tags=["book_annotation"],

View File

@@ -1,5 +1,4 @@
from fastapi import APIRouter, Depends, HTTPException, status, Request from fastapi import APIRouter, Depends, HTTPException, Request, status
from fastapi_pagination import Params from fastapi_pagination import Params
from fastapi_pagination.ext.ormar import paginate from fastapi_pagination.ext.ormar import paginate
@@ -10,7 +9,6 @@ from app.serializers.genre import Genre
from app.services.genre import GenreMeiliSearchService from app.services.genre import GenreMeiliSearchService
from app.utils.pagination import CustomPage from app.utils.pagination import CustomPage
genre_router = APIRouter( genre_router = APIRouter(
prefix="/api/v1/genres", tags=["genres"], dependencies=[Depends(check_token)] prefix="/api/v1/genres", tags=["genres"], dependencies=[Depends(check_token)]
) )
@@ -31,7 +29,8 @@ async def get_genres(genre_filter: dict = Depends(get_genre_filter)):
@genre_router.get("/metas", response_model=list[str]) @genre_router.get("/metas", response_model=list[str])
async def get_genre_metas(): async def get_genre_metas():
genres = await GenreDB.objects.fields("meta").values_list(flatten=True) genres = await GenreDB.objects.fields("meta").values_list(flatten=True)
return sorted(list(set(genres))) genres.sort()
return list(set(genres))
@genre_router.get("/{id}", response_model=Genre) @genre_router.get("/{id}", response_model=Genre)

View File

@@ -1,6 +1,5 @@
from fastapi import APIRouter from fastapi import APIRouter
healtcheck_router = APIRouter(tags=["healthcheck"]) healtcheck_router = APIRouter(tags=["healthcheck"])

View File

@@ -1,5 +1,4 @@
from fastapi import APIRouter, Depends, Request from fastapi import APIRouter, Depends, Request
from fastapi_pagination import Params from fastapi_pagination import Params
from fastapi_pagination.ext.ormar import paginate from fastapi_pagination.ext.ormar import paginate
@@ -8,10 +7,9 @@ from app.models import Book as BookDB
from app.models import Sequence as SequenceDB from app.models import Sequence as SequenceDB
from app.serializers.sequence import Book as SequenceBook from app.serializers.sequence import Book as SequenceBook
from app.serializers.sequence import Sequence from app.serializers.sequence import Sequence
from app.services.sequence import SequenceMeiliSearchService, GetRandomSequenceService from app.services.sequence import GetRandomSequenceService, SequenceMeiliSearchService
from app.utils.pagination import CustomPage from app.utils.pagination import CustomPage
sequence_router = APIRouter( sequence_router = APIRouter(
prefix="/api/v1/sequences", prefix="/api/v1/sequences",
tags=["sequence"], tags=["sequence"],

View File

@@ -1,13 +1,11 @@
from fastapi import APIRouter, Depends from fastapi import APIRouter, Depends
from fastapi_pagination import Page, Params
from fastapi_pagination import Params, Page
from fastapi_pagination.ext.ormar import paginate from fastapi_pagination.ext.ormar import paginate
from app.depends import check_token from app.depends import check_token
from app.models import Source as SourceDB from app.models import Source as SourceDB
from app.serializers.source import Source from app.serializers.source import Source
source_router = APIRouter( source_router = APIRouter(
prefix="/api/v1/sources", prefix="/api/v1/sources",
tags=["source"], tags=["source"],

View File

@@ -1,5 +1,4 @@
from fastapi import APIRouter, Depends from fastapi import APIRouter, Depends
from fastapi_pagination import Params from fastapi_pagination import Params
from fastapi_pagination.ext.ormar import paginate from fastapi_pagination.ext.ormar import paginate
@@ -8,7 +7,6 @@ from app.models import Translation as TranslationDB
from app.serializers.translation import Translation from app.serializers.translation import Translation
from app.utils.pagination import CustomPage from app.utils.pagination import CustomPage
translation_router = APIRouter( translation_router = APIRouter(
prefix="/api/v1/translation", prefix="/api/v1/translation",
tags=["translation"], tags=["translation"],

View File

@@ -1,16 +1,14 @@
import sentry_sdk
from fastapi import FastAPI from fastapi import FastAPI
from fastapi.responses import ORJSONResponse from fastapi.responses import ORJSONResponse
from fastapi_pagination import add_pagination from fastapi_pagination import add_pagination
from prometheus_fastapi_instrumentator import Instrumentator from prometheus_fastapi_instrumentator import Instrumentator
from redis import asyncio as aioredis from redis import asyncio as aioredis
import sentry_sdk
from app.views import routers from app.views import routers
from core.config import env_config from core.config import env_config
from core.db import database from core.db import database
sentry_sdk.init( sentry_sdk.init(
env_config.SENTRY_SDN, env_config.SENTRY_SDN,
) )

View File

@@ -1,4 +1,3 @@
from fastapi.security import APIKeyHeader from fastapi.security import APIKeyHeader
default_security = APIKeyHeader(name="Authorization") default_security = APIKeyHeader(name="Authorization")

View File

@@ -5,7 +5,6 @@ from sqlalchemy import MetaData
from core.config import env_config from core.config import env_config
DATABASE_URL = ( DATABASE_URL = (
f"postgresql://{env_config.POSTGRES_USER}:{quote(env_config.POSTGRES_PASSWORD)}@" f"postgresql://{env_config.POSTGRES_USER}:{quote(env_config.POSTGRES_PASSWORD)}@"
f"{env_config.POSTGRES_HOST}:{env_config.POSTGRES_PORT}/{env_config.POSTGRES_DB}" f"{env_config.POSTGRES_HOST}:{env_config.POSTGRES_PORT}/{env_config.POSTGRES_DB}"

View File

@@ -1,4 +1,3 @@
from core.app import start_app from core.app import start_app
app = start_app() app = start_app()

797
poetry.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -5,10 +5,10 @@ description = ""
authors = ["Kurbanov Bulat <kurbanovbul@gmail.com>"] authors = ["Kurbanov Bulat <kurbanovbul@gmail.com>"]
[tool.poetry.dependencies] [tool.poetry.dependencies]
python = "^3.9" python = "^3.11"
fastapi = "^0.88.0" fastapi = "^0.89.0"
pydantic = "^1.10.2" pydantic = "^1.10.2"
uvicorn = {extras = ["standart"], version = "^0.20.0"} uvicorn = {extras = ["standard"], version = "^0.20.0"}
ormar = {extras = ["postgresql"], version = "^0.12.0"} ormar = {extras = ["postgresql"], version = "^0.12.0"}
alembic = "^1.9.1" alembic = "^1.9.1"
fastapi-pagination = {extras = ["ormar"], version = "^0.11.1"} fastapi-pagination = {extras = ["ormar"], version = "^0.11.1"}
@@ -21,8 +21,8 @@ gunicorn = "^20.1.0"
sentry-sdk = "^1.12.1" sentry-sdk = "^1.12.1"
redis = {extras = ["hiredis"], version = "^4.4.0"} redis = {extras = ["hiredis"], version = "^4.4.0"}
[tool.poetry.dev-dependencies] [tool.poetry.group.dev.dependencies]
pytest = "^7.1.2" pre-commit = "^2.21.0"
[build-system] [build-system]
requires = ["poetry-core>=1.0.0"] requires = ["poetry-core>=1.0.0"]
@@ -39,31 +39,38 @@ exclude = '''
)/ )/
''' '''
[tool.flake8] [tool.ruff]
ignore = [ fix = true
# Whitespace before ':' ( https://www.flake8rules.com/rules/E203.html ) target-version = "py311"
"E203" src = ["fastapi_book_server"]
] line-length=88
max-line-length=88 ignore = []
max-complexity = 15 select = ["B", "C", "E", "F", "W", "B9", "I001"]
select = "B,C,E,F,W,T4,B9"
exclude = [ exclude = [
# No need to traverse our git directory # No need to traverse our git directory
".git", ".git",
# There's no value in checking cache directories # There's no value in checking cache directories
"__pycache__", "__pycache__",
# The conf file is mostly autogenerated, ignore it # The conf file is mostly autogenerated, ignore it
"fastapi_book_server/app/alembic/*", "fastapi_book_server/app/alembic",
# The old directory contains Flake8 2.0
] ]
[tool.isort] [tool.ruff.flake8-bugbear]
profile = "black" extend-immutable-calls = ["fastapi.File", "fastapi.Form", "fastapi.Security", "fastapi.Query", "fastapi.Depends"]
only_sections = true
force_sort_within_sections = true [tool.ruff.mccabe]
lines_after_imports = 2 max-complexity = 15
lexicographical = true
sections = ["FUTURE", "STDLIB", "BASEFRAMEWORK", "FRAMEWORKEXT", "THIRDPARTY", "FIRSTPARTY", "LOCALFOLDER"] [tool.ruff.isort]
known_baseframework = ["fastapi",] known-first-party = ["core", "app"]
known_frameworkext = ["starlette",]
src_paths = ["fastapi_book_server"] # only_sections = true
# force_sort_within_sections = true
# lines_after_imports = 2
# lexicographical = true
# sections = ["FUTURE", "STDLIB", "BASEFRAMEWORK", "FRAMEWORKEXT", "THIRDPARTY", "FIRSTPARTY", "LOCALFOLDER"]
# known_baseframework = ["fastapi",]
# known_frameworkext = ["starlette",]
[tool.ruff.pyupgrade]
keep-runtime-typing = true

View File

@@ -1,6 +1,5 @@
import httpx import httpx
response = httpx.get( response = httpx.get(
"http://localhost:8080/healthcheck", "http://localhost:8080/healthcheck",
) )