Skip to content

kimberly-emerson/drilling-api

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

10 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Drilling API

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.


Overview

drilling-api provides RESTful endpoints for core drilling domain and geographic entities:

  • Companies
  • Fields
  • Pads
  • Wells
  • Countries
  • States
  • Counties

Features

  • 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

Tech Stack

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

Project Structure

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

Domain Model

---
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"
Loading

Geographic Domain

Country → State → County

A strict hierarchy used to anchor drilling operations geographically.

Operational Domain

Company → Field → Pad → Well

The core drilling structure:

  • A Company operates multiple Fields
  • A Field contains multiple Pads
  • A Pad contains multiple Wells

Enums

PadType and WellStatus are modeled as string enums and referenced by Pads and Wells.

Users

A standalone entity for authentication/ownership (depending on your service design).


Getting Started

1. Clone the repository

git clone https://github.com/kimberly-emerson/drilling-api.git
cd drilling-api

2. Create environment variables

  • Create a .env file
  • .env.example provided

3. Install dependencies

Using PDM (recommended):

pdm install

Or Poetry:

poetry install

Database Setup

Run Alembic migrations

alembic upgrade head

Create a new migration

alembic revision --autogenerate -m "add Initial Schema"

Running the API

Local development

pdm run fastapi app.main:app --reload

API docs will be available at:

  • Swagger UI: http://localhost:8000/docs
  • ReDoc: http://localhost:8000/redoc

Example Endpoints

Create a Well

POST /api/v1/wells
{
  "name": "Well A-12",
  "pad_id": 1,
  "status": "drilling"
}

Get all Wells

GET /api/v1/wells

Architecture Notes

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).

Future Enhancements

  • Event‑driven integration (Kafka/SNS/SQS)
  • Role‑based access control
  • Caching layer (Redis)
  • OpenTelemetry tracing
  • CI/CD pipeline with linting, tests, and security scans

License

MIT or your preferred license.

Releases

No releases published

Packages

 
 
 

Contributors

Languages