예제 #1
0
 async def add_metadata_headers_with_maintainer(request: Request, call_next):
     response = await call_next(request)
     response.headers["X-App-Version"] = get_setting("APP_VERSION")
     response.headers["X-App-Valid-Till"] = get_setting("APP_VALID_DATE")
     response.headers["X-Maintainer"] = get_setting("APP_MAINTAINER")
     response.headers["X-Maintainer-Email"] = get_setting("APP_MAINTAINER_EMAIL")
     return response
예제 #2
0
def add_application_metadata(logger, method_name, event_dict):
    if 'app_version' not in event_dict:
        event_dict['app_version'] = get_setting('APP_VERSION')
    if 'app_valid_date' not in event_dict:
        event_dict['app_valid_date'] = get_setting('APP_VALID_DATE')

    return event_dict
예제 #3
0
 async def add_metadata_headers_with_maintainer(request: Request, call_next):
     response = await call_next(request)
     response.headers['X-App-Version'] = get_setting('APP_VERSION')
     response.headers['X-App-Valid-Till'] = get_setting('APP_VALID_DATE')
     response.headers['X-Maintainer'] = get_setting('APP_MAINTAINER')
     response.headers['X-Maintainer-Email'] = get_setting('APP_MAINTAINER_EMAIL')
     return response
예제 #4
0
def add_application_metadata(logger, method_name, event_dict):
    if "app_version" not in event_dict:
        event_dict["app_version"] = get_setting("APP_VERSION")
    if "app_valid_date" not in event_dict:
        event_dict["app_valid_date"] = get_setting("APP_VALID_DATE")

    return event_dict
예제 #5
0
async def handle_http_exception(request: Request, exc: StarletteHTTPException) -> JSONResponse:
    headers = getattr(exc, "headers", None)

    body = {'detail': exc.detail}
    if get_setting('SHOW_MAINTAINER'):
        body['maintainer'] = get_setting('APP_MAINTAINER')
        body['maintainer_email'] = get_setting('APP_MAINTAINER_EMAIL')

    return JSONResponse(body, status_code=exc.status_code, headers=headers)
예제 #6
0
async def handle_http_exception(request: Request,
                                exc: StarletteHTTPException) -> JSONResponse:
    headers = getattr(exc, "headers", None)

    body = {"detail": exc.detail}
    if get_setting("SHOW_MAINTAINER"):
        body["maintainer"] = get_setting("APP_MAINTAINER")
        body["maintainer_email"] = get_setting("APP_MAINTAINER_EMAIL")

    return JSONResponse(body, status_code=exc.status_code, headers=headers)
예제 #7
0
def initialize_logging():
    timestamper = structlog.processors.TimeStamper(fmt="iso")

    shared_processors = [
        structlog.stdlib.add_logger_name,
        structlog.stdlib.add_log_level,
        add_application_metadata,
        timestamper,
        structlog.processors.UnicodeDecoder(),
    ]

    pre_chain = shared_processors

    # Setup JSON-logging to stdout
    logging.captureWarnings(True)
    logging.config.dictConfig(
        {
            "version": 1,
            "disable_existing_loggers": False,
            "formatters": {
                "json": {
                    "()": structlog.stdlib.ProcessorFormatter,
                    "processor": structlog.processors.JSONRenderer(),
                    "foreign_pre_chain": pre_chain,
                }
            },
            "handlers": {
                "default": {
                    "level": get_setting("LOG_LEVEL"),
                    "class": "logging.StreamHandler",
                    "formatter": "json",
                }
            },
            "loggers": {
                "": {
                    "handlers": ["default"],
                    "level": get_setting("LOG_LEVEL"),
                    "propagate": True,
                }
            },
        }
    )

    structlog.configure(
        processors=[structlog.stdlib.filter_by_level]
        + shared_processors
        + [structlog.stdlib.ProcessorFormatter.wrap_for_formatter],
        logger_factory=structlog.stdlib.LoggerFactory(),
        cache_logger_on_first_use=True,
    )
    def __init__(self):
        """
        Specification of required fields for a weather data storage repository:
            - repository_folder:    Contains the folder where the repository will be saved. Is set inside a main
                                    repository folder, and based on a sub-folder passed by the repository itself
                                    through the _get_repo_subfolder() function.
            - file_prefix:          Contains a string with the file_prefix to use for all files within the
                                    repository. Is set from the repository itself.
            - runtime_limit:        Contains the maximum time the update function of the repository is allowed to be
                                    running, in seconds.
            - first_day_of_repo:    Contains a datetime indicating the oldest moment allowed to be stored in the
                                    repository.
            - last_day_of_repo:     Contains a datetime indicating the newest moment allowed to be stored in the
                                    repository.
            - permanent_suffixes:   Contains a list of suffixes that can be added to the repository files to
                                    indicate that the file should not be deleted. Any file not matching the prefix
                                    or having a suffix not matching this list will be deleted upon cleanup.
            - file_identifier_length:   This is the length in characters that the unique identifier part of the
                                        filename takes up. Usually this is based on a datetime.

        """
        self.repository_folder = Path(get_setting("REPO_FOLDER")).joinpath(
            self._get_repo_sub_folder())
        self.logger = structlog.get_logger(__name__)
        self.repository_name = None
        self.file_prefix = None
        self.runtime_limit = 60 * 60 * 2  # seconds * minutes * hours (2 hours default)
        self.first_day_of_repo = None
        self.last_day_of_repo = None
        self.permanent_suffixes = None
        self.file_identifier_length = None
def initialize_prometheus_middleware(app, endpoint="/metrics"):
    """Start HTTP endpoint for Prometheus monitoring.

    Args:
        app: FastAPI app instance
        endpoint (str): URL at which the metrics should be available
    """
    if get_setting("DEPLOYED"):
        logger.info(f'Enabling Prometheus endpoint on: "{endpoint}"')
        app.add_middleware(PrometheusMiddleware)
        app.add_route(endpoint, metrics)
def initialize_validation_middleware(app):

    valid_date = datetime.datetime.strptime(get_setting("APP_VALID_DATE"), "%Y-%m-%d")

    async def check_api_validity(request: Request, call_next):
        if datetime.datetime.now() > valid_date:
            response = await handle_http_exception(request, APIExpiredException())
        else:
            response = await call_next(request)

        return response

    app.add_middleware(BaseHTTPMiddleware, dispatch=check_api_validity)
예제 #11
0
def initialize_metadata_header_middleware(app):
    async def add_metadata_headers(request: Request, call_next):
        response = await call_next(request)
        response.headers['X-App-Version'] = get_setting('APP_VERSION')
        response.headers['X-App-Valid-Till'] = get_setting('APP_VALID_DATE')
        return response

    async def add_metadata_headers_with_maintainer(request: Request, call_next):
        response = await call_next(request)
        response.headers['X-App-Version'] = get_setting('APP_VERSION')
        response.headers['X-App-Valid-Till'] = get_setting('APP_VALID_DATE')
        response.headers['X-Maintainer'] = get_setting('APP_MAINTAINER')
        response.headers['X-Maintainer-Email'] = get_setting('APP_MAINTAINER_EMAIL')
        return response

    show_maintainer = get_setting('SHOW_MAINTAINER')
    if show_maintainer:
        insertion_func = add_metadata_headers_with_maintainer
    else:
        insertion_func = add_metadata_headers

    app.add_middleware(BaseHTTPMiddleware, dispatch=insertion_func)
예제 #12
0
 async def add_metadata_headers(request: Request, call_next):
     response = await call_next(request)
     response.headers['X-App-Version'] = get_setting('APP_VERSION')
     response.headers['X-App-Valid-Till'] = get_setting('APP_VALID_DATE')
     return response
예제 #13
0
initialize_metadata_header_middleware(app)
initialize_validation_middleware(app)
initialize_prometheus_middleware(app)

origins = ["*"]

app.add_middleware(
    CORSMiddleware,
    allow_origins=origins,
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

# Activate enabled API versions
mount_api_version(app, v1)


# Redirect users to the docs
@app.get('/')
def redirect_to_docs():
    redirect_url = '/api/v1/sample/docs'  # replace with docs URL or use app.url_path_for()
    return RedirectResponse(url=redirect_url)


if __name__ == '__main__':
    # Run the application
    uvicorn.run(app,
                host=get_setting('NETWORK_INTERFACE'),
                port=get_setting('NETWORK_PORT'))