starting full refactor with FastAPI routes + HTMX and AlpineJS on client side
This commit is contained in:
95
src/dependencies.py
Normal file
95
src/dependencies.py
Normal file
@@ -0,0 +1,95 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
"""
|
||||
FastAPI dependency injection providers.
|
||||
Replaces Handler class variables with proper DI.
|
||||
"""
|
||||
|
||||
import os
|
||||
from datetime import datetime
|
||||
|
||||
from fastapi import Request
|
||||
from fastapi.templating import Jinja2Templates
|
||||
|
||||
from config import Config
|
||||
from tracker import AccessTracker
|
||||
from database import DatabaseManager, get_database
|
||||
from logger import get_app_logger, get_access_logger, get_credential_logger
|
||||
|
||||
# Shared Jinja2 templates instance
|
||||
_templates = None
|
||||
|
||||
|
||||
def get_templates() -> Jinja2Templates:
|
||||
"""Get shared Jinja2Templates instance with custom filters."""
|
||||
global _templates
|
||||
if _templates is None:
|
||||
templates_dir = os.path.join(
|
||||
os.path.dirname(__file__), "templates", "jinja2"
|
||||
)
|
||||
_templates = Jinja2Templates(directory=templates_dir)
|
||||
_templates.env.filters["format_ts"] = _format_ts
|
||||
return _templates
|
||||
|
||||
|
||||
def _format_ts(value, time_only=False):
|
||||
"""Custom Jinja2 filter for formatting ISO timestamps."""
|
||||
if not value:
|
||||
return "N/A"
|
||||
if isinstance(value, str):
|
||||
try:
|
||||
value = datetime.fromisoformat(value)
|
||||
except (ValueError, TypeError):
|
||||
return value
|
||||
if time_only:
|
||||
return value.strftime("%H:%M:%S")
|
||||
return value.strftime("%m/%d/%Y %H:%M:%S")
|
||||
|
||||
|
||||
def get_tracker(request: Request) -> AccessTracker:
|
||||
return request.app.state.tracker
|
||||
|
||||
|
||||
def get_app_config(request: Request) -> Config:
|
||||
return request.app.state.config
|
||||
|
||||
|
||||
def get_db() -> DatabaseManager:
|
||||
return get_database()
|
||||
|
||||
|
||||
def get_client_ip(request: Request) -> str:
|
||||
"""Extract client IP address from request, checking proxy headers first."""
|
||||
forwarded_for = request.headers.get("X-Forwarded-For")
|
||||
if forwarded_for:
|
||||
return forwarded_for.split(",")[0].strip()
|
||||
|
||||
real_ip = request.headers.get("X-Real-IP")
|
||||
if real_ip:
|
||||
return real_ip.strip()
|
||||
|
||||
if request.client:
|
||||
return request.client.host
|
||||
|
||||
return "0.0.0.0"
|
||||
|
||||
|
||||
def build_raw_request(request: Request, body: str = "") -> str:
|
||||
"""Build raw HTTP request string for forensic analysis."""
|
||||
try:
|
||||
raw = f"{request.method} {request.url.path}"
|
||||
if request.url.query:
|
||||
raw += f"?{request.url.query}"
|
||||
raw += f" HTTP/1.1\r\n"
|
||||
|
||||
for header, value in request.headers.items():
|
||||
raw += f"{header}: {value}\r\n"
|
||||
|
||||
raw += "\r\n"
|
||||
|
||||
if body:
|
||||
raw += body
|
||||
|
||||
return raw
|
||||
except Exception as e:
|
||||
return f"{request.method} {request.url.path} (error building full request: {str(e)})"
|
||||
Reference in New Issue
Block a user