From a2c6e688de0e9a37e1b935747b22005a8f321d40 Mon Sep 17 00:00:00 2001 From: philsv Date: Thu, 17 Oct 2024 01:03:08 +0200 Subject: [PATCH] Refactor API class and add type hints --- myeia/api.py | 7 +++++-- requirements.txt | 6 +++--- setup.py | 2 +- tests/test_api.py | 24 ++++++++++++++++-------- 4 files changed, 25 insertions(+), 14 deletions(-) diff --git a/myeia/api.py b/myeia/api.py index de59a59..6e4a9b6 100644 --- a/myeia/api.py +++ b/myeia/api.py @@ -17,6 +17,7 @@ load_dotenv(verbose=True) + class API: """ Python Wrapper for U.S. Energy Information Administration (EIA) APIv2. @@ -32,9 +33,11 @@ def __init__( if token: self.token = token elif os.getenv("EIA_TOKEN"): - self.token = os.getenv("EIA_TOKEN") + self.token = str(os.getenv("EIA_TOKEN")) else: - raise ValueError('EIA_TOKEN is not set. Please set it in your .env file or environment variables.') + raise ValueError( + "EIA_TOKEN is not set. Please set it in your .env file or environment variables." + ) self.base_url = "https://api.eia.gov/v2/" self.header = {"Accept": "*/*"} diff --git a/requirements.txt b/requirements.txt index a7bcc74..ae29bcd 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,8 +1,8 @@ backoff>=2.2.1 +numpy>=1.21.4 pandas>=1.5.3 -pytest>=7.2.1 pytest-mock>=3.14.0 +pytest>=7.2.1 python-dateutil>=2.9.0 python-dotenv>=0.19.0 -requests>=2.32.0 -numpy>=1.21.4 \ No newline at end of file +requests>=2.32.0 \ No newline at end of file diff --git a/setup.py b/setup.py index f846176..53e8a5f 100644 --- a/setup.py +++ b/setup.py @@ -1,4 +1,4 @@ -import setuptools +import setuptools # type: ignore from myeia.version import __version__ diff --git a/tests/test_api.py b/tests/test_api.py index c2967b4..621160a 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -9,8 +9,13 @@ eia = API() -def mock_requests_get(mocker, file_path): + +def mock_requests_get( + mocker, + file_path: str, +) -> requests.Response: """Helper function to mock requests.get and manage test data files.""" + class MockGetResponse: def status_code(self): return 200 @@ -31,10 +36,10 @@ def raise_for_status(self): # register spy on requests.get spy_get = mocker.spy(requests, "get") - return spy_get -def save_mock_data(file_path, json_response): + +def save_mock_data(file_path: str, json_response: dict) -> None: """Helper function to save mock data to a file.""" # clean request data as it can contain secrets like api key json_response["request"] = {} @@ -44,12 +49,14 @@ def save_mock_data(file_path, json_response): with open(file_path, "w") as f: f.write(json.dumps(json_response)) -def get_mock_data_path(file_path): + +def get_mock_data_path(file_path: str) -> str: """Helper function to get the path of the mock data file.""" base_dir = os.path.dirname(os.path.abspath(__file__)) data_dir = os.path.join(base_dir, "data/") return os.path.join(data_dir, file_path) + @pytest.mark.parametrize( "series_id, start_date, end_date", [ @@ -62,7 +69,6 @@ def get_mock_data_path(file_path): def test_get_series(series_id, start_date, end_date, mocker): """Test get_series method.""" file_path = get_mock_data_path(f"{series_id}_{start_date}_{end_date}.json") - spy_get = mock_requests_get(mocker, file_path) df = eia.get_series(series_id, start_date=start_date, end_date=end_date) @@ -75,6 +81,7 @@ def test_get_series(series_id, start_date, end_date, mocker): assert not df.empty assert isinstance(df, pd.DataFrame) + @pytest.mark.parametrize( "route, series, frequency, facet", [ @@ -88,8 +95,9 @@ def test_get_series(series_id, start_date, end_date, mocker): ) def test_get_series_via_route(route, series, frequency, facet, mocker): """Test get_series_via_route method.""" - file_path = get_mock_data_path(f"{route.replace('/', '-')}_{series}_{frequency}_{facet}.json") - + file_path = get_mock_data_path( + f"{route.replace('/', '-')}_{series}_{frequency}_{facet}.json" + ) spy_get = mock_requests_get(mocker, file_path) df = eia.get_series_via_route(route, series, frequency, facet) @@ -100,4 +108,4 @@ def test_get_series_via_route(route, series, frequency, facet, mocker): save_mock_data(file_path, spy_get.spy_return.json()) assert not df.empty - assert isinstance(df, pd.DataFrame) \ No newline at end of file + assert isinstance(df, pd.DataFrame)