Python turns up in two places in our work: as a normal application backend, and as the language everything data-shaped is already written in. Both are production code here, with the same review, the same tests and the same deployment path as anything else.
Services
FastAPI or Django, chosen by how much of the framework you will actually use. A content-heavy admin with permissions and an ORM is a Django job. A narrow, fast API in front of a model or a data store usually is not.
Data and pipelines
Extraction, transformation and loading into the warehouse; scheduled reports; reconciliation jobs that compare two systems and shout when they disagree. These are the jobs that quietly become business-critical, so they get monitoring and alerting from the first day rather than after the first silent failure.
Getting a notebook into production
Most machine learning work starts as a notebook, and a notebook is not a system. We turn it into one: pinned dependencies, a defined input contract, tests on the transformation steps, a versioned artefact, and a rollback that does not require its author. That path is described in more detail under machine learning.
Speed, honestly
Python is fast enough for most of what people ask it to do, and when it is not, the answer is usually the database query rather than the language. When it really is the language, we move that one path to Go instead of rewriting the service around a hot loop.
What we insist on
- Dependencies pinned and rebuilt reproducibly
- Typed function signatures at module boundaries
- One config source, no settings read from three places
- Long-running work in a worker, never in a web request
Related: Node.js, BigQuery and warehousing, LLM development.