Skip to content

Commit 4d65527

Browse files
authored
feat: aws manager (#17)
1 parent 45a2856 commit 4d65527

7 files changed

Lines changed: 39 additions & 85 deletions

File tree

aind-sharepoint-service-server/pyproject.toml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,10 @@ dynamic = ["version"]
1818

1919
dependencies = [
2020
'pydantic>=2.0',
21-
'pydantic-settings>=2.0',
21+
'aind-settings-utils>=0.1.0',
2222
'fastapi[standard]>=0.114.0',
2323
'fastapi-cache2[redis]>=0.2.2',
2424
'azure-identity>=1.15.0',
25-
'aind-settings-utils>=0.0.3',
2625
'requests',
2726
]
2827

aind-sharepoint-service-server/src/aind_sharepoint_service_server/configs.py

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,12 @@
33
from typing import ClassVar, Optional
44
from urllib.parse import urljoin
55

6-
from aind_settings_utils.aws import (
7-
ParameterStoreAppBaseSettings,
8-
)
6+
from aind_settings_utils.aws import SecretsManagerBaseSettings
97
from pydantic import Field, RedisDsn, SecretStr
108
from pydantic_settings import SettingsConfigDict
119

1210

13-
class Settings(ParameterStoreAppBaseSettings):
11+
class Settings(SecretsManagerBaseSettings):
1412
"""Settings needed to connect to Sharepoint database"""
1513

1614
model_config = SettingsConfigDict(
@@ -105,6 +103,4 @@ def nsb_present_url(self) -> str:
105103
)
106104

107105

108-
def get_settings() -> Settings:
109-
"""Return a Settings object."""
110-
return Settings()
106+
settings = Settings()

aind-sharepoint-service-server/src/aind_sharepoint_service_server/main.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
from redis.asyncio import from_url # noqa
1717

1818
from aind_sharepoint_service_server import __version__ as service_version
19-
from aind_sharepoint_service_server.configs import get_settings
19+
from aind_sharepoint_service_server.configs import settings
2020
from aind_sharepoint_service_server.route import router
2121

2222
# The log level can be set by adding an environment variable before launch.
@@ -34,7 +34,6 @@
3434
@asynccontextmanager
3535
async def lifespan(_: FastAPI) -> AsyncIterator[None]:
3636
"""Init cache and add to lifespan of app"""
37-
settings = get_settings()
3837
if settings.redis_url is not None:
3938
redis = from_url(settings.redis_url.unicode_string())
4039
FastAPICache.init(RedisBackend(redis), prefix="fastapi-cache")

aind-sharepoint-service-server/src/aind_sharepoint_service_server/models/nsb_2023.py

Lines changed: 8 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -528,9 +528,7 @@ class NSB2023LimsTaskflow(Enum, metaclass=EnumMeta):
528528
"Brain Observatory Transgenic Characterization"
529529
)
530530
BRAIN_OBSERVATORY_V1_DD = "Brain Observatory V1DD"
531-
BRAIN_OBSERVATORY_VISUAL_BEHAVIOR = (
532-
"Brain Observatory Visual Behavior"
533-
)
531+
BRAIN_OBSERVATORY_VISUAL_BEHAVIOR = "Brain Observatory Visual Behavior"
534532
BRAIN_OBSERVATORY_VISUAL_BEHAVIOR_1B = (
535533
"Brain Observatory Visual Behavior 1B"
536534
)
@@ -746,27 +744,21 @@ class NSB2023Procedure(Enum, metaclass=EnumMeta):
746744
SX_9__GRID_INJ_6_OR_9__MO = "Sx-09 Grid INJ (6 or 9) + Motor Ctx 2P"
747745
SX_11_19_HP__ONLY = "Sx-11&19 HP Only"
748746
SX_11_19_HP__TRANSCRANIAL = "Sx-11&19 HP Transcranial"
749-
SX_12__STEREOTAXIC__INJEC = (
750-
"Sx-12 Stereotaxic Injection (with Headpost)"
751-
)
747+
SX_12__STEREOTAXIC__INJEC = "Sx-12 Stereotaxic Injection (with Headpost)"
752748
SX_14__VISUAL__CTX_NP = "Sx-14 Visual Ctx NP"
753749
SX_15_WHC_NP = "Sx-15 WHC NP"
754750
SX_16_INJ_WHC_NP = "Sx-16 INJ + WHC NP"
755751
SX_17_DHC = "Sx-17 DHC"
756752
SX_18_INJ_DHC = "Sx-18 INJ+DHC"
757-
SX_21__FIBER__OPTIC__IMPL = (
758-
"Sx-21 Fiber Optic Implant (with Headpost)"
759-
)
753+
SX_21__FIBER__OPTIC__IMPL = "Sx-21 Fiber Optic Implant (with Headpost)"
760754
SX_21__INJECTION__FIBER = (
761755
"Sx-21 Injection + Fiber Optic Implant (with Headpost)"
762756
)
763757
SX_24__STEREOTAXIC_INJECT = "Sx-24 Stereotaxic injections: 1 INJ material"
764758
SX_25__STEREOTAXIC_INJECT = (
765759
"Sx-25 Stereotaxic injections: 2+ INJ materials"
766760
)
767-
SX_26_ISI_GUIDED__INJECTI = (
768-
"Sx-26 ISI-guided Injection (with Headpost)"
769-
)
761+
SX_26_ISI_GUIDED__INJECTI = "Sx-26 ISI-guided Injection (with Headpost)"
770762
SX__SPINAL__CORD_INJ = "Sx- Spinal Cord INJ"
771763
SX_EMG__ARRAY = "Sx- EMG Array"
772764
SX__TESTES__INJECTION = "Sx- Testes Injection"
@@ -779,9 +771,7 @@ class NSB2023Procedure(Enum, metaclass=EnumMeta):
779771
FRONTAL_CTX_2_P = "Frontal Ctx 2P"
780772
HP_ONLY = "HP Only"
781773
HP_TRANSCRANIAL = "HP Transcranial"
782-
INJECTION_FIBER_OPTIC_IMP = (
783-
"Injection+Fiber Optic Implant (with Headpost)"
784-
)
774+
INJECTION_FIBER_OPTIC_IMP = "Injection+Fiber Optic Implant (with Headpost)"
785775
INJ_MOTOR_CTX = "INJ + Motor Ctx"
786776
INJ_VISUAL_CTX_2_P = "INJ + Visual Ctx 2P"
787777
INJ_WHC_NP_1_INJECTION_LO = "INJ + WHC NP (1 Injection Location)"
@@ -5687,9 +5677,7 @@ class NSB2023List(BaseModel, extra="allow"):
56875677
)
56885678
craniotomy_type: Annotated[
56895679
NSB2023CraniotomyType, WrapValidator(optional_enum)
5690-
] = Field(
5691-
default=None, alias="CraniotomyType", title="Craniotomy Type"
5692-
)
5680+
] = Field(default=None, alias="CraniotomyType", title="Craniotomy Type")
56935681
created: Optional[datetime] = Field(
56945682
default=None, alias="Created", title="Created"
56955683
)
@@ -6163,9 +6151,7 @@ class NSB2023List(BaseModel, extra="allow"):
61636151
)
61646152
surgery_status: Annotated[
61656153
NSB2023SurgeryStatus, WrapValidator(optional_enum)
6166-
] = Field(
6167-
default=None, alias="SurgeryStatus", title="Surgery Status"
6168-
)
6154+
] = Field(default=None, alias="SurgeryStatus", title="Surgery Status")
61696155
test1: Optional[str] = Field(
61706156
default=None, alias="Test1", title="Initial Surgeon"
61716157
)
@@ -6175,9 +6161,7 @@ class NSB2023List(BaseModel, extra="allow"):
61756161
title="Follow up Surgeon",
61766162
)
61776163
thermistor: Annotated[NSB2023Thermistor, WrapValidator(optional_enum)] = (
6178-
Field(
6179-
default=None, alias="Thermistor", title="Thermistor"
6180-
)
6164+
Field(default=None, alias="Thermistor", title="Thermistor")
61816165
)
61826166
title: Optional[str] = Field(default=None, alias="Title", title="Title")
61836167
ui_version_string: Optional[str] = Field(

aind-sharepoint-service-server/src/aind_sharepoint_service_server/route.py

Lines changed: 19 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@
44

55
from azure.core.credentials import AccessToken
66
from azure.identity import ClientSecretCredential
7-
from fastapi import APIRouter, Depends, Path, status
7+
from fastapi import APIRouter, Path, status
88
from fastapi_cache.decorator import cache
99
from httpx import AsyncClient
1010

11-
from aind_sharepoint_service_server.configs import Settings, get_settings
11+
from aind_sharepoint_service_server.configs import settings
1212
from aind_sharepoint_service_server.handler import SessionHandler
1313
from aind_sharepoint_service_server.models.core import HealthCheck
1414
from aind_sharepoint_service_server.models.las_2020 import Las2020List
@@ -19,7 +19,7 @@
1919

2020

2121
@cache(expire=3360)
22-
async def get_access_token(settings: Settings) -> str:
22+
async def get_access_token() -> str:
2323
"""
2424
Get access token from either Azure or cache. Token is valid for 60 minutes.
2525
We set cache lifespan to 56 minutes.
@@ -38,9 +38,9 @@ async def get_access_token(settings: Settings) -> str:
3838

3939

4040
@cache(expire=3600)
41-
async def get_las_2020_list(settings: Settings) -> List[Dict[str, Any]]:
41+
async def get_las_2020_list() -> List[Dict[str, Any]]:
4242
"""Get the LAS_2020 list items"""
43-
bearer_token = await get_access_token(settings=settings)
43+
bearer_token = await get_access_token()
4444
headers = {
4545
"Authorization": f"Bearer {bearer_token}",
4646
"Content-Type": "application/json",
@@ -58,11 +58,9 @@ async def get_las_2020_list(settings: Settings) -> List[Dict[str, Any]]:
5858

5959

6060
# Not worthwhile to cache results for NSB lists
61-
async def get_nsb_2019_list(
62-
subject_id: str, settings: Settings
63-
) -> List[Dict[str, Any]]:
61+
async def get_nsb_2019_list(subject_id: str) -> List[Dict[str, Any]]:
6462
"""Get the NSB_2019 list items"""
65-
bearer_token = await get_access_token(settings=settings)
63+
bearer_token = await get_access_token()
6664
headers = {
6765
"Authorization": f"Bearer {bearer_token}",
6866
"Content-Type": "application/json",
@@ -79,11 +77,9 @@ async def get_nsb_2019_list(
7977
return list_items
8078

8179

82-
async def get_nsb_2023_list(
83-
subject_id: str, settings: Settings
84-
) -> List[Dict[str, Any]]:
80+
async def get_nsb_2023_list(subject_id: str) -> List[Dict[str, Any]]:
8581
"""Get the NSB_2023 list items"""
86-
bearer_token = await get_access_token(settings=settings)
82+
bearer_token = await get_access_token()
8783
headers = {
8884
"Authorization": f"Bearer {bearer_token}",
8985
"Content-Type": "application/json",
@@ -100,11 +96,9 @@ async def get_nsb_2023_list(
10096
return list_items
10197

10298

103-
async def get_nsb_present_list(
104-
subject_id: str, settings: Settings
105-
) -> List[Dict[str, Any]]:
99+
async def get_nsb_present_list(subject_id: str) -> List[Dict[str, Any]]:
106100
"""Get the NSB Present list items"""
107-
bearer_token = await get_access_token(settings=settings)
101+
bearer_token = await get_access_token()
108102
headers = {
109103
"Authorization": f"Bearer {bearer_token}",
110104
"Content-Type": "application/json",
@@ -153,14 +147,13 @@ async def get_las_2020(
153147
"value": "805811",
154148
}
155149
},
156-
),
157-
settings=Depends(get_settings),
150+
)
158151
):
159152
"""
160153
# LAS 2020 Endpoint
161154
Retrieve information from the LAS 2020 list for a given subject ID.
162155
"""
163-
las_2020_list = await get_las_2020_list(settings=settings)
156+
las_2020_list = await get_las_2020_list()
164157
las_2020_models = [
165158
Las2020List.model_validate(item["fields"])
166159
for item in las_2020_list
@@ -183,17 +176,14 @@ async def get_nsb_2019(
183176
"value": "656374",
184177
}
185178
},
186-
),
187-
settings=Depends(get_settings),
179+
)
188180
):
189181
"""
190182
# NSB 2019 Endpoint
191183
Retrieve information from the NSB 2019 list for a given subject ID.
192184
"""
193185

194-
nsb_2019_list = await get_nsb_2019_list(
195-
subject_id=subject_id, settings=settings
196-
)
186+
nsb_2019_list = await get_nsb_2019_list(subject_id=subject_id)
197187
nsb_2019_models = [
198188
NSB2019List.model_validate(item["fields"]) for item in nsb_2019_list
199189
]
@@ -214,17 +204,14 @@ async def get_nsb_2023(
214204
"value": "657849",
215205
}
216206
},
217-
),
218-
settings=Depends(get_settings),
207+
)
219208
):
220209
"""
221210
# NSB 2023 Endpoint
222211
Retrieve information from the NSB 2023-Archive list for a given subject ID.
223212
"""
224213

225-
nsb_2023_list = await get_nsb_2023_list(
226-
subject_id=subject_id, settings=settings
227-
)
214+
nsb_2023_list = await get_nsb_2023_list(subject_id=subject_id)
228215
nsb_2023_models = [
229216
NSB2023List.model_validate(item["fields"]) for item in nsb_2023_list
230217
]
@@ -245,17 +232,14 @@ async def get_nsb_present(
245232
"value": "790025",
246233
}
247234
},
248-
),
249-
settings=Depends(get_settings),
235+
)
250236
):
251237
"""
252238
# NSB Present Endpoint
253239
Retrieve information from the NSB 2023-Present list for a given subject ID.
254240
"""
255241

256-
nsb_present_list = await get_nsb_present_list(
257-
subject_id=subject_id, settings=settings
258-
)
242+
nsb_present_list = await get_nsb_present_list(subject_id=subject_id)
259243
nsb_present_models = [
260244
NSB2023List.model_validate(item["fields"]) for item in nsb_present_list
261245
]

aind-sharepoint-service-server/tests/conftest.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
from fastapi.testclient import TestClient
1111
from pydantic import RedisDsn
1212

13-
from aind_sharepoint_service_server.configs import Settings
13+
from aind_sharepoint_service_server.configs import settings
1414

1515
RESOURCES_DIR = Path(os.path.dirname(os.path.realpath(__file__))) / "resources"
1616

@@ -95,13 +95,12 @@ def client_with_redis() -> Generator[TestClient, Any, None]:
9595
# Import moved to be able to mock cache
9696
from aind_sharepoint_service_server.main import app
9797

98-
settings = Settings()
9998
settings_with_redis = settings.model_copy(
10099
update={"redis_url": RedisDsn("redis://example.com:1234")}, deep=True
101100
)
102101
with (
103102
patch(
104-
"aind_sharepoint_service_server.main.get_settings",
103+
"aind_sharepoint_service_server.main.settings",
105104
return_value=settings_with_redis,
106105
),
107106
patch(

aind-sharepoint-service-server/tests/test_route.py

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
from azure.core.credentials import AccessToken
88
from fastapi.testclient import TestClient
99

10-
from aind_sharepoint_service_server.configs import Settings
1110
from aind_sharepoint_service_server.route import (
1211
get_access_token,
1312
get_las_2020_list,
@@ -33,7 +32,7 @@ async def test_get_access_token(self, mock_azure_credentials: MagicMock):
3332
mock_azure_credentials.return_value.get_token.return_value = (
3433
AccessToken(token="abc", expires_on=100)
3534
)
36-
token = await get_access_token(settings=Settings())
35+
token = await get_access_token()
3736
mock_azure_credentials.assert_has_calls(
3837
[
3938
call(
@@ -61,7 +60,7 @@ async def test_get_las_2020_list(
6160
"""Tests get_las_2020_list method"""
6261
mock_get_access_token.return_value = "abc"
6362
mock_get_list_items.return_value = mock_get_las_2020_list_items
64-
list_items = await get_las_2020_list(settings=Settings())
63+
list_items = await get_las_2020_list()
6564
mock_client.assert_called_once()
6665
assert 4 == len(list_items)
6766

@@ -93,9 +92,7 @@ async def test_get_nsb_2023_list(
9392
"""Tests get_nsb_2023_list method"""
9493
mock_get_access_token.return_value = "abc"
9594
mock_get_list_items.return_value = mock_get_nsb_2023_list_items
96-
list_items = await get_nsb_2023_list(
97-
settings=Settings(), subject_id="657849"
98-
)
95+
list_items = await get_nsb_2023_list(subject_id="657849")
9996
mock_client.assert_called_once()
10097
assert 1 == len(list_items)
10198

@@ -127,9 +124,7 @@ async def test_get_nsb_2019_list(
127124
"""Tests get_nsb_2019_list method"""
128125
mock_get_access_token.return_value = "abc"
129126
mock_get_list_items.return_value = mock_get_nsb_2019_list_items
130-
list_items = await get_nsb_2019_list(
131-
settings=Settings(), subject_id="656374"
132-
)
127+
list_items = await get_nsb_2019_list(subject_id="656374")
133128
mock_client.assert_called_once()
134129
assert 1 == len(list_items)
135130

@@ -161,9 +156,7 @@ async def test_get_nsb_present_list(
161156
"""Tests get_nsb_present_list method"""
162157
mock_get_access_token.return_value = "abc"
163158
mock_get_list_items.return_value = mock_get_nsb_present_list_items
164-
list_items = await get_nsb_present_list(
165-
settings=Settings(), subject_id="790025"
166-
)
159+
list_items = await get_nsb_present_list(subject_id="790025")
167160
mock_client.assert_called_once()
168161
assert 1 == len(list_items)
169162

0 commit comments

Comments
 (0)