Skip to content

Commit da05e46

Browse files
committed
tests for tars
1 parent dd657bd commit da05e46

15 files changed

Lines changed: 623 additions & 326 deletions

File tree

aind-tars-service-server/src/aind_tars_service_server/configs.py

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
"""Module for settings to connect to TARS backend"""
22

3-
from azure.identity import ClientSecretCredential
3+
from typing import Optional
4+
45
from pydantic import Field, SecretStr
56
from pydantic_settings import BaseSettings, SettingsConfigDict
6-
from typing import Optional
7+
78

89
class Settings(BaseSettings):
910
"""Settings needed to connect to LabTracks Database"""
@@ -22,16 +23,6 @@ class Settings(BaseSettings):
2223
scope: str = Field(..., description="Scope")
2324
resource: str = Field(..., description="Resource")
2425
redis_url: Optional[str] = Field(default=None)
25-
26-
def get_bearer_token(self):
27-
"""Retrieves Access Token"""
28-
credentials = ClientSecretCredential(
29-
tenant_id=self.tenant_id,
30-
client_id=self.client_id,
31-
client_secret=self.client_secret.get_secret_value(),
32-
)
33-
token, exp = credentials.get_token(self.scope)
34-
return token, exp
3526

3627

3728
def get_settings() -> Settings:

aind-tars-service-server/src/aind_tars_service_server/handler.py

Lines changed: 6 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -118,11 +118,14 @@ def get_prep_lot_data(self, prep_lot_id: str) -> List[PrepLotData]:
118118
response = self._get_prep_lot_response(prep_lot_id=sanitized_id)
119119
prep_lot_data = []
120120
for d in response.data:
121-
if isinstance(d.lot, str) and d.lot.strip().lower() == sanitized_id.lower():
121+
if (
122+
isinstance(d.lot, str)
123+
and d.lot.strip().lower() == sanitized_id.lower()
124+
):
122125
prep_lot_data.append(d)
123126
return prep_lot_data
124127

125-
def _get_raw_molecules_response(self, plasmid_name: str) -> Response:
128+
def _get_raw_molecule_response(self, plasmid_name: str) -> Response:
126129
"""
127130
Get raw requests Response
128131
Parameters
@@ -161,7 +164,7 @@ def _get_molecule_response(self, plasmid_name: str) -> MoleculeResponse:
161164
162165
"""
163166

164-
response = self._get_raw_molecules_response(plasmid_name=plasmid_name)
167+
response = self._get_raw_molecule_response(plasmid_name=plasmid_name)
165168
response.raise_for_status()
166169
model_response = MoleculeResponse.model_validate_json(
167170
json.dumps(response.json())
@@ -256,29 +259,3 @@ def get_virus_data(self, virus_name: str) -> List[Virus]:
256259
else:
257260
continue
258261
return virus_data
259-
260-
def get_injection_material_data(self, prep_lot_id: str):
261-
"""
262-
Return injection material data for a prep_lot_id
263-
Parameters
264-
----------
265-
prep_lot_id : str
266-
267-
Returns
268-
-------
269-
List[PrepLotData]
270-
"""
271-
prep_lot_data = self.get_prep_lot_data(prep_lot_id=prep_lot_id)
272-
for lot in prep_lot_data:
273-
virus_tars_id = next(
274-
(
275-
alias["name"]
276-
for alias in lot["viralPrep"]["virus"]["aliases"]
277-
if alias["isPreferred"]
278-
),
279-
None,
280-
)
281-
# check virus registry with tars id
282-
virus_data = self.get_virus_data(virus_name=virus_tars_id)
283-
284-

aind-tars-service-server/src/aind_tars_service_server/main.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,23 @@
22

33
import logging
44
import os
5+
from collections.abc import AsyncIterator
6+
from contextlib import asynccontextmanager
57

68
from fastapi import FastAPI
79
from fastapi.middleware.cors import CORSMiddleware
810
from fastapi.routing import APIRoute
9-
from collections.abc import AsyncIterator
10-
from contextlib import asynccontextmanager
11-
12-
from aind_tars_service_server import __version__ as service_version
13-
from aind_tars_service_server.route import router
14-
from aind_tars_service_server.configs import get_settings
1511
from fastapi_cache import FastAPICache
1612
from fastapi_cache.backends.inmemory import InMemoryBackend
1713
from fastapi_cache.backends.redis import RedisBackend
1814

1915
# from redis import asyncio as aioredis # noqa
2016
from redis.asyncio import from_url # noqa
2117

18+
from aind_tars_service_server import __version__ as service_version
19+
from aind_tars_service_server.configs import get_settings
20+
from aind_tars_service_server.route import router
21+
2222
# The log level can be set by adding an environment variable before launch.
2323
log_level = os.getenv("LOG_LEVEL", "INFO")
2424
logging.basicConfig(level=log_level)
@@ -30,6 +30,7 @@
3030
3131
"""
3232

33+
3334
@asynccontextmanager
3435
async def lifespan(_: FastAPI) -> AsyncIterator[None]:
3536
"""Init cache and add to lifespan of app"""
@@ -41,6 +42,7 @@ async def lifespan(_: FastAPI) -> AsyncIterator[None]:
4142
FastAPICache.init(InMemoryBackend(), prefix="fastapi-cache")
4243
yield
4344

45+
4446
# noinspection PyTypeChecker
4547
app = FastAPI(
4648
title="aind-tars-service",

aind-tars-service-server/src/aind_tars_service_server/models.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,20 @@
11
"""Module for defining models from TARS"""
22

33
from datetime import datetime
4-
from typing import Any, List, Optional, Literal
4+
from typing import Any, List, Literal, Optional
55

66
from pydantic import BaseModel, Field
7+
78
from aind_tars_service_server import __version__
89

10+
911
class HealthCheck(BaseModel):
1012
"""Response model to validate and return when performing a health check."""
1113

1214
status: Literal["OK"] = "OK"
1315
service_version: str = __version__
1416

17+
1518
class BaseResponse(BaseModel):
1619
"""Most responses have this shape"""
1720

@@ -51,7 +54,7 @@ class Virus(DataModel):
5154
aliases: List[Alias] = Field(default=[])
5255
capsid: Optional[Any] = Field(default=None)
5356
citations: list = Field(default=None)
54-
molecules: list = Field(default=None) # List[Molecule]?
57+
molecules: list = Field(default=None) # List[Molecule]?
5558
otherMolecules: list = Field(default=None)
5659
patents: list = Field(default=None)
5760

@@ -171,8 +174,9 @@ class VirusResponse(BaseResponse):
171174

172175
data: List[Virus] = Field(default=[])
173176

177+
174178
class InjectionMaterialData(BaseModel):
175179
"""Tars Injection Material Data"""
176180

177181
prep_lot_data: List[PrepLotData] = Field(default=[])
178-
virus_data: List[Virus] = Field(default=[])
182+
virus_data: List[Virus] = Field(default=[])

aind-tars-service-server/src/aind_tars_service_server/route.py

Lines changed: 28 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,26 @@
11
"""Module to handle endpoint responses"""
22

3+
from typing import List
4+
5+
from azure.core.credentials import AccessToken
6+
from azure.identity import ClientSecretCredential
37
from fastapi import APIRouter, Depends, HTTPException, Path, status
4-
from aind_tars_service_server.handler import SessionHandler
5-
from aind_tars_service_server.models import HealthCheck
6-
from aind_tars_service_server.session import get_session
7-
from aind_tars_service_server.configs import Settings, get_settings
8-
from aind_tars_service_server.models import PrepLotData, MoleculeData, Virus
98
from fastapi_cache.decorator import cache
109
from requests import Session
11-
from typing import List
10+
11+
from aind_tars_service_server.configs import Settings, get_settings
12+
from aind_tars_service_server.handler import SessionHandler
13+
from aind_tars_service_server.models import (
14+
HealthCheck,
15+
MoleculeData,
16+
PrepLotData,
17+
Virus,
18+
)
19+
from aind_tars_service_server.session import get_session
1220

1321
router = APIRouter()
1422

23+
1524
@router.get(
1625
"/healthcheck",
1726
tags=["healthcheck"],
@@ -44,8 +53,12 @@ async def get_access_token(settings: Settings) -> str:
4453
str
4554
4655
"""
47-
token, _ = settings.get_bearer_token()
48-
return token
56+
credentials: AccessToken = ClientSecretCredential(
57+
tenant_id=settings.tenant_id,
58+
client_id=settings.client_id,
59+
client_secret=settings.client_secret.get_secret_value(),
60+
).get_token(settings.scope)
61+
return credentials.token
4962

5063

5164
@router.get(
@@ -58,8 +71,8 @@ async def get_viral_prep_lot(
5871
settings: Settings = Depends(get_settings),
5972
):
6073
"""
61-
## TARS Endpoint to retrieve injection materials.
62-
Retrieves injection materials information from TARS for a prep_lot_id.
74+
## TARS Endpoint to retrieve viral prep lot data.
75+
Retrieves viral prep lot information from TARS for a prep_lot_id.
6376
"""
6477
bearer_token = await get_access_token(settings=settings)
6578
handler = SessionHandler(
@@ -69,10 +82,11 @@ async def get_viral_prep_lot(
6982
if len(prep_lot_data) == 0:
7083
raise HTTPException(
7184
status_code=status.HTTP_404_NOT_FOUND,
72-
detail=f"Prep lot with ID {prep_lot_id} not found"
85+
detail=f"Prep lot with ID {prep_lot_id} not found",
7386
)
7487
return prep_lot_data
7588

89+
7690
@router.get(
7791
"/molecule/{plasmid_name}",
7892
response_model=List[MoleculeData],
@@ -94,10 +108,11 @@ async def get_molecule_data(
94108
if len(molecule_data) == 0:
95109
raise HTTPException(
96110
status_code=status.HTTP_404_NOT_FOUND,
97-
detail=f"Molecule data for plasmid with name {plasmid_name} not found"
111+
detail=f"Molecule data for {plasmid_name} not found",
98112
)
99113
return molecule_data
100114

115+
101116
@router.get(
102117
"/virus/{virus_name}",
103118
response_model=List[Virus],
@@ -119,32 +134,6 @@ async def get_virus_data(
119134
if len(virus_data) == 0:
120135
raise HTTPException(
121136
status_code=status.HTTP_404_NOT_FOUND,
122-
detail=f"Virus data for {virus_name} not found"
137+
detail=f"Virus data for {virus_name} not found",
123138
)
124139
return virus_data
125-
126-
# @router.get(
127-
# "/injection_materials/{prep_lot_id}",
128-
# response_model=List[PrepLotData],
129-
# )
130-
# async def get_injection_materials(
131-
# prep_lot_id: str = Path(..., examples=["VT3214g"]),
132-
# session: Session = Depends(get_session),
133-
# settings: Settings = Depends(get_settings),
134-
# ):
135-
# """
136-
# ## TARS Endpoint to retrieve injection materials.
137-
# Retrieves injection materials information from TARS for a prep_lot_id.
138-
# """
139-
# bearer_token = await get_access_token(settings=settings)
140-
# handler = SessionHandler(
141-
# session=session, bearer_token=bearer_token, settings=settings
142-
# )
143-
144-
# injection_materials = handler.get_injection_materials(prep_lot_id=prep_lot_id)
145-
# if len(injection_materials) == 0:
146-
# raise HTTPException(
147-
# status_code=status.HTTP_404_NOT_FOUND,
148-
# detail=f"Injection materials for prep lot with ID {prep_lot_id} not found"
149-
# )
150-
# return injection_materials

0 commit comments

Comments
 (0)