From b34b9558e39c52c79eadd44c894f6a2de45b3e1f Mon Sep 17 00:00:00 2001 From: lostbean Date: Fri, 5 Jul 2024 18:54:36 -0300 Subject: [PATCH] add demo example --- examples/voting-app/load-generator.py | 35 +++++ examples/voting-app/shell.nix | 27 ++++ examples/voting-app/voting-app-ui/Dockerfile | 12 ++ .../voting-app/voting-app-ui/Dockerfile-v2 | 14 ++ examples/voting-app/voting-app-ui/app.py | 94 ++++++++++++ .../voting-app-ui/templates/index.html | 142 ++++++++++++++++++ shell.nix | 10 +- 7 files changed, 333 insertions(+), 1 deletion(-) create mode 100755 examples/voting-app/load-generator.py create mode 100644 examples/voting-app/shell.nix create mode 100644 examples/voting-app/voting-app-ui/Dockerfile create mode 100644 examples/voting-app/voting-app-ui/Dockerfile-v2 create mode 100644 examples/voting-app/voting-app-ui/app.py create mode 100644 examples/voting-app/voting-app-ui/templates/index.html diff --git a/examples/voting-app/load-generator.py b/examples/voting-app/load-generator.py new file mode 100755 index 00000000..afddde0c --- /dev/null +++ b/examples/voting-app/load-generator.py @@ -0,0 +1,35 @@ +import requests +import time + +# The URL to send the POST requests to +host = "prod.app.localhost" +url = "http://127.0.0.1/" + +# Headers to be included in the POST requests +headers = { + "Origin": f"http://{host}", + "Host": host, +} + +# Data to be sent in the POST requests +data_options = ["option1", "option2"] +data_index = 0 + + +# Function to send a burst of 5 POST requests +def send_burst(data): + print(f"New burst of {data}") + for _ in range(5): + response = None + try: + response = requests.post(url, headers=headers, data={"vote": data}) + print(f"Sent '{data}' - Response status code: {response.status_code}") + except requests.exceptions.RequestException as e: + print(f"Error sending '{data}' - {e}") + + +# Send bursts of 5 POST requests every 5 seconds, alternating between 'Cats' and 'Dogs' +while True: + send_burst(data_options[data_index]) + data_index = (data_index + 1) % 2 + time.sleep(5) diff --git a/examples/voting-app/shell.nix b/examples/voting-app/shell.nix new file mode 100644 index 00000000..b082bd69 --- /dev/null +++ b/examples/voting-app/shell.nix @@ -0,0 +1,27 @@ +{pkgs, ...}: let + pyEnv = pkgs.python3.buildEnv.override { + extraLibs = [pkgs.python3Packages.click pkgs.python3Packages.requests]; + ignoreCollisions = true; + }; + + pname = "demo-load-generator"; + demo-load-genarator = pkgs.stdenv.mkDerivation { + inherit pname; + version = "1.0.0"; + + src = ./.; + + installPhase = '' + mkdir -p $out/bin + echo "#!${pyEnv}/bin/python3" > $out/bin/${pname} + cat load-generator.py >> $out/bin/${pname} + chmod +x $out/bin/${pname} + ''; + }; +in + pkgs.mkShell { + buildInputs = [ + demo-load-genarator + pyEnv + ]; + } diff --git a/examples/voting-app/voting-app-ui/Dockerfile b/examples/voting-app/voting-app-ui/Dockerfile new file mode 100644 index 00000000..032b37ca --- /dev/null +++ b/examples/voting-app/voting-app-ui/Dockerfile @@ -0,0 +1,12 @@ +FROM python:3.9-slim + +WORKDIR /app + +COPY . . + +RUN pip install Flask redis + +EXPOSE 5000 + +CMD ["python", "app.py"] + diff --git a/examples/voting-app/voting-app-ui/Dockerfile-v2 b/examples/voting-app/voting-app-ui/Dockerfile-v2 new file mode 100644 index 00000000..cee5a378 --- /dev/null +++ b/examples/voting-app/voting-app-ui/Dockerfile-v2 @@ -0,0 +1,14 @@ +FROM python:3.9-slim + +WORKDIR /app + +COPY . . + +RUN pip install Flask redis + +ENV APP_VERSION v2 + +EXPOSE 5000 + +CMD ["python", "app.py"] + diff --git a/examples/voting-app/voting-app-ui/app.py b/examples/voting-app/voting-app-ui/app.py new file mode 100644 index 00000000..accb3b3b --- /dev/null +++ b/examples/voting-app/voting-app-ui/app.py @@ -0,0 +1,94 @@ +from flask import Flask, render_template, request, redirect, url_for +import redis +import os + +app = Flask(__name__) + +redis_server = os.environ["REDIS"] + +# Initialize Redis +r = redis.Redis(host=redis_server, port=6379) + +# Getting app version +if "APP_VERSION" in os.environ and os.environ["APP_VERSION"]: + app_version = os.environ["APP_VERSION"] +else: + app_version = "v1" + +print("app_version is: " + app_version) + +if "OPTION1" in os.environ and os.environ["OPTION1"]: + option1 = os.environ["OPTION1"] +else: + option1 = "Option 1" + +if "OPTION2" in os.environ and os.environ["OPTION2"]: + option2 = os.environ["OPTION2"] +else: + option2 = "Option 2" + +if "OPTION3" in os.environ and os.environ["OPTION3"] and app_version != "v1": + option3 = os.environ["OPTION3"] +elif app_version != "v1": + option3 = "Option 3" + +if "TITLE" in os.environ and os.environ["TITLE"]: + title = os.environ["TITLE"] +else: + title = "Vote For Your Favorite Option" + +# Set up initial vote counts +# TODO: implement this on redis proxy +if not r.exists("option1"): + r.set("option1", 0) +if not r.exists("option2"): + r.set("option2", 0) + +if app_version == "v1": + if not r.exists("option3"): + r.set("option3", 0) + + +@app.route("/", methods=["GET", "POST"]) +def index(): + if request.method == "POST": + vote = request.form["vote"] + if vote == "option1": + r.incr("option1") + elif vote == "option2": + r.incr("option2") + elif vote == "option3" and app_version != "v1": + r.incr("option3") + return redirect(url_for("index")) + + # Get current vote counts + option1_votes = int(r.get("option1") or 0) + option2_votes = int(r.get("option2") or 0) + if app_version != "v1": + option3_votes = int(r.get("option3") or 0) + + if app_version != "v1": + return render_template( + "index.html", + option1_votes=option1_votes, + option2_votes=option2_votes, + option3_votes=option3_votes, + title=title, + option1=option1, + option2=option2, + option3=option3, + ) + else: + return render_template( + "index.html", + option1_votes=option1_votes, + option2_votes=option2_votes, + title=title, + option1=option1, + option2=option2, + ) + + + +if __name__ == "__main__": + app.run(debug=True, host="0.0.0.0", port=80) diff --git a/examples/voting-app/voting-app-ui/templates/index.html b/examples/voting-app/voting-app-ui/templates/index.html new file mode 100644 index 00000000..0babd41c --- /dev/null +++ b/examples/voting-app/voting-app-ui/templates/index.html @@ -0,0 +1,142 @@ + + + + + + Voting App + + + +
+ +
+
+
+
+
+ + + {% if option3 %} + + {% endif %} +
+
+
+
+
Current votes
+
+ {{ option1 }}: {{ option1_votes }} | + {{ option2 }}: {{ option2_votes }} + {% if option3 %} + | + {{ option3 }}: {{ option3_votes }} + {% endif %} +
+
+
+ + diff --git a/shell.nix b/shell.nix index a28ff08b..6d4db0c1 100644 --- a/shell.nix +++ b/shell.nix @@ -14,6 +14,8 @@ manager_shell = pkgs.callPackage ./kardinal-manager/shell.nix {inherit pkgs;}; cli_shell = pkgs.callPackage ./kardinal-cli/shell.nix {inherit pkgs;}; cli_kontrol_api_shell = pkgs.callPackage ./libs/cli-kontrol-api/shell.nix {inherit pkgs;}; + demo_shell = pkgs.callPackage ./examples/voting-app/shell.nix {inherit pkgs;}; + kardinal_shell = with pkgs; pkgs.mkShell { nativeBuildInputs = [bashInteractive bash-completion]; @@ -64,4 +66,10 @@ ''; }; in - mergeShells [manager_shell cli_shell kardinal_shell cli_kontrol_api_shell] + mergeShells [ + manager_shell + cli_shell + kardinal_shell + cli_kontrol_api_shell + demo_shell + ]