-
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 #28 from bento-platform/chore/fastapi-rewrite
refact!: FastAPI rewrite
- Loading branch information
Showing
31 changed files
with
640 additions
and
1,229 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 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 |
---|---|---|
|
@@ -8,7 +8,6 @@ __pycache__ | |
.tox | ||
|
||
# IDE stuff | ||
.idea/workspace.xml | ||
.idea/dataSources* | ||
.idea/* | ||
*.swp | ||
*.swo |
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
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 |
---|---|---|
@@ -1,46 +1,36 @@ | ||
import os | ||
|
||
from bento_lib.responses.quart_errors import ( | ||
quart_error_wrap, | ||
quart_error_wrap_with_traceback, | ||
quart_bad_request_error, | ||
quart_not_found_error, | ||
quart_internal_server_error | ||
from bento_lib.responses.fastapi_errors import http_exception_handler_factory, validation_exception_handler_factory | ||
from fastapi import FastAPI | ||
from fastapi.exceptions import RequestValidationError | ||
from fastapi.middleware.cors import CORSMiddleware | ||
from starlette.exceptions import HTTPException as StarletteHTTPException | ||
|
||
from .authz import authz_middleware | ||
from .config import get_config | ||
from .logger import get_logger | ||
from .routes import drop_box_router | ||
|
||
__all__ = [ | ||
"application", | ||
] | ||
|
||
|
||
application = FastAPI() | ||
application.include_router(drop_box_router) | ||
|
||
# TODO: Find a way to DI this | ||
config_for_setup = get_config() | ||
|
||
application.add_middleware( | ||
CORSMiddleware, | ||
allow_origins=config_for_setup.cors_origins, | ||
allow_headers=["Authorization"], | ||
allow_credentials=True, | ||
allow_methods=["*"], | ||
) | ||
from quart import Quart | ||
from werkzeug.exceptions import BadRequest, NotFound | ||
|
||
from bento_drop_box_service.backend import close_backend | ||
from bento_drop_box_service.constants import SERVICE_NAME, SERVICE_TYPE | ||
from bento_drop_box_service.routes import drop_box_service | ||
|
||
|
||
SERVICE_DATA = os.environ.get("SERVICE_DATA", "data/") | ||
MINIO_URL = os.environ.get("MINIO_URL", None) | ||
|
||
application = Quart(__name__) | ||
application.config.from_mapping( | ||
BENTO_DEBUG=os.environ.get( | ||
"CHORD_DEBUG", os.environ.get("BENTO_DEBUG", os.environ.get("QUART_ENV", "production")) | ||
).strip().lower() in ("true", "1", "development"), | ||
SERVICE_ID=os.environ.get("SERVICE_ID", str(":".join(list(SERVICE_TYPE.values())[:2]))), | ||
SERVICE_DATA_SOURCE="minio" if MINIO_URL else "local", | ||
SERVICE_DATA=None if MINIO_URL else SERVICE_DATA, | ||
SERVICE_URL=os.environ.get("SERVICE_URL", "http://127.0.0.1:5000"), # base URL to construct object URIs from | ||
MINIO_URL=MINIO_URL, | ||
MINIO_USERNAME=os.environ.get("MINIO_USERNAME") if MINIO_URL else None, | ||
MINIO_PASSWORD=os.environ.get("MINIO_PASSWORD") if MINIO_URL else None, | ||
MINIO_BUCKET=os.environ.get("MINIO_BUCKET") if MINIO_URL else None, | ||
MINIO_RESOURCE=None, # manual application-wide override for MinIO boto3 resource | ||
TRAVERSAL_LIMIT=16, | ||
) | ||
|
||
application.register_blueprint(drop_box_service) | ||
|
||
# Generic catch-all | ||
application.register_error_handler(Exception, quart_error_wrap_with_traceback(quart_internal_server_error, | ||
service_name=SERVICE_NAME)) | ||
application.register_error_handler(BadRequest, quart_error_wrap(quart_bad_request_error)) | ||
application.register_error_handler(NotFound, quart_error_wrap(quart_not_found_error)) | ||
# Non-standard middleware setup so that we can import the instance and use it for dependencies too | ||
authz_middleware.attach(application) | ||
|
||
application.teardown_appcontext(close_backend) | ||
application.exception_handler(StarletteHTTPException)( | ||
http_exception_handler_factory(get_logger(config_for_setup), authz_middleware)) | ||
application.exception_handler(RequestValidationError)(validation_exception_handler_factory(authz_middleware)) |
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,17 @@ | ||
from bento_lib.auth.middleware.fastapi import FastApiAuthMiddleware | ||
from .config import get_config | ||
|
||
__all__ = [ | ||
"authz_middleware", | ||
] | ||
|
||
# TODO: Find a way to DI this | ||
config = get_config() | ||
|
||
|
||
# Non-standard middleware setup so that we can import the instance and use it for dependencies too | ||
authz_middleware = FastApiAuthMiddleware( | ||
config.bento_authz_service_url, | ||
debug_mode=config.bento_debug, | ||
enabled=config.authz_enabled, | ||
) |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,8 @@ | ||
from .base import DropBoxBackend | ||
from .local import LocalBackend | ||
from .minio import MinioBackend | ||
|
||
|
||
__all__ = [ | ||
"DropBoxBackend", | ||
"LocalBackend", | ||
"MinioBackend", | ||
] |
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 |
---|---|---|
@@ -1,27 +1,51 @@ | ||
import logging | ||
from abc import ABC, abstractmethod | ||
from typing import Tuple | ||
from werkzeug import Request, Response | ||
from fastapi import Request, Response | ||
from typing import TypedDict | ||
|
||
from ..config import Config | ||
|
||
__all__ = ["DropBoxBackend"] | ||
|
||
__all__ = ["DropBoxEntry", "DropBoxBackend"] | ||
|
||
|
||
# TODO: py3.11: individual optional fields | ||
class DropBoxEntry(TypedDict, total=False): | ||
name: str | ||
filePath: str | ||
relativePath: str | ||
uri: str | ||
size: int | ||
lastModified: float | ||
lastMetadataChange: float | ||
contents: tuple["DropBoxEntry", ...] | ||
|
||
|
||
class DropBoxBackend(ABC): | ||
def __init__(self, logger: logging.Logger): | ||
self.logger = logger | ||
def __init__(self, config: Config, logger: logging.Logger): | ||
self._config = config | ||
self._logger = logger | ||
|
||
@property | ||
def config(self) -> Config: | ||
return self._config | ||
|
||
@property | ||
def logger(self) -> logging.Logger: | ||
return self._logger | ||
|
||
@abstractmethod | ||
async def get_directory_tree(self) -> Tuple[dict]: | ||
async def get_directory_tree(self) -> tuple[DropBoxEntry, ...]: # pragma: no cover | ||
pass | ||
|
||
@abstractmethod | ||
async def upload_to_path(self, request: Request, path: str, content_length: int) -> Response: | ||
async def upload_to_path(self, request: Request, path: str, content_length: int) -> Response: # pragma: no cover | ||
pass | ||
|
||
@abstractmethod | ||
async def retrieve_from_path(self, path: str) -> Response: | ||
async def retrieve_from_path(self, path: str) -> Response: # pragma: no cover | ||
pass | ||
|
||
async def close(self): | ||
@abstractmethod | ||
async def delete_at_path(self, path: str) -> None: # pragma: no cover | ||
pass |
Oops, something went wrong.