Skip to content

Commit

Permalink
Merge pull request #51 from bento-platform/refact/bento-fastapi-base
Browse files Browse the repository at this point in the history
refact: use Bento FastAPI base class + remove redundant code
  • Loading branch information
davidlougheed authored May 27, 2024
2 parents 4138236 + e3edc22 commit 059e5da
Show file tree
Hide file tree
Showing 9 changed files with 22 additions and 61 deletions.
31 changes: 11 additions & 20 deletions bento_drop_box_service/app.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
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 bento_lib.apps.fastapi import BentoFastAPI
from bento_lib.service_info.types import BentoExtraServiceInfo

from . import __version__
from .authz import authz_middleware
from .config import get_config
from .constants import BENTO_SERVICE_KIND, SERVICE_TYPE
from .logger import get_logger
from .routes import drop_box_router

Expand All @@ -14,23 +13,15 @@
]


application = FastAPI()
application.include_router(drop_box_router)
BENTO_SERVICE_INFO: BentoExtraServiceInfo = {
"serviceKind": BENTO_SERVICE_KIND,
"gitRepository": "https://github.com/bento-platform/bento_drop_box_service",
}

# 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=["*"],
application = BentoFastAPI(
authz_middleware, config_for_setup, get_logger(config_for_setup), BENTO_SERVICE_INFO, SERVICE_TYPE, __version__
)

# Non-standard middleware setup so that we can import the instance and use it for dependencies too
authz_middleware.attach(application)

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))
application.include_router(drop_box_router)
8 changes: 2 additions & 6 deletions bento_drop_box_service/authz.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from bento_lib.auth.middleware.fastapi import FastApiAuthMiddleware
from .config import get_config
from .logger import get_logger

__all__ = [
"authz_middleware",
Expand All @@ -8,10 +9,5 @@
# 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,
)
authz_middleware = FastApiAuthMiddleware.build_from_pydantic_config(config, get_logger(config))
2 changes: 1 addition & 1 deletion bento_drop_box_service/backends/local.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ async def _get_directory_tree(
"size": entry_path_stat.st_size,
"lastModified": entry_path_stat.st_mtime,
"lastMetadataChange": entry_path_stat.st_ctime,
"uri": self.config.service_url + f"/objects{rel_path}",
"uri": self.config.service_url_base_path + f"/objects{rel_path}",
})
})

Expand Down
7 changes: 2 additions & 5 deletions bento_drop_box_service/config.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from bento_lib.config.pydantic import BentoBaseConfig
from bento_lib.config.pydantic import BentoFastAPIBaseConfig
from fastapi import Depends
from functools import lru_cache
from typing import Annotated, Literal
Expand All @@ -12,18 +12,15 @@
]


class Config(BentoBaseConfig):
class Config(BentoFastAPIBaseConfig):
service_id: str = str(":".join(list(SERVICE_TYPE.values())[:2]))
service_name: str = "Bento Drop Box Service"
service_description: str = "Drop box service for a Bento platform node."
service_url: str = "http://127.0.0.1:5000" # base URL to construct object URIs from

service_data: str = "data/"
service_data_source: Literal["local"] = "local"
traversal_limit: int = 16

authz_enabled: bool = True


@lru_cache()
def get_config() -> Config:
Expand Down
7 changes: 2 additions & 5 deletions bento_drop_box_service/constants.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from bento_lib.service_info.helpers import build_bento_service_type
from bento_lib.service_info.types import GA4GHServiceType
from bento_drop_box_service import __version__

Expand All @@ -7,8 +8,4 @@
]

BENTO_SERVICE_KIND = "drop-box"
SERVICE_TYPE: GA4GHServiceType = {
"group": "ca.c3g.bento",
"artifact": BENTO_SERVICE_KIND,
"version": __version__,
}
SERVICE_TYPE: GA4GHServiceType = build_bento_service_type(BENTO_SERVICE_KIND, __version__)
20 changes: 0 additions & 20 deletions bento_drop_box_service/routes.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,13 @@
from bento_lib.auth.permissions import P_VIEW_DROP_BOX, P_INGEST_DROP_BOX, P_DELETE_DROP_BOX
from bento_lib.auth.resources import RESOURCE_EVERYTHING
from bento_lib.service_info.helpers import build_service_info_from_pydantic_config
from fastapi import APIRouter, Form, Request, status
from fastapi.exceptions import HTTPException
from fastapi.responses import JSONResponse
from starlette.responses import Response
from typing import Annotated

from . import __version__
from .authz import authz_middleware
from .backends.dependency import BackendDependency
from .constants import BENTO_SERVICE_KIND, SERVICE_TYPE
from .config import ConfigDependency
from .logger import LoggerDependency


drop_box_router = APIRouter()
Expand Down Expand Up @@ -69,18 +64,3 @@ async def drop_box_upload(request: Request, path: str, backend: BackendDependenc
)
async def drop_box_delete(path: str, backend: BackendDependency):
return await backend.delete_at_path(path)


@drop_box_router.get("/service-info", dependencies=[authz_middleware.dep_public_endpoint()])
async def service_info(config: ConfigDependency, logger: LoggerDependency) -> Response:
# Spec: https://github.com/ga4gh-discovery/ga4gh-service-info
return JSONResponse(await build_service_info_from_pydantic_config(
config,
logger,
{
"serviceKind": BENTO_SERVICE_KIND,
"gitRepository": "https://github.com/bento-platform/bento_drop_box_service",
},
SERVICE_TYPE,
__version__,
))
2 changes: 1 addition & 1 deletion poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api"

[tool.poetry]
name = "bento_drop_box_service"
version = "1.1.6"
version = "1.1.7"
description = "Drop box and basic file management service for the Bento platform."
authors = ["David Lougheed <[email protected]>", "Simon Chénard <[email protected]>"]
readme = "README.md"
Expand All @@ -19,7 +19,7 @@ classifiers = [

[tool.poetry.dependencies]
python = "^3.10.0"
bento-lib = {extras = ["fastapi"], version = "^11.10.0"}
bento-lib = {extras = ["fastapi"], version = "^11.10.1"}
aiofiles = "^23.2.1"
fastapi = "^0.111.0"
werkzeug = "^3.0.3"
Expand Down
2 changes: 1 addition & 1 deletion tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
@lru_cache
def get_test_local_config():
os.environ["BENTO_DEBUG"] = "True"
os.environ["AUTHZ_ENABLED"] = "False"
os.environ["BENTO_AUTHZ_ENABLED"] = "False"
os.environ["CORS_ORIGINS"] = "*"
os.environ["SERVICE_DATA"] = local_dir
os.environ["BENTO_AUTHZ_SERVICE_URL"] = "https://skip"
Expand Down

0 comments on commit 059e5da

Please sign in to comment.