Live data from Hacker News

Architecture Patterns with Python

cosmicpython.com

61–70 of 143 posts

Re: Architecture Patterns with Python

#61

Some parts of this book are extremely useful, especially when it's talking about concepts that are more general than Python or any other specific language -- such as event-driven architecture, commands, CQRS etc. That being said, I have a number issues with other parts of it, and I have seen how dangerous it can be when inexperienced developers take it as a gospel and try to implement everything at once (which is a c…

> I have seen how dangerous it can be when inexperienced developers take it as a gospel and try to implement everything at once

This book explicitly tells you not to do this.

> Similarly, service layers and unit of work are useful when you have complex applications that cover multiple complex use cases; but in a system consisting of small services with narrow responsibilities they quickly become overly bloated using this pattern. And don't even get me started with dependency injection in Python.

I have found service layers and DI really helpful for writing functional programs. I have some complex image-processing scripts in Python that I can use as plug-ins with a distributed image processing service in Celery. Service layer and DI just takes code from:

```python

dependency.do_thing(params)

```

To:

```python

do_thing(dependency, params)

```

Which ends up being a lot more testable. I can run image processing tasks in a live deployment with all of their I/O mocked, or I can run real image processing tasks on a mocked version of Celery. This lets me test all my different functions end-to-end before I ever do a full deploy. Also using the Result type with service layer has helped me propagate relevant error information back to the web client without crashing the program, since the failure modes are all handled in their specific service layer function.

Re: Architecture Patterns with Python

#62

Some parts of this book are extremely useful, especially when it's talking about concepts that are more general than Python or any other specific language -- such as event-driven architecture, commands, CQRS etc. That being said, I have a number issues with other parts of it, and I have seen how dangerous it can be when inexperienced developers take it as a gospel and try to implement everything at once (which is a c…

> And don't even get me started with dependency injection in Python. Could I get you started? Or could you point me to a place to get myself started? I primarily code in Python and I've found dependency injection, by which I mean giving a function all the inputs it needs to calculate via parameters, is a principle worth designing projects around.

[deleted]

Re: Architecture Patterns with Python

#63
post #38

I see Python at a nice glue language. I grew tired from the forced OOP mindset, where you have to enforce encapsulation and inheritance on everything, where you only have private fields which are set through methods. I grew tired of SOLID, clean coding, clean architecture, GoF patterns and Uncle Bob. I grew tired of the Kingdom of Nouns and of FizzBuzz Enterprise Editions. I now follow imperative or functional flows…

my favourite model is to write as many pure functions as possible, and then as many functions of 1-4 parameters that interact with the outside world, and only then create domain objects to wrap those - it keeps the unrelated complexity out of the domain and then I can also reuse those functions without having to create the entire object that I don't always need.

Pure functions are also way more testable

Re: Architecture Patterns with Python

#64
I started writing python professionally a few years ago. Coming from Kotlin and TypeScript, I found the language approachable but I was struggling to build things in an idiomatic fashion that achieved the loose coupling and testability that I was used to. I bought this book after a colleague recommended it and read it cover to cover. It really helped me get my head around ways to manage complexity in non trivial Python codebases. I don’t follow every pattern it recommends, but it opened my eyes to what’s possible and how to apply my experience in other paradigms to Python without it becoming “Java guy does Python”.

I cannot recommend it enough. Worth every penny.

Re: Architecture Patterns with Python

#65
post #59
post #51

Earlier quoted context omitted.

I've used SqlAlchemy in a biggish project. Had many problems, the worst ones were around session scoping and DB hitting season limits, but we had issues around the models too. The argument for hiding SqlAlchemy is nothing to do with "what if we change the DB"; that's done approximately never, and, even if so, you have some work to do, so do it at the time. YAGNI The argument is that SA models are funky things with la…

Based on that, do you find SQLModel[0] to be an elegant integration of these ideas, or a horrid ball of spaghetti? [0] https://sqlmodel.tiangolo.com/

SQLModel is supposed to be the best of both Pydantic and SQLAlchemy, but by design an SQLModel entity backed by a database table doesn't validate its fields on creation, which is the point of Pydantic.

https://github.com/fastapi/sqlmodel/issues/52#issuecomment-1...

Re: Architecture Patterns with Python

#66
post #38

Earlier quoted context omitted.

my favourite model is to write as many pure functions as possible, and then as many functions of 1-4 parameters that interact with the outside world, and only then create domain objects to wrap those - it keeps the unrelated complexity out of the domain and then I can also reuse those functions without having to create the entire object that I don't always need.

I am not convinced that domain driven design works. Objects doesn't model the real world well. Why we should think DDD model the real world or a business well? And why do we even need to model something? Computers are different than humans. I think we should be pragmatic and come with the best solution in terms of money/time/complexity. Not trying to mimick human thought using computers. After all a truck isn't mimic…

> I am not convinced that domain driven design works. Objects doesn't model the real world well.

DDD does not necessitate OOP. You can do DDD in functional languages. I think there's a whole F# book about it. So I think you can conclude that OOP doesn't model the world well, which may or may not be true, but I think it's not valid to extend the conclusion to DDD. Is there a DDD-inherent reason why you think DDD does not work?

> And why do we even need to model something?

Well I suppose it depends on your definition of "model", but aren't you by necessity modeling something when you write software? Somewhere in your software there is a user thingy/record/object/type/dictionary/struct which is an imperfect and incomplete representation of a real life person. I.e., a model.

Re: Architecture Patterns with Python

#67

Wow this book is a goldmine for architecture patterns. I love how easy it is to get into a topic and quickly grasp it. Having said that, from a practical and experience standpoint, using some of these patterns can really spiral out into an increased complexity and performance issues in Python, specially when you use already opinionated frameworks like Django which already uses the ActiveRecord pattern. I’ve been in c…

I found the book's use of modeling how to pilot an alien starship to be a little misleading, because a starship is a highly engineered product that functions in large part as a control mechanism for software. It comes with a clean design model already available for you to discover and copy.

Domain modeling should not be about copying the existing model -- it should be about improving on it using all the advantages software has over the physical and social technologies the new software product is meant to replace. People are smart, and in most projects, there are key aspects of the existing domain model that are excellent abstractions that can and should be part of the new model. It's important to understand what stakeholders are trying to achieve with their current system before attempting to replace it.

But the models used in the business and cultural world are often messy, outdated and unoptimized for code. They rely on a human to interpret the edge cases and underspecified parts. We should treat that as inspiration, not the end goal.

Re: Architecture Patterns with Python

#68
post #40

Earlier quoted context omitted.

In theory it's a nice abstraction, and the benefit is clear. In practice, your repository likely ends up forwarding its arguments one-for-one to SQLAlchemy's select() or session.query(). That's aside from their particular example of SQLAlchemy sessions, which is extra weird because a Session is already a repository, more or less. I mean, sure, there's a difference between your repository for your things and types you…

SQLAlchemy Session is actually a unit of work (UoW), which they also build on top. By the end of the book they are using their UoW to collect and dispatch events emitted by the services. How would they have done that if they just used SQLAlchemy directly? You might argue that they should have waited until they wanted their own UoW behaviour before actually implementing it, but that means by the time they need it they…

I understand not everyone agrees on what "repository" means. The session is a UoW (at two or three levels) and also a repository (in the sense of object-scoped persistence) and also like four other things.

I'm sort of tolerant of bits of Session leaking into things. I'd argue that its leaking pieces are the application-level things you'd implement, not versions of them from the lower layers that you need to wrap.

When users filter data and their filters go from POST submissions to some high-level Filter thing I'd pass to a repository query, what does that construct look like? Pretty much Query.filter(). When I pick how many things I want from the repository, it's Query.first() or Query.one(), or Query.filter().filter().filter().all().

Yes, it's tied to SQL, but only in a literal sense. The API would look like that no matter what, even if it wasn't. When the benefit outweighs the cost, I choose to treat it like it is the thing I should have written.

It isn't ideal or ideally correct, but it's fine, and it's simple.

Re: Architecture Patterns with Python

#69

Earlier quoted context omitted.

I am not convinced that domain driven design works. Objects doesn't model the real world well. Why we should think DDD model the real world or a business well? And why do we even need to model something? Computers are different than humans. I think we should be pragmatic and come with the best solution in terms of money/time/complexity. Not trying to mimick human thought using computers. After all a truck isn't mimic…

At its core, objects are just containers for properties, and exploiting that fact leads to easily understood systems than the one without. For example, at work I'm currently refactoring a test for parsing the CSV output of a system; as it stands it depends on hardcoded array indexes, which makes the thing a mess. Defining a few dataclasses here and there to model each entry of the CSV file, and then writing the test…

This is how I treat it as well by now. I'm not even certain if it's object oriented, or not or hybrid, or not, or whatever.

But in a small project at work that's mostly about orchestrating infrastructure components around a big central configuration it's just that. You define some dataclasses, or in our case Pydantic models to parse APIs or JSON configurations because then you can use type-aheads based off of types and it's more readable.

And then, if you notice you end up having a lot of "compute_some_thing(some_object)", you just make it an @property on that object, so you can use "some_object.some_thing". If you often move attributes of some foo-object to create some bar-object, why not introduce an @classmethod Foo.from_bar or @property Bar.as_foo? This also makes the relationship between Foo and Bar more explicit.

OOP doesn't have to be the horrible case some legacy Java Enterprise Projects make it to be. It can also be a bunch of procedural code with a few quaint objects in between, encapsulating closely related ideas of the domain.

Re: Architecture Patterns with Python

#70
post #57

Earlier quoted context omitted.

So far off from what actually happens. The type annotations provide an easy scaffolding for understand what the code does in detail when reading making code flow and logic less ambiguous. Reading Python functions in isolation, you might not even know what data/structure you’re getting as input… if there’s something that muddles up immediate clarity it’s ambiguity about what data code is operating on.

Type annotations are just like documentation though. Just because the annotation says int the function can still return a list.

Annotations can and should be checked. If I change a parameter type, other code using the function will now show errors. That won't happen with just documentation.
Post reply on HN