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


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.valohai.com/serving-your-models/real-time-endpoints/deployment-prefix.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
