Route Prefixes
Valohai serves your deployment under a specific URL path. If your application uses path-based routing, you need to handle these prefixes correctly.
How prefixes work
Valohai provides two ways to access the current prefix:
VH_DEFAULT_PREFIX environment variable Contains the default prefix: organization/project/deployment/version/endpoint
X-VH-Prefix HTTP header Contains the actual prefix used (accounts for aliases): organization/project/deployment/alias/endpoint
When you need this
If your app uses path-based routing: Routes like /predict, /health, /v1/inference need prefix handling
If your routes are RPC-style or query-based: You likely don't need this
FastAPI example
Use middleware to strip the prefix from incoming requests:
import os
from fastapi import FastAPI
from starlette.requests import Request
app = FastAPI()
@app.middleware("http")
async def process_valohai_prefix(request: Request, call_next):
path = request.scope["path"]
# Check both header and environment variable
for prefix in (
request.headers.get("X-VH-Prefix"),
os.environ.get("VH_DEFAULT_PREFIX"),
):
if not prefix:
continue
if path.startswith(prefix):
# Tell FastAPI about the mount point
request.scope["root_path"] = prefix
# Strip the prefix for internal routing
request.scope["path"] = "/" + path[len(prefix):].lstrip("/")
break
return await call_next(request)
@app.get("/predict")
def predict(name: str):
return {"predicted_first_letter": name[:1].lower()}How it works:
Middleware runs before route matching
Extracts prefix from header or environment
Strips prefix so your routes match correctly
Flask example
Use WSGI middleware for the same functionality:
import os
from functools import wraps
from flask import Flask, request, jsonify
from werkzeug import run_simple
def handle_valohai_prefix(environ):
"""Strip Valohai prefix from request path."""
path = environ["PATH_INFO"]
for prefix in (
environ.get("HTTP_X_VH_PREFIX"),
os.environ.get("VH_DEFAULT_PREFIX"),
):
if not prefix:
continue
if path.startswith(prefix):
environ["PATH_INFO"] = "/" + path[len(prefix):].lstrip("/")
break
def manage_prefixes(app):
"""Decorator to apply prefix management to WSGI app."""
@wraps(app)
def prefix_managed_app(environ, start_response):
handle_valohai_prefix(environ)
return app(environ, start_response)
return prefix_managed_app
app = Flask(__name__)
@app.route("/predict")
def predict():
name = request.args.get("name", "")
return jsonify({"predicted_first_letter": name[:1].lower()})
# Apply middleware
app = manage_prefixes(app)
if __name__ == "__main__":
run_simple("0", 8000, use_reloader=True, application=app)Alternative: Accept any prefix
If you don't need specific route paths, configure your app to accept any prefix:
FastAPI:
@app.post("{full_path:path}")
def predict_any(full_path: str):
# Handle request regardless of prefix
passFlask:
@app.route("/<path:full_path>", methods=["POST"])
def predict_any(full_path):
# Handle request regardless of prefix
passNeed help? Check out the troubleshooting guide for common routing issues.
Last updated
Was this helpful?
