New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
schema ref_template #1480
schema ref_template #1480
Conversation
41e3eb5
to
de3e038
Compare
Codecov Report
@@ Coverage Diff @@
## master #1480 +/- ##
=======================================
Coverage 99.90% 99.90%
=======================================
Files 21 21
Lines 4000 4003 +3
Branches 798 799 +1
=======================================
+ Hits 3996 3999 +3
Misses 3 3
Partials 1 1
Continue to review full report at Codecov.
|
pydantic/schema.py
Outdated
if ref_template: | ||
m_schema = {'$ref': ref_template.substitute(model_name=model_name)} | ||
else: | ||
m_schema = {'$ref': ref_prefix + model_name} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could probably be done more elegantly.
Some additional things I could do.
- regular
ref_prefix
s could also be resolved using the samestring.Template
method."#/components/schemas/${model_name}"
. Could avoid thisif else
conditional. - better error message if a bad template is passed.
- coerce a regular string into a template instead of taking an actual
string.Template
object.
pydantic/schema.py
Outdated
@@ -69,6 +70,7 @@ def schema( | |||
title: Optional[str] = None, | |||
description: Optional[str] = None, | |||
ref_prefix: Optional[str] = None, | |||
ref_template: Optional[string.Template] = None, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With no extra handling...
- If
str
is passed instead of astring.Template
anAttributeError
will be raised.
AttributeError: 'str' object has no attribute 'substitute'
- If
string.Template
is passed that doesn't have the$model_name
identifier aKeyError
will be raised.
KeyError: 'foo_bar'
https://docs.python.org/3/library/string.html#template-strings
tests/test_schema.py
Outdated
def test_schema_with_ref_template(): | ||
class Foo(BaseModel): | ||
a: str | ||
|
||
class Bar(BaseModel): | ||
b: Foo | ||
|
||
class Baz(BaseModel): | ||
c: Bar | ||
|
||
model_schema = schema([Bar, Baz], ref_template=string.Template('/schemas/${model_name}.json#/')) | ||
assert model_schema == { | ||
'definitions': { | ||
'Baz': { | ||
'title': 'Baz', | ||
'type': 'object', | ||
'properties': {'c': {'$ref': '/schemas/Bar.json#/'}}, | ||
'required': ['c'], | ||
}, | ||
'Bar': { | ||
'title': 'Bar', | ||
'type': 'object', | ||
'properties': {'b': {'$ref': '/schemas/Foo.json#/'}}, | ||
'required': ['b'], | ||
}, | ||
'Foo': { | ||
'title': 'Foo', | ||
'type': 'object', | ||
'properties': {'a': {'title': 'A', 'type': 'string'}}, | ||
'required': ['a'], | ||
}, | ||
} | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm happy to add more tests.
sorry for the slow reply, as I mentioned on the issue #1479, I think a normal It's not necessary, and |
Makes sense, and thanks for the reminder. I'll try to update this over the weekend. |
0fc49f4
to
82631c8
Compare
pydantic/schema.py
Outdated
@@ -76,6 +77,7 @@ def schema( | |||
title: Optional[str] = None, | |||
description: Optional[str] = None, | |||
ref_prefix: Optional[str] = None, | |||
ref_template: Optional[str] = None, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@samuelcolvin I was just following the existing pattern here.
But should I set the default_template
as the default argument for ref_template
?
ref_template: Optional[str] = '#/definitions/{model}',
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think better to switch to ref_template: str = '#/definitions/{model}',
, the others are only optional because they really can be optional.
The only advantage of making this optional would be that ref_template
could take priority over ref_prefix
if it's not None
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
I don't know if it would have been better to keep a REF_TEMPLATE
constant and use that as the default for all the ref_template
defaults, but it looked like doing that prevented the editor help text from showing what the actual value was.
50378db
to
cf5154e
Compare
Getting a failure on > raise validation_error
E pydantic.error_wrappers.ValidationError: 1 validation error for ConSetModelMax
E v
E value is not a valid set (type=type_error.set)
pydantic/main.py:346: ValidationError |
See #1682 |
@samuelcolvin I still need to update the schema-customization section docs. I'll do that tonight or tomorrow. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just need documentation and the tweak discussed here, otherwise looks good.
pydantic/schema.py
Outdated
@@ -76,6 +77,7 @@ def schema( | |||
title: Optional[str] = None, | |||
description: Optional[str] = None, | |||
ref_prefix: Optional[str] = None, | |||
ref_template: Optional[str] = None, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think better to switch to ref_template: str = '#/definitions/{model}',
, the others are only optional because they really can be optional.
The only advantage of making this optional would be that ref_template
could take priority over ref_prefix
if it's not None
.
use a string.Template instead of a ref_prefix to allow for more varied`$ref`s to be created. Template string is expected to have $model_name `identifier `
if no `ref_prefix` provided, use the `template_default`
test name change test for key error
This is looking great, but you still need to:
|
What are the cases that need to be covered? |
look at the codecov report above. |
thanks so much. |
Change Summary
Adds a
ref_template
option toschema
generation that takes astring.Template
and substitutes themodel_name
when generating$ref
s to other schemas.my_model.schema(ref_template=string.Template("/foo/${model_name}.json#/bar"))
Edit:
Updated to just use a regular
.format()
template.#1479 (comment)
Related issue number
#1479
Checklist
changes/<pull request or issue id>-<github username>.md
file added describing change(see changes/README.md for details)