redis implemntations and api setup completed

This commit is contained in:
2025-01-25 20:59:47 +03:00
parent 32022ca521
commit 3d5a43220e
138 changed files with 2888 additions and 1117 deletions

View File

@@ -19,15 +19,18 @@ RUN poetry config virtualenvs.create false \
&& rm -rf ~/.cache/pypoetry
# Copy application code
COPY DockerApiServices/AllApiNeeds /app
COPY DockerApiServices/AuthServiceApi /app
# Copy application code
COPY ApiLayers /app/ApiLayers
COPY Services /app/Services
# Events
COPY Events/AllEvents/auth /app/Events/AllEvents/auth
# COPY Events/base_request_model.py /app/Events/base_request_model.py
COPY Events/Engine /app/Events/Engine
COPY Events/base_request_model.py /app/Events/base_request_model.py
COPY Events/abstract_class.py /app/Events/abstract_class.py
COPY Events/AllEvents/authentication /app/Events/AllEvents/authentication
COPY DockerApiServices/AuthServiceApi/events_file.py /app/Events/AllEvents/events_file.py
# Set Python path to include app directory
ENV PYTHONPATH=/app \

View File

@@ -0,0 +1,27 @@
"""
FastAPI Application Entry Point
This module initializes and configures the FastAPI application with:
- CORS middleware for cross-origin requests
- Request timing middleware for performance monitoring
- Custom exception handlers for consistent error responses
- Prometheus instrumentation for metrics
- API routers for endpoint organization
"""
import uvicorn
from prometheus_fastapi_instrumentator import Instrumentator
from app_handler import setup_middleware
from create_file import create_app
from config import ApiConfig
app = create_app() # Initialize FastAPI application
Instrumentator().instrument(app=app).expose(app=app) # Setup Prometheus metrics
setup_middleware(app) # Configure middleware and exception handlers
if __name__ == "__main__":
# Run the application with Uvicorn
uvicorn.Server(uvicorn.Config(**ApiConfig.as_dict())).run()

View File

@@ -0,0 +1,77 @@
"""
FastAPI Application Handler Module
This module contains all the handler functions for configuring and setting up the FastAPI application:
- CORS middleware configuration
- Exception handlers setup
- Uvicorn server configuration
"""
from fastapi import FastAPI, Request, status
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import JSONResponse
from ApiLayers.ErrorHandlers.Exceptions.api_exc import HTTPExceptionApi
from ApiLayers.Middleware.auth_middleware import RequestTimingMiddleware, LoggerTimingMiddleware
def setup_cors_middleware(app: FastAPI) -> None:
"""
Configure CORS middleware for the application.
Args:
app: FastAPI application instance
"""
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
async def generic_exception_handler(request: Request, exc: Exception) -> JSONResponse:
"""
Handle generic exceptions and return formatted error responses.
Args:
request: FastAPI request object
exc: Exception instance
Returns:
JSONResponse: Formatted error response
"""
return JSONResponse(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
content={"detail": "Internal server error", "error_code": "INTERNAL_ERROR"},
)
def setup_exception_handlers(app: FastAPI) -> None:
"""
Configure custom exception handlers for the application.
Args:
app: FastAPI application instance
"""
from ApiLayers.ErrorHandlers.ErrorHandlers.api_exc_handler import HTTPExceptionApiHandler
custom_exception_handler = HTTPExceptionApiHandler(response_model=JSONResponse)
app.add_exception_handler(
HTTPExceptionApi, custom_exception_handler.handle_exception
)
app.add_exception_handler(Exception, generic_exception_handler)
def setup_middleware(app: FastAPI) -> None:
"""
Configure all middleware for the application.
Args:
app: FastAPI application instance
"""
setup_cors_middleware(app)
app.add_middleware(RequestTimingMiddleware)
app.add_middleware(LoggerTimingMiddleware)
setup_exception_handlers(app)

View File

@@ -0,0 +1,70 @@
class DefaultApiConfig:
app: str
host: str
port: int
log_level: str
reload: bool
@classmethod
def as_dict(cls):
return {
"app": cls.app,
"host": cls.host,
"port": int(cls.port),
"log_level": cls.log_level,
"reload": bool(cls.reload),
}
class ApiStatic:
PLACEHOLDER = "https://s.tmimgcdn.com/scr/800x500/276800/building-home-nature-logo-vector-template-3_276851-original.jpg"
FORGOT_LINK = "https://www.evyos.com.tr/password/create?tokenUrl="
BLACKLIST_LINK = "https://www.evyos.com.tr/support/unknown-login-notice/"
APP_DIR = "/home/berkay/git-evyos/api-managment-backend/"
@classmethod
def forgot_link(cls, forgot_key):
return cls.FORGOT_LINK + forgot_key
@classmethod
def blacklist_login(cls, record_id):
return cls.BLACKLIST_LINK + record_id
class HostConfig:
MAIN_HOST = "10.10.2.36" # http://10.10.2.36
EMAIL_HOST = "10.10.2.34" # http://10.10.2.34
class ApiConfig(DefaultApiConfig):
# Application Information
APP_NAME = "evyos-auth-api-gateway"
TITLE = "WAG API Auth Api Gateway"
DESCRIPTION = "This api is serves as web auth api gateway only to evyos web services."
APP_URL = "https://www.auth.eys.gen.tr"
# Server Configuration
app = "app:app"
host = "0.0.0.0"
port = 41575
log_level = "info"
reload = True
class MainConfig:
# Date and Time Configuration
DATETIME_FORMAT = "YYYY-MM-DD HH:mm:ss Z"
DATETIME_FORMAT_JS = "YYYY-MM-DD HH:mm:ss +0"
# Timezone Configuration
DEFAULT_TIMEZONE = "GMT+3" # Default timezone for the application
SYSTEM_TIMEZONE = "GMT+0" # System timezone (used for internal operations)
SUPPORTED_TIMEZONES = ["GMT+0", "GMT+3"] # List of supported timezones
class LanguageConfig:
SUPPORTED_LANGUAGES = ["en", "tr"]
DEFAULT_LANGUAGE = "tr"

View File

@@ -0,0 +1,48 @@
"""
FastAPI Application Factory Module
This module provides functionality to create and configure a FastAPI application with:
- Custom OpenAPI schema configuration
- Security scheme configuration for Bearer authentication
- Automatic router registration
- Response class configuration
- Security requirements for protected endpoints
"""
from fastapi import FastAPI
from fastapi.responses import JSONResponse, RedirectResponse
from config import ApiConfig
from create_routes import get_all_routers
def create_app() -> FastAPI:
"""
Create and configure a FastAPI application with dynamic route creation.
Returns:
FastAPI: Configured FastAPI application instance
"""
from open_api_creator import create_openapi_schema
app = FastAPI(
title=ApiConfig.TITLE,
description=ApiConfig.DESCRIPTION,
default_response_class=JSONResponse,
) # Initialize FastAPI app
@app.get("/", include_in_schema=False, summary=str(ApiConfig.DESCRIPTION))
def home() -> RedirectResponse:
"""Redirect root path to API documentation."""
return RedirectResponse(url="/docs")
# Get all routers and protected routes using the dynamic route creation
prepare_routing = get_all_routers()
# Include all routers
for router in prepare_routing.routers:
app.include_router(router)
app.openapi = lambda app=app: create_openapi_schema(app)
return app

View File

@@ -0,0 +1,31 @@
"""
Route configuration and factory module.
Handles dynamic route creation based on configurations.
"""
from fastapi import Request
from Events.Engine.set_defaults.setClusters import PrepareRouting
async def health_check(request: Request):
"""Default health check endpoint."""
return {"status": "healthy", "message": "Service is running"}
async def ping_test(request: Request, service_name: str = "base-router"):
"""Default ping test endpoint."""
return {"ping": "pong", "service": service_name}
def get_all_routers() -> PrepareRouting:
"""
Get all routers and protected routes from route configurations.
Returns:
tuple: (routers, protected_routes)
"""
from Events.Engine.set_defaults.run import get_cluster_controller_group
cluster_list = get_cluster_controller_group()
prepare_routing = PrepareRouting(cluster_controller_group=cluster_list)
return prepare_routing

View File

@@ -0,0 +1,3 @@
import Events.AllEvents.authentication as auths_events
events_list = (auths_events,)

View File

@@ -0,0 +1,249 @@
"""
OpenAPI Schema Creator Module
This module provides functionality to create and customize OpenAPI documentation:
- Custom security schemes (Bearer Auth, API Key)
- Response schemas and examples
- Tag management and descriptions
- Error responses and validation
- Custom documentation extensions
"""
from typing import Any, Dict
from fastapi import FastAPI
from fastapi.routing import APIRoute
from fastapi.openapi.utils import get_openapi
from create_routes import get_all_routers
from config import ApiConfig
class OpenAPISchemaCreator:
"""
OpenAPI schema creator and customizer for FastAPI applications.
"""
def __init__(self, app: FastAPI):
"""
Initialize the OpenAPI schema creator.
Args:
app: FastAPI application instance
"""
self.app = app
self.cluster = get_all_routers()
self.safe_endpoint_list = self.cluster.safe_endpoints if hasattr(self.cluster, 'safe_endpoints') else []
def _create_security_schemes(self) -> Dict[str, Any]:
"""
Create security scheme definitions.
Returns:
Dict[str, Any]: Security scheme configurations
"""
from ApiLayers.AllConfigs.Token.config import Auth
return {
"BearerAuth": {
"type": "apiKey",
"in": "header",
"name": Auth.ACCESS_TOKEN_TAG,
"description": "Enter: **'Bearer <JWT>'**, where JWT is the access token",
}
}
def _create_common_responses(self) -> Dict[str, Any]:
"""
Create common response schemas.
Returns:
Dict[str, Any]: Common response configurations
"""
return {
"401": {
"description": "Unauthorized - Invalid or missing credentials",
"content": {
"application/json": {
"schema": {"$ref": "#/components/schemas/HTTPValidationError"}
}
},
},
"403": {
"description": "Forbidden - Insufficient permissions",
"content": {
"application/json": {
"schema": {"$ref": "#/components/schemas/HTTPValidationError"}
}
},
},
"422": {
"description": "Validation Error",
"content": {
"application/json": {
"schema": {"$ref": "#/components/schemas/HTTPValidationError"}
}
},
},
"500": {
"description": "Internal Server Error",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"detail": {"type": "string"},
"error_code": {"type": "string"},
},
},
"example": {
"detail": "Internal server error occurred",
"error_code": "INTERNAL_ERROR",
},
}
},
},
}
def _process_request_body(
self, path: str, method: str, schema: Dict[str, Any]
) -> None:
"""
Process request body to include examples from model config.
Args:
path: Route path
method: HTTP method
schema: OpenAPI schema to modify
"""
try:
route_schema = schema["paths"][path][method]
if "requestBody" in route_schema:
request_body = route_schema["requestBody"]
if "content" in request_body:
content = request_body["content"]
if "application/json" in content:
json_content = content["application/json"]
if (
"schema" in json_content
and "$ref" in json_content["schema"]
):
ref = json_content["schema"]["$ref"]
model_name = ref.split("/")[-1]
if model_name in schema["components"]["schemas"]:
model_schema = schema["components"]["schemas"][
model_name
]
if "example" in model_schema:
json_content["example"] = model_schema["example"]
except KeyError:
pass
def _process_response_examples(
self, path: str, method: str, schema: Dict[str, Any]
) -> None:
"""
Process response body to include examples from model config.
Args:
path: Route path
method: HTTP method
schema: OpenAPI schema to modify
"""
try:
route_schema = schema["paths"][path][method]
if "responses" in route_schema:
responses = route_schema["responses"]
if "200" in responses:
response = responses["200"]
if "content" in response:
content = response["content"]
if "application/json" in content:
json_content = content["application/json"]
if (
"schema" in json_content
and "$ref" in json_content["schema"]
):
ref = json_content["schema"]["$ref"]
model_name = ref.split("/")[-1]
if model_name in schema["components"]["schemas"]:
model_schema = schema["components"]["schemas"][
model_name
]
if "example" in model_schema:
json_content["example"] = model_schema[
"example"
]
except KeyError:
pass
def configure_route_security(
self, path: str, method: str, schema: Dict[str, Any]
) -> None:
"""
Configure security requirements for a specific route.
Args:
path: Route path
method: HTTP method
schema: OpenAPI schema to modify
"""
if not schema.get("paths", {}).get(path, {}).get(method):
return
# Check if endpoint is in safe list
endpoint_path = f"{path}:{method}"
if endpoint_path not in [f"{e.URL}:{e.METHOD.lower()}" for e in self.safe_endpoint_list]:
if "security" not in schema["paths"][path][method]:
schema["paths"][path][method]["security"] = []
schema["paths"][path][method]["security"].append(
{"BearerAuth": []}
)
def create_schema(self) -> Dict[str, Any]:
"""
Create the complete OpenAPI schema.
Returns:
Dict[str, Any]: Complete OpenAPI schema
"""
openapi_schema = get_openapi(
title=ApiConfig.TITLE,
description=ApiConfig.DESCRIPTION,
version="1.1.1",
routes=self.app.routes,
)
# Add security schemes
if "components" not in openapi_schema:
openapi_schema["components"] = {}
openapi_schema["components"]["securitySchemes"] = self._create_security_schemes()
# Configure route security and responses
for route in self.app.routes:
if isinstance(route, APIRoute) and route.include_in_schema:
path = str(route.path)
methods = [method.lower() for method in route.methods]
for method in methods:
self.configure_route_security(path, method, openapi_schema)
# Add custom documentation extensions
openapi_schema["x-documentation"] = {
"postman_collection": "/docs/postman",
"swagger_ui": "/docs",
"redoc": "/redoc",
}
return openapi_schema
def create_openapi_schema(app: FastAPI) -> Dict[str, Any]:
"""
Create OpenAPI schema for a FastAPI application.
Args:
app: FastAPI application instance
Returns:
Dict[str, Any]: Complete OpenAPI schema
"""
creator = OpenAPISchemaCreator(app)
return creator.create_schema()