PyOdoo 0.7.1__tar.gz → 0.8.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. pyodoo-0.8.0/PKG-INFO +67 -0
  2. pyodoo-0.8.0/PyOdoo.egg-info/PKG-INFO +67 -0
  3. {pyodoo-0.7.1 → pyodoo-0.8.0}/PyOdoo.egg-info/SOURCES.txt +5 -5
  4. pyodoo-0.8.0/PyOdoo.egg-info/requires.txt +2 -0
  5. pyodoo-0.8.0/README.md +42 -0
  6. {pyodoo-0.7.1 → pyodoo-0.8.0}/pyodoo/__init__.py +6 -1
  7. {pyodoo-0.7.1 → pyodoo-0.8.0}/pyodoo/active_status_choice.py +1 -1
  8. {pyodoo-0.7.1/pyodoo/v12 → pyodoo-0.8.0/pyodoo}/api.py +105 -31
  9. {pyodoo-0.7.1 → pyodoo-0.8.0}/pyodoo/boolean_operator.py +1 -1
  10. {pyodoo-0.7.1 → pyodoo-0.8.0}/pyodoo/compare_type.py +1 -1
  11. {pyodoo-0.7.1 → pyodoo-0.8.0}/pyodoo/constants.py +3 -3
  12. {pyodoo-0.7.1 → pyodoo-0.8.0}/pyodoo/filter.py +6 -4
  13. pyodoo-0.8.0/pyodoo/implementation.py +26 -0
  14. {pyodoo-0.7.1 → pyodoo-0.8.0}/pyodoo/message_subtype.py +1 -1
  15. {pyodoo-0.7.1/pyodoo/v12 → pyodoo-0.8.0/pyodoo}/model.py +302 -122
  16. {pyodoo-0.7.1/pyodoo/v12 → pyodoo-0.8.0/pyodoo}/python_code.py +37 -20
  17. {pyodoo-0.7.1 → pyodoo-0.8.0}/pyodoo/samples/awaitable.py +1 -1
  18. pyodoo-0.8.0/pyodoo/samples/contacts.py +156 -0
  19. {pyodoo-0.7.1 → pyodoo-0.8.0}/pyodoo/samples/contacts_async.py +8 -7
  20. {pyodoo-0.7.1 → pyodoo-0.8.0}/pyodoo/samples/python_code.py +11 -8
  21. {pyodoo-0.7.1 → pyodoo-0.8.0}/pyodoo/samples/sql_excel_query.py +12 -8
  22. {pyodoo-0.7.1/pyodoo/v12 → pyodoo-0.8.0/pyodoo}/sql_excel_query.py +81 -36
  23. {pyodoo-0.7.1 → pyodoo-0.8.0}/pyodoo/v12/__init__.py +9 -5
  24. pyodoo-0.8.0/pyproject.toml +43 -0
  25. pyodoo-0.8.0/setup.cfg +4 -0
  26. {pyodoo-0.7.1 → pyodoo-0.8.0}/tests/test_compare_types.py +160 -120
  27. {pyodoo-0.7.1 → pyodoo-0.8.0}/tests/test_contacts.py +118 -56
  28. {pyodoo-0.7.1 → pyodoo-0.8.0}/tests/test_python_code.py +73 -33
  29. {pyodoo-0.7.1 → pyodoo-0.8.0}/tests/test_sql_excel_query.py +114 -44
  30. pyodoo-0.7.1/PKG-INFO +0 -55
  31. pyodoo-0.7.1/PyOdoo.egg-info/PKG-INFO +0 -55
  32. pyodoo-0.7.1/PyOdoo.egg-info/requires.txt +0 -2
  33. pyodoo-0.7.1/README.md +0 -32
  34. pyodoo-0.7.1/pyodoo/samples/contacts.py +0 -150
  35. pyodoo-0.7.1/pyproject.toml +0 -3
  36. pyodoo-0.7.1/setup.cfg +0 -39
  37. {pyodoo-0.7.1 → pyodoo-0.8.0}/LICENSE +0 -0
  38. {pyodoo-0.7.1 → pyodoo-0.8.0}/PyOdoo.egg-info/dependency_links.txt +0 -0
  39. {pyodoo-0.7.1 → pyodoo-0.8.0}/PyOdoo.egg-info/top_level.txt +0 -0
  40. {pyodoo-0.7.1 → pyodoo-0.8.0}/pyodoo/samples/__init__.py +0 -0
pyodoo-0.8.0/PKG-INFO ADDED
@@ -0,0 +1,67 @@
1
+ Metadata-Version: 2.4
2
+ Name: PyOdoo
3
+ Version: 0.8.0
4
+ Summary: API for Odoo
5
+ Author-email: Fabio Castelli <muflone@muflone.com>
6
+ License-Expression: GPL-3.0-or-later
7
+ Project-URL: Homepage, http://www.muflone.com/pyodoo/
8
+ Project-URL: Source, https://github.com/muflone/pyodoo/
9
+ Project-URL: Issues, https://github.com/muflone/pyodoo/issues
10
+ Project-URL: Releases, https://github.com/muflone/pyodoo/releases
11
+ Classifier: Development Status :: 1 - Planning
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Operating System :: OS Independent
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Programming Language :: Python :: 3.13
19
+ Classifier: Programming Language :: Python :: 3.14
20
+ Description-Content-Type: text/markdown
21
+ License-File: LICENSE
22
+ Requires-Dist: xlrd~=2.0
23
+ Requires-Dist: requests~=2.32
24
+ Dynamic: license-file
25
+
26
+ # PyOdoo
27
+
28
+ [![Travis CI Build Status](https://img.shields.io/travis/com/muflone/pyodoo/master.svg)](https://www.travis-ci.com/github/muflone/pyodoo)
29
+ [![CircleCI Build Status](https://img.shields.io/circleci/project/github/muflone/pyodoo/master.svg)](https://circleci.com/gh/muflone/pyodoo)
30
+ [![Python 3.9](https://github.com/muflone/pyodoo/actions/workflows/python-3.9.yml/badge.svg)](https://github.com/muflone/pyodoo/actions/workflows/python-3.9.yml)
31
+ [![Python 3.10](https://github.com/muflone/pyodoo/actions/workflows/python-3.10.yml/badge.svg)](https://github.com/muflone/pyodoo/actions/workflows/python-3.10.yml)
32
+ [![Python 3.11](https://github.com/muflone/pyodoo/actions/workflows/python-3.11.yml/badge.svg)](https://github.com/muflone/pyodoo/actions/workflows/python-3.11.yml)
33
+ [![Python 3.12](https://github.com/muflone/pyodoo/actions/workflows/python-3.12.yml/badge.svg)](https://github.com/muflone/pyodoo/actions/workflows/python-3.12.yml)
34
+ [![Python 3.13](https://github.com/muflone/pyodoo/actions/workflows/python-3.13.yml/badge.svg)](https://github.com/muflone/pyodoo/actions/workflows/python-3.13.yml)
35
+ [![Python 3.14](https://github.com/muflone/pyodoo/actions/workflows/python-3.14.yml/badge.svg)](https://github.com/muflone/pyodoo/actions/workflows/python-3.14.yml)
36
+ [![PyPI - Version](https://img.shields.io/pypi/v/PyOdoo.svg)](https://pypi.org/project/PyOdoo/)
37
+ [![PyPI - Python Version](https://img.shields.io/pypi/pyversions/PyOdoo.svg)](https://pypi.org/project/PyOdoo/)
38
+
39
+ **Description:** API for Odoo
40
+
41
+ **Copyright:** 2021-2026 Fabio Castelli (Muflone) <muflone@muflone.com>
42
+
43
+ **License:** GPL-3+
44
+
45
+ **Source code:** https://github.com/muflone/pyodoo
46
+
47
+ **Documentation:** http://www.muflone.com/pyodoo/
48
+
49
+ # Description
50
+
51
+ PyOdoo is an attempt to build a common API to interact with any
52
+ [**Odoo**](https://www.odoo.com/) server in order to operate using
53
+ its APIs.
54
+
55
+ Currently the following implementations are provided:
56
+ - XML-RPC
57
+ - JSON-RPC
58
+
59
+ # System Requirements
60
+
61
+ * Python 3.x
62
+ * xlrd 2.0.x (https://pypi.org/project/xlrd/)
63
+ * requests 2.32.x (https://pypi.org/project/requests/)
64
+
65
+ # Usage
66
+
67
+ Please see the **samples** and the **tests** folders for some usage examples.
@@ -0,0 +1,67 @@
1
+ Metadata-Version: 2.4
2
+ Name: PyOdoo
3
+ Version: 0.8.0
4
+ Summary: API for Odoo
5
+ Author-email: Fabio Castelli <muflone@muflone.com>
6
+ License-Expression: GPL-3.0-or-later
7
+ Project-URL: Homepage, http://www.muflone.com/pyodoo/
8
+ Project-URL: Source, https://github.com/muflone/pyodoo/
9
+ Project-URL: Issues, https://github.com/muflone/pyodoo/issues
10
+ Project-URL: Releases, https://github.com/muflone/pyodoo/releases
11
+ Classifier: Development Status :: 1 - Planning
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Operating System :: OS Independent
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Programming Language :: Python :: 3.13
19
+ Classifier: Programming Language :: Python :: 3.14
20
+ Description-Content-Type: text/markdown
21
+ License-File: LICENSE
22
+ Requires-Dist: xlrd~=2.0
23
+ Requires-Dist: requests~=2.32
24
+ Dynamic: license-file
25
+
26
+ # PyOdoo
27
+
28
+ [![Travis CI Build Status](https://img.shields.io/travis/com/muflone/pyodoo/master.svg)](https://www.travis-ci.com/github/muflone/pyodoo)
29
+ [![CircleCI Build Status](https://img.shields.io/circleci/project/github/muflone/pyodoo/master.svg)](https://circleci.com/gh/muflone/pyodoo)
30
+ [![Python 3.9](https://github.com/muflone/pyodoo/actions/workflows/python-3.9.yml/badge.svg)](https://github.com/muflone/pyodoo/actions/workflows/python-3.9.yml)
31
+ [![Python 3.10](https://github.com/muflone/pyodoo/actions/workflows/python-3.10.yml/badge.svg)](https://github.com/muflone/pyodoo/actions/workflows/python-3.10.yml)
32
+ [![Python 3.11](https://github.com/muflone/pyodoo/actions/workflows/python-3.11.yml/badge.svg)](https://github.com/muflone/pyodoo/actions/workflows/python-3.11.yml)
33
+ [![Python 3.12](https://github.com/muflone/pyodoo/actions/workflows/python-3.12.yml/badge.svg)](https://github.com/muflone/pyodoo/actions/workflows/python-3.12.yml)
34
+ [![Python 3.13](https://github.com/muflone/pyodoo/actions/workflows/python-3.13.yml/badge.svg)](https://github.com/muflone/pyodoo/actions/workflows/python-3.13.yml)
35
+ [![Python 3.14](https://github.com/muflone/pyodoo/actions/workflows/python-3.14.yml/badge.svg)](https://github.com/muflone/pyodoo/actions/workflows/python-3.14.yml)
36
+ [![PyPI - Version](https://img.shields.io/pypi/v/PyOdoo.svg)](https://pypi.org/project/PyOdoo/)
37
+ [![PyPI - Python Version](https://img.shields.io/pypi/pyversions/PyOdoo.svg)](https://pypi.org/project/PyOdoo/)
38
+
39
+ **Description:** API for Odoo
40
+
41
+ **Copyright:** 2021-2026 Fabio Castelli (Muflone) <muflone@muflone.com>
42
+
43
+ **License:** GPL-3+
44
+
45
+ **Source code:** https://github.com/muflone/pyodoo
46
+
47
+ **Documentation:** http://www.muflone.com/pyodoo/
48
+
49
+ # Description
50
+
51
+ PyOdoo is an attempt to build a common API to interact with any
52
+ [**Odoo**](https://www.odoo.com/) server in order to operate using
53
+ its APIs.
54
+
55
+ Currently the following implementations are provided:
56
+ - XML-RPC
57
+ - JSON-RPC
58
+
59
+ # System Requirements
60
+
61
+ * Python 3.x
62
+ * xlrd 2.0.x (https://pypi.org/project/xlrd/)
63
+ * requests 2.32.x (https://pypi.org/project/requests/)
64
+
65
+ # Usage
66
+
67
+ Please see the **samples** and the **tests** folders for some usage examples.
@@ -1,7 +1,6 @@
1
1
  LICENSE
2
2
  README.md
3
3
  pyproject.toml
4
- setup.cfg
5
4
  PyOdoo.egg-info/PKG-INFO
6
5
  PyOdoo.egg-info/SOURCES.txt
7
6
  PyOdoo.egg-info/dependency_links.txt
@@ -9,11 +8,16 @@ PyOdoo.egg-info/requires.txt
9
8
  PyOdoo.egg-info/top_level.txt
10
9
  pyodoo/__init__.py
11
10
  pyodoo/active_status_choice.py
11
+ pyodoo/api.py
12
12
  pyodoo/boolean_operator.py
13
13
  pyodoo/compare_type.py
14
14
  pyodoo/constants.py
15
15
  pyodoo/filter.py
16
+ pyodoo/implementation.py
16
17
  pyodoo/message_subtype.py
18
+ pyodoo/model.py
19
+ pyodoo/python_code.py
20
+ pyodoo/sql_excel_query.py
17
21
  pyodoo/samples/__init__.py
18
22
  pyodoo/samples/awaitable.py
19
23
  pyodoo/samples/contacts.py
@@ -21,10 +25,6 @@ pyodoo/samples/contacts_async.py
21
25
  pyodoo/samples/python_code.py
22
26
  pyodoo/samples/sql_excel_query.py
23
27
  pyodoo/v12/__init__.py
24
- pyodoo/v12/api.py
25
- pyodoo/v12/model.py
26
- pyodoo/v12/python_code.py
27
- pyodoo/v12/sql_excel_query.py
28
28
  tests/test_compare_types.py
29
29
  tests/test_contacts.py
30
30
  tests/test_python_code.py
@@ -0,0 +1,2 @@
1
+ xlrd~=2.0
2
+ requests~=2.32
pyodoo-0.8.0/README.md ADDED
@@ -0,0 +1,42 @@
1
+ # PyOdoo
2
+
3
+ [![Travis CI Build Status](https://img.shields.io/travis/com/muflone/pyodoo/master.svg)](https://www.travis-ci.com/github/muflone/pyodoo)
4
+ [![CircleCI Build Status](https://img.shields.io/circleci/project/github/muflone/pyodoo/master.svg)](https://circleci.com/gh/muflone/pyodoo)
5
+ [![Python 3.9](https://github.com/muflone/pyodoo/actions/workflows/python-3.9.yml/badge.svg)](https://github.com/muflone/pyodoo/actions/workflows/python-3.9.yml)
6
+ [![Python 3.10](https://github.com/muflone/pyodoo/actions/workflows/python-3.10.yml/badge.svg)](https://github.com/muflone/pyodoo/actions/workflows/python-3.10.yml)
7
+ [![Python 3.11](https://github.com/muflone/pyodoo/actions/workflows/python-3.11.yml/badge.svg)](https://github.com/muflone/pyodoo/actions/workflows/python-3.11.yml)
8
+ [![Python 3.12](https://github.com/muflone/pyodoo/actions/workflows/python-3.12.yml/badge.svg)](https://github.com/muflone/pyodoo/actions/workflows/python-3.12.yml)
9
+ [![Python 3.13](https://github.com/muflone/pyodoo/actions/workflows/python-3.13.yml/badge.svg)](https://github.com/muflone/pyodoo/actions/workflows/python-3.13.yml)
10
+ [![Python 3.14](https://github.com/muflone/pyodoo/actions/workflows/python-3.14.yml/badge.svg)](https://github.com/muflone/pyodoo/actions/workflows/python-3.14.yml)
11
+ [![PyPI - Version](https://img.shields.io/pypi/v/PyOdoo.svg)](https://pypi.org/project/PyOdoo/)
12
+ [![PyPI - Python Version](https://img.shields.io/pypi/pyversions/PyOdoo.svg)](https://pypi.org/project/PyOdoo/)
13
+
14
+ **Description:** API for Odoo
15
+
16
+ **Copyright:** 2021-2026 Fabio Castelli (Muflone) <muflone@muflone.com>
17
+
18
+ **License:** GPL-3+
19
+
20
+ **Source code:** https://github.com/muflone/pyodoo
21
+
22
+ **Documentation:** http://www.muflone.com/pyodoo/
23
+
24
+ # Description
25
+
26
+ PyOdoo is an attempt to build a common API to interact with any
27
+ [**Odoo**](https://www.odoo.com/) server in order to operate using
28
+ its APIs.
29
+
30
+ Currently the following implementations are provided:
31
+ - XML-RPC
32
+ - JSON-RPC
33
+
34
+ # System Requirements
35
+
36
+ * Python 3.x
37
+ * xlrd 2.0.x (https://pypi.org/project/xlrd/)
38
+ * requests 2.32.x (https://pypi.org/project/requests/)
39
+
40
+ # Usage
41
+
42
+ Please see the **samples** and the **tests** folders for some usage examples.
@@ -2,7 +2,7 @@
2
2
  # Project: PyOdoo
3
3
  # Description: API for Odoo
4
4
  # Author: Fabio Castelli (Muflone) <muflone@muflone.com>
5
- # Copyright: 2021-2024 Fabio Castelli
5
+ # Copyright: 2021-2026 Fabio Castelli
6
6
  # License: GPL-3+
7
7
  # This program is free software: you can redistribute it and/or modify
8
8
  # it under the terms of the GNU General Public License as published by
@@ -19,8 +19,13 @@
19
19
  ##
20
20
 
21
21
  from .active_status_choice import ActiveStatusChoice # noqa: F401
22
+ from .api import Api # noqa: F401
22
23
  from .boolean_operator import BooleanOperator # noqa: F401
23
24
  from .compare_type import CompareType # noqa: F401
24
25
  from .constants import APP_VERSION as __version__ # noqa: F401
25
26
  from .filter import Filter # noqa: F401
27
+ from .implementation import Implementation # noqa: F401
26
28
  from .message_subtype import MessageSubType # noqa: F401
29
+ from .model import Model # noqa: F401
30
+ from .python_code import PythonCode # noqa: F401
31
+ from .sql_excel_query import SqlExcelQuery # noqa: F401
@@ -2,7 +2,7 @@
2
2
  # Project: PyOdoo
3
3
  # Description: API for Odoo
4
4
  # Author: Fabio Castelli (Muflone) <muflone@muflone.com>
5
- # Copyright: 2021-2024 Fabio Castelli
5
+ # Copyright: 2021-2026 Fabio Castelli
6
6
  # License: GPL-3+
7
7
  # This program is free software: you can redistribute it and/or modify
8
8
  # it under the terms of the GNU General Public License as published by
@@ -2,7 +2,7 @@
2
2
  # Project: PyOdoo
3
3
  # Description: API for Odoo
4
4
  # Author: Fabio Castelli (Muflone) <muflone@muflone.com>
5
- # Copyright: 2021-2024 Fabio Castelli
5
+ # Copyright: 2021-2026 Fabio Castelli
6
6
  # License: GPL-3+
7
7
  # This program is free software: you can redistribute it and/or modify
8
8
  # it under the terms of the GNU General Public License as published by
@@ -21,12 +21,17 @@
21
21
  from typing import Any, Optional, Union
22
22
  from xmlrpc.client import ServerProxy
23
23
 
24
- from pyodoo import BooleanOperator, Filter
24
+ import requests
25
+ import requests.auth
26
+
27
+ from .boolean_operator import BooleanOperator
28
+ from .filter import Filter
29
+ from .implementation import Implementation
25
30
 
26
31
 
27
32
  class Api(object):
28
33
  """
29
- Odoo v12 XML-RPC API
34
+ Odoo base API
30
35
  """
31
36
  def __init__(self,
32
37
  model_name: str,
@@ -34,7 +39,9 @@ class Api(object):
34
39
  database: str,
35
40
  username: str,
36
41
  password: str,
37
- language: str = None):
42
+ language: str = None,
43
+ implementation: Implementation = Implementation.XMLRPC
44
+ ) -> None:
38
45
  # Associate model
39
46
  if not model_name:
40
47
  raise NotImplementedError('model name was not set properly')
@@ -45,25 +52,53 @@ class Api(object):
45
52
  self.password = password
46
53
  self.language = language
47
54
  self.uid = None
55
+ self.implementation = implementation
48
56
  # Remove trailing / from endpoint
49
57
  if self.endpoint.endswith('/'):
50
58
  self.endpoint = self.endpoint[:-1]
59
+ # Specific implementations
60
+ if implementation == Implementation.JSONRPC:
61
+ self.session = requests.Session()
51
62
 
52
- def authenticate(self) -> int:
63
+ def authenticate(self
64
+ ) -> int:
53
65
  """
54
66
  Authenticate the session using database, username and password
55
67
 
56
68
  :return: The user ID for the authenticated user
57
69
  """
58
- proxy = self.get_proxy(method='xmlrpc/2/common')
59
- self.uid = proxy.authenticate(self.database,
60
- self.username,
61
- self.password,
62
- {})
70
+ if self.implementation == Implementation.XMLRPC:
71
+ # Authentication for XML-RPC
72
+ proxy = self.get_proxy(method='xmlrpc/2/common')
73
+ self.uid = proxy.authenticate(self.database,
74
+ self.username,
75
+ self.password,
76
+ {})
77
+ elif self.implementation == Implementation.JSONRPC:
78
+ # Authentication for JSON-RPC
79
+ self.session.auth = requests.auth.HTTPBasicAuth(
80
+ username=self.username,
81
+ password=self.password)
82
+ response = self.session.post(
83
+ url=self.build_endpoint('web/session/authenticate'),
84
+ json={
85
+ 'jsonrpc': '2.0',
86
+ 'params': {
87
+ 'db': self.database,
88
+ 'login': self.username,
89
+ 'password': self.password
90
+ }
91
+ })
92
+ result = response.json() if response else None
93
+ self.uid = result['result']['uid'] if result else None
94
+ else:
95
+ # Invalid implementation
96
+ raise ValueError(f'Invalid implementation {self.implementation}')
63
97
  return self.uid
64
98
 
65
99
  def build_endpoint(self,
66
- method: str) -> str:
100
+ method: str
101
+ ) -> str:
67
102
  """
68
103
  Build the remote endpoint URL
69
104
 
@@ -74,7 +109,8 @@ class Api(object):
74
109
  METHOD=method)
75
110
 
76
111
  def get_proxy(self,
77
- method: str) -> ServerProxy:
112
+ method: str
113
+ ) -> ServerProxy:
78
114
  """
79
115
  Get the proxy for the remote endpoint URL
80
116
 
@@ -83,7 +119,8 @@ class Api(object):
83
119
  """
84
120
  return ServerProxy(self.build_endpoint(method=method))
85
121
 
86
- def get_proxy_object(self) -> ServerProxy:
122
+ def get_proxy_object(self
123
+ ) -> ServerProxy:
87
124
  """
88
125
  Get the proxy for the standard object method
89
126
 
@@ -107,7 +144,8 @@ class Api(object):
107
144
  def do_execute(self,
108
145
  method_name: str,
109
146
  args: list[Any],
110
- kwargs: dict[str, Any]) -> Any:
147
+ kwargs: dict[str, Any]
148
+ ) -> Any:
111
149
  """
112
150
  Execute a method on a model
113
151
 
@@ -116,19 +154,47 @@ class Api(object):
116
154
  :param kwargs: arguments dict passed by keyword
117
155
  :return:
118
156
  """
119
- proxy = self.get_proxy_object()
120
- results = proxy.execute_kw(self.database,
121
- self.uid,
122
- self.password,
123
- self.model_name,
124
- method_name,
125
- args,
126
- kwargs)
157
+ if self.implementation == Implementation.XMLRPC:
158
+ # Execute for XML-RPC
159
+ proxy = self.get_proxy_object()
160
+ results = proxy.execute_kw(self.database,
161
+ self.uid,
162
+ self.password,
163
+ self.model_name,
164
+ method_name,
165
+ args,
166
+ kwargs)
167
+ elif self.implementation == Implementation.JSONRPC:
168
+ # Execute for JSON-RPC
169
+ results = self.session.post(
170
+ url=self.build_endpoint(method='jsonrpc'),
171
+ json={
172
+ 'jsonrpc': '2.0',
173
+ 'method': 'call',
174
+ 'params': {
175
+ 'service': 'object',
176
+ 'method': 'execute_kw',
177
+ 'args': [
178
+ self.database,
179
+ self.uid,
180
+ self.password,
181
+ self.model_name,
182
+ method_name,
183
+ args,
184
+ kwargs
185
+ ],
186
+ }
187
+ }
188
+ ).json().get('result')
189
+ else:
190
+ # Invalid implementation
191
+ raise ValueError(f'Invalid implementation {self.implementation}')
127
192
  return results
128
193
 
129
194
  def do_read(self,
130
195
  entity_id: int,
131
- options: dict[str, Any]) -> Optional[dict[str, Any]]:
196
+ options: dict[str, Any]
197
+ ) -> Optional[dict[str, Any]]:
132
198
  """
133
199
  Get a record in the requested model applying a filter and some
134
200
  options (like fields or context)
@@ -160,7 +226,8 @@ class Api(object):
160
226
 
161
227
  def do_fields_get(self,
162
228
  fields: list[str],
163
- options: dict[str, Any]) -> dict[str, dict]:
229
+ options: dict[str, Any]
230
+ ) -> dict[str, dict]:
164
231
  """
165
232
  Get the model fields
166
233
 
@@ -175,7 +242,8 @@ class Api(object):
175
242
 
176
243
  def do_search(self,
177
244
  filters: list[Union[BooleanOperator, Filter, str]],
178
- options: dict[str, Any]) -> list[int]:
245
+ options: dict[str, Any]
246
+ ) -> list[int]:
179
247
  """
180
248
  Search some records in the requested model applying a filter and some
181
249
  options (like fields or context)
@@ -191,7 +259,8 @@ class Api(object):
191
259
 
192
260
  def do_search_count(self,
193
261
  filters: list[Union[BooleanOperator, Filter, str]],
194
- options: dict[str, Any]) -> int:
262
+ options: dict[str, Any]
263
+ ) -> int:
195
264
  """
196
265
  Get the records count in the requested model applying a filter
197
266
 
@@ -206,7 +275,8 @@ class Api(object):
206
275
 
207
276
  def do_search_read(self,
208
277
  filters: list[Union[BooleanOperator, Filter]],
209
- options: dict[str, Any]) -> list[dict[str, Any]]:
278
+ options: dict[str, Any]
279
+ ) -> list[dict[str, Any]]:
210
280
  """
211
281
  Search some records in the requested model applying a filter and some
212
282
  options (like fields or context) and returns the found data
@@ -223,7 +293,8 @@ class Api(object):
223
293
 
224
294
  def do_create(self,
225
295
  values: dict[str, Any],
226
- options: dict[str, Any]) -> int:
296
+ options: dict[str, Any]
297
+ ) -> int:
227
298
  """
228
299
  Create a new record in the requested model and returns its ID
229
300
 
@@ -239,7 +310,8 @@ class Api(object):
239
310
  def do_update(self,
240
311
  entity_id: Union[int, list[int]],
241
312
  values: dict[str, Any],
242
- options: dict[str, Any]) -> bool:
313
+ options: dict[str, Any]
314
+ ) -> bool:
243
315
  """
244
316
  Update one or more records in the requested model
245
317
 
@@ -255,7 +327,8 @@ class Api(object):
255
327
 
256
328
  def do_delete(self,
257
329
  entity_id: Union[int, list[int]],
258
- options: dict[str, Any]) -> bool:
330
+ options: dict[str, Any]
331
+ ) -> bool:
259
332
  """
260
333
  Delete one or multiple records in the requested model
261
334
 
@@ -274,7 +347,8 @@ class Api(object):
274
347
  author_id: int,
275
348
  subject: str,
276
349
  body: str,
277
- options: dict[str, Any]) -> int:
350
+ options: dict[str, Any]
351
+ ) -> int:
278
352
  """
279
353
  Add a message to a model row
280
354
 
@@ -2,7 +2,7 @@
2
2
  # Project: PyOdoo
3
3
  # Description: API for Odoo
4
4
  # Author: Fabio Castelli (Muflone) <muflone@muflone.com>
5
- # Copyright: 2021-2024 Fabio Castelli
5
+ # Copyright: 2021-2026 Fabio Castelli
6
6
  # License: GPL-3+
7
7
  # This program is free software: you can redistribute it and/or modify
8
8
  # it under the terms of the GNU General Public License as published by
@@ -2,7 +2,7 @@
2
2
  # Project: PyOdoo
3
3
  # Description: API for Odoo
4
4
  # Author: Fabio Castelli (Muflone) <muflone@muflone.com>
5
- # Copyright: 2021-2024 Fabio Castelli
5
+ # Copyright: 2021-2026 Fabio Castelli
6
6
  # License: GPL-3+
7
7
  # This program is free software: you can redistribute it and/or modify
8
8
  # it under the terms of the GNU General Public License as published by
@@ -2,7 +2,7 @@
2
2
  # Project: PyOdoo
3
3
  # Description: API for Odoo
4
4
  # Author: Fabio Castelli (Muflone) <muflone@muflone.com>
5
- # Copyright: 2021-2024 Fabio Castelli
5
+ # Copyright: 2021-2026 Fabio Castelli
6
6
  # License: GPL-3+
7
7
  # This program is free software: you can redistribute it and/or modify
8
8
  # it under the terms of the GNU General Public License as published by
@@ -19,13 +19,13 @@
19
19
  ##
20
20
 
21
21
  APP_NAME = 'PyOdoo'
22
- APP_VERSION = '0.7.1'
22
+ APP_VERSION = '0.8.0'
23
23
  APP_DESCRIPTION = 'API for Odoo'
24
24
  APP_DOMAIN = 'pyodoo'
25
25
  APP_ID = f'{APP_DOMAIN}.muflone.com'
26
26
  APP_AUTHOR = 'Fabio Castelli'
27
27
  APP_AUTHOR_EMAIL = 'muflone@muflone.com'
28
- APP_COPYRIGHT = f'Copyright 2021-2024 {APP_AUTHOR}'
28
+ APP_COPYRIGHT = f'Copyright 2021-2026 {APP_AUTHOR}'
29
29
  URL_AUTHOR = 'http://www.muflone.com/'
30
30
  URL_APPLICATION = f'{URL_AUTHOR}{APP_DOMAIN}/'
31
31
  URL_SOURCES = f'https://github.com/muflone/{APP_DOMAIN}/'
@@ -2,7 +2,7 @@
2
2
  # Project: PyOdoo
3
3
  # Description: API for Odoo
4
4
  # Author: Fabio Castelli (Muflone) <muflone@muflone.com>
5
- # Copyright: 2021-2024 Fabio Castelli
5
+ # Copyright: 2021-2026 Fabio Castelli
6
6
  # License: GPL-3+
7
7
  # This program is free software: you can redistribute it and/or modify
8
8
  # it under the terms of the GNU General Public License as published by
@@ -20,7 +20,7 @@
20
20
 
21
21
  from typing import Union
22
22
 
23
- from pyodoo import CompareType
23
+ from .compare_type import CompareType
24
24
 
25
25
 
26
26
  class Filter(object):
@@ -30,12 +30,14 @@ class Filter(object):
30
30
  def __init__(self,
31
31
  field: str,
32
32
  compare_type: CompareType,
33
- value: object):
33
+ value: object
34
+ ) -> None:
34
35
  self.field = field
35
36
  self.compare_type = compare_type
36
37
  self.value = value
37
38
 
38
- def explode(self) -> list[Union[str, object]]:
39
+ def explode(self
40
+ ) -> list[Union[str, object]]:
39
41
  """
40
42
  Extract the list from the filter, in the format used in Odoo filters
41
43
 
@@ -0,0 +1,26 @@
1
+ ##
2
+ # Project: PyOdoo
3
+ # Description: API for Odoo
4
+ # Author: Fabio Castelli (Muflone) <muflone@muflone.com>
5
+ # Copyright: 2021-2026 Fabio Castelli
6
+ # License: GPL-3+
7
+ # This program is free software: you can redistribute it and/or modify
8
+ # it under the terms of the GNU General Public License as published by
9
+ # the Free Software Foundation, either version 3 of the License, or
10
+ # (at your option) any later version.
11
+ #
12
+ # This program is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU General Public License
18
+ # along with this program. If not, see <https://www.gnu.org/licenses/>.
19
+ ##
20
+
21
+ class Implementation(object):
22
+ """
23
+ Implementations used in Odoo API
24
+ """
25
+ XMLRPC = 'xmlrpc'
26
+ JSONRPC = 'jsonrpc'
@@ -2,7 +2,7 @@
2
2
  # Project: PyOdoo
3
3
  # Description: API for Odoo
4
4
  # Author: Fabio Castelli (Muflone) <muflone@muflone.com>
5
- # Copyright: 2021-2024 Fabio Castelli
5
+ # Copyright: 2021-2026 Fabio Castelli
6
6
  # License: GPL-3+
7
7
  # This program is free software: you can redistribute it and/or modify
8
8
  # it under the terms of the GNU General Public License as published by