Compare commits

..

No commits in common. "262353a4e7405d444208a340913cc338df457cdb" and "9914410cb7633004e71c8c6aac96a5e2d0da71fd" have entirely different histories.

12 changed files with 532 additions and 224 deletions

6
.gitignore vendored
View File

@ -6,8 +6,4 @@ __pycache__/
*$py.class *$py.class
# Visual Studio Code # Visual Studio Code
.vscode/ .vscode/
#nix
dist/
result/

View File

@ -1,30 +1,3 @@
# Ozai WebUI # ozai-webui
Ozai WebUI is a web interface for the Ozai server. This document provides instructions on how to configure and run the application. webui for ozai azul server.
Configuration
The application can be configured using environment variables. Here are the environment variables you can set:
- OZAI_URL: The URL of the Ozai server that the web UI should connect to. If not set, the application will use a default value.
- OZAI_WEBUI_HOST: The host that the Ozai web UI server should run on. If not set, the application will use a default value.
- OZAI_WEBUI_PORT: The port that the Ozai web UI server should run on. If not set, the application will use a default value.
- OZAI_WEBUI_SECRET_KEY: The secret key used for session handling in the Flask application. If not set, the application will use a default value.
You can set these environment variables in your shell before running the application, like this:
```bash
export OZAI_URL=http://localhost:8000/api/
export OZAI_WEBUI_HOST=0.0.0.0
export OZAI_WEBUI_PORT=5000
export OZAI_WEBUI_SECRET_KEY=your-secret-key
```
Running the Application
To run the application, you can use the following commands:
```bash
python main.py
```

View File

@ -1,2 +0,0 @@
{ pkgs ? import <nixpkgs> {} }:
pkgs.callPackage ./src/derivation.nix {}

View File

@ -1,12 +1,51 @@
{ {
"nodes": { "nodes": {
"flake-utils": {
"inputs": {
"systems": "systems"
},
"locked": {
"lastModified": 1705309234,
"narHash": "sha256-uNRRNRKmJyCRC/8y1RqBkqWBLM034y4qN7EprSdmgyA=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "1ef2e671c3b0c19053962c07dbda38332dcebf26",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"nix-github-actions": {
"inputs": {
"nixpkgs": [
"poetry2nix",
"nixpkgs"
]
},
"locked": {
"lastModified": 1703863825,
"narHash": "sha256-rXwqjtwiGKJheXB43ybM8NwWB8rO2dSRrEqes0S7F5Y=",
"owner": "nix-community",
"repo": "nix-github-actions",
"rev": "5163432afc817cf8bd1f031418d1869e4c9d5547",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "nix-github-actions",
"type": "github"
}
},
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1711200738, "lastModified": 1711106783,
"narHash": "sha256-dkJmk/ET/tRV4007O6kU101UEg1svUwiyk/zEEX9Tdg=", "narHash": "sha256-PDwAcHahc6hEimyrgGmFdft75gmLrJOZ0txX7lFqq+I=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "20bc93ca7b2158ebc99b8cef987a2173a81cde35", "rev": "a3ed7406349a9335cb4c2a71369b697cecd9d351",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -16,9 +55,98 @@
"type": "github" "type": "github"
} }
}, },
"nixpkgs_2": {
"locked": {
"lastModified": 1708422533,
"narHash": "sha256-OJxUslyGM/Eni66IOq8WGCjpM3H0vEfdv+fwzUmsOSY=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "e1135102e9ae9f7fe84147f9700a17cf4839f97f",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "master",
"repo": "nixpkgs",
"type": "github"
}
},
"poetry2nix": {
"inputs": {
"flake-utils": "flake-utils",
"nix-github-actions": "nix-github-actions",
"nixpkgs": "nixpkgs_2",
"systems": "systems_2",
"treefmt-nix": "treefmt-nix"
},
"locked": {
"lastModified": 1708589824,
"narHash": "sha256-2GOiFTkvs5MtVF65sC78KNVxQSmsxtk0WmV1wJ9V2ck=",
"owner": "nix-community",
"repo": "poetry2nix",
"rev": "3c92540611f42d3fb2d0d084a6c694cd6544b609",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "poetry2nix",
"type": "github"
}
},
"root": { "root": {
"inputs": { "inputs": {
"nixpkgs": "nixpkgs" "nixpkgs": "nixpkgs",
"poetry2nix": "poetry2nix"
}
},
"systems": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
},
"systems_2": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"id": "systems",
"type": "indirect"
}
},
"treefmt-nix": {
"inputs": {
"nixpkgs": [
"poetry2nix",
"nixpkgs"
]
},
"locked": {
"lastModified": 1708335038,
"narHash": "sha256-ETLZNFBVCabo7lJrpjD6cAbnE11eDOjaQnznmg/6hAE=",
"owner": "numtide",
"repo": "treefmt-nix",
"rev": "e504621290a1fd896631ddbc5e9c16f4366c9f65",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "treefmt-nix",
"type": "github"
} }
} }
}, },

View File

@ -1,72 +1,30 @@
{ {
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
inputs.poetry2nix.url = "github:nix-community/poetry2nix";
outputs = { self, nixpkgs}: outputs = { self, nixpkgs, poetry2nix }:
let let
supportedSystems = [ "x86_64-linux"]; supportedSystems = [ "x86_64-linux" "aarch64-linux"];
forAllSystems = nixpkgs.lib.genAttrs supportedSystems; forAllSystems = nixpkgs.lib.genAttrs supportedSystems;
pkgs = forAllSystems (system: nixpkgs.legacyPackages.${system}); pkgs = forAllSystems (system: nixpkgs.legacyPackages.${system});
in in
{ {
packages = forAllSystems (system: let packages = forAllSystems (system: let
python = pkgs.${system}.python3.withPackages (ps: [ps.flask ps.flask-socketio]); inherit (poetry2nix.lib.mkPoetry2Nix { pkgs = pkgs.${system}; }) mkPoetryApplication;
ozaiWebui = import ./default.nix { inherit (pkgs.${system}) pkgs; };
in { in {
default = ozaiWebui; default = mkPoetryApplication { projectDir = self; };
}); });
devShells = forAllSystems (system: let devShells = forAllSystems (system: let
python = pkgs.${system}.python3.withPackages (ps: [ps.flask ps.flask-socketio]); inherit (poetry2nix.lib.mkPoetry2Nix { pkgs = pkgs.${system}; }) mkPoetryEnv;
in { in {
default = pkgs.${system}.mkShellNoCC { default = pkgs.${system}.mkShellNoCC {
packages = with pkgs.${system}; [ packages = with pkgs.${system}; [
python (mkPoetryEnv { projectDir = self; })
poetry
]; ];
}; };
}); });
nixosModules = forAllSystems (system: let
ozaiWebui = import ./default.nix { inherit (pkgs.${system}) pkgs; };
in {
ozai-webui = { config, pkgs, ... }: {
options.services.ozai-webui = {
enable = mkEnableOption "Ozai WebUI";
host = mkOption {
type = types.str;
default = "127.0.0.1";
description = "The host to run the server on";
};
port = mkOption {
type = types.int;
default = 8080;
description = "The port to run the server on";
};
ozaiUrl = mkOption {
type = types.str;
default = "http://localhost:8000/api/";
description = "The URL of the Ozai server";
};
secretKey = mkOption {
type = types.str;
default = "secret_key";
description = "The secret key for the Flask app";
};
};
config = mkIf config.services.ozai-webui.enable {
systemd.services.ozai-webui = {
description = "Ozai WebUI";
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
serviceConfig = {
ExecStart = "${ozaiWebui}/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}'";
Restart = "always";
};
};
};
};
});
}; };
} }

288
poetry.lock generated Normal file
View File

@ -0,0 +1,288 @@
# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand.
[[package]]
name = "bidict"
version = "0.23.1"
description = "The bidirectional mapping library for Python."
optional = false
python-versions = ">=3.8"
files = [
{file = "bidict-0.23.1-py3-none-any.whl", hash = "sha256:5dae8d4d79b552a71cbabc7deb25dfe8ce710b17ff41711e13010ead2abfc3e5"},
{file = "bidict-0.23.1.tar.gz", hash = "sha256:03069d763bc387bbd20e7d49914e75fc4132a41937fa3405417e1a5a2d006d71"},
]
[[package]]
name = "blinker"
version = "1.7.0"
description = "Fast, simple object-to-object and broadcast signaling"
optional = false
python-versions = ">=3.8"
files = [
{file = "blinker-1.7.0-py3-none-any.whl", hash = "sha256:c3f865d4d54db7abc53758a01601cf343fe55b84c1de4e3fa910e420b438d5b9"},
{file = "blinker-1.7.0.tar.gz", hash = "sha256:e6820ff6fa4e4d1d8e2747c2283749c3f547e4fee112b98555cdcdae32996182"},
]
[[package]]
name = "click"
version = "8.1.7"
description = "Composable command line interface toolkit"
optional = false
python-versions = ">=3.7"
files = [
{file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"},
{file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"},
]
[package.dependencies]
colorama = {version = "*", markers = "platform_system == \"Windows\""}
[[package]]
name = "colorama"
version = "0.4.6"
description = "Cross-platform colored terminal text."
optional = false
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7"
files = [
{file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"},
{file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"},
]
[[package]]
name = "flask"
version = "2.3.3"
description = "A simple framework for building complex web applications."
optional = false
python-versions = ">=3.8"
files = [
{file = "flask-2.3.3-py3-none-any.whl", hash = "sha256:f69fcd559dc907ed196ab9df0e48471709175e696d6e698dd4dbe940f96ce66b"},
{file = "flask-2.3.3.tar.gz", hash = "sha256:09c347a92aa7ff4a8e7f3206795f30d826654baf38b873d0744cd571ca609efc"},
]
[package.dependencies]
blinker = ">=1.6.2"
click = ">=8.1.3"
itsdangerous = ">=2.1.2"
Jinja2 = ">=3.1.2"
Werkzeug = ">=2.3.7"
[package.extras]
async = ["asgiref (>=3.2)"]
dotenv = ["python-dotenv"]
[[package]]
name = "flask-socketio"
version = "5.3.6"
description = "Socket.IO integration for Flask applications"
optional = false
python-versions = ">=3.6"
files = [
{file = "Flask-SocketIO-5.3.6.tar.gz", hash = "sha256:bb8f9f9123ef47632f5ce57a33514b0c0023ec3696b2384457f0fcaa5b70501c"},
{file = "Flask_SocketIO-5.3.6-py3-none-any.whl", hash = "sha256:9e62d2131842878ae6bfdd7067dfc3be397c1f2b117ab1dc74e6fe74aad7a579"},
]
[package.dependencies]
Flask = ">=0.9"
python-socketio = ">=5.0.2"
[package.extras]
docs = ["sphinx"]
[[package]]
name = "h11"
version = "0.14.0"
description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1"
optional = false
python-versions = ">=3.7"
files = [
{file = "h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761"},
{file = "h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d"},
]
[[package]]
name = "itsdangerous"
version = "2.1.2"
description = "Safely pass data to untrusted environments and back."
optional = false
python-versions = ">=3.7"
files = [
{file = "itsdangerous-2.1.2-py3-none-any.whl", hash = "sha256:2c2349112351b88699d8d4b6b075022c0808887cb7ad10069318a8b0bc88db44"},
{file = "itsdangerous-2.1.2.tar.gz", hash = "sha256:5dbbc68b317e5e42f327f9021763545dc3fc3bfe22e6deb96aaf1fc38874156a"},
]
[[package]]
name = "jinja2"
version = "3.1.3"
description = "A very fast and expressive template engine."
optional = false
python-versions = ">=3.7"
files = [
{file = "Jinja2-3.1.3-py3-none-any.whl", hash = "sha256:7d6d50dd97d52cbc355597bd845fabfbac3f551e1f99619e39a35ce8c370b5fa"},
{file = "Jinja2-3.1.3.tar.gz", hash = "sha256:ac8bd6544d4bb2c9792bf3a159e80bba8fda7f07e81bc3aed565432d5925ba90"},
]
[package.dependencies]
MarkupSafe = ">=2.0"
[package.extras]
i18n = ["Babel (>=2.7)"]
[[package]]
name = "markupsafe"
version = "2.1.5"
description = "Safely add untrusted strings to HTML/XML markup."
optional = false
python-versions = ">=3.7"
files = [
{file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc"},
{file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5"},
{file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46"},
{file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f"},
{file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae2ad8ae6ebee9d2d94b17fb62763125f3f374c25618198f40cbb8b525411900"},
{file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff"},
{file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad"},
{file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd"},
{file = "MarkupSafe-2.1.5-cp310-cp310-win32.whl", hash = "sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4"},
{file = "MarkupSafe-2.1.5-cp310-cp310-win_amd64.whl", hash = "sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5"},
{file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f"},
{file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2"},
{file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced"},
{file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5"},
{file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7502934a33b54030eaf1194c21c692a534196063db72176b0c4028e140f8f32c"},
{file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f"},
{file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a"},
{file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f"},
{file = "MarkupSafe-2.1.5-cp311-cp311-win32.whl", hash = "sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906"},
{file = "MarkupSafe-2.1.5-cp311-cp311-win_amd64.whl", hash = "sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617"},
{file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1"},
{file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4"},
{file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee"},
{file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5"},
{file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b"},
{file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a"},
{file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f"},
{file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169"},
{file = "MarkupSafe-2.1.5-cp312-cp312-win32.whl", hash = "sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad"},
{file = "MarkupSafe-2.1.5-cp312-cp312-win_amd64.whl", hash = "sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb"},
{file = "MarkupSafe-2.1.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c8b29db45f8fe46ad280a7294f5c3ec36dbac9491f2d1c17345be8e69cc5928f"},
{file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec6a563cff360b50eed26f13adc43e61bc0c04d94b8be985e6fb24b81f6dcfdf"},
{file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a549b9c31bec33820e885335b451286e2969a2d9e24879f83fe904a5ce59d70a"},
{file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4f11aa001c540f62c6166c7726f71f7573b52c68c31f014c25cc7901deea0b52"},
{file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:7b2e5a267c855eea6b4283940daa6e88a285f5f2a67f2220203786dfa59b37e9"},
{file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:2d2d793e36e230fd32babe143b04cec8a8b3eb8a3122d2aceb4a371e6b09b8df"},
{file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ce409136744f6521e39fd8e2a24c53fa18ad67aa5bc7c2cf83645cce5b5c4e50"},
{file = "MarkupSafe-2.1.5-cp37-cp37m-win32.whl", hash = "sha256:4096e9de5c6fdf43fb4f04c26fb114f61ef0bf2e5604b6ee3019d51b69e8c371"},
{file = "MarkupSafe-2.1.5-cp37-cp37m-win_amd64.whl", hash = "sha256:4275d846e41ecefa46e2015117a9f491e57a71ddd59bbead77e904dc02b1bed2"},
{file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:656f7526c69fac7f600bd1f400991cc282b417d17539a1b228617081106feb4a"},
{file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:97cafb1f3cbcd3fd2b6fbfb99ae11cdb14deea0736fc2b0952ee177f2b813a46"},
{file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f3fbcb7ef1f16e48246f704ab79d79da8a46891e2da03f8783a5b6fa41a9532"},
{file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa9db3f79de01457b03d4f01b34cf91bc0048eb2c3846ff26f66687c2f6d16ab"},
{file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffee1f21e5ef0d712f9033568f8344d5da8cc2869dbd08d87c84656e6a2d2f68"},
{file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:5dedb4db619ba5a2787a94d877bc8ffc0566f92a01c0ef214865e54ecc9ee5e0"},
{file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:30b600cf0a7ac9234b2638fbc0fb6158ba5bdcdf46aeb631ead21248b9affbc4"},
{file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8dd717634f5a044f860435c1d8c16a270ddf0ef8588d4887037c5028b859b0c3"},
{file = "MarkupSafe-2.1.5-cp38-cp38-win32.whl", hash = "sha256:daa4ee5a243f0f20d528d939d06670a298dd39b1ad5f8a72a4275124a7819eff"},
{file = "MarkupSafe-2.1.5-cp38-cp38-win_amd64.whl", hash = "sha256:619bc166c4f2de5caa5a633b8b7326fbe98e0ccbfacabd87268a2b15ff73a029"},
{file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7a68b554d356a91cce1236aa7682dc01df0edba8d043fd1ce607c49dd3c1edcf"},
{file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:db0b55e0f3cc0be60c1f19efdde9a637c32740486004f20d1cff53c3c0ece4d2"},
{file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e53af139f8579a6d5f7b76549125f0d94d7e630761a2111bc431fd820e163b8"},
{file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:17b950fccb810b3293638215058e432159d2b71005c74371d784862b7e4683f3"},
{file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4c31f53cdae6ecfa91a77820e8b151dba54ab528ba65dfd235c80b086d68a465"},
{file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bff1b4290a66b490a2f4719358c0cdcd9bafb6b8f061e45c7a2460866bf50c2e"},
{file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:bc1667f8b83f48511b94671e0e441401371dfd0f0a795c7daa4a3cd1dde55bea"},
{file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5049256f536511ee3f7e1b3f87d1d1209d327e818e6ae1365e8653d7e3abb6a6"},
{file = "MarkupSafe-2.1.5-cp39-cp39-win32.whl", hash = "sha256:00e046b6dd71aa03a41079792f8473dc494d564611a8f89bbbd7cb93295ebdcf"},
{file = "MarkupSafe-2.1.5-cp39-cp39-win_amd64.whl", hash = "sha256:fa173ec60341d6bb97a89f5ea19c85c5643c1e7dedebc22f5181eb73573142c5"},
{file = "MarkupSafe-2.1.5.tar.gz", hash = "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b"},
]
[[package]]
name = "python-engineio"
version = "4.9.0"
description = "Engine.IO server and client for Python"
optional = false
python-versions = ">=3.6"
files = [
{file = "python-engineio-4.9.0.tar.gz", hash = "sha256:e87459c15638e567711fd156e6f9c4a402668871bed79523f0ecfec744729ec7"},
{file = "python_engineio-4.9.0-py3-none-any.whl", hash = "sha256:979859bff770725b75e60353d7ae53b397e8b517d05ba76733b404a3dcca3e4c"},
]
[package.dependencies]
simple-websocket = ">=0.10.0"
[package.extras]
asyncio-client = ["aiohttp (>=3.4)"]
client = ["requests (>=2.21.0)", "websocket-client (>=0.54.0)"]
docs = ["sphinx"]
[[package]]
name = "python-socketio"
version = "5.11.1"
description = "Socket.IO server and client for Python"
optional = false
python-versions = ">=3.8"
files = [
{file = "python-socketio-5.11.1.tar.gz", hash = "sha256:bbcbd758ed8c183775cb2853ba001361e2fa018babf5cbe11a5b77e91c2ec2a2"},
{file = "python_socketio-5.11.1-py3-none-any.whl", hash = "sha256:f1a0228b8b1fbdbd93fbbedd821ebce0ef54b2b5bf6e98fcf710deaa7c574259"},
]
[package.dependencies]
bidict = ">=0.21.0"
python-engineio = ">=4.8.0"
[package.extras]
asyncio-client = ["aiohttp (>=3.4)"]
client = ["requests (>=2.21.0)", "websocket-client (>=0.54.0)"]
docs = ["sphinx"]
[[package]]
name = "simple-websocket"
version = "1.0.0"
description = "Simple WebSocket server and client for Python"
optional = false
python-versions = ">=3.6"
files = [
{file = "simple-websocket-1.0.0.tar.gz", hash = "sha256:17d2c72f4a2bd85174a97e3e4c88b01c40c3f81b7b648b0cc3ce1305968928c8"},
{file = "simple_websocket-1.0.0-py3-none-any.whl", hash = "sha256:1d5bf585e415eaa2083e2bcf02a3ecf91f9712e7b3e6b9fa0b461ad04e0837bc"},
]
[package.dependencies]
wsproto = "*"
[package.extras]
docs = ["sphinx"]
[[package]]
name = "werkzeug"
version = "3.0.1"
description = "The comprehensive WSGI web application library."
optional = false
python-versions = ">=3.8"
files = [
{file = "werkzeug-3.0.1-py3-none-any.whl", hash = "sha256:90a285dc0e42ad56b34e696398b8122ee4c681833fb35b8334a095d82c56da10"},
{file = "werkzeug-3.0.1.tar.gz", hash = "sha256:507e811ecea72b18a404947aded4b3390e1db8f826b494d76550ef45bb3b1dcc"},
]
[package.dependencies]
MarkupSafe = ">=2.1.1"
[package.extras]
watchdog = ["watchdog (>=2.3)"]
[[package]]
name = "wsproto"
version = "1.2.0"
description = "WebSockets state-machine based protocol implementation"
optional = false
python-versions = ">=3.7.0"
files = [
{file = "wsproto-1.2.0-py3-none-any.whl", hash = "sha256:b9acddd652b585d75b20477888c56642fdade28bdfd3579aa24a4d2c037dd736"},
{file = "wsproto-1.2.0.tar.gz", hash = "sha256:ad565f26ecb92588a3e43bc3d96164de84cd9902482b130d0ddbaa9664a85065"},
]
[package.dependencies]
h11 = ">=0.9.0,<1"
[metadata]
lock-version = "2.0"
python-versions = "^3.10"
content-hash = "3ec8970e92663047ebf7f98b2bca6e0524e026a90e56bb2f2b5e65959d29f050"

19
pyproject.toml Normal file
View File

@ -0,0 +1,19 @@
[tool.poetry]
name = "ozai webui"
version = "0.1.1"
description = "ozai webui"
authors = ["Adrian Gunnar Lauterer <adrian@lauterer.it>"]
readme = "README.md"
license = "MIT"
packages = [
{ include = "src" }
]
[tool.poetry.dependencies]
python = "^3.10"
flask = "^2.0.2"
flask-socketio = "^5.1.1"
[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"

1
result
View File

@ -1 +0,0 @@
/nix/store/6wx55axmy6d2hbcypyd3r3dxygvhpgrj-ozai-webui-0.1.1

66
src/main.py → src/__main__.py Executable file → Normal file
View File

@ -1,47 +1,15 @@
#!/usr/bin/env python # Python
from flask import Flask, render_template, request from flask import Flask, render_template, request
from flask_socketio import SocketIO, join_room from flask_socketio import SocketIO, join_room
import requests import requests
import argparse
import os
ozai_url = 'http://localhost:8000/api/'
app = Flask(__name__) app = Flask(__name__)
socketio = SocketIO(app) socketio = SocketIO(app)
ozai_url = 'http://localhost:8000/api/' #get tis from env variable
ozai_webui_host = '0.0.0.0' import os
ozai_webui_port = 5000 app.config['SECRET_KEY'] = os.environ.get('OZAI_WEBUI_SECRET_KEY')
app.config['SECRET_KEY'] = "secret"
#check if the environment variables are set
if os.getenv('OZAI_URL') is not None:
ozai_url = os.getenv('OZAI_URL')
if os.getenv('OZAI_WEBUI_HOST') is not None:
ozai_webui_host = os.getenv('OZAI_WEBUI_HOST')
if os.getenv('OZAI_WEBUI_PORT') is not None:
ozai_webui_port = int(os.getenv('OZAI_WEBUI_PORT'))
if os.getenv('OZAI_WEBUI_SECRET_KEY') is not None:
app.config['SECRET_KEY'] = os.getenv('OZAI_WEBUI_SECRET_KEY')
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')
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
#home page #home page
@ -90,16 +58,17 @@ def create():
player_names.append(player_name) player_names.append(player_name)
player_names = {"player_names": player_names} player_names = {"player_names": player_names}
# print(player_names) print(player_names)
response = requests.post(ozai_url + 'game', json=player_names) response = requests.post(ozai_url + 'game', json=player_names)
if response.status_code == 200: if response.status_code == 200:
game_id = response.json() game_id = response.json()
# print("Game ID:", game_id) print("Game ID:", game_id)
return render_template('create.html', game_id=game_id) return render_template('create.html', game_id=game_id)
else: else:
pass print("Error:", response.status_code, response.text)#log the game id
# print("Error:", response.status_code, response.text)#log the game id
#return the game id to the user #return the game id to the user
pass
return render_template('create.html') return render_template('create.html')
@ -126,7 +95,7 @@ def join_game(game_id):
if request.method == 'POST': if request.method == 'POST':
#get the chosen player name from the form and redirect to the game page #get the chosen player name from the form and redirect to the game page
player_name = request.form['player'] player_name = request.form['player']
# print('Player Name:', player_name) print('Player Name:', player_name)
local_game = request.form.get('local_game') local_game = request.form.get('local_game')
return render_template('join_game.html', game_id=game_id, players=players, player_name=player_name, local_game=local_game) return render_template('join_game.html', game_id=game_id, players=players, player_name=player_name, local_game=local_game)
@ -152,19 +121,19 @@ def game(game_id, player_name, local_game=None):
@socketio.on('connect') @socketio.on('connect')
def ws_connect(message): def ws_connect(message):
# print('Client connected' + str(message)) print('Client connected' + str(message))
pass pass
@socketio.on('join') @socketio.on('join')
def ws_message(message): def ws_message(message):
# print('Client message' + str(message)) print('Client message' + str(message))
game_id = message['game_id'] game_id = message['game_id']
# print('Game ID: ', game_id) print('Game ID: ', game_id)
join_room(game_id) join_room(game_id)
@socketio.on('move') @socketio.on('move')
def ws_message(data): def ws_message(data):
# print('Client move' + str(data)) print('Client move' + str(data))
game_id = data['game_id'] game_id = data['game_id']
player_name = data['player_name'] player_name = data['player_name']
@ -184,7 +153,7 @@ def ws_message(data):
'source': source, 'source': source,
'destination': destination 'destination': destination
} }
# print(move) print(move)
response = requests.put(ozai_url + 'game/' + game_id, json=move) response = requests.put(ozai_url + 'game/' + game_id, json=move)
if response.status_code == 200: if response.status_code == 200:
socketio.emit('move', data, room=game_id) socketio.emit('move', data, room=game_id)
@ -197,4 +166,5 @@ def ws_message(data):
if __name__ == '__main__': if __name__ == '__main__':
# app.run(debug=True, host='0.0.0.0', port=5000,ssl_context='adhoc') # 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)
socketio.run(app, debug=True, host='0.0.0.0', port=5000)

View File

@ -1,16 +0,0 @@
{ lib, python3Packages }:
with python3Packages;
buildPythonApplication rec {
pname = "ozai-webui";
version = "0.1.1";
propagatedBuildInputs = [ flask flask-socketio ];
src = ./.;
doCheck = false;
#copy the static files to the output
postInstall = ''
cp -r static $out/bin/static
cp -r templates $out/bin/templates
mv $out/bin/main.py $out/bin/ozai-webui
'';
}

View File

@ -1,26 +0,0 @@
#!/usr/bin/env python
from setuptools import setup, find_packages
import os
requires = (
"flask",
"flask-socketio",
)
def read(fname):
return open(os.path.join(os.path.dirname(__file__), fname)).read()
setup(
name='ozai-webui',
version='0.1.1',
author = "Adrian Gunnar Lauterer",
packages=find_packages(),
scripts=["main.py"],
install_requires=requires,
package_data={
'': ['templates/*.html', 'static/*.*'],
},
include_package_data=True,
)

View File

@ -6,19 +6,13 @@
<link rel="icon" type="image/png" href="/azul-flake.png"> <link rel="icon" type="image/png" href="/azul-flake.png">
<style> <style>
* { * {
--border-color: #616C71; --border-color: rgb(172, 172, 172);
--bg-transparency: 0.5; --bg-transparency: 0.5;
--tile-size: 2em; --tile-size: 2em;
--blue: 49, 157, 245;
--yellow: 210, 160, 0;
--red: 200, 50, 50;
--black: 30, 30, 30;
--white: 160, 160, 160;
--start: 165, 1, 155;
} }
body { body {
background-color: #2C3235; background-color: #383737;
color: white; color: white;
color-scheme: dark; color-scheme: dark;
display: flex; display: flex;
@ -31,15 +25,15 @@
padding: 1em; padding: 1em;
display: inline-block; display: inline-block;
text-decoration: none; text-decoration: none;
color: white; color: #aba4f6;
background-color: #3232d1; background-color: #1919a7;
border-radius: 1em; border-radius: 1em;
font-weight: bold; font-weight: bold;
font-size: 1.5em; /* increase font size */ font-size: 1.5em; /* increase font size */
} }
a:hover { a:hover {
background-color: #3f3ff2; background-color: #204ac8;
} }
input[type="submit"] { input[type="submit"] {
border: none; border: none;
@ -157,8 +151,6 @@
text-align: center; text-align: center;
margin-top: 0.1em; margin-top: 0.1em;
} }
.pattern_lines { .pattern_lines {
display: flex; display: flex;
justify-content: space-around; justify-content: space-around;
@ -198,23 +190,51 @@
width: var(--tile-size); width: var(--tile-size);
} }
.blue, .yellow, .red, .black, .white, .start {
border-radius: calc(var(--tile-size) * 0.2);
text-align: center; .blue_bg {
vertical-align: middle; background-color: rgb(49, 157, 245, var(--bg-transparency));
background: linear-gradient(45deg, rgba(255, 255, 255, 0.05) 30%, transparent 30%);
} }
.blue {background-color: rgb(var(--blue));} .yellow_bg {
.yellow {background-color: rgb(var(--yellow));} background-color: rgb(247, 148, 62, var(--bg-transparency));
.red {background-color: rgb(var(--red));} }
.black {background-color: rgb(var(--black));} .red_bg {
.white {background-color:rgb(var(--white));} background-color: rgb(200, 50, 50, var(--bg-transparency));
.start {background-color: rgb(var(--start));} }
.blue_bg {background-color: rgb(var(--blue), var(--bg-transparency));} .black_bg {
.yellow_bg {background-color: rgb(var(--yellow), var(--bg-transparency));} background-color: rgb(30, 30, 30, var(--bg-transparency));
.red_bg {background-color: rgb(var(--red), var(--bg-transparency));} }
.black_bg {background-color: rgb(var(--black), var(--bg-transparency));} .white_bg {
.white_bg {background-color:rgb(var(--white), var(--bg-transparency));} background-color:rgb(130, 130, 130, var(--bg-transparency));
}
.blue {
border-radius: calc(var(--tile-size) * 0.2);
background-color: rgb(49, 157, 245);
}
.yellow {
border-radius: calc(var(--tile-size) * 0.2);
background-color: rgb(247, 148, 62);
}
.red {
border-radius: calc(var(--tile-size) * 0.2);
background-color: rgb(200, 50, 50);
}
.black {
border-radius: calc(var(--tile-size) * 0.2);
background-color: rgb(30, 30, 30);
}
.white {
border-radius: calc(var(--tile-size) * 0.2);
background-color:rgb(130, 130, 130);
}
.start {
border-radius: calc(var(--tile-size) * 0.2);
background-color: rgb(165, 1, 155);
}
</style> </style>
</head> </head>
@ -302,10 +322,7 @@
{% for row in player_data.wall %} {% for row in player_data.wall %}
{% set colors = colors_base[-loop.index0:] + colors_base[:-loop.index0] %} {% set colors = colors_base[-loop.index0:] + colors_base[:-loop.index0] %}
{% for cell in row %} {% for cell in row %}
{% set color = colors[loop.index0]+ '_bg'%} {% set color = colors[loop.index0] + "_bg" %}
{% if cell %}
{% set color = colors[loop.index0]%}
{% endif %}
<div class="{{ color }}">{% if cell %}{{ color[:1] }}{% else %}{{ '_' }}{% endif %}</div> <div class="{{ color }}">{% if cell %}{{ color[:1] }}{% else %}{{ '_' }}{% endif %}</div>
{% endfor %} {% endfor %}
{% endfor %} {% endfor %}
@ -398,11 +415,11 @@
{% if local_game %} {% if local_game %}
{% set current_index = gamestate.player_names.index(player_name) %} {% set current_index = gamestate.player_names.index(player_name) %}
{% set next_index = current_index + 1 if current_index + 1 < gamestate.player_names|length else 0 %} {% set next_index = current_index + 1 if current_index + 1 < gamestate.player_names|length else 0 %}
<a href="/game/{{ game_id }}/player/{{ gamestate.player_names[next_index] }}/local/True">Next Player</a> <a href="/game/{{ game_id }}/player/{{ gamestate.player_names[next_index] }}">Next Player</a>
{% endif %} {% endif %}
{% endif %}
{% endif %}
<script src="/socket.io.js"></script> <script src="/socket.io.js"></script>
@ -410,9 +427,6 @@
console.log('Game ID: {{ game_id }}'); console.log('Game ID: {{ game_id }}');
console.log('Player Name: {{ player_name }}'); console.log('Player Name: {{ player_name }}');
console.log('Gamestate: {{ gamestate }}'); console.log('Gamestate: {{ gamestate }}');
// refresh the page by listening to websocket events
game_id = '{{ game_id }}';
player_name = '{{ player_name }}';
function selectTile(tile) { function selectTile(tile) {
var source = tile.parentElement.id; var source = tile.parentElement.id;
@ -449,9 +463,16 @@
destinationOption.selected = true; destinationOption.selected = true;
} }
// refresh the page by listening to websocket events
game_id = '{{ game_id }}';
player_name = '{{ player_name }}';
var socket = io(); var socket = io();
// send a message to the server in the message name space // send a message to the server in the message name space
socket.emit('join', {game_id: game_id}); socket.emit('join', {game_id: game_id});
socket.addEventListener('move', function (event) { socket.addEventListener('move', function (event) {
console.log('Game update received: ' + event); console.log('Game update received: ' + event);
window.location.reload(); window.location.reload();
@ -469,11 +490,11 @@
formData.forEach((value, key) => data[key] = value); formData.forEach((value, key) => data[key] = value);
console.log(data); console.log(data);
socket.emit('move', {game_id: game_id, player_name, move: data}); socket.emit('move', {game_id: game_id, player_name, move: data});
// if local_game is tru change player // if local_game is tru change player
//{% if local_game %} //{% if local_game %}
let nextPlayer = '{{ gamestate.player_names[gamestate.player_names.index(player_name) + 1 if gamestate.player_names.index(player_name) + 1 < gamestate.player_names|length else 0] }}'; let nextPlayer = '{{ gamestate.player_names[gamestate.player_names.index(player_name) + 1 if gamestate.player_names.index(player_name) + 1 < gamestate.player_names|length else 0] }}';
window.location.href = '/game/{{ game_id }}/player/' + nextPlayer + '/local/True'; window.location.href = '/game/{{ game_id }}/player/' + nextPlayer;
//{% endif %} //{% endif %}
}); });