[+] improve rest api for summarizer

1. refactor out dependency logic into dependencies;
  2. fix input schema for summarizer;
  3. fix early app initialization before uvicorn sets logging;
  4. add manual basicConfig call;
  5. update default host and port for fastapi server;
  6. add pyright watch mode;
This commit is contained in:
Siarhei Siniak 2025-07-25 12:05:20 +03:00
parent e82586e08c
commit 5568c458c2
13 changed files with 69 additions and 22 deletions

@ -35,11 +35,18 @@ venv:
-p $(ENV_PATH) \ -p $(ENV_PATH) \
-r requirements.txt -r requirements.txt
PYRIGHT_ARGS ?= --threads 3
pyright: pyright:
$(ENV_PATH)/bin/python3 -m pyright \ $(ENV_PATH)/bin/python3 -m pyright \
-p pyproject.toml \ -p pyproject.toml \
--threads 3 \ --pythonpath $(PYTHON_PATH) \
--pythonpath $(PYTHON_PATH) $(PYRIGHT_ARGS)
pyright_watch:
make \
PYRIGHT_ARGS=-w \
pyright
ruff_check: ruff_check:
$(ENV_PATH)/bin/python3 -m ruff \ $(ENV_PATH)/bin/python3 -m ruff \

@ -41,11 +41,15 @@ services:
<<: *web <<: *web
image: online.fxreader.pr34.test_task_2025_07_17_v1:dev image: online.fxreader.pr34.test_task_2025_07_17_v1:dev
env_file: .env/summarizer.patched.env env_file: .env/summarizer.patched.env
ports:
- 127.0.0.1:9003:80
deploy: deploy:
resources: resources:
limits: limits:
cpus: '4' cpus: '4'
memory: 3068M memory: 3068M
volumes:
- ~/.cache/huggingface/hub:/root/.cache/huggingface/hub:ro
postgresql: postgresql:
image: docker.io/postgres:14.18-bookworm@sha256:c0aab7962b283cf24a0defa5d0d59777f5045a7be59905f21ba81a20b1a110c9 image: docker.io/postgres:14.18-bookworm@sha256:c0aab7962b283cf24a0defa5d0d59777f5045a7be59905f21ba81a20b1a110c9

@ -45,7 +45,7 @@ RUN \
--break-system-packages \ --break-system-packages \
--no-index \ --no-index \
-f releases/whl \ -f releases/whl \
'online.fxreader.pr34.test_task_2025_07_17_v2==0.1.5' 'online.fxreader.pr34.test_task_2025_07_17_v2==0.1.8'
ENTRYPOINT ["tini", "--"] ENTRYPOINT ["tini", "--"]
CMD [ \ CMD [ \

@ -1 +1,3 @@
APPS=["online.fxreader.pr34.test_task_2025_07_17_v2.transform.app:get_app_router:"] APPS=["online.fxreader.pr34.test_task_2025_07_17_v2.transform.app:get_app_router:"]
UVICORN_HOST=0.0.0.0
UVICORN_PORT=80

@ -9,7 +9,7 @@ classifiers = [
] ]
name = 'online.fxreader.pr34.test_task_2025_07_17_v2' name = 'online.fxreader.pr34.test_task_2025_07_17_v2'
version = '0.1.5' version = '0.1.8'
dependencies = [ dependencies = [
'alembic', 'alembic',

@ -54,7 +54,9 @@ def create_app() -> fastapi.FastAPI:
app = fastapi.FastAPI() app = fastapi.FastAPI()
logger.info(dict(msg='started loading apps'))
for app_config in APISettings.singleton().apps: for app_config in APISettings.singleton().apps:
logger.info(dict(msg='start loading app = {}'.format(app_config)))
app_module, app_method, app_prefix = app_config.split(':') app_module, app_method, app_prefix = app_config.split(':')
app_router = cast( app_router = cast(
@ -72,6 +74,8 @@ def create_app() -> fastapi.FastAPI:
prefix=app_prefix, prefix=app_prefix,
# prefix='/', # prefix='/',
) )
logger.info(dict(msg='done loading app = {}'.format(app_config)))
logger.info(dict(msg='done loading apps'))
# app.websocket( # app.websocket(
# '/tickers/', # '/tickers/',
@ -86,10 +90,13 @@ def create_app() -> fastapi.FastAPI:
def run(args: list[str]): def run(args: list[str]):
logging.basicConfig(level=logging.INFO)
log_config = copy.deepcopy(uvicorn.config.LOGGING_CONFIG) log_config = copy.deepcopy(uvicorn.config.LOGGING_CONFIG)
uvicorn.run( uvicorn.run(
create_app(), # create_app(),
create_app,
host=APISettings.singleton().uvicorn_host, host=APISettings.singleton().uvicorn_host,
port=APISettings.singleton().uvicorn_port, port=APISettings.singleton().uvicorn_port,
loop='uvloop', loop='uvloop',

@ -4,21 +4,11 @@ import fastapi
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
from . import views from . import views
from .worker import Summarizer
from .dependencies import summarizer_dependency
from typing import (Annotated,) from typing import (Annotated,)
async def create_summarizer(
) -> Summarizer:
return Summarizer()
async def summarizer_dependency(
summarizer: Annotated[
Summarizer, fastapi.Depends(create_summarizer)
]
) -> None:
pass
def get_app_router() -> fastapi.APIRouter: def get_app_router() -> fastapi.APIRouter:
logger.info(dict(msg='started')) logger.info(dict(msg='started'))
router = fastapi.APIRouter( router = fastapi.APIRouter(

@ -0,0 +1,19 @@
import logging
import fastapi
logger = logging.getLogger(__name__)
from .worker import Summarizer
from typing import (Annotated,)
async def create_summarizer(
) -> Summarizer:
return Summarizer()
async def summarizer_dependency(
summarizer: Annotated[
Summarizer, fastapi.Depends(create_summarizer)
]
) -> None:
pass

@ -2,3 +2,6 @@ import pydantic
class Summary(pydantic.BaseModel): class Summary(pydantic.BaseModel):
data: list[str] data: list[str]
class SummaryRequest(pydantic.BaseModel):
data: list[str]

@ -3,19 +3,25 @@ import fastapi
from typing import (Annotated, Any,) from typing import (Annotated, Any,)
from . import schema from . import schema
from .worker import Summarizer from .worker import Summarizer
from .dependencies import create_summarizer
router = fastapi.APIRouter() router = fastapi.APIRouter()
@router.post('summarize') @router.post(
'/summarize',
# response_model=schema.Summary,
)
async def summarize( async def summarize(
data: Annotated[ request: Annotated[
list[str], schema.SummaryRequest,
fastapi.Body(), fastapi.Body(),
], ],
summarizer: Summarizer, summarizer: Annotated[
Summarizer, fastapi.Depends(create_summarizer)
]
) -> schema.Summary: ) -> schema.Summary:
return schema.Summary( return schema.Summary(
data=summarizer.summarize( data=summarizer.summarize(
data, request.data,
) )
) )