From 36183acb53c5c0b160611b12b1ccd13d844223fd Mon Sep 17 00:00:00 2001 From: Adrian Gunnar Lauterer Date: Fri, 31 May 2024 18:06:33 +0200 Subject: [PATCH] updated prod deployment to gunicorn --- flake.nix | 93 +++++++++++++++++++++---- result | 1 + result-1 | 1 + src/{main.py => ozai_webui/__init__.py} | 65 ++++++++++------- src/result | 1 + src/run.sh | 16 +++++ src/setup.py | 13 +++- 7 files changed, 148 insertions(+), 42 deletions(-) create mode 120000 result create mode 120000 result-1 rename src/{main.py => ozai_webui/__init__.py} (80%) create mode 120000 src/result create mode 100644 src/run.sh diff --git a/flake.nix b/flake.nix index 94f5256..5401cf5 100644 --- a/flake.nix +++ b/flake.nix @@ -10,20 +10,83 @@ pkgs = import nixpkgs { system = "x86_64-linux"; }; lib = pkgs.lib; types = lib.types; + deps = [ + pkgs.python3 + pkgs.python3Packages.flask + pkgs.python3Packages.flask-socketio + pkgs.python3Packages.requests + pkgs.python3Packages.gunicorn + pkgs.python3Packages.eventlet + ]; in { - packages.x86_64-linux.default = pkgs.python3Packages.buildPythonApplication rec { + packages.x86_64-linux.default = pkgs.python3Packages.buildPythonPackage rec { pname = "ozai-webui"; version = "0.1.1"; - propagatedBuildInputs = [ pkgs.python3Packages.flask pkgs.python3Packages.flask-socketio pkgs.python3Packages.requests ]; + #propagatedBuildInputs = deps; + dependencies = deps; src = ./src; doCheck = false; - + postInstall = '' - mkdir -p $out/share/ozai-webui - cp -r static $out/share/ozai-webui/static - cp -r templates $out/share/ozai-webui/templates - mv $out/bin/main.py $out/bin/ozai-webui + mkdir -p $out/share/ozai_webui/static + mkdir -p $out/share/ozai_webui/templates + install -Dm444 ${src}/static/* $out/share/ozai_webui/static/ + install -Dm444 ${src}/templates/* $out/share/ozai_webui/templates/ + ''; + }; + + + +packages.x86_64-linux.ozai-webui-run = pkgs.stdenv.mkDerivation rec { + pname = "ozai-webui-run"; + version = "0.1.1"; + src = ./src; + + pythonEnv = pkgs.python3.withPackages (ps: with ps; [ + flask + flask-socketio + requests + gunicorn + eventlet + ]); + + buildInputs = [ + pkgs.bash + pythonEnv + ]; + + propagatedBuildInputs = buildInputs; + + nativeBuildInputs = [ + pkgs.makeWrapper + ]; + + installPhase = '' + mkdir -p $out/bin + cp $src/run.sh $out/bin/run + chmod +x $out/bin/run + wrapProgram $out/bin/run \ + --prefix PATH : ${lib.makeBinPath buildInputs} + ''; +}; + + + + + + + + + + + + + devShells.x86_64-linux.default = pkgs.mkShell { + buildInputs = deps; + shellHook = '' + OZAI_WEBUI_STATIC_FOLDER=result/share/ozai-webui/static + OZAI_WEBUI_TEMPLATE_FOLDER=result/share/ozai-webui/templates ''; }; @@ -45,11 +108,6 @@ default = "http://localhost:8000/api/"; description = "The URL of the Ozai server"; }; - secretKey = lib.mkOption { - type = types.str; - default = "secret_key"; - description = "The secret key for the Flask app"; - }; }; config = lib.mkIf config.services.ozai-webui.enable { @@ -57,8 +115,17 @@ description = "Ozai WebUI server"; after = [ "network.target" ]; wantedBy = [ "multi-user.target" ]; + environment = { + OZAI_URL= "${config.services.ozai-webui.ozaiUrl}"; + OZAI_WEBUI_HOST= "${config.services.ozai-webui.host}"; + OZAI_WEBUI_PORT= toString(config.services.ozai-webui.port); + OZAI_WEBUI_STATIC_FOLDER= "${self.packages.x86_64-linux.default}/share/ozai-webui/static"; + OZAI_WEBUI_TEMPLATE_FOLDER="${self.packages.x86_64-linux.default}/share/ozai-webui/templates"; + }; + serviceConfig = { - ExecStart = "${self.packages.x86_64-linux.default}/bin/ozai-webui --port ${toString config.services.ozai-webui.port} --host '${config.services.ozai-webui.host}' --ozai_url '${config.services.ozai-webui.ozaiUrl}' --secret_key '${config.services.ozai-webui.secretKey}' --static_folder '${self.packages.x86_64-linux.default}/share/ozai-webui/static' --template_folder '${self.packages.x86_64-linux.default}/share/ozai-webui/templates'"; + #ExecStart = "${self.packages.x86_64-linux.ozai-webui-run}/bin/run ${config.services.ozai-webui.host} ${toString(config.services.ozai-webui.port)} ${self.packages.x86_64-linux.default}/bin"; + ExecStart = "${self.packages.x86_64-linux.ozai-webui-run}/bin/run ${config.services.ozai-webui.host} ${toString(config.services.ozai-webui.port)} ${self.packages.x86_64-linux.default}/lib/python3.11/site-packages/"; Restart = "always"; }; }; diff --git a/result b/result new file mode 120000 index 0000000..b001729 --- /dev/null +++ b/result @@ -0,0 +1 @@ +/nix/store/y0qplxs953g27lij0rzlrb764wqxj495-ozai-webui-run-0.1.1 \ No newline at end of file diff --git a/result-1 b/result-1 new file mode 120000 index 0000000..1e16958 --- /dev/null +++ b/result-1 @@ -0,0 +1 @@ +/nix/store/v1f53kxj21mfchmnzxhf32val7hv8v9a-python3.11-ozai-webui-0.1.1 \ No newline at end of file diff --git a/src/main.py b/src/ozai_webui/__init__.py similarity index 80% rename from src/main.py rename to src/ozai_webui/__init__.py index 14b2318..4334b5d 100755 --- a/src/main.py +++ b/src/ozai_webui/__init__.py @@ -2,11 +2,9 @@ from flask import Flask, render_template, request from flask_socketio import SocketIO, join_room import requests -import argparse +#import argparse import os -app = Flask(__name__) -socketio = SocketIO(app) ozai_url = 'http://localhost:8000/api/' ozai_webui_host = '0.0.0.0' @@ -29,31 +27,42 @@ if os.getenv('OZAI_WEBUI_STATIC_FOLDER') is not None: if os.getenv('OZAI_WEBUI_TEMPLATE_FOLDER') is not None: template_folder = os.getenv('TEMPLATE_FOLDER') -parser = argparse.ArgumentParser(description="Run the Ozai WebUI server") -parser.add_argument('-H', '--host', type=str, default=ozai_webui_host, help='The host to run the server on') -parser.add_argument('-P', '--port', type=int, default=ozai_webui_port, help='The port to run the server on') -parser.add_argument('-O', '--ozai_url', type=str, default=ozai_url, help='The URL of the Ozai server') -parser.add_argument('-S', '--secret_key', type=str, default=app.config['SECRET_KEY'], help='The secret key for the Flask app') -parser.add_argument('--static_folder', type=str, default=static_folder, help='The location of the static folder') -parser.add_argument('--template_folder', type=str, default=template_folder, help='The location of the template folder') +print(f"using host { ozai_webui_host }") +print(f"using port { ozai_webui_port }") +print(f"using ozai url { ozai_url }") +print(f"using template folder { template_folder }") +print(f"using static folder { static_folder }") + +app = Flask(__name__,template_folder=template_folder,static_folder=static_folder ) +socketio = SocketIO(app) -args = parser.parse_args() - -if args.host: - ozai_webui_host = args.host -if args.port: - ozai_webui_port = args.port -if args.ozai_url: - ozai_url = args.ozai_url -if args.secret_key: - app.config['SECRET_KEY'] = args.secret_key -if args.static_folder: - app.static_folder = args.static_folder -if args.template_folder: - app.template_folder = args.template_folder - +#parser = argparse.ArgumentParser(description="Run the Ozai WebUI server") +# +#parser.add_argument('-H', '--host', type=str, default=ozai_webui_host, help='The host to run the server on') +#parser.add_argument('-P', '--port', type=int, default=ozai_webui_port, help='The port to run the server on') +#parser.add_argument('-O', '--ozai_url', type=str, default=ozai_url, help='The URL of the Ozai server') +#parser.add_argument('-S', '--secret_key', type=str, default=app.config['SECRET_KEY'], help='The secret key for the Flask app') +#parser.add_argument('--static_folder', type=str, default=static_folder, help='The location of the static folder') +#parser.add_argument('--template_folder', type=str, default=template_folder, help='The location of the template folder') +# +# +#args = parser.parse_args() +# +#if args.host: +# ozai_webui_host = args.host +#if args.port: +# ozai_webui_port = args.port +#if args.ozai_url: +# ozai_url = args.ozai_url +#if args.secret_key: +# app.config['SECRET_KEY'] = args.secret_key +#if args.static_folder: +# app.static_folder = args.static_folder +#if args.template_folder: +# app.template_folder = args.template_folder +# #home page @app.route('/') @@ -210,7 +219,9 @@ def ws_message(data): #send message to the player that the move was invalid socketio.emit('move_status', response.text, room=game_id) +def main (): + # app.run(debug=True, host='0.0.0.0', port=5000,ssl_context='adhoc') + return socketio.run(app, debug=False, host=ozai_webui_host, port=ozai_webui_port, allow_unsafe_werkzeug=True) if __name__ == '__main__': - # app.run(debug=True, host='0.0.0.0', port=5000,ssl_context='adhoc') - socketio.run(app, debug=False, host=ozai_webui_host, port=ozai_webui_port, allow_unsafe_werkzeug=True) + main() diff --git a/src/result b/src/result new file mode 120000 index 0000000..dd014d1 --- /dev/null +++ b/src/result @@ -0,0 +1 @@ +/nix/store/ldv1rcfs9phhh7hh2wzcvn2600dvgw4y-python3.11-ozai-webui-0.1.1 \ No newline at end of file diff --git a/src/run.sh b/src/run.sh new file mode 100644 index 0000000..5d32038 --- /dev/null +++ b/src/run.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash + +# Default values for host, port, and package path +DEFAULT_HOST="0.0.0.0" +DEFAULT_PORT="8000" +DEFAULT_PACKAGE_PATH="ozai_webui" + +# Get the host, port, and package path from command line arguments, or use defaults +HOST="${1:-$DEFAULT_HOST}" +PORT="${2:-$DEFAULT_PORT}" +PACKAGE_PATH="${3:-$DEFAULT_PACKAGE_PATH}" + +# Run Gunicorn with the specified host, port, and package path +#gunicorn -w 1 --chdir "$PACKAGE_PATH" --bind "$HOST:$PORT" __init__:main +gunicorn --worker-class eventlet -w 1 --chdir "$PACKAGE_PATH" --bind "$HOST:$PORT" ozai_webui:app + diff --git a/src/setup.py b/src/setup.py index 2f916d4..c0ff482 100644 --- a/src/setup.py +++ b/src/setup.py @@ -6,6 +6,8 @@ requires = ( "flask", "flask-socketio", "requests", + "gunicorn", + "eventlet", ) @@ -17,9 +19,16 @@ setup( name='ozai-webui', version='0.1.1', author = "Adrian Gunnar Lauterer", - packages=find_packages(), - scripts=["main.py"], + packages=find_packages("."), + #scripts=["ozai_webui.py"], + #scripts={"ozai_webui:main": "ozai_webui"}, + entry_points = { + "console_scripts": [ + "ozai_webui = ozai_webui:main" + ] + }, install_requires=requires, + #package_dir= {'':'src'}, package_data={ '': ['templates/*.html', 'static/*.*'], },