This commit is contained in:
Richin Jain 2017-10-04 14:52:40 -04:00
Родитель 63689c8d0e c8a86b28bb
Коммит 63789f4893
3 изменённых файлов: 129 добавлений и 0 удалений

Просмотреть файл

@ -9,3 +9,21 @@ This decouples the app developers and data scientists, to make sure that the pro
Variation to this tutorial could be consuming the ML application as an endpoint instead of packaging it in the app.
The goal is to show how easy it is do devops for an AI application.
Steps to set up build and test
* Create VM on Azure
* Install Docker
* Setup Docker to be executed without sudo
If you want to avoid typing sudo whenever you run the docker command, add your username to the docker group:
• sudo usermod -aG docker ${USER}
To apply the new group membership, you can log out of the server and back in, or you can type the following:
• su - ${USER}
You will be prompted to enter your user's password to continue. Afterwards, you can confirm that your user is now added to the docker group by typing:
• id -nG
* Login to ACR so credentials are stored
* Install anaconda
https://medium.com/@GalarnykMichael/install-python-on-ubuntu-anaconda-65623042cb5a

Просмотреть файл

@ -0,0 +1,76 @@
import base64
import json
import logging
import urllib
from io import BytesIO
import sys
import requests
import toolz
from PIL import Image, ImageOps
ch = logging.StreamHandler(sys.stdout)
ch.setLevel(logging.INFO)
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
ch.setFormatter(formatter)
logging.basicConfig(level=logging.INFO, stream=sys.stdout)
logger = logging.getLogger(__name__)
# logger.addHandler(ch)
TEST_IMAGES ={ # Examples used for testing
'https://www.britishairways.com/assets/images/information/about-ba/fleet-facts/airbus-380-800/photo-gallery/240x295-BA-A380-exterior-2-high-res.jpg':
'n02690373 airliner',
}
def read_image_from(url):
return toolz.pipe(url,
urllib.request.urlopen,
lambda x: x.read(),
BytesIO)
def to_rgb(img_bytes):
return Image.open(img_bytes).convert('RGB')
@toolz.curry
def resize(img_file, new_size=(100, 100)):
return ImageOps.fit(img_file, new_size, Image.ANTIALIAS)
def to_base64(img):
imgio = BytesIO()
img.save(imgio, 'PNG')
imgio.seek(0)
dataimg = base64.b64encode(imgio.read())
return dataimg.decode('utf-8')
def to_img(img_url):
return toolz.pipe(img_url,
read_image_from,
to_rgb,
resize(new_size=(224,224)))
def img_url_to_json(url):
img_data = toolz.pipe(url,
to_img,
to_base64)
return json.dumps({'input':'[\"{0}\"]'.format(img_data)})
if __name__=='__main__':
logger.info('Starting classifier test')
headers = {'content-type': 'application/json'}
for url, label in TEST_IMAGES.items():
jsonimg = img_url_to_json(url)
r = requests.post('http://0.0.0.0:88/score', data=jsonimg, headers=headers)
json_response = r.json()
logger.info(json_response)
prediction=json_response['result'][0][0][0][0]
if prediction != label:
raise ValueError('The predicted label {} is not the same as {}'.format(prediction,label))
logger.info('CORRECT! {}'.format(prediction))

Просмотреть файл

@ -0,0 +1,35 @@
#!/bin/bash
# This script tests the docker image passed to it
IMAGE=$1
echo "Starting Docker image " $IMAGE
docker pull $IMAGE
docker run -d -p 88:88 $IMAGE
sleep 10
# Simple API test
echo "Testing API"
reply=$(curl -s http://0.0.0.0:88/version)
if [[ $reply == 2.0rc1 ]]; then
echo -e "Successfully validated version API call"
else
echo "Basic API call failed"
exit 1
fi
# Testing classification
echo "Testing Classification"
source ~/anaconda/bin/activate root
result=$(python test/classify.py)
source ~/anaconda/bin/deactivate
echo $result
echo "Stopping container and removing"
docker stop $(docker ps -a -q)
docker rm $(docker ps -a -q)
echo "Finished"
exit 0