Live data from Hacker News

I use Attrs instead of Pydantic

threeofwands.com

61–70 of 76 posts

Re: I use Attrs instead of Pydantic

#62

Why should I use either? I hope that’s not an obtuse question.

I used Pydantic for a JSON API project recently and found it extremely useful.

Say your API accepts the following JSON POST:

    POST /create-entry
    {
        "author_id": 123,
        "title": "My new blog post",
        "body": "

...

", "tags": ["writing", "productivity"] }
Your API needs some validation here: some of these fields may be required. The "author_id" field must provide the ID of a valid author (that the API caller has permission to create posts for). The "tags" field must be an array.

More importantly: if there is a validation error, you need to provide an error message explaining what was wrong. This can be quite tricky to do well, especially for complex nested JSON objects.

Pydantic solves this problem really well - including returning detailed error messages helping show what went wrong.

Re: I use Attrs instead of Pydantic

#63
Pyantic and Cattrs both suffer with unacceptable issues and footguns. I have used Pydantic in production a lot and have played around with Cattrs. I've also looked at similar libraries like Dacite and marshmallow-dataclasses but none seem to be well thought out and mature.

* Neither Pydantic nor Cattrs handle unions like how I'd expect (although Cattrs has stronger guarantees in converting Unions)

  >>> class Y(BaseModel): pass
  >>> class X(BaseModel): pass
  >>> class Z(BaseModel): a: Union[X, Y]
  >>> Z(a=Y())
  Z(a=X()) # Converts Y to X implicitly
Cattrs has some problems with generics [1] [2]. Dacite and marshmallow-dataclasses don't support generics well either, with some issues around Union types.

They do work well for simple python types but what I'd like to see is guarantee that the serialisation operation is completely reversible and if not raise warning/exception.

[1] https://github.com/Tinche/cattrs/issues/149

[2] https://github.com/Tinche/cattrs/issues/44

Re: I use Attrs instead of Pydantic

#64

Earlier quoted context omitted.

As of 2021, there is now a complete Pydantic "CRUD stack" (ODMantic/SQLModel + FastAPI) that is ridiculously easy to get up and running with, and it has all of the features one might want in a brave new type safe world. By comparison, the system of tools around Attrs and Cattrs is a bit scattered and underdeveloped. I don't think there's a technical reason for it, that's just how it happened. It would be great to see…

SQLModel is brand new? why not just use sqlalchemy which is more mature?

SQLModel is a glue/shim layer for defining models that are both pydantic & SA compatible so you don't have to duplicate the effort.

Re: I use Attrs instead of Pydantic

#65
post #16

I absolutely hate the attrs “joke” names attr.ib and attr.s. That’s it. I simply can’t stand them, they drive me crazy. When I first saw them I wondered what the fuck “ib” meant. And the thing is, I’d expect every decent python programmer to have the same reaction: . is syntax; it simply can’t be part of a name. The library is called “attrs”, so why is it imported as “attr”? I simply don’t know what the author though…

The `attrs` authors address it in the documentation: https://www.attrs.org/en/stable/overview.html#on-the-attr-s-... At first, some people have a negative gut reaction to that; resembling the reactions to Python’s significant whitespace. And as with that, once one gets used to it, the readability and explicitness of that API prevails and delights. For those who can’t swallow that API at all, attrs comes with serious…

Imagine we're in an elevator together and I said "I'm gonna fart now" then I passed gas. Would my saying so make it better?

Admitting to doing something obnoxious does not make it less obnoxious. If anything, it makes it more so. It says the person knew what they were doing was a problem and they wanted to share the problem with everyone.

Re: I use Attrs instead of Pydantic

#66

I absolutely hate the attrs “joke” names attr.ib and attr.s. That’s it. I simply can’t stand them, they drive me crazy. When I first saw them I wondered what the fuck “ib” meant. And the thing is, I’d expect every decent python programmer to have the same reaction: . is syntax; it simply can’t be part of a name. The library is called “attrs”, so why is it imported as “attr”? I simply don’t know what the author though…

We need more cute aliases!

    @att.rs  # because it refers to both AT&T and Rust
    @at.trs  # musicians will love it
    @a.ttrs  # because I never remember where the dot goes
    @ttrs    # because @ looks like an a @lready
    @trs     # @ is “at”! Get it?
    @t.rs    # I like both Perl and Rust

Re: I use Attrs instead of Pydantic

#67

A little off topic, but the article mentions: > There are three reasons to use dataclasses over attrs: Another, not in this list, is that since it is in the standard library, co-workers/contributors are significantly more likely to have heard of dataclasses and already know its interface. Another reason, sort of along similar lines, is the fact that that dataclasses has fewer features than attrs - the author mentions…

In my experience way more Python devs know and are comfortable with attrs than dataclasses simply because its been around much longer.

Devs moving off of attrs generally go to pydantic in my experience.

Direct usage of dataclasses is literally zero across several python companies and many python codebases I have worked with.

Re: I use Attrs instead of Pydantic

#68
post #6

Earlier quoted context omitted.

You could have a look at Marshmallow perhaps? I use it to great effect with marshmallow-dataclass so I don't have to define the boiler-plate data classes separately to the validation/schema. Essentially the dataclass (with type-hints) becomes the data-validation specification. Links: https://pypi.org/project/marshmallow-dataclass/ https://pypi.org/project/marshmallow/

Thanks, I've had a look at Marshmallow in the past, but it's still doing the extra bits of dealing with the extra bits of serialization, it never really felt all that dissimilar to Pydantic. What I've really been looking for something that I can just use to check a data structure i'm passing in to a function call is valid. One use case is related to state machines, where I'm providing some data along with a transitio…

I have used a combo of attrs and fastjsonschema to do dataclass validation on instance construction.

It works great for a python stack and you can generate some clean looking code if you have a reusable data class package

Re: I use Attrs instead of Pydantic

#69

I absolutely hate the attrs “joke” names attr.ib and attr.s. That’s it. I simply can’t stand them, they drive me crazy. When I first saw them I wondered what the fuck “ib” meant. And the thing is, I’d expect every decent python programmer to have the same reaction: . is syntax; it simply can’t be part of a name. The library is called “attrs”, so why is it imported as “attr”? I simply don’t know what the author though…

We need more cute aliases! @att.rs # because it refers to both AT&T and Rust @at.trs # musicians will love it @a.ttrs # because I never remember where the dot goes @ttrs # because @ looks like an a @lready @trs # @ is “at”! Get it? @t.rs # I like both Perl and Rust

Haha, thanks! I think I'm warming to the idea now.

Re: I use Attrs instead of Pydantic

#70
post #3

Recently there's a strong tendency in the Python ecosystem to wrap perfectly fine idioms with even higher abstractions. Not sure if I like this, in the end it leads to a lot of cargo culting and people writing code they don't fully understand because it contains a lot of metaclass and runtime magic. But I understand that a lot of developers find this attractive, and type annotations really provide a good channel for…

For myself, better code completion is enough to lure me into the world of fully type-annotated python. I don't understand what you mean by saying "cargo cult", please enlighten me.

> fully type-annotated python

When I do that, I ask myself: "how is it different from writing Java code?". I don't have a clear answer. It becomes almost as verbose as Java. Java has better type validation (doesn't compile on mistake); it is faster (at least some payback for verbosity); real type system has additional advantages, for example using types as part of method signature.

Post reply on HN