The Python execution model
Runtime, dev versus production, and deployment.
Runtime
When a BionicJS project includes Python capabilities (AI, Jobs), bionicjs dev spawns a Python child process. This process runs a FastAPI server that handles RPC calls from the Nitro server.
1bionicjs dev
2 |-- Vite (:3000) # the React client
3 |-- Nitro (:3001) # the API / h3 handlers
4 `-- Python (internal) # FastAPI RPC surface (only when ai//jobs/ exist)
The Python process is started and managed by the dev orchestrator. It picks up its dependencies from pyproject.toml, and it is torn down cleanly when the dev server exits. The developer never starts it separately.
The FastAPI server is the RPC surface, not a public API. It is reached from Nitro over an internal channel - never from the browser. There is no CORS, no OAuth flow, and no public route for the browser to hit.
Dev versus production
Everything about the Python process is environment-dependent:
| Concern | Development | Production |
|---|---|---|
| Process | Spawned by bionicjs dev | Supervised (container / systemd) |
| Channel | Internal localhost | Same container or private network |
| Dependencies | Installed on demand | Locked in pyproject.toml / lockfile |
| Failures | Logged to unified terminal | Container restart policy |
Key management is the same in both environments: each provider template writes its expected variables into .env.example, and the Python code reads them from the environment.
Deployment
In production, the deployment model can either run both Node.js and Python in the same container, or split them into separate microservices communicating over a private network. BionicJS generates the Dockerfiles and configurations to support either model.
1same unit split services
2+--------------+ +---------+ +---------+
3| nitro server | <--Python-> | nitro | | fastapi |
4| python proc | | server |<->| worker |
5+--------------+ +---------+ +---------+
6 simpler cloud-native scale-outs
19 / 25