Зовнішній API

Odoo зазвичай розширюється внутрішньо за допомогою модулів, але багато його функцій і всі його дані також доступні ззовні для зовнішнього аналізу або інтеграції з різними інструментами. Частина API Моделі легко доступна через XML-RPC і доступна з різних мов.

Важливо

Starting with PHP8, the XML-RPC extension may not be available by default. Check out the manual for the installation steps.

Примітка

Access to data via the external API is only available on Custom Odoo pricing plans. Access to the external API is not available on One App Free or Standard plans. For more information visit the Odoo pricing page or reach out to your Customer Success Manager.

Перегляньте також

Підключення

Налаштування

Якщо у вас уже встановлено сервер Odoo, ви можете просто скористатися його параметрами.

Важливо

Для екземплярів Odoo Online (<domain>.odoo.com) користувачі створюються без локального пароля (ви входите в систему через систему автентифікації Odoo Online, а не через сам екземпляр). Щоб використовувати XML-RPC в екземплярах Odoo Online, вам потрібно буде встановити пароль для облікового запису користувача, який ви хочете використовувати:

  • Увійдіть у свій екземпляр за допомогою облікового запису адміністратора.

  • Перейдіть до Налаштування ‣ Користувачі та компанії ‣ Користувачі.

  • Клацніть користувача, якого ви хочете використовувати для доступу до XML-RPC.

  • Натисніть Дія і виберіть Змінити пароль.

  • Встановіть значення Новий пароль, а потім натисніть Змінити пароль.

URL-адреса сервера - це домен примірника (наприклад, https://mycompany.odoo.com), назва бази даних - це назва примірника (наприклад, mycompany). Ім’я користувача - це налаштоване ім’я користувача, як показано на екрані Змінити пароль.

url = <insert server URL>
db = <insert database name>
username = 'admin'
password = <insert password for your admin user (default: admin)>

API ключі

Нове в версії 14.0.

Odoo підтримує ключі API і (залежно від модулів або налаштувань) може вимагати ці ключі для виконання операцій веб-сервісу.

Щоб використовувати ключі API у своїх сценаріях, просто замініть свій пароль на ключ. Логін залишається у використанні. Ви повинні зберігати ключ API так само ретельно, як і пароль, оскільки вони, по суті, надають той самий доступ до вашого облікового запису користувача (хоча їх не можна використовувати для входу через інтерфейс).

Щоб додати ключ до свого облікового запису, просто перейдіть у Налаштування (або Мій профіль):

../../_images/preferences.png

потім відкрийте вкладку Безпека облікового запису і натисніть Новий ключ API:

../../_images/account-security1.png

Введіть опис ключа, цей опис має бути максимально чітким і повним: це єдиний спосіб пізніше ідентифікувати ваші ключі та знати, чи слід їх видалити чи залишити.

Натисніть Створити ключ, а потім скопіюйте наданий ключ. Зберігайте цей ключ обережно: він еквівалентний вашому паролю, і так само, як і ваш пароль, система не зможе відновити чи показати ключ пізніше. Якщо ви втратите цей ключ, вам доведеться створити новий (і, можливо, видалити той, який ви втратили).

Після налаштування ключів у вашому обліковому записі вони з’являться над кнопкою Новий ключ API, і ви зможете їх видалити:

../../_images/delete-key.png

Видалений ключ API не можна відновити або відновити. Вам доведеться створити новий ключ і оновити всі місця, де ви використовували старий.

Тестова база даних

Щоб спростити дослідження, ви також можете запитати на https://demo.odoo.com тестову базу даних:

import xmlrpc.client
info = xmlrpc.client.ServerProxy('https://demo.odoo.com/start').start()
url, db, username, password = info['host'], info['database'], info['user'], info['password']

Вхід в систему

Odoo вимагає, щоб користувачі API пройшли автентифікацію, перш ніж вони зможуть запитувати більшість даних.

Кінцева точка xmlrpc/2/common забезпечує мета-виклики, які не потребують автентифікації, як-от сама автентифікація чи отримання інформації про версію. Щоб переконатися, що інформація про підключення правильна перед спробою автентифікації, найпростішим викликом є запит на версію сервера. Сама автентифікація виконується за допомогою функції authenticate і повертає ідентифікатор користувача (uid), який використовується в автентифікованих викликах замість логіна.

common = xmlrpc.client.ServerProxy('{}/xmlrpc/2/common'.format(url))
common.version()

Результат:

{
    "server_version": "13.0",
    "server_version_info": [13, 0, 0, "final", 0],
    "server_serie": "13.0",
    "protocol_version": 1,
}
uid = common.authenticate(db, username, password, {})

Методи виклику

Другою кінцевою точкою є xmlrpc/2/object. Він використовується для виклику методів моделей odoo через функцію RPC execute_kw.

Кожен виклик execute_kw приймає такі параметри:

  • база даних для використання, рядок

  • id користувача (отриманий через authenticate), ціле число

  • пароль користувача, рядок

  • назва моделі, рядок

  • назва методу, рядок

  • масив/список параметрів, що передаються за позицією

  • зіставлення/словник параметрів для передачі за ключовим словом (необов’язково)

Example

Наприклад, щоб побачити, чи можемо ми прочитати модель res.partner, ми можемо викликати check_access_rights з operation, переданим позицією, і raise_exception, переданим ключовим словом (щоб отримати результат істина/неправда, а не істина/помилка):

models = xmlrpc.client.ServerProxy('{}/xmlrpc/2/object'.format(url))
models.execute_kw(db, uid, password, 'res.partner', 'check_access_rights', ['read'], {'raise_exception': False})

Результат:

true

Список записів

Записи можна перераховувати та фільтрувати за допомогою search().

search() використовує обов’язковий фільтр domain (можливо, порожній) і повертає ідентифікатори бази даних усіх записів, які відповідають фільтру.

Example

Щоб перерахувати компанії-клієнти, наприклад:

models.execute_kw(db, uid, password, 'res.partner', 'search', [[['is_company', '=', True]]])

Результат:

[7, 18, 12, 14, 17, 19, 8, 31, 26, 16, 13, 20, 30, 22, 29, 15, 23, 28, 74]

Розбиття на сторінки

За замовчуванням пошук повертає ідентифікатори всіх записів, які відповідають умові, яких може бути величезна кількість. Параметри offset і limit доступні для отримання лише підмножини всіх відповідних записів.

Example

models.execute_kw(db, uid, password, 'res.partner', 'search', [[['is_company', '=', True]]], {'offset': 10, 'limit': 5})

Результат:

[13, 20, 30, 22, 29]

К-сть записів

Замість того, щоб отримати, можливо, гігантський список записів і підрахувати їх, search_count() можна використовувати для отримання лише кількості записів, які відповідають запиту. Він використовує той самий фільтр domain, що й search() і жодних інших параметрів.

Example

models.execute_kw(db, uid, password, 'res.partner', 'search_count', [[['is_company', '=', True]]])

Результат:

19

Примітка

Виклик search, а потім search_count (або навпаки) може не дати узгоджених результатів, якщо інші користувачі використовують сервер: збережені дані могли змінитися між викликами.

Читайте записи

Дані записів доступні за допомогою методу read(), який приймає список ідентифікаторів (як повертає search()) і, за бажанням, список полів для отримання. За замовчуванням він отримує всі поля, які поточний користувач може прочитати, а це, як правило, величезна кількість.

Example

ids = models.execute_kw(db, uid, password, 'res.partner', 'search', [[['is_company', '=', True]]], {'limit': 1})
[record] = models.execute_kw(db, uid, password, 'res.partner', 'read', [ids])
# count the number of fields fetched by default
len(record)

Результат:

121

І навпаки, вибір лише трьох полів вважається цікавим.

models.execute_kw(db, uid, password, 'res.partner', 'read', [ids], {'fields': ['name', 'country_id', 'comment']})

Результат:

[{"comment": false, "country_id": [21, "Belgium"], "id": 7, "name": "Agrolait"}]

Примітка

Навіть якщо поле id не запитується, воно завжди повертається.

Список полів запису

fields_get() можна використовувати для перевірки полів моделі та перевірки, які з них представляють інтерес.

Оскільки він повертає велику кількість метаінформації (вона також використовується клієнтськими програмами), її слід відфільтрувати перед друком. Найцікавішими елементами для користувача є string (мітка поля), ``help` ` (текст довідки, якщо доступний) і `` type `` (щоб знати, які значення очікувати або надсилати під час оновлення запису).

Example

models.execute_kw(db, uid, password, 'res.partner', 'fields_get', [], {'attributes': ['string', 'help', 'type']})

Результат:

{
    "ean13": {
        "type": "char",
        "help": "BarCode",
        "string": "EAN13"
    },
    "property_account_position_id": {
        "type": "many2one",
        "help": "The fiscal position will determine taxes and accounts used for the partner.",
        "string": "Fiscal Position"
    },
    "signup_valid": {
        "type": "boolean",
        "help": "",
        "string": "Signup Token is Valid"
    },
    "date_localization": {
        "type": "date",
        "help": "",
        "string": "Geo Localization Date"
    },
    "ref_company_ids": {
        "type": "one2many",
        "help": "",
        "string": "Companies that refers to partner"
    },
    "sale_order_count": {
        "type": "integer",
        "help": "",
        "string": "# of Sales Order"
    },
    "purchase_order_count": {
        "type": "integer",
        "help": "",
        "string": "# of Purchase Order"
    },

Пошук і читання

Оскільки це дуже поширене завдання, Odoo надає ярлик search_read(), який, як випливає з назви, еквівалентний search() за допомогою read(), але уникає необхідності виконувати два запити та зберігати ідентифікатори.

Його аргументи подібні до аргументів search(), але він також може приймати список fields (наприклад read(), якщо цей список не надано, він отримає всі поля відповідних записів).

Example

models.execute_kw(db, uid, password, 'res.partner', 'search_read', [[['is_company', '=', True]]], {'fields': ['name', 'country_id', 'comment'], 'limit': 5})

Результат:

[
    {
        "comment": false,
        "country_id": [ 21, "Belgium" ],
        "id": 7,
        "name": "Agrolait"
    },
    {
        "comment": false,
        "country_id": [ 76, "France" ],
        "id": 18,
        "name": "Axelor"
    },
    {
        "comment": false,
        "country_id": [ 233, "United Kingdom" ],
        "id": 12,
        "name": "Bank Wealthy and sons"
    },
    {
        "comment": false,
        "country_id": [ 105, "India" ],
        "id": 14,
        "name": "Best Designers"
    },
    {
        "comment": false,
        "country_id": [ 76, "France" ],
        "id": 17,
        "name": "Camptocamp"
    }
]

Створення записів

Записи моделі створюються за допомогою create(). Метод створює один запис і повертає його ідентифікатор бази даних.

create() виконує зіставлення полів зі значеннями, які використовуються для ініціалізації запису. Для будь-якого поля, яке має значення за замовчуванням і не встановлене за допомогою аргументу зіставлення, буде використано значення за замовчуванням.

Example

id = models.execute_kw(db, uid, password, 'res.partner', 'create', [{'name': "New Partner"}])

Результат:

78

Попередження

Хоча більшість типів значень відповідають очікуванням (ціле число для Integer, рядок для Char або Text),

Оновлення записів

Записи можна оновити за допомогою write(). Потрібен список записів для оновлення та зіставлення оновлених полів зі значеннями, подібними до create().

Кілька записів можна оновлювати одночасно, але всі вони отримають однакові значення для встановлених полів. Неможливо виконати «обчислене» оновлення (де встановлене значення залежить від існуючого значення запису).

Example

models.execute_kw(db, uid, password, 'res.partner', 'write', [[id], {'name': "Newer partner"}])
# get record name after having changed it
models.execute_kw(db, uid, password, 'res.partner', 'read', [[id], ['display_name']])

Результат:

[[78, "Newer partner"]]

Видалення записів

Записи можна видаляти масово, надавши їхні ідентифікатори unlink().

Example

models.execute_kw(db, uid, password, 'res.partner', 'unlink', [[id]])
# check if the deleted record is still in the database
models.execute_kw(db, uid, password, 'res.partner', 'search', [[['id', '=', id]]])

Результат:

[]

Огляд і самоспостереження

Хоча раніше ми використовували fields_get() для запиту моделі та з самого початку використовували довільну модель, Odoo зберігає більшість метаданих моделі в кількох метамоделях, які дозволяють як запитувати систему, так і зміна моделей і полів (з деякими обмеженнями) на льоту через XML-RPC.

ir.model

Надає інформацію про моделі Odoo через різні поля.

name

зрозумілий опис моделі

model

назву кожної моделі в системі

state

чи була модель згенерована в коді Python (base) чи шляхом створення запису ir.model (manual)

field_id

список полів моделі через One2many до ir.model.fields

view_ids

One2many to the View architectures defined for the model

access_ids

One2many відношення до Права доступу набору в моделі

ir.model можна використовувати для

  • Надсилайте запит системі щодо встановлених моделей (як передумова для операцій над моделлю або для вивчення вмісту системи).

  • Отримайте інформацію про конкретну модель (зазвичай перерахувавши пов’язані з нею поля).

  • Створюйте нові моделі динамічно через RPC.

Важливо

  • Назви користувацьких моделей мають починатися з x_.

  • Необхідно вказати state і встановити значення manual, інакше модель не буде завантажено.

  • Неможливо додати нові методи до спеціальної моделі, лише поля.

Example

Спеціальна модель спочатку міститиме лише «вбудовані» поля, доступні для всіх моделей:

models.execute_kw(db, uid, password, 'ir.model', 'create', [{
    'name': "Custom Model",
    'model': "x_custom_model",
    'state': 'manual',
}])
models.execute_kw(db, uid, password, 'x_custom_model', 'fields_get', [], {'attributes': ['string', 'help', 'type']})

Результат:

{
    "create_uid": {
        "type": "many2one",
        "string": "Created by"
    },
    "create_date": {
        "type": "datetime",
        "string": "Created on"
    },
    "__last_update": {
        "type": "datetime",
        "string": "Last Modified on"
    },
    "write_uid": {
        "type": "many2one",
        "string": "Last Updated by"
    },
    "write_date": {
        "type": "datetime",
        "string": "Last Updated on"
    },
    "display_name": {
        "type": "char",
        "string": "Display Name"
    },
    "id": {
        "type": "integer",
        "string": "Id"
    }
}

ir.model.fields

Надає інформацію про поля моделей Odoo та дозволяє додавати власні поля без використання коду Python.

model_id

Many2one до ir.model, до якого належить поле

name

технічна назва поля (використовується в read або write)

field_description

зрозуміла мітка поля (наприклад, string у fields_get)

ttype

type поля для створення

state

незалежно від того, було поле створено через код Python (base) чи через ir.model.fields (manual)

required, readonly, translate

вмикає відповідний прапорець на полі

groups

контроль доступу на рівні поля, a Many2many до res.groups

selection, size, on_delete, relation, relation_field, domain

специфічні для типу властивості та налаштування див. документацію полів для деталей

Важливо

  • Подібно до спеціальних моделей, лише нові поля, створені за допомогою state="manual", активуються як фактичні поля в моделі.

  • Обчислені поля не можна додавати через ir.model.fields, деякі поля мета-інформації (за замовчуванням, onchange) також не можуть бути встановлені.

Example

id = models.execute_kw(db, uid, password, 'ir.model', 'create', [{
    'name': "Custom Model",
    'model': "x_custom",
    'state': 'manual',
}])
models.execute_kw(db, uid, password, 'ir.model.fields', 'create', [{
    'model_id': id,
    'name': 'x_name',
    'ttype': 'char',
    'state': 'manual',
    'required': True,
}])
record_id = models.execute_kw(db, uid, password, 'x_custom', 'create', [{'x_name': "test record"}])
models.execute_kw(db, uid, password, 'x_custom', 'read', [[record_id]])

Результат:

[
    {
        "create_uid": [1, "Administrator"],
        "x_name": "test record",
        "__last_update": "2014-11-12 16:32:13",
        "write_uid": [1, "Administrator"],
        "write_date": "2014-11-12 16:32:13",
        "create_date": "2014-11-12 16:32:13",
        "id": 1,
        "display_name": "test record"
    }
]