-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathapp.py
More file actions
107 lines (88 loc) · 3.71 KB
/
app.py
File metadata and controls
107 lines (88 loc) · 3.71 KB
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
from fastapi import FastAPI
from fastapi.security import HTTPAuthorizationCredentials
import httpx
from importlib.metadata import version
import os
import time
from cdislogging import get_logger
from gen3authz.client.arborist.async_client import ArboristClient
from fastapi import Request, HTTPException
from gen3workflow import logger
from gen3workflow.config import config
from gen3workflow.metrics import Metrics
from gen3workflow.routes.ga4gh_tes import router as ga4gh_tes_router
from gen3workflow.routes.s3 import router as s3_router
from gen3workflow.routes.storage import router as storage_router
from gen3workflow.routes.system import router as system_router
from gen3workflow.auth import Auth
def get_app(httpx_client=None) -> FastAPI:
logger.info("Initializing app")
config.validate()
debug = config["APP_DEBUG"]
log_level = "debug" if debug else "info"
app = FastAPI(
title="Gen3Workflow",
version=version("gen3workflow"),
debug=config["APP_DEBUG"],
root_path=config["DOCS_URL_PREFIX"],
)
app.async_client = httpx_client or httpx.AsyncClient()
app.include_router(ga4gh_tes_router, tags=["GA4GH TES"])
app.include_router(s3_router, tags=["S3"])
app.include_router(storage_router, tags=["Storage"])
app.include_router(system_router, tags=["System"])
# Following will update logger level, propagate, and handlers
get_logger("gen3workflow", log_level=log_level)
logger.info("Initializing Arborist client")
if config["MOCK_AUTH"]:
logger.warning(
"Mock authentication and authorization are enabled! 'MOCK_AUTH' should NOT be enabled in production!"
)
custom_arborist_url = os.environ.get("ARBORIST_URL", config["ARBORIST_URL"])
if custom_arborist_url:
app.arborist_client = ArboristClient(
arborist_base_url=custom_arborist_url,
authz_provider="gen3-workflow",
logger=get_logger("gen3workflow.gen3authz", log_level=log_level),
)
else:
app.arborist_client = ArboristClient(
authz_provider="gen3-workflow",
logger=get_logger("gen3workflow.gen3authz", log_level=log_level),
)
app.metrics = Metrics(
enabled=config["ENABLE_PROMETHEUS_METRICS"],
prometheus_dir=config["PROMETHEUS_MULTIPROC_DIR"],
)
if app.metrics.enabled:
app.mount("/metrics", app.metrics.get_asgi_app())
@app.middleware("http")
async def middleware_log_response_and_api_metric(
request: Request, call_next
) -> None:
"""
This FastAPI middleware effectively allows pre and post logic to a request.
We are using this to log the response consistently across defined endpoints (including execution time).
Args:
request (Request): the incoming HTTP request
call_next (Callable): function to call (this is handled by FastAPI's middleware support)
"""
start_time = time.perf_counter()
response = await call_next(request)
response_time_seconds = time.perf_counter() - start_time
path = request.url.path
method = request.method
# NOTE: If adding more endpoints to metrics, try making it configurable using a list of paths and methods in config.
# For now, we are only interested in the "/ga4gh/tes/v1/tasks" endpoint for metrics.
if method != "POST" or path != "/ga4gh/tes/v1/tasks":
return response
metrics = app.metrics
metrics.add_create_task_api_interaction(
method=method,
path=path,
response_time_seconds=response_time_seconds,
status_code=response.status_code,
)
return response
return app
app = get_app()