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

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

```python
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:**

```python
@app.post("{full_path:path}")
def predict_any(full_path: str):
    # Handle request regardless of prefix
    pass
```

**Flask:**

```python
@app.route("/<path:full_path>", methods=["POST"])
def predict_any(full_path):
    # Handle request regardless of prefix
    pass
```

***

**Need help?** Check out the [troubleshooting guide](https://github.com/valohai/dokuhai/blob/main/docs/debug.md) for common routing issues.
