Skip to content

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 (577c47a) with main (20b9176)

Summary

✅ 13 untouched benchmarks

@NeevCohen
Copy link
Contributor Author

Please review

Copy link
Contributor

@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-hooky pydantic-hooky bot added awaiting author revision awaiting changes from the PR author and removed ready for review labels Apr 30, 2024
@pydantic-hooky pydantic-hooky bot assigned NeevCohen and unassigned dmontagu Apr 30, 2024
@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
Collaborator

@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
Collaborator

@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
Contributor

@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
Contributor

@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.

@sydney-runkle
Copy link
Contributor

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
Contributor

@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: ...

@@ -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.

@NeevCohen NeevCohen requested a review from samuelcolvin May 31, 2024 15:06
@sydney-runkle
Copy link
Contributor

@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

@sydney-runkle sydney-runkle added ready for review and removed awaiting author revision awaiting changes from the PR author labels Jun 6, 2024
@sydney-runkle
Copy link
Contributor

@NeevCohen,

I think @samuelcolvin is quite busy this week - I'll take another pass + review this today. Great work thus far! I think we can definitely get this across the line soon 🚀.

@sydney-runkle
Copy link
Contributor

So I think the lingering questions / things to do here are:

  • Add more documentation for the title_priority logic
  • Decide if the title generator function should take an argument of type FieldInfo as well
  • Just want to circle back - are we ok with adding the title argument to the modify_model_json schema function? In general, I'm not super happy with the way we prep to modify JSON schema while building the core schema, so I'm not super excited about this change...

@NeevCohen, great job with the tests and existing docs!

@sydney-runkle
Copy link
Contributor

Add more documentation for the title_priority logic

@NeevCohen, lmk when you've done this and I can do a final review!

Decide if the title generator function should take an argument of type FieldInfo as well

I think this could be useful down the line, but it's not a breaking change to introduce later bc we can do signature introspection, so I don't think we need to include this in this PR.

Just want to circle back - are we ok with adding the title argument to the modify_model_json schema function? In general, I'm not super happy with the way we prep to modify JSON schema while building the core schema, so I'm not super excited about this change...

Yeah, the change I'm requesting above is major, I think this is ok to add for now!

@NeevCohen
Copy link
Contributor Author

NeevCohen commented Jun 12, 2024

@sydney-runkle regarding title_priority, after giving it some more thought I feel like it is not necessary. When I first implemented it, I did what alias_generator did. title_priority can be used to determine the priority of title over title_generator, but I think that specifying a title should always take precedence over title_generator, and there is no real use-case for title_priority, so I think I'll just remove it all together.

Regarding adding another FieldInfo parameter to the title_generator, I think that's a good idea and I can see how someone would want to generate a title based on more than just the name of the field, so I think I'll add it in this PR.

Let me know what you think.

@sydney-runkle
Copy link
Contributor

@sydney-runkle regarding title_priority, after giving it some more thought I feel like it is not necessary. When I first implemented it, I did what alias_generator did. title_priority can be used to determine the priority of title over title_generator, but I think that specifying a title should always take precedence over title_generator, and there is no real use-case for title_priority, so I think I'll just remove it all together.

Go for it. The more simple, the better. We can always add that down the line if some realistic use case is presented.

Regarding adding another FieldInfo parameter to the title_generator, I think that's a good idea and I can see how someone would want to generate a title based on more than just the name of the field, so I think I'll add it in this PR.

Sure thing. Ping me when you'd like a review, sounds great!

@sydney-runkle
Copy link
Contributor

@NeevCohen,

Hoping to release v2.8 before the end of June - any chance you'll have those updates in by then? Thanks for all of your work on this awesome new feature!

@sydney-runkle sydney-runkle added awaiting author revision awaiting changes from the PR author and removed ready for review labels Jun 20, 2024
* Refactor model_title_generator to accept the class as an arguments instead of the name of the class
@NeevCohen
Copy link
Contributor Author

NeevCohen commented Jun 22, 2024

Hey @sydney-runkle, sorry for the delay, I've been a little busy at work 😅
Anyway, I've implemented the changes you've requested and some more:

  1. I've removed title_priority from FieldInfo
  2. I've changed field_title_generator to accept the info of the field as well
  3. I've changed model_title_generator to accept the class itself, instead of just its name

@sydney-runkle
Copy link
Contributor

@NeevCohen,

No worries at all! Thanks so much for your work on this. I'll do a final review today 🚀 !

Copy link
Contributor

@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.

This is truly impressive. Great work on this significant feature!!

Thanks for your amazing work on this @NeevCohen!

@@ -1523,6 +1578,7 @@ def _dataclass_schema(
dataclass_bases_stack.enter_context(self._types_namespace_stack.push(dataclass_base))

# Pushing a config overwrites the previous config, so iterate though the MRO backwards
config = None
Copy link
Contributor

Choose a reason for hiding this comment

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

I have a suspicion that this isn't needed, but perhaps that's wrong

@sydney-runkle
Copy link
Contributor

If someone would like to add some more robust testing showcasing how to use both the field name and field info in the title generator function, that would be awesome! (great first issue)

@sydney-runkle sydney-runkle enabled auto-merge (squash) June 25, 2024 00:17
@sydney-runkle sydney-runkle merged commit 557be4d into pydantic:main Jun 25, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
awaiting author revision awaiting changes from the PR author relnotes-feature
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add Title Generator to Support Programmatic Titles
5 participants