Migrate to ruff

This commit is contained in:
2023-01-07 23:57:48 +01:00
parent f9d701ec3b
commit 1f18897dc3
16 changed files with 1136 additions and 723 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',
]

1730
poetry.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -5,16 +5,16 @@ 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"
httpx = "^0.23.1" httpx = "^0.23.3"
alembic = "^1.9.1" alembic = "^1.9.1"
uvicorn = {extras = ["standart"], version = "^0.20.0"} uvicorn = {extras = ["standard"], version = "^0.20.0"}
arq = "^0.25.0" arq = "^0.25.0"
prometheus-fastapi-instrumentator = "^5.9.1" prometheus-fastapi-instrumentator = "^5.9.1"
uvloop = "^0.17.0" uvloop = "^0.17.0"
gunicorn = "^20.1.0" gunicorn = "^20.1.0"
orjson = "^3.8.3" orjson = "^3.8.4"
sentry-sdk = "^1.12.1" sentry-sdk = "^1.12.1"
ormar = {extras = ["postgresql"], version = "^0.12.0"} ormar = {extras = ["postgresql"], version = "^0.12.0"}
greenlet = "^2.0.1" greenlet = "^2.0.1"
@@ -22,7 +22,8 @@ pydantic = "1.10.2"
redis = {extras = ["hiredis"], version = "^4.4.0"} redis = {extras = ["hiredis"], version = "^4.4.0"}
msgpack = "^1.0.4" msgpack = "^1.0.4"
[tool.poetry.dev-dependencies] [tool.poetry.group.dev.dependencies]
pre-commit = "^2.21.0"
[build-system] [build-system]
requires = ["poetry-core>=1.0.0"] requires = ["poetry-core>=1.0.0"]
@@ -39,31 +40,38 @@ exclude = '''
)/ )/
''' '''
[tool.flake8] [tool.ruff]
ignore = [ fix = true
# Whitespace before ':' ( https://www.flake8rules.com/rules/E203.html ) target-version = "py311"
"E203" src = ["app"]
] 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
"src/app/alembic/*", "src/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"]
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 = ["src"] # 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("http://localhost:8080/healthcheck") response = httpx.get("http://localhost:8080/healthcheck")
print(f"HEALTHCHECK STATUS: {response.status_code}") print(f"HEALTHCHECK STATUS: {response.status_code}")
exit(0 if response.status_code == 200 else 1) exit(0 if response.status_code == 200 else 1)

View File

@@ -1,4 +1,4 @@
from fastapi import Security, HTTPException, status from fastapi import HTTPException, 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,6 +1,6 @@
import ormar import ormar
from core.db import metadata, database from core.db import database, metadata
class BaseMeta(ormar.ModelMeta): class BaseMeta(ormar.ModelMeta):

View File

@@ -1,15 +1,14 @@
import collections import collections
from datetime import timedelta
import logging import logging
import random import random
from datetime import timedelta
from tempfile import SpooledTemporaryFile from tempfile import SpooledTemporaryFile
from typing import Optional, cast from typing import Optional, cast
from fastapi import UploadFile import httpx
from arq.connections import ArqRedis from arq.connections import ArqRedis
from arq.worker import Retry from arq.worker import Retry
import httpx from fastapi import UploadFile
from redis import asyncio as aioredis from redis import asyncio as aioredis
from redis.exceptions import LockError from redis.exceptions import LockError
@@ -17,8 +16,7 @@ from app.models import CachedFile
from app.services.caption_getter import get_caption from app.services.caption_getter import get_caption
from app.services.downloader import download from app.services.downloader import download
from app.services.files_client import upload_file from app.services.files_client import upload_file
from app.services.library_client import get_books, get_book, Book from app.services.library_client import Book, get_book, get_books
logger = logging.getLogger("telegram_channel_files_manager") logger = logging.getLogger("telegram_channel_files_manager")
@@ -61,7 +59,7 @@ async def check_books(ctx: dict, *args, **kwargs) -> None: # NOSONAR
try: try:
books_page = await get_books(1, PAGE_SIZE) books_page = await get_books(1, PAGE_SIZE)
except httpx.ConnectError: except httpx.ConnectError:
raise Retry(defer=15) raise Retry(defer=15) # noqa: B904
for i, page_number in enumerate(range(books_page.total_pages, 0, -1)): for i, page_number in enumerate(range(books_page.total_pages, 0, -1)):
await arq_pool.enqueue_job( await arq_pool.enqueue_job(
@@ -143,7 +141,9 @@ async def cache_file_by_book_id(
if by_request: if by_request:
return result return result
except LockError: except LockError:
raise Retry(defer=timedelta(minutes=15).seconds * random.random()) raise Retry( # noqa: B904
defer=timedelta(minutes=15).seconds * random.random()
)
except Retry as e: except Retry as e:
if by_request: if by_request:
return None return None

View File

@@ -1,12 +1,11 @@
from datetime import date from datetime import date
from typing import Generic, TypeVar, Optional from typing import Generic, Optional, TypeVar
import httpx import httpx
from pydantic import BaseModel from pydantic import BaseModel
from core.config import env_config from core.config import env_config
T = TypeVar("T") T = TypeVar("T")

View File

@@ -1,12 +1,10 @@
import asyncio import asyncio
import base64 import base64
from fastapi import APIRouter, Depends, HTTPException, status, Request
from fastapi.responses import StreamingResponse
from starlette.background import BackgroundTask
from arq.connections import ArqRedis from arq.connections import ArqRedis
from fastapi import APIRouter, Depends, HTTPException, Request, status
from fastapi.responses import StreamingResponse
from starlette.background import BackgroundTask
from app.depends import check_token from app.depends import check_token
from app.models import CachedFile as CachedFileDB from app.models import CachedFile as CachedFileDB
@@ -17,7 +15,6 @@ from app.services.downloader import get_filename
from app.services.files_client import download_file as download_file_from_cache from app.services.files_client import download_file as download_file_from_cache
from app.services.library_client import get_book from app.services.library_client import get_book
router = APIRouter( router = APIRouter(
prefix="/api/v1", tags=["files"], dependencies=[Depends(check_token)] prefix="/api/v1", tags=["files"], dependencies=[Depends(check_token)]
) )

View File

@@ -1,13 +1,12 @@
from fastapi import FastAPI from fastapi import FastAPI
from fastapi.responses import ORJSONResponse from fastapi.responses import ORJSONResponse
from prometheus_fastapi_instrumentator import Instrumentator from prometheus_fastapi_instrumentator import Instrumentator
from app.views import router, healthcheck_router import core.sentry # noqa: F401
from app.views import healthcheck_router, router
from core.arq_pool import get_arq_pool from core.arq_pool import get_arq_pool
from core.db import database from core.db import database
from core.redis_client import get_client from core.redis_client import get_client
import core.sentry # noqa: F401
def start_app() -> FastAPI: def start_app() -> FastAPI:

View File

@@ -1,5 +1,5 @@
from arq.connections import create_pool, RedisSettings, ArqRedis
import msgpack import msgpack
from arq.connections import ArqRedis, RedisSettings, create_pool
from core.config import env_config from core.config import env_config

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

@@ -2,7 +2,6 @@ import sentry_sdk
from core.config import env_config from core.config import env_config
sentry_sdk.init( sentry_sdk.init(
env_config.SENTRY_DSN, env_config.SENTRY_DSN,
) )

View File

@@ -1,14 +1,14 @@
import msgpack import msgpack
import core.sentry # noqa: F401
from app.services.cache_updater import ( from app.services.cache_updater import (
check_books,
cache_file_by_book_id, cache_file_by_book_id,
check_books,
check_books_page, check_books_page,
) )
from core.arq_pool import get_redis_settings, get_arq_pool from core.arq_pool import get_arq_pool, get_redis_settings
from core.db import database from core.db import database
from core.redis_client import get_client from core.redis_client import get_client
import core.sentry # noqa: F401
async def startup(ctx): async def startup(ctx):

View File

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