This looks great! Question on the API/CLI - is there any provision for capturing frames (or even streams?) from Homekit cameras, or even triggering events or webhooks based on the cameras detecting motion?
HN user
j4mie
https://www.mtth.org
When we bought our house (1950s semidetached) it needed a full electrical rewire. I’m so glad I asked the electricians to run Ethernet all over the house at the same time, including to the ceiling in some rooms for WiFi access points.
Hi, author here. I have been building Django and DRF applications commercially for about fifteen years at DabApps, and this guidebook is an attempt to write down the architecture patterns we have arrived at, for projects that have to survive years of ongoing maintenance.
High level summary:
* We don’t hide Django under layers of abstraction, we just slice it up a bit differently than you would by default.
* Organise code by responsibility (readers, actions, interfaces, data) rather than by app.
* Put most business logic in plain functions, not in fat models or deep class hierarchies.
* Keep views thin: treat GET as "read some data" and POST as "do an action".
* Design endpoints around real frontend use cases (backend for frontend) instead of idealised resources.
* Control queries carefully to avoid performance traps.
Happy to answer questions!
Laravel’s ORM was originally inspired by my now-long-dead PHP projects Idiorm and Paris:
https://laravelpodcast.com/episodes/c7807d42/transcript (Search for “Paris” to find the relevant section)
https://github.com/j4mie/idiorm
https://github.com/j4mie/paris
Idiorm was started in early 2010 while I was still writing PHP professionally. I’d heard about Django from a talk @simonw gave at the FlashBrighton meet-up group in 2009 and immediately fell in love. Idiorm and Paris, although not direct attempts to duplicate Django’s ORM, came from frustration that such an elegant ORM and query builder didn’t exist in the PHP world.
So in a roundabout way, Laravel’s ORM was absolutely inspired by Django.
As a side note, I’m still doing Django 16 years later and love it more than ever.
It's worth noting that uv also supports a workflow that directly replaces pyenv, virtualenv and pip without mandating a change to a lockfile/pyproject.toml approach.
uv python pin <version> will create a .python-version file in the current directory.
uv virtualenv will download the version of Python specified in your .python-version file (like pyenv install) and create a virtualenv in the current directory called .venv using that version of Python (like pyenv exec python -m venv .venv)
uv pip install -r requirements.txt will behave the same as .venv/bin/pip install -r requirements.txt.
uv run <command> will run the command in the virtualenv and will also expose any env vars specified in a .env file (although be careful of precedence issues: https://github.com/astral-sh/uv/issues/9465)
Things that are down or impacted:
* Heroku and most of Salesforce
* Pipedrive: https://news.ycombinator.com/item?id=44234098
* OpenAI: https://status.openai.com/incidents/01JXCAW3K3JAE0EP56AEZ7CB...
* Lobsters: https://news.ycombinator.com/item?id=44234075
What's the common denominator?
"Please state the nature of the medical emergency"
For anyone who wants to understand the economics of hydrogen, I can't recommend this lecture [1] by Michael Liebreich highly enough.
Do you have a source for your statement about copper? The closest I can find is [1] "The expansion of electricity networks means that copper demand for grid lines more than doubles over the same period". That's a doubling of demand, not of total current circulation.
[1] https://www.iea.org/reports/the-role-of-critical-minerals-in...
From the article: "It adds LLM as a dependency, and takes advantage of LLM’s Python API to abstract over the details of talking to the models. This means sqlite-utils-ask can use any of the models supported by LLM or its plugins"
Ollama is supported in LLM via this plugin: https://github.com/simonw/llm-ollama
Previous discussion: https://news.ycombinator.com/item?id=31849787
Repeating my comment from that thread:
from diagrams import Diagram
from diagrams.aws.compute import EC2
with Diagram("Simple Diagram"):
EC2("web")
This has a very odd API. It's using (abusing?) context managers and contextvars to do weird spooky things that you could just as easily do with ordinary objects or functions.Glad someone got the reference!
I wrote a library a little while ago which is intended to be the simplest possible expression of this idea:
https://github.com/j4mie/hotmetal/
The core implementation is only 85 lines of Python, and has no imports at all, so works nicely on minimal/alternative Pythons like Micropython.
I'm using it on a medium-sized side project and it's shockingly productive compared to string templates. I don't think anyone is using it except me, though.
I've been heavily inspired by this styleguide over the years, but I still think it's a bit too complex. A few random thoughts:
- I think "services" is too much of a loaded term. I prefer "actions", and I always use the function-based style.
- I hate the naming of "APIs" in this document. They use the term "API" when they mean "endpoint" or "view".
- "Reuse serializers as little as possible" is the single best piece of advice when using DRF. The inline InputSerializer thing is brilliant.
- Having each each endpoint only handle a single HTTP verb is brilliant.
- URLs and views should be separate from all other business logic (models, actions etc).
- For read endpoints and associated business logic, I'd encourage https://www.django-readers.org/ (disclaimer: I'm the author).This makes me think you've never dealt with untyped Python code in a large production repo.
I run an agency and we maintain dozens of large, mature production projects (up to ~100k lines of code each).
I do understand the arguments and examples in the rest of your post, and intuitively they make sense, but practically I have almost never had an experience like the one you describe in 20+ years of working on Python codebases.
you have to dig into the function to find out what it's actually going to give you
This is exactly what I do, and it's just fine. I find it more difficult to build a mental model of what's happening in type-annotated code.
Like I said, it's subjective. That's why I find "types improve readability" arguments in posts such as this to be problematic. They are stated as basic axioms with no supporting data. It's easier to read for you.
The more I think about it, the more I think that the controversy around static type annotations in Python boils down to this:
Improved readability
This is very subjective, and is particularly sensitive in a language like Python which (rightly) has such a strong historical emphasis on readability above almost anything else.My personal opinion is that static type annotations are extremely detrimental to readability. They add jarring line noise that makes reading Python much less like reading English. Hitting a type annotation when reading Python forces my brain into little backtracking loops which hugely diminishes my ability to form a mental model of the code from a quick read.
I wonder if people who come to Python from other languages (that are already statically typed) are accustomed to the poor comprehension introduced by types, and so don't experience this drawback.
Black Midi is also the name of a rather excellent band: https://bmblackmidi.com/
from diagrams import Diagram
from diagrams.aws.compute import EC2
with Diagram("Simple Diagram"):
EC2("web")
This has a very odd API. It's using (abusing?) context managers and contextvars to do weird spooky things that you could just as easily do with ordinary objects or functions.See also https://hyperview.org/
You still haven't defined "large scale" or "better". And you haven't backed up your argument with any evidence.
What's your definition of "large codebases" here? My experience is that on Python codebases large (~100k lines) and small, type annotations are generally a net negative, particularly with a "rotating roster of many developers", because of their complexity and detrimental effect they have on readability. As the OP says, incorrect types are worse than no types at all.
Just to note: django-zen-queries doesn’t encourage you to execute querysets as soon as you define them, but rather just before you pass them to a template or serializer. This is a pattern we’ve found really useful.
(I’m the author of django-zen-queries)
I’m not a fan of the hyperbole in the article either. Some of the points are genuine problems but none of them should put off beginners.
Python is the most popular language on the planet because it’s a dynamic language, not in spite of it. If the type checker makes dynamic features difficult, ditch the type checker, not the dynamic features. I can’t wait for this pendulum to swing back the other way.
My (perhap controversial) take is that static typing in Python is also a form of premature optimisation. Code should be written without static types first, and static types should only be added when absolutely necessary. 99% of the time, it never will be.
If you’re delegating your load balancing to something else further up the stack and would prefer a simpler WSGI server than Gunicorn, Waitress is worth a look: https://github.com/pylons/waitress
Not to be confused with https://bedrockdb.com/
Is it still called OTA if there isn't any air?
Every web-based video chat I’ve used (including Google Meet and Slack) makes the fans on my decently-specced 2018 MacBook Pro spin up like it’s about to take off. I’ve tried Firefox, Chrome and Safari. Zoom (via the native Mac app) doesn’t do this. Does anyone know why browser-based video is so resource intensive?
A list of bugs found using this approach is here: https://www.manuelrigger.at/dbms-bugs/