Skip to content

Docs (openapi): enrich /docs — metadata, Authorize button, param + error docs#4

Open
sagargg wants to merge 4 commits into
mainfrom
docs/openapi-polish
Open

Docs (openapi): enrich /docs — metadata, Authorize button, param + error docs#4
sagargg wants to merge 4 commits into
mainfrom
docs/openapi-polish

Conversation

@sagargg
Copy link
Copy Markdown
Member

@sagargg sagargg commented May 27, 2026

The interactive docs at /docs were running almost entirely on FastAPI defaults (only title + version). This fills them in across three areas — no behavioral change to the API itself.

App metadata

title, version (read from package metadata so it tracks releases), summary, a markdown description (envelope shape, auth model, streaming + pagination), per-tag descriptions (datastore / health / dump), and contact. The /docs landing area is no longer empty.

Security

The Authorization header is now declared as an APIKeyHeader security scheme instead of a raw Header parameter. Swagger renders an Authorize button (set the token once for every call), and the header stops leaking as a parameter on each operation.

Params + examples

  • Every request field gets a description.
  • The 12 datastore_search query params (filters, q, sort, fields, records_format, …) are documented — previously all undocumented.
  • datastore_create / upsert / delete bodies carry worked examples, so Try it out is pre-filled with a valid body.
  • Human operation summaries replace the machine-derived ones (e.g. "Datastore Search Sql").

Errors

  • New ErrorEnvelope model + a shared ERROR_RESPONSES, attached at router level so every action documents the real CKAN 4xx/5xx shape (400/403/404/409/500).
  • /ready's 503 and the dump endpoint's 302 are documented.
  • The misleading auto-422 is stripped (validation errors are remapped to a 400 CKAN envelope, so a 422 never actually occurs).

Testing

  • pytest: 320 passing (CI-equivalent env); ruff: clean; no net-new mypy errors.
  • The generated /openapi.json was verified: 12/12 search params described, security scheme present, Authorization no longer a param, no 422 anywhere, error codes + 503/302 present.

Note

Includes the same one-line conftest CKAN_URL fix as #3 (needed so create_app() builds under the default ckan auth in CI, where there's no .env). It's identical to #3's, so whichever merges second is a no-op — these two PRs touch otherwise-disjoint files.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Documentation

    • Added new API.md documenting all endpoints and request/response contracts.
    • Updated README with essential configuration overview and quick-start guide.
  • API & OpenAPI Improvements

    • Enhanced endpoint summaries and error response documentation in OpenAPI specifications.
    • Added detailed schema descriptions and examples to all request models.
    • Cleaned up OpenAPI schema to align with custom error handling.

Review Change Stack

…ror docs

The interactive docs were running on FastAPI defaults. This fills them in:

App metadata: title, version (from package metadata), summary, a markdown
description (envelope shape, auth model, streaming/pagination), tag descriptions,
and contact — so the /docs landing page is no longer bare.

Security: declare the `Authorization` header as an APIKeyHeader security scheme
instead of a raw Header param. Swagger now shows an 'Authorize' button (set the
token once) and the header stops leaking as a parameter on every operation.

Params + examples: every request field gets a description; query params on
datastore_search (filters/q/sort/fields/…) are documented; create/upsert/delete
bodies carry worked examples so 'Try it out' is pre-filled.

Errors: add an ErrorEnvelope model and attach the real CKAN 4xx/5xx envelope
(400/403/404/409/500) to every action via a shared ERROR_RESPONSES; document
/ready's 503 and dump's 302; strip FastAPI's misleading auto-422 (validation
errors are remapped to a 400 envelope). Human operation summaries replace the
machine-derived ones (e.g. 'Datastore Search Sql').

Also: set a dummy CKAN_URL in conftest so `create_app()` builds under the default ckan auth in CI (same import-time fix as the schema-in-OPTIONS PR; harmless when both land).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 27, 2026

Warning

Review limit reached

@sagargg, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 52 minutes and 59 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 93fb23fb-0bad-4fac-bc84-02d664ecbb71

📥 Commits

Reviewing files that changed from the base of the PR and between 6434a78 and 374170f.

📒 Files selected for processing (1)
  • API.md
📝 Walkthrough

Walkthrough

This PR consolidates API documentation into a dedicated reference file, enhances request/response schemas with OpenAPI metadata, and upgrades FastAPI endpoint decorators and OpenAPI configuration to provide versioning, error response mappings, and security scheme documentation.

Changes

OpenAPI & API Documentation

Layer / File(s) Summary
API Reference Documentation
API.md
Introduces comprehensive CKAN-compatible API reference documenting all datastore endpoints (datastore_create, datastore_upsert, datastore_delete, datastore_search, datastore_search_sql, datastore_info), /datastore/dump/{resource_id}, health probes, and the read-only resource guard under AUTH_TYPE=ckan.
Documentation Consolidation
CLAUDE.md, README.md
CLAUDE.md and README.md are streamlined by replacing in-document API examples and extensive architecture/env documentation with links to the new API.md reference and brief quickstart/configuration details.
Error Envelope & Response Mapping
datastore/schemas/responses.py, datastore/api/responses.py
Introduces ErrorEnvelope Pydantic model for CKAN-shaped error responses with nested Error object (__type alias, message, optional fields), and defines ERROR_RESPONSES dictionary mapping HTTP status codes to OpenAPI error schema metadata.
Request Schema Documentation
datastore/schemas/request.py
All request schemas (DatastoreCreateRequest, DatastoreUpsertRequest, DatastoreSearchRequest, DatastoreSearchSQLRequest, DatastoreInfoRequest, DatastoreDeleteRequest) are enhanced with Field(...) metadata, descriptions, examples, and json_schema_extra payloads.
OpenAPI Configuration & Versioning
datastore/main.py
Adds _api_version() helper to read installed package version, OPENAPI_TAGS constant for endpoint grouping, enriched FastAPI metadata, and _strip_default_422() helper to remove FastAPI's auto-generated 422 response entries from the published OpenAPI schema.
Security Scheme & Authorization
datastore/api/context.py
Authorization header handling is updated from bare Header(alias="Authorization") to a formal APIKeyHeader security scheme, including documented token formats and anonymous behavior for improved OpenAPI rendering.
Endpoint Decorators & Router Configuration
datastore/api/endpoints/datastore.py, datastore/api/endpoints/dump.py, datastore/api/endpoints/health.py
All routers are updated with capitalized tags and ERROR_RESPONSES mapping; endpoint decorators are expanded with summary fields and explicit response specifications (302/200 for dump, 503 for health ready). datastore_delete endpoint is relocated earlier in the module.
Test Environment Configuration
tests/conftest.py
Ensures CKAN_URL environment variable has a default dummy value during test import to prevent configuration validation failures.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related PRs

  • datopian/datastore#2: Updates the /datastore/dump/{resource_id} endpoint with ERROR_RESPONSES router wiring and route decorator metadata, directly touching the same dump endpoint module modified in this PR.

Poem

📚 A rabbit hops through docs so clear,
With endpoints mapped for all to hear,
From schemas typed to errors shown,
The API contract's fully grown! 🐰

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 65.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: enriching the OpenAPI /docs interface with metadata, Authorize button, and parameter/error documentation.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch docs/openapi-polish

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

sagargg added 2 commits May 27, 2026 15:20
Recapitalise the Swagger tag groups (Health / Datastore / Datastore Download, Health first), move datastore_delete up next to create/upsert, trim the app description, and point contact at datopian.com.
- Rewrite README to a minimal overview (quick start, config essentials, doc links).
- Add API.md — full per-endpoint HTTP reference (envelope, auth, errors, examples, Postman link).
- Replace CLAUDE.md's request/response contracts section with a pointer to API.md (~951 -> ~540 lines).
- Improve the Swagger operation summaries on datastore_search / datastore_search_sql / dump.
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@API.md`:
- Around line 269-275: The two unlabeled fenced code blocks showing example HTTP
requests (the block beginning with "GET /api/3/action/datastore_search
?resource_id=balancing_auction_results_2025 ..." and the block beginning with
"GET /api/3/action/datastore_search_sql?sql= SELECT product_code, AVG(...") must
be given a language tag to satisfy markdownlint MD040; edit those fences to use
a language label such as ```http (or ```text) instead of bare ``` so both
example blocks are explicitly tagged.

In `@datastore/main.py`:
- Around line 130-132: The summary string contains a typo ("Datasore"); update
the summary value used (the summary parameter in the object or function where
it's defined) to read "A Datastore API endpoint for managing tabular data
resources." so the word "Datastore" is spelled correctly; locate the summary
parameter in datatore/main.py and correct the string literal accordingly.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 003c59f8-6644-485a-8b4b-ac9f07fded1c

📥 Commits

Reviewing files that changed from the base of the PR and between fdd3dc3 and 6434a78.

📒 Files selected for processing (12)
  • API.md
  • CLAUDE.md
  • README.md
  • datastore/api/context.py
  • datastore/api/endpoints/datastore.py
  • datastore/api/endpoints/dump.py
  • datastore/api/endpoints/health.py
  • datastore/api/responses.py
  • datastore/main.py
  • datastore/schemas/request.py
  • datastore/schemas/responses.py
  • tests/conftest.py

Comment thread API.md
Comment on lines +269 to +275
```
GET /api/3/action/datastore_search
?resource_id=balancing_auction_results_2025
&filters={"product_code":"DCL","accepted":true}
&sort=delivery_start desc
&limit=100
```
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Add language tags to fenced examples to satisfy markdownlint.

Line 269 and Line 318 use unlabeled code fences; this triggers MD040. Use a language tag (for example, http or text) on both blocks.

Suggested patch
-```
+```http
 GET /api/3/action/datastore_search
     ?resource_id=balancing_auction_results_2025
     &filters={"product_code":"DCL","accepted":true}
     &sort=delivery_start desc
     &limit=100

@@
- +http
GET /api/3/action/datastore_search_sql?sql=
SELECT product_code, AVG(clearing_price_gbp_per_mwh) AS avg_price
FROM "balancing_auction_results_2025"
WHERE accepted = true
GROUP BY product_code
LIMIT 1000

Also applies to: 318-325

🧰 Tools
🪛 markdownlint-cli2 (0.22.1)

[warning] 269-269: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@API.md` around lines 269 - 275, The two unlabeled fenced code blocks showing
example HTTP requests (the block beginning with "GET
/api/3/action/datastore_search ?resource_id=balancing_auction_results_2025 ..."
and the block beginning with "GET /api/3/action/datastore_search_sql?sql= SELECT
product_code, AVG(...") must be given a language tag to satisfy markdownlint
MD040; edit those fences to use a language label such as ```http (or ```text)
instead of bare ``` so both example blocks are explicitly tagged.

Comment thread datastore/main.py
Comment on lines +130 to +132
summary=(
"A Datasore API endpoint for managing tabular data resources. "
),
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Fix typo in summary text.

Line 131 has "Datasore" instead of "Datastore".

📝 Proposed fix
         summary=(
-            "A Datasore API endpoint for managing tabular data resources. "
+            "A Datastore API endpoint for managing tabular data resources. "
         ),
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
summary=(
"A Datasore API endpoint for managing tabular data resources. "
),
summary=(
"A Datastore API endpoint for managing tabular data resources. "
),
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@datastore/main.py` around lines 130 - 132, The summary string contains a typo
("Datasore"); update the summary value used (the summary parameter in the object
or function where it's defined) to read "A Datastore API endpoint for managing
tabular data resources." so the word "Datastore" is spelled correctly; locate
the summary parameter in datatore/main.py and correct the string literal
accordingly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant