Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
566cc64
Add endpoint module
simahawk Sep 13, 2021
9701095
endpoint: add cross model constraint
simahawk Oct 14, 2021
0277dc1
endpoint: split out route handling
simahawk Oct 25, 2021
5c87594
[FIX] endpoint: fix loading of demo data
sebalix Nov 9, 2021
aa6082d
endpoint 14.0.1.0.1
OCA-git-bot Nov 9, 2021
6a76662
endpoint: add tests for archive/unarchive
simahawk Dec 28, 2021
2e4c1ab
endpoint: update tests
simahawk Dec 29, 2021
6a15ca6
endpoint: improve search/tree views
simahawk Nov 12, 2021
154ae29
endpoint 14.0.1.0.2
OCA-git-bot Jan 12, 2022
a5bc9c4
endpoint 14.0.1.1.0
OCA-git-bot Jan 12, 2022
d7f7d6a
Misc fix of authorship name
simahawk Jan 14, 2022
5ff0464
endpoint 14.0.1.1.1
OCA-git-bot Jan 14, 2022
fe1fdad
endpoint: block all RPC calls
simahawk Feb 18, 2022
e97106c
endpoint 14.0.1.3.0
OCA-git-bot Mar 11, 2022
50ecc32
endpoint: move to web-api
simahawk Jun 15, 2022
322f136
[UPD] Update endpoint.pot
Jul 15, 2022
f1b8edf
[UPD] README.rst
OCA-git-bot Jul 15, 2022
58a8569
Added translation using Weblate (French)
klodr Sep 15, 2022
921ab65
endpoint: adapt to endpoint_route_handler
simahawk Jun 15, 2022
f268fb2
endpoint: use registry_sync flag and improve tests
simahawk Jul 25, 2022
12b6a35
endpoint: adapt to new sync behavior
simahawk Jul 26, 2022
df12208
endpoint_route_handler: use sequence as version
simahawk Mar 1, 2023
142f595
endpoint: use model explicitly to find endpoints
simahawk Apr 21, 2023
2ed1598
endpoint: 14.0.2.0.0
simahawk May 11, 2023
80d7da3
[UPD] Update endpoint.pot
May 11, 2023
2cc8b78
[UPD] README.rst
OCA-git-bot May 11, 2023
03c3948
Update translation files
weblate May 11, 2023
1eb7bcd
endpoint: update ROADMAP
simahawk May 12, 2023
7927470
[UPD] README.rst
OCA-git-bot May 12, 2023
0e99c7c
endpoint 14.0.2.0.1
OCA-git-bot May 12, 2023
ba819a8
endpoint: fix duplicate
simahawk May 25, 2023
8079ff0
endpoint 14.0.2.0.2
OCA-git-bot May 25, 2023
0909379
endpoint: Migration to 16.0
JordiBForgeFlow Jun 9, 2023
52d88ce
[UPD] Update endpoint.pot
Jul 25, 2023
b0bc619
[UPD] README.rst
OCA-git-bot Jul 25, 2023
44580d5
Update translation files
weblate Jul 25, 2023
e8bb306
[UPD] README.rst
OCA-git-bot Sep 3, 2023
40e2c81
Added translation using Weblate (Italian)
mymage Nov 27, 2023
84d750e
Translated using Weblate (Italian)
mymage Nov 27, 2023
167935a
[IMP] endpoint: endpoint multi-company
JordiMForgeFlow Jun 5, 2024
ea40f36
[UPD] Update endpoint.pot
Jul 4, 2024
ac6bb34
[BOT] post-merge updates
OCA-git-bot Jul 4, 2024
81e60f0
Update translation files
weblate Jul 4, 2024
97b1600
endpoint: add log function
simahawk Jul 2, 2024
9151971
[BOT] post-merge updates
OCA-git-bot Jul 8, 2024
4492b5d
Translated using Weblate (Italian)
mymage Jul 8, 2024
76c2ade
endpoint: add basic mixin view
simahawk Jul 23, 2024
6a6bc52
[UPD] Update endpoint.pot
Jul 26, 2024
07aa12a
[BOT] post-merge updates
OCA-git-bot Jul 26, 2024
efa3710
Update translation files
weblate Jul 26, 2024
d15427a
[IMP] endpoint: pre-commit auto fixes
SilvioC2C Dec 3, 2024
98a9bef
[MIG] endpoint: Migration to 17.0
SilvioC2C Dec 3, 2024
28807ee
[UPD] Update endpoint.pot
Dec 4, 2024
960a590
[BOT] post-merge updates
OCA-git-bot Dec 4, 2024
be19819
[IMP] endpoint: pre-commit stuff
JordiMForgeFlow Dec 17, 2024
8958d8c
[MIG] endpoint: Migration to V18
JordiMForgeFlow Dec 17, 2024
e8dcc14
endpoint: add mixin views for search and list
simahawk Jan 23, 2025
5d55d62
[IMP] endpoint: don't filter for registry sync
JordiMForgeFlow Jan 31, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
105 changes: 105 additions & 0 deletions endpoint/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
========
Endpoint
========

..
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:5b9d2b71d09ff066cd8d17ae88885c36a1eca061387e2a18d62d526b4844edfc
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
:target: https://odoo-community.org/page/development-status
:alt: Beta
.. |badge2| image:: https://img.shields.io/badge/licence-LGPL--3-blue.png
:target: http://www.gnu.org/licenses/lgpl-3.0-standalone.html
:alt: License: LGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fweb--api-lightgray.png?logo=github
:target: https://github.com/OCA/web-api/tree/18.0/endpoint
:alt: OCA/web-api
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/web-api-18-0/web-api-18-0-endpoint
:alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
:target: https://runboat.odoo-community.org/builds?repo=OCA/web-api&target_branch=18.0
:alt: Try me on Runboat

|badge1| |badge2| |badge3| |badge4| |badge5|

Provide an endpoint framework allowing users to define their own custom
endpoint.

Thanks to endpoint mixin the endpoint records are automatically
registered as real Odoo routes.

You can easily code what you want in the code snippet.

NOTE: for security reasons any kind of RPC call is blocked on endpoint
records.

**Table of contents**

.. contents::
:local:

Configuration
=============

Go to "Technical -> Endpoints" and create a new endpoint.

Known issues / Roadmap
======================

- add validation of request data
- add api docs generation
- handle multiple routes per endpoint

Bug Tracker
===========

Bugs are tracked on `GitHub Issues <https://github.com/OCA/web-api/issues>`_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed
`feedback <https://github.com/OCA/web-api/issues/new?body=module:%20endpoint%0Aversion:%2018.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.

Do not contact contributors directly about support or help with technical issues.

Credits
=======

Authors
-------

* Camptocamp

Contributors
------------

- Simone Orsi <simone.orsi@camptocamp.com>

Maintainers
-----------

This module is maintained by the OCA.

.. image:: https://odoo-community.org/logo.png
:alt: Odoo Community Association
:target: https://odoo-community.org

OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.

.. |maintainer-simahawk| image:: https://github.com/simahawk.png?size=40px
:target: https://github.com/simahawk
:alt: simahawk

Current `maintainer <https://odoo-community.org/page/maintainer-role>`__:

|maintainer-simahawk|

This module is part of the `OCA/web-api <https://github.com/OCA/web-api/tree/18.0/endpoint>`_ project on GitHub.

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
2 changes: 2 additions & 0 deletions endpoint/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from . import controllers
from . import models
23 changes: 23 additions & 0 deletions endpoint/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Copyright 2021 Camptocamp SA
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).

{
"name": "Endpoint",
"summary": """Provide custom endpoint machinery.""",
"version": "18.0.1.0.0",
"license": "LGPL-3",
"development_status": "Beta",
"author": "Camptocamp,Odoo Community Association (OCA)",
"maintainers": ["simahawk"],
"website": "https://github.com/OCA/web-api",
"depends": ["endpoint_route_handler", "rpc_helper"],
"data": [
"data/server_action.xml",
"security/ir.model.access.csv",
"security/ir_rule.xml",
"views/endpoint_view.xml",
],
"demo": [
"demo/endpoint_demo.xml",
],
}
1 change: 1 addition & 0 deletions endpoint/controllers/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import main
54 changes: 54 additions & 0 deletions endpoint/controllers/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# Copyright 2021 Camptocamp SA
# @author: Simone Orsi <simone.orsi@camptocamp.com>
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).


import json

from werkzeug.exceptions import NotFound

from odoo import http
from odoo.http import Response, request


class EndpointControllerMixin:
def _handle_endpoint(self, env, model, endpoint_route, **params):
endpoint = self._find_endpoint(env, model, endpoint_route)
if not endpoint:
raise NotFound()
endpoint._validate_request(request)
result = endpoint._handle_request(request)
return self._handle_result(result)

def _handle_result(self, result):
response = result.get("response")
if isinstance(response, Response):
# Full response already provided
return response
payload = result.get("payload", "")
status = result.get("status_code", 200)
headers = result.get("headers", {})
return self._make_json_response(payload, headers=headers, status=status)

# TODO: probably not needed anymore as controllers are automatically registered
def _make_json_response(self, payload, headers=None, status=200, **kw):
# TODO: guess out type?
data = json.dumps(payload)
if headers is None:
headers = {}

Check warning on line 38 in endpoint/controllers/main.py

View check run for this annotation

Codecov / codecov/patch

endpoint/controllers/main.py#L38

Added line #L38 was not covered by tests
headers["Content-Type"] = "application/json"
resp = request.make_response(data, headers=headers)
resp.status = str(status)
return resp

def _find_endpoint(self, env, model, endpoint_route):
return env[model]._find_endpoint(endpoint_route)

def auto_endpoint(self, model, endpoint_route, **params):
"""Default method to handle auto-generated endpoints"""
env = request.env
return self._handle_endpoint(env, model, endpoint_route, **params)


class EndpointController(http.Controller, EndpointControllerMixin):
pass
13 changes: 13 additions & 0 deletions endpoint/data/server_action.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo noupdate="1">
<record id="server_action_registry_sync" model="ir.actions.server">
<field name="name">Sync registry</field>
<field name="type">ir.actions.server</field>
<field name="model_id" ref="endpoint.model_endpoint_endpoint" />
<field name="binding_model_id" ref="endpoint.model_endpoint_endpoint" />
<field name="binding_type">action</field>
<field name="state">code</field>
<field name="code">records.write({"registry_sync": True})
</field>
</record>
</odoo>
84 changes: 84 additions & 0 deletions endpoint/demo/endpoint_demo.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo noupdate="1">
<record id="endpoint_demo_1" model="endpoint.endpoint">
<field name="name">Demo Endpoint 1</field>
<field name="route">/demo/one</field>
<field name="request_method">GET</field>
<field name="exec_mode">code</field>
<field name="code_snippet">
result = {"response": Response("ok")}
</field>
</record>

<record id="endpoint_demo_2" model="endpoint.endpoint">
<field name="name">Demo Endpoint 2</field>
<field name="route">/demo/as_demo_user</field>
<field name="request_method">GET</field>
<field name="auth_type">public</field>
<field name="exec_as_user_id" ref="base.user_demo" />
<field name="exec_mode">code</field>
<field name="code_snippet">
result = {"response": Response("My name is: " + user.name)}
</field>
</record>

<record id="endpoint_demo_3" model="endpoint.endpoint">
<field name="name">Demo Endpoint 3</field>
<field name="route">/demo/json_data</field>
<field name="request_method">GET</field>
<field name="auth_type">public</field>
<field name="exec_as_user_id" ref="base.user_demo" />
<field name="exec_mode">code</field>
<field name="code_snippet">
result = {"payload": {"a": 1, "b": 2}}
</field>
</record>

<record id="endpoint_demo_4" model="endpoint.endpoint">
<field name="name">Demo Endpoint 4</field>
<field name="route">/demo/raise_not_found</field>
<field name="request_method">GET</field>
<field name="auth_type">public</field>
<field name="exec_as_user_id" ref="base.user_demo" />
<field name="exec_mode">code</field>
<field name="code_snippet">
raise werkzeug.exceptions.NotFound()
</field>
</record>

<record id="endpoint_demo_5" model="endpoint.endpoint">
<field name="name">Demo Endpoint 5</field>
<field name="route">/demo/raise_validation_error</field>
<field name="request_method">GET</field>
<field name="auth_type">public</field>
<field name="exec_as_user_id" ref="base.user_demo" />
<field name="exec_mode">code</field>
<field name="code_snippet">
raise exceptions.ValidationError("Sorry, you cannot do this!")
</field>
</record>

<record id="endpoint_demo_6" model="endpoint.endpoint">
<field name="name">Demo Endpoint 6</field>
<field name="route">/demo/value_from_request</field>
<field name="request_method">GET</field>
<field name="auth_type">public</field>
<field name="exec_as_user_id" ref="base.user_demo" />
<field name="exec_mode">code</field>
<field name="code_snippet">
result = {"response": Response(request.params.get("your_name", ""))}
</field>
</record>

<record id="endpoint_demo_7" model="endpoint.endpoint">
<field name="name">Demo Endpoint 7</field>
<field name="route">/demo/bad_method</field>
<field name="request_method">GET</field>
<field name="exec_mode">code</field>
<field name="auth_type">public</field>
<field name="exec_as_user_id" ref="base.user_demo" />
<field name="code_snippet">
result = {"payload": "Method used:" + request.httprequest.method}
</field>
</record>
</odoo>
Loading
Loading