This project demonstrates MLOps best practices using the MNIST dataset.
data/
: Raw and processed datasrc/
: Source codedata/
: Data processing scriptsmodels/
: Model definition and trainingapi/
: REST API serviceutils/
: Utility functionstests/
: Unit tests
notebooks/
: Jupyter notebooks for explorationDockerfile
: Container definitiondocker-compose.yml
: Multi-container setupMakefile
: Build automationrequirements.txt
: Python dependenciesdvc.yaml
: Data version control
make setup
make train
make serve
curl -X POST http://localhost:3000/predict \ -H "Content-Type: application/json" \ -d '{"image": "iVBORw0KGgoAAAANSUhEUgAAAHEAAABxCAIAAABtHNuHAAAAiXpUWHRSYXcgcHJvZmlsZSB0eXBlIGV4aWYAAHjadY7LDcMwDEPvmiIjUB9L1jhFkADdoONHjl0EPfQdSEoQCNHxeZ+0DRhG1qJ7uqOwtJRXhY6JAizg4aWT5cqVpMY1k8oMnj1gz6EZfmjq3c+wCG+++y7VLofqrayg+2qUjVfyKYrvB/pnv6AL9Sws46Xpnn0AAAoGaVRYdFhNTDpjb20uYWRvYmUueG1wAAAAAAA8P3hwYWNrZXQgYmVnaW49Iu+7vyIgaWQ9Ilc1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI/Pgo8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJYTVAgQ29yZSA0LjQuMC1FeGl2MiI+CiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPgogIDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiCiAgICB4bWxuczpleGlmPSJodHRwOi8vbnMuYWRvYmUuY29tL2V4aWYvMS4wLyIKICAgIHhtbG5zOnRpZmY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vdGlmZi8xLjAvIgogICBleGlmOlBpeGVsWERpbWVuc2lvbj0iMTEzIgogICBleGlmOlBpeGVsWURpbWVuc2lvbj0iMTEzIgogICB0aWZmOkltYWdlV2lkdGg9IjExMyIKICAgdGlmZjpJbWFnZUhlaWdodD0iMTEzIgogICB0aWZmOk9yaWVudGF0aW9uPSIxIi8+CiA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg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"}'