-
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feature: Initial development for Hexagonal Arch
- Loading branch information
1 parent
b03f7ac
commit c91d282
Showing
18 changed files
with
175 additions
and
38 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
from .adapters.outbound.currency_api import CurrencyAPI | ||
from .adapters.inbound.controller import CurrencyController | ||
from .domain.services.get_currency_quote import GetCurrencyQuote | ||
from .domain.services.validate_currency import ValidateCurrency | ||
|
||
|
||
|
||
class CurrencyQuote: | ||
def __init__(self): | ||
currency_api = CurrencyAPI() | ||
validate_currency_service = ValidateCurrency(currency_api) | ||
get_currency_quote_service = GetCurrencyQuote(currency_api, validate_currency_service) | ||
self.controller = CurrencyController(get_currency_quote_service) | ||
|
||
def get_quote(self, currency_code: str): | ||
return self.controller.get_quote(currency_code) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
# src/currency_quote/adapters/inbound/controller.py | ||
from currency_quote.application.ports.inbound.get_currency_quote_use_case import GetCurrencyQuoteUseCase | ||
|
||
|
||
class CurrencyController: | ||
def __init__(self, get_currency_quote_use_case: GetCurrencyQuoteUseCase): | ||
self.get_currency_quote_use_case = get_currency_quote_use_case | ||
|
||
def get_quote(self, currency_code: str): | ||
try: | ||
currency = self.get_currency_quote_use_case.execute(currency_code) | ||
return {"code": currency.code, "name": currency.name, "rate": currency.rate} | ||
except ValueError as e: | ||
return {"error": str(e)} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
# src/currency_quote/adapters/outbound/currency_api.py | ||
from api_to_dataframe import ClientBuilder, RetryStrategies | ||
from currency_quote.application.ports.outbound.currency_repository import CurrencyRepository | ||
from currency_quote.config.endpoints import API | ||
|
||
|
||
class CurrencyAPI(CurrencyRepository): | ||
def _get_last_quote(*args): | ||
url = API.ENDPOINT_LAST_COTATION + ','.join(args) | ||
client = ClientBuilder( | ||
endpoint=url, | ||
retry_strategy=RetryStrategies.LinearRetryStrategy | ||
) | ||
|
||
response = client.get_api_data() | ||
|
||
return response |
22 changes: 22 additions & 0 deletions
22
src/currency_quote/adapters/outbound/currency_validator_api.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
# src/currency_quote/adapters/outbound/currency_validator_api.py | ||
from api_to_dataframe import ClientBuilder, RetryStrategies | ||
from currency_quote.config.endpoints import API | ||
|
||
|
||
class CurrencyValidator: | ||
@staticmethod | ||
def validate_currency_code(currency_list: list) -> list: | ||
client = ClientBuilder( | ||
endpoint=API.ENDPOINT_AVALIABLE_PARITIES, | ||
retry_strategy=RetryStrategies.LinearRetryStrategy | ||
) | ||
|
||
valid_list = client.get_api_data() | ||
|
||
validated_list = [] | ||
|
||
for currency_code in currency_list: | ||
if currency_code in valid_list: | ||
validated_list.append(currency_code) | ||
|
||
return validated_list |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
from abc import ABC, abstractmethod | ||
from currency_quote.domain.entities.currency import Currency | ||
|
||
|
||
class GetCurrencyQuoteUseCase(ABC): | ||
@abstractmethod | ||
def execute(self, currency_code: list) -> Currency: | ||
pass |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
# src/currency_quote/application/ports/outbound/currency_repository.py | ||
from abc import ABC, abstractmethod | ||
|
||
|
||
class CurrencyRepository(ABC): | ||
@abstractmethod | ||
def get_currency_quote(self, currency_code: list): | ||
pass |
8 changes: 8 additions & 0 deletions
8
src/currency_quote/application/ports/outbound/currency_validator_repository.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
# src/currency_quote/application/ports/outbound/currency_validator_port.py | ||
from abc import ABC, abstractmethod | ||
|
||
|
||
class CurrencyValidatorPort(ABC): | ||
@abstractmethod | ||
def validate_currency_code(self, currency_list: list) -> list: | ||
pass |
29 changes: 29 additions & 0 deletions
29
src/currency_quote/application/use_cases/test_validate_currency.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
import pytest | ||
from currency_quote.domain.services.validate_currency import CurrencyValidatorService | ||
from currency_quote.application.use_cases.validate_currency import ValidateCurrencyUseCase | ||
|
||
|
||
def test_valid_currency(): | ||
validator_service = CurrencyValidatorService() | ||
currency_list = ["USD-BRL", "USD-BRLT"] | ||
validate_currency = ValidateCurrencyUseCase(currency_validator_service=validator_service) | ||
result = validate_currency.execute(currency_list=currency_list) | ||
assert result == currency_list | ||
|
||
|
||
def test_partial_valid_currency(): | ||
validator_service = CurrencyValidatorService() | ||
currency_list = ["USD-BRL", "USD-BRLT", "param1"] | ||
expected_result = ["USD-BRL", "USD-BRLT"] | ||
validate_currency = ValidateCurrencyUseCase(currency_validator_service=validator_service) | ||
result = validate_currency.execute(currency_list=currency_list) | ||
assert result == expected_result | ||
|
||
|
||
def test_invalid_currency(): | ||
validator_service = CurrencyValidatorService() | ||
currency_list = ["param1", "param2"] | ||
validate_currency = ValidateCurrencyUseCase(currency_validator_service=validator_service) | ||
with pytest.raises(ValueError): | ||
validate_currency.execute(currency_list=currency_list) | ||
|
10 changes: 10 additions & 0 deletions
10
src/currency_quote/application/use_cases/validate_currency.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
# src/currency_quote/application/use_cases/validate_currency.py | ||
from currency_quote.domain.services.validate_currency import CurrencyValidatorService | ||
|
||
|
||
class ValidateCurrencyUseCase: | ||
def __init__(self, currency_validator_service: CurrencyValidatorService): | ||
self.currency_validator_service = currency_validator_service | ||
|
||
def execute(self, currency_list: list) -> list: | ||
return self.currency_validator_service.validate_currency_code(currency_list) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
class Currency: | ||
def __init__(self, currency: list): | ||
self.currency_list = currency |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
# src/currency_quote/domain/services/get_currency_quote.py | ||
from currency_quote.application.ports.inbound.get_currency_quote_use_case import GetCurrencyQuoteUseCase | ||
from currency_quote.application.ports.outbound.currency_repository import CurrencyRepository | ||
from currency_quote.domain.entities.currency import Currency | ||
from currency_quote.domain.services.validate_currency import ValidateCurrency | ||
|
||
|
||
class GetCurrencyQuote(GetCurrencyQuoteUseCase): | ||
def __init__(self, currency_repository: CurrencyRepository, validate_currency_service: ValidateCurrency): | ||
self.currency_repository = currency_repository | ||
self.validate_currency_service = validate_currency_service | ||
|
||
def execute(self, currency_code: str) -> Currency: | ||
if not self.validate_currency_service.execute(currency_code): | ||
raise ValueError(f"Código de moeda {currency_code} é inválido.") | ||
|
||
currency = self.currency_repository.get_currency_quote(currency_code) | ||
if not currency: | ||
raise ValueError(f"Cotação para a moeda {currency_code} não encontrada.") | ||
return currency |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
# src/currency_quote/application/services/currency_validator_service.py | ||
from currency_quote.application.ports.outbound.currency_validator_repository import CurrencyValidatorPort | ||
from currency_quote.adapters.outbound.currency_validator_api import CurrencyValidator | ||
|
||
|
||
class CurrencyValidatorService(CurrencyValidatorPort): | ||
def __init__(self): | ||
self.currency_validator = CurrencyValidator() | ||
|
||
def validate_currency_code(self, currency_list: list) -> list: | ||
validated_list = self.currency_validator.validate_currency_code(currency_list) | ||
|
||
if len(validated_list) == 0: | ||
raise ValueError(f"All params: {currency_list} are invalid.") | ||
|
||
if len(validated_list) < len(currency_list): | ||
print(f"Invalid currency params: {set(currency_list) - set(validated_list)}") | ||
|
||
return validated_list |
File renamed without changes.
File renamed without changes.