{"id":17586834,"url":"https://github.com/lucienshawls/py-config-web-ui","last_synced_at":"2026-02-04T00:31:53.016Z","repository":{"id":258209360,"uuid":"872322634","full_name":"lucienshawls/py-config-web-ui","owner":"lucienshawls","description":"This package provides tools for editing configuration files in a user-friendly web interface.","archived":false,"fork":false,"pushed_at":"2024-11-19T04:02:23.000Z","size":2957,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-07T02:05:30.287Z","etag":null,"topics":["configuration","editor","flask","json","tool","ui","web","yaml"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lucienshawls.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-10-14T08:36:47.000Z","updated_at":"2024-10-25T13:08:22.000Z","dependencies_parsed_at":"2024-11-16T11:17:45.697Z","dependency_job_id":"2e6867df-b19f-43fd-85a2-e95a711199c5","html_url":"https://github.com/lucienshawls/py-config-web-ui","commit_stats":{"total_commits":51,"total_committers":1,"mean_commits":51.0,"dds":0.0,"last_synced_commit":"f34f4bf7e7347a2b9137265087ec4edcfff9f9a6"},"previous_names":["lucienshawls/py-config-web-ui"],"tags_count":6,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lucienshawls%2Fpy-config-web-ui","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lucienshawls%2Fpy-config-web-ui/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lucienshawls%2Fpy-config-web-ui/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lucienshawls%2Fpy-config-web-ui/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lucienshawls","download_url":"https://codeload.github.com/lucienshawls/py-config-web-ui/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248654094,"owners_count":21140236,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["configuration","editor","flask","json","tool","ui","web","yaml"],"created_at":"2024-10-22T03:06:30.491Z","updated_at":"2026-02-04T00:31:47.993Z","avatar_url":"https://github.com/lucienshawls.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# pyConfigWebUI\n\n[![Build Status](https://github.com/lucienshawls/py-config-web-ui/actions/workflows/release.yml/badge.svg)](https://github.com/lucienshawls/py-config-web-ui/actions/workflows/release.yml)\n[![License](https://img.shields.io/github/license/lucienshawls/py-config-web-ui)](LICENSE)\n[![Latest Release Tag](https://img.shields.io/github/v/release/lucienshawls/py-config-web-ui)](https://github.com/lucienshawls/py-config-web-ui/releases/latest)\n[![Latest PyPI Version](https://img.shields.io/pypi/v/configwebui-lucien.svg)](https://pypi.org/project/configwebui-lucien/)\n\nA simple web-based configuration editor for Python applications.\n\nThis package provides tools for editing configuration files\nin a user-friendly web interface.\n\nPackage on PyPI: [configwebui-lucien · PyPI](https://pypi.org/project/configwebui-lucien/)\n\n## Try it out\nTo get an intuitive understanding of how to use this tool, you can do the following:\n\n1. Clone this repository\n```shell\ngit clone https://github.com/lucienshawls/py-config-web-ui\ncd ./py-config-web-ui\n```\n\n2. Install dependencies in a virtual environment or a conda environment (to avoid conflicts)\n```shell\npip install -r ./requirements.txt\n```\n\n3. Run demo!\n```shell\npython ./examples/demo.py\n```\n\n4. Switch to your web browser\n\nIf your browser does not pop up, visit the link that shows in your terminal.\n\n5. Edit and save any config\n6. See if your config has been saved to `./examples/config`\n7. Click `Launch main program` (a submenu from `Save`) and checkout the terminal\n\nIt should output some messages based on your config.\n\n## Use it in your own project\n1. Install\n\nIn the environment of your own project, run:\n```shell\npip install configwebui-lucien\n```\n\n2. Integrate\n\nIn your python file, import this package:\n```python\nfrom configwebui import ConfigEditor, UserConfig, ResultStatus\n```\nor:\n\n```python\nfrom configwebui import *\n```\n\nThey have exactly the same effect.\n\n3. Optional preparations\n\n- Set up a function that varifies the config\n\nWhen user clicks the `Save` button on the webpage, the config will first pass the extra validations before it can be saved to the memory. You can set up your own validation function.\n\nYour function should take one positional argument, which is for the config itself (`config`).\n\nYour function should return a `ResultStatus` object or a `boolean` value. If you choose the former, you can attach several error messages that the user can see on the webpage.\n\nThis function is related to a specific `UserConfig` that you set up later.\n\nExample:\n```python\ndef always_pass(config: dict | list) -\u003e ResultStatus:\n    # Instantiate a ResultStatus object with no messages, and set its status to True.\n    res = ResultStatus(True)\n    if False:\n        # Just to show what to do when validation fails\n        res.set_status(False)\n        res.add_message(\"message 1\")\n        res.add_message(\"message 2\")\n\n    return res\n```\n\n- Set up a function that saves config\n\nWhen user clicks the `Save` button on the webpage, and after the config passes extra validations, the config is saved to the memory immediately and your save function is then called in a separate thread.\n\nYou can choose not to set the save function; however, if you do so, all edited configurations will only remain in memory and cannot be read, and will disappear when the program is restarted.\n\nYour function should take one positional argument, which is for the config itself (`config`).\n\nYou can freely choose the type (`json`, `yaml`, `toml`, etc.) and save method of the configuration file.\n\nParameter validation is not needed. It is guaranteed that the parameters satisfy your requirements.\n\nReturn values are not needed either, because for now, the package does not read the result.\n\nThis function is related to a specific `UserConfig` that you set up later.\n\nExample:\n```python\nimport json\nimport os\ndef my_save(config: dict | list):\n    # You don't need to perform parameter validation\n    os.makedirs(\"./config\", exist_ok=True)\n    with open(\"config/myconfig.json\", \"w\", encoding=\"utf-8\") as f:\n        json.dump(config, f, indent=4)\n    print(config)\n```\n\n- Set up a main entry point\n\nWhen user clicks `Launch main program` button on the webpage, your save function is called in a separate thread.\n\nYour function should take no positional arguments.\n\nReturn values are not needed.\n\nThis function is related to a specific `ConfigEditor` that you set up later.\n\nATTENTION: Your main entry should be treated as an independent program that independently obtains configurations from the location where the configuration file is saved, and executes the code. Therefore, when the main entry is called, configuration-related parameters will not be passed in.\n\nExample:\n```python\nimport os\nimport json\ndef my_main_entry():\n    print(\"======== This is main entry =======\")\n    if os.path.exists(\"config/myconfig.json\"):\n        with open(\"config/myconfig.json\", \"r\", encoding=\"utf-8\") as f:\n            config = json.load(f)\n        print(config)\n```\n\n4. Fire it up\n\nInstantiate a `ConfigEditor` object, and add one or more config schema to it:\n```python\nimport os\nschema = {\n    \"title\": \"Example Schema\",\n    \"type\": \"object\",\n    \"properties\": {\n        \"name\": {\"type\": \"string\", \"title\": \"Name\"},\n        \"age\": {\"type\": \"integer\", \"title\": \"Age\"},\n        \"is_student\": {\"type\": \"boolean\"},\n    },\n}  # You need to create this\n# Create a ConfigEditor object\nconfig_editor = ConfigEditor(\n    app_name=\"Trial\",  # display name, is used in the webpage title\n    main_entry=my_main_entry,  # optional, main entry point, make sure it can run in a thread.\n)\n\n# Create a UserConfig object\nuser_config = UserConfig(\n    name=\"myconfig\",  # identifier\n    friendly_name=\"Main config\",  # display name\n    schema=schema,  # schema\n    extra_validation_func=always_pass,  # optional, extra validation function\n    save_func=my_save,  # optional, save function\n)\n\n# Load the config from file and set initial values (or not, as you wish)\ndef load_config(name: str) -\u003e dict | list:\n    file_path = f\"config/{name}.json\"\n    if os.path.exists(file_path):\n        with open(file_path, \"r\", encoding=\"utf-8\") as f:\n            config = json.load(f)\n    else:\n        config = None\n    return config\n\nconfig_from_file = load_config(\"myconfig\")\nif config_from_file is not None:\n    user_config.set_config(\n        config=config_from_file,\n        skip_schema_validations=True,  # optional, skip schema validations this time only\n        skip_extra_validations=True,  # optional, skip extra validations this time only\n    )\n\n# Add the UserConfig object to the ConfigEditor object\nconfig_editor.add_user_config(user_config=user_config)\n```\n\n5. Run it\n\nRun the ConfigEditor!\n\nExample:\n```python\n# Change the port to 5000 if you do not have enough permissions.\nconfig_editor.run(host=\"localhost\", port=80)\n```\n\n## Acknowledgements\nI would like to express my gratitude to the following projects and individuals for different scenarios and reasons:\n\n- Front-end design:\n  - JSON Editor: [JSON Schema Based Editor](https://github.com/json-editor/json-editor)\n    - with version: `v2.15.2`\n  - CSS: [Bootstrap · The most popular HTML, CSS, and JS library in the world.](https://getbootstrap.com/)\n    - with version: `v5.3.3`\n  - JavaScript Library: [jQuery](https://jquery.com/)\n    - with version: `v3.7.1`\n  - Icons: [Font Awesome](https://fontawesome.com/)\n    - with version: `v5.15.4`\n- Coding\n  - Testing: My friend [Eric](https://github.com/EricWay1024)\n    - for: providing valuable test feedback\n  - Assistant: [ChatGPT](https://chatgpt.com/)\n    - for: making things easier\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flucienshawls%2Fpy-config-web-ui","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flucienshawls%2Fpy-config-web-ui","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flucienshawls%2Fpy-config-web-ui/lists"}