Fix docker

This commit is contained in:
Urtzi Alfaro
2025-07-17 19:46:41 +02:00
parent ea5b75b685
commit caf7dea73a
8 changed files with 292 additions and 16 deletions

View File

@@ -15,27 +15,32 @@ class Settings(BaseSettings):
DEBUG: bool = os.getenv("DEBUG", "False").lower() == "true"
LOG_LEVEL: str = os.getenv("LOG_LEVEL", "INFO")
# CORS settings
CORS_ORIGINS: List[str] = os.getenv("CORS_ORIGINS", "http://localhost:3000,http://localhost:3001").split(",")
# CORS settings - FIXED: Remove List[str] type and parse manually
CORS_ORIGINS: str = "http://localhost:3000,http://localhost:3001"
# Service URLs
AUTH_SERVICE_URL: str = os.getenv("AUTH_SERVICE_URL", "http://auth-service:8000")
TRAINING_SERVICE_URL: str = os.getenv("TRAINING_SERVICE_URL", "http://training-service:8000")
FORECASTING_SERVICE_URL: str = os.getenv("FORECASTING_SERVICE_URL", "http://forecasting-service:8000")
DATA_SERVICE_URL: str = os.getenv("DATA_SERVICE_URL", "http://data-service:8000")
TENANT_SERVICE_URL: str = os.getenv("TENANT_SERVICE_URL", "http://tenant-service:8000")
NOTIFICATION_SERVICE_URL: str = os.getenv("NOTIFICATION_SERVICE_URL", "http://notification-service:8000")
AUTH_SERVICE_URL: str = "http://auth-service:8000"
TRAINING_SERVICE_URL: str = "http://training-service:8000"
FORECASTING_SERVICE_URL: str = "http://forecasting-service:8000"
DATA_SERVICE_URL: str = "http://data-service:8000"
TENANT_SERVICE_URL: str = "http://tenant-service:8000"
NOTIFICATION_SERVICE_URL: str = "http://notification-service:8000"
# Redis settings
REDIS_URL: str = os.getenv("REDIS_URL", "redis://redis:6379/6")
REDIS_URL: str = "redis://redis:6379/6"
# Rate limiting
RATE_LIMIT_REQUESTS: int = int(os.getenv("RATE_LIMIT_REQUESTS", "100"))
RATE_LIMIT_WINDOW: int = int(os.getenv("RATE_LIMIT_WINDOW", "60"))
RATE_LIMIT_REQUESTS: int = 100
RATE_LIMIT_WINDOW: int = 60
# JWT settings
JWT_SECRET_KEY: str = os.getenv("JWT_SECRET_KEY", "your-secret-key-change-in-production")
JWT_ALGORITHM: str = os.getenv("JWT_ALGORITHM", "HS256")
JWT_SECRET_KEY: str = "your-secret-key-change-in-production"
JWT_ALGORITHM: str = "HS256"
@property
def CORS_ORIGINS_LIST(self) -> List[str]:
"""Parse CORS origins from string to list"""
return [origin.strip() for origin in self.CORS_ORIGINS.split(",") if origin.strip()]
@property
def SERVICES(self) -> Dict[str, str]:
@@ -49,4 +54,7 @@ class Settings(BaseSettings):
"notification": self.NOTIFICATION_SERVICE_URL
}
class Config:
env_file = ".env"
settings = Settings()

View File

@@ -40,10 +40,10 @@ metrics_collector = MetricsCollector("gateway")
# Service discovery
service_discovery = ServiceDiscovery()
# CORS middleware
# CORS middleware - FIXED: Use the parsed list property
app.add_middleware(
CORSMiddleware,
allow_origins=settings.CORS_ORIGINS,
allow_origins=settings.CORS_ORIGINS_LIST,
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],

View File

@@ -0,0 +1,66 @@
"""
Data routes for gateway
"""
from fastapi import APIRouter, Request, HTTPException
from fastapi.responses import JSONResponse
import httpx
import logging
from app.core.config import settings
logger = logging.getLogger(__name__)
router = APIRouter()
@router.post("/upload")
async def upload_sales_data(request: Request):
"""Proxy data upload to data service"""
try:
body = await request.body()
auth_header = request.headers.get("Authorization")
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.post(
f"{settings.DATA_SERVICE_URL}/upload",
content=body,
headers={
"Content-Type": "application/json",
"Authorization": auth_header
}
)
return JSONResponse(
status_code=response.status_code,
content=response.json()
)
except httpx.RequestError as e:
logger.error(f"Data service unavailable: {e}")
raise HTTPException(
status_code=503,
detail="Data service unavailable"
)
@router.get("/sales")
async def get_sales_data(request: Request):
"""Get sales data"""
try:
auth_header = request.headers.get("Authorization")
async with httpx.AsyncClient(timeout=10.0) as client:
response = await client.get(
f"{settings.DATA_SERVICE_URL}/sales",
headers={"Authorization": auth_header}
)
return JSONResponse(
status_code=response.status_code,
content=response.json()
)
except httpx.RequestError as e:
logger.error(f"Data service unavailable: {e}")
raise HTTPException(
status_code=503,
detail="Data service unavailable"
)

View File

@@ -0,0 +1,66 @@
"""
Forecasting routes for gateway
"""
from fastapi import APIRouter, Request, HTTPException
from fastapi.responses import JSONResponse
import httpx
import logging
from app.core.config import settings
logger = logging.getLogger(__name__)
router = APIRouter()
@router.post("/predict")
async def create_forecast(request: Request):
"""Proxy forecast request to forecasting service"""
try:
body = await request.body()
auth_header = request.headers.get("Authorization")
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.post(
f"{settings.FORECASTING_SERVICE_URL}/predict",
content=body,
headers={
"Content-Type": "application/json",
"Authorization": auth_header
}
)
return JSONResponse(
status_code=response.status_code,
content=response.json()
)
except httpx.RequestError as e:
logger.error(f"Forecasting service unavailable: {e}")
raise HTTPException(
status_code=503,
detail="Forecasting service unavailable"
)
@router.get("/forecasts")
async def get_forecasts(request: Request):
"""Get forecasts"""
try:
auth_header = request.headers.get("Authorization")
async with httpx.AsyncClient(timeout=10.0) as client:
response = await client.get(
f"{settings.FORECASTING_SERVICE_URL}/forecasts",
headers={"Authorization": auth_header}
)
return JSONResponse(
status_code=response.status_code,
content=response.json()
)
except httpx.RequestError as e:
logger.error(f"Forecasting service unavailable: {e}")
raise HTTPException(
status_code=503,
detail="Forecasting service unavailable"
)

View File

@@ -0,0 +1,66 @@
"""
Notification routes for gateway
"""
from fastapi import APIRouter, Request, HTTPException
from fastapi.responses import JSONResponse
import httpx
import logging
from app.core.config import settings
logger = logging.getLogger(__name__)
router = APIRouter()
@router.post("/send")
async def send_notification(request: Request):
"""Proxy notification request to notification service"""
try:
body = await request.body()
auth_header = request.headers.get("Authorization")
async with httpx.AsyncClient(timeout=10.0) as client:
response = await client.post(
f"{settings.NOTIFICATION_SERVICE_URL}/send",
content=body,
headers={
"Content-Type": "application/json",
"Authorization": auth_header
}
)
return JSONResponse(
status_code=response.status_code,
content=response.json()
)
except httpx.RequestError as e:
logger.error(f"Notification service unavailable: {e}")
raise HTTPException(
status_code=503,
detail="Notification service unavailable"
)
@router.get("/history")
async def get_notification_history(request: Request):
"""Get notification history"""
try:
auth_header = request.headers.get("Authorization")
async with httpx.AsyncClient(timeout=10.0) as client:
response = await client.get(
f"{settings.NOTIFICATION_SERVICE_URL}/history",
headers={"Authorization": auth_header}
)
return JSONResponse(
status_code=response.status_code,
content=response.json()
)
except httpx.RequestError as e:
logger.error(f"Notification service unavailable: {e}")
raise HTTPException(
status_code=503,
detail="Notification service unavailable"
)

View File

@@ -0,0 +1,66 @@
"""
Tenant routes for gateway
"""
from fastapi import APIRouter, Request, HTTPException
from fastapi.responses import JSONResponse
import httpx
import logging
from app.core.config import settings
logger = logging.getLogger(__name__)
router = APIRouter()
@router.post("/")
async def create_tenant(request: Request):
"""Proxy tenant creation to tenant service"""
try:
body = await request.body()
auth_header = request.headers.get("Authorization")
async with httpx.AsyncClient(timeout=10.0) as client:
response = await client.post(
f"{settings.TENANT_SERVICE_URL}/tenants",
content=body,
headers={
"Content-Type": "application/json",
"Authorization": auth_header
}
)
return JSONResponse(
status_code=response.status_code,
content=response.json()
)
except httpx.RequestError as e:
logger.error(f"Tenant service unavailable: {e}")
raise HTTPException(
status_code=503,
detail="Tenant service unavailable"
)
@router.get("/")
async def get_tenants(request: Request):
"""Get tenants"""
try:
auth_header = request.headers.get("Authorization")
async with httpx.AsyncClient(timeout=10.0) as client:
response = await client.get(
f"{settings.TENANT_SERVICE_URL}/tenants",
headers={"Authorization": auth_header}
)
return JSONResponse(
status_code=response.status_code,
content=response.json()
)
except httpx.RequestError as e:
logger.error(f"Tenant service unavailable: {e}")
raise HTTPException(
status_code=503,
detail="Tenant service unavailable"
)

View File

@@ -10,4 +10,5 @@ prometheus-client==0.17.1
python-json-logger==2.0.4
email-validator==2.0.0
aio-pika==9.3.0
pytz==2023.3
pytz==2023.3
python-logstash==0.4.8

View File

@@ -4,3 +4,6 @@ Messaging service for training service
from shared.messaging.rabbitmq import RabbitMQClient
from app.core.config import settings
# Global message publisher
message_publisher = RabbitMQClient(settings.RABBITMQ_URL)