Skip to content

Commit

Permalink
fix: add chain arg to client; test: add missing tests
Browse files Browse the repository at this point in the history
  • Loading branch information
nickatnight committed Nov 24, 2024
1 parent 6b549d5 commit 40e897b
Show file tree
Hide file tree
Showing 8 changed files with 73 additions and 12 deletions.
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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
20 changes: 16 additions & 4 deletions birdeyepy/birdeye.py
Original file line number Diff line number Diff line change
@@ -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():
Expand Down
5 changes: 4 additions & 1 deletion birdeyepy/utils/__init__.py
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -11,8 +12,10 @@
"BASE_BIRD_EYE_API_URL",
"DEFAULT_SOL_ADDRESS",
"BirdEyeApiUrls",
"BirdEyeChain",
"BirdEyeRequestParams",
"IHttp",
"RequestsClient",
"as_api_args",
"BirdEyeClientError",
]
20 changes: 20 additions & 0 deletions birdeyepy/utils/enums.py
Original file line number Diff line number Diff line change
@@ -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"
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -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"
Expand Down
18 changes: 16 additions & 2 deletions tests/unit/test_birdeye.py
Original file line number Diff line number Diff line change
@@ -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:
Expand All @@ -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:
Expand Down
11 changes: 11 additions & 0 deletions tests/unit/utils/test_helpers.py
Original file line number Diff line number Diff line change
@@ -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"])
2 changes: 1 addition & 1 deletion uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 40e897b

Please sign in to comment.