aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGalen Guyer <galen@galenguyer.com>2022-05-13 11:42:26 -0400
committerGalen Guyer <galen@galenguyer.com>2022-05-13 11:42:26 -0400
commit1110d04f5123e800823c663928065bb1b232a11c (patch)
tree404623864d512a5c025e04953fc1c2a332ca2c37
parenta275cad5fa9a575ed913c5819b8d2f5c902c21fd (diff)
add python/flask
-rw-r--r--python/flask/.gitignore3
-rw-r--r--python/flask/config.py15
-rw-r--r--python/flask/http_perf_flask/__init__.py20
-rw-r--r--python/flask/requirements.txt7
-rwxr-xr-xpython/flask/test.sh29
-rw-r--r--python/flask/wsgi.py8
6 files changed, 82 insertions, 0 deletions
diff --git a/python/flask/.gitignore b/python/flask/.gitignore
new file mode 100644
index 0000000..0498b30
--- /dev/null
+++ b/python/flask/.gitignore
@@ -0,0 +1,3 @@
+env/
+__pycache__/
+*.pyc
diff --git a/python/flask/config.py b/python/flask/config.py
new file mode 100644
index 0000000..2004d4c
--- /dev/null
+++ b/python/flask/config.py
@@ -0,0 +1,15 @@
+import secrets
+import os
+
+# Values in this file are loaded into the flask app instance, `demo.APP` in this
+# demo. This file sources values from the environment if they exist, otherwise a
+# set of defaults are used. This is useful for keeping secrets secret, as well
+# as facilitating configuration in a container. Defaults may be overriden either
+# by defining the environment variables, or by creating a `config.py` file that
+# contains locally set secrets or config values.
+
+
+# Defaults for flask configuration
+IP = os.environ.get('IP', '127.0.0.1')
+PORT = os.environ.get('PORT', 8080)
+SECRET_KEY = os.environ.get('SESSION_KEY', default=''.join(secrets.token_hex(16)))
diff --git a/python/flask/http_perf_flask/__init__.py b/python/flask/http_perf_flask/__init__.py
new file mode 100644
index 0000000..14f85c3
--- /dev/null
+++ b/python/flask/http_perf_flask/__init__.py
@@ -0,0 +1,20 @@
+""" A small flask Hello World """
+
+import os
+import subprocess
+
+from flask import Flask, jsonify
+
+APP = Flask(__name__)
+
+# Load file based configuration overrides if present
+if os.path.exists(os.path.join(os.getcwd(), 'config.py')):
+ APP.config.from_pyfile(os.path.join(os.getcwd(), 'config.py'))
+else:
+ APP.config.from_pyfile(os.path.join(os.getcwd(), 'config.env.py'))
+
+APP.secret_key = APP.config['SECRET_KEY']
+
+@APP.route('/')
+def _index():
+ return jsonify(message="OK")
diff --git a/python/flask/requirements.txt b/python/flask/requirements.txt
new file mode 100644
index 0000000..3017968
--- /dev/null
+++ b/python/flask/requirements.txt
@@ -0,0 +1,7 @@
+click==8.1.3
+Flask==2.1.2
+gunicorn==20.1.0
+itsdangerous==2.1.2
+Jinja2==3.1.2
+MarkupSafe==2.1.1
+Werkzeug==2.1.2
diff --git a/python/flask/test.sh b/python/flask/test.sh
new file mode 100755
index 0000000..8e3ced8
--- /dev/null
+++ b/python/flask/test.sh
@@ -0,0 +1,29 @@
+#!/usr/bin/env bash
+# exit on error
+set -e
+
+# display last non-zero exit code in a failed pipeline
+set -o pipefail
+
+# subshells and functions inherit ERR traps
+set -E
+
+cd "$(dirname "$0")"
+
+function cleanup {
+ >&2 echo "killing server (pid $PID)"
+ kill "$PID"
+ deactivate
+}
+trap cleanup EXIT
+
+>&2 echo "running server"
+source env/bin/activate
+gunicorn http_perf_flask:APP --bind=localhost:8080 &>/dev/null &
+PID="$!"
+
+>&2 echo "captured pid $PID"
+
+sleep 2
+>&2 echo "running wrk"
+wrk -t2 -c500 -d 30s --latency "http://localhost:8080/"
diff --git a/python/flask/wsgi.py b/python/flask/wsgi.py
new file mode 100644
index 0000000..81e38ed
--- /dev/null
+++ b/python/flask/wsgi.py
@@ -0,0 +1,8 @@
+"""
+Primary entry point for the app
+"""
+
+from http_perf_flask import APP
+
+if __name__ == "__main__":
+ APP.run(host=APP.config["IP"], port=int(APP.config["PORT"]))