Description
How can I expose the API documentation to external users?
Automated API documentation is definitely one of the best features provided. However, since it exposes all the endpoints and model structures automatically, it seems more facilitating internal users, and should be protected with some authentication.
What if I want to expose some of these endpoints to external customers? Is it possible to label some of the endpoints so they can be exposed in another external API documentation?
So ideally, I want to achieve:
somedomain.com/docs (internal, authentication required)
somedomain.com/ext-docs (external, free to access)
Thanks.
Additional context
Add any other context or screenshots about the feature request here.
At work we're using API Scrub for this. You add an extra item to everything you want to be private, for example:
paths:
/hello:
get:
description: Returns a hello world string.
/admin:
x-only: admin
get:
description: Get the admin settings
Running it without arguments will remove everything with an x-only key, and then you can use ReDoc to generate docs off of the scrubbed file for external customers. There are a few strange edge cases where it doesn't work well (e.g. you can't scrub a single list item from a response example) but otherwise it has been great.
Perhaps FastAPI could adopt something similar and exposed it as an option on the route? For example:
app = FastAPI()
@app.get("/admin/", only=["internal"])
async def get_admin():
return "Admin page"
That could then render out either the full OpenAPI document with x-only: internal or the scrubbed public or internal versions, along with routes to view generated docs from either one. For example:
Cooool, thanks for the info!
The simplest thing you can do is enable or disable the docs based on an env var.
That way you can deploy your app internally with docs and externally without docs.
E.g.
from fastapi import FastAPI
import os
hide_docs = os.getenv("HIDE_DOCS", False)
openapi_url = "/openapi.json"
docs_url = "/docs"
redoc_url = "/redoc"
if hide_docs:
openapi_url = None
docs_url = None
redoc_url = None
app = FastAPI(openapi_url=openapi_url, docs_url=docs_url, redoc_url=redoc_url)
@app.get("/items/{item_id}")
async def read_items(item_id: int):
return {"id": item_id}
But still, have in mind that having OpenAPI and docs shouldn't be an issue for your app (probably more like a feature). And hiding the docs will not prevent an attacker from using your API.
Assuming the original issue was solved, it will be automatically closed now. But feel free to add more comments or create new issues.
Most helpful comment
At work we're using API Scrub for this. You add an extra item to everything you want to be private, for example:
Running it without arguments will remove everything with an
x-onlykey, and then you can use ReDoc to generate docs off of the scrubbed file for external customers. There are a few strange edge cases where it doesn't work well (e.g. you can't scrub a single list item from a response example) but otherwise it has been great.Perhaps FastAPI could adopt something similar and exposed it as an option on the route? For example:
That could then render out either the full OpenAPI document with
x-only: internalor the scrubbed public or internal versions, along with routes to view generated docs from either one. For example: