Skip to content

Commit

Permalink
Removes AsyncClient, add better documentation, add more tests (#6)
Browse files Browse the repository at this point in the history
* Removes AsyncClient, add better documentation

* Update Python Version

* Update libs

* Update version

* Update tests

* Update tests

* Update docs
  • Loading branch information
affonsobrian authored Mar 8, 2023
1 parent 297afbf commit ee9b84f
Show file tree
Hide file tree
Showing 29 changed files with 668 additions and 1,070 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
- name: Set up Python 3.10
uses: actions/setup-python@v2
with:
python-version: "3.9.9"
python-version: "3.11.2"
- name: Install dependencies
run: |
python -m pip install --upgrade pip
Expand All @@ -35,4 +35,4 @@ jobs:
flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
- name: Test with pytest
run: |
pytest tests
pytest tests --cov=.
13 changes: 10 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ A library to easily handle currency conversions.
- We do not have an official documentation yet, we are working on this.

## Data origin
Currently the API uses the https://theforexapi.com/api to get the values.
We are working to make it extensable so you can pick info from different sources in the future.
Currently the API used to get the values is https://theforexapi.com/api. (If the forex API the default client will not work)
We are working to make the lib extensable so you can pick info from different sources in the future.


## How to install
Expand All @@ -19,7 +19,14 @@ pip install geld

## How to use the Sync Client

```
Code:
```python
from geld.clients import sync_client as client
result = client.convert_currency("USD", "BRL", 25, "2021-12-05")
print(result)
```

Result:
```
141.0127535205030424592109739
```
2 changes: 1 addition & 1 deletion geld/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = "0.2.1"
__version__ = "0.3.0"
Empty file removed geld/asyncio/__init__.py
Empty file.
16 changes: 0 additions & 16 deletions geld/asyncio/base.py

This file was deleted.

27 changes: 0 additions & 27 deletions geld/asyncio/client.py

This file was deleted.

2 changes: 0 additions & 2 deletions geld/clients.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
from geld.sync.client import SyncClient
from geld.asyncio.client import AsyncClient

sync_client = SyncClient()
async_client = AsyncClient()
11 changes: 0 additions & 11 deletions geld/common/helpers.py

This file was deleted.

6 changes: 6 additions & 0 deletions geld/common/singleton.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
class SingletonMeta(type):
"""
This metaclass is used for creating singleton objects.
The class maintains a dictionary of instances created by the class,
and ensures that only one instance of the class is ever created.
"""

_instances = {}

def __call__(cls, *args, **kwargs):
Expand Down
52 changes: 46 additions & 6 deletions geld/common/validators.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from datetime import datetime
from decimal import Decimal
from geld.common.constants import CURRENCY_DATA
from geld.common.exceptions import (
Expand All @@ -7,24 +8,63 @@
)


def currency_code_validator(currency_code):
def currency_code_validator(currency_code: str) -> str:
"""
Validates a given currency code.
Args:
currency_code (str): The currency code to validate.
Returns:
str: The validated currency code.
Raises:
InvalidCurrencyCode: If the given currency code is not valid.
"""
try:
_ = CURRENCY_DATA[currency_code]
except KeyError:
raise InvalidCurrencyCode
return currency_code


def date_validator(date):
def date_validator(date: str) -> str:
"""
Validates a given date.
Args:
date str or datetime.datetime): The date to validate.
Returns:
str: The validated date in the format "YYYY-MM-DD".
Raises:
InvalidDate: If the given date is not valid.
"""
if not date or date == "latest":
return "latest"
try:
if not isinstance(date, str):
date = date.isoformat()[0:10]
except Exception:
if isinstance(date, str):
date = datetime.fromisoformat(date)
date, _ = date.isoformat().split("T")
except (AttributeError, ValueError):
raise InvalidDate
return date


def amount_validator(amount):
def amount_validator(amount: Decimal) -> Decimal:
"""
Validates a given amount.
Args:
amount (Decimal or float or int or str): The amount to validate.
Returns:
Decimal: The validated amount as a Decimal object.
Raises:
InvalidAmount: If the given amount is not valid (not a Decimal object, negative).
"""
try:
if not isinstance(amount, Decimal):
amount = Decimal(amount)
Expand Down
20 changes: 10 additions & 10 deletions geld/sync/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from decimal import Decimal
from geld.common.exceptions import APICallError, BaseUrlNotDefined


class SyncClientBase:
_base_url = None

Expand All @@ -17,14 +18,14 @@ def convert_currency(
to_currency: str,
amount: Decimal,
date: str = None,
):
) -> Decimal:
if from_currency == to_currency:
return amount

url = self._get_url(date)
params = self._get_params(from_currency, to_currency)
response = self._execute_request(url, params)

if not response.status_code == 200:
raise APICallError

Expand All @@ -35,21 +36,20 @@ def convert_currency(

def _get_url(self, date: str):
return f"{self._base_url}/{date}/"

def _get_params(self, from_currency: str, to_currency: str):
return {
"base": from_currency,
"symbols": to_currency,
}

def _execute_request(self, url: str, params: dict):
requests.get(url, params=params)
return requests.get(url, params=params)

def _get_rate_from_response(self, response, to_currency: str):
data = json.loads(response.text)
rate = Decimal(data["rates"][to_currency])
return rate

def _convert_amount(self, amount: Decimal, rate: Decimal):
return amount*rate

def _convert_amount(self, amount: Decimal, rate: Decimal):
return amount * rate
43 changes: 41 additions & 2 deletions geld/sync/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,48 @@

from decimal import Decimal


class SyncClient(SyncClientBase):
"""
A synchronous client for accessing the Currency Converter API and converting currency amounts.
Attributes:
_base_url (str): The base URL of the Currency Converter API.
Methods:
convert_currency: Converts a specified amount of currency from one currency code to another for a given date.
"""

_base_url = BASE_URL

@validate_currency_conversion_data
def convert_currency(self, from_currency: str, to_currency: str, amount: Decimal = 1, date: str = "latest"):
return super(SyncClient, self).convert_currency(from_currency, to_currency, amount, date)
def convert_currency(
self,
from_currency: str,
to_currency: str,
amount: Decimal = 1,
date: str = "latest",
) -> Decimal:
"""
Converts a specified amount of currency from one currency code to another for a given date using the Currency Converter API.
Args:
from_currency (str): The currency code for the currency to convert from.
to_currency (str): The currency code for the currency to convert to.
amount (Decimal, optional): The amount of currency to convert. Defaults to 1.
date (str, optional): The date to use for the conversion rate. Should be in the format "YYYY-MM-DD" or "latest". Defaults to "latest".
Returns:
Decimal: The converted amount of currency as a Decimal object.
Raises:
requests.exceptions.RequestException: If an error occurs while making the request to the API.
InvalidCurrencyCode: If the from_currency or to_currency arguments are not valid currency codes.
InvalidAmount: If the amount argument is not a valid Decimal object or is negative.
InvalidDate: If the date argument is not in a valid format.
KeyError: If the API response does not contain the expected keys.
ValueError: If the API response contains invalid data.
"""
return super(SyncClient, self).convert_currency(
from_currency, to_currency, amount, date
)
Loading

0 comments on commit ee9b84f

Please sign in to comment.