Skip to content

Commit

Permalink
Adds PREFECT_SERVER_API_BASE_PATH setting (#16967)
Browse files Browse the repository at this point in the history
  • Loading branch information
cicdw authored Feb 20, 2025
1 parent f6d728a commit c4b74cf
Show file tree
Hide file tree
Showing 6 changed files with 55 additions and 6 deletions.
14 changes: 13 additions & 1 deletion docs/v3/develop/settings-ref.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -950,7 +950,7 @@ Controls maximum overflow of the connection pool. To prevent overflow, set to -1
## ServerAPISettings
Settings for controlling API server behavior
### `auth_string`
A string to use for basic authentication with the API; typically in the form 'user:password' but can be any string.
A string to use for basic authentication with the API in the form 'user:password'.

**Type**: `string | None`

Expand Down Expand Up @@ -985,6 +985,18 @@ The API's port address (defaults to `4200`).
**Supported environment variables**:
`PREFECT_SERVER_API_PORT`

### `base_path`
The base URL path to serve the API under.

**Type**: `string | None`

**Default**: `None`

**TOML dotted key path**: `server.api.base_path`

**Supported environment variables**:
`PREFECT_SERVER_API_BASE_PATH`

### `default_limit`
The default limit applied to queries that can return multiple objects, such as `POST /flow_runs/filter`.

Expand Down
21 changes: 20 additions & 1 deletion schemas/settings.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -834,7 +834,7 @@
}
],
"default": null,
"description": "A string to use for basic authentication with the API; typically in the form 'user:password' but can be any string.",
"description": "A string to use for basic authentication with the API in the form 'user:password'.",
"supported_environment_variables": [
"PREFECT_SERVER_API_AUTH_STRING"
],
Expand All @@ -858,6 +858,25 @@
"title": "Port",
"type": "integer"
},
"base_path": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "The base URL path to serve the API under.",
"examples": [
"/v2/api"
],
"supported_environment_variables": [
"PREFECT_SERVER_API_BASE_PATH"
],
"title": "Base Path"
},
"default_limit": {
"default": 200,
"description": "The default limit applied to queries that can return multiple objects, such as `POST /flow_runs/filter`.",
Expand Down
11 changes: 9 additions & 2 deletions src/prefect/server/api/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
PREFECT_DEBUG_MODE,
PREFECT_MEMO_STORE_PATH,
PREFECT_MEMOIZE_BLOCK_AUTO_REGISTRATION,
PREFECT_SERVER_API_BASE_PATH,
PREFECT_SERVER_EPHEMERAL_STARTUP_TIMEOUT_SECONDS,
PREFECT_UI_SERVE_BASE,
get_current_settings,
Expand Down Expand Up @@ -356,7 +357,10 @@ async def token_validation(request: Request, call_next: Any): # type: ignore[re
header_token = request.headers.get("Authorization")

# used for probes in k8s and such
if request.url.path in ["/api/health", "/api/ready"]:
if (
request.url.path.endswith(("health", "ready"))
and request.method.upper() == "GET"
):
return await call_next(request)
try:
if header_token is None:
Expand Down Expand Up @@ -691,7 +695,10 @@ async def metrics() -> Response: # type: ignore[reportUnusedFunction]
name="static",
)
app.api_app = api_app
app.mount("/api", app=api_app, name="api")
if PREFECT_SERVER_API_BASE_PATH:
app.mount(PREFECT_SERVER_API_BASE_PATH.value(), app=api_app, name="api")
else:
app.mount("/api", app=api_app, name="api")
app.mount("/", app=ui_app, name="ui")

def openapi():
Expand Down
6 changes: 5 additions & 1 deletion src/prefect/settings/models/root.py
Original file line number Diff line number Diff line change
Expand Up @@ -381,7 +381,11 @@ def _warn_on_misconfigured_api_url(settings: "Settings"):
warnings_list.append(warning)

parsed_url = urlparse(api_url)
if parsed_url.path and not parsed_url.path.startswith("/api"):
if (
parsed_url.path
and "api.prefect.cloud" in api_url
and not parsed_url.path.startswith("/api")
):
warnings_list.append(
"`PREFECT_API_URL` should have `/api` after the base URL."
)
Expand Down
8 changes: 7 additions & 1 deletion src/prefect/settings/models/server/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class ServerAPISettings(PrefectBaseSettings):

auth_string: Optional[SecretStr] = Field(
default=None,
description="A string to use for basic authentication with the API; typically in the form 'user:password' but can be any string.",
description="A string to use for basic authentication with the API in the form 'user:password'.",
)

host: str = Field(
Expand All @@ -31,6 +31,12 @@ class ServerAPISettings(PrefectBaseSettings):
description="The API's port address (defaults to `4200`).",
)

base_path: Optional[str] = Field(
default=None,
description="The base URL path to serve the API under.",
examples=["/v2/api"],
)

default_limit: int = Field(
default=200,
description="The default limit applied to queries that can return multiple objects, such as `POST /flow_runs/filter`.",
Expand Down
1 change: 1 addition & 0 deletions tests/test_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,7 @@
"PREFECT_RUNNER_SERVER_PORT": {"test_value": 8080},
"PREFECT_SERVER_ALLOW_EPHEMERAL_MODE": {"test_value": True, "legacy": True},
"PREFECT_SERVER_API_AUTH_STRING": {"test_value": "admin:admin"},
"PREFECT_SERVER_API_BASE_PATH": {"test_value": "/v2/api"},
"PREFECT_SERVER_ANALYTICS_ENABLED": {"test_value": True},
"PREFECT_SERVER_API_CORS_ALLOWED_HEADERS": {"test_value": "foo"},
"PREFECT_SERVER_API_CORS_ALLOWED_METHODS": {"test_value": "foo"},
Expand Down

0 comments on commit c4b74cf

Please sign in to comment.