Skip to content

Commit 21edb43

Browse files
authored
Merge pull request #96 from dapper91/dev
- pydantic 2 support added
2 parents ddd90ba + 5b23343 commit 21edb43

File tree

6 files changed

+49
-24
lines changed

6 files changed

+49
-24
lines changed

CHANGELOG.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
Changelog
22
=========
33

4+
1.8.0 (2023-09-26)
5+
------------------
6+
7+
- pydantic 2 support added
8+
9+
410
1.7.0 (2023-08-10)
511
------------------
612

pjrpc/__about__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
__description__ = 'Extensible JSON-RPC library'
33
__url__ = 'https://github.com/dapper91/pjrpc'
44

5-
__version__ = '1.7.0'
5+
__version__ = '1.8.0'
66

77
__author__ = 'Dmitry Pershin'
88
__email__ = '[email protected]'

pjrpc/server/specs/extractors/pydantic.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ def extract_params_schema(self, method: MethodType, exclude: Iterable[str] = ())
3333
)
3434

3535
params_model = pd.create_model('RequestModel', **field_definitions)
36-
model_schema = params_model.schema(ref_template=self._ref_template)
36+
model_schema = params_model.model_json_schema(ref_template=self._ref_template)
3737

3838
parameters_schema = {}
3939
for param_name, param_schema in model_schema['properties'].items():
@@ -45,7 +45,7 @@ def extract_params_schema(self, method: MethodType, exclude: Iterable[str] = ())
4545
description=param_schema.get('description', UNSET),
4646
deprecated=param_schema.get('deprecated', UNSET),
4747
required=required,
48-
definitions=model_schema.get('definitions'),
48+
definitions=model_schema.get('$defs'),
4949
)
5050

5151
return parameters_schema
@@ -60,8 +60,8 @@ def extract_result_schema(self, method: MethodType) -> Schema:
6060
else:
6161
return_annotation = result.return_annotation
6262

63-
result_model = pd.create_model('ResultModel', result=(return_annotation, pd.fields.Undefined))
64-
model_schema = result_model.schema(ref_template=self._ref_template)
63+
result_model = pd.create_model('ResultModel', result=(return_annotation, ...))
64+
model_schema = result_model.model_json_schema(ref_template=self._ref_template)
6565

6666
result_schema = model_schema['properties']['result']
6767
required = 'result' in model_schema.get('required', [])
@@ -95,7 +95,7 @@ def extract_errors_schema(
9595
field_definitions[field_name] = (annotation, getattr(error, field_name, ...))
9696

9797
result_model = pd.create_model(error.message, **field_definitions)
98-
model_schema = result_model.schema(ref_template=self._ref_template)
98+
model_schema = result_model.model_json_schema(ref_template=self._ref_template)
9999

100100
data_schema = model_schema['properties'].get('data', UNSET)
101101
required = 'data' in model_schema.get('required', [])
@@ -109,7 +109,7 @@ def extract_errors_schema(
109109
title=error.message,
110110
description=inspect.cleandoc(error.__doc__) if error.__doc__ is not None else UNSET,
111111
deprecated=model_schema.get('deprecated', UNSET),
112-
definitions=model_schema.get('definitions'),
112+
definitions=model_schema.get('$defs'),
113113
),
114114
)
115115
return errors_schema

pjrpc/server/validators/pydantic.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ def __init__(self, coerce: bool = True, **config_args: Any):
2424
config_args.setdefault('extra', 'forbid')
2525

2626
# https://pydantic-docs.helpmanual.io/usage/model_config/
27-
self._model_config = type('ModelConfig', (pydantic.BaseConfig,), config_args)
27+
self._model_config = pydantic.ConfigDict(**config_args)
2828

2929
def validate_method(
3030
self, method: Callable[..., Any], params: Optional['JsonRpcParams'], exclude: Iterable[str] = (), **kwargs: Any,
@@ -43,15 +43,15 @@ def validate_method(
4343
signature = self.signature(method, tuple(exclude))
4444
schema = self.build_validation_schema(signature)
4545

46-
params_model = pydantic.create_model(method.__name__, **schema, __config__=self._model_config)
46+
params_model = pydantic.create_model(method.__name__, **schema, model_config=self._model_config)
4747

4848
bound_params = self.bind(signature, params)
4949
try:
5050
obj = params_model(**bound_params.arguments)
5151
except pydantic.ValidationError as e:
5252
raise base.ValidationError(*e.errors()) from e
5353

54-
return {attr: getattr(obj, attr) for attr in obj.__fields_set__} if self._coerce else bound_params.arguments
54+
return {attr: getattr(obj, attr) for attr in obj.model_fields} if self._coerce else bound_params.arguments
5555

5656
@ft.lru_cache(maxsize=None)
5757
def build_validation_schema(self, signature: inspect.Signature) -> Dict[str, Any]:

pyproject.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tool.poetry]
22
name = "pjrpc"
3-
version = "1.7.0"
3+
version = "1.8.0"
44
description = "Extensible JSON-RPC library"
55
authors = ["Dmitry Pershin <[email protected]>"]
66
license = "Unlicense"
@@ -46,7 +46,7 @@ jsonschema = {version = ">=3.0,<4.0", optional = true}
4646
kombu = { version = ">=5.1", optional = true }
4747
markupsafe = { version = "==2.0.1", optional = true }
4848
openapi-ui-bundles = { version = ">=0.1", optional = true }
49-
pydantic = {version = ">=1.7.0,<2.0", optional = true}
49+
pydantic = {version = ">=2.0", optional = true}
5050
requests = { version = ">=2.0", optional = true }
5151
starlette = { version = ">=0.25.0", optional = true }
5252
werkzeug = { version = ">=2.0", optional = true}

tests/server/resources/openapi-1.json

Lines changed: 31 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -434,9 +434,15 @@
434434
]
435435
},
436436
"result": {
437-
"title": "Result",
438-
"type": "string",
439-
"nullable": "true"
437+
"anyOf": [
438+
{
439+
"type": "string"
440+
},
441+
{
442+
"type": "null"
443+
}
444+
],
445+
"title": "Result"
440446
}
441447
},
442448
"required": [
@@ -532,12 +538,20 @@
532538
"type": "object",
533539
"properties": {
534540
"param1": {
535-
"title": "Param1",
536-
"type": "number"
541+
"anyOf": [
542+
{
543+
"type": "number"
544+
},
545+
{
546+
"type": "null"
547+
}
548+
],
549+
"default": null,
550+
"title": "Param1"
537551
},
538552
"param2": {
539-
"title": "Param2",
540553
"default": 1,
554+
"title": "Param2",
541555
"type": "integer"
542556
}
543557
}
@@ -876,8 +890,7 @@
876890
]
877891
},
878892
"result": {
879-
"title": "Result",
880-
"nullable": "true"
893+
"title": "Result"
881894
}
882895
},
883896
"required": [
@@ -1017,8 +1030,7 @@
10171030
]
10181031
},
10191032
"result": {
1020-
"title": "Result",
1021-
"nullable": "true"
1033+
"title": "Result"
10221034
}
10231035
},
10241036
"required": [
@@ -1190,9 +1202,16 @@
11901202
"type": "string"
11911203
},
11921204
"field2": {
1205+
"anyOf": [
1206+
{
1207+
"type": "integer"
1208+
},
1209+
{
1210+
"type": "null"
1211+
}
1212+
],
11931213
"title": "Field2",
1194-
"default": 1,
1195-
"type": "integer"
1214+
"default": 1
11961215
},
11971216
"field3": {
11981217
"$ref": "#/components/schemas/SubModel"

0 commit comments

Comments
 (0)