-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #5 from lsst-sqre/tickets/DM-44230
DM-44230: Add Slack error reporting
- Loading branch information
Showing
15 changed files
with
698 additions
and
43 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
"""A functional dependency that adds a pagination query string parameter to a | ||
FastAPI path operation. | ||
""" | ||
|
||
from __future__ import annotations | ||
|
||
from dataclasses import dataclass | ||
from enum import Enum | ||
from typing import Annotated | ||
|
||
from fastapi import Query | ||
|
||
__all__ = ["Pagination", "SortOrder", "pagination_dependency"] | ||
|
||
|
||
class SortOrder(str, Enum): | ||
"""Sort order.""" | ||
|
||
asc = "asc" | ||
desc = "desc" | ||
|
||
|
||
@dataclass | ||
class Pagination: | ||
"""Pagination parameters.""" | ||
|
||
page: int | ||
"""The requested page number.""" | ||
|
||
limit: int | ||
"""The requested number of items per page.""" | ||
|
||
order: SortOrder | ||
"""The requested sort order.""" | ||
|
||
@property | ||
def query_params(self) -> dict[str, str]: | ||
"""Get the URL query string parameters for this page. | ||
This can be used to build a URL with a query string for the current | ||
page. | ||
""" | ||
return { | ||
"page": str(self.page), | ||
"limit": str(self.limit), | ||
"order": self.order.value, | ||
} | ||
|
||
|
||
async def pagination_dependency( | ||
page: Annotated[ | ||
int, Query(ge=1, title="Pagination page.", examples=[1, 2, 3]) | ||
] = 1, | ||
limit: Annotated[ | ||
int, Query(title="Max number of items in page.", examples=[10, 20, 30]) | ||
] = 10, | ||
order: Annotated[ | ||
SortOrder, | ||
Query(title="Sort order.", examples=[SortOrder.asc, SortOrder.desc]), | ||
] = SortOrder.asc, | ||
) -> Pagination: | ||
"""Add pagination query string parameters to a FastAPI path operation. | ||
This dependency adds three query string parameters to a FastAPI path | ||
operation: `page`, `limit`, and `order`. | ||
Note that this sets up "offset" pagination, which is simple to implement | ||
for this demo. With a real database, you may want to look into "cursor" | ||
based pagination for better performance and reliability with dynamic data. | ||
Parameters | ||
---------- | ||
page | ||
The page number. | ||
limit | ||
The number of items to return per page. | ||
order | ||
The sort order. | ||
Returns | ||
------- | ||
Pagination | ||
A container with the `page`, `limit`, and `order` query string | ||
parameters. | ||
""" | ||
return Pagination(page=page, limit=limit, order=order) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
"""A class-based FastAPI dependency for demonstration purposes.""" | ||
|
||
from __future__ import annotations | ||
|
||
import random | ||
|
||
from ..exceptions import DemoInternalError | ||
|
||
__all__ = ["example_singleton_dependency", "ExampleSingletonDependency"] | ||
|
||
|
||
class ExampleSingletonDependency: | ||
"""A stateful FastAPI dependency for demonstration purposes. | ||
See lesson 6 in src/fastapibootcamp/handlers/example.py for usage. | ||
""" | ||
|
||
def __init__(self) -> None: | ||
# For this demo we're just using a semi-random string as the state. In | ||
# real applications, this could be a database connection, a client | ||
# to a remote service, etc. This "state" is reused over the life of | ||
# this application instance (i.e. a Kubernetes pod). It's not shared | ||
# between instances, though. | ||
self._state: str | None = None | ||
|
||
async def init(self) -> None: | ||
"""Initialize the dependency. | ||
This initialization is called in main.py in the lifespan context | ||
manager. | ||
""" | ||
self._state = f"{random.choice(ADJECTIVES)} {random.choice(ANIMALS)}" | ||
|
||
async def __call__(self) -> str: | ||
"""Provide the dependency. | ||
This gets called by the fastapi Depends() function when your | ||
path operation function is called. | ||
""" | ||
if self._state is None: | ||
raise DemoInternalError( | ||
"ExampleSingletonDependency not initialized." | ||
) | ||
|
||
return self._state | ||
|
||
async def aclose(self) -> None: | ||
"""Clean up the dependency. | ||
If needed, this method is called when the application is shutting down | ||
to close connections, etc.. This is called in the lifespan context | ||
manager in main.py | ||
""" | ||
self._state = None | ||
|
||
|
||
# This is the singleton instance of the dependency that's referenced in path | ||
# operation functions with the fastapi.Depends() function. Note that it needs | ||
# to be initialized before it can be used. This is done in the lifespan context | ||
# manager in main.py. Another option is to initialize it on the first use. | ||
example_singleton_dependency = ExampleSingletonDependency() | ||
|
||
|
||
ADJECTIVES = [ | ||
"speedy", | ||
"ponderous", | ||
"furious", | ||
"careful", | ||
"mammoth", | ||
"crafty", | ||
] | ||
|
||
ANIMALS = [ | ||
"cat", | ||
"dog", | ||
"sloth", | ||
"snail", | ||
"rabbit", | ||
"turtle", | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.