-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathapp.py
119 lines (97 loc) · 3.35 KB
/
app.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
"""
STAC Auth Proxy API.
This module defines the FastAPI application for the STAC Auth Proxy, which handles
authentication, authorization, and proxying of requests to some internal STAC API.
"""
import logging
from contextlib import asynccontextmanager
from typing import Optional
from fastapi import FastAPI
from starlette_cramjam.middleware import CompressionMiddleware
from .config import Settings
from .handlers import HealthzHandler, ReverseProxyHandler
from .middleware import (
AddProcessTimeHeaderMiddleware,
ApplyCql2FilterMiddleware,
BuildCql2FilterMiddleware,
EnforceAuthMiddleware,
OpenApiMiddleware,
)
from .utils.lifespan import check_conformance, check_server_health
logger = logging.getLogger(__name__)
def create_app(settings: Optional[Settings] = None) -> FastAPI:
"""FastAPI Application Factory."""
settings = settings or Settings()
#
# Application
#
@asynccontextmanager
async def lifespan(app: FastAPI):
assert settings
# Wait for upstream servers to become available
if settings.wait_for_upstream:
logger.info("Running upstream server health checks...")
for url in [settings.upstream_url, settings.oidc_discovery_internal_url]:
await check_server_health(url=url)
# Log all middleware connected to the app
logger.debug(
"Connected middleware:\n%s",
"\n".join([f" - {m.cls.__name__}" for m in app.user_middleware]),
)
if settings.check_conformance:
await check_conformance(
app.user_middleware,
str(settings.upstream_url),
)
yield
app = FastAPI(
openapi_url=None, # Disable OpenAPI schema endpoint, we want to serve upstream's schema
lifespan=lifespan,
)
#
# Handlers (place catch-all proxy handler last)
#
if settings.healthz_prefix:
app.include_router(
HealthzHandler(upstream_url=str(settings.upstream_url)).router,
prefix=settings.healthz_prefix,
)
app.add_api_route(
"/{path:path}",
ReverseProxyHandler(upstream=str(settings.upstream_url)).proxy_request,
methods=["GET", "POST", "PUT", "PATCH", "DELETE"],
)
#
# Middleware (order is important, last added = first to run)
#
if settings.openapi_spec_endpoint:
app.add_middleware(
OpenApiMiddleware,
openapi_spec_path=settings.openapi_spec_endpoint,
oidc_config_url=str(settings.oidc_discovery_url),
public_endpoints=settings.public_endpoints,
private_endpoints=settings.private_endpoints,
default_public=settings.default_public,
)
if settings.items_filter:
app.add_middleware(
ApplyCql2FilterMiddleware,
)
app.add_middleware(
BuildCql2FilterMiddleware,
items_filter=settings.items_filter(),
)
app.add_middleware(
CompressionMiddleware,
)
app.add_middleware(
AddProcessTimeHeaderMiddleware,
)
app.add_middleware(
EnforceAuthMiddleware,
public_endpoints=settings.public_endpoints,
private_endpoints=settings.private_endpoints,
default_public=settings.default_public,
oidc_config_url=settings.oidc_discovery_internal_url,
)
return app