- Python 75.3%
- Makefile 24.7%
| .vscode | ||
| app | ||
| data | ||
| docs | ||
| external | ||
| src/dtwin | ||
| tests | ||
| .env.example | ||
| .gitignore | ||
| .pre-commit-config.yaml | ||
| environment.lock.yml | ||
| environment.yml | ||
| Makefile | ||
| pyproject.toml | ||
| README.md | ||
Manufacturing Digital Twin
A small, clean starting point for modeling real manufacturing systems as graph-based digital twins.
The core idea is to represent production reality as a graph: machines, stations, materials, buffers, products, and orders become nodes; process steps, material flows, capacity constraints, and utilization relations become edges. This gives the project a practical foundation for reasoning about capacity, bottlenecks, and later machine-learning workflows.
The project wording is aligned with ERPNext Manufacturing. English ERPNext terms are the canonical reference because the local ERPNext system will be used in English; German terms are kept in the documentation as a reference for German production users.
Direction
The project starts with a clear separation of concerns:
- SQLModel models describe the manufacturing reality in typed Python and bridge Pydantic validation with SQL persistence.
dtwin.adaptersconnects to source systems, currently ERPNext.dtwin.modelsanddtwin.dataare reserved for the first ERPNext-shaped domain and persistence contracts.- NetworkX can provide an interpretable graph representation for analysis and validation.
- PyTorch Geometric provides the tensor-based graph representation for future graph learning.
PyG is part of the environment from the beginning, but it is not treated as the domain model itself. The goal is to keep the production twin explainable, testable, and ready for ML.
Future manufacturing data should follow ERPNext's shape:
Item/ ArtikelBill of Materials (BOM)/ StücklisteRouting/ Routing or Arbeitsplan-VorlageOperation/ ArbeitsgangWorkstation/ ArbeitsplatzWorkstation Type/ ArbeitsplatztypWork Order/ ArbeitsauftragJob Card/ Jobkarte
The earlier manual Department and Resource capacity slice has been removed from the active API. Realistic data should now enter through ERPNext-shaped concepts: Items, BOMs, Operations, Workstations, Work Orders, and Job Cards.
Environment
Create and activate the Conda environment:
conda env create -f environment.yml
conda activate dtwin
make install
The environment includes CPU-only PyTorch, PyTorch Geometric, NetworkX, pandas, FastAPI, SQLAlchemy, SQLModel, strict type-checking tools, and test/lint tooling.
make install installs the local dtwin package in editable mode into the configured Conda
environment. Dependencies are managed by Conda; the editable install only makes the project package
importable while keeping source changes live.
Development Checks
Run the standard checks before committing:
make ci
make clean
pre-commit run --all-files
Type checking is intentionally strict from the start. New project code should use explicit PEP 484/PEP 526 annotations and avoid unstructured dictionaries where a domain type would be clearer.
Streamlit App
Run the local exploration app:
make streamlit
The app lives under app/ and should stay thin: it collects inputs, calls typed project code from
src/dtwin, and displays results.
The app currently only provides a quiet Home page. Future Streamlit pages should inspect ERPNext connectivity, imported ERPNext-shaped data, graph projections, and capacity scenarios rather than maintaining a separate manual production master data model.
ERPNext API Access
Local ERPNext API credentials live in .env, which is ignored by Git. The commit-safe template is
.env.example.
Expected variables:
ERPNEXT_BASE_URL=http://localhost:8080
ERPNEXT_API_KEY=
ERPNEXT_API_SECRET=
ERPNEXT_TIMEOUT_SECONDS=30
Check the local API credentials without printing secrets:
make erpnext-whoami
List a DocType for a quick read smoke:
make erpnext-list DOCTYPE=Item
Never commit real ERPNext keys or paste them into logs. For production-like use, create a dedicated ERPNext integration user with only the required roles.
Lockfile
Refresh the concrete Conda environment export after dependency changes:
make lock