A lightweight, domain‑driven Python FastAPI microservice for managing oil & gas drilling operations.
It demonstrates clean architecture, modular design, SQLAlchemy ORM modeling, Alembic migrations, and production‑ready API patterns suitable for real microservice environments.
drilling-api provides RESTful endpoints for core drilling domain and geographic entities:
- Companies
- Fields
- Pads
- Wells
- Countries
- States
- Counties
- FastAPI application with automatic OpenAPI documentation
- Async‑friendly architecture
- SQLAlchemy ORM models with Alembic migrations
- Pydantic v2 schemas with strict validation
- Service layer architecture
- Modular routers per domain entity
- Centralized configuration and dependency injection
- PostgreSQL backend with environment‑based configuration
- Docker‑ready structure for local or cloud deployment
- TODO: Structured logging and error handling
- TODO: Pytest testing suites
| Layer | Technology |
|---|---|
| API Framework | FastAPI |
| ORM | SQLAlchemy 2.x |
| Migrations | Alembic |
| Database | PostgreSQL |
| Validation | Pydantic v2 |
| Packaging | PDM or Poetry |
| Runtime | Python 3.14+ |
| Deployment | Docker / Kubernetes‑ready |
A clean layout:
drilling-api/
│
├── app/
│ ├── api/
│ │ ├── v1/
│ │ ├──── endpoints/
│ │ │ ├── companies.py
│ │ │ └── counties.py
│ │ │ └── countries.py
│ │ │ ├── fields.py
│ │ │ ├── pads.py
│ │ │ └── states.py
│ │ │ └── user.py
│ │ │ ├── wells.py
│ │ ├──── services/
│ │ │ ├── base.py
│ │ │ ├── company_service.py
│ │ │ ├── county_service.py
│ │ │ ├── country_service.py
│ │ │ ├── field_service.py
│ │ │ ├── mixins.py
│ │ │ ├── pad_service.py
│ │ │ ├── state_service.py
│ │ │ ├── user_service.py
│ │ │ └── well_service.py
│ │ └── dependencies.py
│ │
│ ├── core/
│ │ ├── settings/
│ │ │ ├── base.py
│ │ │ ├── dev.py
│ │ │ ├── prod.py
│ │ │ └── test.py
│ │ ├── config_engine_options.py
│ │ ├── database.py
│ │ └── security.py
│ │
│ ├── db/
│ │ ├── base.py
│ │ ├── audit_base.py
│ │ ├── engine.py
│ │ ├── mixins.py
│ │ ├── session.py
│ │ └── urls.py
│ │
│ ├── models/
│ │ ├── enums/
│ │ │ ├── pad_types.py
│ │ │ ├── strenums.py
│ │ │ └── well_status.py
│ │ ├── company.py
│ │ ├── country.py
│ │ ├── county.py
│ │ ├── field.py
│ │ ├── pad.py
│ │ ├── state.py
│ │ ├── user.py
│ │ └── well.py
│ │
│ ├── schemas/
│ │ ├── company.py
│ │ ├── country.py
│ │ ├── county.py
│ │ ├── field.py
│ │ ├── mixins.py
│ │ ├── pad.py
│ │ ├── state.py
│ │ ├── user.py
│ │ └── well.py
│ │
│ └── main.py
│
├── alembic.ini
├── .LICENSE
├── pyproject.toml
└── README.md
---
config:
theme: neo
---
erDiagram
%% ============================
%% Geographic Hierarchy
%% ============================
COUNTRY ||--o{ STATE : "has many"
STATE ||--o{ COUNTY : "has many"
COUNTRY {
int id PK
string name
string code
}
STATE {
int id PK
string name
string code
int country_id FK
}
COUNTY {
int id PK
string name
int state_id FK
}
%% ============================
%% Operational Hierarchy
%% ============================
COMPANY ||--o{ FIELD : "operates"
FIELD ||--o{ PAD : "contains"
PAD ||--o{ WELL : "contains"
COMPANY {
int id PK
string name
string country
}
FIELD {
int id PK
string name
int company_id FK
int county_id FK
}
PAD {
int id PK
string name
int field_id FK
string pad_type
}
WELL {
int id PK
string name
int pad_id FK
string status
float depth
}
%% ============================
%% Users
%% ============================
USER {
int id PK
string username
string email
string hashed_password
bool is_active
}
%% ============================
%% Enums (Referenced by Models)
%% ============================
PAD_TYPES {
string type
}
WELL_STATUS {
string status
}
PAD }o--|| PAD_TYPES : "pad_type"
WELL }o--|| WELL_STATUS : "status"
Country → State → County
A strict hierarchy used to anchor drilling operations geographically.
Company → Field → Pad → Well
The core drilling structure:
- A Company operates multiple Fields
- A Field contains multiple Pads
- A Pad contains multiple Wells
PadType and WellStatus are modeled as string enums and referenced by Pads and Wells.
A standalone entity for authentication/ownership (depending on your service design).
git clone https://github.com/kimberly-emerson/drilling-api.git
cd drilling-api
- Create a
.envfile .env.exampleprovided
Using PDM (recommended):
pdm installOr Poetry:
poetry installalembic upgrade headalembic revision --autogenerate -m "add Initial Schema"pdm run fastapi app.main:app --reloadAPI docs will be available at:
- Swagger UI:
http://localhost:8000/docs - ReDoc:
http://localhost:8000/redoc
POST /api/v1/wells
{
"name": "Well A-12",
"pad_id": 1,
"status": "drilling"
}
GET /api/v1/wells
This service demonstrates:
- Domain‑driven design: each drilling entity is isolated into its own model, schema, service, and router.
- Separation of concerns: API layer → service layer → ORM layer.
- Extensibility: new drilling entities can be added with minimal boilerplate.
- Production readiness: logging (TODO), config management, migrations, and containerization (TODO).
- Event‑driven integration (Kafka/SNS/SQS)
- Role‑based access control
- Caching layer (Redis)
- OpenTelemetry tracing
- CI/CD pipeline with linting, tests, and security scans
MIT or your preferred license.