From 2860d530785d7929ac5eadfae287c2ab33de08b2 Mon Sep 17 00:00:00 2001
From: David Chamont <chamont@in2p3.fr>
Date: Wed, 22 Jul 2020 18:39:20 +0200
Subject: [PATCH] =?UTF-8?q?Reproduction=20de=20la=20structure=20de=20CodeG?=
 =?UTF-8?q?uards,=20=C3=A0=20LT=5FCFG=20pr=C3=AAt,=20et=20il=20reste=20du?=
 =?UTF-8?q?=20travail=20sur=20les=20tests=20unitaires=20de=20getter.py?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .gitignore                                    |  26 +++++++--
 .gitlab-ci.yml                                |  54 ++++++++++++++++++
 README.md                                     |  34 +++--------
 test/__init__.py => WORK.md                   |   0
 dist/build.sh                                 |   4 +-
 dist/setup.py                                 |   2 +-
 dist/version.txt                              |   2 +-
 docker/Dockerfile.dev                         |  29 ----------
 docker/Dockerfile.prod                        |  20 -------
 docker/Dockerfile_externals                   |  11 +++-
 docker/Dockerfile_latest                      |  19 +++---
 docker/README.md                              |  35 ++++++++++--
 docker/build_dev.sh                           |   3 -
 docker/build_externals.sh                     |   2 +-
 docker/build_latest.sh                        |   2 +-
 docker/image_dev.txt                          |   1 -
 docker/requirements.txt                       |  18 +++---
 docker/run_dev.sh                             |   3 -
 docker/run_externals.sh                       |   2 +-
 docker/run_latest.sh                          |   2 +-
 labelstower/__init__.py                       |   2 +-
 labelstower/getter.py                         |  10 ++++
 labelstower/request_db.py                     |   6 +-
 labelstower/routes.py                         |   5 +-
 test/{demo_flask => demo}/__init__.py         |   7 ++-
 test/demo/config.py                           |   6 ++
 test/{demo_flask => demo}/models.py           |  10 ++--
 .../static/categories.txt                     |   0
 .../static/css/bootstrap.css                  |   0
 .../static/css/bootstrap_1.css                |   0
 .../static/css/hierarchy.css                  |   0
 test/{demo_flask => demo}/static/css/main.css |   0
 .../static/css/result.css                     |   0
 .../fonts/glyphicons-halflings-regular.eot    |   0
 .../fonts/glyphicons-halflings-regular.svg    |   0
 .../fonts/glyphicons-halflings-regular.ttf    |   0
 .../fonts/glyphicons-halflings-regular.woff   |   0
 .../fonts/glyphicons-halflings-regular.woff2  |   0
 .../static/img/background_loop.png            | Bin
 .../static/img/moins-encadre-rouge.png        | Bin
 .../static/img/moins-encadre.png              | Bin
 .../static/img/moins-rouge.png                | Bin
 .../{demo_flask => demo}/static/img/moins.png | Bin
 .../static/img/monSeparateur.png              | Bin
 .../static/img/plus-encadre-vert.png          | Bin
 .../static/img/plus-encadre.png               | Bin
 .../static/img/plus-vert.png                  | Bin
 test/{demo_flask => demo}/static/img/plus.png | Bin
 test/{demo_flask => demo}/static/js/ajax.js   |   0
 .../{demo_flask => demo}/static/js/cookies.js |   0
 .../static/js/search_new_elements.js          |   0
 test/{demo_flask => demo}/static/js/vue.js    |   0
 .../templates/api_documentation.html          |   0
 .../templates/browse.html                     |   0
 test/demo_flask/config.py                     |   5 --
 ...data_codingpool.sql => DataCodingPool.sql} |   0
 .../{data_voiture.sql => DataVoiture.sql}     |   0
 test/instance/init_db.sh                      |   7 +--
 test/instance/pip_init_db.sh                  |  10 ++++
 test/scripts/doctests.sh                      |   9 +++
 60 files changed, 201 insertions(+), 145 deletions(-)
 create mode 100644 .gitlab-ci.yml
 rename test/__init__.py => WORK.md (100%)
 delete mode 100644 docker/Dockerfile.dev
 delete mode 100644 docker/Dockerfile.prod
 delete mode 100755 docker/build_dev.sh
 delete mode 100644 docker/image_dev.txt
 delete mode 100755 docker/run_dev.sh
 rename test/{demo_flask => demo}/__init__.py (86%)
 create mode 100644 test/demo/config.py
 rename test/{demo_flask => demo}/models.py (81%)
 rename test/{demo_flask => demo}/static/categories.txt (100%)
 rename test/{demo_flask => demo}/static/css/bootstrap.css (100%)
 rename test/{demo_flask => demo}/static/css/bootstrap_1.css (100%)
 rename test/{demo_flask => demo}/static/css/hierarchy.css (100%)
 rename test/{demo_flask => demo}/static/css/main.css (100%)
 rename test/{demo_flask => demo}/static/css/result.css (100%)
 rename test/{demo_flask => demo}/static/fonts/glyphicons-halflings-regular.eot (100%)
 rename test/{demo_flask => demo}/static/fonts/glyphicons-halflings-regular.svg (100%)
 rename test/{demo_flask => demo}/static/fonts/glyphicons-halflings-regular.ttf (100%)
 rename test/{demo_flask => demo}/static/fonts/glyphicons-halflings-regular.woff (100%)
 rename test/{demo_flask => demo}/static/fonts/glyphicons-halflings-regular.woff2 (100%)
 rename test/{demo_flask => demo}/static/img/background_loop.png (100%)
 rename test/{demo_flask => demo}/static/img/moins-encadre-rouge.png (100%)
 rename test/{demo_flask => demo}/static/img/moins-encadre.png (100%)
 rename test/{demo_flask => demo}/static/img/moins-rouge.png (100%)
 rename test/{demo_flask => demo}/static/img/moins.png (100%)
 rename test/{demo_flask => demo}/static/img/monSeparateur.png (100%)
 rename test/{demo_flask => demo}/static/img/plus-encadre-vert.png (100%)
 rename test/{demo_flask => demo}/static/img/plus-encadre.png (100%)
 rename test/{demo_flask => demo}/static/img/plus-vert.png (100%)
 rename test/{demo_flask => demo}/static/img/plus.png (100%)
 rename test/{demo_flask => demo}/static/js/ajax.js (100%)
 rename test/{demo_flask => demo}/static/js/cookies.js (100%)
 rename test/{demo_flask => demo}/static/js/search_new_elements.js (100%)
 rename test/{demo_flask => demo}/static/js/vue.js (100%)
 rename test/{demo_flask => demo}/templates/api_documentation.html (100%)
 rename test/{demo_flask => demo}/templates/browse.html (100%)
 delete mode 100644 test/demo_flask/config.py
 rename test/instance/{data_codingpool.sql => DataCodingPool.sql} (100%)
 rename test/instance/{data_voiture.sql => DataVoiture.sql} (100%)
 create mode 100755 test/instance/pip_init_db.sh
 create mode 100755 test/scripts/doctests.sh

diff --git a/.gitignore b/.gitignore
index 414ed34..35d5540 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,8 +1,22 @@
-#Python
-build
+# Python
+__pycache__
+*.pyc
 *.egg-info
-*__pycache__
-.idea
+build
+
+# PyCharm
+.idea/
+
+# Environnements de developpement
+venv/
+
+# MacOS
+.DS_Store
+
+# Databases
+*.sqlite
+*.db
 
-#database
-*.db
\ No newline at end of file
+# protection contre un retour de requirements.txt
+# dans le répertoire racine...
+requirements.txt
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
new file mode 100644
index 0000000..1f8e79f
--- /dev/null
+++ b/.gitlab-ci.yml
@@ -0,0 +1,54 @@
+image: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
+
+stages:
+  - BuildImage
+  - SetupPackage
+  - PrepareDb
+  - UnitTests
+  - PackageTests
+  
+build:
+  stage: BuildImage
+  image: docker:stable
+  services:
+    - docker:stable-dind
+  script:
+    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
+    - docker pull $CI_REGISTRY_IMAGE:latestci || true
+    - cd docker
+    - docker build -f Dockerfile_externals --cache-from $CI_REGISTRY_IMAGE:latestci --tag $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA --tag $CI_REGISTRY_IMAGE:latestci .
+    - docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
+    - docker push $CI_REGISTRY_IMAGE:latestci
+    
+setup_wheel:
+  stage: SetupPackage
+  script:
+    - echo -n "latestci" > dist/version.txt
+    - dist/build.sh
+    - ls dist
+  artifacts:
+    paths:
+      - dist
+
+init_sqlite:
+  stage: PrepareDb
+  script:
+    - export LT_CFG=Voiture
+    - dist/install.sh
+    - test/instance/init_db.sh
+  artifacts:
+    paths:
+      - test/instance
+
+test_sqlite:
+  stage: PackageTests
+  script:
+    - export LT_CFG=Voiture
+    - cd test/instance
+    - ls -l ${LT_CFG}.sqlite
+
+doctests:
+  stage: UnitTests
+  script:
+    - export LT_CFG=Voiture
+    - test/scripts/doctests.sh
diff --git a/README.md b/README.md
index 8951be8..800ecfc 100644
--- a/README.md
+++ b/README.md
@@ -1,44 +1,24 @@
-# setup and start the labels system's API
-retrieve the application on gitlab repos
 
-    git clone --branch prototype_labelsTower git@gitlab.in2p3.fr:erichard/LabelsTower.git labels-back-end.git
+# Labels Tower
 
-setup the database
-
-    cd labels-back-end.git
-    cd docker
-    ./build_dev.sh
-    ./run_dev.sh /bin/bash
-    mkdir instance
-    python3 -c 'from models import db;db.create_all()'
-    mv test.db codingpool.db
-    sqlite3 codingpool.db '.read data_codingpool.sql'
-    mv codingpool.db instance/
-    exit
-    
-run the application
-
-    ./run_dev.sh
-
-# Code Guards
-
-Some python code for management of user accounts within a Flask application.
+Some python code for management of labels within a Flask application.
+For demo pupose, one must define either `LT_CFG=Voiture` or `LT_CFG=CodingPool`.
 
 ## Directories
 
 Most directories have their own `README.md`.
-* `codeguards` : main code, i.e. a blueprint for Flask.
+* `labelstower` : main code, i.e. a blueprint for Flask.
 * `docker` : anything for building docker images with all the needed externals.
-* `dist` : where we build and store wheel distributions of the main codeguards code.
+* `dist` : where we build and store wheel distributions of the main labelstower code.
 * `test/instance` : where we initialize a test sqlite database.
-* `test/demo_blog` : web demo application.
+* `test/demo` : web demo application.
 * `test/scripts` : various command-line test.
 
 ## Demonstration from scratch, with Docker
 
 With the help of Docker :
 1. Build the dev Docker image : `docker/build_externals.sh`
-1. Build the codeguards distribution : `docker/run_externals.sh dist/build.sh`
+1. Build the labelstower distribution : `docker/run_externals.sh dist/build.sh`
 1. Build the demo Docker image : `docker/build_latest.sh` (it includes the above distribution)
 1. Initialize a database : `docker/run_latest.sh instance/init_db.sh`
 1. Starts the flask server : `docker/run_latest.sh`
diff --git a/test/__init__.py b/WORK.md
similarity index 100%
rename from test/__init__.py
rename to WORK.md
diff --git a/dist/build.sh b/dist/build.sh
index f3e4064..946a327 100755
--- a/dist/build.sh
+++ b/dist/build.sh
@@ -5,10 +5,10 @@
 SCRIPT_NAME=${BASH_SOURCE[0]}
 cd `dirname ${SCRIPT_NAME}`
 
-cp -f setup.py LICENSE  ..
+cp -f setup.py LICENSE MANIFEST.in ..
 rm -rf ../labelstower.egg-info
 mv -f labelstower.egg-info ..
 cd ..
 python3 setup.py bdist_wheel
-rm -f setup.py LICENSE
+rm -f setup.py LICENSE MANIFEST.in
 mv -f labelstower.egg-info dist/
\ No newline at end of file
diff --git a/dist/setup.py b/dist/setup.py
index f63bac8..d467cf1 100644
--- a/dist/setup.py
+++ b/dist/setup.py
@@ -15,7 +15,7 @@ setuptools.setup(
     long_description=long_description,
     long_description_content_type="text/markdown",
     url="https://gitlab.in2p3.fr/MaitresNageurs/README/LabelsTower",
-    packages=setuptools.find_packages(),
+    packages=["labelstower"],
     include_package_data=True,
     classifiers=[
         "Programming Language :: Python :: 3",
diff --git a/dist/version.txt b/dist/version.txt
index 8a9ecc2..6812f81 100644
--- a/dist/version.txt
+++ b/dist/version.txt
@@ -1 +1 @@
-0.0.1
\ No newline at end of file
+0.0.3
\ No newline at end of file
diff --git a/docker/Dockerfile.dev b/docker/Dockerfile.dev
deleted file mode 100644
index 4c6f478..0000000
--- a/docker/Dockerfile.dev
+++ /dev/null
@@ -1,29 +0,0 @@
-
-# Version DEV
-FROM python:3.6.6-slim-stretch
-
-# Ensure use of bash
-SHELL ["/bin/bash","-c"]
-
-# Sqlite3
-RUN echo 'debconf debconf/frontend select Noninteractive' | debconf-set-selections
-ARG DEBIAN_FRONTEND=noninteractive
-RUN apt-get update \
-&& apt-get install -yq apt-utils \
-&& apt-get install -yq sqlite3 \
-&& apt-get install -yq curl \
-&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
-
-# Install flask
-COPY requirements.txt requirements.txt
-RUN pip install --trusted-host pypi.python.org -r requirements.txt
-
-# Run flask
-EXPOSE 5000
-ENV FLASK_ENV=development
-ENV LC_ALL=C.UTF-8
-ENV LANG=C.UTF-8
-
-ENV LABELSTOWER_ENV="app.config.ConfigCodingPool"
-
-CMD [ "flask", "run", "--reload", "--host", "0.0.0.0" ]
\ No newline at end of file
diff --git a/docker/Dockerfile.prod b/docker/Dockerfile.prod
deleted file mode 100644
index 37ed13f..0000000
--- a/docker/Dockerfile.prod
+++ /dev/null
@@ -1,20 +0,0 @@
-
-# Version PROD
-FROM gitlab-registry.in2p3.fr/maitresnageurs/readme/labelstower:dev0.4
-
-# Ensure use of bash
-SHELL ["/bin/bash","-c"]
-
-# Copy framework files
-COPY app app
-
-# Run flask
-EXPOSE 80
-ENV FLASK_APP=app/labelsTower.py
-ENV FLASK_ENV=production
-ENV LC_ALL=C.UTF-8
-ENV LANG=C.UTF-8
-CMD [ "flask", "run", "--host", "0.0.0.0", "--port", "80" ]
-
-
-
diff --git a/docker/Dockerfile_externals b/docker/Dockerfile_externals
index aa20ced..de224ee 100644
--- a/docker/Dockerfile_externals
+++ b/docker/Dockerfile_externals
@@ -1,11 +1,14 @@
 
-# Version DEV
+# Version EXTERNALS
+
 FROM python:3.6.6-slim-stretch
 
 # Ensure use of bash
+
 SHELL ["/bin/bash","-c"]
 
 # Sqlite3
+
 RUN echo 'debconf debconf/frontend select Noninteractive' | debconf-set-selections
 ARG DEBIAN_FRONTEND=noninteractive
 RUN apt-get update \
@@ -15,6 +18,7 @@ RUN apt-get update \
 && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
 
 # Install flask
+
 RUN pip3 install --upgrade pip setuptools wheel
 COPY requirements.txt requirements.txt
 RUN pip3 install --trusted-host pypi.python.org -r requirements.txt
@@ -23,10 +27,11 @@ RUN pip3 install --trusted-host pypi.python.org -r requirements.txt
 
 EXPOSE 5000
 
-ENV FLASK_APP=demo_flask
+ENV FLASK_APP=test/demo
 ENV FLASK_ENV=development
 
 ENV LC_ALL=C.UTF-8
 ENV LANG=C.UTF-8
 
-ENV LABELSTOWER_ENV="app.config.ConfigCodingPool"
+COPY flask.sh flask.sh
+CMD [ "/flask.sh" ]
diff --git a/docker/Dockerfile_latest b/docker/Dockerfile_latest
index 0d39417..7557650 100644
--- a/docker/Dockerfile_latest
+++ b/docker/Dockerfile_latest
@@ -1,24 +1,27 @@
 
-# Version DEMO
-FROM labelstower:dev
+# Version LATEST
+
+FROM labelstower:externals
 
 # Ensure use of bash
+
 SHELL ["/bin/bash","-c"]
 
 # Install labelstower
+
 RUN pip3 install --upgrade pip setuptools wheel
 COPY labelstower-latest-py3-none-any.whl labelstower-latest-py3-none-any.whl
 RUN pip3 install labelstower-latest-py3-none-any.whl
 
 # Run flask
-EXPOSE 5000
 
-ENV FLASK_APP=demo_flask
-ENV FLASK_ENV=development
+EXPOSE 80
+
+ENV FLASK_APP=demo
+ENV FLASK_ENV=production
 
 ENV LC_ALL=C.UTF-8
 ENV LANG=C.UTF-8
 
-ENV LABELSTOWER_ENV="app.config.ConfigCodingPool"
-
-CMD [ "flask", "run", "--reload", "--host", "0.0.0.0" ]
\ No newline at end of file
+COPY flask.sh flask.sh
+CMD [ "/flask.sh" ]
diff --git a/docker/README.md b/docker/README.md
index 55f221b..b7f8f85 100644
--- a/docker/README.md
+++ b/docker/README.md
@@ -1,9 +1,36 @@
+
+LAST MINUTE : if you want to run such a container with no command,
+that is with the default flask command, then one must define `LT_CFG``
+environment variable before, so that docker defines `LABELSTOWER_ENV=demo.config.Config${LF_CFG}`
+for the need of the demo web application.
+
+# Directory for Docker images and utility scripts
+
+* The "externals" flavor of scripts produce a `labelstower:externals` image, containing only the external software needed for the development of labelstower.
+* The "lastest" flavor of scripts produce a `labelstower:latest` image, containing an installation of the latest labelstower package found in `../dist/`.
+
+## Requirements
+
 Testing the LabelsTower code thanks to Docker requires only Docker to be installed. Yet, if one wants also to take profit of the utility scripts provided in the current directory, the command `/usr/bin/env bash` (used as a shebang in the scripts) must return a valid bash shell.
 
-The commands below are meant to be launched within the `docker` directory. Each time a significant change is made to the `Dockerfile`, please increase the version number in `image.txt`.
+## Scripts
+
+The commands below are meant to be launched within the `docker` directory :
+* `build_externals.sh` : build a local image for development.
+* `run_externals.sh` : start a container with the previous image, mounting `..` as `/work`. by default, it is starting the flaks server, but can be used with optional other commands.
+
+Note : as one can see in the `Dockerfile_externals` file, Flask is started with the option `--host 0.0.0.0`, which is necessary so that the http server, running potentially on a small virtual machine (at least on MacOS and Windows), can be seen from the real local machine.
+
+## Usages of `run_externals.sh`
+
+The `run.sh` script can be be given optional additional commands :
+* `run_externals.sh` : starts a flask web server.
+* `run_externals.sh dist/build.sh` : build a new wheel in `dist`.
+* `run_externals.sh instance/pip_init_db.sh` : install the wheel and initialize a database in `instance`.
 
-* build_dev.sh : build a local image.
-* run_dev.sh : run the demo web server, thanks to the local image, mounting `..` as `/work`.
+Note : the `run.sh` script starts a docker container with the option `--rm`, meaning when the container command ends, the container is automatically removed, and anything which was not stored in the `/work` directory (a mount of `..`) will be lost. This typically concerns commands such as `pip3 install ...`, whose affects root internal directoris of the container.
 
-Worth to note : as one can see in the Dockerfile command, Flask is started with the option `--host 0.0.0.0`, which is necessary so that the http server, running  potentially on a small virtual machine (at least on MacOS and Windows), can be seen from the real local machine.
+## About builtin the Docker image in Gitlab-CI (Docker in Docker)
 
+* https://jpetazzo.github.io/2015/09/03/do-not-use-docker-in-docker-for-ci/
+* https://docs.gitlab.com/ee/ci/docker/README.html
diff --git a/docker/build_dev.sh b/docker/build_dev.sh
deleted file mode 100755
index ef498fc..0000000
--- a/docker/build_dev.sh
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/bin/bash
-docker build  -f Dockerfile.dev -t `cat image_dev.txt` .
-# --force-rm --no-cache
\ No newline at end of file
diff --git a/docker/build_externals.sh b/docker/build_externals.sh
index eb5cce1..21771fe 100755
--- a/docker/build_externals.sh
+++ b/docker/build_externals.sh
@@ -5,5 +5,5 @@
 SCRIPT_NAME=${BASH_SOURCE[0]}
 cd `dirname ${SCRIPT_NAME}`
 
-docker build -f Dockerfile_externals -t labelstower:dev .
+docker build -f Dockerfile_externals -t labelstower:externals .
 # --force-rm --no-cache
diff --git a/docker/build_latest.sh b/docker/build_latest.sh
index 2f2de24..53a298c 100755
--- a/docker/build_latest.sh
+++ b/docker/build_latest.sh
@@ -9,7 +9,7 @@ cd `dirname ${SCRIPT_NAME}`
 version=`cat ../dist/version.txt`
 cp ../dist/labelstower-${version}-py3-none-any.whl labelstower-latest-py3-none-any.whl
 
-docker build -f Dockerfile_latest -t labelstower:demo .
+docker build -f Dockerfile_latest -t labelstower:latest .
 # --force-rm --no-cache
 
 # cleaning
diff --git a/docker/image_dev.txt b/docker/image_dev.txt
deleted file mode 100644
index bd907f5..0000000
--- a/docker/image_dev.txt
+++ /dev/null
@@ -1 +0,0 @@
-gitlab-registry.in2p3.fr/erichard/prototype_labelstower:dev0.1
diff --git a/docker/requirements.txt b/docker/requirements.txt
index 362db1f..1e9450e 100644
--- a/docker/requirements.txt
+++ b/docker/requirements.txt
@@ -1,18 +1,18 @@
-asn1crypto==1.0.1
-blinker==1.4
-cffi==1.12.3
 Click==7.0
-cryptography==2.7
 Flask==1.1.1
-Flask-Login==0.4.1
 Flask-Mail==0.9.1
-Flask-SQLAlchemy==2.4.1
 itsdangerous==1.1.0
 Jinja2==2.10.3
 MarkupSafe==1.1.1
-pycparser==2.19
-six==1.12.0
-SQLAlchemy==1.3.13
 Werkzeug==0.16.0
 WTForms==2.2.1
+Flask-Login==0.4.1
+cryptography==2.7
+SQLAlchemy==1.3.13
+Flask-SQLAlchemy==2.4.1
 Flask-Cors==3.0.8
+asn1crypto==1.0.1
+blinker==1.4
+cffi==1.12.3
+pycparser==2.19
+six==1.12.0
diff --git a/docker/run_dev.sh b/docker/run_dev.sh
deleted file mode 100755
index f2e7b20..0000000
--- a/docker/run_dev.sh
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/bin/bash
-# Flask opère par defaut sur le port 5000
-docker run -it --rm -p 5000:5000 -v $PWD/..:/work -w /work `cat image_dev.txt` $*
diff --git a/docker/run_externals.sh b/docker/run_externals.sh
index 2c66595..32cb7f5 100755
--- a/docker/run_externals.sh
+++ b/docker/run_externals.sh
@@ -6,4 +6,4 @@ SCRIPT_NAME=${BASH_SOURCE[0]}
 cd `dirname ${SCRIPT_NAME}`
 
 # Flask opère sur le port 5000
-docker run -it --rm -p 5000:5000 -v $PWD/..:/work -w /work labelstower:dev $*
\ No newline at end of file
+docker run -it --rm -p 5000:5000 -v $PWD/..:/work -w /work --env LF_CFG="${LF_CFG}" labelstower:externals $*
diff --git a/docker/run_latest.sh b/docker/run_latest.sh
index 86dcfd9..9cbc2e8 100755
--- a/docker/run_latest.sh
+++ b/docker/run_latest.sh
@@ -6,4 +6,4 @@ SCRIPT_NAME=${BASH_SOURCE[0]}
 cd `dirname ${SCRIPT_NAME}`
 
 # Flask opère sur le port 5000
-docker run -it --rm -p 5000:5000 -v $PWD/..:/work -w /work/test labelstower:demo $*
\ No newline at end of file
+docker run -it --rm -p 5000:5000 -v $PWD/..:/work -w /work/test --env LF_CFG="${LF_CFG}" labelstower:latest $*
\ No newline at end of file
diff --git a/labelstower/__init__.py b/labelstower/__init__.py
index 7c8f1f7..0a51978 100644
--- a/labelstower/__init__.py
+++ b/labelstower/__init__.py
@@ -2,5 +2,5 @@ from flask import Blueprint
 
 bp = Blueprint('sort', __name__)
 
-from labelstower import routes
+from . import routes
 
diff --git a/labelstower/getter.py b/labelstower/getter.py
index b2cb67e..9b62647 100644
--- a/labelstower/getter.py
+++ b/labelstower/getter.py
@@ -1,5 +1,6 @@
 from typing import Dict, List
 from .request_db import send_query_to_db
+from ..labelstower import bp
 
 
 def get_selected_elements(id_mandatory_labels: int, id_forbiden_labels: str, number_of_mandatory_labels: str) -> List[Dict[int, str]] :
@@ -210,5 +211,14 @@ def get_user_selection(number_of_mandatory_labels: int, optional1: str, optional
     return id_mandatory_labels, id_forbiden_labels
 
 if __name__ == "__main__":
+    
+    from flask import Flask
+    from flask_sqlalchemy import SQLAlchemy
+    import os
+    
+    app = Flask(__name__)
+    app.config.from_object(os.environ['LABELSTOWER_ENV'])
+    bp.db = SQLAlchemy(app)
+
     import doctest
     doctest.testmod(verbose=True)
\ No newline at end of file
diff --git a/labelstower/request_db.py b/labelstower/request_db.py
index 4cc119a..8c092ef 100644
--- a/labelstower/request_db.py
+++ b/labelstower/request_db.py
@@ -1,5 +1,5 @@
 from typing import Dict, List
-from labelstower import db
+from ..labelstower import bp
 
 def send_query_to_db(query: str) -> List[Dict[int, str]] :
     '''
@@ -8,8 +8,8 @@ def send_query_to_db(query: str) -> List[Dict[int, str]] :
     :return: List[Dict[int, str]]
     '''
     result = []
-    stmt = db.text(query)
-    response = db.session.execute(stmt)
+    stmt = bp.db.text(query)
+    response = bp.db.session.execute(stmt)
     for row in response:
          result.append({"id": row[0], "name": row[1]})
     return result
\ No newline at end of file
diff --git a/labelstower/routes.py b/labelstower/routes.py
index b2f7496..5328ced 100644
--- a/labelstower/routes.py
+++ b/labelstower/routes.py
@@ -1,8 +1,7 @@
 from typing import Dict, List
 import json
-from labelstower.getter import get_selected_elements, get_discriminating_labels, get_high_discriminating_labels, get_user_selection
-from labelstower import bp
-
+from ..labelstower.getter import get_selected_elements, get_discriminating_labels, get_high_discriminating_labels, get_user_selection
+from ..labelstower import bp
 
 #URLs call to update labels and elements along researchs
 
diff --git a/test/demo_flask/__init__.py b/test/demo/__init__.py
similarity index 86%
rename from test/demo_flask/__init__.py
rename to test/demo/__init__.py
index 0fa7173..7d8f638 100644
--- a/test/demo_flask/__init__.py
+++ b/test/demo/__init__.py
@@ -3,7 +3,6 @@ from flask import Flask, render_template
 from flask_sqlalchemy import SQLAlchemy
 from flask_cors import CORS
 
-
 db = SQLAlchemy()
 
 class CustomFlask(Flask):
@@ -25,13 +24,15 @@ def create_app():
 
     app.config.from_object(os.environ['LABELSTOWER_ENV'])
 
-    from labelstower import bp
-    app.register_blueprint(bp, url_prefix='/sort')
+    from labelstower import bp as bp_labels
+    bp_labels.db = db
+    app.register_blueprint(bp_labels, url_prefix='/sort')
 
     @app.route('/')
     @app.route('/browse')
     def home():
         return render_template('browse.html', txt=text_component)
+
     return app
 
 
diff --git a/test/demo/config.py b/test/demo/config.py
new file mode 100644
index 0000000..a8c1f30
--- /dev/null
+++ b/test/demo/config.py
@@ -0,0 +1,6 @@
+
+class ConfigCodingPool():
+    SQLALCHEMY_DATABASE_URI = 'sqlite:///../instance/CodingPool.sqlite'
+
+class ConfigVoiture():
+    SQLALCHEMY_DATABASE_URI = 'sqlite:///../instance/Voiture.sqlite'
\ No newline at end of file
diff --git a/test/demo_flask/models.py b/test/demo/models.py
similarity index 81%
rename from test/demo_flask/models.py
rename to test/demo/models.py
index d51e759..3f24d5d 100644
--- a/test/demo_flask/models.py
+++ b/test/demo/models.py
@@ -1,15 +1,15 @@
 from flask import Flask
 from flask_sqlalchemy import SQLAlchemy
+import os
 
 app = Flask(__name__)
-app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///test.db'
+app.config.from_object(os.environ['LABELSTOWER_ENV'])
 db = SQLAlchemy(app)
 
-
 element_label = db.Table('Element_Label', db.Model.metadata,
-                         db.Column('id_element', db.Integer, db.ForeignKey('element.id')),
-                         db.Column('id_label', db.Integer, db.ForeignKey('label.id'))
-                         )
+     db.Column('id_element', db.Integer, db.ForeignKey('element.id')),
+     db.Column('id_label', db.Integer, db.ForeignKey('label.id'))
+     )
 
 class Element(db.Model):
     id = db.Column(db.INTEGER, primary_key=True)
diff --git a/test/demo_flask/static/categories.txt b/test/demo/static/categories.txt
similarity index 100%
rename from test/demo_flask/static/categories.txt
rename to test/demo/static/categories.txt
diff --git a/test/demo_flask/static/css/bootstrap.css b/test/demo/static/css/bootstrap.css
similarity index 100%
rename from test/demo_flask/static/css/bootstrap.css
rename to test/demo/static/css/bootstrap.css
diff --git a/test/demo_flask/static/css/bootstrap_1.css b/test/demo/static/css/bootstrap_1.css
similarity index 100%
rename from test/demo_flask/static/css/bootstrap_1.css
rename to test/demo/static/css/bootstrap_1.css
diff --git a/test/demo_flask/static/css/hierarchy.css b/test/demo/static/css/hierarchy.css
similarity index 100%
rename from test/demo_flask/static/css/hierarchy.css
rename to test/demo/static/css/hierarchy.css
diff --git a/test/demo_flask/static/css/main.css b/test/demo/static/css/main.css
similarity index 100%
rename from test/demo_flask/static/css/main.css
rename to test/demo/static/css/main.css
diff --git a/test/demo_flask/static/css/result.css b/test/demo/static/css/result.css
similarity index 100%
rename from test/demo_flask/static/css/result.css
rename to test/demo/static/css/result.css
diff --git a/test/demo_flask/static/fonts/glyphicons-halflings-regular.eot b/test/demo/static/fonts/glyphicons-halflings-regular.eot
similarity index 100%
rename from test/demo_flask/static/fonts/glyphicons-halflings-regular.eot
rename to test/demo/static/fonts/glyphicons-halflings-regular.eot
diff --git a/test/demo_flask/static/fonts/glyphicons-halflings-regular.svg b/test/demo/static/fonts/glyphicons-halflings-regular.svg
similarity index 100%
rename from test/demo_flask/static/fonts/glyphicons-halflings-regular.svg
rename to test/demo/static/fonts/glyphicons-halflings-regular.svg
diff --git a/test/demo_flask/static/fonts/glyphicons-halflings-regular.ttf b/test/demo/static/fonts/glyphicons-halflings-regular.ttf
similarity index 100%
rename from test/demo_flask/static/fonts/glyphicons-halflings-regular.ttf
rename to test/demo/static/fonts/glyphicons-halflings-regular.ttf
diff --git a/test/demo_flask/static/fonts/glyphicons-halflings-regular.woff b/test/demo/static/fonts/glyphicons-halflings-regular.woff
similarity index 100%
rename from test/demo_flask/static/fonts/glyphicons-halflings-regular.woff
rename to test/demo/static/fonts/glyphicons-halflings-regular.woff
diff --git a/test/demo_flask/static/fonts/glyphicons-halflings-regular.woff2 b/test/demo/static/fonts/glyphicons-halflings-regular.woff2
similarity index 100%
rename from test/demo_flask/static/fonts/glyphicons-halflings-regular.woff2
rename to test/demo/static/fonts/glyphicons-halflings-regular.woff2
diff --git a/test/demo_flask/static/img/background_loop.png b/test/demo/static/img/background_loop.png
similarity index 100%
rename from test/demo_flask/static/img/background_loop.png
rename to test/demo/static/img/background_loop.png
diff --git a/test/demo_flask/static/img/moins-encadre-rouge.png b/test/demo/static/img/moins-encadre-rouge.png
similarity index 100%
rename from test/demo_flask/static/img/moins-encadre-rouge.png
rename to test/demo/static/img/moins-encadre-rouge.png
diff --git a/test/demo_flask/static/img/moins-encadre.png b/test/demo/static/img/moins-encadre.png
similarity index 100%
rename from test/demo_flask/static/img/moins-encadre.png
rename to test/demo/static/img/moins-encadre.png
diff --git a/test/demo_flask/static/img/moins-rouge.png b/test/demo/static/img/moins-rouge.png
similarity index 100%
rename from test/demo_flask/static/img/moins-rouge.png
rename to test/demo/static/img/moins-rouge.png
diff --git a/test/demo_flask/static/img/moins.png b/test/demo/static/img/moins.png
similarity index 100%
rename from test/demo_flask/static/img/moins.png
rename to test/demo/static/img/moins.png
diff --git a/test/demo_flask/static/img/monSeparateur.png b/test/demo/static/img/monSeparateur.png
similarity index 100%
rename from test/demo_flask/static/img/monSeparateur.png
rename to test/demo/static/img/monSeparateur.png
diff --git a/test/demo_flask/static/img/plus-encadre-vert.png b/test/demo/static/img/plus-encadre-vert.png
similarity index 100%
rename from test/demo_flask/static/img/plus-encadre-vert.png
rename to test/demo/static/img/plus-encadre-vert.png
diff --git a/test/demo_flask/static/img/plus-encadre.png b/test/demo/static/img/plus-encadre.png
similarity index 100%
rename from test/demo_flask/static/img/plus-encadre.png
rename to test/demo/static/img/plus-encadre.png
diff --git a/test/demo_flask/static/img/plus-vert.png b/test/demo/static/img/plus-vert.png
similarity index 100%
rename from test/demo_flask/static/img/plus-vert.png
rename to test/demo/static/img/plus-vert.png
diff --git a/test/demo_flask/static/img/plus.png b/test/demo/static/img/plus.png
similarity index 100%
rename from test/demo_flask/static/img/plus.png
rename to test/demo/static/img/plus.png
diff --git a/test/demo_flask/static/js/ajax.js b/test/demo/static/js/ajax.js
similarity index 100%
rename from test/demo_flask/static/js/ajax.js
rename to test/demo/static/js/ajax.js
diff --git a/test/demo_flask/static/js/cookies.js b/test/demo/static/js/cookies.js
similarity index 100%
rename from test/demo_flask/static/js/cookies.js
rename to test/demo/static/js/cookies.js
diff --git a/test/demo_flask/static/js/search_new_elements.js b/test/demo/static/js/search_new_elements.js
similarity index 100%
rename from test/demo_flask/static/js/search_new_elements.js
rename to test/demo/static/js/search_new_elements.js
diff --git a/test/demo_flask/static/js/vue.js b/test/demo/static/js/vue.js
similarity index 100%
rename from test/demo_flask/static/js/vue.js
rename to test/demo/static/js/vue.js
diff --git a/test/demo_flask/templates/api_documentation.html b/test/demo/templates/api_documentation.html
similarity index 100%
rename from test/demo_flask/templates/api_documentation.html
rename to test/demo/templates/api_documentation.html
diff --git a/test/demo_flask/templates/browse.html b/test/demo/templates/browse.html
similarity index 100%
rename from test/demo_flask/templates/browse.html
rename to test/demo/templates/browse.html
diff --git a/test/demo_flask/config.py b/test/demo_flask/config.py
deleted file mode 100644
index 5461e27..0000000
--- a/test/demo_flask/config.py
+++ /dev/null
@@ -1,5 +0,0 @@
-class ConfigCodingPool():
-    SQLALCHEMY_DATABASE_URI = 'sqlite:///../instance/codingpool.db'
-
-class ConfigVoiture():
-    SQLALCHEMY_DATABASE_URI = 'sqlite:///../instance/voiture.db'
\ No newline at end of file
diff --git a/test/instance/data_codingpool.sql b/test/instance/DataCodingPool.sql
similarity index 100%
rename from test/instance/data_codingpool.sql
rename to test/instance/DataCodingPool.sql
diff --git a/test/instance/data_voiture.sql b/test/instance/DataVoiture.sql
similarity index 100%
rename from test/instance/data_voiture.sql
rename to test/instance/DataVoiture.sql
diff --git a/test/instance/init_db.sh b/test/instance/init_db.sh
index 0b97342..7332fe1 100644
--- a/test/instance/init_db.sh
+++ b/test/instance/init_db.sh
@@ -5,9 +5,8 @@
 SCRIPT_NAME=${BASH_SOURCE[0]}
 cd `dirname ${SCRIPT_NAME}`
 
-rm -f codeguards.sqlite
+rm -f ${LT_CFG}.sqlite
 cd .. # so to see demo_blog
-python3 -c 'from demo_flask.models import db; from demo import create_app; db.create_all(app=create_app());'
+python3 -c 'from demo.models import db; from demo import create_app; db.create_all(app=create_app());'
 cd instance
-sqlite3 codeguards.sqlite '.read insert_roles.sql'
-sqlite3 codeguards.sqlite '.read insert_data.sql'
\ No newline at end of file
+sqlite3 ${LT_CFG}.sqlite '.read Data${LT_CFG}.sql'
diff --git a/test/instance/pip_init_db.sh b/test/instance/pip_init_db.sh
new file mode 100755
index 0000000..f1e4f50
--- /dev/null
+++ b/test/instance/pip_init_db.sh
@@ -0,0 +1,10 @@
+#!/usr/bin/env bash
+
+# This ensures that we are in this script directory,
+# even if we call it from another one.
+SCRIPT_NAME=${BASH_SOURCE[0]}
+cd `dirname ${SCRIPT_NAME}`
+
+cd ../..
+dist/install.sh
+test/instance/init_voiture_db.sh
\ No newline at end of file
diff --git a/test/scripts/doctests.sh b/test/scripts/doctests.sh
new file mode 100755
index 0000000..ee1859f
--- /dev/null
+++ b/test/scripts/doctests.sh
@@ -0,0 +1,9 @@
+#!/usr/bin/env bash
+
+# This ensures that we are in this script directory,
+# even if we call it from another one.
+SCRIPT_NAME=${BASH_SOURCE[0]}
+cd `dirname ${SCRIPT_NAME}`
+
+cd ../..
+python3 labelstower/getter.py
-- 
GitLab