Skip to content

Commit

Permalink
Merge branch 'main' into feat-initial-waterlog
Browse files Browse the repository at this point in the history
  • Loading branch information
patricklatimer committed Jun 25, 2024
2 parents e39842d + 655ab26 commit 9eddaa0
Show file tree
Hide file tree
Showing 21 changed files with 2,438 additions and 132 deletions.
1 change: 1 addition & 0 deletions .flake8
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ exclude =
__pycache__,
build
max-complexity = 10
max-line-length = 88
52 changes: 0 additions & 52 deletions .github/workflows/init.yml

This file was deleted.

14 changes: 5 additions & 9 deletions .github/workflows/tag_and_publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@ on:
push:
branches:
- main
# Remove line 61 to enable automated semantic version bumps.
# Change line 67 from "if: false" to "if: true" to enable PyPI publishing.
# Requires that svc-aindscicomp be added as an admin to repo.

jobs:
update_badges:
runs-on: ubuntu-latest
Expand All @@ -16,10 +14,10 @@ jobs:
ref: ${{ env.DEFAULT_BRANCH }}
fetch-depth: 0
token: ${{ secrets.SERVICE_TOKEN }}
- name: Set up Python 3.8
- name: Set up Python 3.10
uses: actions/setup-python@v3
with:
python-version: 3.8
python-version: '3.10'
- name: Install dependencies
run: |
python -m pip install -e .[dev] --no-cache-dir
Expand Down Expand Up @@ -62,22 +60,20 @@ jobs:
add: '["README.md"]'
tag:
needs: update_badges
if: ${{github.event.repository.name == 'aind-library-template'}}
uses: AllenNeuralDynamics/aind-github-actions/.github/workflows/tag.yml@main
secrets:
SERVICE_TOKEN: ${{ secrets.SERVICE_TOKEN }}
publish:
needs: tag
if: false
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Pull latest changes
run: git pull origin main
- name: Set up Python 3.8
- name: Set up Python 3.10
uses: actions/setup-python@v2
with:
python-version: 3.8
python-version: '3.10'
- name: Install dependencies
run: |
pip install --upgrade setuptools wheel twine build
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test_and_lint.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.8', '3.9', '3.10' ]
python-version: [ '3.10', '3.11', '3.12' ]
steps:
- uses: actions/checkout@v3
- name: Set up Python ${{ matrix.python-version }}
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
[![semantic-release: angular](https://img.shields.io/badge/semantic--release-angular-e10079?logo=semantic-release)](https://github.com/semantic-release/semantic-release)
![Interrogate](https://img.shields.io/badge/interrogate-100.0%25-brightgreen)
![Coverage](https://img.shields.io/badge/coverage-100%25-brightgreen?logo=codecov)
![Python](https://img.shields.io/badge/python->=3.7-blue?logo=python)
![Python](https://img.shields.io/badge/python->=3.10-blue?logo=python)

This library is for pythonic access to data stored in the AIND SLIMS deployment. It is not meant to be a generic way to interact with SLIMS, but rather specific to how data is modeled in AIND's SLIMS instance.

Expand Down
7 changes: 5 additions & 2 deletions doc_template/source/conf.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
"""Configuration file for the Sphinx documentation builder."""

#
# For the full list of built-in configuration values, see the documentation:
# https://www.sphinx-doc.org/en/master/usage/configuration.html

from datetime import date

# -- Path Setup --------------------------------------------------------------
from os.path import dirname, abspath
from os.path import abspath, dirname
from pathlib import Path
from datetime import date

from aind_slims_api import __version__ as package_version

INSTITUTE_NAME = "Allen Institute for Neural Dynamics"
Expand Down
8 changes: 4 additions & 4 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ build-backend = "setuptools.build_meta"
name = "aind-slims-api"
description = "Generated from aind-library-template"
license = {text = "MIT"}
requires-python = ">=3.7"
requires-python = ">=3.10"
authors = [
{name = "Allen Institute for Neural Dynamics"}
]
Expand Down Expand Up @@ -40,8 +40,8 @@ where = ["src"]
version = {attr = "aind_slims_api.__version__"}

[tool.black]
line-length = 79
target_version = ['py36']
line-length = 88
target_version = ['py310']
exclude = '''
(
Expand Down Expand Up @@ -74,7 +74,7 @@ exclude_lines = [
fail_under = 100

[tool.isort]
line_length = 79
line_length = 88
profile = "black"

[tool.interrogate]
Expand Down
6 changes: 3 additions & 3 deletions src/aind_slims_api/__init__.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
"""Init package"""

__version__ = "0.0.0"
__version__ = "0.0.2"

from .configuration import AindSlimsApiSettings
from aind_slims_api.configuration import AindSlimsApiSettings

config = AindSlimsApiSettings()

from .core import SlimsClient # noqa
from aind_slims_api.core import SlimsClient # noqa
16 changes: 8 additions & 8 deletions src/aind_slims_api/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ class MyModel(SlimsBaseModel):
"""

pk: int = None
json_entity: dict = None
_slims_table: SLIMSTABLES

@field_validator("*", mode="before")
Expand Down Expand Up @@ -137,7 +138,7 @@ class SlimsClient:
def __init__(self, url=None, username=None, password=None):
"""Create object and try to connect to database"""
self.url = url or config.slims_url
self.db: Slims = None
self.db: Optional[Slims] = None

self.connect(
self.url,
Expand Down Expand Up @@ -191,9 +192,10 @@ def fetch(
start=start,
end=end,
)
except _SlimsApiException:
raise
return None # TODO: Raise or return empty list?
except _SlimsApiException as e:
# TODO: Add better error handling
# Let's just raise error for the time being
raise e

return records

Expand All @@ -220,7 +222,7 @@ def update(self, table: SLIMSTABLES, pk: int, data: dict):
"""Update a SLIMS record"""
record = self.db.fetch_by_pk(table, pk)
if record is None:
raise ValueError('No data in SLIMS "{table}" table for pk "{pk}"')
raise ValueError(f'No data in SLIMS "{table}" table for pk "{pk}"')
new_record = record.update(data)
logger.info(f"SLIMS Update: {table}/{pk}")
return new_record
Expand All @@ -231,9 +233,7 @@ def rest_link(self, table: SLIMSTABLES, **kwargs):
queries = [f"?{k}={v}" for k, v in kwargs.items()]
return base_url + "".join(queries)

def add_model(
self, model: SlimsBaseModel, *args, **kwargs
) -> SlimsBaseModel:
def add_model(self, model: SlimsBaseModel, *args, **kwargs) -> SlimsBaseModel:
"""Given a SlimsBaseModel object, add it to SLIMS
Args
model (SlimsBaseModel): object to add
Expand Down
16 changes: 8 additions & 8 deletions src/aind_slims_api/mouse.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
import logging
from typing import Annotated

from pydantic import Field, ValidationError
from pydantic import Field, BeforeValidator, ValidationError

from .core import SlimsBaseModel, SlimsClient, UnitSpec, SLIMSTABLES
from aind_slims_api.core import SlimsBaseModel, SlimsClient, UnitSpec, SLIMSTABLES

logger = logging.getLogger()

Expand All @@ -16,10 +16,10 @@ class SlimsMouseContent(SlimsBaseModel):
baseline_weight_g: Annotated[float | None, UnitSpec("g")] = Field(
..., alias="cntn_cf_baselineWeight"
)
point_of_contact: str | None = Field(
..., alias="cntn_cf_scientificPointOfContact"
point_of_contact: str | None = Field(..., alias="cntn_cf_scientificPointOfContact")
water_restricted: Annotated[bool, BeforeValidator(lambda x: x or False)] = Field(
..., alias="cntn_cf_waterRestricted"
)
water_restricted: bool = Field(..., alias="cntn_cf_waterRestricted")
barcode: str = Field(..., alias="cntn_barCode")
pk: int = Field(..., alias="cntn_pk")

Expand All @@ -45,7 +45,7 @@ class SlimsMouseContent(SlimsBaseModel):
def fetch_mouse_content(
client: SlimsClient,
mouse_name: str,
) -> SlimsMouseContent:
) -> SlimsMouseContent | dict | None:
"""Fetches mouse information for a mouse with labtracks id {mouse_name}"""
mice = client.fetch(
"Content",
Expand All @@ -58,7 +58,7 @@ def fetch_mouse_content(
if len(mice) > 1:
logger.warning(
f"Warning, Multiple mice in SLIMS with barcode "
f"{mouse_name}, using pk={mouse_details.cntn_pk}"
f"{mouse_name}, using pk={mouse_details.cntn_pk.value}"
)
else:
logger.warning("Warning, Mouse not in SLIMS")
Expand All @@ -68,6 +68,6 @@ def fetch_mouse_content(
mouse = SlimsMouseContent.model_validate(mouse_details)
except ValidationError as e:
logger.error(f"SLIMS data validation failed, {repr(e)}")
return
return mouse_details.json_entity

return mouse
20 changes: 20 additions & 0 deletions src/aind_slims_api/unit.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
"""Contains a model for a unit"""

import logging
from typing import Optional

from pydantic import Field

from aind_slims_api.core import SlimsBaseModel

logger = logging.getLogger()


class SlimsUnit(SlimsBaseModel):
"""Model for unit information in SLIMS"""

name: str = Field(..., alias="unit_name")
abbreviation: Optional[str] = Field("", alias="unit_abbreviation")
pk: int = Field(..., alias="unit_pk")

_slims_table: str = "Unit"
13 changes: 7 additions & 6 deletions src/aind_slims_api/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

from pydantic import Field, ValidationError

from .core import SlimsBaseModel, SlimsClient
from aind_slims_api.core import SlimsBaseModel, SlimsClient

logger = logging.getLogger()

Expand All @@ -27,7 +27,7 @@ class SlimsUser(SlimsBaseModel):
def fetch_user(
client: SlimsClient,
username: str,
) -> SlimsUser:
) -> SlimsUser | dict | None:
"""Fetches user information for a user with username {username}"""
users = client.fetch(
"User",
Expand All @@ -39,16 +39,17 @@ def fetch_user(
if len(users) > 1:
logger.warning(
f"Warning, Multiple users in SLIMS with "
f"username {users}, using pk={user_details.pk}"
f"username {username}, "
f"using pk={user_details.pk()}"
)
else:
logger.warning("Warning, User not in SLIMS")
return

try:
mouse = SlimsUser.model_validate(user_details)
user = SlimsUser.model_validate(user_details)
except ValidationError as e:
logger.error(f"SLIMS data validation failed, {repr(e)}")
return
return user_details.json_entity

return mouse
return user
Loading

0 comments on commit 9eddaa0

Please sign in to comment.