Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
13 changes: 9 additions & 4 deletions docker/dockerfile → docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
FROM python:3.6
# Use Python 3 base image
FROM python:3

# Add maintainer information
LABEL maintainer="[email protected]"

COPY docker/requirements.txt .

# Add project
COPY src/main /main

# Install requirements
COPY docker/requirements.txt .
RUN pip install -r requirements.txt

# Set work dir
WORKDIR /main

CMD ["uvicorn", "start:app", "--host", "0.0.0.0", "--port", "7770"]
# Set init command
CMD ["uvicorn", "start:app", "--host", "0.0.0.0", "--port", "7770"]
10 changes: 6 additions & 4 deletions install_prerequisites.sh
Original file line number Diff line number Diff line change
@@ -1,26 +1,28 @@
#!/bin/bash

# This will install docker following [https://docs.docker.com/install/linux/docker-ce/ubuntu/]
# Install Docker as described in https://docs.docker.com/install/linux/docker-ce/ubuntu/
# Prepare environment
sudo apt-get remove docker docker-engine docker.io
sudo apt-get update

# Add further dependencies
sudo apt-get install \
apt-transport-https \
ca-certificates \
curl \
software-properties-common

# Add Docker package repository
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo apt-key fingerprint 0EBFCD88

sudo add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) \
stable"

# Install Docker and add user
sudo apt-get update
sudo apt-get install -y docker-ce
sudo groupadd docker
sudo usermod -aG docker ${USER}
docker run hello-world

docker run hello-world
6 changes: 3 additions & 3 deletions src/main/deep_learning_service.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# Import dependencies
import os
import json
import uuid
Expand All @@ -6,9 +7,8 @@
from inference.exceptions import ModelNotFound, InvalidModelConfiguration, ModelNotLoaded, InferenceEngineNotFound, \
InvalidInputData, ApplicationError


# Deep learning service class
class DeepLearningService:

def __init__(self):
"""
Sets the models base directory, and initializes some dictionaries.
Expand Down Expand Up @@ -164,4 +164,4 @@ def get_config(self, model_name):
"""
if not self.model_loaded(model_name):
self.load_model(model_name)
return self.models_dict[model_name].configuration
return self.models_dict[model_name].configuration
6 changes: 3 additions & 3 deletions src/main/inference/base_error.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# Import dependencies
import logging
from datetime import datetime
from abc import ABC, abstractmethod


# Abstract error class
class AbstractError(ABC):

def __init__(self):
"""
Sets the logger file, level, and format.
Expand Down Expand Up @@ -43,4 +43,4 @@ def error(self, message):
:param message: Containing the request status and the model response
:return:
"""
pass
pass
6 changes: 3 additions & 3 deletions src/main/inference/base_inference_engine.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# Import dependencies
from abc import ABC, abstractmethod
from inference.exceptions import InvalidModelConfiguration, ModelNotLoaded, ApplicationError


# Abstract inference engine class
class AbstractInferenceEngine(ABC):

def __init__(self, model_path):
"""
Takes a model path and calls the load function.
Expand Down Expand Up @@ -89,4 +89,4 @@ def validate_json_configuration(self, data):
pass

def __del__(self):
self.free()
self.free()
6 changes: 3 additions & 3 deletions src/main/inference/errors.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
# Import dependencies
import os
import logging
from datetime import datetime, date
from inference.base_error import AbstractError


# Abstract error class
class Error(AbstractError):

def __init__(self):
if 'logs' not in os.listdir():
os.mkdir('logs')
Expand Down Expand Up @@ -44,4 +44,4 @@ def check_date(self):
b = datetime.strptime(oldest_date, '%Y-%m-%d')
delta = a - b
if delta.days > 365:
os.remove('logs/' + oldest_log_file)
os.remove('logs/' + oldest_log_file)
9 changes: 2 additions & 7 deletions src/main/inference/exceptions.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# Define meta class
__metaclass__ = type


class ApplicationError(Exception):
"""Base class for other exceptions"""

def __init__(self, default_message, additional_message=''):
self.default_message = default_message
self.additional_message = additional_message
Expand All @@ -18,39 +18,34 @@ def get_message(self):

class InvalidModelConfiguration(ApplicationError):
"""Raised when the model's configuration is corrupted"""

def __init__(self, additional_message=''):
# super('Invalid model configuration', additional_message)
super().__init__('Invalid model configuration', additional_message)


class ModelNotFound(ApplicationError):
"""Raised when the model is not found"""

def __init__(self, additional_message=''):
# super('Model not found', additional_message)
super().__init__('Model not found', additional_message)


class ModelNotLoaded(ApplicationError):
"""Raised when the model is not loaded"""

def __init__(self, additional_message=''):
# super('Error loading model', additional_message)
super().__init__('Error loading model', additional_message)


class InvalidInputData(ApplicationError):
"""Raised when the input data is corrupted"""

def __init__(self, additional_message=''):
# super('Invalid input data', additional_message)
super().__init__('Invalid input data', additional_message)


class InferenceEngineNotFound(ApplicationError):
"""Raised when the Inference Engine is not found"""

def __init__(self, additional_message=''):
# super('Inference engine not found', additional_message)
super().__init__('Inference engine not found', additional_message)
super().__init__('Inference engine not found', additional_message)
4 changes: 2 additions & 2 deletions src/main/inference/inference_engines_factory.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# Import dependencies
import os
import json
from inference.exceptions import ModelNotFound, ApplicationError, InvalidModelConfiguration, InferenceEngineNotFound, ModelNotLoaded


# Inference engine factory class
class InferenceEngineFactory:

@staticmethod
def get_engine(path_to_model):
"""
Expand Down
6 changes: 3 additions & 3 deletions src/main/inference/yolov3_opencv_cpu_detection.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# Import dependencies
import os
import cv2
import uuid
Expand All @@ -9,9 +10,8 @@
from inference.base_inference_engine import AbstractInferenceEngine
from inference.exceptions import InvalidModelConfiguration, InvalidInputData, ApplicationError


# Inference engine class
class InferenceEngine(AbstractInferenceEngine):

def __init__(self, model_path):
self.net = None
self.scale = None
Expand Down Expand Up @@ -234,4 +234,4 @@ def validate_json_configuration(self, data):
try:
jsonschema.validate(data, schema)
except Exception as e:
raise InvalidModelConfiguration(e)
raise InvalidModelConfiguration(e)
4 changes: 2 additions & 2 deletions src/main/models.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# API response class
class ApiResponse:

def __init__(self, success=True, data=None, error=None):
"""
Defines the response shape
Expand All @@ -9,4 +9,4 @@ def __init__(self, success=True, data=None, error=None):
"""
self.data = data
self.error = error.get_message() if error is not None else ''
self.success = success
self.success = success
21 changes: 7 additions & 14 deletions src/main/start.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# Import dependencies
import sys
from starlette.responses import FileResponse
from models import ApiResponse
Expand All @@ -10,28 +11,20 @@
InferenceEngineNotFound, InvalidInputData
from inference.errors import Error

# Append path
sys.path.append('./inference')

# Init deep learning service
dl_service = DeepLearningService()
error_logging = Error()
app = FastAPI(version='3.1.0', title='BMW InnovationLab YOLOv3 opencv inference Automation',
description="<b>API for performing YOLOv3 opencv inference</b></br></br>"
app = FastAPI(version='3.1.0', title='BMW InnovationLab YOLOv3 OpenCV Inference Automation',
description="<b>API for YOLOv3 OpenCV Inference</b></br></br>"
"<b>Contact the developers:</b></br>"
"<b>Antoine Charbel: <a href='mailto:[email protected]'>[email protected]</a></b></br>"
"<b>BMW Innovation Lab: <a href='mailto:[email protected]'>[email protected]</a></b>")


# app.mount("/public", StaticFiles(directory="/main/public"), name="public")

# app.add_middleware(
# CORSMiddleware,
# allow_origins=["*"],
# allow_credentials=True,
# allow_methods=["*"],
# allow_headers=["*"],
# )


# Load app
@app.get('/load')
def load_custom():
"""
Expand Down Expand Up @@ -189,4 +182,4 @@ async def list_model_config(model_name: str):
:return: List of model's configuration
"""
config = dl_service.get_config(model_name)
return ApiResponse(data=config)
return ApiResponse(data=config)