Skip to content

Commit 562955d

Browse files
hrodmnvincentsarago
andcommitted
feat: update ingestor-api runtime dependencies (#125)
--------- Co-authored-by: Vincent Sarago <[email protected]>
1 parent b77911d commit 562955d

File tree

6 files changed

+29
-28
lines changed

6 files changed

+29
-28
lines changed

lib/ingestor-api/runtime/requirements.txt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,8 @@ cachetools==5.3.0
33
fastapi>=0.75.1
44
orjson>=3.6.8
55
psycopg[binary,pool]>=3.0.15
6-
pydantic_ssm_settings>=0.2.0,<1.0
6+
pydantic_ssm_settings>=1.0,<2.0
77
pydantic>=1.9.0
88
pypgstac==0.8.5
99
requests>=2.27.1
10-
# Waiting for https://github.com/stac-utils/stac-pydantic/pull/116
11-
stac-pydantic @ git+https://github.com/alukach/stac-pydantic.git@patch-1
10+
stac-pydantic>=3.0,<4.0

lib/ingestor-api/runtime/src/config.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,11 @@
22
from getpass import getuser
33
from typing import Optional
44

5-
from pydantic import AnyHttpUrl, BaseSettings, Field, constr
6-
from pydantic_ssm_settings import AwsSsmSourceConfig
5+
from pydantic import AnyHttpUrl, Field, constr
6+
from pydantic_settings import BaseSettings
7+
from pydantic_ssm_settings.settings import SsmBaseSettings
78

8-
AwsArn = constr(regex=r"^arn:aws:iam::\d{12}:role/.+")
9+
AwsArn = constr(pattern=r"^arn:aws:iam::\d{12}:role/.+")
910

1011

1112
class Settings(BaseSettings):
@@ -27,8 +28,8 @@ class Settings(BaseSettings):
2728
description="Path from where to serve this URL.", default=False
2829
)
2930

30-
class Config(AwsSsmSourceConfig):
31-
env_file = ".env"
31+
class Config(SsmBaseSettings):
32+
env_file: str = ".env"
3233

3334
@classmethod
3435
def from_ssm(cls, stack: str):

lib/ingestor-api/runtime/src/schemas.py

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
PositiveInt,
1515
dataclasses,
1616
error_wrappers,
17-
validator,
17+
field_validator,
1818
)
1919
from stac_pydantic import Collection, Item, shared
2020

@@ -25,7 +25,7 @@
2525

2626

2727
class AccessibleAsset(shared.Asset):
28-
@validator("href")
28+
@field_validator("href")
2929
def is_accessible(cls, href):
3030
url = urlparse(href)
3131

@@ -44,7 +44,7 @@ def is_accessible(cls, href):
4444
class AccessibleItem(Item):
4545
assets: Dict[str, AccessibleAsset]
4646

47-
@validator("collection")
47+
@field_validator("collection")
4848
def exists(cls, collection):
4949
validators.collection_exists(collection_id=collection)
5050
return collection
@@ -66,15 +66,14 @@ class Status(str, enum.Enum):
6666
class Ingestion(BaseModel):
6767
id: str
6868
status: Status
69-
message: Optional[str]
69+
message: Optional[str] = None
7070
created_by: str
71-
created_at: datetime = None
72-
updated_at: datetime = None
71+
created_at: datetime = datetime.now()
72+
updated_at: datetime = datetime.now()
7373

7474
item: Union[Item, Json[Item]]
7575

76-
@validator("created_at", pre=True, always=True, allow_reuse=True)
77-
@validator("updated_at", pre=True, always=True, allow_reuse=True)
76+
@field_validator("created_at", "updated_at", mode="before")
7877
def set_ts_now(cls, v):
7978
return v or datetime.now()
8079

@@ -94,10 +93,10 @@ def save(self, db: "services.Database"):
9493
def dynamodb_dict(self):
9594
"""DynamoDB-friendly serialization"""
9695
# convert to dictionary
97-
output = self.dict(exclude={"item"})
96+
output = self.model_dump(exclude={"item"})
9897

9998
# add STAC item as string
100-
output["item"] = self.item.json()
99+
output["item"] = self.item.model_dump_json()
101100

102101
# make JSON-friendly (will be able to do with Pydantic V2, https://github.com/pydantic/pydantic/issues/1409#issuecomment-1423995424)
103102
return jsonable_encoder(output)
@@ -106,7 +105,7 @@ def dynamodb_dict(self):
106105
@dataclasses.dataclass
107106
class ListIngestionRequest:
108107
status: Status = Status.queued
109-
limit: PositiveInt = None
108+
limit: Optional[PositiveInt] = None
110109
next: Optional[str] = None
111110

112111
def __post_init_post_parse__(self) -> None:
@@ -133,7 +132,7 @@ class ListIngestionResponse(BaseModel):
133132
items: List[Ingestion]
134133
next: Optional[str]
135134

136-
@validator("next", pre=True)
135+
@field_validator("next", mode="before")
137136
def b64_encode_next(cls, next):
138137
"""
139138
Base64 encode next parameter for easier transportability
@@ -144,5 +143,5 @@ def b64_encode_next(cls, next):
144143

145144

146145
class UpdateIngestionRequest(BaseModel):
147-
status: Status = None
148-
message: str = None
146+
status: Optional[Status] = None
147+
message: Optional[str] = None

lib/ingestor-api/runtime/tests/conftest.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ def test_environ():
2121
os.environ["STAC_URL"] = "https://test-stac.url"
2222
os.environ["DATA_ACCESS_ROLE"] = "arn:aws:iam::123456789012:role/test-role"
2323
os.environ["DB_SECRET_ARN"] = "testing"
24+
os.environ["ROOT_PATH"] = "testing"
2425

2526

2627
@pytest.fixture
@@ -259,13 +260,13 @@ def stac_collection(example_stac_collection):
259260
return schemas.StacCollection(**example_stac_collection)
260261

261262

262-
@pytest.fixture
263+
@pytest.fixture(scope="function")
263264
def example_ingestion(example_stac_item):
264265
from src import schemas
265266

266267
return schemas.Ingestion(
267268
id=example_stac_item["id"],
268269
created_by="test-user",
269270
status=schemas.Status.queued,
270-
item=Item.parse_obj(example_stac_item),
271+
item=Item.model_validate(example_stac_item),
271272
)

lib/ingestor-api/runtime/tests/test_registration.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,9 @@ def test_create(self, client_authenticated, collection_exists, asset_exists):
7474
)
7575

7676
assert response.status_code == 201
77-
assert collection_exists.called_once_with(self.example_ingestion.item.collection)
77+
collection_exists.assert_called_once_with(
78+
collection_id=self.example_ingestion.item.collection
79+
)
7880

7981
stored_data = self.db.fetch_many(status="queued")["items"]
8082
assert len(stored_data) == 1
@@ -87,7 +89,6 @@ def test_validates_missing_collection(
8789
ingestion_endpoint,
8890
json=jsonable_encoder(self.example_ingestion.item),
8991
)
90-
9192
collection_missing.assert_called_once_with(
9293
collection_id=self.example_ingestion.item.collection
9394
)
@@ -140,7 +141,7 @@ def setup(
140141
def populate_table(self, count=100) -> List["schemas.Ingestion"]:
141142
example_ingestions = []
142143
for i in range(count):
143-
ingestion = self.example_ingestion.copy()
144+
ingestion = self.example_ingestion.model_copy()
144145
ingestion.id = str(i)
145146
ingestion.created_at = ingestion.created_at + timedelta(hours=i)
146147
self.mock_table.put_item(Item=ingestion.dynamodb_dict())

tox.ini

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ passenv = AWS_DEFAULT_REGION
99
commands =
1010
pip install -r ./lib/ingestor-api/runtime/requirements.txt
1111
pip install -r ./lib/ingestor-api/runtime/dev_requirements.txt
12-
python -m pytest -s
12+
python -m pytest -s -vv
1313

1414
[pytest]
1515
addopts = -ra -q

0 commit comments

Comments
 (0)