Skip to content

Commit 2cc8ce6

Browse files
authored
Issue #39: Update pre-commit to run type checking; fix some type errors (#45)
1 parent 90331d4 commit 2cc8ce6

File tree

9 files changed

+73
-42
lines changed

9 files changed

+73
-42
lines changed

.pre-commit-config.yaml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,12 @@ repos:
2323
hooks:
2424
- id: cspell
2525
exclude: cspell.json
26+
- repo: local
27+
hooks:
28+
- id: ty-check
29+
name: ty-check
30+
entry: uv run ty check --error-on-warning
31+
language: system
32+
types: [python]
33+
pass_filenames: false
34+
always_run: true

bases/lif/identity_mapper_restapi/core.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
from typing import List
33
from uuid import uuid4
44

5-
from fastapi import FastAPI, Request, Response, status
5+
from fastapi import FastAPI, Request, status
66
from fastapi.responses import JSONResponse
77
from sqlalchemy.orm import sessionmaker, Session
88

@@ -49,8 +49,10 @@ def shutdown():
4949
status_code=status.HTTP_200_OK,
5050
response_model=List[IdentityMapping],
5151
)
52-
async def do_save_mappings(org_id: str, person_id: str, mappings: List[IdentityMapping]) -> Response:
52+
async def do_save_mappings(org_id: str, person_id: str, mappings: List[IdentityMapping]) -> List[IdentityMapping]:
5353
logger.info(f"CALL RECEIVED TO (POST) /organizations/{org_id}/persons/{person_id}/mappings API")
54+
if service is None:
55+
raise RuntimeError("Service is not initialized")
5456
mappings_created: List[IdentityMapping] = await service.save_mappings(org_id, person_id, mappings)
5557
logger.info(f"Mappings saved successfully for person {person_id} in organization {org_id}")
5658
return mappings_created
@@ -63,6 +65,8 @@ async def do_save_mappings(org_id: str, person_id: str, mappings: List[IdentityM
6365
)
6466
async def do_get_mappings(org_id: str, person_id: str) -> List[IdentityMapping]:
6567
logger.info(f"CALL RECEIVED TO (GET) /organizations/{org_id}/persons/{person_id}/mappings API")
68+
if service is None:
69+
raise RuntimeError("Service is not initialized")
6670
mappings = await service.get_mappings(org_id, person_id)
6771
logger.info(f"Mappings retrieved successfully for person {person_id} in organization {org_id}")
6872
return mappings
@@ -71,6 +75,8 @@ async def do_get_mappings(org_id: str, person_id: str) -> List[IdentityMapping]:
7175
@app.delete("/organizations/{org_id}/persons/{person_id}/mappings/{mapping_id}", status_code=status.HTTP_204_NO_CONTENT)
7276
async def do_delete_mapping(org_id: str, person_id: str, mapping_id: str):
7377
logger.info(f"CALL RECEIVED TO (DELETE) /organizations/{org_id}/persons/{person_id}/mappings/{mapping_id} API")
78+
if service is None:
79+
raise RuntimeError("Service is not initialized")
7480
await service.delete_mapping(org_id, person_id, mapping_id)
7581
logger.info(f"Mapping {mapping_id} deleted successfully for person {person_id} in organization {org_id}")
7682

components/lif/auth/core.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import os
2-
from datetime import datetime, timedelta
2+
from datetime import datetime, timedelta, timezone
33

44
import jwt
55
from fastapi import HTTPException, Security
@@ -19,15 +19,15 @@
1919
def create_access_token(data: dict) -> str:
2020
"""Create a JWT access token with expiration."""
2121
to_encode = data.copy()
22-
expire = datetime.utcnow() + timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
22+
expire = datetime.now(timezone.utc) + timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
2323
to_encode.update({"exp": expire})
2424
return jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
2525

2626

2727
def create_refresh_token(data: dict) -> str:
2828
"""Create a JWT refresh token with expiration."""
2929
to_encode = data.copy()
30-
expire = datetime.utcnow() + timedelta(days=REFRESH_TOKEN_EXPIRE_DAYS)
30+
expire = datetime.now(timezone.utc) + timedelta(days=REFRESH_TOKEN_EXPIRE_DAYS)
3131
to_encode.update({"exp": expire})
3232
return jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
3333

components/lif/datatypes/core.py

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -78,12 +78,6 @@ class LIFQueryFilter(RootModel[LIFQueryPersonFilter]):
7878

7979
root: LIFQueryPersonFilter
8080

81-
def __iter__(self):
82-
return iter(self.root)
83-
84-
def __getitem__(self, item):
85-
return self.root[item]
86-
8781

8882
class LIFQuery(BaseModel):
8983
"""
@@ -112,10 +106,12 @@ class LIFQueryStatusResponse(BaseModel):
112106
Attributes:
113107
query_id (str): Query ID for the query.
114108
status (str): Status of the query (e.g., 'PENDING').
109+
error_message (str | None): Error message if the query failed.
115110
"""
116111

117112
query_id: str = Field(..., description="Query ID for the query")
118113
status: str = Field(..., description="Status of the query (e.g., 'PENDING', 'COMPLETED)")
114+
error_message: str | None = Field(None, description="Error message if the query failed")
119115

120116

121117
class LIFUpdatePersonPayload(BaseModel):

components/lif/identity_mapper_storage_sql/model.py

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from uuid import uuid4
22

3-
from sqlalchemy import Column, String, UniqueConstraint
3+
from sqlalchemy import String, UniqueConstraint
4+
from sqlalchemy.orm import Mapped, mapped_column
45
from lif.identity_mapper_storage_sql.db import Base
56
from lif.datatypes import IdentityMapping
67

@@ -10,12 +11,12 @@ class IdentityMappingModel(Base):
1011

1112
__tablename__ = "identity_mappings"
1213

13-
mapping_id: Column[String] = Column(String(36), primary_key=True, index=True, default=lambda: str(uuid4()))
14-
lif_organization_id: Column[String] = Column(String(255), index=True, nullable=False)
15-
lif_organization_person_id: Column[String] = Column(String(255), index=True, nullable=False)
16-
target_system_id: Column[String] = Column(String(255), index=True, nullable=False)
17-
target_system_person_id_type: Column[String] = Column(String(100), index=True, nullable=False)
18-
target_system_person_id: Column[String] = Column(String(255), index=True, nullable=False)
14+
mapping_id: Mapped[str] = mapped_column(String(36), primary_key=True, index=True, default=lambda: str(uuid4()))
15+
lif_organization_id: Mapped[str] = mapped_column(String(255), index=True, nullable=False)
16+
lif_organization_person_id: Mapped[str] = mapped_column(String(255), index=True, nullable=False)
17+
target_system_id: Mapped[str] = mapped_column(String(255), index=True, nullable=False)
18+
target_system_person_id_type: Mapped[str] = mapped_column(String(100), index=True, nullable=False)
19+
target_system_person_id: Mapped[str] = mapped_column(String(255), index=True, nullable=False)
1920
__table_args__ = (
2021
UniqueConstraint(
2122
"lif_organization_id",

components/lif/query_cache_service/core.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,7 @@ async def add(lif_record: LIFRecord) -> LIFRecord:
275275
result = await collection.insert_one(lif_record.model_dump())
276276
if result.inserted_id:
277277
added_record = await collection.find_one({"_id": result.inserted_id})
278-
return LIFRecord(**added_record)
278+
return LIFRecord(**added_record) # type: ignore
279279
raise ResourceNotFoundException("Failed to add record, no inserted ID returned.")
280280
except Exception as e:
281281
logger.exception("Add Exception: %s", e)

components/lif/query_planner_service/core.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ async def run_query(self, query: LIFQuery, first_run: bool) -> List[LIFRecord] |
111111

112112
orchestrator_job_request: OrchestratorJobRequest = OrchestratorJobRequest(
113113
lif_query_plan=lif_query_plan,
114-
async_=True, # Run the orchestration asynchronously
114+
async_=True, # ty: ignore[unknown-argument]
115115
)
116116

117117
try:

pyproject.toml

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,8 +116,8 @@ line-length = 120
116116
required-version = "~=0.11.13"
117117

118118
[tool.ruff.format]
119-
# use '\n' line endings for all files (*nix/mac default)
120119
docstring-code-format = true
120+
# use '\n' line endings for all files (*nix/mac default)
121121
line-ending = "lf"
122122
skip-magic-trailing-comma = true
123123

@@ -130,3 +130,22 @@ ignore = [
130130
"TD002",
131131
"TD003"
132132
]
133+
134+
[tool.ty.src]
135+
exclude = [
136+
"scripts/",
137+
"test/",
138+
"bases/lif/advisor_restapi/",
139+
"bases/lif/api_graphql/",
140+
"bases/lif/mdr_restapi/",
141+
"bases/lif/semantic_search_mcp_server",
142+
"components/lif/langchain_agent/",
143+
"components/lif/mdr_dto/",
144+
"components/lif/mdr_services/",
145+
"components/lif/mdr_utils/",
146+
"components/lif/openapi_to_graphql/",
147+
"components/lif/orchestrator_clients/",
148+
"components/lif/semantic_search_service/",
149+
"development/"
150+
]
151+

uv.lock

Lines changed: 21 additions & 21 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)