Skip to content
This repository was archived by the owner on Sep 29, 2025. It is now read-only.

Commit 3247d93

Browse files
committed
feat(pems_data): factory composes services
1 parent 4f74d64 commit 3247d93

File tree

4 files changed

+65
-12
lines changed

4 files changed

+65
-12
lines changed
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
from pems_data.cache import Cache
2+
from pems_data.services.stations import StationsService
3+
from pems_data.sources.cache import CachingDataSource
4+
from pems_data.sources.s3 import S3DataSource
5+
6+
7+
class ServiceFactory:
8+
"""
9+
A factory class to create and configure various services.
10+
11+
Shared dependencies are created once during initialization.
12+
"""
13+
14+
def __init__(self):
15+
self.cache = Cache()
16+
self.s3_source = S3DataSource()
17+
self.caching_s3_source = CachingDataSource(data_source=self.s3_source, cache=self.cache)
18+
19+
def stations_service(self) -> StationsService:
20+
"""Creates a fully-configured `StationsService`."""
21+
return StationsService(data_source=self.caching_s3_source)

tests/pytest/pems_data/conftest.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,16 @@
55
@pytest.fixture
66
def df() -> pd.DataFrame:
77
return pd.DataFrame({"col1": [1, 2, 3], "col2": ["a", "b", "c"]})
8+
9+
10+
@pytest.fixture(autouse=True)
11+
def mock_s3(mocker):
12+
s3 = mocker.patch("boto3.client").return_value
13+
s3.list_objects.return_value = {
14+
"Contents": [
15+
{"Key": "path1/file2.json"},
16+
{"Key": "path2/file1.json"},
17+
{"Key": "path1/file1.json"},
18+
]
19+
}
20+
return s3

tests/pytest/pems_data/sources/test_s3.py

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,18 +11,6 @@ class TestS3DataSource:
1111
def data_source(self) -> S3DataSource:
1212
return S3DataSource()
1313

14-
@pytest.fixture(autouse=True)
15-
def mock_s3(self, mocker):
16-
s3 = mocker.patch("boto3.client").return_value
17-
s3.list_objects.return_value = {
18-
"Contents": [
19-
{"Key": "path1/file2.json"},
20-
{"Key": "path2/file1.json"},
21-
{"Key": "path1/file1.json"},
22-
]
23-
}
24-
return s3
25-
2614
@pytest.fixture(autouse=True)
2715
def mock_read_parquet(self, mocker):
2816
return mocker.patch("pandas.read_parquet")
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import pytest
2+
3+
from pems_data import ServiceFactory
4+
from pems_data.cache import Cache
5+
from pems_data.services.stations import StationsService
6+
from pems_data.sources.cache import CachingDataSource
7+
from pems_data.sources.s3 import S3DataSource
8+
9+
10+
class TestServiceFactory:
11+
12+
@pytest.fixture
13+
def factory(self):
14+
return ServiceFactory()
15+
16+
def test_init_cache(self, factory: ServiceFactory):
17+
assert isinstance(factory.cache, Cache)
18+
19+
def test_init_s3_source(self, factory: ServiceFactory):
20+
assert isinstance(factory.s3_source, S3DataSource)
21+
22+
def test_init_caching_s3_source(self, factory: ServiceFactory):
23+
assert isinstance(factory.caching_s3_source, CachingDataSource)
24+
assert isinstance(factory.caching_s3_source.data_source, S3DataSource)
25+
assert isinstance(factory.caching_s3_source.cache, Cache)
26+
27+
def test_stations_service(self, factory: ServiceFactory):
28+
service = factory.stations_service()
29+
30+
assert isinstance(service, StationsService)
31+
assert service.data_source == factory.caching_s3_source

0 commit comments

Comments
 (0)