commit 9a907c3a8e590b77eed7de63cda1fec788d55f22 Author: Wolfgang Hottgenroth Date: Sat Jan 16 19:47:34 2021 +0100 initial diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2f3e41d --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +__pycache__/ +ENV \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..64124ea --- /dev/null +++ b/Dockerfile @@ -0,0 +1,42 @@ +FROM python:latest + +LABEL Maintainer="Wolfgang Hottgenroth wolfgang.hottgenroth@icloud.com" + +ARG APP_DIR="/opt/app" +ARG CONF_DIR="${APP_DIR}/config" + +ENV DB_HOST="172.16.10.18" +ENV DB_NAME="hausverwaltung" +ENV DB_USER="hausverwaltung-ui" +ENV DB_PASS="test123" + + +RUN \ + apt update && \ + apt install -y libmariadbclient-dev && \ + pip3 install mariadb && \ + pip3 install connexion && \ + pip3 install connexion[swagger-ui] && \ + pip3 install uwsgi && \ + pip3 install flask-cors + +RUN \ + mkdir -p ${APP_DIR} && \ + mkdir -p ${CONF_DIR} && \ + useradd -d ${APP_DIR} -u 1000 user + +COPY *.py ${APP_DIR}/ +COPY swagger.yaml ${APP_DIR}/ +COPY server.ini ${CONF_DIR}/ + +USER 1000:1000 +WORKDIR ${APP_DIR} +VOLUME ${CONF_DIR} + +EXPOSE 5000 +EXPOSE 9191 + +CMD [ "uwsgi", "./config/server.ini" ] + + + diff --git a/Objekte.py b/Objekte.py new file mode 100644 index 0000000..af9e19e --- /dev/null +++ b/Objekte.py @@ -0,0 +1,46 @@ +from dbpool import getConnection + +def get_objekte(): + try: + dbh = getConnection() + objekte = [] + cur = dbh.cursor() + cur.execute("SELECT id, shortname, flaeche FROM objekt") + for (id, shortname, flaeche) in cur: + objekte.append({ + "id": id, + "shortname": shortname, + "flaeche": flaeche + }) + return objekte + except Exception as err: + return str(err), 500 + finally: + dbh.close() + + +def get_objekt(id=None): + try: + dbh = getConnection() + cur = dbh.cursor() + cur.execute("SELECT id, shortname, flaeche FROM objekt WHERE id = ?", (id,)) + objekt = None + try: + (id, shortname, flaeche) = cur.next() + objekt = { + "id": id, + "shortname": shortname, + "flaeche": flaeche + } + except StopIteration: + return "Objekt not found", 404 + try: + (id, shortname, flaeche) = cur.next() + return "More than one Objekt by that id ({}, {}, {})".format(id, shortname, flaeche), 500 + except: + pass + return objekt + except Exception as err: + return str(err), 500 + finally: + dbh.close() diff --git a/Wohnungen.py b/Wohnungen.py new file mode 100644 index 0000000..d34a7d2 --- /dev/null +++ b/Wohnungen.py @@ -0,0 +1,67 @@ +from dbpool import getConnection + +def get_wohnungen(): + try: + dbh = getConnection() + wohnungen = [] + cur = dbh.cursor() + cur.execute(""" +SELECT w.id as id, + w.objekt as objekt_id, + w.shortname as wohnung, + w.flaeche as flaeche, + o.shortname as objekt + FROM wohnung w, objekt o + WHERE o.id = w.objekt +""") + for (id, objekt_id, wohnung, flaeche, objekt) in cur: + wohnungen.append({ + "id": id, + "objekt_id": objekt_id, + "wohnung": wohnung, + "flaeche": flaeche, + "objekt": objekt + }) + return wohnungen + except Exception as err: + return str(err), 500 + finally: + dbh.close() + + +def get_wohnung(id=None): + try: + dbh = getConnection() + cur = dbh.cursor() + cur.execute(""" +SELECT w.id as id, + w.objekt as objekt_id, + w.shortname as wohnung, + w.flaeche as flaeche, + o.shortname as objekt + FROM wohnung w, objekt o + WHERE o.id = w.objekt AND + w.id = ? +""", (id, )) + wohnung = None + try: + (id, objekt_id, wohnung_name, flaeche, objekt_name) = cur.next() + wohnung = { + "id": id, + "objekt_id": objekt_id, + "wohnung": wohnung_name, + "flaeche": flaeche, + "objekt": objekt_name + } + except StopIteration: + return "Wohnung not found", 404 + try: + (id, objekt_id, wohnung_name, flaeche, objekt_name) = cur.next() + return "More than one Wohnung by that id ({}, {}, {}, {})".format(id, objekt_name, wohnung_name, flaeche), 500 + except: + pass + return wohnung + except Exception as err: + return str(err), 500 + finally: + dbh.close() diff --git a/dbpool.py b/dbpool.py new file mode 100644 index 0000000..e8feb53 --- /dev/null +++ b/dbpool.py @@ -0,0 +1,28 @@ +import mariadb +import os + +pool = None + +def createConnectionPool(): + global pool + + try: + user = os.environ["DB_USER"] + password = os.environ["DB_PASS"] + host = os.environ["DB_HOST"] + database = os.environ["DB_NAME"] + except KeyError as err: + raise Exception("Database configuration variable {} not available".format(err)) + + pool = mariadb.ConnectionPool( + user = user, + password = password, + host = host, + database = database, + pool_name = 'hv-wep-app', + pool_size = 5 + ) + +def getConnection(): + global pool + return pool.get_connection() diff --git a/server.ini b/server.ini new file mode 100644 index 0000000..81f216b --- /dev/null +++ b/server.ini @@ -0,0 +1,7 @@ +[uwsgi] +http = :5000 +wsgi-file = server.py +processes = 4 +threads = 2 +stats = :9191 + diff --git a/server.py b/server.py new file mode 100644 index 0000000..c6aeb4c --- /dev/null +++ b/server.py @@ -0,0 +1,16 @@ +import connexion +from flask_cors import CORS +from dbpool import createConnectionPool + +# prepare database connections +createConnectionPool() + +# instantiate the webservice +app = connexion.App(__name__) +app.add_api('swagger.yaml') + +# CORSify it - otherwise Angular won't accept it +CORS(app.app) + +# provide the webservice application to uwsgi +application = app.app diff --git a/swagger.yaml b/swagger.yaml new file mode 100644 index 0000000..d5afe02 --- /dev/null +++ b/swagger.yaml @@ -0,0 +1,102 @@ +swagger: '2.0' +info: + title: Hausverwaltung + version: "0.1" + +paths: + /hv/objekte: + get: + tags: [ "Objekte" ] + operationId: Objekte.get_objekte + summary: Returns all Objekte + responses: + 200: + description: Successful response. + schema: + type: array + items: + $ref: '#/definitions/Objekt' + 404: + description: No Objekte available + 500: + description: Some server error + /hv/objekt/{id}: + get: + tags: [ "Objekte" ] + operationId: Objekte.get_objekt + summary: Returns Objekt by id + parameters: + - name: id + in: path + type: integer + required: true + responses: + 200: + description: Successful response. + schema: + $ref: '#/definitions/Objekt' + 404: + description: Objekt not found + 500: + description: Some server error + /hv/wohnungen: + get: + tags: [ "Wohnungen" ] + operationId: Wohnungen.get_wohnungen + summary: Returns all Wohnungen + responses: + 200: + description: Successful response. + schema: + type: array + items: + $ref: '#/definitions/Wohnung' + 404: + description: No Wohnung available + 500: + description: Some server error + /hv/wohnung/{id}: + get: + tags: [ "Wohnungen" ] + operationId: Wohnungen.get_wohnung + summary: Returns Wohnung by id + parameters: + - name: id + in: path + type: integer + required: true + responses: + 200: + description: Successful response. + schema: + $ref: '#/definitions/Wohnung' + 404: + description: Wohnung not found + 500: + description: Some server error + +definitions: + Objekt: + description: Objekt type + type: object + properties: + id: + type: integer + shortname: + type: string + flaeche: + type: number + Wohnung: + description: Wohnung type + type: object + properties: + id: + type: integer + objekt_id: + type: integer + wohnung: + type: string + flaeche: + type: number + objekt: + type: string