Skip to content

feat: hot reloading - #88

Merged
j03-dev merged 7 commits into
mainfrom
feat/hot_reloading
Jul 22, 2026
Merged

feat: hot reloading#88
j03-dev merged 7 commits into
mainfrom
feat/hot_reloading

Conversation

@j03-dev

@j03-dev j03-dev commented Jul 22, 2026

Copy link
Copy Markdown
Owner
  • feat: add hot reloading
  • chore: make it more configurable
  • chore: updae doc string
  • chore: use new constructor
  • chore: use original repo stub gen

Summary by CodeRabbit

  • New Features
    • Introduced the Oxapy Python server with optional automatic hot-reloading for development.
    • Added APIs to configure watched directories and file patterns, and to run with configurable worker processes.
    • Updated Python type stubs and exports for Oxapy.
    • Added Helix editor language-server configuration for Python (pylsp).
  • Bug Fixes
    • Improved shutdown reliability so the server’s accept loop stops consistently.

@coderabbitai

coderabbitai Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 6bf85edd-7076-426e-ad22-2d32bad4582b

📥 Commits

Reviewing files that changed from the base of the PR and between 0c1b6e1 and efdc3aa.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (1)
  • oxapy/__init__.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • oxapy/init.py

📝 Walkthrough

Walkthrough

Adds the exported Oxapy server with optional watchdog-based hot reloading, shared HttpServer lifecycle state, updated Python type declarations and dependencies, and revised application and fixture startup wiring.

Changes

Oxapy hot-reload server

Layer / File(s) Summary
Native Oxapy API and lifecycle
Cargo.toml, src/lib.rs
Adds the exported Oxapy class, registers it in the Python module, and shares the server running flag with connection handling.
Python supervisor and public surface
oxapy/__init__.py, oxapy/__init__.pyi, pyproject.toml, .helix/languages.toml
Implements watchdog-based worker supervision, restart handling, public stubs, runtime dependencies, and Python language-server configuration.
Application and fixture startup
tests/app.py, tests/conftest.py
Switches startup to Oxapy, configures reload patterns, adds the health route, and updates fixture construction.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Application
  participant Oxapy
  participant Watchdog
  participant Worker
  Application->>Oxapy: run(reload=True)
  Oxapy->>Worker: start with OXAPY_WORKER=1
  Oxapy->>Watchdog: monitor configured files
  Watchdog->>Oxapy: report file change
  Oxapy->>Worker: terminate and restart
Loading

Possibly related PRs

  • j03-dev/oxapy#20: Updates the same Python module initializer used here to expose the Oxapy class.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 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: adding hot reloading support.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
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.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/hot_reloading

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: 7

Caution

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

⚠️ Outside diff range comments (1)
src/lib.rs (1)

439-481: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Shared running flag is not connected to Ctrl+C shutdown.
ShutDownSignal::new() creates its own Arc<AtomicBool>, so the ctrlc handler never flips HttpServer::running. process_requests exits on the shutdown channel, but the accept loop in spawn_connection_handler keeps accepting because self.running stays true. Thread the server’s Arc<AtomicBool> into ShutDownSignal or stop the shared flag from the handler.

🤖 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 `@src/lib.rs` around lines 439 - 481, The server shutdown state is split
between HttpServer::running and the flag owned by ShutDownSignal, so Ctrl+C does
not stop the accept loop. Update setup_serve and the ShutDownSignal construction
to share HttpServer::running, or otherwise have the shutdown handler set that
existing flag, ensuring spawn_connection_handler observes false and stops
accepting connections.
🧹 Nitpick comments (1)
Cargo.toml (1)

18-26: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Pin pyo3-stub-gen to a crates.io release.
A compatible 0.22.x release already exists for PyO3 0.28, so branch = "main" is an unnecessary moving target. If you still need git, pin an explicit commit instead.

🤖 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 `@Cargo.toml` around lines 18 - 26, Update the pyo3-stub-gen dependency in the
[dependencies] section to use the compatible crates.io 0.22.x release instead of
tracking the main branch; preserve its existing default-features and feature
settings, and only use a pinned git commit if a registry release cannot be used.
🤖 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 `@oxapy/__init__.py`:
- Line 18: Add an inline Ruff suppression for F403 to the wildcard import in
__init__.py, or replace it with explicit re-exports from oxapy. Preserve the
package’s existing public exports and follow the file’s established inline
suppression style.
- Around line 82-150: Update the non-zero exit branch in _run_supervisor so it
logs the worker_process.returncode before waiting for reload_requested. Preserve
the existing restart behavior and wait semantics, while clearly indicating that
the worker exited and the supervisor is waiting for a file change.
- Around line 334-347: Update the exception raises and Response return in the
file-serving flow to use the file’s established `# ty:ignore` convention instead
of `# type:ignore`, matching the existing annotations and the migration applied
near line 219. Preserve any necessary diagnostic code while making all three
affected annotations consistent.
- Line 52: Rename the set_watch_dir parameter dir to a non-shadowing name,
update all references within the method, and apply the same parameter rename in
the corresponding set_watch_dir declaration in the .pyi stub to keep the APIs
synchronized.

In `@tests/app.py`:
- Line 9: Update the main function signature in tests/app.py to include the None
return type annotation, making it def main() -> None while preserving its
existing implementation.
- Line 16: Guard the main() call with an if __name__ == "__main__" entrypoint
check so importing tests.app does not start the server; preserve direct script
execution behavior.
- Around line 4-6: Update the greet handler and health route in tests/app.py to
use explicit typed request handlers: make greet accept request as its first
parameter and annotate it with Request, and replace the health lambda with a
named health(request: Request) -> str function. Preserve both routes’ existing
response behavior.

---

Outside diff comments:
In `@src/lib.rs`:
- Around line 439-481: The server shutdown state is split between
HttpServer::running and the flag owned by ShutDownSignal, so Ctrl+C does not
stop the accept loop. Update setup_serve and the ShutDownSignal construction to
share HttpServer::running, or otherwise have the shutdown handler set that
existing flag, ensuring spawn_connection_handler observes false and stops
accepting connections.

---

Nitpick comments:
In `@Cargo.toml`:
- Around line 18-26: Update the pyo3-stub-gen dependency in the [dependencies]
section to use the compatible crates.io 0.22.x release instead of tracking the
main branch; preserve its existing default-features and feature settings, and
only use a pinned git commit if a registry release cannot be used.
🪄 Autofix (Beta)

❌ Autofix failed (check again to retry)

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: 88685447-7f62-443c-bd2f-1bdbc9e002a9

📥 Commits

Reviewing files that changed from the base of the PR and between 1b946a1 and 0c1b6e1.

⛔ Files ignored due to path filters (2)
  • Cargo.lock is excluded by !**/*.lock
  • uv.lock is excluded by !**/*.lock
📒 Files selected for processing (8)
  • .helix/languages.toml
  • Cargo.toml
  • oxapy/__init__.py
  • oxapy/__init__.pyi
  • pyproject.toml
  • src/lib.rs
  • tests/app.py
  • tests/conftest.py

Comment thread oxapy/__init__.py
Comment thread oxapy/__init__.py Outdated
Comment thread oxapy/__init__.py
Comment thread oxapy/__init__.py
Comment thread tests/app.py
Comment on lines 4 to 6
@get("/greet/{name}")
def greet(_r, name: str):
return f"Hello, {name}!"

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.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '--- tests/app.py ---\n'
cat -n tests/app.py | sed -n '1,120p'

printf '\n--- search for request handler guidance/usages ---\n'
rg -n "def .*request|`@get`\\(|health lambda|request: Request|from .*Request" tests -S || true

Repository: j03-dev/oxapy

Length of output: 242


🏁 Script executed:

#!/bin/bash
set -euo pipefail
cat -n tests/app.py | sed -n '1,120p'

Repository: j03-dev/oxapy

Length of output: 589


Use request and type-annotate the handlers. In tests/app.py:4-12, both routes should take request as the first argument, and the health lambda should be a named health(request: Request) -> str handler so both signatures are explicit.

🤖 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 `@tests/app.py` around lines 4 - 6, Update the greet handler and health route
in tests/app.py to use explicit typed request handlers: make greet accept
request as its first parameter and annotate it with Request, and replace the
health lambda with a named health(request: Request) -> str function. Preserve
both routes’ existing response behavior.

Source: Coding guidelines

Comment thread tests/app.py
Comment thread tests/app.py
@coderabbitai

coderabbitai Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Note

Autofix is a beta feature. Expect some limitations and changes as we gather feedback and continue to improve it.

⚠️ Branch updated during autofix.

The branch was updated while autofix was in progress. Please try again.

@j03-dev
j03-dev merged commit 2adfbb2 into main Jul 22, 2026
17 checks passed
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