lavkach3

Форк
0
/
front_server.py 
181 строка · 5.5 Кб
1
import logging
2
import os
3
from contextlib import asynccontextmanager
4
from dataclasses import dataclass
5
from typing import List
6

7
import taskiq_fastapi
8
import uvicorn
9
from fastapi import FastAPI, Request, Depends
10
from fastapi.middleware import Middleware
11
from fastapi.middleware.cors import CORSMiddleware
12
from fastapi.responses import JSONResponse
13
from fastapi.staticfiles import StaticFiles
14
from starlette.requests import HTTPConnection
15
from starlette.types import ASGIApp, Scope, Receive, Send
16
from app.front.tkq import broker
17
from app.front.front_router import front_router
18
#from app.front.front_tasks import remove_expired_tokens
19
from core.helpers.broker import list_brocker
20
from core.db_config import config
21
from core.env import Env
22
from app.basic import __domain__ as basic_domain
23
from app.inventory import __domain__ as inventory_domain
24
from app.prescription import __domain__ as prescription_domain
25
from core.exceptions import CustomException
26
from core.fastapi.dependencies import Logging
27
from core.fastapi.middlewares import (
28
    AuthenticationMiddleware,
29
    AuthBffBackend,
30
    SQLAlchemyMiddleware, AuthBackend,
31
)
32
from core.helpers.cache import Cache, CustomKeyMaker
33
from core.helpers.cache import RedisBackend
34
from core.utils.timeit import add_timing_middleware
35
from app.front.front_config import config as cf
36

37
logging.basicConfig(level=logging.INFO)
38
logger = logging.getLogger(__name__)
39

40

41
@dataclass
42
class Htmx:
43
    hx_target: str = None
44
    hx_current_url: str = None
45
    hx_request: bool = None
46

47

48
class HTMXMidlleWare:
49
    """
50
    Адартер кладется в request для удобства htmx переменных
51
    """
52

53
    def __init__(self, app: ASGIApp, *args, **kwargs):
54
        self.app = app
55

56
    async def __call__(self, scope: Scope, receive: Receive, send: Send):
57
        if scope['type'] in ("http", "websocket"):
58
            conn = HTTPConnection(scope)
59
            scope['htmx'] = Htmx(
60
                hx_target=conn.headers.get('hx-target'),
61
                hx_current_url=conn.headers.get('hx-current-url'),
62
                hx_request=True if conn.headers.get('hx-request') == 'true' else False
63
            )
64
        await self.app(scope, receive, send)
65

66
env = None
67

68
class EnvMidlleWare:
69
    """
70
    Адартер кладется в request для удобства обращений к обьектам сервисов
71
    """
72
    def __init__(self, app: ASGIApp, *args, **kwargs):
73
        self.app = app
74

75
    async def __call__(self, scope: Scope, receive: Receive, send: Send):
76
        global env
77
        if scope['type'] in ("http", "websocket"):
78
            conn = HTTPConnection(scope)
79
            if not env:
80
                env = Env([inventory_domain, basic_domain, prescription_domain], conn, broker=list_brocker)
81
                scope['env'] = env
82
                broker.env = env
83
            else:
84
                scope['env'] = env
85
                broker.env = env
86
                env.request = conn
87
        await self.app(scope, receive, send)
88

89

90
def init_routers(app_: FastAPI) -> None:
91
    app_.include_router(front_router)
92

93

94
def init_listeners(app_: FastAPI) -> None:
95
    # Exception handler
96
    @app_.exception_handler(CustomException)
97
    async def custom_exception_handler(request: Request, exc: CustomException):
98
        return JSONResponse(
99
            status_code=exc.code,
100
            content={"error_code": exc.error_code, "message": exc.message},
101
        )
102

103

104
def on_auth_error(request: Request, exc: Exception):
105
    status_code, error_code, message = 401, None, str(exc)
106
    if isinstance(exc, CustomException):
107
        status_code = int(exc.code)
108
        error_code = exc.error_code
109
        message = exc.message
110

111
    return JSONResponse(
112
        status_code=status_code,
113
        content={"error_code": error_code, "message": message},
114
    )
115

116

117
def make_middleware() -> List[Middleware]:
118
    middleware = [
119
        Middleware(EnvMidlleWare),
120
        Middleware(HTMXMidlleWare),
121
        Middleware(
122
            CORSMiddleware,
123
            allow_origins=["*"],
124
            allow_credentials=False,
125
            allow_methods=["*"],
126
            allow_headers=["*"],
127
        ),
128
        Middleware(
129
            AuthenticationMiddleware,
130
            backend=AuthBackend(),
131
            on_error=on_auth_error,
132
        ),
133
        Middleware(SQLAlchemyMiddleware),
134

135
    ]
136
    return middleware
137

138

139
def init_cache() -> None:
140
    Cache.init(backend=RedisBackend(), key_maker=CustomKeyMaker())
141

142

143
def fake_answer_to_everything_ml_model(x: float):
144
    return x * 42
145

146
@asynccontextmanager
147
async def lifespan(app: FastAPI):
148
    """
149
        Старт сервера
150
    """
151
    setattr(broker, 'env', env)
152
    await broker.startup()
153
    yield
154
    """
155
            Выключение сервера
156
    """
157
    await broker.shutdown()
158

159
def create_app() -> FastAPI:
160
    app_ = FastAPI(
161
        title="Hide",
162
        lifespan=lifespan,
163
        description="Hide API",
164
        version="1.0.0",
165
        docs_url=None if config.ENV == "production" else "/docs",
166
        redoc_url=None if config.ENV == "production" else "/redoc",
167
        dependencies=[Depends(Logging)],
168
        middleware=make_middleware(),
169
    )
170
    init_routers(app_=app_)
171
    init_listeners(app_=app_)
172
    init_cache()
173
    return app_
174

175
app = create_app()
176
path = os.path.dirname(os.path.abspath(__file__))
177
add_timing_middleware(app, record=logger.info, prefix="front", exclude="untimed")
178
app.mount(f"/static", StaticFiles(directory=f"{path}/static"), name="static")
179

180
# if __name__ == "__main__":
181
#     uvicorn.run(app, host="127.0.0.1", port=8003, log_level="info")
182

183

184

185

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.