Срез 0 [2.1]: ruff format и правки линтера в коде шаблона, отметка задачи

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
Andrey Epifancev 2026-10-04 02:33:18 +04:00
parent 5a818b4356
commit 55fa7ce25c
11 changed files with 35 additions and 16 deletions

View File

@ -1,4 +1,5 @@
import uvicorn
from src import app, get_settings
if __name__ == "__main__":
@ -9,4 +10,3 @@ if __name__ == "__main__":
port=settings.server.PORT,
lifespan="on",
)

View File

@ -2,6 +2,6 @@ from .app import app
from .core.config import get_settings
__all__ = [
'app',
'get_settings',
]
"app",
"get_settings",
]

View File

@ -5,8 +5,9 @@ headers), обработчики ошибок, `GET /healthcheck` (`uptime`, `ve
Чего здесь пока нет: NATS-воркера и S3-клиента (подключаются в lifespan задачами 5.2/5.3 change slice-0-skeleton),
полей `nats`/`hotfolder` в healthcheck.
"""
from contextlib import asynccontextmanager
from datetime import datetime, timezone
from datetime import UTC, datetime
import smbclient
from fastapi import FastAPI
@ -31,7 +32,7 @@ def _normalize_root_path(value: str) -> str:
def create_app(settings: Settings | None = None) -> FastAPI:
settings = settings or get_settings()
version = settings.VERSION
up_time = datetime.now(timezone.utc)
up_time = datetime.now(UTC)
@asynccontextmanager
async def lifespan(app: FastAPI):

View File

@ -1,5 +1,6 @@
class NotFoundError(Exception):
pass
class CouldntCreateError(Exception):
pass
pass

View File

@ -1,6 +1,7 @@
"""Клиенты инфраструктуры. Каркас: оставлен S3Storage; outbox-паблишер (PollWorker) реализуется в Срезе 0
по docs/context/03-architecture.md (референс — reference-old-arm/api/src/core/clients.py).
"""
from io import BytesIO
from miniopy_async import Minio
@ -10,11 +11,11 @@ class S3Storage:
def __init__(self, client: Minio, bucket_name: str):
self.client = client
self.bucket = bucket_name
async def put_object(self, obj_name, file_data):
try:
stream = BytesIO(file_data)
await self.client.put_object(self.bucket, obj_name, stream, length=len(file_data))
await self.client.put_object(self.bucket, obj_name, stream, length=len(file_data))
except:
raise
@ -23,5 +24,5 @@ class S3Storage:
response = await self.client.get_object(self.bucket, obj_name)
# file_bytes = await response.content.read()
return response
except:
except:
raise

View File

@ -6,6 +6,7 @@
Файл окружения выбирается переменной `ENV_FILE` (по умолчанию `.env`, путь считается от текущего каталога — `api/`);
переменные окружения приоритетнее файла. Настройки читаются при первом вызове `get_settings()`, не при импорте.
"""
import os
from functools import lru_cache
from typing import Literal

View File

@ -5,7 +5,6 @@ import sys
from loguru import logger
# Периодические пробы мониторинга/оркестратора и служебные doc-эндпоинты.
NOISE_PATHS: tuple[str, ...] = (
"/healthcheck",
@ -22,8 +21,20 @@ _NOISE_MARKERS: tuple[str, ...] = ("/static/", "/static-swagger/")
# Расширения статических ассетов (картинки, стили, скрипты, шрифты).
_STATIC_SUFFIXES: tuple[str, ...] = (
".png", ".jpg", ".jpeg", ".gif", ".svg", ".ico", ".webp",
".css", ".js", ".map", ".woff", ".woff2", ".ttf", ".eot",
".png",
".jpg",
".jpeg",
".gif",
".svg",
".ico",
".webp",
".css",
".js",
".map",
".woff",
".woff2",
".ttf",
".eot",
)
@ -73,6 +84,7 @@ def setup_logger(
class InterceptHandler(logging.Handler):
def emit(self, record: logging.LogRecord) -> None:
lvl: str | int
try:
lvl = logger.level(record.levelname).name
except ValueError:

View File

@ -4,6 +4,7 @@
маппинг JSON из S3 в document/osv_entry/financial_statement_*) реализуется в Срезе 0–2 по
docs/context/03-architecture.md. Для референса — reference-old-arm/api/src/core/nats_callback.py.
"""
from loguru import logger
from nats.aio.client import Client as NATS

View File

@ -1,5 +1,6 @@
"""Общие фикстуры. Минимальное окружение local-режима задаётся здесь, чтобы `import src` (он создаёт приложение)
работал без `.env.test` и без инфраструктуры; значения можно переопределить переменными окружения."""
import os
import pytest
@ -20,7 +21,8 @@ for _key, _value in _MINIMAL_ENV.items():
@pytest.fixture(autouse=True)
def _fresh_settings():
"""get_settings кэшируется (lru_cache): сбрасываем кэш до и после каждого теста."""
from src.core.config import get_settings
# Импорт отложен намеренно: `import src` создаёт приложение и требует окружения, заданного выше
from src.core.config import get_settings # noqa: PLC0415
get_settings.cache_clear()
yield

View File

@ -32,7 +32,7 @@
### Task 4: [2.1] `api/pyproject.toml` (ruff, mypy), `requirements-dev.txt` = `-r requirements.txt
- [ ] `api/pyproject.toml` (ruff, mypy), `requirements-dev.txt` = `-r requirements.txt` + ruff, mypy, pytest, pytest-asyncio, pytest-env, httpx, jsonschema; `Makefile`: `venv` (python3.11, без `raisa_*`), `lint`, `test`, `test-integration`, `check`, `check-full`, `up`, `emulator`; проверка: `make venv && make lint` зелёные
- [x] `api/pyproject.toml` (ruff, mypy), `requirements-dev.txt` = `-r requirements.txt` + ruff, mypy, pytest, pytest-asyncio, pytest-env, httpx, jsonschema; `Makefile`: `venv` (python3.11, без `raisa_*`), `lint`, `test`, `test-integration`, `check`, `check-full`, `up`, `emulator`; проверка: `make venv && make lint` зелёные
### Task 5: [2.2] `Dockerfile` (`python

View File

@ -19,7 +19,7 @@
## 2. Инструменты
- [ ] 2.1 `api/pyproject.toml` (ruff, mypy), `requirements-dev.txt` = `-r requirements.txt` + ruff, mypy, pytest,
- [x] 2.1 `api/pyproject.toml` (ruff, mypy), `requirements-dev.txt` = `-r requirements.txt` + ruff, mypy, pytest,
pytest-asyncio, pytest-env, httpx, jsonschema; `Makefile`: `venv` (python3.11, без `raisa_*`), `lint`, `test`,
`test-integration`, `check`, `check-full`, `up`, `emulator`; проверка: `make venv && make lint` зелёные
- [ ] 2.2 `Dockerfile` (`python:3.11-slim`; `CMD python run_server.py`, эмулятор — через `command` в compose),