Skip to content

Commit

Permalink
Feat 134 smartsheet client (#150)
Browse files Browse the repository at this point in the history
* feat: adds smartsheet client

* feat: makes get async

* feat: drop support for python 3.7
  • Loading branch information
jtyoung84 authored Oct 30, 2023
1 parent b4bca31 commit 6e507bd
Show file tree
Hide file tree
Showing 11 changed files with 549 additions and 18 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: [ '3.7', '3.8', '3.9', '3.10' ]
python-version: [ '3.8', '3.9', '3.10', '3.11' ]
steps:
- uses: actions/checkout@v3
- name: Set up Python ${{ matrix.python-version }}
Expand Down
5 changes: 3 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ license = {text = "MIT"}
authors = [
{name = "Allen Institute for Neural Dynamics"}
]
requires-python = ">=3.7"
requires-python = ">=3.8"
classifiers = [
"Programming Language :: Python :: 3"
]
Expand All @@ -36,6 +36,7 @@ server = [
'pydantic<2.0',
'pyodbc',
'office365-rest-python-client==2.4.1',
'smartsheet-python-sdk==3.0.2',
'fastapi',
'uvicorn[standard]',
'python-dateutil'
Expand All @@ -54,7 +55,7 @@ readme = {file = ["README.md"]}

[tool.black]
line-length = 79
target_version = ['py36']
target_version = ['py38']
exclude = '''
(
Expand Down
7 changes: 5 additions & 2 deletions src/aind_metadata_service/labtracks/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -349,8 +349,11 @@ def _map_housing(
room_id = None if room_id is None or int(room_id) < 0 else room_id
cage_id = None if cage_id is None or int(cage_id) < 0 else cage_id

return Housing.construct(room_id=room_id,
cage_id=cage_id) if room_id is not None or cage_id is not None else None
return (
Housing.construct(room_id=room_id, cage_id=cage_id)
if room_id is not None or cage_id is not None
else None
)

def map_response_to_subject(self, results: List[dict]) -> List[Subject]:
"""
Expand Down
5 changes: 5 additions & 0 deletions src/aind_metadata_service/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,15 @@
SharePointClient,
SharepointSettings,
)
from aind_metadata_service.smartsheet.client import SmartsheetSettings

# TODO: Move client instantiation when the server starts instead of creating
# one for each request?
sharepoint_settings = SharepointSettings()
labtracks_settings = LabTracksSettings()

smartsheet_settings = SmartsheetSettings()

app = FastAPI()

app.add_middleware(
Expand Down
18 changes: 6 additions & 12 deletions src/aind_metadata_service/sharepoint/nsb2023/mapping.py
Original file line number Diff line number Diff line change
Expand Up @@ -2955,8 +2955,7 @@ def burr_hole_info(self, burr_hole_num: int) -> BurrHoleInfo:
alternating_current=self.aind_inj1_alternating_time,
inj_duration=self.aind_inj1_ionto_time,
inj_volume=self._map_burr_hole_volume(
vol=self.aind_inj1volperdepth,
dv=coordinate_depth
vol=self.aind_inj1volperdepth, dv=coordinate_depth
),
fiber_implant_depth=self.aind_fiber_implant1_dv,
)
Expand All @@ -2979,8 +2978,7 @@ def burr_hole_info(self, burr_hole_num: int) -> BurrHoleInfo:
alternating_current=self.aind_inj2_alternating_time,
inj_duration=self.aind_inj2_ionto_time,
inj_volume=self._map_burr_hole_volume(
vol=self.aind_inj2volperdepth,
dv=coordinate_depth
vol=self.aind_inj2volperdepth, dv=coordinate_depth
),
fiber_implant_depth=self.aind_fiber_implant2_dv,
)
Expand All @@ -3003,8 +3001,7 @@ def burr_hole_info(self, burr_hole_num: int) -> BurrHoleInfo:
alternating_current=self.aind_inj3_alternating_time,
inj_duration=self.aind_inj3_ionto_time,
inj_volume=self._map_burr_hole_volume(
vol=self.aind_inj3volperdepth,
dv=coordinate_depth
vol=self.aind_inj3volperdepth, dv=coordinate_depth
),
fiber_implant_depth=self.aind_fiber_implant3_d_x00,
)
Expand All @@ -3027,8 +3024,7 @@ def burr_hole_info(self, burr_hole_num: int) -> BurrHoleInfo:
alternating_current=self.aind_inj4_alternating_time,
inj_duration=self.aind_inj4_ionto_time,
inj_volume=self._map_burr_hole_volume(
vol=self.aind_inj4volperdepth,
dv=coordinate_depth
vol=self.aind_inj4volperdepth, dv=coordinate_depth
),
fiber_implant_depth=self.aind_fiber_implant4_d_x00,
)
Expand All @@ -3051,8 +3047,7 @@ def burr_hole_info(self, burr_hole_num: int) -> BurrHoleInfo:
alternating_current=self.aind_inj5_alternating_time,
inj_duration=self.aind_inj5_ionto_time,
inj_volume=self._map_burr_hole_volume(
vol=self.aind_inj5volperdepth,
dv=coordinate_depth
vol=self.aind_inj5volperdepth, dv=coordinate_depth
),
fiber_implant_depth=self.aind_fiber_implant5_d_x00,
)
Expand All @@ -3075,8 +3070,7 @@ def burr_hole_info(self, burr_hole_num: int) -> BurrHoleInfo:
alternating_current=self.aind_inj6_alternating_time,
inj_duration=self.aind_inj6_ionto_time,
inj_volume=self._map_burr_hole_volume(
vol=self.aind_inj6volperdepth,
dv=coordinate_depth
vol=self.aind_inj6volperdepth, dv=coordinate_depth
),
fiber_implant_depth=self.aind_fiber_implant6_d_x00,
)
Expand Down
1 change: 1 addition & 0 deletions src/aind_metadata_service/smartsheet/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""Package to retrieve information from Smartsheet"""
75 changes: 75 additions & 0 deletions src/aind_metadata_service/smartsheet/client.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
"""Module to instantiate a client to connect to Smartsheet and provide helpful
methods to retrieve data."""

import logging
from typing import Optional

from pydantic import BaseSettings, Extra, Field, SecretStr
from smartsheet import Smartsheet

from aind_metadata_service import __version__


class SmartsheetSettings(BaseSettings):
"""Configuration class. Mostly a wrapper around smartsheet.Smartsheet
class constructor arguments."""

access_token: SecretStr = Field(
..., description="API token can be created in Smartsheet UI"
)
sheet_id: int = Field(
...,
description=(
"Sheet ID to query. Can be found in Smartsheet under "
"File | Properties."
),
)
user_agent: Optional[str] = Field(
default=f"AIND_Metadata_Service/{__version__}",
description=(
"The user agent to use when making requests. "
"Helps identify requests coming from this app."
),
)
max_connections: int = Field(
default=8, description="Maximum connection pool size."
)

class Config:
"""Set env prefix and forbid extra fields."""

env_prefix = "SMARTSHEET_"
extra = Extra.forbid


class SmartSheetClient:
"""Main client to connect to a Smartsheet sheet. Requires an API token
and the sheet id."""

def __init__(self, smartsheet_settings: SmartsheetSettings):
"""
Class constructor
Parameters
----------
smartsheet_settings : SmartsheetSettings
"""
self.smartsheet_settings = smartsheet_settings
self.smartsheet_client = Smartsheet(
user_agent=self.smartsheet_settings.user_agent,
max_connections=self.smartsheet_settings.max_connections,
access_token=(
self.smartsheet_settings.access_token.get_secret_value()
),
)

async def get_sheet(self) -> dict:
"""Retrieve the sheet defined by the settings sheet_id."""
try:
smartsheet_response = self.smartsheet_client.Sheets.get_sheet(
self.smartsheet_settings.sheet_id
)
smartsheet_json = smartsheet_response.to_json()
return smartsheet_json
except Exception as e:
logging.error(repr(e))
raise Exception(e)
4 changes: 3 additions & 1 deletion tests/labtracks/test_response_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,9 @@ def test_map_housing(self):
housing3 = Housing.construct(cage_id="1234")
housing4 = Housing.construct(room_id="000", cage_id="1234")

subject_housing1 = self.rh._map_housing(room_id="-99999999999", cage_id=None)
subject_housing1 = self.rh._map_housing(
room_id="-99999999999", cage_id=None
)
subject_housing2 = self.rh._map_housing(room_id="000", cage_id=None)
subject_housing3 = self.rh._map_housing(room_id=None, cage_id="1234")
subject_housing4 = self.rh._map_housing(room_id="000", cage_id="1234")
Expand Down
Loading

0 comments on commit 6e507bd

Please sign in to comment.