Skip to content

Commit d949ca2

Browse files
committed
Merge PR #551 into 17.0
Signed-off-by lmignon
2 parents 84b401f + 79aba45 commit d949ca2

13 files changed

Lines changed: 273 additions & 143 deletions

File tree

graphql_base/README.rst

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,9 @@ Usage
4444

4545
To use this module, you need to
4646

47-
- create your graphene schema
48-
- create your controller to expose your GraphQL endpoint, and
49-
optionally a GraphiQL IDE.
47+
- create your graphene schema
48+
- create your controller to expose your GraphQL endpoint, and optionally
49+
a GraphiQL IDE.
5050

5151
This module does not attempt to expose the whole Odoo object model. This
5252
could be the purpose of another module based on this one. We believe
@@ -56,12 +56,12 @@ exposed and needs to be tested when upgrading Odoo.
5656

5757
To start working with this module, we recommend the following approach:
5858

59-
- Learn `GraphQL basics <https://graphql.org/learn/>`__
60-
- Learn `graphene <https://graphene-python.org/>`__, the python library
61-
used to create GraphQL schemas and resolvers.
62-
- Examine the ``graphql_demo`` module in this repo, copy it, adapt the
63-
controller to suit your needs (routes, authentication methods).
64-
- Start building your own schema and resolver.
59+
- Learn `GraphQL basics <https://graphql.org/learn/>`__
60+
- Learn `graphene <https://graphene-python.org/>`__, the python library
61+
used to create GraphQL schemas and resolvers.
62+
- Examine the ``graphql_demo`` module in this repo, copy it, adapt the
63+
controller to suit your needs (routes, authentication methods).
64+
- Start building your own schema and resolver.
6565

6666
Building your schema
6767
--------------------
@@ -71,11 +71,11 @@ The schema can be built using native graphene types. An
7171
convenience. It is a graphene ``ObjectType`` with a default attribute
7272
resolver which:
7373

74-
- converts False to None (except for Boolean types), to avoid Odoo's
75-
weird ``False`` strings being rendered as json ``"false"``;
76-
- adds the user timezone to Datetime fields;
77-
- raises an error if an attribute is absent to avoid field name typing
78-
errors.
74+
- converts False to None (except for Boolean types), to avoid Odoo's
75+
weird ``False`` strings being rendered as json ``"false"``;
76+
- adds the user timezone to Datetime fields;
77+
- raises an error if an attribute is absent to avoid field name typing
78+
errors.
7979

8080
Creating GraphQL controllers
8181
----------------------------

graphql_base/__manifest__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
"website": "https://github.com/OCA/rest-framework",
1212
"depends": ["base"],
1313
"data": ["views/graphiql.xml"],
14-
"external_dependencies": {"python": ["graphene", "graphql_server"]},
14+
"external_dependencies": {"python": ["graphene", "graphql_server==3.0.0b7"]},
1515
"development_status": "Production/Stable",
1616
"maintainers": ["sbidoul"],
1717
"installable": True,

graphql_base/static/description/index.html

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -396,8 +396,8 @@ <h1><a class="toc-backref" href="#toc-entry-1">Usage</a></h1>
396396
<p>To use this module, you need to</p>
397397
<ul class="simple">
398398
<li>create your graphene schema</li>
399-
<li>create your controller to expose your GraphQL endpoint, and
400-
optionally a GraphiQL IDE.</li>
399+
<li>create your controller to expose your GraphQL endpoint, and optionally
400+
a GraphiQL IDE.</li>
401401
</ul>
402402
<p>This module does not attempt to expose the whole Odoo object model. This
403403
could be the purpose of another module based on this one. We believe
@@ -433,24 +433,24 @@ <h2><a class="toc-backref" href="#toc-entry-3">Creating GraphQL controllers</a><
433433
<tt class="docutils literal">odoo.addons.graphql_base.GraphQLControllerMixin</tt> class to help you
434434
build GraphQL controllers providing GraphiQL and/or GraphQL endpoints.</p>
435435
<pre class="code python literal-block">
436-
<span class="kn">from</span> <span class="nn">odoo</span> <span class="kn">import</span> <span class="n">http</span><span class="w">
437-
</span><span class="kn">from</span> <span class="nn">odoo.addons.graphql_base</span> <span class="kn">import</span> <span class="n">GraphQLControllerMixin</span><span class="w">
436+
<span class="kn">from</span><span class="w"> </span><span class="nn">odoo</span><span class="w"> </span><span class="kn">import</span> <span class="n">http</span><span class="w">
437+
</span><span class="kn">from</span><span class="w"> </span><span class="nn">odoo.addons.graphql_base</span><span class="w"> </span><span class="kn">import</span> <span class="n">GraphQLControllerMixin</span><span class="w">
438438

439-
</span><span class="kn">from</span> <span class="nn">..schema</span> <span class="kn">import</span> <span class="n">schema</span><span class="w">
439+
</span><span class="kn">from</span><span class="w"> </span><span class="nn">..schema</span><span class="w"> </span><span class="kn">import</span> <span class="n">schema</span><span class="w">
440440

441441

442-
</span><span class="k">class</span> <span class="nc">GraphQLController</span><span class="p">(</span><span class="n">http</span><span class="o">.</span><span class="n">Controller</span><span class="p">,</span> <span class="n">GraphQLControllerMixin</span><span class="p">):</span><span class="w">
442+
</span><span class="k">class</span><span class="w"> </span><span class="nc">GraphQLController</span><span class="p">(</span><span class="n">http</span><span class="o">.</span><span class="n">Controller</span><span class="p">,</span> <span class="n">GraphQLControllerMixin</span><span class="p">):</span><span class="w">
443443

444444
</span> <span class="c1"># The GraphiQL route, providing an IDE for developers</span><span class="w">
445445
</span> <span class="nd">&#64;http</span><span class="o">.</span><span class="n">route</span><span class="p">(</span><span class="s2">&quot;/graphiql/demo&quot;</span><span class="p">,</span> <span class="n">auth</span><span class="o">=</span><span class="s2">&quot;user&quot;</span><span class="p">)</span><span class="w">
446-
</span> <span class="k">def</span> <span class="nf">graphiql</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span><span class="w">
446+
</span> <span class="k">def</span><span class="w"> </span><span class="nf">graphiql</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span><span class="w">
447447
</span> <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_handle_graphiql_request</span><span class="p">(</span><span class="n">schema</span><span class="p">)</span><span class="w">
448448

449449
</span> <span class="c1"># The graphql route, for applications.</span><span class="w">
450450
</span> <span class="c1"># Note csrf=False: you may want to apply extra security</span><span class="w">
451451
</span> <span class="c1"># (such as origin restrictions) to this route.</span><span class="w">
452452
</span> <span class="nd">&#64;http</span><span class="o">.</span><span class="n">route</span><span class="p">(</span><span class="s2">&quot;/graphql/demo&quot;</span><span class="p">,</span> <span class="n">auth</span><span class="o">=</span><span class="s2">&quot;user&quot;</span><span class="p">,</span> <span class="n">csrf</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span><span class="w">
453-
</span> <span class="k">def</span> <span class="nf">graphql</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span><span class="w">
453+
</span> <span class="k">def</span><span class="w"> </span><span class="nf">graphql</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span><span class="w">
454454
</span> <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_handle_graphql_request</span><span class="p">(</span><span class="n">schema</span><span class="p">)</span>
455455
</pre>
456456
</div>

pydantic/README.rst

Lines changed: 16 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,13 @@ Pydantic
2929
|badge1| |badge2| |badge3| |badge4| |badge5|
3030

3131
This addon provides a utility method that can be used to map odoo record
32-
to a `Pydantic model <https://pydantic-docs.helpmanual.io/>`__.
32+
to a `Pydantic model (>= v2) <https://docs.pydantic.dev/>`__.
3333

3434
If you need to make your Pydantic models extendable at runtime, takes a
3535
look at the python package
3636
`extendable-pydantic <https://pypi.org/project/extendable_pydantic/>`__
37-
and the odoo addon
38-
`extendable <https://github.com/acsone/odoo-addon-extendable>`__
37+
and the `odoo addon
38+
extendable <https://pypi.org/project/odoo-addon-extendable>`__
3939

4040
**Table of contents**
4141

@@ -47,36 +47,28 @@ Usage
4747

4848
To support pydantic models that map to Odoo models, Pydantic model
4949
instances can be created from arbitrary odoo model instances by mapping
50-
fields from odoo models to fields defined by the pydantic model. To ease
51-
the mapping, the addon provide a utility class
52-
odoo.addons.pydantic.utils.GenericOdooGetter.
50+
fields from odoo models to fields defined by the pydantic model.
51+
52+
To ease the mapping, the addon provide an utility class (using
53+
``pydantic>2.0``) ``odoo.addons.pydantic.utils.PydanticOdooBaseModel``:
5354

5455
.. code:: python
5556
56-
import pydantic
57-
from odoo.addons.pydantic import utils
57+
from odoo.addons.pydantic.utils import PydanticOdooBaseModel
5858
59-
class Group(pydantic.BaseModel):
60-
name: str
6159
62-
class Config:
63-
orm_mode = True
64-
getter_dict = utils.GenericOdooGetter
60+
class Group(PydanticOdooBaseModel):
61+
name: str
6562
66-
class UserInfo(pydantic.BaseModel):
63+
class UserInfo(PydanticOdooBaseModel):
6764
name: str
6865
groups: List[Group] = pydantic.Field(alias="groups_id")
6966
70-
class Config:
71-
orm_mode = True
72-
getter_dict = utils.GenericOdooGetter
73-
7467
user = self.env.user
7568
user_info = UserInfo.from_orm(user)
7669
77-
See the official `Pydantic
78-
documentation <https://pydantic-docs.helpmanual.io/>`__ to discover all
79-
the available functionalities.
70+
See the official `Pydantic documentation <https://docs.pydantic.dev/>`__
71+
to discover all the available functionalities.
8072

8173
Known issues / Roadmap
8274
======================
@@ -108,8 +100,9 @@ Authors
108100
Contributors
109101
------------
110102

111-
- Laurent Mignon <laurent.mignon@acsone.eu>
112-
- Tris Doan <tridm@trobz.com>
103+
- Laurent Mignon <laurent.mignon@acsone.eu>
104+
- Tris Doan <tridm@trobz.com>
105+
- Pierre Verkest <pierre@verkest.fr>
113106

114107
Maintainers
115108
-----------

pydantic/__manifest__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
"data": [],
1616
"demo": [],
1717
"external_dependencies": {
18-
"python": ["pydantic", "contextvars", "typing-extensions"]
18+
"python": ["pydantic>=2.0", "contextvars", "typing-extensions"]
1919
},
2020
"installable": True,
2121
}

pydantic/readme/CONTRIBUTORS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
- Laurent Mignon \<<laurent.mignon@acsone.eu>\>
22
- Tris Doan \<<tridm@trobz.com>\>
3+
- Pierre Verkest \<<pierre@verkest.fr>\>

pydantic/readme/DESCRIPTION.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
This addon provides a utility method that can be used to map odoo record
2-
to a [Pydantic model](https://pydantic-docs.helpmanual.io/).
2+
to a [Pydantic model (>= v2)](https://docs.pydantic.dev/).
33

44
If you need to make your Pydantic models extendable at runtime, takes a
55
look at the python package
66
[extendable-pydantic](https://pypi.org/project/extendable_pydantic/) and
7-
the odoo addon
8-
[extendable](https://github.com/acsone/odoo-addon-extendable)
7+
the [odoo addon extendable](https://pypi.org/project/odoo-addon-extendable)

pydantic/readme/USAGE.md

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,25 @@
11
To support pydantic models that map to Odoo models, Pydantic model
22
instances can be created from arbitrary odoo model instances by mapping
3-
fields from odoo models to fields defined by the pydantic model. To ease
4-
the mapping, the addon provide a utility class
5-
odoo.addons.pydantic.utils.GenericOdooGetter.
3+
fields from odoo models to fields defined by the pydantic model.
4+
5+
6+
To ease the mapping, the addon provide an utility class (using `pydantic>2.0`) `odoo.addons.pydantic.utils.PydanticOdooBaseModel`:
67

78
``` python
8-
import pydantic
9-
from odoo.addons.pydantic import utils
9+
from odoo.addons.pydantic.utils import PydanticOdooBaseModel
1010

11-
class Group(pydantic.BaseModel):
12-
name: str
1311

14-
class Config:
15-
orm_mode = True
16-
getter_dict = utils.GenericOdooGetter
12+
class Group(PydanticOdooBaseModel):
13+
name: str
1714

18-
class UserInfo(pydantic.BaseModel):
15+
class UserInfo(PydanticOdooBaseModel):
1916
name: str
2017
groups: List[Group] = pydantic.Field(alias="groups_id")
2118

22-
class Config:
23-
orm_mode = True
24-
getter_dict = utils.GenericOdooGetter
25-
2619
user = self.env.user
2720
user_info = UserInfo.from_orm(user)
2821
```
2922

3023
See the official [Pydantic
31-
documentation](https://pydantic-docs.helpmanual.io/) to discover all the
24+
documentation](https://docs.pydantic.dev/) to discover all the
3225
available functionalities.

pydantic/static/description/index.html

Lines changed: 13 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -371,12 +371,12 @@ <h1 class="title">Pydantic</h1>
371371
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
372372
<p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/lgpl-3.0-standalone.html"><img alt="License: LGPL-3" src="https://img.shields.io/badge/licence-LGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/OCA/rest-framework/tree/17.0/pydantic"><img alt="OCA/rest-framework" src="https://img.shields.io/badge/github-OCA%2Frest--framework-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/rest-framework-17-0/rest-framework-17-0-pydantic"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external image-reference" href="https://runboat.odoo-community.org/builds?repo=OCA/rest-framework&amp;target_branch=17.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
373373
<p>This addon provides a utility method that can be used to map odoo record
374-
to a <a class="reference external" href="https://pydantic-docs.helpmanual.io/">Pydantic model</a>.</p>
374+
to a <a class="reference external" href="https://docs.pydantic.dev/">Pydantic model (&gt;= v2)</a>.</p>
375375
<p>If you need to make your Pydantic models extendable at runtime, takes a
376376
look at the python package
377377
<a class="reference external" href="https://pypi.org/project/extendable_pydantic/">extendable-pydantic</a>
378-
and the odoo addon
379-
<a class="reference external" href="https://github.com/acsone/odoo-addon-extendable">extendable</a></p>
378+
and the <a class="reference external" href="https://pypi.org/project/odoo-addon-extendable">odoo addon
379+
extendable</a></p>
380380
<p><strong>Table of contents</strong></p>
381381
<div class="contents local topic" id="contents">
382382
<ul class="simple">
@@ -395,34 +395,25 @@ <h1 class="title">Pydantic</h1>
395395
<h1><a class="toc-backref" href="#toc-entry-1">Usage</a></h1>
396396
<p>To support pydantic models that map to Odoo models, Pydantic model
397397
instances can be created from arbitrary odoo model instances by mapping
398-
fields from odoo models to fields defined by the pydantic model. To ease
399-
the mapping, the addon provide a utility class
400-
odoo.addons.pydantic.utils.GenericOdooGetter.</p>
398+
fields from odoo models to fields defined by the pydantic model.</p>
399+
<p>To ease the mapping, the addon provide an utility class (using
400+
<tt class="docutils literal">pydantic&gt;2.0</tt>) <tt class="docutils literal">odoo.addons.pydantic.utils.PydanticOdooBaseModel</tt>:</p>
401401
<pre class="code python literal-block">
402-
<span class="kn">import</span> <span class="nn">pydantic</span><span class="w">
403-
</span><span class="kn">from</span> <span class="nn">odoo.addons.pydantic</span> <span class="kn">import</span> <span class="n">utils</span><span class="w">
402+
<span class="kn">from</span><span class="w"> </span><span class="nn">odoo.addons.pydantic.utils</span><span class="w"> </span><span class="kn">import</span> <span class="n">PydanticOdooBaseModel</span><span class="w">
404403

405-
</span><span class="k">class</span> <span class="nc">Group</span><span class="p">(</span><span class="n">pydantic</span><span class="o">.</span><span class="n">BaseModel</span><span class="p">):</span><span class="w">
406-
</span> <span class="n">name</span><span class="p">:</span> <span class="nb">str</span><span class="w">
407404

408-
</span> <span class="k">class</span> <span class="nc">Config</span><span class="p">:</span><span class="w">
409-
</span> <span class="n">orm_mode</span> <span class="o">=</span> <span class="kc">True</span><span class="w">
410-
</span> <span class="n">getter_dict</span> <span class="o">=</span> <span class="n">utils</span><span class="o">.</span><span class="n">GenericOdooGetter</span><span class="w">
405+
</span><span class="k">class</span><span class="w"> </span><span class="nc">Group</span><span class="p">(</span><span class="n">PydanticOdooBaseModel</span><span class="p">):</span><span class="w">
406+
</span> <span class="n">name</span><span class="p">:</span> <span class="nb">str</span><span class="w">
411407

412-
</span><span class="k">class</span> <span class="nc">UserInfo</span><span class="p">(</span><span class="n">pydantic</span><span class="o">.</span><span class="n">BaseModel</span><span class="p">):</span><span class="w">
408+
</span><span class="k">class</span><span class="w"> </span><span class="nc">UserInfo</span><span class="p">(</span><span class="n">PydanticOdooBaseModel</span><span class="p">):</span><span class="w">
413409
</span> <span class="n">name</span><span class="p">:</span> <span class="nb">str</span><span class="w">
414410
</span> <span class="n">groups</span><span class="p">:</span> <span class="n">List</span><span class="p">[</span><span class="n">Group</span><span class="p">]</span> <span class="o">=</span> <span class="n">pydantic</span><span class="o">.</span><span class="n">Field</span><span class="p">(</span><span class="n">alias</span><span class="o">=</span><span class="s2">&quot;groups_id&quot;</span><span class="p">)</span><span class="w">
415411

416-
</span> <span class="k">class</span> <span class="nc">Config</span><span class="p">:</span><span class="w">
417-
</span> <span class="n">orm_mode</span> <span class="o">=</span> <span class="kc">True</span><span class="w">
418-
</span> <span class="n">getter_dict</span> <span class="o">=</span> <span class="n">utils</span><span class="o">.</span><span class="n">GenericOdooGetter</span><span class="w">
419-
420412
</span><span class="n">user</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">env</span><span class="o">.</span><span class="n">user</span><span class="w">
421413
</span><span class="n">user_info</span> <span class="o">=</span> <span class="n">UserInfo</span><span class="o">.</span><span class="n">from_orm</span><span class="p">(</span><span class="n">user</span><span class="p">)</span>
422414
</pre>
423-
<p>See the official <a class="reference external" href="https://pydantic-docs.helpmanual.io/">Pydantic
424-
documentation</a> to discover all
425-
the available functionalities.</p>
415+
<p>See the official <a class="reference external" href="https://docs.pydantic.dev/">Pydantic documentation</a>
416+
to discover all the available functionalities.</p>
426417
</div>
427418
<div class="section" id="known-issues-roadmap">
428419
<h1><a class="toc-backref" href="#toc-entry-2">Known issues / Roadmap</a></h1>
@@ -453,6 +444,7 @@ <h2><a class="toc-backref" href="#toc-entry-6">Contributors</a></h2>
453444
<ul class="simple">
454445
<li>Laurent Mignon &lt;<a class="reference external" href="mailto:laurent.mignon&#64;acsone.eu">laurent.mignon&#64;acsone.eu</a>&gt;</li>
455446
<li>Tris Doan &lt;<a class="reference external" href="mailto:tridm&#64;trobz.com">tridm&#64;trobz.com</a>&gt;</li>
447+
<li>Pierre Verkest &lt;<a class="reference external" href="mailto:pierre&#64;verkest.fr">pierre&#64;verkest.fr</a>&gt;</li>
456448
</ul>
457449
</div>
458450
<div class="section" id="maintainers">

pydantic/tests/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from . import test_pydantic_generic_odoo_getter

0 commit comments

Comments
 (0)