Three private tiles published to the codeflash workspace: - codeflash-internal-rules: 6 eager rules (code-style, architecture, optimization-patterns, git-conventions, testing-rules, multi-language-handlers) - codeflash-internal-docs: 8 lazy doc pages (domain-types, optimization-pipeline, test-generation-pipeline, context-extraction, aiservice/cf-api endpoints, configuration-thresholds, llm-provider-abstraction) - codeflash-internal-skills: 4 on-demand skills (debug-optimization-failure, add-language-support, add-api-endpoint, debug-test-generation)
5.3 KiB
| name | description |
|---|---|
| add-api-endpoint | Guide for adding a new API endpoint to the codeflash-internal system. Use when adding a new endpoint, creating a route, or implementing a new API. Covers both aiservice (Django-Ninja) and cf-api (Express) endpoints including schemas, routers, authentication, URL registration, and tests. |
Add API Endpoint
Use this workflow when adding a new endpoint to either the aiservice backend or the cf-api middleware. Follow the section that matches your target service.
Part A: AIService Endpoint (Django-Ninja)
Step 1: Define Schemas
Create request and response schemas.
- Create or update schemas in the appropriate module (e.g.,
core/shared/for shared,core/languages/python/for Python-specific) - Use
ninja.Schemafor all request/response types:from ninja import Schema class MyRequestSchema(Schema): source_code: str trace_id: str language: str = "python" class MyResponseSchema(Schema): results: list[str] class MyErrorResponseSchema(Schema): message: str - Follow existing patterns in
core/shared/optimizer_models.py
Checkpoint: Schemas should use Pydantic validation. Test with MyRequestSchema.model_validate(data).
Step 2: Create the Router
Create a NinjaAPI router for the endpoint.
- Create a new module (e.g.,
core/shared/my_feature.pyorcore/languages/python/my_feature/my_feature.py) - Define the router and endpoint:
from ninja import NinjaAPI from authapp.auth import AuthenticatedRequest my_feature_api = NinjaAPI(urls_namespace="my_feature") @my_feature_api.post( "/", response={200: MyResponseSchema, 400: MyErrorResponseSchema, 500: MyErrorResponseSchema} ) async def my_endpoint( request: AuthenticatedRequest, data: MyRequestSchema ) -> tuple[int, MyResponseSchema | MyErrorResponseSchema]: # Implementation here return 200, MyResponseSchema(results=[]) - All endpoints must be
async def - Use
AuthenticatedRequestfor authenticated endpoints - For multi-language endpoints, add dispatch by
data.languagewith lazy imports
Checkpoint: The endpoint should handle success and error cases with proper status codes.
Step 3: Register in urls.py
Add the endpoint to aiservice/urls.py.
- Import the API object:
from core.shared.my_feature import my_feature_api - Add to
urlpatterns:path("ai/my-feature", my_feature_api.urls), - Follow the naming convention:
ai/<kebab-case-name>
Checkpoint: The endpoint should be accessible at /ai/my-feature/.
Step 4: Add Tests
Write tests for the endpoint.
- Create test file in
tests/matching the source structure - Test the handler function directly (not via HTTP):
@pytest.mark.asyncio async def test_my_endpoint(): # Mock request and data result = await my_endpoint(mock_request, mock_data) assert result[0] == 200 - Run:
uv run pytest tests/path/test_file.py -v
Checkpoint: Tests pass. Run uv run prek run --all-files.
Part B: CF-API Endpoint (Express)
Step 1: Create Endpoint Handler
Create the endpoint handler in js/cf-api/endpoints/.
- Create
js/cf-api/endpoints/my-feature.ts:import { Request, Response } from "express" export async function myFeature(req: Request, res: Response) { // Implementation res.status(200).json({ results: [] }) } - Follow existing patterns in
endpoints/
Checkpoint: Handler should return appropriate status codes and JSON responses.
Step 2: Create Route File or Add to Existing
Add the route to the appropriate route file.
- If it's a new domain, create
js/cf-api/routes/my-feature.routes.ts:import { Router } from "express" import { addAsync } from "@awaitjs/express" import { myFeature } from "../endpoints/my-feature.js" import { ROUTES } from "../constants/index.js" const router = addAsync(Router()) as any router.postAsync(ROUTES.MY_FEATURE, myFeature) export default router - If it belongs to an existing domain, add to the corresponding route file
- Add the route constant to
constants/index.ts
Checkpoint: Route file exports a router with the endpoint registered.
Step 3: Register in Route Index
Register the route in js/cf-api/routes/index.ts.
- Import the route module
- Register in the correct section:
- Before body parser: webhook routes only
- Public routes: no auth required
- Protected routes: after
checkForValidAPIKeymiddleware
- Apply middleware as needed (
trackUsage,idLimiter, etc.)
Checkpoint: The endpoint should be accessible with proper authentication.
Step 4: Add Tests
Write tests using the dependency injection pattern.
- Create test file in
js/cf-api/__tests__/ - Use
setXxxDependencies()/resetXxxDependencies()for mocking - Follow existing test patterns
Checkpoint: Tests pass with npm test.
Key Files Reference
| File | What to modify |
|---|---|
core/shared/optimizer_models.py |
Schema patterns |
aiservice/urls.py |
AIService endpoint registration |
js/cf-api/routes/index.ts |
CF-API route registration |
js/cf-api/constants/index.ts |
Route constants |
authapp/auth.py |
Authentication patterns |