1
0
mirror of https://github.com/ijaric/voice_assistant.git synced 2025-07-12 22:43:28 +00:00

feat: postgres async session maker

This commit is contained in:
Artem Litvinov 2023-09-27 19:44:48 +01:00
parent 5ddcfe32ad
commit a6fac4a95b
12 changed files with 163 additions and 47 deletions

View File

@ -1,3 +1,4 @@
POSTGRES_PROTOCOL=postgresql+asyncpg
POSTGRES_HOST=db POSTGRES_HOST=db
POSTGRES_PORT=5432 POSTGRES_PORT=5432
POSTGRES_USER=user POSTGRES_USER=user

View File

@ -1,19 +1,27 @@
import logging import logging
import fastapi import fastapi
import sqlalchemy
import sqlalchemy.ext.asyncio as sa_asyncio
import lib.app.settings as app_settings import lib.app.settings as app_settings
import lib.clients as clients
# import sqlalchemy.ext.asyncio as sa_asyncio
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class Application: class Application:
def __init__(self) -> None: def __init__(self) -> None:
self.settings = app_settings self.settings = app_settings.settings
self.logger = logging.getLogger(__name__) self.logger = logging.getLogger(__name__)
self.producer = None self.producer = None
def create_app(self) -> fastapi.FastAPI: async def create_app(self) -> fastapi.FastAPI:
postgres_client = clients.get_async_session(self.settings.postgres)
app = fastapi.FastAPI( app = fastapi.FastAPI(
title="FastAPI", title="FastAPI",
version="0.1.0", version="0.1.0",
@ -22,15 +30,26 @@ class Application:
default_response_class=fastapi.responses.ORJSONResponse, default_response_class=fastapi.responses.ORJSONResponse,
) )
router = fastapi.APIRouter()
@router.get("/health")
async def health(get_async_session: sa_asyncio.async_sessionmaker[sa_asyncio.AsyncSession]):
async with get_async_session.begin() as session:
statement = sqlalchemy.text("SELECT 1")
results = await session.execute(statement)
print(results.unique().scalar_one_or_none())
return {"status": "ok"}
app.include_router(router)
# app.include_router(api_handlers.user_router, prefix="/api/v1/users", tags=["users"]) # app.include_router(api_handlers.user_router, prefix="/api/v1/users", tags=["users"])
# app.include_router(api_handlers.movie_router, prefix="/api/v1/movies", tags=["movies"]) # app.include_router(api_handlers.movie_router, prefix="/api/v1/movies", tags=["movies"])
@app.on_event("startup") @app.on_event("startup")
async def startup_event(): async def startup_event(): # noqa: ANN202
self.logger.info("Starting server") self.logger.info("Starting server")
@app.on_event("shutdown") @app.on_event("shutdown")
async def shutdown_event(): async def shutdown_event(): # noqa: ANN202
self.logger.info("Shutting down server") self.logger.info("Shutting down server")
return app return app

View File

@ -4,7 +4,39 @@ import pydantic_settings
import lib.app.split_settings.utils as app_split_settings_utils import lib.app.split_settings.utils as app_split_settings_utils
class PostgresSettings(pydantic_settings.BaseSettings): class DBSettings(pydantic_settings.BaseSettings):
"""Parent DB Settings Class."""
# Connection settings
protocol: str
name: str
host: str
port: int
user: str
password: pydantic.SecretStr
# Enginge settings
pool_size: int = 10
pool_pre_ping: bool = True
echo: bool = False
# Session settings
auto_commit: bool = False
auto_flush: bool = False
expire_on_commit: bool = False
@property
def dsn(self) -> str:
return f"{self.protocol}://{self.user}:{self.password}@{self.host}:{self.port}"
@property
def dsn_as_safe_url(self) -> str:
return f"{self.protocol}://{self.user}:***@{self.host}:{self.port}"
class PostgresSettings(DBSettings):
"""Postgres settings."""
model_config = pydantic_settings.SettingsConfigDict( model_config = pydantic_settings.SettingsConfigDict(
env_file=app_split_settings_utils.ENV_PATH, env_file=app_split_settings_utils.ENV_PATH,
env_prefix="POSTGRES_", env_prefix="POSTGRES_",
@ -12,6 +44,7 @@ class PostgresSettings(pydantic_settings.BaseSettings):
extra="ignore", extra="ignore",
) )
protocol: str = "postgresql+asyncpg"
name: str = "database_name" name: str = "database_name"
host: str = "localhost" host: str = "localhost"
port: int = 5432 port: int = 5432

View File

@ -0,0 +1,3 @@
from .postgres import get_async_session
__all__ = ["get_async_session"]

View File

@ -0,0 +1,24 @@
import sqlalchemy.ext.asyncio as sa_asyncio
import lib.app.split_settings as app_split_settings
async def get_async_session(
settings: app_split_settings.DBSettings,
) -> sa_asyncio.async_sessionmaker[sa_asyncio.AsyncSession]:
engine = sa_asyncio.create_async_engine(
url=settings.dsn,
pool_size=settings.pool_size,
pool_pre_ping=settings.pool_pre_ping,
echo=settings.echo,
future=True,
)
async_session = sa_asyncio.async_sessionmaker(
bind=engine,
autocommit=settings.auto_commit,
autoflush=settings.auto_flush,
expire_on_commit=settings.expire_on_commit,
)
return async_session # noqa: RET504

View File

@ -1,3 +0,0 @@
# from libs.api.models.movies import *
# from libs.api.models.notification_templates import *
# from libs.api.models.users import *

View File

@ -1,38 +0,0 @@
import typing
from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker, create_async_engine
from sqlalchemy.orm import DeclarativeBase
import lib.app.settings as app_settings
settings = app_settings.settings
# Создаём базовый класс для будущих моделей
class Base(DeclarativeBase):
pass
# Создаём движок
# Настройки подключения к БД передаём из переменных окружения, которые заранее загружены в файл настроек
class AsyncDB:
def __init__(self):
self.database_dsn = (
f"postgresql+asyncpg://{settings.db.user}:{settings.db.password}"
f"@{settings.db.host}:{settings.db.port}/{settings.db.name}"
)
self.engine = create_async_engine(self.database_dsn, echo=settings.project.debug, future=True)
self.async_session = async_sessionmaker(self.engine, class_=AsyncSession, expire_on_commit=False)
db = AsyncDB()
async def get_session() -> typing.AsyncGenerator[AsyncSession, typing.Any]:
async with db.async_session() as session:
try:
yield session
except Exception:
await session.rollback()
raise

View File

@ -0,0 +1,3 @@
from .base_sqlalchemy import Base
__all__ = ["Base"]

View File

@ -0,0 +1,3 @@
import sqlalchemy.ext.declarative
Base = sqlalchemy.ext.declarative.declarative_base()

View File

@ -559,6 +559,75 @@ files = [
[package.dependencies] [package.dependencies]
setuptools = "*" setuptools = "*"
[[package]]
name = "orjson"
version = "3.9.7"
description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy"
optional = false
python-versions = ">=3.7"
files = [
{file = "orjson-3.9.7-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:b6df858e37c321cefbf27fe7ece30a950bcc3a75618a804a0dcef7ed9dd9c92d"},
{file = "orjson-3.9.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5198633137780d78b86bb54dafaaa9baea698b4f059456cd4554ab7009619221"},
{file = "orjson-3.9.7-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5e736815b30f7e3c9044ec06a98ee59e217a833227e10eb157f44071faddd7c5"},
{file = "orjson-3.9.7-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a19e4074bc98793458b4b3ba35a9a1d132179345e60e152a1bb48c538ab863c4"},
{file = "orjson-3.9.7-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80acafe396ab689a326ab0d80f8cc61dec0dd2c5dca5b4b3825e7b1e0132c101"},
{file = "orjson-3.9.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:355efdbbf0cecc3bd9b12589b8f8e9f03c813a115efa53f8dc2a523bfdb01334"},
{file = "orjson-3.9.7-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:3aab72d2cef7f1dd6104c89b0b4d6b416b0db5ca87cc2fac5f79c5601f549cc2"},
{file = "orjson-3.9.7-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:36b1df2e4095368ee388190687cb1b8557c67bc38400a942a1a77713580b50ae"},
{file = "orjson-3.9.7-cp310-none-win32.whl", hash = "sha256:e94b7b31aa0d65f5b7c72dd8f8227dbd3e30354b99e7a9af096d967a77f2a580"},
{file = "orjson-3.9.7-cp310-none-win_amd64.whl", hash = "sha256:82720ab0cf5bb436bbd97a319ac529aee06077ff7e61cab57cee04a596c4f9b4"},
{file = "orjson-3.9.7-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:1f8b47650f90e298b78ecf4df003f66f54acdba6a0f763cc4df1eab048fe3738"},
{file = "orjson-3.9.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f738fee63eb263530efd4d2e9c76316c1f47b3bbf38c1bf45ae9625feed0395e"},
{file = "orjson-3.9.7-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:38e34c3a21ed41a7dbd5349e24c3725be5416641fdeedf8f56fcbab6d981c900"},
{file = "orjson-3.9.7-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:21a3344163be3b2c7e22cef14fa5abe957a892b2ea0525ee86ad8186921b6cf0"},
{file = "orjson-3.9.7-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:23be6b22aab83f440b62a6f5975bcabeecb672bc627face6a83bc7aeb495dc7e"},
{file = "orjson-3.9.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e5205ec0dfab1887dd383597012199f5175035e782cdb013c542187d280ca443"},
{file = "orjson-3.9.7-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:8769806ea0b45d7bf75cad253fba9ac6700b7050ebb19337ff6b4e9060f963fa"},
{file = "orjson-3.9.7-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:f9e01239abea2f52a429fe9d95c96df95f078f0172489d691b4a848ace54a476"},
{file = "orjson-3.9.7-cp311-none-win32.whl", hash = "sha256:8bdb6c911dae5fbf110fe4f5cba578437526334df381b3554b6ab7f626e5eeca"},
{file = "orjson-3.9.7-cp311-none-win_amd64.whl", hash = "sha256:9d62c583b5110e6a5cf5169ab616aa4ec71f2c0c30f833306f9e378cf51b6c86"},
{file = "orjson-3.9.7-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:1c3cee5c23979deb8d1b82dc4cc49be59cccc0547999dbe9adb434bb7af11cf7"},
{file = "orjson-3.9.7-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a347d7b43cb609e780ff8d7b3107d4bcb5b6fd09c2702aa7bdf52f15ed09fa09"},
{file = "orjson-3.9.7-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:154fd67216c2ca38a2edb4089584504fbb6c0694b518b9020ad35ecc97252bb9"},
{file = "orjson-3.9.7-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7ea3e63e61b4b0beeb08508458bdff2daca7a321468d3c4b320a758a2f554d31"},
{file = "orjson-3.9.7-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1eb0b0b2476f357eb2975ff040ef23978137aa674cd86204cfd15d2d17318588"},
{file = "orjson-3.9.7-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b9a20a03576c6b7022926f614ac5a6b0914486825eac89196adf3267c6489d"},
{file = "orjson-3.9.7-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:915e22c93e7b7b636240c5a79da5f6e4e84988d699656c8e27f2ac4c95b8dcc0"},
{file = "orjson-3.9.7-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:f26fb3e8e3e2ee405c947ff44a3e384e8fa1843bc35830fe6f3d9a95a1147b6e"},
{file = "orjson-3.9.7-cp312-none-win_amd64.whl", hash = "sha256:d8692948cada6ee21f33db5e23460f71c8010d6dfcfe293c9b96737600a7df78"},
{file = "orjson-3.9.7-cp37-cp37m-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:7bab596678d29ad969a524823c4e828929a90c09e91cc438e0ad79b37ce41166"},
{file = "orjson-3.9.7-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63ef3d371ea0b7239ace284cab9cd00d9c92b73119a7c274b437adb09bda35e6"},
{file = "orjson-3.9.7-cp37-cp37m-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2f8fcf696bbbc584c0c7ed4adb92fd2ad7d153a50258842787bc1524e50d7081"},
{file = "orjson-3.9.7-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:90fe73a1f0321265126cbba13677dcceb367d926c7a65807bd80916af4c17047"},
{file = "orjson-3.9.7-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:45a47f41b6c3beeb31ac5cf0ff7524987cfcce0a10c43156eb3ee8d92d92bf22"},
{file = "orjson-3.9.7-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5a2937f528c84e64be20cb80e70cea76a6dfb74b628a04dab130679d4454395c"},
{file = "orjson-3.9.7-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:b4fb306c96e04c5863d52ba8d65137917a3d999059c11e659eba7b75a69167bd"},
{file = "orjson-3.9.7-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:410aa9d34ad1089898f3db461b7b744d0efcf9252a9415bbdf23540d4f67589f"},
{file = "orjson-3.9.7-cp37-none-win32.whl", hash = "sha256:26ffb398de58247ff7bde895fe30817a036f967b0ad0e1cf2b54bda5f8dcfdd9"},
{file = "orjson-3.9.7-cp37-none-win_amd64.whl", hash = "sha256:bcb9a60ed2101af2af450318cd89c6b8313e9f8df4e8fb12b657b2e97227cf08"},
{file = "orjson-3.9.7-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:5da9032dac184b2ae2da4bce423edff7db34bfd936ebd7d4207ea45840f03905"},
{file = "orjson-3.9.7-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7951af8f2998045c656ba8062e8edf5e83fd82b912534ab1de1345de08a41d2b"},
{file = "orjson-3.9.7-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b8e59650292aa3a8ea78073fc84184538783966528e442a1b9ed653aa282edcf"},
{file = "orjson-3.9.7-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9274ba499e7dfb8a651ee876d80386b481336d3868cba29af839370514e4dce0"},
{file = "orjson-3.9.7-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ca1706e8b8b565e934c142db6a9592e6401dc430e4b067a97781a997070c5378"},
{file = "orjson-3.9.7-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:83cc275cf6dcb1a248e1876cdefd3f9b5f01063854acdfd687ec360cd3c9712a"},
{file = "orjson-3.9.7-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:11c10f31f2c2056585f89d8229a56013bc2fe5de51e095ebc71868d070a8dd81"},
{file = "orjson-3.9.7-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:cf334ce1d2fadd1bf3e5e9bf15e58e0c42b26eb6590875ce65bd877d917a58aa"},
{file = "orjson-3.9.7-cp38-none-win32.whl", hash = "sha256:76a0fc023910d8a8ab64daed8d31d608446d2d77c6474b616b34537aa7b79c7f"},
{file = "orjson-3.9.7-cp38-none-win_amd64.whl", hash = "sha256:7a34a199d89d82d1897fd4a47820eb50947eec9cda5fd73f4578ff692a912f89"},
{file = "orjson-3.9.7-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:e7e7f44e091b93eb39db88bb0cb765db09b7a7f64aea2f35e7d86cbf47046c65"},
{file = "orjson-3.9.7-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:01d647b2a9c45a23a84c3e70e19d120011cba5f56131d185c1b78685457320bb"},
{file = "orjson-3.9.7-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0eb850a87e900a9c484150c414e21af53a6125a13f6e378cf4cc11ae86c8f9c5"},
{file = "orjson-3.9.7-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8f4b0042d8388ac85b8330b65406c84c3229420a05068445c13ca28cc222f1f7"},
{file = "orjson-3.9.7-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd3e7aae977c723cc1dbb82f97babdb5e5fbce109630fbabb2ea5053523c89d3"},
{file = "orjson-3.9.7-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c616b796358a70b1f675a24628e4823b67d9e376df2703e893da58247458956"},
{file = "orjson-3.9.7-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:c3ba725cf5cf87d2d2d988d39c6a2a8b6fc983d78ff71bc728b0be54c869c884"},
{file = "orjson-3.9.7-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:4891d4c934f88b6c29b56395dfc7014ebf7e10b9e22ffd9877784e16c6b2064f"},
{file = "orjson-3.9.7-cp39-none-win32.whl", hash = "sha256:14d3fb6cd1040a4a4a530b28e8085131ed94ebc90d72793c59a713de34b60838"},
{file = "orjson-3.9.7-cp39-none-win_amd64.whl", hash = "sha256:9ef82157bbcecd75d6296d5d8b2d792242afcd064eb1ac573f8847b52e58f677"},
{file = "orjson-3.9.7.tar.gz", hash = "sha256:85e39198f78e2f7e054d296395f6c96f5e02892337746ef5b6a1bf3ed5910142"},
]
[[package]] [[package]]
name = "packaging" name = "packaging"
version = "23.1" version = "23.1"
@ -1288,4 +1357,4 @@ files = [
[metadata] [metadata]
lock-version = "2.0" lock-version = "2.0"
python-versions = "^3.11" python-versions = "^3.11"
content-hash = "9510f3e6de8529a041dc81466c5e601fbd93e3fcfe5fa0d0d70e6f74bfc8003f" content-hash = "f9ae9c843527beb7b8c58cae8cfbf5a6d4a2ef89d7b0a83f5fe30d9f8956fdc8"

View File

@ -23,6 +23,8 @@ version = "0.1.0"
alembic = "^1.12.0" alembic = "^1.12.0"
asyncpg = "^0.28.0" asyncpg = "^0.28.0"
fastapi = "0.103.1" fastapi = "0.103.1"
greenlet = "^2.0.2"
orjson = "^3.9.7"
psycopg2 = "^2.9.7" psycopg2 = "^2.9.7"
pydantic = {extras = ["email"], version = "^2.3.0"} pydantic = {extras = ["email"], version = "^2.3.0"}
pydantic-settings = "^2.0.3" pydantic-settings = "^2.0.3"