-
-
Save Bahus/19c9350f083678797e5bacb873ef827b to your computer and use it in GitHub Desktop.
planning of architecture
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
from decimal import Decimal | |
import pydantic | |
@shared_task | |
def get_provider_api_stocks(api_key, url_constructor, deserialize_constructor): | |
# api_key в принципе нельзя передавать так | |
return True | |
from typing import Protocol | |
class BaseCodeProviderClient(Protocol): | |
@abstractmethod | |
def get_one_game_detail_stock(): | |
return True | |
@abstractmethod | |
def get_codes_from_order(): | |
return True | |
@abstractmethod | |
def get_orders_history(): | |
return True | |
@abstractmethod | |
def get_detail_of_order(self, order_id: str): | |
return True | |
def get_profitable_stocks_info(params): | |
get_provider_api_stocks(params) | |
get_one_game_detail_stock(params) | |
class HTTPClient: | |
def __init__( | |
self, | |
base_url: str, | |
retry_policy: Retry(connect=2, read=2), | |
timeout_policy: TimePolicy(5, 20), | |
auth: BasicHTTPAuth(user, password), | |
middleware = [HTTPLoggingMiddleware, HTTPMetricsMiddleware, HTTPXRequestID], | |
session: Optional[requests.Session] = None # requests.Session(), | |
): | |
pass | |
class OrderDetails(pydantic.BaseModel): | |
id: int | |
amount: Decimal | |
code: str | |
class GameEXECodesProvider(BaseCodeProviderClient): | |
slug = 'game_exe' | |
def __init__(self, provider: 'CodeProvider'): | |
self._provider = provider | |
self._http_client = HTTPClient( | |
base_url=provider.url, | |
auth=provider.get_auth(), | |
) | |
def get_detail_of_order(self, order_id: str) -> OrderDetails: | |
response = self._http_client.get(f'/orders/{order_id}') | |
return OrderDetails.parse_obj(response.json()) | |
class Codes1Provider(BaseCodeProviderClient): | |
slug = 'code_1' | |
def get_one_game_detail_stock(self): | |
"""do something""" | |
class Codes2Provider(BaseCodeProviderClient): | |
slug = 'code_2' | |
def get_orders_history(self, ...): | |
"""do something""" | |
AVAILABLE_PROVIDERS = { | |
GameEXECodesProvider.slug: GameEXECodesProvider, | |
Codes1Provider.slug: Codes1Provider, | |
Codes2Provider.slug: Codes2Provider, | |
} | |
class CodeProvider(Model): | |
slug = TextField(unique=True) | |
url = URLField() | |
# Authentication data can be different between providers | |
auth_data = JSONField() | |
@shared_task | |
def gather_new_codes_dispatcher(): | |
"""Scheduled tasks, executed every hour and gather all new available codes from providers.""" | |
for provider_id in CodeProvider.objects.values_list('id', flat=True): | |
gather_new_cored_for_provider(provider_id=provider_id).apply_async() | |
@shared_task | |
def gather_new_cored_for_provider(*, provider_id: int): | |
provider = CodeProvider.objects.get(id=provider_id) | |
provider_client: BaseCodeProviderClient = AVAILABLE_PROVIDERS[provider.slug](provider=provider) | |
codes = provider_client.gather_codes() | |
save_codes() |
в __init__
не стоит вообще никаких сложных действий делать (ходить в базу, ходить по http) и т.д. так как это считается сайд эффектом, в инициализаторе обычно идет присвоение данных, сами данные передаются из получаются из вне.
В указанном тобой случае класс бы выглядел так:
class GameEXECodesProvider(BaseCodeProviderClient):
def __init__(self, provider_slug: str):
self._provider_slug = provider_slug
@cached_property
def provider(self) -> 'Provider':
return Provider.objects.get(slug=self.slug)
в
__init__
не стоит вообще никаких сложных действий делать (ходить в базу, ходить по http) и т.д. так как это считается сайд эффектом, в инициализаторе обычно идет присвоение данных, сами данные передаются из получаются из вне.В указанном тобой случае класс бы выглядел так:
class GameEXECodesProvider(BaseCodeProviderClient): def __init__(self, provider_slug: str): self._provider_slug = provider_slug @cached_property def provider(self) -> 'Provider': return Provider.objects.get(slug=self.slug)
аа, ну да. Не вопрос. Так, что такой вариант c получением объекта из класса, тоже норм ?
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
а почему нельзя прямо в коде во время инициализации объекта доставать его из базы? Зачем его явно передавать?