PyOdoo 0.7.1__tar.gz → 0.7.2__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 (36) hide show
  1. {pyodoo-0.7.1 → pyodoo-0.7.2}/PKG-INFO +19 -13
  2. {pyodoo-0.7.1 → pyodoo-0.7.2}/PyOdoo.egg-info/PKG-INFO +19 -13
  3. {pyodoo-0.7.1 → pyodoo-0.7.2}/PyOdoo.egg-info/SOURCES.txt +0 -1
  4. pyodoo-0.7.2/PyOdoo.egg-info/requires.txt +2 -0
  5. {pyodoo-0.7.1 → pyodoo-0.7.2}/README.md +7 -2
  6. {pyodoo-0.7.1 → pyodoo-0.7.2}/pyodoo/__init__.py +1 -1
  7. {pyodoo-0.7.1 → pyodoo-0.7.2}/pyodoo/active_status_choice.py +1 -1
  8. {pyodoo-0.7.1 → pyodoo-0.7.2}/pyodoo/boolean_operator.py +1 -1
  9. {pyodoo-0.7.1 → pyodoo-0.7.2}/pyodoo/compare_type.py +1 -1
  10. {pyodoo-0.7.1 → pyodoo-0.7.2}/pyodoo/constants.py +3 -3
  11. {pyodoo-0.7.1 → pyodoo-0.7.2}/pyodoo/filter.py +5 -3
  12. {pyodoo-0.7.1 → pyodoo-0.7.2}/pyodoo/message_subtype.py +1 -1
  13. {pyodoo-0.7.1 → pyodoo-0.7.2}/pyodoo/samples/awaitable.py +1 -1
  14. pyodoo-0.7.2/pyodoo/samples/contacts.py +156 -0
  15. {pyodoo-0.7.1 → pyodoo-0.7.2}/pyodoo/samples/contacts_async.py +1 -1
  16. {pyodoo-0.7.1 → pyodoo-0.7.2}/pyodoo/samples/python_code.py +1 -1
  17. {pyodoo-0.7.1 → pyodoo-0.7.2}/pyodoo/samples/sql_excel_query.py +2 -1
  18. {pyodoo-0.7.1 → pyodoo-0.7.2}/pyodoo/v12/__init__.py +1 -1
  19. {pyodoo-0.7.1 → pyodoo-0.7.2}/pyodoo/v12/api.py +31 -16
  20. {pyodoo-0.7.1 → pyodoo-0.7.2}/pyodoo/v12/model.py +290 -114
  21. {pyodoo-0.7.1 → pyodoo-0.7.2}/pyodoo/v12/python_code.py +20 -10
  22. {pyodoo-0.7.1 → pyodoo-0.7.2}/pyodoo/v12/sql_excel_query.py +44 -21
  23. pyodoo-0.7.2/pyproject.toml +42 -0
  24. pyodoo-0.7.2/setup.cfg +4 -0
  25. {pyodoo-0.7.1 → pyodoo-0.7.2}/tests/test_compare_types.py +43 -22
  26. {pyodoo-0.7.1 → pyodoo-0.7.2}/tests/test_contacts.py +87 -44
  27. {pyodoo-0.7.1 → pyodoo-0.7.2}/tests/test_python_code.py +17 -9
  28. {pyodoo-0.7.1 → pyodoo-0.7.2}/tests/test_sql_excel_query.py +33 -17
  29. pyodoo-0.7.1/PyOdoo.egg-info/requires.txt +0 -2
  30. pyodoo-0.7.1/pyodoo/samples/contacts.py +0 -150
  31. pyodoo-0.7.1/pyproject.toml +0 -3
  32. pyodoo-0.7.1/setup.cfg +0 -39
  33. {pyodoo-0.7.1 → pyodoo-0.7.2}/LICENSE +0 -0
  34. {pyodoo-0.7.1 → pyodoo-0.7.2}/PyOdoo.egg-info/dependency_links.txt +0 -0
  35. {pyodoo-0.7.1 → pyodoo-0.7.2}/PyOdoo.egg-info/top_level.txt +0 -0
  36. {pyodoo-0.7.1 → pyodoo-0.7.2}/pyodoo/samples/__init__.py +0 -0
@@ -1,36 +1,42 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: PyOdoo
3
- Version: 0.7.1
3
+ Version: 0.7.2
4
4
  Summary: API for Odoo
5
- Home-page: http://www.muflone.com/pyodoo/
6
- Author: Fabio Castelli
7
- Author-email: muflone@muflone.com
8
- License: GPLv3+
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
9
11
  Classifier: Development Status :: 1 - Planning
10
12
  Classifier: Intended Audience :: Developers
11
- Classifier: License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)
12
13
  Classifier: Operating System :: OS Independent
13
14
  Classifier: Programming Language :: Python :: 3
14
- Classifier: Programming Language :: Python :: 3.9
15
15
  Classifier: Programming Language :: Python :: 3.10
16
16
  Classifier: Programming Language :: Python :: 3.11
17
17
  Classifier: Programming Language :: Python :: 3.12
18
- Classifier: Topic :: Software Development :: Libraries :: Python Modules
18
+ Classifier: Programming Language :: Python :: 3.13
19
19
  Description-Content-Type: text/markdown
20
20
  License-File: LICENSE
21
- Requires-Dist: xlrd==2.0.1
22
- Requires-Dist: requests==2.32.3
21
+ Requires-Dist: xlrd~=2.0
22
+ Requires-Dist: requests~=2.32
23
+ Dynamic: license-file
23
24
 
24
25
  # PyOdoo
25
26
 
26
27
  [![Travis CI Build Status](https://img.shields.io/travis/com/muflone/pyodoo/master.svg)](https://www.travis-ci.com/github/muflone/pyodoo)
27
28
  [![CircleCI Build Status](https://img.shields.io/circleci/project/github/muflone/pyodoo/master.svg)](https://circleci.com/gh/muflone/pyodoo)
29
+ [![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)
30
+ [![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)
31
+ [![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)
32
+ [![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)
33
+ [![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)
28
34
  [![PyPI - Version](https://img.shields.io/pypi/v/PyOdoo.svg)](https://pypi.org/project/PyOdoo/)
29
35
  [![PyPI - Python Version](https://img.shields.io/pypi/pyversions/PyOdoo.svg)](https://pypi.org/project/PyOdoo/)
30
36
 
31
37
  **Description:** API for Odoo
32
38
 
33
- **Copyright:** 2021-2024 Fabio Castelli (Muflone) <muflone@muflone.com>
39
+ **Copyright:** 2021-2025 Fabio Castelli (Muflone) <muflone@muflone.com>
34
40
 
35
41
  **License:** GPL-3+
36
42
 
@@ -48,7 +54,7 @@ its XML RPC API.
48
54
 
49
55
  * Python 3.x
50
56
  * xlrd 2.0.x (https://pypi.org/project/xlrd/)
51
- * requests 2.31.x (https://pypi.org/project/requests/)
57
+ * requests 2.32.x (https://pypi.org/project/requests/)
52
58
 
53
59
  # Usage
54
60
 
@@ -1,36 +1,42 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: PyOdoo
3
- Version: 0.7.1
3
+ Version: 0.7.2
4
4
  Summary: API for Odoo
5
- Home-page: http://www.muflone.com/pyodoo/
6
- Author: Fabio Castelli
7
- Author-email: muflone@muflone.com
8
- License: GPLv3+
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
9
11
  Classifier: Development Status :: 1 - Planning
10
12
  Classifier: Intended Audience :: Developers
11
- Classifier: License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)
12
13
  Classifier: Operating System :: OS Independent
13
14
  Classifier: Programming Language :: Python :: 3
14
- Classifier: Programming Language :: Python :: 3.9
15
15
  Classifier: Programming Language :: Python :: 3.10
16
16
  Classifier: Programming Language :: Python :: 3.11
17
17
  Classifier: Programming Language :: Python :: 3.12
18
- Classifier: Topic :: Software Development :: Libraries :: Python Modules
18
+ Classifier: Programming Language :: Python :: 3.13
19
19
  Description-Content-Type: text/markdown
20
20
  License-File: LICENSE
21
- Requires-Dist: xlrd==2.0.1
22
- Requires-Dist: requests==2.32.3
21
+ Requires-Dist: xlrd~=2.0
22
+ Requires-Dist: requests~=2.32
23
+ Dynamic: license-file
23
24
 
24
25
  # PyOdoo
25
26
 
26
27
  [![Travis CI Build Status](https://img.shields.io/travis/com/muflone/pyodoo/master.svg)](https://www.travis-ci.com/github/muflone/pyodoo)
27
28
  [![CircleCI Build Status](https://img.shields.io/circleci/project/github/muflone/pyodoo/master.svg)](https://circleci.com/gh/muflone/pyodoo)
29
+ [![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)
30
+ [![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)
31
+ [![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)
32
+ [![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)
33
+ [![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)
28
34
  [![PyPI - Version](https://img.shields.io/pypi/v/PyOdoo.svg)](https://pypi.org/project/PyOdoo/)
29
35
  [![PyPI - Python Version](https://img.shields.io/pypi/pyversions/PyOdoo.svg)](https://pypi.org/project/PyOdoo/)
30
36
 
31
37
  **Description:** API for Odoo
32
38
 
33
- **Copyright:** 2021-2024 Fabio Castelli (Muflone) <muflone@muflone.com>
39
+ **Copyright:** 2021-2025 Fabio Castelli (Muflone) <muflone@muflone.com>
34
40
 
35
41
  **License:** GPL-3+
36
42
 
@@ -48,7 +54,7 @@ its XML RPC API.
48
54
 
49
55
  * Python 3.x
50
56
  * xlrd 2.0.x (https://pypi.org/project/xlrd/)
51
- * requests 2.31.x (https://pypi.org/project/requests/)
57
+ * requests 2.32.x (https://pypi.org/project/requests/)
52
58
 
53
59
  # Usage
54
60
 
@@ -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
@@ -0,0 +1,2 @@
1
+ xlrd~=2.0
2
+ requests~=2.32
@@ -2,12 +2,17 @@
2
2
 
3
3
  [![Travis CI Build Status](https://img.shields.io/travis/com/muflone/pyodoo/master.svg)](https://www.travis-ci.com/github/muflone/pyodoo)
4
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)
5
10
  [![PyPI - Version](https://img.shields.io/pypi/v/PyOdoo.svg)](https://pypi.org/project/PyOdoo/)
6
11
  [![PyPI - Python Version](https://img.shields.io/pypi/pyversions/PyOdoo.svg)](https://pypi.org/project/PyOdoo/)
7
12
 
8
13
  **Description:** API for Odoo
9
14
 
10
- **Copyright:** 2021-2024 Fabio Castelli (Muflone) <muflone@muflone.com>
15
+ **Copyright:** 2021-2025 Fabio Castelli (Muflone) <muflone@muflone.com>
11
16
 
12
17
  **License:** GPL-3+
13
18
 
@@ -25,7 +30,7 @@ its XML RPC API.
25
30
 
26
31
  * Python 3.x
27
32
  * xlrd 2.0.x (https://pypi.org/project/xlrd/)
28
- * requests 2.31.x (https://pypi.org/project/requests/)
33
+ * requests 2.32.x (https://pypi.org/project/requests/)
29
34
 
30
35
  # Usage
31
36
 
@@ -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-2025 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-2025 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-2025 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-2025 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-2025 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.7.2'
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-2025 {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-2025 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
@@ -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
 
@@ -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-2025 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-2025 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
@@ -0,0 +1,156 @@
1
+ ##
2
+ # Project: PyOdoo
3
+ # Description: API for Odoo
4
+ # Author: Fabio Castelli (Muflone) <muflone@muflone.com>
5
+ # Copyright: 2021-2025 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
+ import os
22
+
23
+ from pyodoo import (BooleanOperator,
24
+ CompareType,
25
+ Filter,
26
+ MessageSubType)
27
+ from pyodoo.v12 import Model
28
+
29
+
30
+ # Instance model object
31
+ model = Model(model_name='res.partner',
32
+ endpoint=os.environ['ODOO_ENDPOINT'],
33
+ database=os.environ['ODOO_DATABASE'],
34
+ username=os.environ['ODOO_USERNAME'],
35
+ password=os.environ['ODOO_PASSWORD'],
36
+ language=None,
37
+ authenticate=False)
38
+ # Authenticate user
39
+ if model.authenticate():
40
+ print('Authentication successful')
41
+ print('UID: ', model.uid)
42
+ print('Partner ID: ', model.partner_id)
43
+ print('Partner name: ', model.partner_name)
44
+ # Change default language
45
+ model.language = 'en_GB'
46
+ # Filters by name and excluding an explicit ID
47
+ filters = [BooleanOperator.AND,
48
+ Filter(field='name',
49
+ compare_type=CompareType.CONTAINS,
50
+ value='Castelli Fabio'),
51
+ BooleanOperator.AND,
52
+ BooleanOperator.NOT,
53
+ Filter(field='name',
54
+ compare_type=CompareType.CONTAINS,
55
+ value='Ross'),
56
+ Filter(field='id',
57
+ compare_type=CompareType.NOT_EQUAL,
58
+ value=193623)
59
+ ]
60
+ # Search some records by name
61
+ results = model.search(filters=filters)
62
+ print('search', len(results), results)
63
+
64
+ # Find some records by ID
65
+ results = model.find(entity_ids=results,
66
+ fields=('id', 'name', 'country_id'))
67
+ print('find many', results)
68
+
69
+ # Find a record by ID
70
+ results = model.find(entity_ids=[131492],
71
+ fields=('id', 'name'))
72
+ print('find', results)
73
+
74
+ # Find some records by filters
75
+ results = model.filter(filters=filters,
76
+ fields=('id', 'name', 'country_id'))
77
+ print('filter', results)
78
+
79
+ # Find first record by filters
80
+ results = model.first(filters=filters,
81
+ fields=('id', 'name', 'country_id'))
82
+ print('first', results)
83
+
84
+ # Get all the record
85
+ results = model.all(fields=('id', 'name'),
86
+ limit=1000)
87
+ print('all', len(results))
88
+
89
+ # Get a record by ID
90
+ results = model.get(entity_id=131492,
91
+ fields=('id', 'name'))
92
+ print('get', results)
93
+
94
+ # Create a new record
95
+ entity_id = model.create(values={'firstname': 'TEST TEST TEST',
96
+ 'lastname': '123 456'},
97
+ ignore_none_errors=True)
98
+ print('create', entity_id)
99
+
100
+ # Update a record by ID
101
+ model.update(entity_id=entity_id,
102
+ values={'street': 'TEST TEST TEST'},
103
+ ignore_none_errors=True)
104
+ results = model.get(entity_id=entity_id,
105
+ fields=('id', 'street'))
106
+ print('update', results)
107
+
108
+ # Get Message subtype IDs
109
+ for subtype in (MessageSubType.ACTIVITY,
110
+ MessageSubType.COMMENT,
111
+ MessageSubType.NOTE):
112
+ print(subtype,
113
+ model.get_message_subtype_id(subtype=subtype))
114
+
115
+ # Post an activity message
116
+ results = model.post_message_as_activity(entity_id=entity_id,
117
+ body='Activity message',
118
+ author_id=model.partner_id)
119
+ print('activity message', results)
120
+
121
+ # Post a comment message
122
+ results = model.post_message_as_comment(entity_id=entity_id,
123
+ body='Comment message',
124
+ author_id=model.partner_id)
125
+ print('comment message', results)
126
+
127
+ # Post a note message
128
+ results = model.post_message_as_note(entity_id=entity_id,
129
+ body='This is a note',
130
+ author_id=model.partner_id)
131
+ print('note message', results)
132
+
133
+ # Delete a record
134
+ model.delete(entity_id=entity_id)
135
+ print('delete')
136
+
137
+ # Find customers from France with different languages
138
+ filters.append(Filter(field='lang',
139
+ compare_type=CompareType.NOT_EQUAL,
140
+ value='fr_FR'))
141
+ filters.append(Filter(field='country_id',
142
+ compare_type=CompareType.EQUAL,
143
+ value='France'))
144
+ results = model.search(filters=filters)
145
+ print('search', len(results), results)
146
+
147
+ # Update those customers to French language
148
+ for entity_id in results:
149
+ model.update(entity_id=entity_id,
150
+ values={'lang': 'fr_FR'},
151
+ ignore_none_errors=True)
152
+ print('updating ID', entity_id)
153
+ results = model.search(filters=filters)
154
+ print('search', len(results), results)
155
+ else:
156
+ print('Authentication was not succesful')
@@ -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-2025 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-2025 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-2025 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
@@ -62,6 +62,7 @@ query.execute()
62
62
 
63
63
  # Get Excel file
64
64
  data = query.get_file()
65
+ print(len(data))
65
66
 
66
67
  # Process the Excel file and extract its data
67
68
  data = query.get_data()
@@ -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-2025 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-2025 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
@@ -34,7 +34,8 @@ class Api(object):
34
34
  database: str,
35
35
  username: str,
36
36
  password: str,
37
- language: str = None):
37
+ language: str = None
38
+ ) -> None:
38
39
  # Associate model
39
40
  if not model_name:
40
41
  raise NotImplementedError('model name was not set properly')
@@ -49,7 +50,8 @@ class Api(object):
49
50
  if self.endpoint.endswith('/'):
50
51
  self.endpoint = self.endpoint[:-1]
51
52
 
52
- def authenticate(self) -> int:
53
+ def authenticate(self
54
+ ) -> int:
53
55
  """
54
56
  Authenticate the session using database, username and password
55
57
 
@@ -63,7 +65,8 @@ class Api(object):
63
65
  return self.uid
64
66
 
65
67
  def build_endpoint(self,
66
- method: str) -> str:
68
+ method: str
69
+ ) -> str:
67
70
  """
68
71
  Build the remote endpoint URL
69
72
 
@@ -74,7 +77,8 @@ class Api(object):
74
77
  METHOD=method)
75
78
 
76
79
  def get_proxy(self,
77
- method: str) -> ServerProxy:
80
+ method: str
81
+ ) -> ServerProxy:
78
82
  """
79
83
  Get the proxy for the remote endpoint URL
80
84
 
@@ -83,7 +87,8 @@ class Api(object):
83
87
  """
84
88
  return ServerProxy(self.build_endpoint(method=method))
85
89
 
86
- def get_proxy_object(self) -> ServerProxy:
90
+ def get_proxy_object(self
91
+ ) -> ServerProxy:
87
92
  """
88
93
  Get the proxy for the standard object method
89
94
 
@@ -107,7 +112,8 @@ class Api(object):
107
112
  def do_execute(self,
108
113
  method_name: str,
109
114
  args: list[Any],
110
- kwargs: dict[str, Any]) -> Any:
115
+ kwargs: dict[str, Any]
116
+ ) -> Any:
111
117
  """
112
118
  Execute a method on a model
113
119
 
@@ -128,7 +134,8 @@ class Api(object):
128
134
 
129
135
  def do_read(self,
130
136
  entity_id: int,
131
- options: dict[str, Any]) -> Optional[dict[str, Any]]:
137
+ options: dict[str, Any]
138
+ ) -> Optional[dict[str, Any]]:
132
139
  """
133
140
  Get a record in the requested model applying a filter and some
134
141
  options (like fields or context)
@@ -160,7 +167,8 @@ class Api(object):
160
167
 
161
168
  def do_fields_get(self,
162
169
  fields: list[str],
163
- options: dict[str, Any]) -> dict[str, dict]:
170
+ options: dict[str, Any]
171
+ ) -> dict[str, dict]:
164
172
  """
165
173
  Get the model fields
166
174
 
@@ -175,7 +183,8 @@ class Api(object):
175
183
 
176
184
  def do_search(self,
177
185
  filters: list[Union[BooleanOperator, Filter, str]],
178
- options: dict[str, Any]) -> list[int]:
186
+ options: dict[str, Any]
187
+ ) -> list[int]:
179
188
  """
180
189
  Search some records in the requested model applying a filter and some
181
190
  options (like fields or context)
@@ -191,7 +200,8 @@ class Api(object):
191
200
 
192
201
  def do_search_count(self,
193
202
  filters: list[Union[BooleanOperator, Filter, str]],
194
- options: dict[str, Any]) -> int:
203
+ options: dict[str, Any]
204
+ ) -> int:
195
205
  """
196
206
  Get the records count in the requested model applying a filter
197
207
 
@@ -206,7 +216,8 @@ class Api(object):
206
216
 
207
217
  def do_search_read(self,
208
218
  filters: list[Union[BooleanOperator, Filter]],
209
- options: dict[str, Any]) -> list[dict[str, Any]]:
219
+ options: dict[str, Any]
220
+ ) -> list[dict[str, Any]]:
210
221
  """
211
222
  Search some records in the requested model applying a filter and some
212
223
  options (like fields or context) and returns the found data
@@ -223,7 +234,8 @@ class Api(object):
223
234
 
224
235
  def do_create(self,
225
236
  values: dict[str, Any],
226
- options: dict[str, Any]) -> int:
237
+ options: dict[str, Any]
238
+ ) -> int:
227
239
  """
228
240
  Create a new record in the requested model and returns its ID
229
241
 
@@ -239,7 +251,8 @@ class Api(object):
239
251
  def do_update(self,
240
252
  entity_id: Union[int, list[int]],
241
253
  values: dict[str, Any],
242
- options: dict[str, Any]) -> bool:
254
+ options: dict[str, Any]
255
+ ) -> bool:
243
256
  """
244
257
  Update one or more records in the requested model
245
258
 
@@ -255,7 +268,8 @@ class Api(object):
255
268
 
256
269
  def do_delete(self,
257
270
  entity_id: Union[int, list[int]],
258
- options: dict[str, Any]) -> bool:
271
+ options: dict[str, Any]
272
+ ) -> bool:
259
273
  """
260
274
  Delete one or multiple records in the requested model
261
275
 
@@ -274,7 +288,8 @@ class Api(object):
274
288
  author_id: int,
275
289
  subject: str,
276
290
  body: str,
277
- options: dict[str, Any]) -> int:
291
+ options: dict[str, Any]
292
+ ) -> int:
278
293
  """
279
294
  Add a message to a model row
280
295