amocrm-api


Nameamocrm-api JSON
Version 2.6.1 PyPI version JSON
download
home_pagehttps://github.com/Krukov/amocrm_api
SummaryPython API for Amocrm
upload_time2023-06-27 05:41:53
maintainer
docs_urlNone
authorDmitry Kryukov
requires_python>=3.6
licenseMIT license
keywords
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            ===============================
AmoCRM python API. V2
===============================

.. image:: https://travis-ci.org/Krukov/amocrm_api.svg?branch=master
    :target: https://travis-ci.org/Krukov/amocrm_api
.. image:: https://img.shields.io/coveralls/Krukov/amocrm_api.svg
    :target: https://coveralls.io/r/Krukov/amocrm_api


Python AmoCRM API v2 (http://www.amocrm.ru/) (human interface for easy using)


Installation
============

::

    pip install amocrm_api

Usage
=====

Авторизация
-----------

Авторизация - с Июня 2020 amoCRM форсировала смену авторизации с токена на OAuth

И без поддержки server to server взаимодействия, в связи с чем текущая реализация содержит следующие ограничения

1. В личном кабинете необходимо создать интеграцию
2. Рефреш токен одноразовый и обновляется при каждом получении аксесс токена
3. Ecли запросы в amoCRM происходят реже чем время жизни рефреш токена то вам не подойдет такой варант интеграции
4. Токены нужно хранить, для этого есть api и существует 3 типа хранилища (можно реализовать свой):

- MemoryTokensStorage - хранит токены в памяти (если вы перезапускаете приложение то придется снова создавать refresh_token)
- FileStorage - сохраняет токены в файле
- RedisTokensStorage - сохраняет токены в редисе (pip install redis) для new-age приложений которые работают в нескольких экземплярах

Example::

    from amocrm.v2 import tokens

    tokens.default_token_manager(
        client_id="xxx-xxx-xxxx-xxxx-xxxxxxx",
        client_secret="xxxx",
        subdomain="subdomain",
        redirect_url="https://xxxx/xx",
        storage=tokens.FileTokensStorage(),  # by default FileTokensStorage
    )
    tokens.default_token_manager.init(code="..very long code...", skip_error=True)


- Контакт - Contact
- Компания  - Company
- Теги - Tags
- Сделка - Lead
- Задача - Task
- Примечание - Note
- Событие - Event
- Воронки и Статусы - Pipeline, Status

Работа с сущностями
--------------------

У каждой сущности есть менеджер (аттрибут objects), который имеет следующие методы

::

    <Entity>.objects.get(object_id=1, query="test")  # получение обьекта
    <Entity>.objects.all()  # получение всех сущностей
    <Entity>.objects.filter(**kwargs)  # получение списка сущностей с фильтром

    <Entity>.objects.create(**kwargs)  # создание сущности (нет явной сигнатуры поэтому лучше использовать метод create самой сущности)
    <Entity>.objects.update(**kwargs)  # обносление сущности (нет явной сигнатуры поэтому лучше использовать метод update самой сущности)

В свою очередь сама сущность имеет несколько методов для более простого создания и обновления

::

    <EntityInstance>.create()
    <EntityInstance>.update()
    <EntityInstance>.save()  # создаст или обновит в зависимости от того как обьект был инициализирован

Исключение - создание звонка происходит через упрошенную сущность
::

    from amocrm.v2 import Call, CallDirection, CallStatus

    Call().create(CallDirection.OUTBOUNT, phone="....", source="", duration=timedelta(minutes=10), status=CallStatus.CALL_LATER, created_by=manager)


Рассмотрим полный процесс работы на примере контакта

::

    from amocrm.v2 import Contact, Company

    contact = Contact.objects.get(query="Тест")
    print(contact.first_name)
    print(contact.company.name)
    print(contact.created_at)

    contact.last_name = "Новое"
    contact.tags.append("new")
    contact.notes.objects.create(text="Примечание")

    contact.save()

    contact.company = Company(name="Amocrm")  # создаст и сразу прилинкует компанию
    print(contact.company.id)

    len(list(contact.customers)) # lazy list
    contact.customers.append(Customer(name="Volta"))


Кастомные поля
--------------

Одна из удобных возможностей amoCRM  - кастомные поля

Example::

    from amocrm.v2 import Lead as _Lead, custom_field

    class Lead(_Lead):
        utm = custom_field.UrlCustomField("UTM метка")
        delivery_type = custom_field.SelectCustomField("Способ доставки")
        address = custom_field.TextCustomField("Адрес")


Однако мапинг всех кастомных полей дело утоминетльное,
поэтому для генерации файла с готовым мапингом есть команда::

    export AMOCRM_CLIENT_ID=xxx
    export AMOCRM_SECRET=xxx
    export AMOCRM_SUBDOMAIN=xxx
    export AMOCRM_REDIRECT_URL=xxx
    export AMOCRM_CODE=xxx # optional
    pyamogen > models.py

Для ее работы необходимо установить пакет python-slugify (https://github.com/un33k/python-slugify)

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/Krukov/amocrm_api",
    "name": "amocrm-api",
    "maintainer": "",
    "docs_url": null,
    "requires_python": ">=3.6",
    "maintainer_email": "",
    "keywords": "",
    "author": "Dmitry Kryukov",
    "author_email": "glebov.ru@gmail.com",
    "download_url": "https://files.pythonhosted.org/packages/8d/f0/e90b3828628ee47399b41bb967850f372c6f1071ccfb22cc551c9224b6dc/amocrm_api-2.6.1.tar.gz",
    "platform": null,
    "description": "===============================\nAmoCRM python API. V2\n===============================\n\n.. image:: https://travis-ci.org/Krukov/amocrm_api.svg?branch=master\n    :target: https://travis-ci.org/Krukov/amocrm_api\n.. image:: https://img.shields.io/coveralls/Krukov/amocrm_api.svg\n    :target: https://coveralls.io/r/Krukov/amocrm_api\n\n\nPython AmoCRM API v2 (http://www.amocrm.ru/) (human interface for easy using)\n\n\nInstallation\n============\n\n::\n\n    pip install amocrm_api\n\nUsage\n=====\n\n\u0410\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u044f\n-----------\n\n\u0410\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u044f - \u0441 \u0418\u044e\u043d\u044f 2020 amoCRM \u0444\u043e\u0440\u0441\u0438\u0440\u043e\u0432\u0430\u043b\u0430 \u0441\u043c\u0435\u043d\u0443 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438 \u0441 \u0442\u043e\u043a\u0435\u043d\u0430 \u043d\u0430 OAuth\n\n\u0418 \u0431\u0435\u0437 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0438 server to server \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f, \u0432 \u0441\u0432\u044f\u0437\u0438 \u0441 \u0447\u0435\u043c \u0442\u0435\u043a\u0443\u0449\u0430\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f\n\n1. \u0412 \u043b\u0438\u0447\u043d\u043e\u043c \u043a\u0430\u0431\u0438\u043d\u0435\u0442\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044e\n2. \u0420\u0435\u0444\u0440\u0435\u0448 \u0442\u043e\u043a\u0435\u043d \u043e\u0434\u043d\u043e\u0440\u0430\u0437\u043e\u0432\u044b\u0439 \u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u0440\u0438 \u043a\u0430\u0436\u0434\u043e\u043c \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0438 \u0430\u043a\u0441\u0435\u0441\u0441 \u0442\u043e\u043a\u0435\u043d\u0430\n3. Ec\u043b\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u0432 amoCRM \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u044f\u0442 \u0440\u0435\u0436\u0435 \u0447\u0435\u043c \u0432\u0440\u0435\u043c\u044f \u0436\u0438\u0437\u043d\u0438 \u0440\u0435\u0444\u0440\u0435\u0448 \u0442\u043e\u043a\u0435\u043d\u0430 \u0442\u043e \u0432\u0430\u043c \u043d\u0435 \u043f\u043e\u0434\u043e\u0439\u0434\u0435\u0442 \u0442\u0430\u043a\u043e\u0439 \u0432\u0430\u0440\u0430\u043d\u0442 \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u0438\n4. \u0422\u043e\u043a\u0435\u043d\u044b \u043d\u0443\u0436\u043d\u043e \u0445\u0440\u0430\u043d\u0438\u0442\u044c, \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0435\u0441\u0442\u044c api \u0438 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 3 \u0442\u0438\u043f\u0430 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430 (\u043c\u043e\u0436\u043d\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0432\u043e\u0439):\n\n- MemoryTokensStorage - \u0445\u0440\u0430\u043d\u0438\u0442 \u0442\u043e\u043a\u0435\u043d\u044b \u0432 \u043f\u0430\u043c\u044f\u0442\u0438 (\u0435\u0441\u043b\u0438 \u0432\u044b \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0442\u043e \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u0441\u043d\u043e\u0432\u0430 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c refresh_token)\n- FileStorage - \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442 \u0442\u043e\u043a\u0435\u043d\u044b \u0432 \u0444\u0430\u0439\u043b\u0435\n- RedisTokensStorage - \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442 \u0442\u043e\u043a\u0435\u043d\u044b \u0432 \u0440\u0435\u0434\u0438\u0441\u0435 (pip install redis) \u0434\u043b\u044f new-age \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442 \u0432 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u0430\u0445\n\nExample::\n\n    from amocrm.v2 import tokens\n\n    tokens.default_token_manager(\n        client_id=\"xxx-xxx-xxxx-xxxx-xxxxxxx\",\n        client_secret=\"xxxx\",\n        subdomain=\"subdomain\",\n        redirect_url=\"https://xxxx/xx\",\n        storage=tokens.FileTokensStorage(),  # by default FileTokensStorage\n    )\n    tokens.default_token_manager.init(code=\"..very long code...\", skip_error=True)\n\n\n- \u041a\u043e\u043d\u0442\u0430\u043a\u0442 - Contact\n- \u041a\u043e\u043c\u043f\u0430\u043d\u0438\u044f  - Company\n- \u0422\u0435\u0433\u0438 - Tags\n- \u0421\u0434\u0435\u043b\u043a\u0430 - Lead\n- \u0417\u0430\u0434\u0430\u0447\u0430 - Task\n- \u041f\u0440\u0438\u043c\u0435\u0447\u0430\u043d\u0438\u0435 - Note\n- \u0421\u043e\u0431\u044b\u0442\u0438\u0435 - Event\n- \u0412\u043e\u0440\u043e\u043d\u043a\u0438 \u0438 \u0421\u0442\u0430\u0442\u0443\u0441\u044b - Pipeline, Status\n\n\u0420\u0430\u0431\u043e\u0442\u0430 \u0441 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044f\u043c\u0438\n--------------------\n\n\u0423 \u043a\u0430\u0436\u0434\u043e\u0439 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438 \u0435\u0441\u0442\u044c \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440 (\u0430\u0442\u0442\u0440\u0438\u0431\u0443\u0442 objects), \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0438\u043c\u0435\u0435\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u043c\u0435\u0442\u043e\u0434\u044b\n\n::\n\n    <Entity>.objects.get(object_id=1, query=\"test\")  # \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u043e\u0431\u044c\u0435\u043a\u0442\u0430\n    <Entity>.objects.all()  # \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0432\u0441\u0435\u0445 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439\n    <Entity>.objects.filter(**kwargs)  # \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0441\u043f\u0438\u0441\u043a\u0430 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439 \u0441 \u0444\u0438\u043b\u044c\u0442\u0440\u043e\u043c\n\n    <Entity>.objects.create(**kwargs)  # \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438 (\u043d\u0435\u0442 \u044f\u0432\u043d\u043e\u0439 \u0441\u0438\u0433\u043d\u0430\u0442\u0443\u0440\u044b \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043b\u0443\u0447\u0448\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043c\u0435\u0442\u043e\u0434 create \u0441\u0430\u043c\u043e\u0439 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438)\n    <Entity>.objects.update(**kwargs)  # \u043e\u0431\u043d\u043e\u0441\u043b\u0435\u043d\u0438\u0435 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438 (\u043d\u0435\u0442 \u044f\u0432\u043d\u043e\u0439 \u0441\u0438\u0433\u043d\u0430\u0442\u0443\u0440\u044b \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043b\u0443\u0447\u0448\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043c\u0435\u0442\u043e\u0434 update \u0441\u0430\u043c\u043e\u0439 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438)\n\n\u0412 \u0441\u0432\u043e\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u0441\u0430\u043c\u0430 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044c \u0438\u043c\u0435\u0435\u0442 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043c\u0435\u0442\u043e\u0434\u043e\u0432 \u0434\u043b\u044f \u0431\u043e\u043b\u0435\u0435 \u043f\u0440\u043e\u0441\u0442\u043e\u0433\u043e \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f\n\n::\n\n    <EntityInstance>.create()\n    <EntityInstance>.update()\n    <EntityInstance>.save()  # \u0441\u043e\u0437\u0434\u0430\u0441\u0442 \u0438\u043b\u0438 \u043e\u0431\u043d\u043e\u0432\u0438\u0442 \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0442\u043e\u0433\u043e \u043a\u0430\u043a \u043e\u0431\u044c\u0435\u043a\u0442 \u0431\u044b\u043b \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\n\n\u0418\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 - \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0437\u0432\u043e\u043d\u043a\u0430 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0447\u0435\u0440\u0435\u0437 \u0443\u043f\u0440\u043e\u0448\u0435\u043d\u043d\u0443\u044e \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044c\n::\n\n    from amocrm.v2 import Call, CallDirection, CallStatus\n\n    Call().create(CallDirection.OUTBOUNT, phone=\"....\", source=\"\", duration=timedelta(minutes=10), status=CallStatus.CALL_LATER, created_by=manager)\n\n\n\u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043f\u043e\u043b\u043d\u044b\u0439 \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0440\u0430\u0431\u043e\u0442\u044b \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u043a\u043e\u043d\u0442\u0430\u043a\u0442\u0430\n\n::\n\n    from amocrm.v2 import Contact, Company\n\n    contact = Contact.objects.get(query=\"\u0422\u0435\u0441\u0442\")\n    print(contact.first_name)\n    print(contact.company.name)\n    print(contact.created_at)\n\n    contact.last_name = \"\u041d\u043e\u0432\u043e\u0435\"\n    contact.tags.append(\"new\")\n    contact.notes.objects.create(text=\"\u041f\u0440\u0438\u043c\u0435\u0447\u0430\u043d\u0438\u0435\")\n\n    contact.save()\n\n    contact.company = Company(name=\"Amocrm\")  # \u0441\u043e\u0437\u0434\u0430\u0441\u0442 \u0438 \u0441\u0440\u0430\u0437\u0443 \u043f\u0440\u0438\u043b\u0438\u043d\u043a\u0443\u0435\u0442 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u044e\n    print(contact.company.id)\n\n    len(list(contact.customers)) # lazy list\n    contact.customers.append(Customer(name=\"Volta\"))\n\n\n\u041a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u0435 \u043f\u043e\u043b\u044f\n--------------\n\n\u041e\u0434\u043d\u0430 \u0438\u0437 \u0443\u0434\u043e\u0431\u043d\u044b\u0445 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0435\u0439 amoCRM  - \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u0435 \u043f\u043e\u043b\u044f\n\nExample::\n\n    from amocrm.v2 import Lead as _Lead, custom_field\n\n    class Lead(_Lead):\n        utm = custom_field.UrlCustomField(\"UTM \u043c\u0435\u0442\u043a\u0430\")\n        delivery_type = custom_field.SelectCustomField(\"\u0421\u043f\u043e\u0441\u043e\u0431 \u0434\u043e\u0441\u0442\u0430\u0432\u043a\u0438\")\n        address = custom_field.TextCustomField(\"\u0410\u0434\u0440\u0435\u0441\")\n\n\n\u041e\u0434\u043d\u0430\u043a\u043e \u043c\u0430\u043f\u0438\u043d\u0433 \u0432\u0441\u0435\u0445 \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u0445 \u043f\u043e\u043b\u0435\u0439 \u0434\u0435\u043b\u043e \u0443\u0442\u043e\u043c\u0438\u043d\u0435\u0442\u043b\u044c\u043d\u043e\u0435,\n\u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0434\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u0444\u0430\u0439\u043b\u0430 \u0441 \u0433\u043e\u0442\u043e\u0432\u044b\u043c \u043c\u0430\u043f\u0438\u043d\u0433\u043e\u043c \u0435\u0441\u0442\u044c \u043a\u043e\u043c\u0430\u043d\u0434\u0430::\n\n    export AMOCRM_CLIENT_ID=xxx\n    export AMOCRM_SECRET=xxx\n    export AMOCRM_SUBDOMAIN=xxx\n    export AMOCRM_REDIRECT_URL=xxx\n    export AMOCRM_CODE=xxx # optional\n    pyamogen > models.py\n\n\u0414\u043b\u044f \u0435\u0435 \u0440\u0430\u0431\u043e\u0442\u044b \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u043f\u0430\u043a\u0435\u0442 python-slugify (https://github.com/un33k/python-slugify)\n",
    "bugtrack_url": null,
    "license": "MIT license",
    "summary": "Python API for Amocrm",
    "version": "2.6.1",
    "project_urls": {
        "Download": "https://github.com/Krukov/amocrm_api/tarball/2.6.1",
        "Homepage": "https://github.com/Krukov/amocrm_api"
    },
    "split_keywords": [],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "f2d1858e7d8a50e343d1025f31eec929f1b0bd1b8a8a17906ec5d43f3cdb5063",
                "md5": "cd830c20565ee4c2b5a67b8b58f3150c",
                "sha256": "bede2e1b51dbcd5043509f8930bb72ba50fe070283754777089abf8c0c7766a6"
            },
            "downloads": -1,
            "filename": "amocrm_api-2.6.1-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "cd830c20565ee4c2b5a67b8b58f3150c",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.6",
            "size": 28172,
            "upload_time": "2023-06-27T05:41:51",
            "upload_time_iso_8601": "2023-06-27T05:41:51.971583Z",
            "url": "https://files.pythonhosted.org/packages/f2/d1/858e7d8a50e343d1025f31eec929f1b0bd1b8a8a17906ec5d43f3cdb5063/amocrm_api-2.6.1-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "8df0e90b3828628ee47399b41bb967850f372c6f1071ccfb22cc551c9224b6dc",
                "md5": "faf3129965df2cac43849fca7eefe8e7",
                "sha256": "a5b1ef61f1d4235eac07fb4f02792c0f03f4a1edd80888cda16f9b966bf5a61f"
            },
            "downloads": -1,
            "filename": "amocrm_api-2.6.1.tar.gz",
            "has_sig": false,
            "md5_digest": "faf3129965df2cac43849fca7eefe8e7",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.6",
            "size": 23249,
            "upload_time": "2023-06-27T05:41:53",
            "upload_time_iso_8601": "2023-06-27T05:41:53.514859Z",
            "url": "https://files.pythonhosted.org/packages/8d/f0/e90b3828628ee47399b41bb967850f372c6f1071ccfb22cc551c9224b6dc/amocrm_api-2.6.1.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2023-06-27 05:41:53",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "Krukov",
    "github_project": "amocrm_api",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "amocrm-api"
}
        
Elapsed time: 0.18005s