A lot of people have this misconception that Pydantic models are only useful for returning API responses. This is proliferated by all-in-one frameworks like FastAPI.

They are useful in and of themselves as internal business/domain objects, though. For a lot of cases I prefer lighter weight dataclasses that have less ceremony and runtime slowdown with the validation layer, but we use Pydantic models all over the place to guarantee and establish contracts for objects flowing thru our system, irrespective of external facing API layer.

One advantage of something like attrs/cattrs is you can use the regular attrs objects inside the module without all the serialisation/validation baggage, then use cattrs to do the serialisation at the edge where you need it.

Pydantic models are validating. Hence their natural place is interfaces with external systems, outside the reach of your typechecker.

dataclasses can do validation too and are faster

Dataclasses can skip validation, hence they are faster, when you can trust the inputs.