Skip to content

Commit

Permalink
Merge pull request #301 from AllenNeuralDynamics/release-v0.16.0
Browse files Browse the repository at this point in the history
Release v0.16.0
  • Loading branch information
jtyoung84 authored Nov 27, 2024
2 parents 4b97319 + 50e52b2 commit da0d5c2
Show file tree
Hide file tree
Showing 33 changed files with 2,281 additions and 327 deletions.
8 changes: 4 additions & 4 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ dynamic = ["version"]

dependencies = [
'pydantic-settings>=2.0',
'pydantic>=2.7,<2.9',
'aind-metadata-mapper[bergamo]==0.18.0',
'aind-data-schema==1.1.1',
'pydantic>=2.10',
'aind-metadata-mapper[bergamo]==0.21.0',
'aind-data-schema==1.2.0',
'typing-extensions==4.12.2'
]

Expand All @@ -43,7 +43,7 @@ server = [
'fastapi==0.115.0',
'uvicorn[standard]==0.31.0',
'python-dateutil',
'aind-slims-api==0.1.15',
'aind-slims-api==0.1.17',
'azure-identity==1.15.0'
]

Expand Down
2 changes: 1 addition & 1 deletion src/aind_metadata_service/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
"""REST service to retrieve metadata from databases."""

__version__ = "0.15.1"
__version__ = "0.16.0"
47 changes: 37 additions & 10 deletions src/aind_metadata_service/response_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
ViralMaterial,
)
from aind_data_schema.core.rig import Rig
from aind_data_schema.core.session import Session
from aind_data_schema.core.subject import Subject
from aind_metadata_mapper.core import JobResponse
from fastapi import Response
Expand All @@ -35,6 +36,7 @@
ProtocolInformation,
Instrument,
Rig,
Session,
)


Expand Down Expand Up @@ -89,37 +91,42 @@ def no_data_found_error_response(cls):
message="No Data Found.",
)

@staticmethod
def _validate_model(model) -> Optional[str]:
"""Helper method to validate a model and return validation errors."""
validation_error = None
try:
model.__class__.model_validate(model.model_dump())
except ValidationError as e:
validation_error = repr(e)
except (AttributeError, ValueError, KeyError) as oe:
validation_error = repr(oe)
return validation_error

def _map_data_response( # noqa: C901
self, validate: bool = True
) -> Union[Response, JSONResponse]:
"""Map ModelResponse with StatusCodes.DB_RESPONDED to a JSONResponse.
Perform validations, bypasses validation if flag is set to False."""

if len(self.aind_models) == 0:
status_code = StatusCodes.NO_DATA_FOUND.value
content_data = None
message = "No Data Found."

elif len(self.aind_models) == 1:
aind_model = self.aind_models[0]
content_data = jsonable_encoder(
json.loads(aind_model.model_dump_json())
)
if validate:
validation_error = None
try:
aind_model.__class__.model_validate(
aind_model.model_dump()
)
except ValidationError as e:
validation_error = repr(e)
except (AttributeError, ValueError, KeyError) as oe:
validation_error = repr(oe)
validation_error = self._validate_model(aind_model)
if validation_error:
status_code = StatusCodes.INVALID_DATA.value
message = f"Validation Errors: {validation_error}"
else:
status_code = StatusCodes.VALID_DATA.value
message = "Valid Model."
# if validate flag is False
else:
status_code = StatusCodes.UNPROCESSIBLE_ENTITY.value
message = (
Expand All @@ -132,13 +139,33 @@ def _map_data_response( # noqa: C901
"There was an error retrieving records from one or more of"
" the databases."
)

else:
status_code = StatusCodes.MULTIPLE_RESPONSES.value
message = "Multiple Items Found."
content_data = [
jsonable_encoder(json.loads(model.model_dump_json()))
for model in self.aind_models
]

if validate:
# Validate each model and accumulate errors
validation_errors = []
for model in self.aind_models:
error = self._validate_model(model)
print(error)
if error:
validation_errors.append(error)

if validation_errors:
message += (
f" Validation Errors: {', '.join(validation_errors)}"
)
else:
message += " All Models Valid."
else:
message += " Models have not been validated."

return JSONResponse(
status_code=status_code,
content=({"message": message, "data": content_data}),
Expand Down
9 changes: 9 additions & 0 deletions src/aind_metadata_service/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,15 @@ async def retrieve_rig(rig_id):
return model_response.map_to_json_response(validate=False)


@app.get("/ecephys_sessions_by_subject/{subject_id}")
async def retrieve_sessions(subject_id):
"""Retrieves sessions from slims"""
model_response = await run_in_threadpool(
slims_client.get_sessions_model_response, subject_id=subject_id
)
return model_response.map_to_json_response()


@app.get("/protocols/{protocol_name}")
async def retrieve_protocols(
protocol_name,
Expand Down
19 changes: 11 additions & 8 deletions src/aind_metadata_service/sharepoint/las2020/mapping.py
Original file line number Diff line number Diff line change
Expand Up @@ -2094,7 +2094,7 @@ def map_viral_materials(injectable_materials: List[InjectableMaterial]):
)
return viral_materials

def get_procedure(self, subject_id) -> Surgery:
def get_procedure(self, subject_id) -> Optional[Surgery]:
"""Return Surgery as best as possible from a record."""
subject_procedures = []
if self.has_ip_injection():
Expand All @@ -2118,10 +2118,13 @@ def get_procedure(self, subject_id) -> Surgery:
injection_materials=injection_materials,
)
subject_procedures.append(ro_injection)
return Surgery.model_construct(
experimenter_full_name=self.aind_author_id,
iacuc_protocol=self.aind_protocol,
start_date=self.aind_n_start_date,
end_date=self.aind_n_end_date,
procedures=subject_procedures,
)
if subject_procedures:
return Surgery.model_construct(
experimenter_full_name=self.aind_author_id,
iacuc_protocol=self.aind_protocol,
start_date=self.aind_n_start_date,
end_date=self.aind_n_end_date,
procedures=subject_procedures,
)
else:
return None
3 changes: 2 additions & 1 deletion src/aind_metadata_service/sharepoint/las2020/procedures.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,5 +49,6 @@ def get_procedures_from_sharepoint(
las_model = LASList.model_validate(list_item.to_json())
mapped_model = MappedLASList(las=las_model)
procedure = mapped_model.get_procedure(subject_id=subject_id)
list_of_procedures.append(procedure)
if procedure:
list_of_procedures.append(procedure)
return list_of_procedures
Loading

0 comments on commit da0d5c2

Please sign in to comment.