feat(parsers): добавлен API клиент для checko.ru

- Реализован CheckoClient с поддержкой всех 10 эндпоинтов API v2
- Frozen dataclass модели для запросов и ответов
- Справочники ОКВЭД2, ОКФС, ОКОПФ, ОКПД, статусы компаний
- Маппинг русских полей API на английские имена
- Unit тесты с моками
- E2E тесты с реальными запросами
- Настройка CHECKO_API_KEY в settings.py
This commit is contained in:
2026-02-03 17:00:19 +01:00
parent 5c88c6466d
commit c36c7b9ba9
22 changed files with 5943 additions and 4 deletions

View File

@@ -0,0 +1,132 @@
"""
ОКВЭД-2 (ОК 029-2014) - Общероссийский классификатор видов экономической деятельности.
Использование:
from apps.parsers.clients.checko.datasets import OKVED2
# Получить название по коду
name = OKVED2.get_name("62.01")
# Получить полный объект
item = OKVED2.get("62.01")
# Поиск по названию
items = OKVED2.search("программное")
# Получить все коды раздела
section_j = OKVED2.get_section("J")
# Получить дочерние коды
children = OKVED2.get_children("62")
"""
from dataclasses import dataclass
from typing import ClassVar
from apps.parsers.clients.checko.datasets.base import BaseDataset
@dataclass(frozen=True)
class OkvedItem:
"""Элемент справочника ОКВЭД-2."""
code: str
"""Код ОКВЭД (например: '62.01')."""
name: str
"""Наименование вида деятельности."""
section: str | None = None
"""Раздел классификатора (A-U)."""
parent_code: str | None = None
"""Код родительского элемента."""
comment: str | None = None
"""Пояснения к коду."""
class OKVED2(BaseDataset[OkvedItem]):
"""
Справочник ОКВЭД-2 (виды экономической деятельности).
Данные: ОК 029-2014 (КДЕС Ред. 2).
"""
_data: ClassVar[dict[str, OkvedItem] | None] = None
_json_filename: ClassVar[str] = "okved_2.json"
@classmethod
def _parse_item(cls, raw: dict) -> OkvedItem:
return OkvedItem(
code=raw.get("code", ""),
name=raw.get("name", ""),
section=raw.get("section"),
parent_code=raw.get("parent_code"),
comment=raw.get("comment"),
)
@classmethod
def get_section(cls, section: str) -> list[OkvedItem]:
"""
Получить все коды раздела.
Args:
section: Код раздела (A-U).
Returns:
Список элементов раздела.
"""
cls._ensure_loaded()
return [i for i in cls._data.values() if i.section == section.upper()]
@classmethod
def get_children(cls, code: str) -> list[OkvedItem]:
"""
Получить дочерние коды.
Args:
code: Родительский код ОКВЭД.
Returns:
Список дочерних элементов.
"""
cls._ensure_loaded()
return [i for i in cls._data.values() if i.parent_code == code]
@classmethod
def get_parent(cls, code: str) -> OkvedItem | None:
"""
Получить родительский элемент.
Args:
code: Код ОКВЭД.
Returns:
Родительский элемент или None.
"""
item = cls.get(code)
if item and item.parent_code:
return cls.get(item.parent_code)
return None
@classmethod
def get_hierarchy(cls, code: str) -> list[OkvedItem]:
"""
Получить иерархию от корня до указанного кода.
Args:
code: Код ОКВЭД.
Returns:
Список от корневого раздела до указанного кода.
"""
result = []
current = cls.get(code)
while current:
result.insert(0, current)
if current.parent_code:
current = cls.get(current.parent_code)
else:
break
return result