-
Notifications
You must be signed in to change notification settings - Fork 0
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
Refactor magstats to fast api #173
Open
mmolina2018
wants to merge
21
commits into
main
Choose a base branch
from
refactor-magstats-to-FastAPI
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
21 commits
Select commit
Hold shift + click to select a range
4b8edba
refactor: create structure and first try
mmolina2018 72269f4
refactor: create service and database
mmolina2018 9c6878b
refactor: add core and api
mmolina2018 8c98570
refactor: create tests
mmolina2018 920ba87
refactor: add tests magstats
mmolina2018 d1bbd15
cd: add magstats workflows
mmolina2018 2dcbb97
refactor: add dependencies
mmolina2018 0766d74
ci: add packages
mmolina2018 12a7e9e
ci: change tests
mmolina2018 18a521b
refactor: fix tests
mmolina2018 72cb025
refactor: delete mongo
mmolina2018 0e5a377
refactor:change db tests
mmolina2018 b7eef71
refactor: change error structure
mmolina2018 5254787
refactor: fix test_service
mmolina2018 9826617
refactor: finish testing
mmolina2018 65f9bfb
style: black formatting
mmolina2018 beb8bd5
cd: change path in dockerfile and add build
mmolina2018 7f9a2ae
fix: name error
mmolina2018 643f594
Merge branch 'main' into magstats-to-FastAPI
mmolina2018 48c4660
pull main changes
mmolina2018 028d86e
ci: change dockerfile
mmolina2018 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 |
---|---|---|
@@ -0,0 +1,30 @@ | ||
FROM python:3.11 as python-base | ||
LABEL org.opencontainers.image.authors="ALeRCE" | ||
ENV PYTHONDONTWRITEBYTECODE=1 \ | ||
PYTHONUNBUFFERED=1 \ | ||
PYTHONFAULTHANDLER=1 \ | ||
PIP_NO_CACHE_DIR=off \ | ||
PIP_DISABLE_PIP_VERSION_CHECK=on \ | ||
PIP_DEFAULT_TIMEOUT=100 \ | ||
POETRY_VIRTUALENVS_IN_PROJECT=true \ | ||
POETRY_NO_INTERACTION=1 | ||
|
||
|
||
FROM python-base as builder | ||
RUN pip install poetry | ||
WORKDIR /app | ||
COPY ./poetry.lock ./pyproject.toml /app | ||
RUN poetry install --no-root --without=dev | ||
|
||
|
||
FROM python:3.11-slim as production | ||
RUN pip install poetry | ||
COPY --from=builder /app /app | ||
WORKDIR /app | ||
COPY ./README.md /app/README.md | ||
COPY ./entrypoint.sh /app/ | ||
COPY ./core /app/core | ||
COPY ./api /app/api | ||
COPY ./database /app/database | ||
RUN poetry install --only-root | ||
CMD ["bash", "entrypoint.sh"] |
Empty file.
Empty file.
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,23 @@ | ||
import os | ||
from fastapi.middleware.cors import CORSMiddleware | ||
from fastapi import FastAPI | ||
from .routes import router | ||
from prometheus_fastapi_instrumentator import Instrumentator | ||
|
||
app = FastAPI() | ||
instrumentator = Instrumentator().instrument(app) | ||
|
||
app.add_middleware( | ||
CORSMiddleware, | ||
allow_origins=["*"], | ||
allow_credentials=True, | ||
allow_methods=["*"], | ||
allow_headers=["*"], | ||
) | ||
|
||
app.include_router(router) | ||
|
||
|
||
@app.on_event("startup") | ||
async def _startup(): | ||
instrumentator.expose(app) |
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,27 @@ | ||
from fastapi import HTTPException | ||
from core.exceptions import ( | ||
DatabaseError, | ||
OidError, | ||
) | ||
import logging | ||
|
||
|
||
def handle_success(result): | ||
return result | ||
|
||
|
||
def handle_error(err: Exception): | ||
if isinstance(err, DatabaseError): | ||
_handle_server_error(err) | ||
if isinstance(err, OidError): | ||
_handle_client_error(err) | ||
|
||
|
||
def _handle_server_error(err: Exception): | ||
logging.error(err) | ||
raise HTTPException(status_code=500, detail=str(err)) | ||
|
||
|
||
def _handle_client_error(err: Exception): | ||
print(str(err)) | ||
raise HTTPException(status_code=400, detail=str(err)) |
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,24 @@ | ||
from fastapi import Request, APIRouter | ||
from core.service import get_magstats | ||
from .result_handler import handle_success, handle_error | ||
from database.sql import session | ||
|
||
router = APIRouter() | ||
|
||
|
||
@router.get("/") | ||
def root(): | ||
return "this is the magstats module" | ||
|
||
|
||
@router.get("/magstats/{oid}") | ||
def magstats( | ||
request: Request, | ||
oid: str, | ||
): | ||
return get_magstats( | ||
oid=oid, | ||
session_factory=session, | ||
handle_success=handle_success, | ||
handle_error=handle_error, | ||
) |
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,22 @@ | ||
class WrapperException(BaseException): | ||
def __init__(self, original_e, subcode=None): | ||
super().__init__() | ||
self.original_exception = original_e | ||
self.subcode = subcode | ||
|
||
def __str__(self) -> str: | ||
return self.original_exception.__str__() | ||
|
||
|
||
class DatabaseError(WrapperException): | ||
def __init__(self, original_e, subcode=None): | ||
super().__init__(original_e, subcode) | ||
|
||
|
||
class OidError(BaseException): | ||
def __init__(self, oid) -> None: | ||
super().__init__() | ||
self.oid = oid | ||
|
||
def __str__(self) -> str: | ||
return f"Can't retrieve magstats oid not recognized {self.oid}" |
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,33 @@ | ||
from pydantic import BaseModel, Field | ||
|
||
|
||
class MagstatsModel(BaseModel): | ||
fid: int = Field(description="Filter ID (1=g; 2=r, 3=i)") | ||
stellar: bool = Field( | ||
description="Whether the object appears to be unresolved in the given band" | ||
) | ||
corrected: bool = Field( | ||
description="Whether the corrected photometry should be used" | ||
) | ||
ndet: int = Field(description="Number of detections in the given band") | ||
ndubious: int = Field(description="Number of dubious corrections") | ||
magmean: float = Field(description="The mean magnitude for the given fid") | ||
magmedian: float = Field( | ||
description="The median magnitude for the given fid" | ||
) | ||
magmax: float = Field(description="The max magnitude for the given fid") | ||
magmin: float = Field(description="The min magnitude for the given fid") | ||
magsigma: float = Field( | ||
description="Magnitude standard deviation for the given fid" | ||
) | ||
maglast: float = Field(description="The last magnitude for the given fid") | ||
magfirst: float = Field( | ||
description="The first magnitude for the given fid" | ||
) | ||
firstmjd: float = Field( | ||
description="The time of the first detection in the given fid" | ||
) | ||
lastmjd: float = Field( | ||
description="The time of the last detection in the given fid" | ||
) | ||
step_id_corr: str = Field(description="Correction step pipeline version") |
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,51 @@ | ||
from contextlib import AbstractContextManager | ||
from typing import Callable | ||
from .models import MagstatsModel | ||
from pymongo.database import Database | ||
from sqlalchemy.orm import Session | ||
from .exceptions import DatabaseError, OidError | ||
from db_plugins.db.sql import models | ||
from sqlalchemy import select, text | ||
|
||
|
||
def default_handle_success(result): | ||
return result | ||
|
||
|
||
def default_handle_error(error): | ||
raise error | ||
|
||
|
||
def get_magstats( | ||
oid: str, | ||
session_factory: Callable[..., AbstractContextManager[Session]] = None, | ||
handle_success: Callable[..., dict] = default_handle_success, | ||
handle_error: Callable[Exception, None] = default_handle_error, | ||
): | ||
result = _get_magstats_sql(session_factory, oid, handle_error) | ||
if len(result) == 0: | ||
handle_error(OidError(oid)) | ||
else: | ||
print(result) | ||
return handle_success(result) | ||
|
||
|
||
def _get_magstats_sql( | ||
session_factory: Callable[..., AbstractContextManager[Session]], | ||
oid: str, | ||
handle_error: Callable[Exception, None] = default_handle_error, | ||
): | ||
try: | ||
with session_factory() as session: | ||
stmt = select(models.MagStats, text("'ztf'")).filter( | ||
models.MagStats.oid == oid | ||
) | ||
result = session.execute(stmt) | ||
result = [ | ||
MagstatsModel(**ob[0].__dict__, tid=ob[1]) | ||
for ob in result.all() | ||
] | ||
return result | ||
|
||
except Exception as e: | ||
return handle_error(DatabaseError(e)) |
Empty file.
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,36 @@ | ||
from contextlib import contextmanager, AbstractContextManager | ||
import logging | ||
import os | ||
from typing import Callable | ||
from sqlalchemy.orm import scoped_session, sessionmaker, Session | ||
from sqlalchemy.engine import Engine, create_engine | ||
|
||
|
||
logger = logging.getLogger(__name__) | ||
|
||
|
||
user = os.getenv("PSQL_USER") | ||
pwd = os.getenv("PSQL_PASSWORD") | ||
host = os.getenv("PSQL_HOST") | ||
port = os.getenv("PSQL_PORT") | ||
db = os.getenv("PSQL_DATABASE") | ||
db_url = f"postgresql://{user}:{pwd}@{host}:{port}/{db}" | ||
|
||
engine: Engine = create_engine(db_url, echo=False) | ||
|
||
|
||
@contextmanager | ||
def session() -> Callable[..., AbstractContextManager[Session]]: | ||
session_factory = scoped_session( | ||
sessionmaker(autocommit=False, autoflush=False, bind=engine) | ||
) | ||
session: Session = session_factory() | ||
try: | ||
yield session | ||
except Exception: | ||
logger.debug("Connecting databases") | ||
logger.exception("Session rollback because of exception") | ||
session.rollback() | ||
raise | ||
finally: | ||
session.close() |
Binary file not shown.
Binary file not shown.
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,3 @@ | ||
#!/usr/bin/env sh | ||
|
||
poetry run uvicorn --port $PORT api.api:app |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
El path acá no está correcto