Let's talk

Backend

Hire Python Developers

Python engineers who build typed, tested services rather than scripts that grew into one.

Python earns its place where business logic is intricate enough to be worth expressing clearly. Sazinga Quote runs a formula pricing engine on FastAPI, and Field synchronises offline data from sales representatives who spend their day out of signal — both are cases where readable rules and strong typing matter more than raw request throughput.

The modern Python service is a typed one. Pydantic validating at the boundary, SQLAlchemy 2.0 with real annotations on the models, and a type checker in continuous integration turn a language famous for runtime surprises into one where most of the surprises are found before merge.

Async is where these services actually fail

A blocking call inside an async handler passes every test and then falls over under concurrency, because it holds the single event loop while it waits. It is the defining failure mode of the stack, and it is nearly always a library that was not written for async — a synchronous database driver, an HTTP client, an image or PDF routine.

The controls that work are unglamorous. Every I/O library is checked for an async implementation before it is adopted; anything that has none goes to a thread pool explicitly rather than by accident; and the connection pool is configured rather than defaulted, with a recycle interval and a pre-ping so a connection killed by a firewall or a database restart is discovered by the pool rather than by a user.

Three bugs that lived in one connection string

One helper in our quoting service exists purely to sanitise a database URL, and each of its three steps is a defect somebody spent an afternoon on.

The session timezone was set to Asia/Calcutta, a deprecated alias that PostgreSQL rejects outright on many builds; the canonical name works. Unknown query parameters in a SQLAlchemy URL are passed through as keyword arguments to the driver, so a stray timezone= in the string raises an error from a layer nobody was looking at. And SQLAlchemy 2 masks the password when a URL object is turned into a string, so a URL that has been round-tripped through str() authenticates with three asterisks and fails in a way that reads exactly like wrong credentials.

Configuration deserves the same scepticism as code, because it fails in the same places and has no tests.

Never reach for eval, even when the requirement is arithmetic

Our pricing engine evaluates user-authored formulas. The tempting implementation is eval, and it is a remote code execution vulnerability with a business justification attached.

What it does instead is parse the expression into an abstract syntax tree and walk it with an allow-list of operations — addition, subtraction, multiplication, division, unary minus, parentheses — resolving identifiers from a supplied context and refusing everything else. The identifiers are validated when the formula is saved rather than when it is evaluated, so a typo fails in front of the person who made it.

The detail that shows the work is real: users write formulas in the Excel idiom, where X means multiply. Rewriting that to an operator requires a rule that does not corrupt identifiers such as VALUE1 or VALUE10, which is a lookbehind on the preceding token rather than a naive replace. Requirements like that never appear in a specification; they appear in the first ten files a customer sends you.

What makes a Python test suite worth running

Two decisions matter more than coverage percentage. The application is exercised in-process through an ASGI transport rather than against a running server, so the suite needs no ports, no start-up wait and no cleanup of a stray process. And the tests run against a real PostgreSQL rather than SQLite, because half the behaviour worth testing — constraints, transactional semantics, decimal handling, timezone-aware columns — differs between them.

Money is Numeric, never a float, and the audit columns are defined once on a mixin so every table carries created and updated timestamps and the user who made the change, with the circular foreign key between the audit columns and the user table deferred so the schema can be created at all.

Where Python is the wrong choice

Where per-request latency is the product and the workload is CPU-heavy, because the global interpreter lock still shapes what you can do in one process. Where the deployment target rewards a single small binary. And where a team is tempted to use it for a large application without adopting typing and a checker — Python scales to big systems on discipline, and without it produces exactly the codebase its reputation describes.

What we interview for

The fastest filter is types and async. Ask what the type checker told them about their last codebase, how they handled a blocking library inside an async service, and how their migrations run in deployment. Anyone who describes Python as a scripting language is usually describing their own experience of it rather than the language.

Then two more. What is in your requirements file that is pinned to an exact version, and why — there is always one, and the reason is always a story. And how do you make a migration reversible when it drops a column.

Teams are built for companies in the United States and the Gulf — the UAE, Saudi Arabia, Qatar, Kuwait, Bahrain and Oman. The engineers are in Pune, which matters mostly for the clock. Dubai is ninety minutes behind us and Riyadh two and a half hours, so a Gulf team shares almost the whole working day. New York is nine and a half hours behind, so American engagements run on a written handover and one fixed overlap window rather than on a standing call — a real constraint, and better stated than discovered.

What these engineers do

  • FastAPI and Pydantic v2 with typed schemas and a generated OpenAPI contract
  • SQLAlchemy 2.0, Alembic migrations and query performance held under load
  • Async Python done properly - concurrency limits, pooling and blocking call audits
  • Celery or ARQ workers for scheduled and long-running work
  • pytest with real fixtures, plus mypy or Pyright enforced in CI

Delivered AI-first

AI assistance is used to generate Pydantic models and endpoint scaffolding from a schema, to write test fixtures and parametrised test cases, and to add type annotations to untyped legacy modules ahead of a refactor. Async correctness is deliberately kept as human work, because a blocking call inside an async handler passes every test and then falls over under concurrency. Review discipline is unchanged. The measurable effect is throughput per engineer, not fewer reviews.

Built with Python at Sazinga

These are our own production applications, not client references — which is why the engineers have operated them, not just written them.

Python engineers in client teams

Tell us what the Python work is.

Roughly what it involves, the seniority you need, and when it has to start. We will say what it takes to staff it, or say honestly that we are not the right people for it.

A person reads every enquiry and replies within one working day.