From 94db3a0757adddc67875ce512544c4571d32b6f4 Mon Sep 17 00:00:00 2001
From: Campos Airas <d.campos@ibermatica.com>
Date: Thu, 11 May 2023 10:47:20 +0200
Subject: [PATCH] [IMP] added docker files + info

---
 Dockerfile                  |  15 ++
 README.md                   |   5 +
 docker-compose.yml          |  30 ++++
 extra_data/Dump20230302.zip | Bin 0 -> 7135 bytes
 main.py                     | 303 ++++++++++++++++++++++++++++++++++++
 requirements.txt            |   2 +-
 requirements_docker.txt     |   7 +
 uwsgi.ini                   |   4 +
 8 files changed, 365 insertions(+), 1 deletion(-)
 create mode 100644 Dockerfile
 create mode 100644 docker-compose.yml
 create mode 100644 extra_data/Dump20230302.zip
 create mode 100644 main.py
 create mode 100644 requirements_docker.txt
 create mode 100644 uwsgi.ini

diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000..7f2de82
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,15 @@
+FROM tiangolo/uwsgi-nginx-flask:python3.10
+
+RUN apt -qq -y update && apt -qq -y upgrade
+
+ENV STATIC_URL /static
+ENV STATIC_PATH /var/www/app/static
+COPY ./requirements_docker.txt /app/requirements.txt
+RUN python -m pip install --no-cache-dir --index-url https://support.bayesfusion.com/pysmile-A/ pysmile
+RUN pip install --no-cache-dir --upgrade -r /app/requirements.txt
+COPY . /app
+
+#EXPOSE 5000
+# Finally, we run uWSGI with the ini file we
+# created earlier
+#CMD [ "python", "./app/main.py" ]
\ No newline at end of file
diff --git a/README.md b/README.md
index 94d0b43..45ad17c 100644
--- a/README.md
+++ b/README.md
@@ -3,6 +3,11 @@
 INSTALL
 python -m pip install --no-cache-dir --index-url https://support.bayesfusion.com/pysmile-A/ pysmile
 
+Docker
+https://hub.docker.com/r/tiangolo/uwsgi-nginx-flask
+
+docker compose -f docker-compose.yml up
+
 ## Getting started
 
 To make it easy for you to get started with GitLab, here's a list of recommended next steps.
diff --git a/docker-compose.yml b/docker-compose.yml
new file mode 100644
index 0000000..5fc44b2
--- /dev/null
+++ b/docker-compose.yml
@@ -0,0 +1,30 @@
+version: "3.9"
+services:
+  urbanite:
+    build:
+#   build: .
+      context: .
+      dockerfile: ./Dockerfile
+    container_name: urbanite-api
+    depends_on:
+      - mysqldb
+    ports:
+      - "80:80"
+    links:
+      - mysqldb:mysql
+  mysqldb:
+    image: mysql
+    restart: always
+    ports:
+      - "3308:3306"
+    environment:
+      - MYSQL_ROOT_PASSWORD=admin
+      - MYSQL_DATABASE=urbanite_recommender
+    volumes:
+      #- db-data:/var/lib/mysql
+      - ./ddbb_scripts/Dump_urbanite_recommender.sql:/docker-entrypoint-initdb.d/urbanite_recommender.sql
+
+# Names our volume
+volumes:
+  db-data:
+    driver: local
diff --git a/extra_data/Dump20230302.zip b/extra_data/Dump20230302.zip
new file mode 100644
index 0000000000000000000000000000000000000000..af81576ec78f828f9036ed2c10b8a909665b7873
GIT binary patch
literal 7135
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
JGD&`a{TDUb`jG$t

literal 0
HcmV?d00001

diff --git a/main.py b/main.py
new file mode 100644
index 0000000..0ceb7bc
--- /dev/null
+++ b/main.py
@@ -0,0 +1,303 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+"""
+Created on: 16/01/2023
+@author: Andoni Aranguren Ubierna
+@updates: Sergio Campos 02-03/2023
+"""
+
+import pickle
+import pysmile
+import sys
+import json
+print(sys.path)
+from src import constants, pysmile_license
+from werkzeug.middleware.proxy_fix import ProxyFix
+
+
+import mysql.connector
+from flask import Flask, request, render_template
+
+from src import configuration, recommender, database, planner, modal_choice
+
+app = Flask(__name__)
+
+model = pickle.load(open('model.pkcls', 'rb'))
+"""
+net = pysmile.Network()
+"""
+
+#CORS
+from flask_cors import CORS
+cors = CORS(app, resources={r"/*": {"origins": "*"}})
+
+cnx = None
+
+
+@app.route("/")
+def index():
+    return render_template("index.html")
+
+
+
+# MODAL CHOICE: -------------------------------------------------------------------------------------------------------
+@app.get("/modal_choice/getConfigurationFile")
+def modal_choice_getconfigurationfile():
+    """
+    We ask for actions based on popularity of the actions
+    :return: json
+    """
+    return modal_choice.modal_choice_getconfigurationfile(cnx, request)
+
+
+
+
+@app.get("/modal_choice/estimation")
+def modal_choice_estimation():
+    """
+    We ask for actions based on popularity of the actions
+    :return: json
+    """
+    return modal_choice.modal_choice_estimation(cnx, request) 
+
+@app.get("/modal_choice/getProbabilites")
+def modal_choice_getprobabilities():
+    """
+    We ask for actions based on popularity of the actions
+    :return: json
+    """
+    return modal_choice.modal_choice_getprobabilities(cnx, request)
+
+@app.get("/modal_choice/setProbabilites")
+def modal_choice_setprobabilities():
+    """
+    We ask for actions based on popularity of the actions
+    :return: json
+    """
+    return modal_choice.modal_choice_setprobabilities(cnx, request)
+
+
+@app.get("/modal_choice/getDependencies")
+def modal_choice_getdependencies():
+    """
+    We ask for actions based on popularity of the actions
+    :return: json
+    """
+    return modal_choice.modal_choice_getdependencies(cnx, request)
+
+
+@app.get("/modal_choice/getValues")
+def modal_choice_getvalues():
+    """
+    We ask for actions based on popularity of the actions
+    :return: json
+    """
+    return modal_choice.modal_choice_getvalues(cnx, request)
+
+
+
+
+
+#Dexi configuration: -------------------------------------------------------------------------------------------------
+@app.get("/recommender/configuration/getMatrix")
+def configuration_getmatrix():
+    """
+    We ask for actions based on popularity of the actions
+    :return: json
+    """
+    return configuration.getmatrix(cnx, request) 
+
+
+@app.get("/recommender/configuration/setMatrix")
+def configuration_setmatrix():
+    """
+    We ask for actions based on popularity of the actions
+    :return: json
+    """
+    return configuration.setmatrix(cnx, request)
+
+
+@app.get("/recommender/configuration/getSliders")
+def configuration_getsliders():
+    """
+    We ask for actions based on popularity of the actions
+    :return: json
+    """
+    return configuration.getsliders(cnx, request)
+
+
+@app.get("/recommender/configuration/setSliders")
+def configuration_setsliders():
+    """
+    We ask for actions based on popularity of the actions
+    :return: json
+    """
+    return configuration.setsliders(cnx, request)
+
+
+
+@app.get("/recommender/configuration/getEvaluationFile")
+def configuration_getevaluationfile():
+    """
+    We ask for actions based on popularity of the actions
+    :return: json
+    """
+    return configuration.getevaluationfile(cnx, request)
+
+
+@app.get("/recommender/configuration/getConfigurationFile")
+def configuration_getconfigurationfile():
+    """
+    We ask for actions based on popularity of the actions
+    :return: json
+    """
+    return configuration.getconfigurationfile(cnx, request)
+
+
+
+# RECOMMENDERS: -------------------------------------------------------------------------------------------------------
+@app.get("/recommender/popularity")
+def recommender_popularity():
+    """
+    We ask for actions based on popularity of the actions
+    :return: json
+    """
+    return recommender.recommender_popularity(cnx, request)
+
+
+@app.get("/recommender/geographic/action_id")
+def recommender_geographic_id():
+    """
+    We ask for actions based on popularity of the actions
+    :return: json
+    """
+    return recommender.recommender_geographic_id(cnx, request)
+
+
+@app.get("/recommender/geographic/lat_lon")
+def recommender_geographic_lat_lon():
+    """
+    We ask for actions based on popularity of the actions
+    :return: json
+    """
+    return recommender.recommender_geographic_lat_lon(cnx, request)
+
+
+@app.get("/recommender/preferences")
+def recommender_preferences():
+    """
+    We ask for kpis based on the affinity to the kpi provided.
+    :return: json
+    """
+    return recommender.recommender_preferences(cnx, request)
+
+
+@app.get("/recommender/kpis/kpi_id")
+def recommender_kpis_kpi_id():
+    """
+    Provided a action it returns a set of kpis by their affinity regarding the provided action
+    :return: json
+    """
+    return recommender.recommender_kpis_kpi_id(cnx, request)
+
+
+@app.get("/recommender/kpis/action_id")
+def recommender_kpis_action_id():
+    """
+    Provided a action it returns a set of kpis by their affinity regarding the provided action
+    :return: json
+    """
+    return recommender.recommender_kpis_action_id(cnx, request)
+
+
+@app.get("/recommender/bayesian")
+def recommender_bayesian_action_id():
+    """
+    We ask for actions based on popularity of the actions
+    :return: json
+    """
+    return recommender.recommender_bayesian_action_id(cnx, request)
+
+
+# DATABASE SAVE: -------------------------------------------------------------------------------------------------------
+@app.post("/database/save/plan")
+def database_save_plan():
+    """
+    It stores the plan_details that have been selected.
+    The json provided should have the same format that /planner/plan_detail outputs filled with each plan_detail
+    :return: json with the plan_detail
+    """
+    if request.json:
+        return database.database_save_plan(cnx, request)
+    else:
+        return constants.ERROR_JSON_NEEDED
+
+
+# plan_detail PLANNER: -------------------------------------------------------------------------------------------------------
+@app.get("/planner/plan_detail")
+def planner_plan_detail():
+    """
+    It calculates the best plan_detail traversing streets and reordering the intermediate nodes provided.
+    :return: json with the plan_detail
+    """
+    return planner.planner_plan_detail(cnx, request)
+
+@app.get("/database/store/kpi")
+def database_store_kpi():
+    """
+    The json provided should have the same format that json with the kpi
+    """
+    #if request.json:
+    if request:
+        return database.database_store_kpi(cnx, request)
+    else:
+        return constants.ERROR_JSON_NEEDED
+
+@app.get("/database/store/kpi_relative")
+def database_store_kpi_relative():
+    """
+    The json provided should have the same format that json with the kpi
+    """
+    #if request.json:
+    if request:
+        return database.database_store_kpi(cnx, request, relative=True)
+    else:
+        return constants.ERROR_JSON_NEEDED
+
+@app.get("/database/store/kpi_area")
+def database_store_kpi_area():
+    """
+    The json provided should have the same format that json with the kpi
+    """
+    #if request.json:
+    if request:
+        return database.database_store_kpi(cnx, request, area=True)
+    else:
+        return constants.ERROR_JSON_NEEDED
+
+@app.get("/database/store/kpi_relative_area")
+def database_store_kpi_relative_area():
+    """
+    The json provided should have the same format that json with the kpi
+    """
+    #if request.json:
+    if request:
+        return database.database_store_kpi_relative_area(cnx, request)
+    else:
+        return constants.ERROR_JSON_NEEDED
+
+# MAIN: ----------------------------------------------------------------------------------------------------------------
+if __name__ == "__main__":
+    """model = pickle.load(open('model.pkcls', 'rb'))
+    net = pysmile.Network()
+    net.read_file("URBANITE_ModalChoice.xdsl");
+    """
+    #cnx = mysql.connector.connect(**constants.DDBB_CONFIG)
+    user = 'root'
+    passwd = 'admin'
+    ip = 'mysql'
+    bd = 'urbanite_recommender'
+    cnx = "mysql+pymysql://%s:%s@%s/%s" % (user, passwd, ip, bd)
+    # app.run(debug=True, host='0.0.0.0')
+    # app.wsgi_app = ProxyFix( app.wsgi_app, x_for=1, x_proto=1, x_host=1, x_prefix=1)
+
diff --git a/requirements.txt b/requirements.txt
index b574026..ab56717 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -88,7 +88,7 @@ pyzmq==25.0.0
 qasync==0.23.0
 qtconsole==5.4.1
 QtPy==2.3.0
-requests=2.28.2
+requests==2.28.2
 rfc3986==1.5.0
 scikit-learn==1.1.3
 scipy==1.10.1
diff --git a/requirements_docker.txt b/requirements_docker.txt
new file mode 100644
index 0000000..8f3169a
--- /dev/null
+++ b/requirements_docker.txt
@@ -0,0 +1,7 @@
+Flask==2.2.3
+Flask-Cors==3.0.10
+mysql-connector-python~=8.0.32
+numpy==1.23.5
+Orange3==3.34.1
+requests==2.28.2
+xmltodict==0.13.0
diff --git a/uwsgi.ini b/uwsgi.ini
new file mode 100644
index 0000000..7a6dccc
--- /dev/null
+++ b/uwsgi.ini
@@ -0,0 +1,4 @@
+[uwsgi]
+module = main
+callable = app
+master = true
-- 
GitLab