From 15b7cd6193408266ec28c69568749155bb5a249a Mon Sep 17 00:00:00 2001 From: ReeInk Date: Sat, 29 Apr 2023 18:10:27 +0800 Subject: [PATCH 1/8] feat: build docker image automatically --- .github/workflows/docker-image.yml | 45 ++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 .github/workflows/docker-image.yml diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml new file mode 100644 index 0000000..112a608 --- /dev/null +++ b/.github/workflows/docker-image.yml @@ -0,0 +1,45 @@ +# https://docs.github.com/en/actions/publishing-packages/publishing-docker-images#publishing-images-to-github-packages +name: Create and publish a Docker image + +on: + push: + branches: + - 'master' + tags: + - 'v*' + +env: + REGISTRY: ghcr.io + IMAGE_NAME: ${{ github.repository }} + +jobs: + build-and-push-image: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Log in to the Container registry + uses: docker/login-action@v2 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract metadata (tags, labels) for Docker + id: meta + uses: docker/metadata-action@v4 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + + - name: Build and push Docker image + uses: docker/build-push-action@v4 + with: + context: . + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} From 601c36e6079e44c17567d0bec7917cbb7edfb874 Mon Sep 17 00:00:00 2001 From: ReeInk Date: Sat, 29 Apr 2023 19:53:43 +0800 Subject: [PATCH 2/8] =?UTF-8?q?=E5=8A=A0=E8=BD=BD=E7=8E=AF=E5=A2=83?= =?UTF-8?q?=E5=8F=98=E9=87=8F=E4=BD=9C=E4=B8=BA=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config.py | 47 +++++++++++++++++++++++++++++------------------ 1 file changed, 29 insertions(+), 18 deletions(-) diff --git a/config.py b/config.py index 30c388e..ea1bb0c 100644 --- a/config.py +++ b/config.py @@ -1,8 +1,11 @@ +from os import environ + # [step 1]>> 例如: API_KEY = "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" (此key无效) -API_KEY = "sk-此处填API密钥" # 可同时填写多个API-KEY,用英文逗号分割,例如API_KEY = "sk-openaikey1,sk-openaikey2,fkxxxx-api2dkey1,fkxxxx-api2dkey2" +API_KEY = environ.get("GPT_ACADEMIC_API_KEY") or "sk-此处填API密钥" +# 可同时填写多个API-KEY,用英文逗号分割,例如API_KEY = "sk-openaikey1,sk-openaikey2,fkxxxx-api2dkey1,fkxxxx-api2dkey2" # [step 2]>> 改为True应用代理,如果直接在海外服务器部署,此处不修改 -USE_PROXY = False +USE_PROXY = environ.get("GPT_ACADEMIC_USE_PROXY") == "true" or False if USE_PROXY: # 填写格式是 [协议]:// [地址] :[端口],填写之前不要忘记把USE_PROXY改成True,如果直接在海外服务器部署,此处不修改 # 例如 "socks5h://localhost:11284" @@ -13,62 +16,70 @@ if USE_PROXY: # 代理网络的地址,打开你的*学*网软件查看代理的协议(socks5/http)、地址(localhost)和端口(11284) proxies = { # [协议]:// [地址] :[端口] - "http": "socks5h://localhost:11284", - "https": "socks5h://localhost:11284", + "http": environ.get("GPT_ACADEMIC_HTTP_PROXY") or "socks5h://localhost:11284", + "https": environ.get("GPT_ACADEMIC_HTTPS_PROXY") or "socks5h://localhost:11284", } else: proxies = None # [step 3]>> 多线程函数插件中,默认允许多少路线程同时访问OpenAI。Free trial users的限制是每分钟3次,Pay-as-you-go users的限制是每分钟3500次 # 一言以蔽之:免费用户填3,OpenAI绑了信用卡的用户可以填 16 或者更高。提高限制请查询:https://platform.openai.com/docs/guides/rate-limits/overview -DEFAULT_WORKER_NUM = 3 +DEFAULT_WORKER_NUM = int(environ.get("GPT_ACADEMIC_DEFAULT_WORKER_NUM") or 3) # [step 4]>> 以下配置可以优化体验,但大部分场合下并不需要修改 # 对话窗的高度 -CHATBOT_HEIGHT = 1115 +CHATBOT_HEIGHT = int(environ.get("GPT_ACADEMIC_CHATBOT_HEIGHT") or 1115) # 代码高亮 -CODE_HIGHLIGHT = True +CODE_HIGHLIGHT = environ.get("GPT_ACADEMIC_CODE_HIGHLIGHT") != "false" # 默认为True # 窗口布局 -LAYOUT = "LEFT-RIGHT" # "LEFT-RIGHT"(左右布局) # "TOP-DOWN"(上下布局) -DARK_MODE = True # "LEFT-RIGHT"(左右布局) # "TOP-DOWN"(上下布局) +LAYOUT = environ.get("GPT_ACADEMIC_LAYOUT") or "LEFT-RIGHT" # "LEFT-RIGHT"(左右布局) # "TOP-DOWN"(上下布局) +DARK_MODE = environ.get("GPT_ACADEMIC_DARK_MODE") == "true" # 是否启用暗色模式,默认为False # 发送请求到OpenAI后,等待多久判定为超时 -TIMEOUT_SECONDS = 30 +TIMEOUT_SECONDS = int(environ.get("GPT_ACADEMIC_TIMEOUT_SECONDS") or 30) # 网页的端口, -1代表随机端口 -WEB_PORT = -1 +WEB_PORT = int(environ.get("GPT_ACADEMIC_WEB_PORT") or -1) # 如果OpenAI不响应(网络卡顿、代理失败、KEY失效),重试的次数限制 -MAX_RETRY = 2 +MAX_RETRY = int(environ.get("GPT_ACADEMIC_MAX_RETRY") or 2) # OpenAI模型选择是(gpt4现在只对申请成功的人开放,体验gpt-4可以试试api2d) -LLM_MODEL = "gpt-3.5-turbo" # 可选 ↓↓↓ +LLM_MODEL = environ.get("GPT_ACADEMIC_LLM_MODEL") or "gpt-3.5-turbo" # 可选 ↓↓↓ AVAIL_LLM_MODELS = ["gpt-3.5-turbo", "api2d-gpt-3.5-turbo", "gpt-4", "api2d-gpt-4", "chatglm", "newbing"] # 本地LLM模型如ChatGLM的执行方式 CPU/GPU -LOCAL_MODEL_DEVICE = "cpu" # 可选 "cuda" +LOCAL_MODEL_DEVICE = environ.get("GPT_ACADEMIC_LOCAL_MODEL_DEVICE") or "cpu" # 可选 "cuda" # 设置gradio的并行线程数(不需要修改) -CONCURRENT_COUNT = 100 +CONCURRENT_COUNT = int(environ.get("GPT_ACADEMIC_CONCURRENT_COUNT") or 100) # 设置用户名和密码(不需要修改)(相关功能不稳定,与gradio版本和网络都相关,如果本地使用不建议加这个) # [("username", "password"), ("username2", "password2"), ...] AUTHENTICATION = [] +# 如果设置`GPT_ACADEMIC_AUTHENTICATION`环境变量,格式为 "username,password;username2,password2;..." +if environ.get("GPT_ACADEMIC_AUTHENTICATION"): + for i in environ.get("GPT_ACADEMIC_AUTHENTICATION").split(";"): + AUTHENTICATION.append(tuple(i.split(","))) # 重新URL重新定向,实现更换API_URL的作用(常规情况下,不要修改!!) # (高危设置!通过修改此设置,您将把您的API-KEY和对话隐私完全暴露给您设定的中间人!) # 格式 {"https://api.openai.com/v1/chat/completions": "在这里填写重定向的api.openai.com的URL"} # 例如 API_URL_REDIRECT = {"https://api.openai.com/v1/chat/completions": "https://ai.open.com/api/conversation"} API_URL_REDIRECT = {} +# 如果设置`GPT_ACADEMIC_API_URL_REDIRECT`环境变量,格式为 "https://api.openai.com/v1/chat/completions,https://ai.open.com/api/conversation;..." +if environ.get("GPT_ACADEMIC_API_URL_REDIRECT"): + for i in environ.get("GPT_ACADEMIC_API_URL_REDIRECT").split(";"): + API_URL_REDIRECT[i.split(",")[0]] = i.split(",")[1] # 如果需要在二级路径下运行(常规情况下,不要修改!!)(需要配合修改main.py才能生效!) -CUSTOM_PATH = "/" +CUSTOM_PATH = environ.get("GPT_ACADEMIC_CUSTOM_PATH") or "/" # 如果需要使用newbing,把newbing的长长的cookie放到这里 -NEWBING_STYLE = "creative" # ["creative", "balanced", "precise"] -NEWBING_COOKIES = """ +NEWBING_STYLE = environ.get("GPT_ACADEMIC_NEWBING_STYLE") or "creative" # ["creative", "balanced", "precise"] +NEWBING_COOKIES = environ.get("GPT_ACADEMIC_NEWBING_COOKIES") or """ your bing cookies here """ \ No newline at end of file From f187a23dc13985052842604e8f761dd4c5574f2a Mon Sep 17 00:00:00 2001 From: ReeInk Date: Sun, 30 Apr 2023 14:34:35 +0800 Subject: [PATCH 3/8] =?UTF-8?q?Revert=20"=E5=8A=A0=E8=BD=BD=E7=8E=AF?= =?UTF-8?q?=E5=A2=83=E5=8F=98=E9=87=8F=E4=BD=9C=E4=B8=BA=E9=85=8D=E7=BD=AE?= =?UTF-8?q?"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 601c36e6079e44c17567d0bec7917cbb7edfb874. --- config.py | 47 ++++++++++++++++++----------------------------- 1 file changed, 18 insertions(+), 29 deletions(-) diff --git a/config.py b/config.py index ea1bb0c..30c388e 100644 --- a/config.py +++ b/config.py @@ -1,11 +1,8 @@ -from os import environ - # [step 1]>> 例如: API_KEY = "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" (此key无效) -API_KEY = environ.get("GPT_ACADEMIC_API_KEY") or "sk-此处填API密钥" -# 可同时填写多个API-KEY,用英文逗号分割,例如API_KEY = "sk-openaikey1,sk-openaikey2,fkxxxx-api2dkey1,fkxxxx-api2dkey2" +API_KEY = "sk-此处填API密钥" # 可同时填写多个API-KEY,用英文逗号分割,例如API_KEY = "sk-openaikey1,sk-openaikey2,fkxxxx-api2dkey1,fkxxxx-api2dkey2" # [step 2]>> 改为True应用代理,如果直接在海外服务器部署,此处不修改 -USE_PROXY = environ.get("GPT_ACADEMIC_USE_PROXY") == "true" or False +USE_PROXY = False if USE_PROXY: # 填写格式是 [协议]:// [地址] :[端口],填写之前不要忘记把USE_PROXY改成True,如果直接在海外服务器部署,此处不修改 # 例如 "socks5h://localhost:11284" @@ -16,70 +13,62 @@ if USE_PROXY: # 代理网络的地址,打开你的*学*网软件查看代理的协议(socks5/http)、地址(localhost)和端口(11284) proxies = { # [协议]:// [地址] :[端口] - "http": environ.get("GPT_ACADEMIC_HTTP_PROXY") or "socks5h://localhost:11284", - "https": environ.get("GPT_ACADEMIC_HTTPS_PROXY") or "socks5h://localhost:11284", + "http": "socks5h://localhost:11284", + "https": "socks5h://localhost:11284", } else: proxies = None # [step 3]>> 多线程函数插件中,默认允许多少路线程同时访问OpenAI。Free trial users的限制是每分钟3次,Pay-as-you-go users的限制是每分钟3500次 # 一言以蔽之:免费用户填3,OpenAI绑了信用卡的用户可以填 16 或者更高。提高限制请查询:https://platform.openai.com/docs/guides/rate-limits/overview -DEFAULT_WORKER_NUM = int(environ.get("GPT_ACADEMIC_DEFAULT_WORKER_NUM") or 3) +DEFAULT_WORKER_NUM = 3 # [step 4]>> 以下配置可以优化体验,但大部分场合下并不需要修改 # 对话窗的高度 -CHATBOT_HEIGHT = int(environ.get("GPT_ACADEMIC_CHATBOT_HEIGHT") or 1115) +CHATBOT_HEIGHT = 1115 # 代码高亮 -CODE_HIGHLIGHT = environ.get("GPT_ACADEMIC_CODE_HIGHLIGHT") != "false" # 默认为True +CODE_HIGHLIGHT = True # 窗口布局 -LAYOUT = environ.get("GPT_ACADEMIC_LAYOUT") or "LEFT-RIGHT" # "LEFT-RIGHT"(左右布局) # "TOP-DOWN"(上下布局) -DARK_MODE = environ.get("GPT_ACADEMIC_DARK_MODE") == "true" # 是否启用暗色模式,默认为False +LAYOUT = "LEFT-RIGHT" # "LEFT-RIGHT"(左右布局) # "TOP-DOWN"(上下布局) +DARK_MODE = True # "LEFT-RIGHT"(左右布局) # "TOP-DOWN"(上下布局) # 发送请求到OpenAI后,等待多久判定为超时 -TIMEOUT_SECONDS = int(environ.get("GPT_ACADEMIC_TIMEOUT_SECONDS") or 30) +TIMEOUT_SECONDS = 30 # 网页的端口, -1代表随机端口 -WEB_PORT = int(environ.get("GPT_ACADEMIC_WEB_PORT") or -1) +WEB_PORT = -1 # 如果OpenAI不响应(网络卡顿、代理失败、KEY失效),重试的次数限制 -MAX_RETRY = int(environ.get("GPT_ACADEMIC_MAX_RETRY") or 2) +MAX_RETRY = 2 # OpenAI模型选择是(gpt4现在只对申请成功的人开放,体验gpt-4可以试试api2d) -LLM_MODEL = environ.get("GPT_ACADEMIC_LLM_MODEL") or "gpt-3.5-turbo" # 可选 ↓↓↓ +LLM_MODEL = "gpt-3.5-turbo" # 可选 ↓↓↓ AVAIL_LLM_MODELS = ["gpt-3.5-turbo", "api2d-gpt-3.5-turbo", "gpt-4", "api2d-gpt-4", "chatglm", "newbing"] # 本地LLM模型如ChatGLM的执行方式 CPU/GPU -LOCAL_MODEL_DEVICE = environ.get("GPT_ACADEMIC_LOCAL_MODEL_DEVICE") or "cpu" # 可选 "cuda" +LOCAL_MODEL_DEVICE = "cpu" # 可选 "cuda" # 设置gradio的并行线程数(不需要修改) -CONCURRENT_COUNT = int(environ.get("GPT_ACADEMIC_CONCURRENT_COUNT") or 100) +CONCURRENT_COUNT = 100 # 设置用户名和密码(不需要修改)(相关功能不稳定,与gradio版本和网络都相关,如果本地使用不建议加这个) # [("username", "password"), ("username2", "password2"), ...] AUTHENTICATION = [] -# 如果设置`GPT_ACADEMIC_AUTHENTICATION`环境变量,格式为 "username,password;username2,password2;..." -if environ.get("GPT_ACADEMIC_AUTHENTICATION"): - for i in environ.get("GPT_ACADEMIC_AUTHENTICATION").split(";"): - AUTHENTICATION.append(tuple(i.split(","))) # 重新URL重新定向,实现更换API_URL的作用(常规情况下,不要修改!!) # (高危设置!通过修改此设置,您将把您的API-KEY和对话隐私完全暴露给您设定的中间人!) # 格式 {"https://api.openai.com/v1/chat/completions": "在这里填写重定向的api.openai.com的URL"} # 例如 API_URL_REDIRECT = {"https://api.openai.com/v1/chat/completions": "https://ai.open.com/api/conversation"} API_URL_REDIRECT = {} -# 如果设置`GPT_ACADEMIC_API_URL_REDIRECT`环境变量,格式为 "https://api.openai.com/v1/chat/completions,https://ai.open.com/api/conversation;..." -if environ.get("GPT_ACADEMIC_API_URL_REDIRECT"): - for i in environ.get("GPT_ACADEMIC_API_URL_REDIRECT").split(";"): - API_URL_REDIRECT[i.split(",")[0]] = i.split(",")[1] # 如果需要在二级路径下运行(常规情况下,不要修改!!)(需要配合修改main.py才能生效!) -CUSTOM_PATH = environ.get("GPT_ACADEMIC_CUSTOM_PATH") or "/" +CUSTOM_PATH = "/" # 如果需要使用newbing,把newbing的长长的cookie放到这里 -NEWBING_STYLE = environ.get("GPT_ACADEMIC_NEWBING_STYLE") or "creative" # ["creative", "balanced", "precise"] -NEWBING_COOKIES = environ.get("GPT_ACADEMIC_NEWBING_COOKIES") or """ +NEWBING_STYLE = "creative" # ["creative", "balanced", "precise"] +NEWBING_COOKIES = """ your bing cookies here """ \ No newline at end of file From e5e3e0aa43d8db8b5d731dbabcb1f44d1fed7808 Mon Sep 17 00:00:00 2001 From: ReeInk Date: Sun, 30 Apr 2023 17:30:31 +0800 Subject: [PATCH 4/8] =?UTF-8?q?=E8=AF=BB=E5=8F=96=E7=8E=AF=E5=A2=83?= =?UTF-8?q?=E5=8F=98=E9=87=8F=E4=BD=9C=E4=B8=BA=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- toolbox.py | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 53 insertions(+), 2 deletions(-) diff --git a/toolbox.py b/toolbox.py index 5e42164..81ef1ed 100644 --- a/toolbox.py +++ b/toolbox.py @@ -3,6 +3,7 @@ import importlib import traceback import inspect import re +import os from latex2mathml.converter import convert as tex2mathml from functools import wraps, lru_cache @@ -517,13 +518,63 @@ def select_api_key(keys, llm_model): api_key = random.choice(avail_key_list) # 随机负载均衡 return api_key +def read_single_conf_from_env(arg, default_value): + ENV_PREFIX = "GPT_ACADEMIC_" # 环境变量的前缀 + env_arg = ENV_PREFIX + arg # 环境变量的KEY + if arg == "proxies": + # 对于proxies,我们使用多个环境变量来配置 + # HTTP_PROXY: 对应http代理 + # HTTPS_PROXY: 对应https代理 + # ALL_PROXY: 对应http和https代理,优先级较HTTP_PROXY和HTTPS_PROXY更低 + http_proxy = os.environ.get(ENV_PREFIX + "HTTP_PROXY") or os.environ.get("ALL_PROXY") + assert http_proxy is not None, f"请设置环境变量{ENV_PREFIX + 'HTTP_PROXY'}" + https_proxy = os.environ.get(ENV_PREFIX + "HTTPS_PROXY") or os.environ.get("ALL_PROXY") + assert https_proxy is not None, f"请设置环境变量{ENV_PREFIX + 'HTTPS_PROXY'}" + r = { + "http": http_proxy, + "https": https_proxy + } + elif arg == "AVAIL_LLM_MODELS": + r = [] + # 对于AVAIL_LLM_MODELS的环境变量配置,我们允许用户使用;分隔多个模型 + for item in os.environ[env_arg].split(";"): + r.append(item) + elif arg == "AUTHENTICATION": + r = [] + # 对于AUTHENTICATION的环境变量配置,我们允许用户使用;分隔多个账号 + # 格式为:username1:password1;username2:password2 + for item in os.environ[env_arg].split(";"): + r.append(tuple(item.split(":"))) + elif arg == "API_URL_REDIRECT": + r = {} + # 对于API_URL_REDIRECT的环境变量配置,我们允许用户使用;分隔转发地址 + # 格式为:url1:redirect1;url2:redirect2 + for item in os.environ[env_arg].split(";"): + k, v = item.split(":") + r[k] = v + elif isinstance(default_value, bool): + r = bool(os.environ[env_arg]) + elif isinstance(default_value, int): + r = int(os.environ[env_arg]) + elif isinstance(default_value, float): + r = float(os.environ[env_arg]) + elif isinstance(default_value, str): + r = os.environ[env_arg] + else: + raise RuntimeError(f"[CONFIG] 环境变量{arg}不支持自动转换到{type(default_value)}类型") + return r + @lru_cache(maxsize=128) def read_single_conf_with_lru_cache(arg): from colorful import print亮红, print亮绿, print亮蓝 + default_r = getattr(importlib.import_module('config'), arg) try: - r = getattr(importlib.import_module('config_private'), arg) + r = read_single_conf_from_env(arg, default_r) # 优先获取环境变量作为配置 except: - r = getattr(importlib.import_module('config'), arg) + try: + r = getattr(importlib.import_module('config_private'), arg) + except: + r = default_r # 在读取API_KEY时,检查一下是不是忘了改config if arg == 'API_KEY': print亮蓝(f"[API_KEY] 本项目现已支持OpenAI和API2D的api-key。也支持同时填写多个api-key,如API_KEY=\"openai-key1,openai-key2,api2d-key3\"") From 8865b232ca68906f042a89fcdffbf3cf24907878 Mon Sep 17 00:00:00 2001 From: ReeInk Date: Tue, 2 May 2023 00:12:35 +0800 Subject: [PATCH 5/8] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=EF=BC=9A=E8=AF=BB?= =?UTF-8?q?=E5=8F=96=E7=8E=AF=E5=A2=83=E5=8F=98=E9=87=8F=E9=87=8D=E5=AE=9A?= =?UTF-8?q?=E5=90=91URL=E6=A0=BC=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- toolbox.py | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/toolbox.py b/toolbox.py index 81ef1ed..20a9abb 100644 --- a/toolbox.py +++ b/toolbox.py @@ -545,13 +545,11 @@ def read_single_conf_from_env(arg, default_value): # 格式为:username1:password1;username2:password2 for item in os.environ[env_arg].split(";"): r.append(tuple(item.split(":"))) - elif arg == "API_URL_REDIRECT": - r = {} - # 对于API_URL_REDIRECT的环境变量配置,我们允许用户使用;分隔转发地址 - # 格式为:url1:redirect1;url2:redirect2 - for item in os.environ[env_arg].split(";"): - k, v = item.split(":") - r[k] = v + elif arg == "API_URL_REDIRECT": + # 对于API_URL_REDIRECT的环境变量,我们允许用户使用json格式配置多个url重定向 + # 格式为一个json字符串,例如:{"https://api.openai.com/v1/chat/completions": "https://ai.open.com/api/conversation"} + import json + r = json.loads(os.environ[env_arg]) elif isinstance(default_value, bool): r = bool(os.environ[env_arg]) elif isinstance(default_value, int): From 896077009a58bf2f4d6eae9c06ce8b7c4e3a2326 Mon Sep 17 00:00:00 2001 From: Your Name Date: Tue, 2 May 2023 14:54:51 +0800 Subject: [PATCH 6/8] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E9=80=9A=E7=94=A8?= =?UTF-8?q?=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- toolbox.py | 91 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 47 insertions(+), 44 deletions(-) diff --git a/toolbox.py b/toolbox.py index 20a9abb..d560f3e 100644 --- a/toolbox.py +++ b/toolbox.py @@ -518,61 +518,64 @@ def select_api_key(keys, llm_model): api_key = random.choice(avail_key_list) # 随机负载均衡 return api_key -def read_single_conf_from_env(arg, default_value): - ENV_PREFIX = "GPT_ACADEMIC_" # 环境变量的前缀 - env_arg = ENV_PREFIX + arg # 环境变量的KEY - if arg == "proxies": - # 对于proxies,我们使用多个环境变量来配置 - # HTTP_PROXY: 对应http代理 - # HTTPS_PROXY: 对应https代理 - # ALL_PROXY: 对应http和https代理,优先级较HTTP_PROXY和HTTPS_PROXY更低 - http_proxy = os.environ.get(ENV_PREFIX + "HTTP_PROXY") or os.environ.get("ALL_PROXY") - assert http_proxy is not None, f"请设置环境变量{ENV_PREFIX + 'HTTP_PROXY'}" - https_proxy = os.environ.get(ENV_PREFIX + "HTTPS_PROXY") or os.environ.get("ALL_PROXY") - assert https_proxy is not None, f"请设置环境变量{ENV_PREFIX + 'HTTPS_PROXY'}" - r = { - "http": http_proxy, - "https": https_proxy - } - elif arg == "AVAIL_LLM_MODELS": - r = [] - # 对于AVAIL_LLM_MODELS的环境变量配置,我们允许用户使用;分隔多个模型 - for item in os.environ[env_arg].split(";"): - r.append(item) - elif arg == "AUTHENTICATION": - r = [] - # 对于AUTHENTICATION的环境变量配置,我们允许用户使用;分隔多个账号 - # 格式为:username1:password1;username2:password2 - for item in os.environ[env_arg].split(";"): - r.append(tuple(item.split(":"))) - elif arg == "API_URL_REDIRECT": - # 对于API_URL_REDIRECT的环境变量,我们允许用户使用json格式配置多个url重定向 - # 格式为一个json字符串,例如:{"https://api.openai.com/v1/chat/completions": "https://ai.open.com/api/conversation"} - import json - r = json.loads(os.environ[env_arg]) - elif isinstance(default_value, bool): - r = bool(os.environ[env_arg]) - elif isinstance(default_value, int): - r = int(os.environ[env_arg]) - elif isinstance(default_value, float): - r = float(os.environ[env_arg]) - elif isinstance(default_value, str): - r = os.environ[env_arg] +def read_env_variable(arg, default_value): + """ + 环境变量可以是 `GPT_ACADEMIC_CONFIG`(优先),也可以直接是`CONFIG` + 例如在windows cmd中,既可以写: + set USE_PROXY=True + set API_KEY=sk-j7caBpkRoxxxxxxxxxxxxxxxxxxxxxxxxxxxx + set proxies={"http":"http://127.0.0.1:10085", "https":"http://127.0.0.1:10085",} + set AVAIL_LLM_MODELS=["gpt-3.5-turbo", "chatglm"] + set AUTHENTICATION=[("username", "password"), ("username2", "password2")] + 也可以写: + set GPT_ACADEMIC_USE_PROXY=True + set GPT_ACADEMIC_API_KEY=sk-j7caBpkRoxxxxxxxxxxxxxxxxxxxxxxxxxxxx + set GPT_ACADEMIC_proxies={"http":"http://127.0.0.1:10085", "https":"http://127.0.0.1:10085",} + set GPT_ACADEMIC_AVAIL_LLM_MODELS=["gpt-3.5-turbo", "chatglm"] + set GPT_ACADEMIC_AUTHENTICATION=[("username", "password"), ("username2", "password2")] + """ + from colorful import print亮红, print亮绿 + arg_with_prefix = "GPT_ACADEMIC_" + arg + if arg_with_prefix in os.environ: env_arg = os.environ[arg_with_prefix] + elif arg in os.environ: env_arg = os.environ[arg] else: - raise RuntimeError(f"[CONFIG] 环境变量{arg}不支持自动转换到{type(default_value)}类型") + raise KeyError + if isinstance(default_value, bool): + r = bool(env_arg) + elif isinstance(default_value, int): + r = int(env_arg) + elif isinstance(default_value, float): + r = float(env_arg) + elif isinstance(default_value, str): + r = env_arg + elif isinstance(default_value, dict): + r = eval(env_arg) + elif isinstance(default_value, list): + r = eval(env_arg) + elif default_value is None: + assert arg == "proxies" + r = eval(env_arg) + else: + print亮红(f"[ENV_VAR] 环境变量{arg}不支持通过环境变量设置!{default_value}") + raise KeyError + print亮绿(f"[ENV_VAR] 成功读取环境变量{arg}") return r @lru_cache(maxsize=128) def read_single_conf_with_lru_cache(arg): from colorful import print亮红, print亮绿, print亮蓝 - default_r = getattr(importlib.import_module('config'), arg) try: - r = read_single_conf_from_env(arg, default_r) # 优先获取环境变量作为配置 + # 优先级1. 获取环境变量作为配置 + default_ref = getattr(importlib.import_module('config'), arg) # 读取默认值作为数据类型转换的参考 + r = read_env_variable(arg, default_ref) except: try: + # 优先级2. 获取config_private中的配置 r = getattr(importlib.import_module('config_private'), arg) except: - r = default_r + # 优先级3. 获取config中的配置 + r = getattr(importlib.import_module('config'), arg) + # 在读取API_KEY时,检查一下是不是忘了改config if arg == 'API_KEY': print亮蓝(f"[API_KEY] 本项目现已支持OpenAI和API2D的api-key。也支持同时填写多个api-key,如API_KEY=\"openai-key1,openai-key2,api2d-key3\"") From a69ef7f8c59754aa2a8af65ddabc07fe9cef1182 Mon Sep 17 00:00:00 2001 From: binary-husky <505030475@qq.com> Date: Tue, 2 May 2023 15:33:07 +0800 Subject: [PATCH 7/8] env read failure reminder --- toolbox.py | 48 ++++++++++++++++++++++++++++-------------------- 1 file changed, 28 insertions(+), 20 deletions(-) diff --git a/toolbox.py b/toolbox.py index d560f3e..3872931 100644 --- a/toolbox.py +++ b/toolbox.py @@ -536,28 +536,36 @@ def read_env_variable(arg, default_value): """ from colorful import print亮红, print亮绿 arg_with_prefix = "GPT_ACADEMIC_" + arg - if arg_with_prefix in os.environ: env_arg = os.environ[arg_with_prefix] - elif arg in os.environ: env_arg = os.environ[arg] + if arg_with_prefix in os.environ: + env_arg = os.environ[arg_with_prefix] + elif arg in os.environ: + env_arg = os.environ[arg] else: raise KeyError - if isinstance(default_value, bool): - r = bool(env_arg) - elif isinstance(default_value, int): - r = int(env_arg) - elif isinstance(default_value, float): - r = float(env_arg) - elif isinstance(default_value, str): - r = env_arg - elif isinstance(default_value, dict): - r = eval(env_arg) - elif isinstance(default_value, list): - r = eval(env_arg) - elif default_value is None: - assert arg == "proxies" - r = eval(env_arg) - else: - print亮红(f"[ENV_VAR] 环境变量{arg}不支持通过环境变量设置!{default_value}") - raise KeyError + print(f"[ENV_VAR] 尝试加载{arg},默认值:{default_value} --> 修正值:{env_arg}") + try: + if isinstance(default_value, bool): + r = bool(env_arg) + elif isinstance(default_value, int): + r = int(env_arg) + elif isinstance(default_value, float): + r = float(env_arg) + elif isinstance(default_value, str): + r = env_arg + elif isinstance(default_value, dict): + r = eval(env_arg) + elif isinstance(default_value, list): + r = eval(env_arg) + elif default_value is None: + assert arg == "proxies" + r = eval(env_arg) + else: + print亮红(f"[ENV_VAR] 环境变量{arg}不支持通过环境变量设置! ") + raise KeyError + except: + print亮红(f"[ENV_VAR] 环境变量{arg}加载失败! ") + raise KeyError(f"[ENV_VAR] 环境变量{arg}加载失败! ") + print亮绿(f"[ENV_VAR] 成功读取环境变量{arg}") return r From b7d3ed7135093f36d93235a5cfb342a7fed3e2dd Mon Sep 17 00:00:00 2001 From: binary-husky Date: Thu, 4 May 2023 01:30:24 +0800 Subject: [PATCH 8/8] rm docker image yml --- .github/workflows/docker-image.yml | 45 ------------------------------ 1 file changed, 45 deletions(-) delete mode 100644 .github/workflows/docker-image.yml diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml deleted file mode 100644 index 112a608..0000000 --- a/.github/workflows/docker-image.yml +++ /dev/null @@ -1,45 +0,0 @@ -# https://docs.github.com/en/actions/publishing-packages/publishing-docker-images#publishing-images-to-github-packages -name: Create and publish a Docker image - -on: - push: - branches: - - 'master' - tags: - - 'v*' - -env: - REGISTRY: ghcr.io - IMAGE_NAME: ${{ github.repository }} - -jobs: - build-and-push-image: - runs-on: ubuntu-latest - permissions: - contents: read - packages: write - - steps: - - name: Checkout repository - uses: actions/checkout@v3 - - - name: Log in to the Container registry - uses: docker/login-action@v2 - with: - registry: ${{ env.REGISTRY }} - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: Extract metadata (tags, labels) for Docker - id: meta - uses: docker/metadata-action@v4 - with: - images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} - - - name: Build and push Docker image - uses: docker/build-push-action@v4 - with: - context: . - push: true - tags: ${{ steps.meta.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }}