Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FastAPI lifespan #113

Merged
merged 2 commits into from
Jul 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
* remove `stac-pydantic` dependency
* add optional `root_path` setting to specify a url path prefix to use when running the app behind a reverse proxy
* add landing page `/`
* use `lifespan` option instead of deprecated `@app.on_event` method to initiate/close DB connection

**breaking changes**

Expand Down
19 changes: 15 additions & 4 deletions docs/src/advanced/custom_search.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Even though `TiTiler.PgSTAC` includes default FastAPI application,
it also can be used like a library if you want to extend or
override default behaviour.
override default behavior.

Let's look at one such example. Imagine that we use JSON Web Token (JWT)
based approach for authorization and every token contains information
Expand All @@ -19,6 +19,8 @@ We want our application to take this information into account while
registering a search query. It can be done in the following way:

```python
from contextlib import asynccontextmanager

from typing import Tuple
import json
import jwt
Expand All @@ -27,9 +29,18 @@ from fastapi.security.utils import get_authorization_scheme_param
from starlette.requests import Request
from titiler.pgstac.factory import MosaicTilerFactory
from titiler.pgstac.model import RegisterMosaic, Metadata, PgSTACSearch


app = FastAPI()
from titiler.pgstac.db import close_db_connection, connect_to_db

@asynccontextmanager
async def lifespan(app: FastAPI):
"""FastAPI Lifespan."""
# Create Connection Pool
await connect_to_db(app, settings=postgres_settings)
yield
# Close the Connection Pool
await close_db_connection(app)

app = FastAPI(lifespan=lifespan)

AREAS = {
"zone_A": {"type": "Point", "coordinates": [-41.93, -12.76]},
Expand Down
39 changes: 22 additions & 17 deletions docs/src/tiler_factories.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,24 @@

```python
# Minimal PgSTAC Mosaic Application
from contextlib import asynccontextmanager

from fastapi import FastAPI
from titiler.pgstac.db import close_db_connection, connect_to_db
from titiler.pgstac.factory import MosaicTilerFactory

app = FastAPI()

@app.on_event("startup")
async def startup_event() -> None:
"""Connect to database on startup."""
@asynccontextmanager
async def lifespan(app: FastAPI):
"""FastAPI Lifespan."""
# Create Connection Pool
await connect_to_db(app)

@app.on_event("shutdown")
async def shutdown_event() -> None:
"""Close database connection."""
yield
# Close the Connection Pool
await close_db_connection(app)


app = FastAPI(lifespan=lifespan)

mosaic = MosaicTilerFactory()
app.include_router(mosaic.router)
```
Expand All @@ -45,6 +47,8 @@ This custom `path_dependency` will connect to PgSTAC directly to fetch the STAC

```python
# Minimal PgSTAC Item Application
from contextlib import asynccontextmanager

from fastapi import FastAPI

from titiler.core.factory import MultiBaseTilerFactory
Expand All @@ -53,18 +57,19 @@ from titiler.pgstac.db import close_db_connection, connect_to_db
from titiler.pgstac.dependencies import ItemPathParams
from titiler.pgstac.reader import PgSTACReader

app = FastAPI()

@app.on_event("startup")
async def startup_event() -> None:
"""Connect to database on startup."""
@asynccontextmanager
async def lifespan(app: FastAPI):
"""FastAPI Lifespan."""
# Create Connection Pool
await connect_to_db(app)

@app.on_event("shutdown")
async def shutdown_event() -> None:
"""Close database connection."""
yield
# Close the Connection Pool
await close_db_connection(app)


app = FastAPI(lifespan=lifespan)

item = MultiBaseTilerFactory(
reader=PgSTACReader,
path_dependency=ItemPathParams,
Expand Down
29 changes: 15 additions & 14 deletions titiler/pgstac/main.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""TiTiler+PgSTAC FastAPI application."""

import logging
from contextlib import asynccontextmanager
from typing import Dict

import jinja2
Expand All @@ -26,7 +27,7 @@
from titiler.pgstac.dependencies import ItemPathParams
from titiler.pgstac.factory import MosaicTilerFactory
from titiler.pgstac.reader import PgSTACReader
from titiler.pgstac.settings import ApiSettings
from titiler.pgstac.settings import ApiSettings, PostgresSettings

logging.getLogger("botocore.credentials").disabled = True
logging.getLogger("botocore.utils").disabled = True
Expand All @@ -38,8 +39,20 @@
) # type:ignore


postgres_settings = PostgresSettings()
settings = ApiSettings()


@asynccontextmanager
async def lifespan(app: FastAPI):
"""FastAPI Lifespan."""
# Create Connection Pool
await connect_to_db(app, settings=postgres_settings)
yield
# Close the Connection Pool
await close_db_connection(app)


app = FastAPI(
title=settings.name,
openapi_url="/api",
Expand All @@ -56,21 +69,9 @@
""",
version=titiler_pgstac_version,
root_path=settings.root_path,
lifespan=lifespan,
)


@app.on_event("startup")
async def startup_event() -> None:
"""Connect to database on startup."""
await connect_to_db(app)


@app.on_event("shutdown")
async def shutdown_event() -> None:
"""Close database connection."""
await close_db_connection(app)


add_exception_handlers(app, DEFAULT_STATUS_CODES)
add_exception_handlers(app, MOSAIC_STATUS_CODES)

Expand Down
Loading