Skip to content

feat: Generate and publish API documentation for core services#176

Merged
S3DFX-CYBER merged 9 commits into
TENET-DEV-AI:mainfrom
agsaru:api-doc
Jul 4, 2026
Merged

feat: Generate and publish API documentation for core services#176
S3DFX-CYBER merged 9 commits into
TENET-DEV-AI:mainfrom
agsaru:api-doc

Conversation

@agsaru

@agsaru agsaru commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

🤖 TENET Agent will automatically review this PR for security issues and code quality.
Maintainers: to have TENET solve an issue autonomously, comment /tenet fix on the issue.


Summary

Key Changes

  • Added Swagger/OpenAPI documentation for the analyzer and ingest APIs.
  • Improved API documentation with endpoint descriptions, tags, and parameter validation.
  • Enabled testing APIs in Swagger UI using the x-api-key header.
  • Added standard error response models for 401, 403, 404, and 429 errors.
  • Updated README files with instructions for accessing API documentation.
  • Added a GitHub Actions workflow to automatically publish API documentation on GitHub Pages when changes are pushed to main.

Related Issue

Fixes #98


Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation update
  • CI/CD Improvement
  • Added Tests

Screenshots / Logs (Optional)


How Has This Been Tested?

  • Unit tests
  • Integration tests
  • Manual testing

Checklist

  • My code follows the project's code style
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes

Additional Notes (Optional)



Summary by cubic

Generates and publishes OpenAPI docs for the Ingest and Analyzer services on every push to main. Adds Swagger UI/ReDoc with API key auth, standardized errors, endpoint tags, and a landing page with live Petstore links.

  • New Features

    • Added tags, summaries, and descriptions across endpoints (System, Events, Metrics, Audit, Analysis).
    • Enforced and documented API key auth using fastapi.security.APIKeyHeader + Security (X-API-Key for Ingest, x-api-key for Analyzer).
    • Introduced shared ErrorResponse and documented common errors (401/403/404/422/429/503).
    • CI: .github/workflows/publish-doc.yml imports FastAPI apps to export schemas, sets mock REDIS_HOST for init, builds a landing page with dynamic Petstore links, uploads via actions/upload-pages-artifact, configures with actions/configure-pages, deploys with actions/deploy-pages; READMEs document local /docs, /redoc, and schema URLs with Swagger auth steps.
  • Bug Fixes

    • Ingest unit test now expects 401 when the API key is missing.

Written for commit 1daa4c3. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

  • Documentation
    • Added “API Documentation & Deployment” sections to the Analyzer and Ingest service READMEs with links to Swagger UI, ReDoc, and the OpenAPI JSON.
    • Enhanced API endpoint documentation with clearer summaries/descriptions and standardized documented error responses.
  • New Features
    • Documented API-key security in the OpenAPI specs for secured endpoints.
  • Bug Fixes
    • Updated the Ingest API test to expect 401 Unauthorized when the API key is missing.
  • Chores
    • Added automation to publish interactive API documentation to GitHub Pages on main updates.

Copilot AI review requested due to automatic review settings June 16, 2026 15:05
@vercel

vercel Bot commented Jun 16, 2026

Copy link
Copy Markdown

@agsaru is attempting to deploy a commit to the s3dfx-cyber's projects Team on Vercel.

A member of the Team first needs to authorize it.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@coderabbitai

coderabbitai Bot commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Both FastAPI services now advertise API-key security and richer OpenAPI metadata, a new workflow publishes generated docs to GitHub Pages, and both service READMEs describe the docs URLs and authorization steps.

Changes

OpenAPI Documentation and GitHub Pages Publishing

Layer / File(s) Summary
Ingest API security and route metadata
services/ingest/app.py
Adds the ingest API-key security scheme and ErrorResponse model, updates endpoint decorators with OpenAPI metadata, and switches authenticated handlers to Security(api_key_scheme) while documenting error responses.
Analyzer API security and route metadata
services/analyzer/app.py
Adds the analyzer API-key security scheme and ErrorResponse model, and expands /health and /v1/analyze with OpenAPI metadata and documented security/error responses.
GitHub Pages publishing workflow
.github/workflows/publish-doc.yml
Adds a workflow that generates OpenAPI JSON for both services, builds a static landing page, and deploys the artifact to GitHub Pages.
README API documentation sections
services/analyzer/README.md, services/ingest/README.md
Adds API documentation and deployment sections covering Swagger UI/ReDoc/openapi.json access, API-key authorization, and GitHub Pages publication.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Suggested labels: documentation, Hard

Suggested reviewers: S3DFX-CYBER

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.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
Linked Issues check ✅ Passed The changes satisfy #98 by adding OpenAPI docs, auth examples, error schemas, deployment docs, and GitHub Pages publishing.
Out of Scope Changes check ✅ Passed The modified files stay aligned with the documentation and publishing goals, with no clear unrelated changes.
Title check ✅ Passed The title clearly summarizes the main change: generating and publishing API documentation for the core services.
Description check ✅ Passed The description matches the template with summary, issue link, type of change, testing, checklist, and notes sections filled in.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
services/analyzer/app.py (1)

210-226: ⚠️ Potential issue | 🟠 Major

Header parameter required state bypasses documented 401/403 error contract.

At line 225, x_api_key: Annotated[str, Header(...)] is marked required. FastAPI validates this parameter during dependency resolution before executing the endpoint function, so missing headers return 422 (validation error) instead of allowing security.require_auth() to return the documented 401/403 errors.

Change the header to optional and retrieve it via the Security dependency instead:

Suggested fix
 `@app.post`(
     "/v1/analyze",
     response_model=AnalysisResponse,
     tags=["Analysis"],
     summary="Analyze Prompt",
     description="Analyzes a given prompt for security threats using both heuristic rules and ML-based detection. Requires a valid API key.",
     responses={
         401: {"model": ErrorResponse, "description": "Invalid API key"},
         403: {"model": ErrorResponse, "description": "Insufficient permissions"},
         429: {"model": ErrorResponse, "description": "Rate limit or quota exceeded"}
     },
-    dependencies=[Security(api_key_scheme)]
 )
 async def analyze_prompt(
     request: AnalysisRequest,
-    x_api_key: Annotated[str, Header(...)]
+    x_api_key: Annotated[Optional[str], Security(api_key_scheme)]
 ):

Note: Update require_auth() call to handle the now-optional header value.

🤖 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 `@services/analyzer/app.py` around lines 210 - 226, The x_api_key header
parameter in the analyze_prompt function is currently marked as required,
causing FastAPI to return a 422 validation error for missing headers before the
Security dependency can validate it and return the documented 401/403 errors.
Change the x_api_key header parameter from required to optional by modifying its
type annotation, then update the require_auth() call within the endpoint to
handle the now-optional header value appropriately. This allows the Security
dependency and require_auth() function to control the validation response and
return the correct 401/403 error codes as documented in the endpoint's responses
specification.
🤖 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 @.github/publish-doc.yml:
- Around line 69-77: The "Create Landing Page" step is attempting to interpolate
the page_url output from steps.deployment, but this output is not yet available
since the "Deploy to GitHub Pages" step executes later in the workflow. This
causes the Swagger URLs in lines 69 and 76 to resolve to empty strings,
resulting in invalid links. Move the HTML file generation that creates the
landing page with the Swagger URL references to execute after the "Deploy to
GitHub Pages" step completes, so the page_url output is available for proper
interpolation. Alternatively, regenerate the index.html file in a separate step
that runs after deployment.
- Around line 86-89: Replace the `actions/upload-artifact@v7.0.1` action with
`actions/upload-pages-artifact` in the Upload artifact step. The
`actions/upload-pages-artifact` action automatically handles the required gzip
archive format and names the artifact as `github-pages`, which is necessary for
the subsequent `actions/deploy-pages@v5` deployment to succeed. Make this change
at the location shown (lines 86-89) and also apply the same replacement at the
other Upload artifact step mentioned at lines 91-93 in the same file.

In `@services/ingest/app.py`:
- Around line 332-346: Multiple route handlers use `x_api_key: str =
Header(...)` as a function parameter, which causes FastAPI to validate the
header as required before the handler runs, triggering a 422 response for
missing headers instead of allowing the security logic to return 401/403 as
documented. Replace the `Header(...)` parameter with `Security(api_key_scheme)`
in the ingest_llm_event function and in all other affected handlers (at lines
456-472, 506-521, 544-557, 594-606, and 616-628) to let the security scheme with
`auto_error=False` handle the validation and pass the header value (or None)
directly to the handler for proper error handling.

---

Outside diff comments:
In `@services/analyzer/app.py`:
- Around line 210-226: The x_api_key header parameter in the analyze_prompt
function is currently marked as required, causing FastAPI to return a 422
validation error for missing headers before the Security dependency can validate
it and return the documented 401/403 errors. Change the x_api_key header
parameter from required to optional by modifying its type annotation, then
update the require_auth() call within the endpoint to handle the now-optional
header value appropriately. This allows the Security dependency and
require_auth() function to control the validation response and return the
correct 401/403 error codes as documented in the endpoint's responses
specification.
🪄 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 Plus

Run ID: 58edfc6e-0b16-4dc0-99d8-5832ff5824f7

📥 Commits

Reviewing files that changed from the base of the PR and between aed4a99 and fb3814d.

📒 Files selected for processing (5)
  • .github/publish-doc.yml
  • services/analyzer/README.md
  • services/analyzer/app.py
  • services/ingest/README.md
  • services/ingest/app.py

Comment thread .github/publish-doc.yml Outdated
Comment thread .github/publish-doc.yml Outdated
Comment thread services/ingest/app.py

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

1 issue found and verified against the latest diff

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread services/ingest/app.py
Copilot AI review requested due to automatic review settings June 16, 2026 17:53

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick comments (2)
services/ingest/app.py (1)

150-155: 💤 Low value

Header name casing differs from analyzer service.

The analyzer service defines the header as x-api-key (lowercase) while this service uses X-API-Key (mixed case). Although HTTP headers are case-insensitive at runtime, the OpenAPI documentation will display different header names, potentially confusing API consumers.

Consider aligning with the analyzer service for consistency:

Suggested change
 api_key_scheme = APIKeyHeader(
-    name="X-API-Key", 
+    name="x-api-key", 
     description="Enter your TENET AI API key to authenticate requests.",
     auto_error=False
 )
🤖 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 `@services/ingest/app.py` around lines 150 - 155, The APIKeyHeader
instantiation for api_key_scheme uses mixed case header name X-API-Key, but the
analyzer service uses lowercase x-api-key for the same purpose. Change the name
parameter in the APIKeyHeader constructor from "X-API-Key" to "x-api-key" to
align with the analyzer service and ensure consistent OpenAPI documentation
across services.
.github/workflows/publish-doc.yml (1)

93-102: ⚡ Quick win

Consider pinning actions to commit SHAs for supply chain security.

The static analysis tool flags that actions are pinned to version tags rather than commit hashes. While version tags are common for first-party GitHub actions, pinning to SHAs provides stronger supply chain security by preventing tag-mutation attacks.

Example for actions/configure-pages:

# Instead of:
uses: actions/configure-pages@v6.0.0
# Use:
uses: actions/configure-pages@<commit-sha>  # v6.0.0

This applies to configure-pages, upload-pages-artifact, and deploy-pages.

🤖 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 @.github/workflows/publish-doc.yml around lines 93 - 102, Replace the version
tag references for the three GitHub Actions with their corresponding commit SHAs
to improve supply chain security. For actions/configure-pages,
actions/upload-pages-artifact, and actions/deploy-pages, change each occurrence
from the format `@v`<version> (such as `@v6.0.0` or `@v5.0.0`) to the format
@<commit-sha>, optionally including the version tag as a comment after the SHA
for reference.

Source: Linters/SAST tools

🤖 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.

Nitpick comments:
In @.github/workflows/publish-doc.yml:
- Around line 93-102: Replace the version tag references for the three GitHub
Actions with their corresponding commit SHAs to improve supply chain security.
For actions/configure-pages, actions/upload-pages-artifact, and
actions/deploy-pages, change each occurrence from the format `@v`<version> (such
as `@v6.0.0` or `@v5.0.0`) to the format @<commit-sha>, optionally including the
version tag as a comment after the SHA for reference.

In `@services/ingest/app.py`:
- Around line 150-155: The APIKeyHeader instantiation for api_key_scheme uses
mixed case header name X-API-Key, but the analyzer service uses lowercase
x-api-key for the same purpose. Change the name parameter in the APIKeyHeader
constructor from "X-API-Key" to "x-api-key" to align with the analyzer service
and ensure consistent OpenAPI documentation across services.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 78d1c154-4a02-4c7e-83b7-0d3ba42250ca

📥 Commits

Reviewing files that changed from the base of the PR and between fb3814d and 4f97dea.

📒 Files selected for processing (2)
  • .github/workflows/publish-doc.yml
  • services/ingest/app.py

@agsaru

agsaru commented Jun 21, 2026

Copy link
Copy Markdown
Contributor Author

@S3DFX-CYBER Review

Copilot AI review requested due to automatic review settings June 28, 2026 16:00

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review is ineligible. To be eligible to request a review, you need a paid Copilot license, or your organization must enable Copilot code review.

@vercel

vercel Bot commented Jun 28, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
tenet-ai.org Ready Ready Preview, Comment Jul 4, 2026 6:56pm

@S3DFX-CYBER

Copy link
Copy Markdown
Collaborator

@coderabbitai why is so many prs having CI test failure

@coderabbitai

coderabbitai Bot commented Jun 28, 2026

Copy link
Copy Markdown
Contributor

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== PR `#176` check status =="
gh pr view 176 --repo TENET-DEV-AI/TENET-AI --json number,title,headRefName,baseRefName,statusCheckRollup \
  | jq '{
      number,
      title,
      headRefName,
      baseRefName,
      checks: [.statusCheckRollup[] | {
        name: (.name // .context // "unknown"),
        status: .status,
        conclusion: .conclusion,
        detailsUrl: (.detailsUrl // "")
      }]
    }'

echo
echo "== Recent PRs and their mergeability/status =="
gh pr list --repo TENET-DEV-AI/TENET-AI --limit 15 --state all \
  --json number,title,state,mergeStateStatus,headRefName,baseRefName,updatedAt \
  | jq '.[] | {number,title,state,mergeStateStatus,headRefName,baseRefName,updatedAt}'

echo
echo "== Recent workflow runs (last 20) =="
gh run list --repo TENET-DEV-AI/TENET-AI --limit 20 --json databaseId,workflowName,displayTitle,event,status,conclusion,headBranch,createdAt,updatedAt,url \
  | jq '.[] | {databaseId,workflowName,displayTitle,event,status,conclusion,headBranch,createdAt,updatedAt,url}'

echo
echo "== Workflow files in repo =="
fd .github/workflows -t f . || true

echo
echo "== Outline of workflow files =="
fd -t f .github/workflows | while read -r f; do
  echo "-- $f"
  sed -n '1,220p' "$f"
  echo
done

Length of output: 17493


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Workflow files =="
fd . .github/workflows -t f

echo
for f in $(fd . .github/workflows -t f | sort); do
  echo "===== FILE: $f ====="
  sed -n '1,240p' "$f"
  echo
done

echo
echo "== CI run `#28327889584` jobs =="
gh run view 28327889584 --repo TENET-DEV-AI/TENET-AI --json jobs \
  | jq '.jobs[] | {name, conclusion, startedAt, completedAt, steps: [.steps[] | {name, conclusion, number}]}'

echo
echo "== CI run `#28327889584` failed log =="
gh run view 28327889584 --repo TENET-DEV-AI/TENET-AI --log-failed || true

echo
echo "== CI run `#28327809439` jobs =="
gh run view 28327809439 --repo TENET-DEV-AI/TENET-AI --json jobs \
  | jq '.jobs[] | {name, conclusion, startedAt, completedAt, steps: [.steps[] | {name, conclusion, number}]}'

echo
echo "== CI run `#28327809439` failed log =="
gh run view 28327809439 --repo TENET-DEV-AI/TENET-AI --log-failed || true

echo
echo "== TENET Agent PR Review run `#28327889589` jobs =="
gh run view 28327889589 --repo TENET-DEV-AI/TENET-AI --json jobs \
  | jq '.jobs[] | {name, conclusion, startedAt, completedAt, steps: [.steps[] | {name, conclusion, number}]}'

echo
echo "== TENET Agent PR Review run `#28327889589` failed log =="
gh run view 28327889589 --repo TENET-DEV-AI/TENET-AI --log-failed || true

Length of output: 52554



@S3DFX-CYBER it looks like many PRs are failing for repo-wide CI configuration reasons, not because every PR is broken.

What’s happening:

  • CI is failing before tests even start in .github/workflows/ci.yml
    • That workflow uses Python 3.11
    • But dependency install now requires numpy>=2.5.0
    • The log shows NumPy 2.5.0 requires Python >=3.12, so pip install -r requirements-dev.txt fails immediately
    • That’s why even a docs-only PR and a push to main are failing the same way

Exact failure:

  • ERROR: Could not find a version that satisfies the requirement numpy>=2.5.0
  • 2.5.0 Requires-Python >=3.12

Second failure source:

  • TENET Security Review from .github/workflows/tenet-pr-review.yml
    • The log says: TENET_AI_KEY secret is not set
    • Even though there is a check step, the workflow still proceeds to the review step and then exits with code 1

So the short answer is:

  1. CI is broken globally by a Python/dependency mismatch
    (ci.yml uses 3.11, but numpy>=2.5.0 needs 3.12)

  2. The custom TENET PR review workflow is also failing globally
    because TENET_AI_KEY is missing / not usable in that workflow

If you want, I can help identify the smallest fix for both workflows.
(Probably: update CI to Python 3.12 or relax NumPy, and make the TENET review step skip cleanly when the secret is absent.)

(/)_(\ /)

@S3DFX-CYBER S3DFX-CYBER added SSoC26 Social Summer of Code 2026 S5 Medium 30 pts labels Jul 4, 2026
@S3DFX-CYBER S3DFX-CYBER merged commit 4cf699b into TENET-DEV-AI:main Jul 4, 2026
11 of 13 checks passed
@S3DFX-CYBER S3DFX-CYBER added the documentation Improvements or additions to documentation label Jul 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation Medium 30 pts SSoC26 Social Summer of Code 2026 S5

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Generate and Publish API Documentation

3 participants