Python · The language, not just syntax

How do you structure a Python project for production?

Mediumproject layoutpackagingarchitectureUpdated Oct 2026
Quiz this track

Short answer

Use a src layout with an installable package, keep tests outside the package, centralise configuration in pyproject.toml, and separate domain logic from transport and infrastructure code.

A src layout prevents accidental imports from the working directory, because tests import the installed package rather than a same-named folder. That catches packaging mistakes early and keeps local behaviour close to CI.

text
billing/
  pyproject.toml
  src/billing/
    __init__.py
    domain/
    services/
    adapters/
    config.py
    __main__.py
  tests/
    unit/
    integration/
  README.md
Domain code has no framework imports. Adapters handle HTTP, database and queue details, and tests mirror the boundaries.

Boundaries that pay off

  • Domain layer: pure business rules with no I/O, easy to unit test
  • Services: orchestration of domain objects and ports
  • Adapters: database, HTTP clients, queues and framework glue
  • Entry points: CLI or server bootstrap, declared in pyproject.toml

Avoid import-time side effects such as connecting to a database or reading secrets. They make tests slow and imports order-dependent. Load configuration explicitly in the entry point and pass it inward.

Do not over-engineer for a small script. A single module with clear functions is fine until real boundaries and multiple callers justify the structure.

Follow-ups you should expect

Interviewers use these to check whether the first answer was understanding or memorisation.

  1. 1Why is a src layout preferable to a flat package directory?
  2. 2What belongs in the domain layer versus an adapter?
  3. 3Why avoid side effects at import time?
  4. 4How do entry points work in pyproject.toml?

Say it in the interview

I use a src layout so tests import the installed package, which catches packaging problems early. I separate pure domain logic from orchestration and adapters, so business rules can be tested without a database or HTTP server. Configuration is loaded in the entry point and passed inward rather than read at import time. For a small script I keep it simple and only add layers when there are real boundaries.

Use this as a model, not a script. Saying it in your own words is what makes it survive follow-up pressure.

Related questions

Reading is step one

Now say it out loud.

Understanding an answer and delivering it under pressure are different skills. Rehearse this topic in a live Python mock interview and get scored feedback on depth, clarity and confidence.