From bd44f133274a7aa432fb33c86f0ddacf9f37032c Mon Sep 17 00:00:00 2001 From: "DESKTOP-TDE98GM\\Shin" Date: Thu, 7 Jun 2018 19:03:53 +0900 Subject: [PATCH 01/15] Move parsing part to Module Code --- README.md | 22 ++++++++++++++++++---- initialize_server.sh | 6 +++--- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 77aa2a4..3f33ecf 100644 --- a/README.md +++ b/README.md @@ -111,14 +111,28 @@ def analyzer_by_path(image_path): -## 실행하기 -### Django Initialize -해당 프로그램을 실행하기 위해서는 Django에서 Database를 초기화해야 한다. -이 작업은 맨 처음 및 Django의 Model 구조 변화 시 필요하다. +## Database 설정하기 + +### 만들기 + +Django 내에서 설정한 model 구조를 반영한다. + ```bash sh initailize_server.sh ``` +### 수정하기 + +이 과정은 Django 내의 model 구조가 바뀔 때 마다 다시 만들어주어야 한다. +```bash +sudo rm db.sqlite3 +sh initailize_server.sh +``` + + + +## 실행하기 + ### Web Start 전체 프로그램을 실행하는 것은 다음과 같이 입력한다. ```bash diff --git a/initialize_server.sh b/initialize_server.sh index 33c7438..f4d1304 100644 --- a/initialize_server.sh +++ b/initialize_server.sh @@ -1,8 +1,8 @@ -rm -f db.sqlite3 media/*.* -echo 'db.qulite3 & media file delete' +rm -f media/*.* +echo 'media file delete' rm -f */migrations/[0-9]*_*.py* echo 'migrations file delete' rm -f *.log celerybeat-schedule echo 'Log file delete' python manage.py makemigrations -python manage.py migrate +python manage.py migrate \ No newline at end of file From 8ca04cb3d5010144267a6436c15d7a6ee8a7dd5d Mon Sep 17 00:00:00 2001 From: "DESKTOP-TDE98GM\\Shin" Date: Fri, 8 Jun 2018 16:55:33 +0900 Subject: [PATCH 02/15] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3f33ecf..3d85fb5 100644 --- a/README.md +++ b/README.md @@ -60,7 +60,7 @@ class Dummy: # - Inference using image path import time time.sleep(5) - result = [[[(0, 0, 0, 0), {'TEST': 0.95, 'DEBUG': 0.05}]]] + result = [[(0, 0, 0, 0), {'TEST': 0.95, 'DEBUG': 0.05}], [(100, 100, 100, 100), {'TEST': 0.95, 'DEBUG': 0.05}]] self.result = result return self.result ``` From 0732126d5ddca2228d3dc61d37e4d064321d2a61 Mon Sep 17 00:00:00 2001 From: "DESKTOP-TDE98GM\\Shin" Date: Mon, 18 Jun 2018 10:04:22 +0900 Subject: [PATCH 03/15] Update README.md and Old database file delete bug fixed --- README.md | 20 ++++++++++++++++++++ WebAnalyzer/beats.py | 2 +- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 3d85fb5..ad39d10 100644 --- a/README.md +++ b/README.md @@ -100,6 +100,26 @@ def module_load_init(**__): ``` TODO 부분에 본인이 앞에서 추가한 Class를 하나씩 불러온다 +### 추가 설정하기 + +실행 시 Load하는 Module의 수를 조절해아 할 필요성이 있다. 이 때는 AnalysisModule 폴더의 config.py를 수정한다. +```python +TOTAL_NUMBER_OF_MODULES = 2 + +WORKER_MIN_SCALER = TOTAL_NUMBER_OF_MODULES +WORKER_MAX_SCALER = TOTAL_NUMBER_OF_MODULES +WORKER_CONCURRENCY = (WORKER_MIN_SCALER + WORKER_MAX_SCALER) // 2 + +DATABASE_AUTO_DELETE_HOUR = 4 + 15 # UTC To Asia/Seoul +DATABASE_AUTO_DELETE_MINUTE = 00 +DATABASE_AUTO_DELETE_DAY_OF_WEEK = 0 # 0: Sunday - 6: Saturday +DATABASE_AUTO_DELETE_BEFORE_DAYS = 7 +``` + +TOTAL_NUMBER_OF_MODULES는 기본적으로 2로 설정되어 있으며, 이는 Load하는 모듈의 수가 2개 임을 나타낸다. 따라서 본인의 GPU 환경에 맞추어 이 수를 조절하고자 한다면 이 변수의 수를 조절하면 된다. + + + #### Module 실행하기 ```python @app.task diff --git a/WebAnalyzer/beats.py b/WebAnalyzer/beats.py index 7294faf..613c10b 100644 --- a/WebAnalyzer/beats.py +++ b/WebAnalyzer/beats.py @@ -20,7 +20,7 @@ def delete_old_database(days=0): # Delete Image Folder date_point_dir = str(filter(str.isdigit, date_point.isoformat())) for old_image_dir in os.listdir(MEDIA_ROOT): - if old_image_dir <= date_point_dir: + if old_image_dir < date_point_dir: shutil.rmtree(os.path.join(MEDIA_ROOT, old_image_dir)) print("====================") From 550b1de9a3e813057f0f788376724f4b1b490458 Mon Sep 17 00:00:00 2001 From: "DESKTOP-TDE98GM\\Shin" Date: Fri, 29 Jun 2018 13:43:51 +0900 Subject: [PATCH 04/15] Set a Pagination and edit viewsets --- AnalysisModule/settings.py | 6 ++---- WebAnalyzer/views.py | 12 +++++++++++- initialize_server.sh | 2 +- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/AnalysisModule/settings.py b/AnalysisModule/settings.py index 3d8a626..953975b 100644 --- a/AnalysisModule/settings.py +++ b/AnalysisModule/settings.py @@ -130,8 +130,6 @@ MEDIA_ROOT = os.path.join(BASE_DIR, 'media') REST_FRAMEWORK = { - 'DEFAULT_PERMISSION_CLASSES': [ - # 'rest_framework.permissions.IsAdminUser', - ], - # 'PAGE_SIZE': 10, + 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination', + 'PAGE_SIZE': 50, } diff --git a/WebAnalyzer/views.py b/WebAnalyzer/views.py index e73b2b5..7c4b754 100644 --- a/WebAnalyzer/views.py +++ b/WebAnalyzer/views.py @@ -11,4 +11,14 @@ class ImageViewSet(viewsets.ModelViewSet): queryset = ImageModel.objects.all() - serializer_class = ImageSerializer \ No newline at end of file + serializer_class = ImageSerializer + + def get_queryset(self): + queryset = self.queryset + queryset = queryset.order_by('-token') + + token = self.request.query_params.get('token', None) + if token is not None: + queryset = queryset.filter(token=token) + + return queryset diff --git a/initialize_server.sh b/initialize_server.sh index f4d1304..e601291 100644 --- a/initialize_server.sh +++ b/initialize_server.sh @@ -1,4 +1,4 @@ -rm -f media/*.* +rm -rf media/* echo 'media file delete' rm -f */migrations/[0-9]*_*.py* echo 'migrations file delete' From f5998dec6bf6af0b44377077aa4a84776b0db27e Mon Sep 17 00:00:00 2001 From: kwangsooshin Date: Thu, 5 Jul 2018 13:55:10 +0900 Subject: [PATCH 05/15] Docker-compose Test --- AnalysisModule/celerys.py | 18 +++++++++++- docker/Dockerfile | 30 +++++++------------ docker/docker-compose.yml | 31 ++++++++++++++++++++ docker/entrypoint.sh | 20 +++++++++---- docker/env_files/django.env | 3 ++ docker/env_files/rabbitmq.env | 2 ++ run_celery.sh | 2 +- run_migration.sh | 2 ++ initialize_server.sh => server_initialize.sh | 3 +- server_shutdown.sh | 3 ++ server_start.sh | 3 ++ shutdown_server.sh | 2 -- start_server.sh | 2 -- 13 files changed, 88 insertions(+), 33 deletions(-) create mode 100644 docker/docker-compose.yml create mode 100644 docker/env_files/django.env create mode 100644 docker/env_files/rabbitmq.env create mode 100644 run_migration.sh rename initialize_server.sh => server_initialize.sh (73%) create mode 100644 server_shutdown.sh create mode 100644 server_start.sh delete mode 100644 shutdown_server.sh delete mode 100644 start_server.sh diff --git a/AnalysisModule/celerys.py b/AnalysisModule/celerys.py index fb3284b..e8bd00b 100644 --- a/AnalysisModule/celerys.py +++ b/AnalysisModule/celerys.py @@ -6,8 +6,24 @@ os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'AnalysisModule.settings') app = Celery('AnalysisModule') + + +if 'RABBITMQ_DEFAULT_USER' in os.environ: + app.conf.update( + broker_url='amqp://{user}:{password}@{address}'.format( + user=os.environ['RABBITMQ_DEFAULT_USER'], + password=os.environ['RABBITMQ_DEFAULT_PASS'], + address=os.environ.get('RABBITMQ_PORT_5672_TCP_ADDR', 'rabbitmq')) + ) + +else: + app.conf.update( + broker_url='amqp://localhost', + ) + + app.conf.update( - broker_url='amqp://localhost', + # broker_url='amqp://localhost', result_backend='amqp://localhost', timezone='UTC', enable_utc=True, diff --git a/docker/Dockerfile b/docker/Dockerfile index 6124b2c..3a3578d 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -1,32 +1,22 @@ -# Input deelearning framework you use FROM ubuntu:16.04 -RUN apt-get update && apt-get install -y \ - --no-install-recommends \ - git \ - wget \ - python-pip \ - erlang \ - rabbitmq-server \ - apt-utils && \ - rm -rf /var/lib/apt/lists/* +RUN apt-get update \ + && apt-get install -y --no-install-recommends \ + git wget python-pip apt-utils \ + && rm -rf /var/lib/apt/lists/* RUN pip install --upgrade pip RUN pip install setuptools -RUN pip install \ - django==1.11 \ - djangorestframework \ - requests \ - Pillow \ - kombu==4.1.0 \ - celery==4.1.0 -EXPOSE 8000 +WORKDIR /workspace +RUN git clone https://github.com/kwangsooshin/AnalysisModule.git +WORKDIR /workspace/AnalysisModule +RUN pip install -r requirements.txt COPY entrypoint.sh /entrypoint.sh RUN chmod +x /entrypoint.sh - ENTRYPOINT ["/entrypoint.sh"] -WORKDIR /workspace RUN chmod -R a+w /workspace + +EXPOSE 8000 diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml new file mode 100644 index 0000000..d95ee55 --- /dev/null +++ b/docker/docker-compose.yml @@ -0,0 +1,31 @@ +version: '2.3' + +services: + web: + build: + context: ./ + dockerfile: Dockerfile + runtime: nvidia + image: "${COMPOSE_PROJECT_NAME}" + container_name: "${WEB_CONTAINER_NAME}" + restart: always + links: + - rabbitmq + depends_on: + - rabbitmq + env_file: + - "./env_files/django.env" + - "./env_files/rabbitmq.env" + ports: + - "${WEB_EXTERNAL_PORT}:8000" + stdin_open: true + tty: true + + rabbitmq: + image: rabbitmq:latest + restart: always + env_file: + - "./env_files/rabbitmq.env" + expose: + - "5672" + - "15672" diff --git a/docker/entrypoint.sh b/docker/entrypoint.sh index 7405996..8478b62 100644 --- a/docker/entrypoint.sh +++ b/docker/entrypoint.sh @@ -1,7 +1,17 @@ -#!/bin/sh +#!/usr/bin/env bash +set -e -# Start the initial program -/etc/init.d/rabbitmq-server restart +sh run_migration.sh +python -c "import os +os.environ['DJANGO_SETTINGS_MODULE'] = 'AnalysisSite.settings' +import django +django.setup() +from django.contrib.auth.management.commands.createsuperuser import get_user_model +if not get_user_model().objects.filter(username='$DJANGO_SUPERUSER_USERNAME'): + get_user_model()._default_manager.db_manager().create_superuser(username='$DJANGO_SUPERUSER_USERNAME', email='$DJANGO_SUPERUSER_EMAIL', password='$DJANGO_SUPERUSER_PASSWORD')" +sh server_start.sh -# Execute the CMD -/bin/bash +trap 'sh server_shutdown.sh' SIGTERM +while true; do :; done + +exec "$@" \ No newline at end of file diff --git a/docker/env_files/django.env b/docker/env_files/django.env new file mode 100644 index 0000000..a343982 --- /dev/null +++ b/docker/env_files/django.env @@ -0,0 +1,3 @@ +DJANGO_SUPERUSER_USERNAME=root +DJANGO_SUPERUSER_EMAIL=none@none.com +DJANGO_SUPERUSER_PASSWORD=password diff --git a/docker/env_files/rabbitmq.env b/docker/env_files/rabbitmq.env new file mode 100644 index 0000000..a694bc7 --- /dev/null +++ b/docker/env_files/rabbitmq.env @@ -0,0 +1,2 @@ +RABBITMQ_DEFAULT_USER=rabbitmq +RABBITMQ_DEFAULT_PASS=rabbitmq diff --git a/run_celery.sh b/run_celery.sh index a1216bf..256e16b 100644 --- a/run_celery.sh +++ b/run_celery.sh @@ -1 +1 @@ -celery -A AnalysisModule worker -B -l info +celery -A AnalysisSite worker -B -l info diff --git a/run_migration.sh b/run_migration.sh new file mode 100644 index 0000000..bf6c583 --- /dev/null +++ b/run_migration.sh @@ -0,0 +1,2 @@ +python manage.py makemigrations +python manage.py migrate diff --git a/initialize_server.sh b/server_initialize.sh similarity index 73% rename from initialize_server.sh rename to server_initialize.sh index e601291..97d24c6 100644 --- a/initialize_server.sh +++ b/server_initialize.sh @@ -4,5 +4,4 @@ rm -f */migrations/[0-9]*_*.py* echo 'migrations file delete' rm -f *.log celerybeat-schedule echo 'Log file delete' -python manage.py makemigrations -python manage.py migrate \ No newline at end of file +sh run_migration.sh \ No newline at end of file diff --git a/server_shutdown.sh b/server_shutdown.sh new file mode 100644 index 0000000..82c227d --- /dev/null +++ b/server_shutdown.sh @@ -0,0 +1,3 @@ +(exec kill $(ps aux |awk '/runserver/ {print $2}')) 2>/dev/null & +(exec kill $(ps aux |awk '/celery/ {print $2}')) 2>/dev/null & +echo "Shutdown Server" diff --git a/server_start.sh b/server_start.sh new file mode 100644 index 0000000..a334ce9 --- /dev/null +++ b/server_start.sh @@ -0,0 +1,3 @@ +(exec nohup sh -- ./run_celery.sh > celery.log) 2>/dev/null & +(exec nohup sh -- ./run_django.sh > django.log) 2>/dev/null & +echo "Start Server" \ No newline at end of file diff --git a/shutdown_server.sh b/shutdown_server.sh deleted file mode 100644 index 5a41d42..0000000 --- a/shutdown_server.sh +++ /dev/null @@ -1,2 +0,0 @@ -kill $(ps aux |awk '/runserver/ {print $2}') -kill $(ps aux |awk '/celery/ {print $2}') diff --git a/start_server.sh b/start_server.sh deleted file mode 100644 index f39e374..0000000 --- a/start_server.sh +++ /dev/null @@ -1,2 +0,0 @@ -nohup sh -- ./run_celery.sh > celery.log & -nohup sh -- ./run_django.sh > django.log & From 29964c6c66cdc015094907153e0c676c438e7bcb Mon Sep 17 00:00:00 2001 From: kwangsooshin Date: Thu, 5 Jul 2018 13:59:02 +0900 Subject: [PATCH 06/15] Docker-compose Test --- .gitignore | 14 +++++++------- docker/.env | 4 ++++ 2 files changed, 11 insertions(+), 7 deletions(-) create mode 100644 docker/.env diff --git a/.gitignore b/.gitignore index df4ef74..aa6849b 100644 --- a/.gitignore +++ b/.gitignore @@ -91,13 +91,13 @@ celerybeat-schedule *.sage.py # Environments -.env -.venv -env/ -venv/ -ENV/ -env.bak/ -venv.bak/ +# .env +# .venv +# env/ +# venv/ +# ENV/ +# env.bak/ +# venv.bak/ # Spyder project settings .spyderproject diff --git a/docker/.env b/docker/.env new file mode 100644 index 0000000..336f1b1 --- /dev/null +++ b/docker/.env @@ -0,0 +1,4 @@ +COMPOSE_PROJECT_NAME=analysis-site + +WEB_CONTAINER_NAME=site +WEB_EXTERNAL_PORT=8000 \ No newline at end of file From 711e2474b0357d4963fdc63e556dfb8bc87b3c09 Mon Sep 17 00:00:00 2001 From: kwangsooshin Date: Thu, 5 Jul 2018 16:06:07 +0900 Subject: [PATCH 07/15] Edit README.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit README 파일을 더욱 구체적으로 작성하였고, 예시를 더욱 현실적으로 만들어 사용자로 하여금 생길 수 있는 의문을 최대한 해소하고자 노력함. --- Modules/dummy/example/__init__.py | 0 Modules/dummy/example/test.py | 0 Modules/dummy/main.py | 13 +- Modules/dummy/model.txt | 0 README.md | 296 ++++++++++++++++-------------- docker/.env | 4 +- docker/Dockerfile | 2 +- 7 files changed, 170 insertions(+), 145 deletions(-) create mode 100644 Modules/dummy/example/__init__.py create mode 100644 Modules/dummy/example/test.py create mode 100644 Modules/dummy/model.txt diff --git a/Modules/dummy/example/__init__.py b/Modules/dummy/example/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/Modules/dummy/example/test.py b/Modules/dummy/example/test.py new file mode 100644 index 0000000..e69de29 diff --git a/Modules/dummy/main.py b/Modules/dummy/main.py index 5e743e3..e0001e7 100644 --- a/Modules/dummy/main.py +++ b/Modules/dummy/main.py @@ -1,16 +1,23 @@ +import os +from Modules.dummy.example import test + class Dummy: + model = None + result = None + path = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + def __init__(self): # TODO # - initialize and load model here - self.model = None - self.result = None + model_path = os.path.join(self.path, "model.txt") + self.model = open(model_path, "r") def inference_by_path(self, image_path): result = [] # TODO # - Inference using image path import time - time.sleep(5) + time.sleep(2) result = [[(0, 0, 0, 0), {'TEST': 0.95, 'DEBUG': 0.05}], [(100, 100, 100, 100), {'TEST': 0.95, 'DEBUG': 0.05}]] self.result = result diff --git a/Modules/dummy/model.txt b/Modules/dummy/model.txt new file mode 100644 index 0000000..e69de29 diff --git a/README.md b/README.md index ad39d10..6099f8a 100644 --- a/README.md +++ b/README.md @@ -1,178 +1,196 @@ -# AnalysisModule +# Analysis Module -## 실행 환경 세팅 +- [Introduce](#introduce) +- [Installation](#installation) + - [From Source](#from-source) + - [Docker Compose](#docker-compose) +- [Setting Module](#setting-module) + - [Configure Module Class](#configure-module-class) + - [Modify Tasks](#modify-tasks) + - [Additional Settings](#additional-settings) +- [Setting Database](#setting-database) +- [Run Web Server](#run-web-server) + +## Introduce -### 필요 프로그램 설치 +본 프로젝트는 Neural Network의 결과를 REST API로 서비스 하기 위한 웹 서버를 제공합니다. -#### 일반적인 사용 시 +Python 코드로 구성되어 있으며, Django 및 Django REST framework를 사용하여 개발하였습니다. -실행하기 전, Celery에 필요한 message broker software인 RabbitMQ를 설치한다. +본 프로젝트는 [Analysis Site](https://github.com/sogang-mm/Analysis-Site)와 함께 설치하기를 추천합니다. +Linux 사용을 가정하여 코드를 작성하였으며, 만약 다른 환경에서의 설치를 진행하려면 문의하시기 바랍니다. + + +## Installation + +### From Source + +실행에 필요한 service를 설치한다. ```bash sudo apt-get install rabbitmq-server sudo service rabbitmq-server restart ``` -이후 필요한 pip package를 설치한다 +실행에 필요한 package를 설치한다. ```bash pip install -r requirements.txt ``` -만약 pip requirements가 설치되지 않는다면 pip를 업데이트 한 후, 다음 package를 먼저 설치한다 +만약 package 설치가 진행되지 않는다면 pip를 업데이트 한 후 다시 시도한다. ```bash pip install --upgrade pip pip install setuptools ``` -#### Docker 사용 시 - -Docker를 사용할 경우 docker 폴더로 이동하여 Dockerfile의 맨 윗부분의 FROM 부분을 본인이 사용할 Docker Image로 수정하고 빌드한다. - -##### Dockerfile -```Dockerfile -FROM ubuntu:16.04 -``` - -##### Docker Build -```bash -cd docker -docker build [OPTIONS] -t [TAG] . -``` +### Docker Compose +Docker Compose를 사용하기 위해서는 다음을 필요로 한다. -## Module 추가하기 +- [Docker](https://docs.docker.com/) & [Docker compose](https://docs.docker.com/compose/) +- [NVIDIA Container Runtime for Docker](https://github.com/NVIDIA/nvidia-docker) -### Class 생성하기 +이후, docker 디렉토리 내 파일에서 다음과 같은 부분을 수정한다. -Modules 폴더의 dummy 폴더 내 main.py를 참고하여 본인이 사용할 Module을 가진 Class를 생성한다. +1. Dockerfile + * 본인이 사용할 Deep learning framework가 담긴 Docker image로 수정한다. + ```dockerfile + FROM ubuntu:16.04 + ``` + * 본인의 git repository로 주소를 수정한다. + ```dockerfile + RUN git clone https://github.com/sogang-mm/AnalysisModule.git + ``` + +2. .env + * Docker로 여러 Module 을 올리고자 한다면 다음을 수정한다. + ```text + COMPOSE_PROJECT_NAME=analysis-module + WEB_CONTAINER_NAME=module + WEB_EXTERNAL_PORT=8000 + ``` + * COMPOSE_PROJECT_NAME은 Dockerfile에서 build한 image의 이름으로 설정된다. + * WEB_CONTAINER_NAME은 Dockerfile에서 build한 image의 container의 이름으로 설정된다. + * WEB_EXTERNAL_PORT는 웹 서버의 외부 통신을 위한 PORT로 설정된다. -```python -class Dummy: - def __init__(self): - # TODO - # - initialize and load model here - self.model = None - self.result = None - - def inference_by_path(self, image_path): - result = [] - # TODO - # - Inference using image path - import time - time.sleep(5) - result = [[(0, 0, 0, 0), {'TEST': 0.95, 'DEBUG': 0.05}], [(100, 100, 100, 100), {'TEST': 0.95, 'DEBUG': 0.05}]] - self.result = result - return self.result -``` -#### def init() -Class를 초기화하는 부분에선 Module을 미리 Load하고, 대기 상태로 유지할 수 있도록 준비한다. +모든 설정이 끝났다면 docker 디렉토리 내에서 docker-compose up으로 실행하면 웹 서버가 시작된다. -#### def inference_by_path(image_path) -이미지 경로를 받고, init()에서 Load한 Module을 사용하여 그 결과값을 반환한다. -결과값은 다음과 같은 형태를 띄도록 설계한다. +웹 서버가 실행된 것을 확인하였으면 Module 추가를 위해 web container에 /bin/bash로 접근하여 일단 웹 서버를 종료한다. ```bash -[ [ ( x, y, w, h ), { Label1 : Percent1, Label2 : Perecnt2 } ], [ ( x, y, w, h ), { Label : Percent } ] ] +sh server_shutdown.sh ``` -이는 Module을 통한 결과 Label이 위치 (x, y)에서 너비 w, 높이 h 크기의 사각형 위에서 검출되었으며, 그 확률이 Percent임을 의미한다. - -### Tasks 추가하기 - -WebAnalyzer 폴더의 tasks.py 파일을 수정한다. - -#### Module 불러오기 -```python -@worker_process_init.connect -def module_load_init(**__): - global analyzer - worker_index = current_process().index - - print("====================") - print(" Worker Id: {0}".format(worker_index)) - print("====================") - - # TODO: - # - Add your model - # - You can use worker_index if you need to get and set gpu_id - # - ex) gpu_id = worker_index % TOTAL_GPU_NUMBER - from Modules.dummy.main import Dummy - analyzer = Dummy() -``` -TODO 부분에 본인이 앞에서 추가한 Class를 하나씩 불러온다 - -### 추가 설정하기 - -실행 시 Load하는 Module의 수를 조절해아 할 필요성이 있다. 이 때는 AnalysisModule 폴더의 config.py를 수정한다. + + +## Setting Module + +모든 설치가 끝났다면 Modules을 추가하기 위해 Modules 디렉토리로 이동한다. +여기에는 작성에 도움을 주기 위해 dummy 디렉토리 내 main.py를 참고하여 작성한다. + +### Configure Module Class + +* Module 내 다른 python import 하기 + ```python + from Modules.dummy.example import test + ``` + * Django 실행 시 root 폴더가 프로젝트의 최상위 폴더가 되므로, sub 폴더 내 다른 python 파일을 import 위해서는 위와 같이 최상위 폴더 기준으로 import를 해야한다. + +* \__init\__ + ```python + model_path = os.path.join(self.path, "model.txt") + self.model = open(model_path, "r") + ``` + * \__init\__에서는 model 불러오기 및 대기 상태 유지를 위한 코드를 작성한다. + * model 등의 파일을 불러오기 위해선 model_path를 사용하여 절대경로로 불러오도록 한다. + +* inference_by_path + ```python + result = [[(0, 0, 0, 0), {'TEST': 0.95, 'DEBUG': 0.05}], [(100, 100, 100, 100), {'TEST': 0.95, 'DEBUG': 0.05}]] + ``` + * 이미지 경로를 받고 \__init\__ 에서 불러온 모델을 통해 분석 결과를 반환하여 저장한다. 이때 결과값은 다음과 같은 형태를 가지도록 구성한다. + ```text + [ [ ( x, y, w, h ), { Label_1 : Percent_1, Label_2 : Percent_2 } ], [ ( x, y, w, h ), { Label : Percent } ] ] + ``` + * 이는 결과로서 두 개의 객채를 검출했으며, 첫 객체는 (x, y)를 시작점으로 하고 너비 w, 높이 h를 가지는 사각 영역에서 나타났으며, 그때 그 객체는 순서대로 Label_1 및 Label_2로 예상됨을 나타낸다. + +### Modify Tasks + +위와 같이 Moduele 설정이 끝났다면 작성한 Module을 추가하기 위해 WebAnalyzer 디렉토리로 이동한다. 그 후 tasks.py를 수정한다. + +* Module 불러오기 + ```python + @worker_process_init.connect + def module_load_init(**__): + global analyzer + worker_index = current_process().index + + print("====================") + print(" Worker Id: {0}".format(worker_index)) + print("====================") + + # TODO: + # - Add your model + # - You can use worker_index if you need to get and set gpu_id + # - ex) gpu_id = worker_index % TOTAL_GPU_NUMBER + from Modules.dummy.main import Dummy + analyzer = Dummy() + ``` + * 위에서 작성한 class을 불러온 후, anlyzer에 추가한다. + * 만약 이 때, Multi-gpu를 사용하여 gpu 별로 나누어 추가하고 싶다면, worker_index를 사용하여 이를 수정할 수 있다. + +* Module 실행하기 + ```python + @app.task + def analyzer_by_path(image_path): + result = analyzer.inference_by_path(image_path) + return result + ``` + * 위에서 불러온 Module이 실제로 실행되는 부분으로, 분석 결과를 받아 반환한다. + + +### Additional Settings + +실행 시에 필요한 다양한 Setting을 변경하고 싶다면 AnalysisModule 디렉토리의 config.py를 수정한다. + +* 불러오는 Module 수 조절하기 ```python TOTAL_NUMBER_OF_MODULES = 2 - -WORKER_MIN_SCALER = TOTAL_NUMBER_OF_MODULES -WORKER_MAX_SCALER = TOTAL_NUMBER_OF_MODULES -WORKER_CONCURRENCY = (WORKER_MIN_SCALER + WORKER_MAX_SCALER) // 2 - -DATABASE_AUTO_DELETE_HOUR = 4 + 15 # UTC To Asia/Seoul -DATABASE_AUTO_DELETE_MINUTE = 00 -DATABASE_AUTO_DELETE_DAY_OF_WEEK = 0 # 0: Sunday - 6: Saturday -DATABASE_AUTO_DELETE_BEFORE_DAYS = 7 ``` -TOTAL_NUMBER_OF_MODULES는 기본적으로 2로 설정되어 있으며, 이는 Load하는 모듈의 수가 2개 임을 나타낸다. 따라서 본인의 GPU 환경에 맞추어 이 수를 조절하고자 한다면 이 변수의 수를 조절하면 된다. - - - -#### Module 실행하기 -```python -@app.task -def analyzer_by_path(image_path): - result = analyzer.inference_by_path(image_path) - return result - ``` - 위에서 불러온 Class를 통해 Module로부터 이미지 결과를 받아온다. - - - -## Database 설정하기 - -### 만들기 - -Django 내에서 설정한 model 구조를 반영한다. +## Setting Database +### Migration +Django 내 필요한 model 구조를 반영하기 위해 다음을 실행한다. ```bash -sh initailize_server.sh +sh run_migration.sh ``` - -### 수정하기 - -이 과정은 Django 내의 model 구조가 바뀔 때 마다 다시 만들어주어야 한다. +만약 필요에 의해 model 구조를 변경하였다면, run_migration.sh을 통해 생성된 파일을 지우고 다시 설정해주어야 한다. ```bash sudo rm db.sqlite3 -sh initailize_server.sh +sh server_initialize.sh +sh run_migration.sh ``` - - -## 실행하기 - -### Web Start -전체 프로그램을 실행하는 것은 다음과 같이 입력한다. -```bash -sh start_server.sh -``` - -#### Django Only -만약 Debug 등의 이유로 Django만 실행하고 싶을 경우 다음과 같이 입력한다. 주로 웹 페이지를 통한 접근에 문제가 있을 경우, 확인을 위해 실행한다. -```bash -sh run_django.sh -``` - -#### Celery Only -만약 Debug 등의 이유로 Celery만 실행하고 싶을 경우 다음과 같이 입력한다. 주로 Module을 통한 결과에 문제가 있을 경우, 확인을 위해 실행한다. -```bash -sh run_celery.sh -``` - -### Web Shutdown -전체 프로그램을 종료하는 것은 다음과 같이 입력한다. -```bash -sh shutdown_server.sh -``` +## Run Web Server + +* Web Server를 실행하고자 한다면 server_start.sh를 실행한다. + ```bash + sh server_start.sh + ``` + 이후 http://localhost:8000/ 또는 구성한 서버의 IP 및 Domain으로 접근하여 접속한다. + +* 만약 접속 시 문제가 있어 실행 Log를 보고자 할 때는 다음과 같이 실행하여 확인한다. + * Web Server에 문제가 있어 Django 부분만 실행하고자 한다면 run_django.sh를 실행한다. + ```bash + sh run_django.sh + ``` + + * Web Server는 실행되나 분석 결과가 나오지 않아 Module 부분만 실행하고자 한다면 run_celery.sh를 실행한다. + ```bash + sh run_celery.sh + ``` + +* Web Server를 종료하고자 한다면 server_shutdown.sh를 실행한다. + ```bash + sh server_shutdown.sh + ``` diff --git a/docker/.env b/docker/.env index 336f1b1..c13b9d2 100644 --- a/docker/.env +++ b/docker/.env @@ -1,4 +1,4 @@ -COMPOSE_PROJECT_NAME=analysis-site +COMPOSE_PROJECT_NAME=analysis-module -WEB_CONTAINER_NAME=site +WEB_CONTAINER_NAME=module WEB_EXTERNAL_PORT=8000 \ No newline at end of file diff --git a/docker/Dockerfile b/docker/Dockerfile index 3a3578d..bece7ba 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -9,7 +9,7 @@ RUN pip install --upgrade pip RUN pip install setuptools WORKDIR /workspace -RUN git clone https://github.com/kwangsooshin/AnalysisModule.git +RUN git clone https://github.com/sogang-mm/AnalysisModule.git WORKDIR /workspace/AnalysisModule RUN pip install -r requirements.txt From d4cd8b85e76d62ddcabf3846d4db14721f8f62a0 Mon Sep 17 00:00:00 2001 From: kwangsooshin Date: Thu, 5 Jul 2018 16:12:20 +0900 Subject: [PATCH 08/15] =?UTF-8?q?Dockerfile=EC=9D=98=20git=20clone=20URL?= =?UTF-8?q?=EC=9D=84=20=EC=88=98=EC=A0=95=ED=95=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docker/Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docker/Dockerfile b/docker/Dockerfile index bece7ba..c05bad1 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -9,8 +9,8 @@ RUN pip install --upgrade pip RUN pip install setuptools WORKDIR /workspace -RUN git clone https://github.com/sogang-mm/AnalysisModule.git -WORKDIR /workspace/AnalysisModule +RUN git clone https://github.com/sogang-mm/Analysis-Module.git +WORKDIR /workspace/Analysis-Module RUN pip install -r requirements.txt COPY entrypoint.sh /entrypoint.sh From 39fe42d6f0b8709cf3be143ec1eff892e68b5ec4 Mon Sep 17 00:00:00 2001 From: kwangsooshin Date: Thu, 5 Jul 2018 16:30:33 +0900 Subject: [PATCH 09/15] Error Fixed --- README.md | 2 +- run_celery.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 6099f8a..e61a884 100644 --- a/README.md +++ b/README.md @@ -59,7 +59,7 @@ Docker Compose를 사용하기 위해서는 다음을 필요로 한다. ``` * 본인의 git repository로 주소를 수정한다. ```dockerfile - RUN git clone https://github.com/sogang-mm/AnalysisModule.git + RUN git clone https://github.com/sogang-mm/Analysis-Module.git ``` 2. .env diff --git a/run_celery.sh b/run_celery.sh index 256e16b..a1216bf 100644 --- a/run_celery.sh +++ b/run_celery.sh @@ -1 +1 @@ -celery -A AnalysisSite worker -B -l info +celery -A AnalysisModule worker -B -l info From 025e990fe6a43a74c401c0933e28a45578476ca5 Mon Sep 17 00:00:00 2001 From: kwangsooshin Date: Thu, 5 Jul 2018 17:01:30 +0900 Subject: [PATCH 10/15] Bug Fixed and Edit README.md --- README.md | 2 ++ docker/entrypoint.sh | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index e61a884..eb386f4 100644 --- a/README.md +++ b/README.md @@ -75,6 +75,8 @@ Docker Compose를 사용하기 위해서는 다음을 필요로 한다. 모든 설정이 끝났다면 docker 디렉토리 내에서 docker-compose up으로 실행하면 웹 서버가 시작된다. +http://localhost:8000/ 또는 구성한 서버의 IP 및 Domain으로 접근하여 접속이 되는지 확인한다. + 웹 서버가 실행된 것을 확인하였으면 Module 추가를 위해 web container에 /bin/bash로 접근하여 일단 웹 서버를 종료한다. ```bash diff --git a/docker/entrypoint.sh b/docker/entrypoint.sh index 8478b62..da5ecf4 100644 --- a/docker/entrypoint.sh +++ b/docker/entrypoint.sh @@ -3,7 +3,7 @@ set -e sh run_migration.sh python -c "import os -os.environ['DJANGO_SETTINGS_MODULE'] = 'AnalysisSite.settings' +os.environ['DJANGO_SETTINGS_MODULE'] = 'AnalysisModule.settings' import django django.setup() from django.contrib.auth.management.commands.createsuperuser import get_user_model From ed82a64392267eebf27863cdd659ae693532bebb Mon Sep 17 00:00:00 2001 From: kwangsooshin Date: Fri, 6 Jul 2018 19:31:43 +0900 Subject: [PATCH 11/15] Bug fixed: Show Log when docker-compose --- docker/entrypoint.sh | 1 + server_start.sh | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/docker/entrypoint.sh b/docker/entrypoint.sh index da5ecf4..5142779 100644 --- a/docker/entrypoint.sh +++ b/docker/entrypoint.sh @@ -10,6 +10,7 @@ from django.contrib.auth.management.commands.createsuperuser import get_user_mod if not get_user_model().objects.filter(username='$DJANGO_SUPERUSER_USERNAME'): get_user_model()._default_manager.db_manager().create_superuser(username='$DJANGO_SUPERUSER_USERNAME', email='$DJANGO_SUPERUSER_EMAIL', password='$DJANGO_SUPERUSER_PASSWORD')" sh server_start.sh +tail -f celery.log -f django.log trap 'sh server_shutdown.sh' SIGTERM while true; do :; done diff --git a/server_start.sh b/server_start.sh index a334ce9..cea26f4 100644 --- a/server_start.sh +++ b/server_start.sh @@ -1,3 +1,3 @@ -(exec nohup sh -- ./run_celery.sh > celery.log) 2>/dev/null & -(exec nohup sh -- ./run_django.sh > django.log) 2>/dev/null & +nohup sh -- ./run_celery.sh > celery.log 2>&1 & +nohup sh -- ./run_django.sh > django.log 2>&1 & echo "Start Server" \ No newline at end of file From 9257cbf722e95ed6e10b713c38f4df4c1d4ca911 Mon Sep 17 00:00:00 2001 From: kwangsooshin Date: Mon, 9 Jul 2018 17:03:33 +0900 Subject: [PATCH 12/15] Edit README.md: Add Prerequisites and change repository name (Upper to Lower) --- README.md | 13 +++++++++++-- docker/Dockerfile | 4 ++-- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index eb386f4..918edb4 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ # Analysis Module - [Introduce](#introduce) +- [Prerequisites](#prerequisites) - [Installation](#installation) - [From Source](#from-source) - [Docker Compose](#docker-compose) @@ -17,11 +18,18 @@ Python 코드로 구성되어 있으며, Django 및 Django REST framework를 사용하여 개발하였습니다. -본 프로젝트는 [Analysis Site](https://github.com/sogang-mm/Analysis-Site)와 함께 설치하기를 추천합니다. +본 프로젝트는 [Analysis Site](https://github.com/sogang-mm/analysis-site)와 함께 설치하기를 추천합니다. Linux 사용을 가정하여 코드를 작성하였으며, 만약 다른 환경에서의 설치를 진행하려면 문의하시기 바랍니다. +## Prerequisites + +- Linux +- Python 2.7, 3.4, 3.5, or 3.6 +- And so on + + ## Installation ### From Source @@ -59,7 +67,8 @@ Docker Compose를 사용하기 위해서는 다음을 필요로 한다. ``` * 본인의 git repository로 주소를 수정한다. ```dockerfile - RUN git clone https://github.com/sogang-mm/Analysis-Module.git + RUN git clone https://github.com/sogang-mm/analysis-module.git + WORKDIR /workspace/analysis-module ``` 2. .env diff --git a/docker/Dockerfile b/docker/Dockerfile index c05bad1..a0951b7 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -9,8 +9,8 @@ RUN pip install --upgrade pip RUN pip install setuptools WORKDIR /workspace -RUN git clone https://github.com/sogang-mm/Analysis-Module.git -WORKDIR /workspace/Analysis-Module +RUN git clone https://github.com/sogang-mm/analysis-module.git +WORKDIR /workspace/analysis-module RUN pip install -r requirements.txt COPY entrypoint.sh /entrypoint.sh From 56797dd86ffb4ecc3e787b8066d4cfb229b85f7c Mon Sep 17 00:00:00 2001 From: kwangsooshin Date: Mon, 9 Jul 2018 18:24:25 +0900 Subject: [PATCH 13/15] Dummy Module bug fix change dummy.path --- Modules/dummy/main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/dummy/main.py b/Modules/dummy/main.py index e0001e7..97c6683 100644 --- a/Modules/dummy/main.py +++ b/Modules/dummy/main.py @@ -4,7 +4,7 @@ class Dummy: model = None result = None - path = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + path = os.path.dirname(os.path.abspath(__file__)) def __init__(self): # TODO From d116df5d2d33220185ef07df5ff234bbf438bba4 Mon Sep 17 00:00:00 2001 From: kwangsooshin Date: Mon, 9 Jul 2018 20:00:45 +0900 Subject: [PATCH 14/15] Fixed Encoding adapt to Unix --- docker/entrypoint.sh | 2 +- run_django.sh | 2 +- server_initialize.sh | 2 +- server_start.sh | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docker/entrypoint.sh b/docker/entrypoint.sh index 5142779..e80c3d3 100644 --- a/docker/entrypoint.sh +++ b/docker/entrypoint.sh @@ -15,4 +15,4 @@ tail -f celery.log -f django.log trap 'sh server_shutdown.sh' SIGTERM while true; do :; done -exec "$@" \ No newline at end of file +exec "$@" diff --git a/run_django.sh b/run_django.sh index 19721a2..6a14855 100644 --- a/run_django.sh +++ b/run_django.sh @@ -1 +1 @@ -python manage.py runserver 0.0.0.0:8000 \ No newline at end of file +python manage.py runserver 0.0.0.0:8000 diff --git a/server_initialize.sh b/server_initialize.sh index 97d24c6..0b65e34 100644 --- a/server_initialize.sh +++ b/server_initialize.sh @@ -4,4 +4,4 @@ rm -f */migrations/[0-9]*_*.py* echo 'migrations file delete' rm -f *.log celerybeat-schedule echo 'Log file delete' -sh run_migration.sh \ No newline at end of file +sh run_migration.sh diff --git a/server_start.sh b/server_start.sh index cea26f4..d46dcd9 100644 --- a/server_start.sh +++ b/server_start.sh @@ -1,3 +1,3 @@ nohup sh -- ./run_celery.sh > celery.log 2>&1 & nohup sh -- ./run_django.sh > django.log 2>&1 & -echo "Start Server" \ No newline at end of file +echo "Start Server" From e8a067a7c5b49fa4c5923d0e380a10bac8db9fd1 Mon Sep 17 00:00:00 2001 From: kwangsooshin Date: Tue, 10 Jul 2018 12:12:35 +0900 Subject: [PATCH 15/15] Add Shebang Line --- run_celery.sh | 1 + run_django.sh | 1 + run_migration.sh | 1 + server_initialize.sh | 1 + server_shutdown.sh | 1 + server_start.sh | 1 + 6 files changed, 6 insertions(+) diff --git a/run_celery.sh b/run_celery.sh index a1216bf..dcd2b25 100644 --- a/run_celery.sh +++ b/run_celery.sh @@ -1 +1,2 @@ +#!/usr/bin/env bash celery -A AnalysisModule worker -B -l info diff --git a/run_django.sh b/run_django.sh index 6a14855..86f8e96 100644 --- a/run_django.sh +++ b/run_django.sh @@ -1 +1,2 @@ +#!/usr/bin/env bash python manage.py runserver 0.0.0.0:8000 diff --git a/run_migration.sh b/run_migration.sh index bf6c583..f5b53b4 100644 --- a/run_migration.sh +++ b/run_migration.sh @@ -1,2 +1,3 @@ +#!/usr/bin/env bash python manage.py makemigrations python manage.py migrate diff --git a/server_initialize.sh b/server_initialize.sh index 0b65e34..ac52b7c 100644 --- a/server_initialize.sh +++ b/server_initialize.sh @@ -1,3 +1,4 @@ +#!/usr/bin/env bash rm -rf media/* echo 'media file delete' rm -f */migrations/[0-9]*_*.py* diff --git a/server_shutdown.sh b/server_shutdown.sh index 82c227d..302e461 100644 --- a/server_shutdown.sh +++ b/server_shutdown.sh @@ -1,3 +1,4 @@ +#!/usr/bin/env bash (exec kill $(ps aux |awk '/runserver/ {print $2}')) 2>/dev/null & (exec kill $(ps aux |awk '/celery/ {print $2}')) 2>/dev/null & echo "Shutdown Server" diff --git a/server_start.sh b/server_start.sh index d46dcd9..d1041a5 100644 --- a/server_start.sh +++ b/server_start.sh @@ -1,3 +1,4 @@ +#!/usr/bin/env bash nohup sh -- ./run_celery.sh > celery.log 2>&1 & nohup sh -- ./run_django.sh > django.log 2>&1 & echo "Start Server"