Extending Schemas
Overview
The testing-api uses a structured schema approach to ensure all API responses are consistent and validated. If you need to support new data formats for the Supervised AI platform or update existing ones, follow the steps below to extend the schema definitions.
Adding a New Response Type
To introduce a new response type, you must define its structure within the schema directory. This ensures that the testing suite can validate the response against the expected format.
1. Define the Model
Create or locate the relevant schema file (usually under schemas/ or models/). Define your new response structure using the standard JSON schema format or the internal Pydantic-style classes.
from pydantic import BaseModel, Field
from typing import List, Optional
class NewFeatureResponse(BaseModel):
id: str = Field(..., description="Unique identifier for the feature")
score: float = Field(..., ge=0, le=1)
tags: List[str] = []
metadata: Optional[dict] = None
2. Register the Schema
If the API uses a factory pattern or a registry to map response types to endpoints, add your new model to the central registry:
# In your registry or factory file
from .schemas import NewFeatureResponse
RESPONSE_MAPPING = {
"feature_success": NewFeatureResponse,
# Add your new mapping here
}
Modifying Existing JSON Structures
When the requirements for an existing API endpoint change, you must update the schema to reflect these changes without breaking backward compatibility for older test cases.
Update Fields
Locate the existing schema class and update the attributes.
- To add a required field: Add the field without a default value.
- To add an optional field: Use
Optionalor provide a default value. - To deprecate a field: Keep the field but mark it as optional or use a deprecation warning in the description.
class ExistingResponse(BaseModel):
# Old field
user_id: int
# New added field (Optional to maintain compatibility)
session_token: Optional[str] = None
Implementing Validation
Once the schema is defined or modified, apply it to your API endpoint or testing mock to enforce the structure.
Using Schemas in Endpoints
When defining a route, type-hint the return value with your schema. This automatically handles serialization and validation.
@app.get("/api/v1/feature", response_model=NewFeatureResponse)
async def get_feature():
return {
"id": "feat_01",
"score": 0.95,
"tags": ["alpha", "beta"]
}
Validating Mock Data
If you are using these schemas for testing purposes, you can manually validate raw JSON against the schema:
from .schemas import NewFeatureResponse
def test_api_response(raw_json):
# This will raise a ValidationError if the structure is incorrect
validated_data = NewFeatureResponse(**raw_json)
return validated_data
Best Practices
- Descriptions: Always include the
Field(description="...")parameter for new fields to ensure the auto-generated documentation is clear. - Strict Typing: Avoid using
Anywhere possible. Define nested models for complex JSON structures. - Versioning: If making a breaking change to a schema (e.g., changing a data type), consider creating a new version of the schema (e.g.,
FeatureResponseV2) instead of modifying the existing one.