Skip to content

Latest commit

 

History

History
63 lines (53 loc) · 3.53 KB

public-api.md

File metadata and controls

63 lines (53 loc) · 3.53 KB

Public catalog API beta

The public reference at /docs/api describes a selected subset of the existing /api/v1 catalog. backend/services/public_api_schema.py owns that selection and small example requests. /api/v1/openapi.json generates the response and parameter schemas from the actual routes. /openapi.json remains the full application schema. Discovery links advertise the public schema.

Adding or changing an endpoint

  1. Confirm the read has no user-specific data or side effects and uses a bounded response. Add a typed response model before documenting an opaque dictionary.
  2. Add the route and a valid example to PUBLIC_ENDPOINTS. The public browser middleware matches the actual registered route, not just its URL shape.
  3. Check request parameters and examples against the route. The public search contract requires explicit mode=keyword; existing search modes and defaults are unchanged for website and other clients.
  4. Run backend/tests/test_public_api.py, backend/tests/test_public_api_nginx.py, and frontend/src/views/ApiDocsView.test.tsx. Verify actual responses and identifiers too: contract tests cannot establish that an example record still exists.
  5. Record planned breaking changes in the /docs/api#changelog section (frontend/src/views/ApiDocsView.tsx) with announcement and effective dates at least 14 days apart. Urgent security or restoration fixes are exempt. Do not silently change documented behavior.

Traffic controls

Both nginx templates (deploy/nginx/) contain shared per-IP zones: catalog GETs under /api/v1/(papers|tasks|datasets|evaluations) sustain 120/minute with 60 excess burst slots; list/search GETs additionally sustain 60/minute with 20 excess burst slots. The identity is nginx's $binary_remote_addr, never an untrusted forwarding header. Production sits behind Cloudflare and the templates do not set real_ip, so that address is currently a Cloudflare edge IP, not the visitor. OPTIONS and mutations do not enter these zones.

These are initial operating limits sized from a pre-launch access-log sample, not a capacity guarantee. Follow nginx's limit-exceeded log entries and API latency; adjust rates and bursts together with the docs and avoid production load tests. A rejected request receives JSON, no-store, a two-second Retry-After, and public CORS headers. The fixed, credential-independent error reflects an Origin header and permits credentials so existing browser clients can read the retry instruction; successful responses still use the application CORS policy.

The application CORS middleware grants anonymous cross-origin GET access only to the explicitly selected operations and the public schema. It does not grant credentialed access or change administrative/write CORS rules. Staging's nginx access gate remains in place.

Release dependency

Rate limits and the exact /docs/api location (served by the frontend; the broad /docs proxy remains for backend docs) live in nginx. Changing them needs both the application release through pwc-deploy and the checked-in nginx template applied separately through pwc-nginx for the target environment; an application deploy alone changes neither. Verify deep-link and footer navigation, the public schema, an anonymous read with an Origin header, and normal site browsing.

test_public_api_nginx.py uses disposable directories, ephemeral ports, a synthetic upstream, and an unprivileged nginx process, including its configuration check. It does not include host config, contact live services, or signal a live nginx process.