Search 1.9 billion lines of Odoo code on GitHub

restful

Author: Babatope Ajepe
License: LGPL-3
Branch: 12.0
Repository: ajepe/odoo-addons
Dependencies: base, and web
Languages: HTML (14, 1.8%), Markdown (301, 37.7%), Python (411, 51.4%), XML (50, 6.3%), and reStructuredText (23, 2.9%)
Other branches: 10.0, 11.0, 13.0, 14.0, 15.0, master, and sola
Other repositories: Bedo1212/odoo-addons, Coding-Squad/odoo-addons, Jaquedeveloper/odoo-addons, Rodasac/odoo-addons, akurey/ajepe-odoo-addons, cialuo/odoo-addons-3, cnkenny/odoo-addons, consultingerp/odoo_redis_session_storage, elmosolutions/odoo-addons, haylahi/odoo-addons-6, latera/odoo-restful, leodoooca/odoo-addons, niulinlnc/odoo-addons-1, scbrianti/odoo-addons-2, sspankaj/odoo-addons, thinkwelltwd/odoo-addons, wahello/ajepe-odoo-addons, wahhid/odoo-addons, wbsouza/odoo-addons-1, and wuhuizhong/odoo-addons

<h1>AUTHENTICATION</h1> <ul> <li>login </li> <li>logout</li> </ul> <p>In order to be able to access any document an access token needs to generated which serves as session cookies in a regular web language. The token will <strong>be needed</strong> for every subsequent requests. Except for <em>/api/auth/token</em> enpoint that accept <strong>multipart/form-data</strong> as the Content type every other endpoints accept application/json as the &#39;Content Type&#39;</p> <h2>Request for access token(login)</h2> <p><code>bash curl --request GET --url http://192.168.43.58:8069/api/auth/token --form db=api.ng --form login=admin --form password=admin </code> Example using python</p> <p><code>python </code>python import requests</p> <p>url = &quot;http://192.168.43.58:8069/api/auth/token&quot;</p> <p>payload = { &quot;db&quot;:&quot;api.ng&quot;, &quot;login&quot;: &quot;admin&quot;, &quot;password&quot;: &quot;admin&quot; }</p> <p>headers = { &#39;content-type&#39;: &quot;multipart/form-data; &#39;access-token&#39;: &quot;access<em>token</em>ebb1914bbdb5622cd782a1a0ff51f81a2cba042a&quot; }</p> <p>response = requests.request(&quot;GET&quot;, url, data=payload, headers=headers)</p> <p>print(response.text) <code> </code> To retrive an access token these following parameters needs to be set. * the database name as <strong>db</strong> * the connecting username as <strong>login</strong> * the user password as <strong>password</strong> The above request will return a response like below. <code>python { &quot;uid&quot;: 2, &quot;user_context&quot;: { &quot;lang&quot;: &quot;en_US&quot;, &quot;tz&quot;: &quot;Europe/Brussels&quot;, &quot;uid&quot;: 2 }, &quot;company_id&quot;: 1, &quot;company_ids&quot;: [ 1 ], &quot;partner_id&quot;: 3, &quot;access_token&quot;: &quot;access_token_ebb1914bbdb5622cd782a1a0ff51f81a2cba042a&quot;, &quot;expires_in&quot;: &quot;31536000&quot; } </code> The most interesting part of the response is the access token field, <em>access<em>token</em>ebb1914bbdb5622cd782a1a0ff51f81a2cba042a</em> for every other request the token should to be send along the request headers else an invalid token response will be generated.</p> <h2>Logout</h2> <p>To logout of the system the token needs to be destroyed i.e deleted, by doing that the user/application making the request on behalf of the user will have not futher access to Odoo. The token <em>/api/auth/token</em> listen to both <strong>GET</strong> and <strong>DELETE</strong> requests, GET will fetch the token while delete request will deleted the token. ```python import requests</p> <p>url = &quot;http://192.168.43.58:8069/api/auth/token&quot;</p> <p>payload = { &quot;db&quot;:&quot;api.ng&quot;, &quot;login&quot;: &quot;admin&quot;, &quot;password&quot;: &quot;admin&quot; }</p> <p>headers = { &#39;content-type&#39;: &quot;multipart/form-data; &#39;access-token&#39;: &quot;access<em>token</em>ebb1914bbdb5622cd782a1a0ff51f81a2cba042a&quot; }</p> <p>response = requests.request(&quot;DELETE&quot;, url, data=payload, headers=headers)</p> <p>print(response.text) ```</p> <h1>Sales</h1> <p>To get or fetch existing sale order ```python import requests</p> <p>url = &quot;http://192.168.43.58:8069/api/sale.order&quot;</p> <p>payload = &quot;{ &quot;limit&quot;: 2, &quot;fields&quot;: &quot;[&#39;id&#39;, &#39;partner_id&#39;, &#39;name&#39;]&quot;, &quot;domain&quot;:&quot;[(&#39;id&#39;, &#39;in&#39;, [10,11,12,13,14])]&quot;, &quot;offset&quot;:0 }&quot;</p> <p>headers = { &#39;access-token&#39;: &quot;access<em>token</em>79406d541ea0a79a942e19871a9c806236d5638c&quot;, &#39;content-type&#39;: &quot;application/json&quot; }</p> <p>response = requests.request(&quot;GET&quot;, url, data=payload, headers=headers)</p> <p>print(response.text) ``` There is posibilty of applying some record filters in order to get just the specific record. * limit: This define the total number of record we are expecting * offset: where the query will start from * fields: this is the list of field that we wanted to return, this can be leave empty if we wanted to return all the fields. * domain: domain is like a filter it is always a list of tuples <em>(field, operator, value)</em></p> <p>These payload applies to all records in Odoo.</p> <p>We can perform create, update and delete operation on any records using corresponding HTTP request headers.</p> <p><strong>GET</strong>: For retriving existing records <strong>POST</strong>: For creating new records <strong>PATCH</strong>: Call an action button on a record <strong>DELETE</strong>: To delete a record</p> <p>All the API of currently installed modules or any module that may be installed has already cattered for dynamically. The API follows this sematic pattern</p> <p><strong>/api{api route}/modelP{model name}/id{optional id for delete request}</strong> e.g for sale order Get request to <strong>api/sale.order</strong> endpoint will return all the sale order in the system.</p> <h1>Sale Order</h1> <ul> <li>GET Request ```python import requests</li> </ul> <p>url = &quot;http://192.168.43.58:8069/api/sale.order&quot;</p> <p>payload = &quot;{}&quot; headers = { &#39;content-type&#39;: &quot;application/json&quot; }</p> <p>response = requests.request(&quot;GET&quot;, url, data=payload, headers=headers)</p> <p>print(response.text) <code> * Response </code>python { &quot;count&quot;: 1, &quot;data&quot;: [ { &quot;id&quot;: 30, &quot;name&quot;: &quot;SO029&quot;, &quot;origin&quot;: false, &quot;client<em>order</em>ref&quot;: false, &quot;reference&quot;: false, &quot;state&quot;: &quot;draft&quot;, &quot;date<em>order&quot;: &quot;2020-06-30T20:58:48.269652&quot;, &quot;validity</em>date&quot;: false, &quot;require<em>signature&quot;: true, &quot;require</em>payment&quot;: true, &quot;create<em>date&quot;: &quot;2020-06-30T20:58:39.806639&quot;, &quot;confirmation</em>date&quot;: false, &quot;user<em>id&quot;: [ 6, &quot;Marc Demo&quot; ], &quot;partner</em>id&quot;: [ 11, &quot;Gemini Furniture&quot; ], &quot;partner<em>invoice</em>id&quot;: [ 31, &quot;Gemini Furniture, Oscar Morgan&quot; ], &quot;partner<em>shipping</em>id&quot;: [ 31, &quot;Gemini Furniture, Oscar Morgan&quot; ], &quot;pricelist<em>id&quot;: [ 1, &quot;Public Pricelist (USD)&quot; ], &quot;analytic</em>account<em>id&quot;: false, &quot;order</em>line&quot;: [ 55 ], &quot;invoice<em>status&quot;: &quot;no&quot;, &quot;note&quot;: &quot;&quot;, &quot;amount</em>untaxed&quot;: 33.0, &quot;amount<em>tax&quot;: 0.0, &quot;amount</em>total&quot;: 33.0, &quot;currency<em>rate&quot;: 1.5289, &quot;payment</em>term<em>id&quot;: false, &quot;fiscal</em>position<em>id&quot;: false, &quot;company</em>id&quot;: [ 1, &quot;YourCompany&quot; ], &quot;team<em>id&quot;: [ 2, &quot;Website&quot; ], &quot;signature&quot;: false, &quot;signed</em>by&quot;: false, &quot;commitment<em>date&quot;: false, &quot;transaction</em>ids&quot;: [], &quot;cart<em>recovery</em>email<em>sent&quot;: false, &quot;website</em>id&quot;: false, &quot;campaign<em>id&quot;: false, &quot;source</em>id&quot;: false, &quot;medium<em>id&quot;: false, &quot;activity</em>ids&quot;: [], &quot;message<em>follower</em>ids&quot;: [ 167, 168 ], &quot;message<em>ids&quot;: [ 218, 217 ], &quot;message</em>main<em>attachment</em>id&quot;: false, &quot;website<em>message</em>ids&quot;: [], &quot;access<em>token&quot;: false, &quot;create</em>uid&quot;: [ 1, &quot;OdooBot&quot; ], &quot;write<em>uid&quot;: [ 1, &quot;OdooBot&quot; ], &quot;write</em>date&quot;: &quot;2020-06-30T20:58:39.806639&quot;, &quot;is<em>expired&quot;: false, &quot;remaining</em>validity<em>days&quot;: 0, &quot;currency</em>id&quot;: [ 2, &quot;USD&quot; ], &quot;invoice<em>count&quot;: 0, &quot;invoice</em>ids&quot;: [], &quot;amount<em>by</em>group&quot;: [], &quot;expected<em>date&quot;: &quot;2020-07-03T06:54:53&quot;, &quot;amount</em>undiscounted&quot;: 33.0, &quot;type<em>name&quot;: &quot;Quotation&quot;, &quot;authorized</em>transaction<em>ids&quot;: [], &quot;website</em>order<em>line&quot;: [ 55 ], &quot;cart</em>quantity&quot;: 2, &quot;only<em>services&quot;: false, &quot;is</em>abandoned<em>cart&quot;: true, &quot;activity</em>state&quot;: false, &quot;activity<em>user</em>id&quot;: false, &quot;activity<em>type</em>id&quot;: false, &quot;activity<em>date</em>deadline&quot;: false, &quot;activity<em>summary&quot;: false, &quot;message</em>is<em>follower&quot;: false, &quot;message</em>partner<em>ids&quot;: [ 2, 7 ], &quot;message</em>channel<em>ids&quot;: [], &quot;message</em>unread&quot;: false, &quot;message<em>unread</em>counter&quot;: 0, &quot;message<em>needaction&quot;: false, &quot;message</em>needaction<em>counter&quot;: 0, &quot;message</em>has<em>error&quot;: false, &quot;message</em>has<em>error</em>counter&quot;: 0, &quot;message<em>attachment</em>count&quot;: 0, &quot;access<em>url&quot;: &quot;/my/orders/30&quot;, &quot;access</em>warning&quot;: &quot;&quot;, &quot;display<em>name&quot;: &quot;SO029&quot;, &quot;</em><em>last</em>update&quot;: &quot;2020-06-30T20:58:39.806639&quot; } ] } <code> The reponse with all the fields, but the return fields can specified along side the request, and also, specific records can be specified by sending along the request Odoo domain as json body. </code>python {&quot;limit&quot;: 2, &quot;fields&quot;: &quot;[&#39;id&#39;, &#39;partner_id&#39;, &#39;name&#39;]&quot;, &quot;domain&quot;:&quot;[(&#39;id&#39;, &#39;in&#39;, [10,11,12,13,14])]&quot;, &quot;offset&quot;:0} ``` The above will only return <strong>2</strong> maximum records, id, partner and sale order name, that have an ID in the given list [10,11,12,13,14], the offset can be set also.</p> <ul> <li>POST (Create Sale Order) ```python import requests</li> </ul> <p>url = &quot;http://192.168.43.58:8069/api/sale.order&quot;</p> <p>payload = {&#39;partner<em>id&#39;: 10, &#39;</em><em>api</em><em>order</em>line&#39;:[(0, 0, {&#39;product<em>id&#39;: 1,&#39;price</em>unit&#39;:4000})]&quot;} headers = { &#39;content-type&#39;: &quot;application/json&quot;, &#39;access-token&#39;: &quot;access<em>token</em>79406d541ea0a79a942e19871a9c806236d5638c&quot; }</p> <p>response = requests.request(&quot;POST&quot;, url, data=payload, headers=headers)</p> <p>print(response.text)</p> <p>``` Note the <strong><strong>api</strong></strong>order<em>line the bolded part. The _</em>api__ is a shortcut (instead of created the line item separately from the main record), it is a way of telling the system that an order line or line Items is being created from an api endpoint. <strong>order_line</strong> is the One2many field that line sale order and order line together.</p> <blockquote> <p>This pattern is applicable to other models</p> </blockquote> <ul> <li>PATCH REQUEST Path request is meant for calling an action button on a record. e.g validating sale order.</li> </ul> <p>```python import requests</p> <p>url = &quot;http://192.168.43.58:8069/api/sale.order/37&quot;</p> <p>payload = {&quot;<em>method&quot;:&quot;action</em>confirm&quot;} headers = { &#39;content-type&#39;: &quot;application/json&quot;, &#39;access-token&#39;: &quot;access<em>token</em>79406d541ea0a79a942e19871a9c806236d5638c&quot; }</p> <p>response = requests.request(&quot;PATCH&quot;, url, data=payload, headers=headers)</p> <p>print(response.text) ``` In the above request, we send a json body like this <strong>{&quot;<em>method&quot;:&quot;action</em>confirm&quot;}</strong> The <strong>_method</strong> is the action/button name in odoo. This is similar to clicking <em>Confirm</em> Button on sale order with ID <strong>37</strong></p> <ul> <li>DELETE SALE ORDER ```python import requests</li> </ul> <p>url = &quot;http://192.168.43.58:8069/api/sale.order/37&quot;</p> <p>payload = &quot;{}&quot; headers = { &#39;content-type&#39;: &quot;application/json&quot;, &#39;access-token&#39;: &quot;access<em>token</em>79406d541ea0a79a942e19871a9c806236d5638c&quot; }</p> <p>response = requests.request(&quot;DELETE&quot;, url, data=payload, headers=headers)</p> <p>print(response.text) ``` We only need to make a delete request to the resource.</p>