mirror of
https://github.com/ijaric/voice_assistant.git
synced 2025-12-17 12:26:17 +00:00
Review fix
This commit is contained in:
0
src/fastapi_app/lib/__init__.py
Normal file
0
src/fastapi_app/lib/__init__.py
Normal file
0
src/fastapi_app/lib/api/__init__.py
Normal file
0
src/fastapi_app/lib/api/__init__.py
Normal file
0
src/fastapi_app/lib/api/handlers/__init__.py
Normal file
0
src/fastapi_app/lib/api/handlers/__init__.py
Normal file
0
src/fastapi_app/lib/api/models/__init__.py
Normal file
0
src/fastapi_app/lib/api/models/__init__.py
Normal file
25
src/fastapi_app/lib/api/models/mixins.py
Normal file
25
src/fastapi_app/lib/api/models/mixins.py
Normal file
@@ -0,0 +1,25 @@
|
||||
import uuid
|
||||
|
||||
import sqlalchemy
|
||||
from sqlalchemy.dialects.postgresql import UUID
|
||||
from sqlalchemy.ext.declarative import declared_attr
|
||||
|
||||
|
||||
class BaseMixin:
|
||||
@declared_attr
|
||||
def id(cls):
|
||||
return sqlalchemy.Column(
|
||||
UUID(as_uuid=True),
|
||||
primary_key=True,
|
||||
default=uuid.uuid4,
|
||||
unique=True,
|
||||
nullable=False,
|
||||
)
|
||||
|
||||
@declared_attr
|
||||
def created_at(cls):
|
||||
return sqlalchemy.Column(sqlalchemy.DateTime, server_default=sqlalchemy.sql.func.now())
|
||||
|
||||
@declared_attr
|
||||
def updated_at(cls):
|
||||
return sqlalchemy.Column(sqlalchemy.DateTime, server_default=sqlalchemy.sql.func.now())
|
||||
0
src/fastapi_app/lib/api/schemas/__init__.py
Normal file
0
src/fastapi_app/lib/api/schemas/__init__.py
Normal file
8
src/fastapi_app/lib/api/schemas/entity.py
Normal file
8
src/fastapi_app/lib/api/schemas/entity.py
Normal file
@@ -0,0 +1,8 @@
|
||||
import uuid
|
||||
|
||||
import pydantic
|
||||
|
||||
|
||||
class Token(pydantic.BaseModel):
|
||||
sub: uuid.UUID
|
||||
exp: int | None = None
|
||||
0
src/fastapi_app/lib/api/services/__init__.py
Normal file
0
src/fastapi_app/lib/api/services/__init__.py
Normal file
27
src/fastapi_app/lib/api/services/token.py
Normal file
27
src/fastapi_app/lib/api/services/token.py
Normal file
@@ -0,0 +1,27 @@
|
||||
import fastapi
|
||||
|
||||
from jose import JWTError, jwt
|
||||
from pydantic import ValidationError
|
||||
|
||||
from lib.api import schemas as app_schemas
|
||||
from lib.app import settings as app_settings
|
||||
|
||||
app = fastapi.FastAPI()
|
||||
settings = app_settings.get_settings()
|
||||
|
||||
security = fastapi.security.HTTPBearer()
|
||||
|
||||
|
||||
def get_token_data(
|
||||
authorization: fastapi.security.HTTPAuthorizationCredentials = fastapi.Security(security),
|
||||
) -> app_schemas.entity.Token:
|
||||
token = authorization.credentials
|
||||
try:
|
||||
secret_key = settings.jwt_secret_key
|
||||
payload = jwt.decode(token, secret_key, algorithms=["HS256"])
|
||||
return app_schemas.entity.Token(**payload)
|
||||
except (JWTError, ValidationError):
|
||||
raise fastapi.HTTPException(
|
||||
status_code=fastapi.status.HTTP_401_UNAUTHORIZED,
|
||||
detail="Could not validate credentials",
|
||||
)
|
||||
0
src/fastapi_app/lib/app/__init__.py
Normal file
0
src/fastapi_app/lib/app/__init__.py
Normal file
41
src/fastapi_app/lib/app/app.py
Normal file
41
src/fastapi_app/lib/app/app.py
Normal file
@@ -0,0 +1,41 @@
|
||||
import logging
|
||||
import logging.config as logging_config
|
||||
|
||||
import lib.api.handlers as admin_api_handlers
|
||||
|
||||
import fastapi
|
||||
|
||||
from .logger import LOGGING
|
||||
from .settings import get_settings
|
||||
|
||||
logging_config.dictConfig(LOGGING)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class Application:
|
||||
def __init__(self) -> None:
|
||||
self.settings = get_settings()
|
||||
self.logger = logging.getLogger(__name__)
|
||||
self.producer = None
|
||||
|
||||
def create_app(self) -> fastapi.FastAPI:
|
||||
app = fastapi.FastAPI(
|
||||
title="FastAPI",
|
||||
version="0.1.0",
|
||||
docs_url="/api/openapi",
|
||||
openapi_url="/api/openapi.json",
|
||||
default_response_class=fastapi.responses.ORJSONResponse,
|
||||
)
|
||||
|
||||
# app.include_router(admin_api_handlers.user_router, prefix="/api/v1/users", tags=["users"])
|
||||
# app.include_router(admin_api_handlers.movie_router, prefix="/api/v1/movies", tags=["movies"])
|
||||
|
||||
@app.on_event("startup")
|
||||
async def startup_event():
|
||||
self.logger.info("Starting server")
|
||||
|
||||
@app.on_event("shutdown")
|
||||
async def shutdown_event():
|
||||
self.logger.info("Shutting down server")
|
||||
|
||||
return app
|
||||
69
src/fastapi_app/lib/app/logger.py
Normal file
69
src/fastapi_app/lib/app/logger.py
Normal file
@@ -0,0 +1,69 @@
|
||||
import pydantic_settings
|
||||
|
||||
|
||||
class LoggingSettings(pydantic_settings.BaseSettings):
|
||||
log_format: str = "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
|
||||
log_default_handlers: list[str] = [
|
||||
"console",
|
||||
]
|
||||
|
||||
log_level_handlers: str = "DEBUG"
|
||||
log_level_loggers: str = "INFO"
|
||||
log_level_root: str = "INFO"
|
||||
|
||||
|
||||
log_settings = LoggingSettings()
|
||||
|
||||
|
||||
LOGGING = {
|
||||
"version": 1,
|
||||
"disable_existing_loggers": False,
|
||||
"formatters": {
|
||||
"verbose": {"format": log_settings.log_format},
|
||||
"default": {
|
||||
"()": "uvicorn.logging.DefaultFormatter",
|
||||
"fmt": "%(levelprefix)s %(message)s",
|
||||
"use_colors": None,
|
||||
},
|
||||
"access": {
|
||||
"()": "uvicorn.logging.AccessFormatter",
|
||||
"fmt": "%(levelprefix)s %(client_addr)s - '%(request_line)s' %(status_code)s",
|
||||
},
|
||||
},
|
||||
"handlers": {
|
||||
"console": {
|
||||
"level": log_settings.log_level_handlers,
|
||||
"class": "logging.StreamHandler",
|
||||
"formatter": "verbose",
|
||||
},
|
||||
"default": {
|
||||
"formatter": "default",
|
||||
"class": "logging.StreamHandler",
|
||||
"stream": "ext://sys.stdout",
|
||||
},
|
||||
"access": {
|
||||
"formatter": "access",
|
||||
"class": "logging.StreamHandler",
|
||||
"stream": "ext://sys.stdout",
|
||||
},
|
||||
},
|
||||
"loggers": {
|
||||
"": {
|
||||
"handlers": log_settings.log_default_handlers,
|
||||
"level": log_settings.log_level_loggers,
|
||||
},
|
||||
"uvicorn.error": {
|
||||
"level": log_settings.log_level_loggers,
|
||||
},
|
||||
"uvicorn.access": {
|
||||
"handlers": ["access"],
|
||||
"level": log_settings.log_level_loggers,
|
||||
"propagate": False,
|
||||
},
|
||||
},
|
||||
"root": {
|
||||
"level": log_settings.log_level_root,
|
||||
"formatter": "verbose",
|
||||
"handlers": log_settings.log_default_handlers,
|
||||
},
|
||||
}
|
||||
36
src/fastapi_app/lib/app/settings.py
Normal file
36
src/fastapi_app/lib/app/settings.py
Normal file
@@ -0,0 +1,36 @@
|
||||
import functools
|
||||
|
||||
import pydantic_settings
|
||||
from dotenv import load_dotenv
|
||||
from pydantic import Field
|
||||
|
||||
load_dotenv(".env.dev")
|
||||
|
||||
|
||||
class DbSettings(pydantic_settings.BaseSettings):
|
||||
model_config = pydantic_settings.SettingsConfigDict(env_prefix="db_")
|
||||
|
||||
host: str = "localhost"
|
||||
port: int = 5432
|
||||
user: str
|
||||
password: str
|
||||
name: str
|
||||
|
||||
|
||||
class ApiSettings(pydantic_settings.BaseSettings):
|
||||
model_config = pydantic_settings.SettingsConfigDict(env_prefix="server_")
|
||||
|
||||
host: str = "0.0.0.0"
|
||||
port: int = 8000
|
||||
|
||||
|
||||
class Settings(pydantic_settings.BaseSettings):
|
||||
db: DbSettings = Field(default_factory=DbSettings)
|
||||
api: ApiSettings = Field(default_factory=ApiSettings)
|
||||
|
||||
jwt_secret_key: str
|
||||
|
||||
|
||||
@functools.lru_cache
|
||||
def get_settings() -> Settings:
|
||||
return Settings()
|
||||
0
src/fastapi_app/lib/db/__init__.py
Normal file
0
src/fastapi_app/lib/db/__init__.py
Normal file
3
src/fastapi_app/lib/db/base.py
Normal file
3
src/fastapi_app/lib/db/base.py
Normal file
@@ -0,0 +1,3 @@
|
||||
# from libs.api.models.movies import *
|
||||
# from libs.api.models.notification_templates import *
|
||||
# from libs.api.models.users import *
|
||||
31
src/fastapi_app/lib/db/postgres.py
Normal file
31
src/fastapi_app/lib/db/postgres.py
Normal file
@@ -0,0 +1,31 @@
|
||||
import typing
|
||||
|
||||
from lib.app import settings as app_settings
|
||||
from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker, create_async_engine
|
||||
from sqlalchemy.orm import DeclarativeBase
|
||||
|
||||
settings = app_settings.get_settings()
|
||||
|
||||
# Создаём базовый класс для будущих моделей
|
||||
|
||||
|
||||
class Base(DeclarativeBase):
|
||||
pass
|
||||
|
||||
|
||||
# Создаём движок
|
||||
# Настройки подключения к БД передаём из переменных окружения, которые заранее загружены в файл настроек
|
||||
|
||||
database_dsn = (
|
||||
f"postgresql+asyncpg://{settings.db.user}:{settings.db.password}"
|
||||
f"@{settings.db.host}:{settings.db.port}/{settings.db.name}"
|
||||
)
|
||||
|
||||
engine = create_async_engine(database_dsn, echo=True, future=True)
|
||||
|
||||
async_session = async_sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)
|
||||
|
||||
|
||||
async def get_session() -> typing.AsyncGenerator[AsyncSession, typing.Any]:
|
||||
async with async_session() as session:
|
||||
yield session
|
||||
Reference in New Issue
Block a user