From 60ca370ed8ebd17dedac543685a1d38d340b5715 Mon Sep 17 00:00:00 2001 From: bpetschowitsch Date: Wed, 13 May 2026 15:18:55 +0200 Subject: [PATCH] Create 11_webservice.md --- 11_webservice.md | 193 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 193 insertions(+) create mode 100644 11_webservice.md diff --git a/11_webservice.md b/11_webservice.md new file mode 100644 index 0000000..e9c6f86 --- /dev/null +++ b/11_webservice.md @@ -0,0 +1,193 @@ +# Webservice + +## Webservice itself +We use flask as application server (python based). +Check if flask is installed/otherwise install it... + +```bash +sudo apt list python3 python3-venv --installed +``` +```bash +sudo apt install python3 python3-venv -y +``` + +create a folder for the source-code & python dependencies: + +```bash +sudo mkdir /opt/webservice +sudo chown tux:tux /opt/webservice +``` + +install python dependencies and webservice: + +```bash +cd /opt/webservice +python3 -m venv venv +source venv/bin/activate +pip install flask flask-restx gunicorn +deactivate + +vi webservice.py +``` + +and paste following code: + +```python +from flask import Flask +from flask_restx import Api, Resource + +app = Flask(__name__) +api = Api(app) + +names_list = ["Alice", "Bob", "Charlie"] + +@api.route('/names') +class AddressList(Resource): + + def get(self): + return names_list + + def post(self): + data = api.payload + if "name" in data: + names_list.append(data["name"]) + return {"status": "success"}, 201 + api.abort(400) + + def delete(self): + names_list.clear() + return {"status": "Liste geleert"}, 200 + +if __name__ == '__main__': + app.run(host='0.0.0.0', port=5000, debug=True) +``` + +test the webservice: + +```bash +/opt/webservice/venv/bin/python3 webservice.py +``` + +Verify the webservice using Postman! +URL: `http://:5000/names` + +## Reverse-Proxy + +Stop the webservice simply by pressing `Ctrl + C`, or by `kill `. +change the binding of flask to localhost only by modifing the last line of the webservice source-code: + +```python +if __name__ == '__main__': + app.run(host='127.0.0.1', port=5000, debug=True) +``` + +**Note:** The webservice is no longer accessible from outside the host. + +Make the webservice available through nginx. + +```bash +sudo vi /etc/nginx/sites-available/*site-name* +``` + +add to the server section: + +```nginx +# API Queries are forwarded to Flask +location /api/names { + proxy_pass http://127.0.0.1:5000/names; +} +``` + +reload nginx, start the webservice: + +```bash +sudo systemctl reload nginx +/opt/webservice/venv/bin/python3 webservice.py +``` + +Verify the webservice using Postman! + +URL: `http://*domain-name*/api/names` + +The previous URL should **NOT** work anylonger: `http://:5000/names` + +To start the webservice "production ready", we have a use a wsgi server like gunicorn (which we installed initially via pip): + +```bash +/opt/webservice/venv/bin/gunicorn -w 1 -b 127.0.0.1:5000 webservice:app +``` + +## API Documentation Example + + + +| Method | Ressource (Path) | Input (Body) | Datatype (In) | Possible Values | Output (JSON) | Datatype (Out) | Description | +| :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- | +| **GET** | `/names` | *n/a* | - | - | `["Alice", "Bob", ...]` | `Array` | returns the complete list of names | +| **POST** | `/names` | `{"name": "..."}` | `String` | `*` | `{"status": "success"}` | `String` | adds a new name to the list | +| **DELETE** | `/names` | *n/a* | - | - | `{"status": "Liste geleert"}` | `String` | clears the complete list | + + +## Webapp -> Frontend + +A simple frontend for the webservice. Create a html document (e.g. `webapp2.html`) with the content: + +```html + + + + Demo: Addressbook + + + +

Einfaches Adressbuch

+ + + + +
+ +

Einträge:

+
+ +

Liste leeren

+ + + + + +```