Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix package dependency issues #36

Open
wants to merge 32 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 29 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
f8ddadf
Unit Testing Production ML Code - Test Preprocessing
ChristopherGS Nov 23, 2019
dcb0636
Unit Testing Production ML Code - Test Config
ChristopherGS Nov 24, 2019
fd102c9
Unit Testing Production ML Code - Test Input Validation
ChristopherGS Nov 24, 2019
2ca8913
Unit Testing Production ML Code - Test Model Quality
ChristopherGS Nov 24, 2019
ebf7691
Unit Testing Production ML Code - Add Tooling
ChristopherGS Nov 24, 2019
8c6dd59
Integration Testing Production ML Code - Initial Setup
ChristopherGS Dec 1, 2019
031ac57
Integration Testing Production ML Code - Create Integration Tests
ChristopherGS Dec 1, 2019
cf7a3f6
Advanced Testing Production ML Code - Create Differential Tests
ChristopherGS Dec 7, 2019
110fdc7
Advanced Testing Production ML Code - Create Differential Tests In Do…
ChristopherGS Dec 8, 2019
8891397
Shadow Mode ML Code - Initial Setup
ChristopherGS Dec 15, 2019
33c8318
Shadow Mode ML Code - Implementation and Tests
ChristopherGS Dec 21, 2019
fb83a3e
Shadow Mode ML Code - Asynchronous Implementation
ChristopherGS Dec 21, 2019
46f8fa4
Shadow Mode ML Code - Populate DB Script
ChristopherGS Dec 28, 2019
c0f42d5
Shadow Mode ML Code - Analyse Results
ChristopherGS Jan 4, 2020
ae898dd
Monitoring with Prometheus - Basic Setup
ChristopherGS Jan 4, 2020
9f70b84
Monitoring with Prometheus - Add Simple Metrics
ChristopherGS Jan 4, 2020
8750b1a
Monitoring with Prometheus - Setup Grafana
ChristopherGS Jan 4, 2020
6126865
Monitoring with Prometheus - Basic Infrastructure Metrics
ChristopherGS Jan 5, 2020
2bd17e4
Monitoring with Prometheus - Instrument Project API
ChristopherGS Jan 5, 2020
e794349
Monitoring with Prometheus - Build Grafana Dashboards for Model
ChristopherGS Jan 12, 2020
621b892
Monitoring Logs with the Elastic Stack - Basic ELK Setup
ChristopherGS Jan 12, 2020
3a9bbf4
Monitoring Logs with the Elastic Stack - Integrate with API
ChristopherGS Feb 8, 2020
f72cfdb
Monitoring Logs with the Elastic Stack - Create Kibana Dashboard for …
ChristopherGS Feb 15, 2020
0a0f131
Not Part Of Course - Add CI
ChristopherGS Feb 15, 2020
c4c0bc8
Update readme
ChristopherGS Feb 16, 2020
0fc27a1
update requirements for research phase and exercise notebooks (#35)
ChristopherGS Apr 8, 2022
e5f959c
update dependencies and use updated regression model from deployments
ChristopherGS Apr 8, 2022
9a134fc
update feature engine api usage
ChristopherGS Apr 8, 2022
2a01c6c
remove failing test
ChristopherGS Apr 9, 2022
28c56f6
fix docker compose exercise dependencies
ChristopherGS Apr 9, 2022
4606a9c
key dependency adjustments
ChristopherGS Apr 9, 2022
b8a73a9
fix elk exercise requirements
ChristopherGS Apr 9, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
127 changes: 127 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
version: 2.1

jobs:
test_gradient_model_py36:
docker:
- image: circleci/python:3.6.9
working_directory: ~/project/packages/gradient_boosting_model
steps:
- checkout:
path: ~/project
- run:
name: Run tests with Python 3.6
command: |
sudo pip install --upgrade pip
pip install --user tox
tox -e py36
test_gradient_model_py37:
docker:
- image: circleci/python:3.7.6
working_directory: ~/project/packages/gradient_boosting_model
steps:
- checkout:
path: ~/project
- run:
name: Run tests with Python 3.7
command: |
sudo pip install --upgrade pip
pip install --user tox
tox -e py37
test_gradient_model_py38:
docker:
- image: circleci/python:3.8.0
working_directory: ~/project/packages/gradient_boosting_model
steps:
- checkout:
path: ~/project
- run:
name: Run tests with Python 3.8
command: |
sudo pip install --upgrade pip
pip install --user tox
tox -e py38
test_ml_api_py36:
docker:
- image: circleci/python:3.6.9
- image: postgres
environment:
POSTGRES_USER: test_user
POSTGRES_PASSWORD: password
POSTGRES_DB: ml_api_test
environment:
DB_HOST: localhost
DB_PORT: 5432
DB_USER: test_user
DB_PASSWORD: password
DB_NAME: ml_api_test
SHADOW_MODE_ACTIVE: true
working_directory: ~/project/packages/ml_api
steps:
- checkout:
path: ~/project
- run:
name: Run API tests with Python 3.6
command: |
sudo pip install --upgrade pip
pip install --user tox
tox -e py36
test_ml_api_py37:
docker:
- image: circleci/python:3.7.6
- image: postgres
environment:
POSTGRES_USER: test_user
POSTGRES_PASSWORD: password
POSTGRES_DB: ml_api_test
environment:
DB_HOST: localhost
DB_PORT: 5432
DB_USER: test_user
DB_PASSWORD: password
DB_NAME: ml_api_test
SHADOW_MODE_ACTIVE: true
working_directory: ~/project/packages/ml_api
steps:
- checkout:
path: ~/project
- run:
name: Run API tests with Python 3.7
command: |
sudo pip install --upgrade pip
pip install --user tox
tox -e py37
test_ml_api_py38:
docker:
- image: circleci/python:3.8.1
- image: postgres
environment:
POSTGRES_USER: test_user
POSTGRES_PASSWORD: password
POSTGRES_DB: ml_api_test
environment:
DB_HOST: localhost
DB_PORT: 5432
DB_USER: test_user
DB_PASSWORD: password
DB_NAME: ml_api_test
SHADOW_MODE_ACTIVE: true
working_directory: ~/project/packages/ml_api
steps:
- checkout:
path: ~/project
- run:
name: Run API tests with Python 3.8
command: |
sudo pip install --upgrade pip
pip install --user tox
tox -e py38
workflows:
version: 2
test-all:
jobs:
- test_gradient_model_py36
- test_gradient_model_py37
- test_gradient_model_py38
- test_ml_api_py36
- test_ml_api_py37
- test_ml_api_py38
18 changes: 18 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
exercise_notebooks/*
*/env*
*/venv*
.circleci*
packages/gradient_boosting_model
*.env
*.log
.git
.gitignore
.dockerignore
*.mypy_cache
*.pytest_cache

### Python ###

# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ venv/
ENV/
env.bak/
venv.bak/
.tox/

# Spyder project settings
.spyderproject
Expand Down Expand Up @@ -124,3 +125,7 @@ test.csv
# trained models
packages/gradient_boosting_model/gradient_boosting_model/trained_models/*.pkl
*.h5

# differential test artifacts
packages/ml_api/differential_tests/expected_results/
packages/ml_api/differential_tests/actual_results/
3 changes: 1 addition & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
# testing-and-monitoring-ml-deployments
WIP
Example project for the course "Testing & Monitoring Machine Learning Model Deployments". For setup instructions, see the course lectures.
23 changes: 23 additions & 0 deletions exercise_notebooks/elk_exercise/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
FROM python:3.7-alpine
WORKDIR /application

COPY ./requirements.txt requirements.txt
RUN apk add --no-cache \
gcc \
libc-dev \
linux-headers \
bash; \
pip install -r requirements.txt;

COPY . /application


EXPOSE 5000
VOLUME /application
CMD gunicorn --bind 0.0.0.0:5000 \
--workers=1 \
--log-config gunicorn_logging.conf \
--log-level=DEBUG \
--access-logfile=- \
--error-logfile=- \
application:application
Empty file.
18 changes: 18 additions & 0 deletions exercise_notebooks/elk_exercise/app/flask_app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import logging

from flask import Flask, current_app


def index():
current_app.logger.info('home')
return 'home'


def create_app():
main_app = Flask(__name__)
main_app.add_url_rule('/', 'index', index)
gunicorn_error_logger = logging.getLogger('gunicorn.error')
main_app.logger.addHandler(gunicorn_error_logger)
main_app.logger.setLevel(logging.DEBUG)

return main_app
7 changes: 7 additions & 0 deletions exercise_notebooks/elk_exercise/application.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from app.flask_app import create_app


application = create_app()

if __name__ == '__main__':
application.run()
91 changes: 91 additions & 0 deletions exercise_notebooks/elk_exercise/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
version: '3.2'

services:
# The environment variable "ELK_VERSION" is used throughout this file to
# specify the version of the images to run. The default is set in the
# '.env' file in this folder. It can be overridden with any normal
# technique for setting environment variables, for example:
#
# ELK_VERSION=7.0.0-beta1 docker-compose up
#
# REF: https://docs.docker.com/compose/compose-file/#variable-substitution
webapp:
build: .
container_name: webapp
expose:
- 5000
ports:
- 5000:5000
links:
- logstash
networks:
- elk
depends_on:
- logstash
- kibana
- elasticsearch
volumes:
- ./:/application
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:${ELK_VERSION}
volumes:
- type: bind
source: ./elasticsearch/config/elasticsearch.yml
target: /usr/share/elasticsearch/config/elasticsearch.yml
read_only: true
- type: volume
source: elasticsearch
target: /usr/share/elasticsearch/data
ports:
- "9200:9200"
- "9300:9300"
environment:
ES_JAVA_OPTS: "-Xmx256m -Xms256m"
ELASTIC_PASSWORD: changeme
# Use single node discovery in order to disable production mode and avoid bootstrap checks
# see https://www.elastic.co/guide/en/elasticsearch/reference/current/bootstrap-checks.html
discovery.type: single-node
networks:
- elk

logstash:
image: docker.elastic.co/logstash/logstash:${ELK_VERSION}
volumes:
- type: bind
source: ./logstash/config/logstash.yml
target: /usr/share/logstash/config/logstash.yml
read_only: true
- type: bind
source: ./logstash/pipeline
target: /usr/share/logstash/pipeline
read_only: true
ports:
- "5001:5001"
- "9600:9600"
environment:
LS_JAVA_OPTS: "-Xmx256m -Xms256m"
networks:
- elk
depends_on:
- elasticsearch

kibana:
image: docker.elastic.co/kibana/kibana:${ELK_VERSION}
volumes:
- type: bind
source: ./kibana/config/kibana.yml
target: /usr/share/kibana/config/kibana.yml
read_only: true
ports:
- "5601:5601"
networks:
- elk
depends_on:
- elasticsearch

networks:
elk:
driver: bridge

volumes:
elasticsearch:
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
## Default Elasticsearch configuration from Elasticsearch base image.
## https://github.com/elastic/elasticsearch/blob/master/distribution/docker/src/docker/config/elasticsearch.yml
cluster.name: "docker-cluster"
network.host: 0.0.0.0

## X-Pack settings
## see https://www.elastic.co/guide/en/elasticsearch/reference/current/setup-xpack.html
xpack.license.self_generated.type: basic
xpack.security.enabled: true
xpack.monitoring.collection.enabled: true
46 changes: 46 additions & 0 deletions exercise_notebooks/elk_exercise/gunicorn_logging.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
[loggers]
keys=root, logstash.error, logstash.access

[handlers]
keys=console, logstash

[formatters]
keys=generic, access, json

[logger_root]
level=INFO
handlers=console

[logger_logstash.error]
level=INFO
handlers=logstash
propagate=1
qualname=gunicorn.error

[logger_logstash.access]
level=INFO
handlers=logstash
propagate=0
qualname=gunicorn.access

[handler_console]
class=StreamHandler
formatter=generic
args=(sys.stdout, )

[handler_logstash]
class=logstash.TCPLogstashHandler
formatter=json
args=('logstash', 5001)

[formatter_generic]
format=%(asctime)s [%(process)d] [%(levelname)s] %(message)s
datefmt=%Y-%m-%d %H:%M:%S
class=logging.Formatter

[formatter_access]
format=%(message)s
class=logging.Formatter

[formatter_json]
class=pythonjsonlogger.jsonlogger.JsonFormatter
13 changes: 13 additions & 0 deletions exercise_notebooks/elk_exercise/kibana/config/kibana.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
## Default Kibana configuration from Kibana base image.
## https://github.com/elastic/kibana/blob/master/src/dev/build/tasks/os_packages/docker_generator/templates/kibana_yml.template.js
#
server.name: kibana
server.host: "0"
elasticsearch.hosts: [ "http://elasticsearch:9200" ]
xpack.monitoring.ui.container.elasticsearch.enabled: true

## X-Pack security credentials
#
elasticsearch.username: elastic
elasticsearch.password: changeme
12 changes: 12 additions & 0 deletions exercise_notebooks/elk_exercise/logstash/config/logstash.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
## Default Logstash configuration from Logstash base image.
## https://github.com/elastic/logstash/blob/master/docker/data/logstash/config/logstash-full.yml
#
http.host: "0.0.0.0"
xpack.monitoring.elasticsearch.hosts: [ "http://elasticsearch:9200" ]

## X-Pack security credentials
#
xpack.monitoring.enabled: true
xpack.monitoring.elasticsearch.username: elastic
xpack.monitoring.elasticsearch.password: changeme
Loading