feat(api): add dynamic server URL configuration to OpenAPI schema

Add a new postprocessing hook 'add_api_servers' that dynamically configures
the servers array in the OpenAPI specification based on the request environment.

This hook:
- Detects the current environment (local, staging, or production) from the
  request host
- Adds the current server URL as the primary option
- Includes production (https://api.prowler.com) as a fallback option when
  generating from non-production environments
- Enables users to toggle between local and production servers in Mintlify's
  API playground via a dropdown

Server detection logic:
- localhost/127.0.0.1 → "Local Development Server"
- hosts with 'dev' or 'staging' → "Development/Staging API"
- api.prowler.com → "Prowler Cloud API"

This enables the "Try it out" feature in Mintlify documentation and allows
testing against different environments without modifying the spec.
This commit is contained in:
Andoni A.
2025-11-05 12:04:18 +01:00
parent 00441e776d
commit 6815a9dd86
4 changed files with 58 additions and 18998 deletions
+47
View File
@@ -152,6 +152,53 @@ def fix_type_formats(result, generator, request, public): # noqa: F841
return fix_invalid_types(result)
def add_api_servers(result, generator, request, public): # noqa: F841
"""
Add servers configuration to OpenAPI spec for Mintlify API playground.
This enables the "Try it out" feature in the documentation.
Dynamically determines the server URL based on the request.
"""
if not isinstance(result, dict):
return result
# Add servers array if not already present
if "servers" not in result:
servers = []
# Try to get the current server URL from the request
if request:
scheme = request.scheme # http or https
host = request.get_host() # e.g., localhost:8080 or api.prowler.com
# Determine description based on host
if "localhost" in host or "127.0.0.1" in host:
description = "Local Development Server"
elif "dev" in host or "staging" in host:
description = "Development/Staging API"
else:
description = "Prowler Cloud API"
servers.append(
{
"url": f"{scheme}://{host}",
"description": description,
}
)
# Always add production as fallback/alternative
if not servers or (request and "prowler.com" not in request.get_host()):
servers.append(
{
"url": "https://api.prowler.com",
"description": "Prowler Cloud API (Production)",
}
)
result["servers"] = servers
return result
def attach_task_202_examples(result, generator, request, public): # noqa: F841
if not isinstance(result, dict):
return result
+1
View File
@@ -128,6 +128,7 @@ SPECTACULAR_SETTINGS = {
"api.schema_hooks.fix_empty_id_fields",
"api.schema_hooks.fix_pattern_properties",
"api.schema_hooks.fix_type_formats",
"api.schema_hooks.add_api_servers",
"api.schema_hooks.attach_task_202_examples",
],
"TITLE": "API Reference - Prowler",
+10
View File
@@ -25722,5 +25722,15 @@
"name": "Mute Rules",
"description": "Endpoints for simple mute rules management. These can be used as an alternative to the Mutelist Processor if you need to mute specific findings across your tenant with a specific reason."
}
],
"servers": [
{
"url": "http://localhost:8080",
"description": "Local Development Server"
},
{
"url": "https://api.prowler.com",
"description": "Prowler Cloud API (Production)"
}
]
}
File diff suppressed because it is too large Load Diff