4.7 KiB
Webservice
Webservice itself
We use flask as application server (python based). Check if flask is installed/otherwise install it...
sudo apt list python3 python3-venv --installed
sudo apt install python3 python3-venv -y
create a folder for the source-code & python dependencies:
sudo mkdir /opt/webservice
sudo chown tux:tux /opt/webservice
install python dependencies and webservice:
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:
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:
/opt/webservice/venv/bin/python3 webservice.py
Verify the webservice using Postman!
URL: http://<server-ip-address>:5000/names
Reverse-Proxy
Stop the webservice simply by pressing Ctrl + C, or by kill <pid>.
change the binding of flask to localhost only by modifing the last line of the webservice source-code:
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.
sudo vi /etc/nginx/sites-available/*site-name*
add to the server section:
# API Queries are forwarded to Flask
location /api/names {
proxy_pass http://127.0.0.1:5000/names;
}
reload nginx, start the webservice:
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://<server-ip-address>:5000/names
To start the webservice "production ready", we have a use a wsgi server like gunicorn (which we installed initially via pip):
/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<String> |
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:
<!DOCTYPE html>
<html>
<head>
<title>Demo: Addressbook</title>
</head>
<body>
<h2>Einfaches Adressbuch</h2>
<input type="text" id="nameAdd" name="name" placeholder="Name eingeben..." required>
<button onclick="addName()">Speichern</button>
<hr>
<h3>Einträge:</h3>
<div id="nameList"></div>
<p><small><a id="deleteLink" href="#" onclick="deleteAll();return false;">Liste leeren</a></small></p>
<script>
const API_URL = '/api/names';
async function loadNames() {
try {
const response = await fetch(API_URL);
const names = await response.json();
const list = document.getElementById('nameList');
list.innerHTML = names.map(n => `Benutzer: ${n}<br>`).join('');
} catch (e) {
console.error("Backend nicht erreichbar", e);
}
}
async function addName() {
const val = document.getElementById('nameAdd').value;
if(!val) return;
await fetch(API_URL, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ "name": val })
});
document.getElementById('nameList').value = '';
loadNames();
}
async function deleteAll() {
await fetch(API_URL, { method: 'DELETE' });
loadNames();
}
loadNames();
</script>
</body>
</html>