Skip to content

Add structured /health endpoint with dependency checks - #76

Merged
zeemscript merged 8 commits into
Deen-Bridge:devfrom
Flor125:health-check-endpoint
Jul 29, 2026
Merged

Add structured /health endpoint with dependency checks#76
zeemscript merged 8 commits into
Deen-Bridge:devfrom
Flor125:health-check-endpoint

Conversation

@Flor125

@Flor125 Flor125 commented Jul 26, 2026

Copy link
Copy Markdown
Contributor

Closes #20

Summary by CodeRabbit

  • New Features
    • Added a structured GET /health endpoint that returns JSON service status, with optional deeper readiness details via a query parameter.
  • Reliability
    • Improved scheduled keep-alive checks to call /health, fail on HTTP errors, and retry with a per-request timeout.
  • Documentation
    • Updated API docs to distinguish GET /ping (liveness) from GET /health (health/readiness).
  • Chores
    • Updated ignore rules and removed committed virtual environment artifacts from the repository.

@coderabbitai

coderabbitai Bot commented Jul 26, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

The service adds a structured /health endpoint, wires it into Render and the keep-awake workflow, documents /ping and /health, and updates repository ignore rules and vendored metadata.

Changes

Health check integration

Layer / File(s) Summary
Health endpoint implementation
main.py, README.md
Adds /health with configuration-based JSON status reporting and documents both health routes.
Deployment health-check wiring
render.yaml, .github/workflows/keep-render-awake.yml
Configures Render and the keep-awake workflow to use /health with HTTP failure detection, timeout, and retries.

Environment cleanup

Layer / File(s) Summary
Environment ignore and metadata cleanup
.gitignore, venv/lib/python3.12/site-packages/pip/_vendor/packaging/__init__.py
Ignores venv/ and .DS_Store, and removes vendored packaging metadata constants.

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

Possibly related issues

  • Deen-Bridge/dnb-backend#14 — Covers equivalent /health, /ping, and keep-awake workflow requirements.

Sequence Diagram(s)

sequenceDiagram
  participant KeepAwakeWorkflow
  participant RenderService
  participant HealthEndpoint
  participant GeminiConfiguration
  KeepAwakeWorkflow->>RenderService: GET /health
  RenderService->>HealthEndpoint: route request
  HealthEndpoint->>GeminiConfiguration: check API key configuration
  GeminiConfiguration-->>HealthEndpoint: return health status
  HealthEndpoint-->>KeepAwakeWorkflow: JSON response with 200 or 503
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning The PR includes massive unrelated deletions under venv/ and vendored packages, which are far outside the health endpoint work. Remove the venv/ and vendored-package deletions from this PR, and keep only the health endpoint, workflow, Render, and README changes.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The summary indicates the /health route, Render health check, keep-awake workflow, README updates, and opt-in deep checks were added as requested.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title matches the main change: a new structured /health endpoint with dependency checks.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

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 `@main.py`:
- Line 752: Remove the extra whitespace before the colon in the "status" key
within the affected mapping, preserving the existing key and value while making
the syntax flake8 E203-compliant.
- Around line 747-750: Update the health endpoint’s deep handling around the
checks["gemini_api_reachable"] assignment: either implement a bounded Gemini
reachability probe that marks the check failed and returns a non-200 health
response when unavailable, or remove the deep parameter and its skipped check
until real behavior exists. Ensure deep=true changes the health verdict rather
than returning 200 with a skipped check.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

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

Comment thread main.py
Comment thread main.py Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Caution

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

⚠️ Outside diff range comments (2)
main.py (2)

448-453: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Apply the requested language to normal /chat generation.

Line 453 normalizes the language, but the non-streaming prompt never adds LANGUAGE_INSTRUCTIONS or response_language (unlike the streaming path). /chat can therefore return a response in the wrong language while reporting the requested language in its payload.

Proposed fix
             system_context = ISLAMIC_CONTEXT + HADITH_ADAB_CONTEXT
+            system_context += LANGUAGE_INSTRUCTIONS
+            if effective_language:
+                system_context += f"\nresponse_language: {effective_language}"
+            else:
+                system_context += "\nresponse_language: auto (respond in the user's language)"
             if is_fiqh:
🤖 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 `@main.py` around lines 448 - 453, Update the non-streaming /chat generation
flow after effective_language is computed in the classification block to apply
LANGUAGE_INSTRUCTIONS and pass response_language, matching the existing
streaming path. Ensure generated responses use the requested normalized language
while preserving the reported language payload.

502-509: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Do not reuse cached responses across explicit language requests.

The semantic-cache lookup is keyed only by prompt embedding, so a cached English response can be returned to a later Arabic request for the same prompt. Line 508 then labels that response as Arabic. Partition the cache by language, or bypass it whenever a supported language was explicitly requested.

Minimal safe fix
         is_cacheable = (
             is_new_chat
             and request.context is None
+            and effective_language is None
             and tafsir_context is None
             and zakat_context is None
             and SEMANTIC_CACHE_ENABLED
🤖 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 `@main.py` around lines 502 - 509, Update the semantic-cache path around the
ChatResponse construction to prevent reuse of cached responses when the caller
explicitly requests a supported language. Bypass the cache for explicit language
requests, or include the requested language in the cache key, while preserving
cached responses for requests without an explicit language.
🤖 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.

Outside diff comments:
In `@main.py`:
- Around line 448-453: Update the non-streaming /chat generation flow after
effective_language is computed in the classification block to apply
LANGUAGE_INSTRUCTIONS and pass response_language, matching the existing
streaming path. Ensure generated responses use the requested normalized language
while preserving the reported language payload.
- Around line 502-509: Update the semantic-cache path around the ChatResponse
construction to prevent reuse of cached responses when the caller explicitly
requests a supported language. Bypass the cache for explicit language requests,
or include the requested language in the cache key, while preserving cached
responses for requests without an explicit language.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 7a222172-d2ce-4991-93ad-4b07f518276e

📥 Commits

Reviewing files that changed from the base of the PR and between 0e603a2 and c676f26.

📒 Files selected for processing (3)
  • README.md
  • main.py
  • render.yaml
🚧 Files skipped from review as they are similar to previous changes (2)
  • render.yaml
  • README.md

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Caution

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

⚠️ Outside diff range comments (4)
main.py (4)

121-128: 🚀 Performance & Scalability | 🟠 Major | ⚡ Quick win

Bound prompt and context in ChatRequest. These fields are plain strs, so a single oversized request can bloat memory and drive unnecessary retrieval/Gemini work in both chat endpoints. Add min_length/max_length constraints at the Pydantic boundary.

🤖 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 `@main.py` around lines 121 - 128, Update the ChatRequest model to constrain
prompt and context with appropriate Pydantic min_length and max_length bounds,
while preserving their existing optional/required behavior and ensuring both
chat endpoints receive validated input.

Source: Path instructions


127-128: 🔒 Security & Privacy | 🟠 Major | 🏗️ Heavy lift

Bind memory access to an authenticated principal.

The caller controls user_id, which is then used to read and write memory. The public /memory/{user_id} routes also allow profile retrieval and deletion without authorization; the existing TODO explicitly acknowledges this exposure. Derive the identifier from authentication, or reject mismatches before any memory operation.

Also applies to: 488-490, 715-719, 989-1013

🤖 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 `@main.py` around lines 127 - 128, Update the memory request handling around
the user_id field and the public /memory/{user_id} routes to require an
authenticated principal, derive the effective user identifier from that
principal, and reject any caller-supplied mismatch before reading, writing,
retrieving, or deleting memory. Apply the same authorization check to the
referenced memory operation paths and remove the exposed unauthenticated access
acknowledged by the existing TODO.

127-127: 🎯 Functional Correctness | 🔴 Critical | ⚡ Quick win

Import Field from Pydantic
ChatRequest.user_id uses Field(...), but main.py only imports BaseModel. That leaves Field undefined and breaks module import/CI.

🤖 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 `@main.py` at line 127, Update the Pydantic import in main.py to include Field
alongside BaseModel so the ChatRequest.user_id declaration resolves correctly
and the module imports successfully.

Sources: Path instructions, Linters/SAST tools


716-720: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Keep a strong reference to these background tasks (main.py:716-720, 729-736). Dropping the Task object means the memory extraction and history summarization jobs can be collected before they finish. Store them in a set and remove them in a done callback, or use a managed background-task facility.

🤖 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 `@main.py` around lines 716 - 720, Update the background task creation around
_extract_and_update_memory and the corresponding history summarization task to
retain each asyncio.Task in a managed set, then remove it via a done callback
after completion. Ensure both jobs remain strongly referenced until they finish.

Sources: Path instructions, 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.

Outside diff comments:
In `@main.py`:
- Around line 121-128: Update the ChatRequest model to constrain prompt and
context with appropriate Pydantic min_length and max_length bounds, while
preserving their existing optional/required behavior and ensuring both chat
endpoints receive validated input.
- Around line 127-128: Update the memory request handling around the user_id
field and the public /memory/{user_id} routes to require an authenticated
principal, derive the effective user identifier from that principal, and reject
any caller-supplied mismatch before reading, writing, retrieving, or deleting
memory. Apply the same authorization check to the referenced memory operation
paths and remove the exposed unauthenticated access acknowledged by the existing
TODO.
- Line 127: Update the Pydantic import in main.py to include Field alongside
BaseModel so the ChatRequest.user_id declaration resolves correctly and the
module imports successfully.
- Around line 716-720: Update the background task creation around
_extract_and_update_memory and the corresponding history summarization task to
retain each asyncio.Task in a managed set, then remove it via a done callback
after completion. Ensure both jobs remain strongly referenced until they finish.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: e204a0d7-309f-4141-814b-dffc42fb09af

📥 Commits

Reviewing files that changed from the base of the PR and between c676f26 and de0f175.

📒 Files selected for processing (2)
  • README.md
  • main.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • README.md

@Flor125
Flor125 force-pushed the health-check-endpoint branch from de0f175 to b52305e Compare July 28, 2026 01:01

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 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 `@README.md`:
- Around line 50-57: Resolve the conflict in the README API table by removing
all merge markers and preserving the intended entries for /ping and /health,
along with the existing /memory/{user_id} endpoints. Ensure the resulting table
is valid Markdown and reflects both API behaviors.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

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

Comment thread README.md Outdated
@Flor125 Flor125 closed this Jul 28, 2026
@Flor125 Flor125 reopened this Jul 28, 2026
@zeemscript
zeemscript merged commit 6342f65 into Deen-Bridge:dev Jul 29, 2026
3 checks passed
@Flor125
Flor125 deleted the health-check-endpoint branch July 29, 2026 19:38
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.

2 participants