diff --git a/app/main.py b/app/main.py index 6824fbec1..0349f5bad 100644 --- a/app/main.py +++ b/app/main.py @@ -9,6 +9,7 @@ from fastapi import FastAPI, Request, Response from fastapi.exceptions import HTTPException from fastapi.responses import JSONResponse +from scalar_fastapi import get_scalar_api_reference from app.exceptions import CloudApiException from app.routes import ( @@ -132,6 +133,8 @@ def create_app() -> FastAPI: description=cloud_api_description(ROLE), lifespan=lifespan, debug=debug, + redoc_url=None, + docs_url=None, ) for route in routes_for_role(ROLE): @@ -144,6 +147,15 @@ def create_app() -> FastAPI: app = create_app() +# Use Scalar instead of Swagger +@app.get("/docs", include_in_schema=False) +async def scalar_html(): + return get_scalar_api_reference( + openapi_url=ROOT_PATH + app.openapi_url, + title=app.title, + ) + + # additional yaml version of openapi.json @app.get("/openapi.yaml", include_in_schema=False) def read_openapi_yaml() -> Response: diff --git a/app/poetry.lock b/app/poetry.lock index c1a3416c4..eab35cd82 100644 --- a/app/poetry.lock +++ b/app/poetry.lock @@ -1748,6 +1748,17 @@ files = [ {file = "pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e"}, ] +[[package]] +name = "scalar-fastapi" +version = "1.0.3" +description = "This plugin provides an easy way to render a beautiful API reference based on a OpenAPI/Swagger file with FastAPI." +optional = false +python-versions = "*" +files = [ + {file = "scalar_fastapi-1.0.3-py3-none-any.whl", hash = "sha256:4a47a140795097ad034518ce0e32940f2c54f0f4bc60e4c3289ca30a7e6f954d"}, + {file = "scalar_fastapi-1.0.3.tar.gz", hash = "sha256:9e9cb8398e298cd435a0171eebe1675b8899eb21e47c238db0d48783143f0ffb"}, +] + [[package]] name = "six" version = "1.16.0" @@ -2367,4 +2378,4 @@ type = ["pytest-mypy"] [metadata] lock-version = "2.0" python-versions = "^3.12" -content-hash = "49cfcab0a9d4149149cb77d5c35adc2d3f25c07c644f1c31625adf4d8463e78c" +content-hash = "83d6f621d9c114278ca6143eb87fa3f1e84177332838f7868f4f06b5f616be16" diff --git a/app/pyproject.toml b/app/pyproject.toml index 815b3f0db..a2ef78e51 100644 --- a/app/pyproject.toml +++ b/app/pyproject.toml @@ -22,6 +22,7 @@ PyYAML = "~6.0.2" typing-extensions = "~4.12.0" uvicorn = { version = "~0.30.5", extras = ["standard"] } ddtrace = "^2.12.2" +scalar-fastapi = "^1.0.3" [tool.poetry.dev-dependencies] anyio = "~4.6.0" diff --git a/endorser/main.py b/endorser/main.py index 802e7bfcf..8e796c69a 100644 --- a/endorser/main.py +++ b/endorser/main.py @@ -3,6 +3,7 @@ from dependency_injector.wiring import Provide, inject from fastapi import Depends, FastAPI, HTTPException +from scalar_fastapi import get_scalar_api_reference from endorser.services.dependency_injection.container import Container from endorser.services.endorsement_processor import EndorsementProcessor @@ -41,6 +42,8 @@ def create_app() -> FastAPI: title=openapi_name, version=PROJECT_VERSION, lifespan=app_lifespan, + redoc_url=None, + docs_url=None, ) return application @@ -49,6 +52,15 @@ def create_app() -> FastAPI: app = create_app() +# Use Scalar instead of Swagger +@app.get("/docs", include_in_schema=False) +async def scalar_html(): + return get_scalar_api_reference( + openapi_url=app.openapi_url, + title=app.title, + ) + + @app.get("/health") @inject async def health_check( diff --git a/endorser/poetry.lock b/endorser/poetry.lock index c487771e1..06a3a8eb5 100644 --- a/endorser/poetry.lock +++ b/endorser/poetry.lock @@ -1588,6 +1588,17 @@ files = [ hiredis = ["hiredis (>1.0.0)"] ocsp = ["cryptography (>=36.0.1)", "pyopenssl (==20.0.1)", "requests (>=2.26.0)"] +[[package]] +name = "scalar-fastapi" +version = "1.0.3" +description = "This plugin provides an easy way to render a beautiful API reference based on a OpenAPI/Swagger file with FastAPI." +optional = false +python-versions = "*" +files = [ + {file = "scalar_fastapi-1.0.3-py3-none-any.whl", hash = "sha256:4a47a140795097ad034518ce0e32940f2c54f0f4bc60e4c3289ca30a7e6f954d"}, + {file = "scalar_fastapi-1.0.3.tar.gz", hash = "sha256:9e9cb8398e298cd435a0171eebe1675b8899eb21e47c238db0d48783143f0ffb"}, +] + [[package]] name = "six" version = "1.16.0" @@ -2176,4 +2187,4 @@ type = ["pytest-mypy"] [metadata] lock-version = "2.0" python-versions = "^3.12" -content-hash = "2703da4ece5ab3a3e8575d114599aeb7a457e29ea3d666634a052b92a44538f2" +content-hash = "7bf6f5cece838b2abca99326cfd2427fc436c0fc68bb9db64fc67d1a8f24d9ad" diff --git a/endorser/pyproject.toml b/endorser/pyproject.toml index f95a77c94..1638b7a94 100644 --- a/endorser/pyproject.toml +++ b/endorser/pyproject.toml @@ -18,6 +18,7 @@ pydantic = "~2.9.0" redis = "~=5.0.8" uvicorn = { version = "~0.30.5", extras = ["standard"] } ddtrace = "^2.12.2" +scalar-fastapi = "^1.0.3" [tool.poetry.dev-dependencies] anyio = "~4.6.0" diff --git a/trustregistry/main.py b/trustregistry/main.py index 61510d916..03b9320ef 100644 --- a/trustregistry/main.py +++ b/trustregistry/main.py @@ -2,6 +2,7 @@ from contextlib import asynccontextmanager from fastapi import Depends, FastAPI +from scalar_fastapi import get_scalar_api_reference from sqlalchemy import inspect from sqlalchemy.orm import Session @@ -40,6 +41,8 @@ def create_app(): version=PROJECT_VERSION, description="Welcome to the OpenAPI interface to the Aries CloudAPI trust registry", lifespan=lifespan, + redoc_url=None, + docs_url=None, ) application.include_router(registry_actors.router) application.include_router(registry_schemas.router) @@ -49,6 +52,15 @@ def create_app(): app = create_app() +# Use Scalar instead of Swagger +@app.get("/docs", include_in_schema=False) +async def scalar_html(): + return get_scalar_api_reference( + openapi_url=app.openapi_url, + title=app.title, + ) + + @app.get("/") async def root(db_session: Session = Depends(get_db)): logger.debug("GET request received: Fetch actors and schemas from registry") diff --git a/trustregistry/poetry.lock b/trustregistry/poetry.lock index 872384c42..214fde7e2 100644 --- a/trustregistry/poetry.lock +++ b/trustregistry/poetry.lock @@ -1249,6 +1249,17 @@ files = [ {file = "pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e"}, ] +[[package]] +name = "scalar-fastapi" +version = "1.0.3" +description = "This plugin provides an easy way to render a beautiful API reference based on a OpenAPI/Swagger file with FastAPI." +optional = false +python-versions = "*" +files = [ + {file = "scalar_fastapi-1.0.3-py3-none-any.whl", hash = "sha256:4a47a140795097ad034518ce0e32940f2c54f0f4bc60e4c3289ca30a7e6f954d"}, + {file = "scalar_fastapi-1.0.3.tar.gz", hash = "sha256:9e9cb8398e298cd435a0171eebe1675b8899eb21e47c238db0d48783143f0ffb"}, +] + [[package]] name = "sniffio" version = "1.3.1" @@ -1791,4 +1802,4 @@ type = ["pytest-mypy"] [metadata] lock-version = "2.0" python-versions = "^3.12" -content-hash = "8409c228c4442849dfcc7daf8f0cd3dd0dae77acb2b6667c64f29bd78a475ef9" +content-hash = "5e66c2b5b49f30cc1bd93d68a6162dc65650a6311986a55976bb4c7add8016b1" diff --git a/trustregistry/pyproject.toml b/trustregistry/pyproject.toml index bb8aa6bea..2dd1e9d89 100644 --- a/trustregistry/pyproject.toml +++ b/trustregistry/pyproject.toml @@ -17,6 +17,7 @@ pydantic = "~2.9.0" sqlalchemy = "~=2.0.19" uvicorn = { version = "~0.30.5", extras = ["standard"] } ddtrace = "^2.12.2" +scalar-fastapi = "^1.0.3" [tool.poetry.dev-dependencies] anyio = "~4.6.0" diff --git a/waypoint/main.py b/waypoint/main.py index d36508cad..24ee8a4e5 100644 --- a/waypoint/main.py +++ b/waypoint/main.py @@ -4,6 +4,7 @@ from dependency_injector.wiring import Provide, inject from fastapi import Depends, FastAPI, HTTPException +from scalar_fastapi import get_scalar_api_reference from shared.constants import PROJECT_VERSION from shared.log_config import get_logger @@ -43,6 +44,8 @@ def create_app() -> FastAPI: """, version=PROJECT_VERSION, lifespan=app_lifespan, + redoc_url=None, + docs_url=None, ) application.include_router(sse.router) @@ -55,6 +58,15 @@ def create_app() -> FastAPI: app = create_app() +# Use Scalar instead of Swagger +@app.get("/docs", include_in_schema=False) +async def scalar_html(): + return get_scalar_api_reference( + openapi_url=app.openapi_url, + title=app.title, + ) + + @app.get("/health/live") async def health_live(): return {"status": "live"} diff --git a/waypoint/poetry.lock b/waypoint/poetry.lock index 061760cb0..abf0fad29 100644 --- a/waypoint/poetry.lock +++ b/waypoint/poetry.lock @@ -1550,6 +1550,17 @@ files = [ {file = "pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e"}, ] +[[package]] +name = "scalar-fastapi" +version = "1.0.3" +description = "This plugin provides an easy way to render a beautiful API reference based on a OpenAPI/Swagger file with FastAPI." +optional = false +python-versions = "*" +files = [ + {file = "scalar_fastapi-1.0.3-py3-none-any.whl", hash = "sha256:4a47a140795097ad034518ce0e32940f2c54f0f4bc60e4c3289ca30a7e6f954d"}, + {file = "scalar_fastapi-1.0.3.tar.gz", hash = "sha256:9e9cb8398e298cd435a0171eebe1675b8899eb21e47c238db0d48783143f0ffb"}, +] + [[package]] name = "six" version = "1.16.0" @@ -2031,4 +2042,4 @@ multidict = ">=4.0" [metadata] lock-version = "2.0" python-versions = "^3.12" -content-hash = "ea4e30870434818afe1618fffa06ad53ec241f1af00671c6dffdbca460618263" +content-hash = "0a1d7b07c10063ce02580c8c3eb68ebb6fb22772dc9abdae704ad33f2854fd55" diff --git a/waypoint/pyproject.toml b/waypoint/pyproject.toml index cd655e14f..1721ae856 100644 --- a/waypoint/pyproject.toml +++ b/waypoint/pyproject.toml @@ -19,6 +19,7 @@ pydantic = "~2.9.0" typing-extensions = "~4.12.0" uvicorn = { version = "~0.30.5", extras = ["standard"] } sse-starlette = "~=2.1.3" +scalar-fastapi = "^1.0.3" [tool.poetry.dev-dependencies] anyio = "~4.6.0" diff --git a/waypoint/routers/sse.py b/waypoint/routers/sse.py index 0f19b0ddd..16d7065d0 100644 --- a/waypoint/routers/sse.py +++ b/waypoint/routers/sse.py @@ -73,10 +73,14 @@ async def nats_event_stream_generator( @router.get( "/{wallet_id}/{topic}/{field}/{field_id}/{desired_state}", response_class=EventSourceResponse, - summary="Wait for a desired state to be reached for some event for this wallet and topic " - "The `relevant_id` refers to a `transaction_id` when using topic `endorsements," - "or a `connection_id` on topics: `connections`, `credentials`, or `proofs`, etc." - "`desired_state` may be `offer-received`, `transaction-acked`, `done`, etc.", + summary=""" + Wait for a desired state to be reached for some event for this wallet and topic. + """, + description=""" + The `relevant_id` refers to a `transaction_id` when using topic `endorsements`, + or a `connection_id` on topics: `connections`, `credentials`, or `proofs`, etc. + `desired_state` may be `offer-received`, `transaction-acked`, `done`, etc. + """, ) @inject async def sse_wait_for_event_with_field_and_state(