Кодогенератор (Codegen) ====================== Обзор ----- Кастомные поля AmoCRM имеют числовые ID и произвольные названия, часто на русском языке. Кодогенератор автоматически создаёт типизированные подклассы DTO (``MyLead``, ``MyContact``, ``MyCompany``) с named-свойствами для каждого кастомного поля, что позволяет обращаться к ним как к обычным атрибутам Python вместо ``get_cf_value(123)``. Имена свойств автоматически транслитерируются из кириллицы в латиницу и приводятся к snake_case: ``Источник трафика`` → ``istochnik_trafika``. Быстрый старт ------------- .. code-block:: python from amocrm import OAuthConfig, DjangoTokenStorage from amocrm.codegen import generate_custom_fields_dto oauth = OAuthConfig( client_id="...", client_secret="...", redirect_uri="https://yourapp.com/oauth/callback", storage=DjangoTokenStorage(my_settings_obj), ) generate_custom_fields_dto("mycompany", oauth, output_file="my_models.py") Функция подключится к AmoCRM, загрузит определения кастомных полей и запишет готовый Python-код в файл ``my_models.py``. Пример сгенерированного файла ------------------------------ Для каждого кастомного поля генерируются **и геттер, и сеттер** — можно читать и записывать значение через стандартный property-синтаксис: .. code-block:: python # Generated by amocrm-sdk codegen. DO NOT EDIT. # Regenerate: from amocrm.codegen import generate_custom_fields_dto from __future__ import annotations from amocrm import Lead, Contact, Company class MyLead(Lead): """Типизированные кастомные поля для сделок.""" @property def istochnik_trafika(self) -> str | None: """Источник трафика (text, id=101)""" return self.get_cf_value(101) @istochnik_trafika.setter def istochnik_trafika(self, value: str | None) -> None: self.set_cf_value(101, value) @property def byudzhet(self) -> float | None: """Бюджет (numeric, id=102)""" return self.get_cf_value(102) @byudzhet.setter def byudzhet(self, value: float | None) -> None: self.set_cf_value(102, value) ... Подключение к клиенту через ``configure_dto`` ---------------------------------------------- После генерации подключите классы к клиенту. Все методы ``get``, ``list``, ``create``, ``update`` начнут возвращать экземпляры вашего подкласса: .. code-block:: python from amocrm.manager import get_client from my_models import MyLead, MyContact, MyCompany client = get_client(subdomain="mycompany", oauth=oauth) client.configure_dto(leads=MyLead, contacts=MyContact, companies=MyCompany) lead = client.leads.get(123) # → MyLead print(lead.istochnik_trafika) # → str | None (геттер) lead.istochnik_trafika = "SEO" # сеттер — записывает в custom_fields_values client.leads.update([lead]) # сохраняет изменения в AmoCRM for lead in client.leads.list(): # → Iterator[MyLead] print(lead.byudzhet) Параметры ``configure_dto`` — все необязательны, можно подменить только часть ресурсов: .. code-block:: python client.configure_dto(leads=MyLead) # contacts и companies остаются стандартными .. note:: Вложенные объекты внутри ``Lead`` (``lead.contacts``, ``lead.company``) остаются стандартными классами ``Contact`` / ``Company``. Чтобы и они были вашими подклассами, переопределите ``from_dict`` в ``MyLead``. Транслитерация имён ------------------- Названия кастомных полей на кириллице автоматически транслитерируются перед преобразованием в snake_case. Это позволяет использовать имена свойств как стандартные Python-атрибуты. Примеры транслитерации: .. list-table:: :header-rows: 1 * - Оригинал - Результат * - ``Источник`` - ``istochnik`` * - ``Источник трафика`` - ``istochnik_trafika`` * - ``пользовательское_соглашение`` - ``polzovatelskoe_soglashenie`` * - ``предыдущая_сделка_1`` - ``predydushchaya_sdelka_1`` Таблица транслитерации (кириллица → латиница): .. list-table:: :header-rows: 1 * - Символ - Транслит * - а, б, в, г, д - a, b, v, g, d * - е, ё, ж, з, и - e, yo, zh, z, i * - й, к, л, м, н - j, k, l, m, n * - о, п, р, с, т - o, p, r, s, t * - у, ф, х, ц, ч - u, f, kh, ts, ch * - ш, щ, ъ, ы, ь - sh, shch, (пусто), y, (пусто) * - э, ю, я - e, yu, ya Запись значений через сеттеры ------------------------------ Каждое сгенерированное property имеет сеттер. Тип аргумента совпадает с типом геттера: .. code-block:: python lead = client.leads.get(123) # Обычные скалярные поля (text, numeric, integer, …) lead.email = "new@example.com" lead.byudzhet = 150000.0 # Multiselect — передаётся список значений lead.uslugi = ["SEO", "Контекст"] # Сброс значения поля lead.email = None client.leads.update([lead]) Под капотом сеттер вызывает методы ``CustomFieldsMixin``: .. list-table:: :header-rows: 1 * - Тип поля AmoCRM - Сеттер в миксине * - text, numeric, integer, select, phone, email, url, checkbox, bool, date, … - ``set_cf_value(field_id, value)`` * - multiselect - ``set_cf_values(field_id, values)`` * - smart_address - ``set_cf_raw(field_id, values)`` Конфигурация ------------ ``generate_custom_fields_dto`` принимает следующие параметры: .. list-table:: :header-rows: 1 * - Параметр - По умолчанию - Описание * - ``subdomain`` - — - Поддомен аккаунта AmoCRM (например, ``"mycompany"``) * - ``oauth`` - — - Объект :class:`~amocrm.OAuthConfig` с реквизитами и хранилищем токенов * - ``entities`` - ``["leads", "contacts", "companies"]`` - Список сущностей для генерации * - ``base_module`` - ``"amocrm"`` - Модуль, из которого импортируются базовые классы * - ``output_file`` - ``None`` - Путь к выходному файлу; если ``None`` — вывод в stdout Использование без записи в файл -------------------------------- Если ``output_file`` не передан, код выводится в stdout: .. code-block:: python generate_custom_fields_dto("mycompany", oauth) Это удобно для просмотра результата перед сохранением или для использования вывода в пайплайне. Генерация только для части сущностей: .. code-block:: python generate_custom_fields_dto( "mycompany", oauth, entities=["leads"], output_file="lead_models.py", ) API-справочник -------------- .. autofunction:: amocrm.codegen.generate_custom_fields_dto .. autofunction:: amocrm.codegen.generate_and_print .. autofunction:: amocrm.codegen.fetch_custom_fields .. autofunction:: amocrm.codegen.generate_custom_models