Skip to content

Commit

Permalink
wip rebase on remote branch & add wip work for actually saving data
Browse files Browse the repository at this point in the history
  • Loading branch information
liviuba committed Jul 31, 2024
1 parent b1bb4db commit f74dcc9
Show file tree
Hide file tree
Showing 11 changed files with 114 additions and 29 deletions.
4 changes: 4 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
**/.share
**/.git
**/.venv
.venv
2 changes: 1 addition & 1 deletion api/.vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
],
"python.testing.unittestEnabled": false,
"python.testing.pytestEnabled": true,
"python.testing.cwd": "${workspaceFolder}",
"python.testing.cwd": "${workspaceFolder}/api",
"[python]": {
"editor.defaultFormatter": "ms-python.black-formatter",
"editor.formatOnSave": true
Expand Down
20 changes: 8 additions & 12 deletions api/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,23 @@ FROM python:3.10.0

EXPOSE 8080


# Override default shell and use bash and bia env
#RUN wget --quiet https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh -O ~/miniconda.sh && \
# /bin/bash ~/miniconda.sh -b -p /opt/conda
#ENV PATH=/opt/conda/bin:$PATH
#RUN conda env create -f conda_env.yml

RUN curl -sSL https://install.python-poetry.org | python3 -
ENV PATH=/root/.local/bin:$PATH

# add files that poetry needs first so layers up to (including) pulling dependencies get reused
WORKDIR /bia-integrator

# only add poetry.lock if it exists (building on local)
ADD ./poetry.lock* /integrator-api/poetry.lock
ADD ./pyproject.toml /integrator-api/pyproject.toml
WORKDIR /integrator-api
ADD ./api/poetry.lock* api/poetry.lock
ADD ./api/pyproject.toml api/pyproject.toml
ADD ./bia-shared-datamodels bia-shared-datamodels

WORKDIR /bia-integrator/api
RUN poetry install

# Everything up to here should be reused most times

# add the actual project, which is what is often changed in between two different container builds
ADD ./ /integrator-api
ADD ./api ./

CMD ["poetry", "run", "uvicorn", "--workers", "4", "--port", "8080", "--log-config", "./src/log_config.yml", "--host", "0.0.0.0", "src.app:app"]
CMD ["poetry", "run", "uvicorn", "--workers", "4", "--port", "8080", "--log-config", "./src/log_config.yml", "--host", "0.0.0.0", "api.app:app"]
Empty file added api/api/__init__.py
Empty file.
14 changes: 13 additions & 1 deletion api/api/app.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,26 @@
from . import public
from . import private
from .models.repository import repository_create, Repository


import uvicorn
from fastapi import FastAPI
from typing import AsyncGenerator


async def repository_dependency() -> AsyncGenerator[Repository, None]:
db = await repository_create(init=False)
try:
yield db
finally:
db.close()


app = FastAPI(
generate_unique_id_function=lambda route: route.name,
# Setting this to true results in duplicated client classes (into *Input and *Output) where the api model has default values
# See https://fastapi.tiangolo.com/how-to/separate-openapi-schemas/#do-not-separate-schemas
separate_input_output_schemas=False,
debug=True,
)

app.openapi_version = "3.0.2"
Expand Down
13 changes: 10 additions & 3 deletions api/api/private.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,15 @@

# ?
import bia_shared_datamodels.bia_data_model as shared_data_models
from .models.repository import Repository
from . import constants
from fastapi import APIRouter, Depends

router = APIRouter()
router = APIRouter(
prefix="/private",
# dependencies=[Depends(get_current_user)], TODO
tags=[constants.OPENAPI_TAG_PRIVATE],
)
models_private = [
shared_data_models.Study,
shared_data_models.ImageAnnotationDataset,
Expand All @@ -15,8 +22,8 @@


def make_post_item(t):
def post_item(doc: t) -> None:
print(t)
async def post_item(doc: t, db: Repository = Depends()) -> None:
await db.persist_doc(doc)

return post_item

Expand Down
14 changes: 8 additions & 6 deletions api/api/public.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
from fastapi import APIRouter
from fastapi import APIRouter, Depends
from pydantic.alias_generators import to_snake

# ?
import bia_shared_datamodels.bia_data_model as shared_data_models
from .models.repository import Repository


router = APIRouter()
models_public = [
Expand All @@ -19,10 +21,10 @@ def make_get_item(t):
# https://eev.ee/blog/2011/04/24/gotcha-python-scoping-closures/

# @TODO: nicer wrapper?
def get_item(uuid: shared_data_models.UUID) -> dict:
print(t)

return {}
async def get_item(
uuid: shared_data_models.UUID, db: Repository = Depends()
) -> dict:
return db.get_doc(uuid, t)

return get_item

Expand All @@ -43,6 +45,6 @@ def not_overwritten(n: int) -> int:
return n


@router.get("/Study")
@router.get("/study")
def yes_overwritten(n: int) -> int:
return n
Empty file added api/api/tests/__init__.py
Empty file.
64 changes: 64 additions & 0 deletions api/api/tests/test_dummy.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
from fastapi.testclient import TestClient
import pytest
import uuid as uuid_lib


TEST_SERVER_BASE_URL = "http://localhost.com/v2"


def get_uuid() -> str:
# @TODO: make this constant and require mongo to always be clean?
generated = uuid_lib.uuid4()

return str(generated)


def get_client(**kwargs) -> TestClient:
from fastapi.responses import JSONResponse
from fastapi import Request
import traceback

from ..app import app

@app.exception_handler(Exception)
def generic_exception_handler(request: Request, exc: Exception):
return JSONResponse(
status_code=500,
content=traceback.format_exception(exc, value=exc, tb=exc.__traceback__),
)

return TestClient(app, base_url=TEST_SERVER_BASE_URL, **kwargs)


@pytest.fixture(scope="module")
def api_client() -> TestClient:
client = get_client(raise_server_exceptions=False)
# authenticate_client(client) # @TODO: DELETEME

return client


def test_create_thing(api_client: TestClient):
study_uuid = get_uuid()
study = {
"uuid": study_uuid,
"version": 0,
"release_date": "2023-01-31",
"accession_id": study_uuid,
"title": "Test BIA study",
"description": "description",
"licence": "CC_BY_4.0",
"see_also": [],
"model": {"type_name": "Study", "version": 1},
"author": [
{
"display_name": "Georg Brenneis",
"contact_email": "[email protected]",
"affiliation": [{"display_name": "University of Vienna"}],
}
],
"attribute": {},
}

rsp = api_client.post("private/study", json=study)
assert rsp.status_code == 201, rsp.json()
9 changes: 4 additions & 5 deletions api/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,20 +20,19 @@ services:
# #- "./.share/keyfile.secret:/home/share/keyfile/keyfile.secret"
bia-integrator-api:
build:
context: .
context: ..
dockerfile: ./api/Dockerfile
env_file: ./.env_compose
container_name: api
hostname: api
ports:
- 8080:8080
expose:
- 8080
volumes:
- "./.env_compose:/integrator-api/.env"
depends_on:
- biaint-mongo


volumes:
api_data:
#? do we always want a 'seed db'?
#external: true
#external: true
3 changes: 2 additions & 1 deletion api/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ ome-types = "^0.4.2"
xsdata = "23.8"
lxml = "^4.9.3"
json-log-formatter = "^1.0"
bia-shared-datamodels = { path = "../bia-shared-datamodels", develop = true }
#@TODO: CHANGEME
bia-shared-datamodels = { path = "../../prs/bia-integrator/bia-shared-datamodels", develop = true }

[tool.poetry.group.dev.dependencies]
locust = "^2.16.1"
Expand Down

0 comments on commit f74dcc9

Please sign in to comment.