refactor: remove config_path from API interface

Makes config_path an internal server detail rather than an API parameter.

Changes:
- Remove config_path from SimulateTriggerRequest
- Add config_path parameter to create_app() with default
- Store in app.state.config_path for internal use
- Update trigger endpoint to use internal config path
- Change missing config error from 400 to 500 (server error)

API calls now only need to specify date_range (and optionally models):
  POST /simulate/trigger
  {"date_range": ["2025-01-16"]}

The server uses configs/default_config.json by default.
This simplifies the API and hides implementation details from clients.
This commit is contained in:
2025-10-31 15:18:56 -04:00
parent ec2a37e474
commit 8e7e80807b
2 changed files with 20 additions and 9 deletions

View File

@@ -8,6 +8,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased] ## [Unreleased]
### Changed ### Changed
- **Simplified API Interface** - Config path is now a server-side detail
- Removed `config_path` parameter from POST /simulate/trigger
- Server uses internal default config (configs/default_config.json)
- Simplifies API calls - only need to specify date_range
- **Model Selection** - `enabled` field in config now controls which models run - **Model Selection** - `enabled` field in config now controls which models run
- API `models` parameter is now optional - API `models` parameter is now optional
- If not provided, uses models where `enabled: true` in config - If not provided, uses models where `enabled: true` in config

View File

@@ -29,7 +29,6 @@ logger = logging.getLogger(__name__)
# Pydantic models for request/response validation # Pydantic models for request/response validation
class SimulateTriggerRequest(BaseModel): class SimulateTriggerRequest(BaseModel):
"""Request body for POST /simulate/trigger.""" """Request body for POST /simulate/trigger."""
config_path: str = Field(..., description="Path to configuration file")
date_range: List[str] = Field(..., min_length=1, description="List of trading dates (YYYY-MM-DD)") date_range: List[str] = Field(..., min_length=1, description="List of trading dates (YYYY-MM-DD)")
models: Optional[List[str]] = Field( models: Optional[List[str]] = Field(
None, None,
@@ -86,12 +85,16 @@ class HealthResponse(BaseModel):
timestamp: str timestamp: str
def create_app(db_path: str = "data/jobs.db") -> FastAPI: def create_app(
db_path: str = "data/jobs.db",
config_path: str = "configs/default_config.json"
) -> FastAPI:
""" """
Create FastAPI application instance. Create FastAPI application instance.
Args: Args:
db_path: Path to SQLite database db_path: Path to SQLite database
config_path: Path to default configuration file
Returns: Returns:
Configured FastAPI app Configured FastAPI app
@@ -102,15 +105,16 @@ def create_app(db_path: str = "data/jobs.db") -> FastAPI:
version="1.0.0" version="1.0.0"
) )
# Store db_path in app state # Store paths in app state
app.state.db_path = db_path app.state.db_path = db_path
app.state.config_path = config_path
@app.post("/simulate/trigger", response_model=SimulateTriggerResponse, status_code=200) @app.post("/simulate/trigger", response_model=SimulateTriggerResponse, status_code=200)
async def trigger_simulation(request: SimulateTriggerRequest): async def trigger_simulation(request: SimulateTriggerRequest):
""" """
Trigger a new simulation job. Trigger a new simulation job.
Creates a job with specified config, dates, and models from config file. Creates a job with dates and models from config file.
If models not specified in request, uses enabled models from config. If models not specified in request, uses enabled models from config.
Job runs asynchronously in background thread. Job runs asynchronously in background thread.
@@ -119,16 +123,19 @@ def create_app(db_path: str = "data/jobs.db") -> FastAPI:
HTTPException 422: If request validation fails HTTPException 422: If request validation fails
""" """
try: try:
# Use config path from app state
config_path = app.state.config_path
# Validate config path exists # Validate config path exists
if not Path(request.config_path).exists(): if not Path(config_path).exists():
raise HTTPException( raise HTTPException(
status_code=400, status_code=500,
detail=f"Config path does not exist: {request.config_path}" detail=f"Server configuration file not found: {config_path}"
) )
# Determine which models to run # Determine which models to run
import json import json
with open(request.config_path, 'r') as f: with open(config_path, 'r') as f:
config = json.load(f) config = json.load(f)
if request.models is not None: if request.models is not None:
@@ -159,7 +166,7 @@ def create_app(db_path: str = "data/jobs.db") -> FastAPI:
# Create job # Create job
job_id = job_manager.create_job( job_id = job_manager.create_job(
config_path=request.config_path, config_path=config_path,
date_range=request.date_range, date_range=request.date_range,
models=models_to_run models=models_to_run
) )