From 40e897be510d5f34c7d904a62c4fe2f5b68e9be6 Mon Sep 17 00:00:00 2001 From: nickatnight Date: Sat, 23 Nov 2024 16:40:22 -0800 Subject: [PATCH] fix: add chain arg to client; test: add missing tests --- README.md | 7 ++++--- birdeyepy/birdeye.py | 20 ++++++++++++++++---- birdeyepy/utils/__init__.py | 5 ++++- birdeyepy/utils/enums.py | 20 ++++++++++++++++++++ pyproject.toml | 2 +- tests/unit/test_birdeye.py | 18 ++++++++++++++++-- tests/unit/utils/test_helpers.py | 11 +++++++++++ uv.lock | 2 +- 8 files changed, 73 insertions(+), 12 deletions(-) create mode 100644 tests/unit/utils/test_helpers.py diff --git a/README.md b/README.md index 12d8050..35d61f4 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,8 @@ $ pip install birdeye-py ```python from birdeyepy import BirdEye -client = BirdEye(api_key="your-api-key") +client = BirdEye(api_key="your-api-key") # 'x-chain' header defaults to solana +eth_client = BirdEye(api_key="your-api-key", chain="ethereum") # DeFi @@ -69,8 +70,8 @@ client.token.list_all() ``` ## Documentation -Coming Soon +See https://docs.birdeye.so/docs/overview --- -If you would like to support development efforts, tips are greatly appreciated. SOL address: HKmUpKBCcZGVX8RqLRcKyjYuY23hQHwnFSHXzdon4pCH +If you would like to support development efforts, tips are greatly appreciated. SOL wallet address: HKmUpKBCcZGVX8RqLRcKyjYuY23hQHwnFSHXzdon4pCH diff --git a/birdeyepy/birdeye.py b/birdeyepy/birdeye.py index db9708d..e1febd3 100644 --- a/birdeyepy/birdeye.py +++ b/birdeyepy/birdeye.py @@ -1,17 +1,29 @@ from birdeyepy.resources import RESOURCE_MAP -from birdeyepy.utils import BASE_BIRD_EYE_API_URL, RequestsClient +from birdeyepy.utils import ( + BASE_BIRD_EYE_API_URL, + BirdEyeChain, + BirdEyeClientError, + RequestsClient, +) -__version__ = "0.0.1" +__version__ = "0.0.2" class BirdEye: """API Client for BirdEye""" - def __init__(self, api_key: str) -> None: + def __init__(self, api_key: str, chain: str = BirdEyeChain.SOLANA) -> None: + if chain not in BirdEyeChain.all(): + raise BirdEyeClientError(f"Invalid chain: {chain}") + _http = RequestsClient( base_url=BASE_BIRD_EYE_API_URL, - headers={"X-API-KEY": api_key, "User-Agent": f"birdeyepy/v{__version__}"}, + headers={ + "x-chain": chain, + "X-API-KEY": api_key, + "User-Agent": f"birdeyepy/v{__version__}", + }, ) for resource_name, resource_class in RESOURCE_MAP.items(): diff --git a/birdeyepy/utils/__init__.py b/birdeyepy/utils/__init__.py index 6c05f67..952e884 100644 --- a/birdeyepy/utils/__init__.py +++ b/birdeyepy/utils/__init__.py @@ -1,5 +1,6 @@ from birdeyepy.utils.constants import BASE_BIRD_EYE_API_URL, DEFAULT_SOL_ADDRESS -from birdeyepy.utils.enums import BirdEyeApiUrls +from birdeyepy.utils.enums import BirdEyeApiUrls, BirdEyeChain +from birdeyepy.utils.exceptions import BirdEyeClientError from birdeyepy.utils.helpers import as_api_args from birdeyepy.utils.http import RequestsClient from birdeyepy.utils.interfaces import IHttp @@ -11,8 +12,10 @@ "BASE_BIRD_EYE_API_URL", "DEFAULT_SOL_ADDRESS", "BirdEyeApiUrls", + "BirdEyeChain", "BirdEyeRequestParams", "IHttp", "RequestsClient", "as_api_args", + "BirdEyeClientError", ] diff --git a/birdeyepy/utils/enums.py b/birdeyepy/utils/enums.py index 3215159..20d48dc 100644 --- a/birdeyepy/utils/enums.py +++ b/birdeyepy/utils/enums.py @@ -1,5 +1,25 @@ +class SimpleEnum: + @classmethod + def all(cls) -> list[str]: + return [v for k, v in cls.__dict__.items() if not k.startswith("__")] + + class BirdEyeApiUrls: # DEFI DEFI_PRICE = "defi/price" DEFI_TOKEN_LIST = "defi/tokenlist" DEFI_HISTORY_PRICE = "defi/history_price" + + +class BirdEyeChain(SimpleEnum): + # Solana + SOLANA = "solana" + ETHEREUM = "ethereum" + BSC = "bsc" + AVALANCHE = "avalanche" + ARBITRUM = "arbitrum" + OPTIMISM = "optimism" + POLYGON = "polygon" + BASE = "base" + ZKSYNC = "zksync" + SUI = "sui" diff --git a/pyproject.toml b/pyproject.toml index d349d92..2d959ea 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "birdeye-py" -version = "0.0.1" +version = "0.0.2" description = "Python wrapper for birdeye.so api" readme = "README.md" requires-python = ">=3.9" diff --git a/tests/unit/test_birdeye.py b/tests/unit/test_birdeye.py index 4fd0b20..f86517a 100644 --- a/tests/unit/test_birdeye.py +++ b/tests/unit/test_birdeye.py @@ -1,8 +1,10 @@ from unittest.mock import MagicMock +import pytest + from birdeyepy.birdeye import BirdEye, __version__ from birdeyepy.resources import RESOURCE_MAP -from birdeyepy.utils import BASE_BIRD_EYE_API_URL +from birdeyepy.utils import BASE_BIRD_EYE_API_URL, BirdEyeClientError def test_client_http_called_with_correct_args(mocker: MagicMock) -> None: @@ -15,10 +17,22 @@ def test_client_http_called_with_correct_args(mocker: MagicMock) -> None: # Assert mock_requests_client.assert_called_once_with( base_url=BASE_BIRD_EYE_API_URL, - headers={"X-API-KEY": "test", "User-Agent": f"birdeyepy/v{__version__}"}, + headers={ + "x-chain": "solana", + "X-API-KEY": "test", + "User-Agent": f"birdeyepy/v{__version__}", + }, ) +def test_client_invalid_chain() -> None: + # Act / Assert + with pytest.raises(BirdEyeClientError) as e: + BirdEye(api_key="test", chain="invalid") + + assert str(e.value) == "Invalid chain: invalid" + + def test_client_properties( mocker: MagicMock, ) -> None: diff --git a/tests/unit/utils/test_helpers.py b/tests/unit/utils/test_helpers.py new file mode 100644 index 0000000..cba7aad --- /dev/null +++ b/tests/unit/utils/test_helpers.py @@ -0,0 +1,11 @@ +from birdeyepy.utils.helpers import as_api_args + + +def test_as_api_args_with_list() -> None: + # Arrange + @as_api_args + def uat_function(ids: str | list) -> None: + assert ids == "a,b,c" + + # Assert + uat_function(ids=["a", "b", "c"]) diff --git a/uv.lock b/uv.lock index 397eba5..6f713ec 100644 --- a/uv.lock +++ b/uv.lock @@ -42,7 +42,7 @@ wheels = [ [[package]] name = "birdeye-py" -version = "0.0.1" +version = "0.0.2" source = { virtual = "." } dependencies = [ { name = "requests" },