From 2ee724f93e36ecdf8ddfbbbb69f26ce7f7ba3760 Mon Sep 17 00:00:00 2001 From: Heiner Lohaus Date: Fri, 22 Mar 2024 12:48:59 +0100 Subject: Add webview docs and examples, Set webview as default --- README.md | 32 +++++++++++++++++++++++++++++--- g4f/Provider/Bing.py | 2 +- g4f/gui/client/static/js/chat.v1.js | 16 ++++++++-------- g4f/gui/server/api.py | 8 ++++---- g4f/gui/webview.py | 3 ++- setup.py | 18 ++++++++++++------ 6 files changed, 56 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index 451ec57d..25fb4188 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,7 @@ As per the survey, here is a list of improvements to come - [ ] 🚧 Improve Documentation (in /docs & Guides, Howtos, & Do video tutorials) - [x] Improve the provider status list & updates - [ ] Tutorials on how to reverse sites to write your own wrapper (PoC only ofc) -- [ ] Improve the Bing wrapper. (might write a new wrapper in golang as it is very fast) +- [x] Improve the Bing wrapper. (Wait and Retry or reuse conversation) - [ ] Write a standard provider performance test to improve the stability - [ ] Potential support and development of local models - [ ] 🚧 Improve compatibility and error handling @@ -170,7 +170,33 @@ image_url = response.data[0].url - New Client API like the OpenAI Python library: [/docs/client](/docs/client.md) - Legacy API with python modules: [/docs/legacy](/docs/legacy.md) -#### Web UI +### Webview GUI + +Open the GUI in a window of your OS. Runs on a local/static/ssl server with a js api. Supports login into the OpenAI Chat, Image Upload and streamed Text Generation. + +Supports all platforms, but only Linux testet. + +1. Install all requirements with: + +```bash +pip install g4f[webview] +``` + +2. Follow the OS specific steps here: + [pywebview installation](https://pywebview.flowrl.com/guide/installation.html#dependencies) + +3. Run the app with: + +```python +from g4f.gui.webview import run_webview +run_webview(debug=True) +``` +or execute the following command: +```bash +python -m g4f.gui.webview -debug +``` + +#### Webserver To start the web interface, type the following codes in python: @@ -237,7 +263,7 @@ set G4F_PROXY=http://host:port | [bing.com](https://bing.com/chat) | `g4f.Provider.Bing` | ❌ | ✔️ | ✔️ | ![Unknown](https://img.shields.io/badge/Unknown-grey) | ❌ | | [chatgpt.ai](https://chatgpt.ai) | `g4f.Provider.ChatgptAi` | ❌ | ✔️ | ✔️ | ![Active](https://img.shields.io/badge/Active-brightgreen) | ❌ | | [liaobots.site](https://liaobots.site) | `g4f.Provider.Liaobots` | ✔️ | ✔️ | ✔️ | ![Active](https://img.shields.io/badge/Active-brightgreen) | ❌ | -| [chat.openai.com](https://chat.openai.com) | `g4f.Provider.OpenaiChat` | ✔️ | ✔️ | ✔️ | ![Unknown](https://img.shields.io/badge/Unknown-grey) | ✔️ | +| [chat.openai.com](https://chat.openai.com) | `g4f.Provider.OpenaiChat` | ✔️ | ❌ | ✔️ | ![Unknown](https://img.shields.io/badge/Unknown-grey) | ✔️ | | [raycast.com](https://raycast.com) | `g4f.Provider.Raycast` | ✔️ | ✔️ | ✔️ | ![Unknown](https://img.shields.io/badge/Unknown-grey) | ✔️ | | [beta.theb.ai](https://beta.theb.ai) | `g4f.Provider.Theb` | ✔️ | ✔️ | ✔️ | ![Unknown](https://img.shields.io/badge/Unknown-grey) | ❌ | | [you.com](https://you.com) | `g4f.Provider.You` | ✔️ | ✔️ | ✔️ | ![Unknown](https://img.shields.io/badge/Unknown-grey) | ❌ | diff --git a/g4f/Provider/Bing.py b/g4f/Provider/Bing.py index a1d14d87..f8b06dd1 100644 --- a/g4f/Provider/Bing.py +++ b/g4f/Provider/Bing.py @@ -414,7 +414,7 @@ async def stream_generate( image_request = await upload_image( session, image, - "Balanced" if Tones.copilot == "Copilot" else tone, + "Balanced" if tone == Tones.copilot else tone, headers ) if image else None async with session.ws_connect( diff --git a/g4f/gui/client/static/js/chat.v1.js b/g4f/gui/client/static/js/chat.v1.js index bcef4a78..f9bc4568 100644 --- a/g4f/gui/client/static/js/chat.v1.js +++ b/g4f/gui/client/static/js/chat.v1.js @@ -240,26 +240,26 @@ async function add_message_chunk(message) { } } -cameraInput?.addEventListener("click", (e) => { - if (window?.pywebview) { - e.preventDefault(); - pywebview.api.choose_file(); - } -}) +// fileInput?.addEventListener("click", (e) => { +// if (window?.pywebview) { +// e.preventDefault(); +// pywebview.api.choose_file(); +// } +// }); cameraInput?.addEventListener("click", (e) => { if (window?.pywebview) { e.preventDefault(); pywebview.api.take_picture(); } -}) +}); imageInput?.addEventListener("click", (e) => { if (window?.pywebview) { e.preventDefault(); pywebview.api.choose_image(); } -}) +}); const ask_gpt = async () => { regenerate.classList.add(`regenerate-hidden`); diff --git a/g4f/gui/server/api.py b/g4f/gui/server/api.py index 3adb88f4..e7683812 100644 --- a/g4f/gui/server/api.py +++ b/g4f/gui/server/api.py @@ -19,12 +19,12 @@ try: filters=[["Image", "*.jpg", "*.jpeg", "*.png", "*.webp", "*.svg"]], ) has_plyer = True -except (ImportError, NameError): +except ImportError: has_plyer = False try: from android.runnable import run_on_ui_thread - from android.storage import app_storage_path - from android.permissions import request_permissions, Permission + import android.permissions + from android.permissions import Permission from android.permissions import _RequestPermissionsManager _RequestPermissionsManager.register_callback() from .android_gallery import user_select_image @@ -161,7 +161,7 @@ class Api(): def request_permissions(self): if has_android: - request_permissions([ + android.permissions.request_permissions([ Permission.CAMERA, Permission.READ_EXTERNAL_STORAGE, Permission.WRITE_EXTERNAL_STORAGE diff --git a/g4f/gui/webview.py b/g4f/gui/webview.py index 36ad0e60..b015dbed 100644 --- a/g4f/gui/webview.py +++ b/g4f/gui/webview.py @@ -16,6 +16,7 @@ import g4f.debug def run_webview( debug: bool = False, + ssl: bool = True, storage_path: str = None ): if getattr(sys, 'frozen', False): @@ -36,7 +37,7 @@ def run_webview( private_mode=False, storage_path=storage_path, debug=debug, - ssl=True + ssl=ssl ) if __name__ == "__main__": diff --git a/setup.py b/setup.py index b6c106c4..fa997b50 100644 --- a/setup.py +++ b/setup.py @@ -18,23 +18,24 @@ EXTRA_REQUIRE = { 'all': [ "curl_cffi>=0.6.2", "certifi", - "async-property", # openai - "py-arkose-generator", # openai + #"py-arkose-generator", # not working "browser_cookie3", # get_cookies "PyExecJS", # GptForLove "duckduckgo-search>=5.0" ,# internet.search "beautifulsoup4", # internet.search and bing.create_images "brotli", # openai - "platformdirs", # webdriver - "undetected-chromedriver>=3.5.5", # webdriver - "setuptools", # webdriver + #"undetected-chromedriver>=3.5.5", # webdriver + #"setuptools", # webdriver + "pywebview", + "platformdirs", + "plyer", "aiohttp_socks", # proxy "pillow", # image "cairosvg", # svg image "werkzeug", "flask", # gui "loguru", "fastapi", "uvicorn", "nest_asyncio", # api - "selenium-wire" + #"selenium-wire" ], "image": [ "pillow", @@ -47,6 +48,11 @@ EXTRA_REQUIRE = { "setuptools", "selenium-wire" ], + "webview": [ + "webview", + "platformdirs", + "plyer" + ], "openai": [ "async-property", "py-arkose-generator", -- cgit v1.2.3