first commit
Some checks failed
Build And Push / publish (push) Failing after 3m15s

This commit is contained in:
2025-09-24 04:11:55 +03:00
commit 967bb8d936
45 changed files with 2651 additions and 0 deletions

View File

@ -0,0 +1,20 @@
from logging import getLogger
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from .access_log_middleware import AccessLogMiddleware
logger = getLogger(__name__)
def register_middlewares(app: FastAPI):
app.add_middleware(AccessLogMiddleware)
app.add_middleware(
CORSMiddleware,
allow_origins=['*'],
allow_methods=['*'],
allow_headers=['*'],
)
return app

View File

@ -0,0 +1,108 @@
from logging import getLogger
from re import findall
from time import perf_counter
from starlette.types import ASGIApp, Message, Receive, Scope, Send
from core.config import settings
LOCALHOST = '127.0.0.1'
BROWSERS = {
'firefox': 'Firefox',
'yabrowser': 'Yandex',
'samsungbrowser': 'Samsung Internet',
'trident': 'Internet Explorer',
'opera': 'Opera',
'vivaldi': 'Vivaldi',
'brave': 'Brave',
'edg': 'Edge',
'chrome': 'Chrome',
'safari': 'Safari',
'chromium': 'Chromium',
'msie': 'Internet Explorer',
}
class AccessLogMiddleware:
def __init__(self, app: ASGIApp):
self.app = app
self.logger = getLogger(__name__)
self.version = (
b'Version',
f'{settings.VERSION}'.encode(),
)
async def detect_browser(self, headers: dict[bytes, bytes]):
if b'user-agent' not in headers:
return 'unknown'
user_agent = headers[b'user-agent'].decode().lower()
for k, v in BROWSERS.items():
if findall(k, user_agent):
return v
return 'unknown'
@staticmethod
async def get_client_ip(
headers: dict[bytes, bytes],
default_ip: str = LOCALHOST,
):
if b'x-forwarded-for' not in headers:
return default_ip
ips = headers[b'x-forwarded-for'].decode().split(',')
if len(ips) > 1:
return ips[-1].strip()
return ips[0]
async def __call__(self, scope: Scope, receive: Receive, send: Send):
if scope['type'] != 'http':
return await self.app(scope, receive, send)
start_time = perf_counter()
async def send_wrapper(message: Message) -> None:
if message['type'] != 'http.response.start':
return await send(message)
headers = dict(scope.get('headers', []))
client_ip = await self.get_client_ip(headers, scope['client'][0])
browser = await self.detect_browser(headers)
response_time = (perf_counter() - start_time) * 1000
response_data = f'dur={response_time:.2f}'
response = (
b'Server-Timing',
f'resp;{response_data};desc="Response Time"'.encode(),
)
message['headers'] = message['headers'] + [response, self.version]
self.logger.info(
'%s - %s %s %d [%0.2fms]',
client_ip,
scope['method'],
scope['path'],
message['status'],
response_time,
extra={
'tags': {
'method': scope['method'],
'path': scope['path'],
'status': message['status'],
'response_time': response_time,
'client_ip': client_ip,
'browser': browser,
},
},
)
await send(message)
return await self.app(scope, receive, send_wrapper)