init update (#1)

Co-authored-by: Sergey Vanyushkin <pi3c@yandex.ru>
Co-committed-by: Sergey Vanyushkin <pi3c@yandex.ru>
This commit is contained in:
2026-04-25 17:47:07 +00:00
parent 9c3b44b561
commit 66ce5ae746
34 changed files with 1078 additions and 0 deletions

View File

@@ -0,0 +1 @@
"""Application package."""

1
app/api/__init__.py Normal file
View File

@@ -0,0 +1 @@
"""API module - HTTP routes and endpoints."""

1
app/api/v1/__init__.py Normal file
View File

@@ -0,0 +1 @@
"""API version 1 endpoints."""

1
app/common/__init__.py Normal file
View File

@@ -0,0 +1 @@
"""Common utilities and shared components."""

View File

@@ -0,0 +1,48 @@
from datetime import datetime
from fastapi import FastAPI, Request
from fastapi.responses import JSONResponse
from pydantic import BaseModel
from starlette.exceptions import HTTPException
from app.core.exceptions import AppException
class ErrorResponse(BaseModel):
status_code: int
message: str
details: dict | None = None
timestamp: str
async def app_exception_handler(request: Request, exc: AppException) -> JSONResponse:
return JSONResponse(
status_code=exc.status_code,
content={
"status_code": exc.status_code,
"message": exc.message,
"timestamp": datetime.utcnow().isoformat(),
},
)
async def http_exception_handler(request: Request, exc: HTTPException) -> JSONResponse:
return JSONResponse(
status_code=exc.status_code,
content={
"status_code": exc.status_code,
"message": str(exc.detail),
"timestamp": datetime.utcnow().isoformat(),
},
)
def register_exception_handlers(app: FastAPI):
app.add_exception_handler(
AppException,
app_exception_handler, # type: ignore[arg-type]
)
app.add_exception_handler(
HTTPException,
http_exception_handler, # type: ignore[arg-type]
)

1
app/core/__init__.py Normal file
View File

@@ -0,0 +1 @@
"""Core module - shared functionality and configuration."""

15
app/core/config.py Normal file
View File

@@ -0,0 +1,15 @@
from pydantic_settings import BaseSettings, SettingsConfigDict
class Settings(BaseSettings):
app_name: str = "Blog API"
debug: bool = False
host: str = "0.0.0.0"
port: int = 8000
database_url: str | None = None
model_config = SettingsConfigDict(env_file=".env")
settings = Settings()

25
app/core/exceptions.py Normal file
View File

@@ -0,0 +1,25 @@
class AppException(Exception):
def __init__(self, message: str, status_code: int = 500):
self.message = message
self.status_code = status_code
super().__init__(self.message)
class NotFoundError(AppException):
def __init__(self, message: str = "Resource not found"):
super().__init__(message, status_code=404)
class ValidationError(AppException):
def __init__(self, message: str = "Validation failed"):
super().__init__(message, status_code=400)
class UnauthorizedError(AppException):
def __init__(self, message: str = "Unauthorized"):
super().__init__(message, status_code=401)
class ForbiddenError(AppException):
def __init__(self, message: str = "Forbidden"):
super().__init__(message, status_code=403)

1
app/modules/__init__.py Normal file
View File

@@ -0,0 +1 @@
"""Feature modules - business logic organized by domain."""