Skip to content

Commit 5decb06

Browse files
Remove s3_client from PredictitAPI attribute and instead supply as parameter in store_to_s3 method. Update lambdas and testing.
1 parent e085648 commit 5decb06

File tree

4 files changed

+15
-21
lines changed

4 files changed

+15
-21
lines changed

lambda_fetch/lambda_function.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ def lambda_function(filename: str) -> None:
2626
bucket = os.getenv("S3_BUCKET")
2727
if not bucket:
2828
raise ValueError("S3_BUCKET environment variable is not set")
29-
predictit.store_to_s3(data, bucket=bucket, filename=filename)
29+
predictit.store_to_s3(s3_client, data, bucket=bucket, filename=filename)
3030
logging.info("Successfully stored data to S3")
3131

3232

src/api.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
class PredictitAPI:
1515
def __init__(self, base_url="https://www.predictit.org/api/marketdata"):
1616
self.base_url = base_url
17-
self.s3_client = boto3.client("s3")
1817

1918
def poll_market_data(self, market_id: Optional[str] = None) -> Optional[dict]:
2019
"""
@@ -42,14 +41,14 @@ def poll_market_data(self, market_id: Optional[str] = None) -> Optional[dict]:
4241
logging.error(f"An error occurred: {e}")
4342

4443
def store_to_s3(
45-
self, data: dict, bucket: Optional[str] = None, filename: Optional[str] = None
44+
self, s3_client: boto3.client, data: dict, bucket: Optional[str] = None, filename: Optional[str] = None
4645
):
4746
if not filename:
4847
timestamp = datetime.datetime.utcnow().strftime("%Y-%m-%dT%H-%M-%S")
4948
filename = f"market_data_{timestamp}.json"
5049
key = f"predictit/stage/{filename}"
5150
try:
52-
self.s3_client.put_object(
51+
s3_client.put_object(
5352
Bucket=bucket,
5453
Key=key,
5554
Body=json.dumps(data),

tests/test_api.py

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -41,28 +41,23 @@ def test_poll_market_http_error(mock_get, caplog):
4141
assert "HTTP error occurred" in caplog.text
4242

4343

44-
@patch("src.api.boto3.client")
45-
def test_store_to_s3_success(mock_boto_client):
44+
def test_store_to_s3_success():
4645
mock_s3 = MagicMock()
47-
mock_boto_client.return_value = mock_s3
4846
test_bucket = "test-bucket"
4947
test_filename = "test_file.json"
5048
test_data = {"markets": []}
5149
predictit = PredictitAPI()
5250
expected_key = f"predictit/stage/{test_filename}"
53-
predictit.store_to_s3(test_data, bucket=test_bucket, filename=test_filename)
51+
predictit.store_to_s3(mock_s3, test_data, bucket=test_bucket, filename=test_filename)
5452
mock_s3.put_object.assert_called_once_with(
5553
Bucket=test_bucket,
5654
Key=expected_key,
5755
Body='{"markets": []}',
5856
ContentType="application/json",
5957
)
6058

61-
62-
@patch("src.api.boto3.client")
63-
def test_store_to_s3_failure(mock_boto_client):
59+
def test_store_to_s3_failure():
6460
mock_s3 = MagicMock()
65-
mock_boto_client.return_value = mock_s3
6661
mock_s3.put_object.side_effect = ClientError(
6762
error_response={"Error": {"Code": "AccessDenied", "Message": "Access Denied"}},
6863
operation_name="PutObject",
@@ -72,7 +67,7 @@ def test_store_to_s3_failure(mock_boto_client):
7267
test_filename = "test_file.json"
7368
predictit = PredictitAPI()
7469
with pytest.raises(ClientError):
75-
predictit.store_to_s3(test_data, bucket=test_bucket, filename=test_filename)
70+
predictit.store_to_s3(mock_s3, test_data, bucket=test_bucket, filename=test_filename)
7671

7772
mock_s3.put_object.assert_called_once_with(
7873
Bucket=test_bucket,

tests/test_lambda_fetch.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
from lambda_fetch.lambda_function import lambda_function, lambda_handler
44
from src.api import PredictitAPI
5-
from unittest.mock import patch
5+
from unittest.mock import patch, MagicMock
66

77

88
@patch("lambda_fetch.lambda_function.lambda_function")
@@ -24,17 +24,17 @@ def test_lambda_handler_no_filename(mock_lambda_func):
2424

2525

2626
@patch("lambda_fetch.lambda_function.os.getenv")
27-
@patch.object(PredictitAPI, "store_to_s3")
28-
@patch.object(PredictitAPI, "poll_market_data")
29-
def test_lambda_function_success(mock_poll, mock_store, mock_getenv):
30-
mock_poll.return_value = {"markets": []}
27+
@patch("lambda_fetch.lambda_function.predictit")
28+
@patch("lambda_fetch.lambda_function.s3_client")
29+
def test_lambda_function_success(mock_s3_client, mock_predictit, mock_getenv):
3130
mock_getenv.return_value = "fake-bucket"
31+
mock_predictit.poll_market_data.return_value = {"markets": []}
3232

3333
lambda_function("test.json")
3434

35-
mock_poll.assert_called_once()
36-
mock_store.assert_called_once_with(
37-
{"markets": []}, bucket="fake-bucket", filename="test.json"
35+
mock_predictit.poll_market_data.assert_called_once()
36+
mock_predictit.store_to_s3.assert_called_once_with(
37+
mock_s3_client, {"markets": []}, bucket="fake-bucket", filename="test.json"
3838
)
3939

4040

0 commit comments

Comments
 (0)