Skip to content
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

Add support for programmatic title generation #9183

Open
wants to merge 12 commits into
base: main
Choose a base branch
from

Conversation

NeevCohen
Copy link
Contributor

@NeevCohen NeevCohen commented Apr 7, 2024

Change Summary

Implement programmatic title generation via ConfigDict and Field

Related issue number

fix #4632

Checklist

  • The pull request title is a good summary of the changes - it will be used in the changelog
  • Unit tests for the changes exist
  • Tests pass on CI
  • Documentation reflects the changes where applicable
  • My PR is ready to review, please add a comment including the phrase "please review" to assign reviewers

Selected Reviewer: @dmontagu

Copy link

codspeed-hq bot commented Apr 7, 2024

CodSpeed Performance Report

Merging #9183 will not alter performance

Comparing NeevCohen:feature/title-generators (eff9e02) with main (e67524c)

Summary

✅ 13 untouched benchmarks

@NeevCohen
Copy link
Contributor Author

Please review

Copy link
Member

@sydney-runkle sydney-runkle left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @NeevCohen,

Great work, as usual!

I want to look again at _generate_schema.py and do a more in-depth look at your tests (great work btw, looks very thorough). This looks very promising though - I've included some initial feedback / some minor change requests.

One other change I'd like to see is the addition of some documentation in the concepts section of our docs!

pydantic/fields.py Outdated Show resolved Hide resolved
pydantic/_internal/_generate_schema.py Outdated Show resolved Hide resolved
pydantic/_internal/_generate_schema.py Outdated Show resolved Hide resolved
@NeevCohen
Copy link
Contributor Author

@sydney-runkle Thanks! I implemented the changes you requested.
Just one question, in what part of the concepts section do you think I should document this feature in?

Copy link
Member

@PrettyWood PrettyWood left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Question : why not having title be a string or a callable that returns a string instead of two params?
This could be extended to alias generation for example with a context passed as arg in case of callable

@NeevCohen
Copy link
Contributor Author

NeevCohen commented May 14, 2024

@PrettyWood I implemented it the way the original issue suggested, I'm fine with changing it if we decide that is the way we want to go.
Also, since this is similar to the alias and alias_generator parameters, I figured it would be better to be consistent with the API. IMO if we change title to be a string or a callable, we should also change alias to be the same way.

@PrettyWood
Copy link
Member

@NeevCohen totally agree. Probably a change for v3 then

@NeevCohen
Copy link
Contributor Author

@PrettyWood Awesome.
@sydney-runkle did you get a chance to do a more in-depth look?

@sydney-runkle
Copy link
Member

@NeevCohen,

Sorry for the delay, was out of the office last week. Looking now 🚀 !

Re your concepts docs question - your changes look great. We might want to add some more cross links with the config / fields sections, but it looks awesome thus far.

Copy link
Member

@sydney-runkle sydney-runkle left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@NeevCohen,

Great work here. Really impressed with the thorough testing, and great work on the docs as well.

docs/concepts/json_schema.md Outdated Show resolved Hide resolved
pydantic/fields.py Show resolved Hide resolved
pydantic/_internal/_generate_schema.py Show resolved Hide resolved
@sydney-runkle
Copy link
Member

Let's have @samuelcolvin do a final review of this given that he made the original feature request. Stay tuned!

NeevCohen and others added 2 commits May 21, 2024 23:44
Apply suggestion

Co-authored-by: Sydney Runkle <54324534+sydney-runkle@users.noreply.github.com>
@sydney-runkle
Copy link
Member

@NeevCohen,

Sorry for the delay here, we'll get this across the line for 2.8!

Copy link
Member

@samuelcolvin samuelcolvin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

overall looks like a good idea, but there are a few things to iron out.

from pydantic import BaseModel, Field


def make_title(field_name: str) -> str:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

my main question is whether the full field should be passed to the function, not just the name.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The full field as in the FieldInfo object? That we need to pass both FieldInfo and the name of the field since FieldInfo doesn't include the name.

Then the signature of make_title would be

def make_title(field_name: str, field_info: FieldInfo) -> str: ...

docs/concepts/json_schema.md Outdated Show resolved Hide resolved
docs/concepts/json_schema.md Show resolved Hide resolved
docs/concepts/json_schema.md Outdated Show resolved Hide resolved
from pydantic import BaseModel, ConfigDict


def make_title(field_name: str) -> str:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

again I would suggest we pass the cls itself, as well as the current name.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure.
What type do you reckon the cls parameter be annotated as? Type[BaseModel]?

@@ -33,11 +33,18 @@ class ConfigDict(TypedDict, total=False):
title: str | None
"""The title for the generated JSON schema, defaults to the model's name"""

class_title_generator: Callable[[str], str] | None
"""A callable that takes a class name and returns the title for it. Defaults to `None`."""
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should be clear about whether this works for:

  • pydantic models?
  • dataclasses?
  • typeddicts?

Copy link
Contributor Author

@NeevCohen NeevCohen May 31, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It works for all model and model-like (pydantic dataclass, builtin dataclass, typeddict) types. ConfigDict can be applied to all of them so IMO it's a little redundant. Changing the name to model_title_generator makes this even more clear I feel.

I will add more documentation if you feel it's necessary.

@@ -106,6 +108,8 @@ class FieldInfo(_repr.Representation):
validation_alias: The validation alias of the field.
serialization_alias: The serialization alias of the field.
title: The title of the field.
title_priority: Priority of the field's title. This affects whether a title generator is used.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you sure we need this? If so, I think it needs more documentation.

Copy link
Contributor Author

@NeevCohen NeevCohen May 31, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess I wanted to have a similar API to alias_generator and alias_priority. Do you think it's worth keeping? If so I'll add more documentation.

@sydney-runkle
Copy link
Member

@NeevCoehn,

Just a side note, we have a pydantic slack that you can join here for faster iteration on development questions, etc :).

Thanks for all of your great work!

@NeevCohen
Copy link
Contributor Author

@sydney-runkle Awesome! Will do!

Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add Title Generator to Support Programmatic Titles
5 participants