-
Notifications
You must be signed in to change notification settings - Fork 0
feat: add static OpenAPI reference page with Scalar UI #318
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
51f1ffd
75bf3cd
5f6bb2e
dbcaf1f
4e2de83
ebea18c
2d73ff9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,31 +5,31 @@ event: file | |
| conditions: | ||
| - field: file_path | ||
| operator: regex_match | ||
| value: "src/ai_company/.*\\.py$" | ||
| pattern: "src/ai_company/.*\\.py$" | ||
| - field: file_path | ||
| operator: not_contains | ||
| value: "__init__" | ||
| pattern: "__init__" | ||
| - field: file_path | ||
| operator: not_contains | ||
| value: "enums.py" | ||
| pattern: "enums.py" | ||
| - field: file_path | ||
| operator: not_contains | ||
| value: "errors.py" | ||
| pattern: "errors.py" | ||
| - field: file_path | ||
| operator: not_contains | ||
| value: "types.py" | ||
| pattern: "types.py" | ||
| - field: file_path | ||
| operator: not_contains | ||
| value: "models.py" | ||
| pattern: "models.py" | ||
| - field: file_path | ||
| operator: not_contains | ||
| value: "protocol.py" | ||
| pattern: "protocol.py" | ||
| - field: new_text | ||
| operator: regex_match | ||
| value: "^\\s*(?:async\\s+)?(?:def |class )" | ||
| pattern: "^\\s*(?:async\\s+)?(?:def |class )" | ||
|
Comment on lines
27
to
+29
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: cat -n ".claude/hookify.missing-logger.md"Repository: Aureliolo/synthorg Length of output: 1157 This hook no longer detects a missing logger. The rule warns on any change to a qualifying 🤖 Prompt for AI Agents |
||
| - field: file_content | ||
| operator: not_contains | ||
| value: "get_logger" | ||
| pattern: "get_logger" | ||
| action: warn | ||
|
greptile-apps[bot] marked this conversation as resolved.
Comment on lines
25
to
33
|
||
| --- | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| --- | ||
| name: no-future-annotations | ||
| enabled: true | ||
| event: file | ||
| pattern: from\s+__future__\s+import\s+annotations | ||
| action: block | ||
| --- | ||
|
|
||
| **`from __future__ import annotations` is forbidden in this project.** | ||
|
|
||
| Python 3.14 has PEP 649 native lazy annotations, making this import unnecessary. | ||
| The project CLAUDE.md explicitly states: "No `from __future__ import annotations`". | ||
|
|
||
| Remove this import and use native type hints directly. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| rules: | ||
| # Daily Dependabot updates are intentional — see CLAUDE.md and dependabot.yml. | ||
| # The project uses daily checks with grouped minor/patch to stay current. | ||
| dependabot-cooldown: | ||
| action: skip | ||
|
Comment on lines
+4
to
+5
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🌐 Web query:
💡 Result: In Disable a rule (turn the audit off entirely)rules:
template-injection:
disable: trueThis disables that audit completely. [1] Ignore specific findings (preferred vs disabling)
rules:
template-injection:
ignore:
- ci.yml:100 # ignore any column on line 100
- tests.yml # ignore entire file
- pypi.yml:12:10 # ignore a specific line+columnNote: composite-action findings can’t currently be ignored via Ignore via inline comments (one-off suppression)You can ignore an individual finding inline with:
Per-rule options (when supported)Some audits expose additional settings under: rules:
unpinned-uses:
config: { ... }(Only some rules are configurable; it depends on the audit.) [1] “Configuration schema”As of Sources: [1] [2] [3] 🏁 Script executed: # Search for zizmor repository and configuration documentation
# First, let's look for any zizmor-related files in the current repository
git ls-files | head -20Repository: Aureliolo/synthorg Length of output: 684 🌐 Web query:
💡 Result:
For the underlying Dependabot Sources: [1] https://docs.zizmor.sh/audits/ , [2] https://docs.github.com/en/code-security/tutorials/secure-your-dependencies/optimizing-pr-creation-version-updates 🏁 Script executed: # Search for zizmor repository structure to understand rule definitions
curl -s https://api.github.com/repos/nozaq/zizmor/contents | head -50 2>/dev/null || echo "Cannot access GitHub API"Repository: Aureliolo/synthorg Length of output: 341 Replace the unsupported zizmor rule field.
🧰 Tools🪛 GitHub Actions: Workflow Security[error] 5-5: Zizmor configuration error: unknown field 🤖 Prompt for AI Agents |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,4 @@ | ||
| # API Reference | ||
| # Library Reference | ||
|
|
||
| Auto-generated reference documentation from source code docstrings. | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -942,7 +942,7 @@ future CLI tool are thin clients that call the API -- they contain no business l | |||||
| If needed, a thin CLI utility wrapping the REST API with terminal formatting (Typer + Rich | ||||||
| or similar). Not a priority -- the API is fully self-sufficient. To be determined whether a | ||||||
| dedicated CLI is warranted or whether `curl`/`httpie` and the interactive Scalar docs at | ||||||
| `/docs/api` suffice. | ||||||
| `/docs/api` (Scalar UI) and `/docs` (OpenAPI JSON) suffice. | ||||||
|
||||||
| `/docs/api` (Scalar UI) and `/docs` (OpenAPI JSON) suffice. | |
| `/api` (Scalar UI) and `/docs/openapi.json` (OpenAPI JSON) suffice. |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,59 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| {% extends "main.html" %} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| {% block content %} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <style> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /* Strip ALL MkDocs Material width constraints so Scalar fills the viewport */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .md-container, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .md-main, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .md-main__inner, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .md-content, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .md-content__inner { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| max-width: 100%; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| width: 100%; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| margin: 0; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| padding: 0; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /* Override the grid layout that constrains content width */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .md-main__inner { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| display: block; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /* Hide MkDocs sidebar, TOC, and footer on this page */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .md-sidebar, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .md-footer { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| display: none; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /* Scalar fills remaining viewport height below header */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .md-content__inner { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| min-height: calc(100vh - 3.6rem); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| display: flex; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| flex-direction: column; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /* Disclaimer banner */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .rest-api-banner { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| padding: 0.75rem 1.5rem; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| font-size: 0.85rem; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| opacity: 0.7; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| border-bottom: 1px solid var(--md-default-fg-color--lightest); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| flex-shrink: 0; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .rest-api-banner code { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| background: var(--md-code-bg-color); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| padding: 0.1rem 0.4rem; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| border-radius: 0.2rem; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| font-size: 0.8rem; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+31
to
+44
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Avoid reducing banner contrast with container opacity. Applying Proposed fix .rest-api-banner {
padding: 0.75rem 1.5rem;
font-size: 0.85rem;
- opacity: 0.7;
+ color: var(--md-default-fg-color--light);
border-bottom: 1px solid var(--md-default-fg-color--lightest);
flex-shrink: 0;
}📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </style> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <div class="rest-api-banner"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| This is a static snapshot of the OpenAPI schema. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| When the server is running, interactive docs are available at | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <code>/docs/api</code> (Scalar) and <code>/docs</code> (OpenAPI JSON). | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <script | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| id="api-reference" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| data-url="../_generated/openapi.json" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| data-configuration='{"theme": "default", "layout": "modern"}' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ></script> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <script src="https://cdn.jsdelivr.net/npm/@scalar/api-reference@1.48.5"></script> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+47
to
+58
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add a fallback path to the bundled schema. If JS is disabled or jsDelivr is blocked, this page loses its primary content even though the static Proposed fix <div class="rest-api-banner">
This is a static snapshot of the OpenAPI schema.
+ Download the bundled snapshot at <a href="../_generated/openapi.json"><code>_generated/openapi.json</code></a>.
When the server is running, interactive docs are available at
<code>/docs/api</code> (Scalar) and <code>/docs</code> (OpenAPI JSON).
</div>
+
+<noscript>
+ <div class="rest-api-banner">
+ JavaScript is required to render Scalar here. You can still use
+ <a href="../_generated/openapi.json"><code>_generated/openapi.json</code></a>.
+ </div>
+</noscript>
<script
id="api-reference"🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| {% endblock %} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| --- | ||
| template: rest-api.html | ||
| --- | ||
|
|
||
| # REST API Reference |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| """Export the Litestar OpenAPI schema to a static JSON file. | ||
|
|
||
| Used by CI (pages.yml, pages-preview.yml) to generate | ||
| ``docs/_generated/openapi.json`` before the MkDocs build, so the | ||
| static Scalar-based REST API reference page in MkDocs can load the schema. | ||
| """ | ||
|
|
||
| import json | ||
| import sys | ||
| from pathlib import Path | ||
|
|
||
| # Repository root is the parent of the scripts/ directory | ||
| REPO_ROOT = Path(__file__).resolve().parent.parent | ||
| OUTPUT_DIR = REPO_ROOT / "docs" / "_generated" | ||
| OUTPUT_FILE = OUTPUT_DIR / "openapi.json" | ||
|
|
||
|
|
||
| def main() -> int: | ||
| """Instantiate the app, extract the OpenAPI schema, and write JSON.""" | ||
| try: | ||
| from ai_company.api.app import create_app | ||
|
|
||
| app = create_app() | ||
| schema_dict = app.openapi_schema.to_schema() | ||
| except Exception as exc: | ||
| print(f"Failed to export OpenAPI schema: {exc}", file=sys.stderr) | ||
| return 1 | ||
|
Comment on lines
+25
to
+27
|
||
|
|
||
| OUTPUT_DIR.mkdir(parents=True, exist_ok=True) | ||
| OUTPUT_FILE.write_text( | ||
| json.dumps(schema_dict, indent=2, ensure_ascii=False) + "\n", | ||
| encoding="utf-8", | ||
| ) | ||
| print(f"Wrote OpenAPI schema to {OUTPUT_FILE.relative_to(REPO_ROOT)}") | ||
|
Comment on lines
+29
to
+34
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. File write errors produce a raw traceback instead of a clean error message The Consider wrapping the write phase in the same (or a separate) OUTPUT_DIR.mkdir(parents=True, exist_ok=True)
try:
OUTPUT_FILE.write_text(
json.dumps(schema_dict, indent=2, ensure_ascii=False) + "\n",
encoding="utf-8",
)
except OSError as exc:
print(f"Failed to write OpenAPI schema to {OUTPUT_FILE}: {exc}", file=sys.stderr)
return 1Prompt To Fix With AIThis is a comment left during a code review.
Path: scripts/export_openapi.py
Line: 29-34
Comment:
**File write errors produce a raw traceback instead of a clean error message**
The `OUTPUT_DIR.mkdir(...)` and `OUTPUT_FILE.write_text(...)` calls are outside the `try/except` block. If either fails (e.g., permission denied, disk full), Python will emit an unhandled exception traceback directly to stderr with no contextual message, and the exit code will be `1` from Python's default handler — which is correct behaviour, but the error output will be harder to interpret in CI logs than the clean message produced for the import/schema failure path.
Consider wrapping the write phase in the same (or a separate) `try/except` with a diagnostic `print(..., file=sys.stderr)` so both failure modes produce equally readable CI output:
```python
OUTPUT_DIR.mkdir(parents=True, exist_ok=True)
try:
OUTPUT_FILE.write_text(
json.dumps(schema_dict, indent=2, ensure_ascii=False) + "\n",
encoding="utf-8",
)
except OSError as exc:
print(f"Failed to write OpenAPI schema to {OUTPUT_FILE}: {exc}", file=sys.stderr)
return 1
```
How can I resolve this? If you propose a fix, please make it concise. |
||
| return 0 | ||
|
|
||
|
|
||
| if __name__ == "__main__": | ||
| sys.exit(main()) | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This
missing-loggerrule seems to have been made overly broad by the removal of the condition that checks for the presence ofget_logger. As it is now, it will trigger a warning for every new class or function, even in files that already have a logger. This is likely to create a lot of unnecessary warnings for developers.To fix this, I suggest re-introducing the check for the absence of
get_logger. You could add the following condition to the list: