How can I integrate pydantic v2 URLs in code? #6395
Replies: 6 comments 10 replies
-
I was about to start the exact same conversation before bumping on yours. The thing is, I'm wondering if this was even expected because I could not find any mention of this change neither in the doc nor the migration guide nor the future plan. I'm supporting the fact that having URLs inherit from This is not actually a big deal to me but I'm really wondering the reason behind (if any) and also to have this mentionned somewhere |
Beta Was this translation helpful? Give feedback.
-
A small correction: since pydantic.AnyHttpUrl has a defined python stub interface, type hinting using it actually works. However, I am still stuck either calling str(...) or .unicode_string() on it everywhere (not sure which one of the two is best-practice, or if there is a difference between them). It is certainly less practical than when they were strings. |
Beta Was this translation helpful? Give feedback.
-
pydantic.AnyHttpUrl field has a defined Python stub interface but you still need to convert it to a str before you can use it in most other ways. If you just need to convert the field to a string that you can pass to another function, then the str() function is probably the best choice. If you need to access the underlying Unicode string representation of the URL, then the .unicode_string() method is the best choice. Here is an example of how you can use the str() function to convert an AnyHttpUrl field to a str:
|
Beta Was this translation helpful? Give feedback.
-
Using an Annotated Validator to convert the serialised format to str seems to work for me. I'm new to pydantic though so there may be some downsides to this approach that I'm not seeing.
|
Beta Was this translation helpful? Give feedback.
-
Ran into this bug (which causes the url to be appended with "/") after fixing converting the url to str. url = "http://google.com"
assert str(HttpUrl(url)) == url # it fails with Pydantic 2.0 - 2.5.3 |
Beta Was this translation helpful? Give feedback.
-
This is one of the many things that is causing me grief in a move from pydantic v1 to pydantic v2. Now, I love pydantic v2, and its speed increases, but running into stuff like this makes me wish I hadn't moved my project to it. Making changes like these are fine for my code, but then when I have to require other developers to also make these little changes to their code, it causes them heartache and pain. @samuelcolvin if you would only give us a way to have the old behavior back, I would be eternally grateful. Or at least grateful for the next 70 years. If I could import something like the following to enable the behavior, it would ease our migration path. Or even a way to implement the old behavior with an equivalent class that we use in our own code. It doesn't matter. from pydantic.legacy import AnyHttpUrl Thank you for reading. |
Beta Was this translation helpful? Give feedback.
-
In pydantic v1, I could set a field to be "AnyHttpUrl", and the format would be validated. The field value would be of type AnyHttpUrl, but that itself is ultimately a str. However, in pydantic v2, instead the field value would be of type "pydantic_core._pydantic_core.Url'" which is not a str. In other words, the following would print "True" in pydantic v1 but "False" in pydantic v2:
In pydantic v1, the url is a str, which means it has all the methods of a str and passes all isinstance checks of a str. In pydantic v2, it is of a type which is an internal pydantic class. I have therefore no idea how to integrate this in my code. Consider the following example code:
In pydantic v1, this would just work. I have function which takes a str, so I pass in x.url to it. However, in pydantic v2, x.url is NOT a str anymore, it is actually of a type which is internal to pydantic. Therefore it does not seem feasible to use it in type hints, and I cannot really use its methods (I mean, it is a private class, I should not have to know its methods - my type checker/IDE certainly does not know). It seems like the only thing I can do is to convert x.url to str -
str(x.url)
- before using it - every single time I access the field.How are issues like this supposed to be resolved? Am I supposed to never access fields without converting them?
(I ran into this issue when trying to go from pydantic v1 to v2, and I got lots of errors saying, e.g.,
AttributeError: 'pydantic_core._pydantic_core.Url' object has no attribute 'startswith'
and similar. My code is obviously designed to handle the URLs as strings.)Beta Was this translation helpful? Give feedback.
All reactions