Spaces:
Sleeping
Sleeping
Add API dollar usage and fix style 增加当月API美金使用量 (#456)
Browse files* add dollar usage and fix style
* conditional rednering of usage
- ChuanhuChatbot.py +14 -3
- assets/custom.css +2 -1
- modules/openai_func.py +63 -3
- modules/presets.py +1 -0
ChuanhuChatbot.py
CHANGED
|
@@ -9,7 +9,7 @@ from modules.utils import *
|
|
| 9 |
from modules.presets import *
|
| 10 |
from modules.overwrites import *
|
| 11 |
from modules.chat_func import *
|
| 12 |
-
from modules.openai_func import get_usage
|
| 13 |
|
| 14 |
logging.basicConfig(
|
| 15 |
level=logging.DEBUG,
|
|
@@ -108,7 +108,7 @@ with gr.Blocks(css=customCSS, theme=small_and_beautiful_theme) as demo:
|
|
| 108 |
visible=not HIDE_MY_KEY,
|
| 109 |
label="API-Key",
|
| 110 |
)
|
| 111 |
-
usageTxt = gr.Markdown("**发送消息** 或 **提交key**
|
| 112 |
model_select_dropdown = gr.Dropdown(
|
| 113 |
label="选择模型", choices=MODELS, multiselect=False, value=MODELS[0]
|
| 114 |
)
|
|
@@ -272,14 +272,20 @@ with gr.Blocks(css=customCSS, theme=small_and_beautiful_theme) as demo:
|
|
| 272 |
fn=get_usage, inputs=[user_api_key], outputs=[usageTxt], show_progress=False
|
| 273 |
)
|
| 274 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 275 |
# Chatbot
|
| 276 |
cancelBtn.click(cancel_outputing, [], [])
|
| 277 |
|
| 278 |
user_input.submit(**transfer_input_args).then(**chatgpt_predict_args).then(**end_outputing_args)
|
| 279 |
user_input.submit(**get_usage_args)
|
|
|
|
| 280 |
|
| 281 |
submitBtn.click(**transfer_input_args).then(**chatgpt_predict_args).then(**end_outputing_args)
|
| 282 |
submitBtn.click(**get_usage_args)
|
|
|
|
| 283 |
|
| 284 |
emptyBtn.click(
|
| 285 |
reset_state,
|
|
@@ -306,6 +312,7 @@ with gr.Blocks(css=customCSS, theme=small_and_beautiful_theme) as demo:
|
|
| 306 |
show_progress=True,
|
| 307 |
).then(**end_outputing_args)
|
| 308 |
retryBtn.click(**get_usage_args)
|
|
|
|
| 309 |
|
| 310 |
delFirstBtn.click(
|
| 311 |
delete_first_conversation,
|
|
@@ -338,9 +345,13 @@ with gr.Blocks(css=customCSS, theme=small_and_beautiful_theme) as demo:
|
|
| 338 |
show_progress=True,
|
| 339 |
)
|
| 340 |
reduceTokenBtn.click(**get_usage_args)
|
|
|
|
| 341 |
|
| 342 |
# ChatGPT
|
| 343 |
-
|
|
|
|
|
|
|
|
|
|
| 344 |
|
| 345 |
# Template
|
| 346 |
templateRefreshBtn.click(get_template_names, None, [templateFileSelectDropdown])
|
|
|
|
| 9 |
from modules.presets import *
|
| 10 |
from modules.overwrites import *
|
| 11 |
from modules.chat_func import *
|
| 12 |
+
from modules.openai_func import get_usage, get_dollar_usage_for_current_month
|
| 13 |
|
| 14 |
logging.basicConfig(
|
| 15 |
level=logging.DEBUG,
|
|
|
|
| 108 |
visible=not HIDE_MY_KEY,
|
| 109 |
label="API-Key",
|
| 110 |
)
|
| 111 |
+
usageTxt = gr.Markdown("**发送消息** 或 **提交key** 以显示额度", elem_id="usage_display")
|
| 112 |
model_select_dropdown = gr.Dropdown(
|
| 113 |
label="选择模型", choices=MODELS, multiselect=False, value=MODELS[0]
|
| 114 |
)
|
|
|
|
| 272 |
fn=get_usage, inputs=[user_api_key], outputs=[usageTxt], show_progress=False
|
| 273 |
)
|
| 274 |
|
| 275 |
+
get_dollar_usage_args = dict(
|
| 276 |
+
fn=get_dollar_usage_for_current_month, inputs=[user_api_key], outputs=[usageTxt], show_progress=False
|
| 277 |
+
)
|
| 278 |
+
|
| 279 |
# Chatbot
|
| 280 |
cancelBtn.click(cancel_outputing, [], [])
|
| 281 |
|
| 282 |
user_input.submit(**transfer_input_args).then(**chatgpt_predict_args).then(**end_outputing_args)
|
| 283 |
user_input.submit(**get_usage_args)
|
| 284 |
+
user_input.submit(**get_dollar_usage_args)
|
| 285 |
|
| 286 |
submitBtn.click(**transfer_input_args).then(**chatgpt_predict_args).then(**end_outputing_args)
|
| 287 |
submitBtn.click(**get_usage_args)
|
| 288 |
+
submitBtn.click(**get_dollar_usage_args)
|
| 289 |
|
| 290 |
emptyBtn.click(
|
| 291 |
reset_state,
|
|
|
|
| 312 |
show_progress=True,
|
| 313 |
).then(**end_outputing_args)
|
| 314 |
retryBtn.click(**get_usage_args)
|
| 315 |
+
retryBtn.click(**get_dollar_usage_args)
|
| 316 |
|
| 317 |
delFirstBtn.click(
|
| 318 |
delete_first_conversation,
|
|
|
|
| 345 |
show_progress=True,
|
| 346 |
)
|
| 347 |
reduceTokenBtn.click(**get_usage_args)
|
| 348 |
+
reduceTokenBtn.click(**get_dollar_usage_args)
|
| 349 |
|
| 350 |
# ChatGPT
|
| 351 |
+
if get_usage(user_api_key) == "**您的免费额度已用完**":
|
| 352 |
+
keyTxt.change(submit_key, keyTxt, [user_api_key, status_display]).then(**get_dollar_usage_args)
|
| 353 |
+
else:
|
| 354 |
+
keyTxt.change(submit_key, keyTxt, [user_api_key, status_display]).then(**get_usage_args)
|
| 355 |
|
| 356 |
# Template
|
| 357 |
templateRefreshBtn.click(get_template_names, None, [templateFileSelectDropdown])
|
assets/custom.css
CHANGED
|
@@ -37,8 +37,9 @@ footer {
|
|
| 37 |
|
| 38 |
/* usage_display */
|
| 39 |
#usage_display {
|
| 40 |
-
height:
|
| 41 |
}
|
|
|
|
| 42 |
#usage_display p{
|
| 43 |
padding: 0 1em;
|
| 44 |
font-size: .85em;
|
|
|
|
| 37 |
|
| 38 |
/* usage_display */
|
| 39 |
#usage_display {
|
| 40 |
+
height: 2em;
|
| 41 |
}
|
| 42 |
+
|
| 43 |
#usage_display p{
|
| 44 |
padding: 0 1em;
|
| 45 |
font-size: .85em;
|
modules/openai_func.py
CHANGED
|
@@ -1,10 +1,19 @@
|
|
| 1 |
import requests
|
| 2 |
import logging
|
| 3 |
-
from modules.presets import
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4 |
from modules import shared
|
| 5 |
from modules.utils import get_proxies
|
| 6 |
import os
|
| 7 |
-
|
| 8 |
|
| 9 |
def get_usage_response(openai_api_key):
|
| 10 |
headers = {
|
|
@@ -42,7 +51,52 @@ def get_usage(openai_api_key):
|
|
| 42 |
logging.error(f"API使用情况解析失败:"+str(e))
|
| 43 |
balance = 0
|
| 44 |
total_used=0
|
| 45 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 46 |
except requests.exceptions.ConnectTimeout:
|
| 47 |
status_text = standard_error_msg + connection_timeout_prompt + error_retrieve_prompt
|
| 48 |
return status_text
|
|
@@ -52,3 +106,9 @@ def get_usage(openai_api_key):
|
|
| 52 |
except Exception as e:
|
| 53 |
logging.error(f"获取API使用情况失败:"+str(e))
|
| 54 |
return standard_error_msg + error_retrieve_prompt
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
import requests
|
| 2 |
import logging
|
| 3 |
+
from modules.presets import (
|
| 4 |
+
timeout_all,
|
| 5 |
+
USAGE_API_URL,
|
| 6 |
+
BALANCE_API_URL,
|
| 7 |
+
standard_error_msg,
|
| 8 |
+
connection_timeout_prompt,
|
| 9 |
+
error_retrieve_prompt,
|
| 10 |
+
read_timeout_prompt
|
| 11 |
+
)
|
| 12 |
+
|
| 13 |
from modules import shared
|
| 14 |
from modules.utils import get_proxies
|
| 15 |
import os
|
| 16 |
+
from datetime import datetime, timedelta
|
| 17 |
|
| 18 |
def get_usage_response(openai_api_key):
|
| 19 |
headers = {
|
|
|
|
| 51 |
logging.error(f"API使用情况解析失败:"+str(e))
|
| 52 |
balance = 0
|
| 53 |
total_used=0
|
| 54 |
+
return f"**API使用情况解析失败**"
|
| 55 |
+
if balance == 0:
|
| 56 |
+
return f"**您的免费额度已用完**"
|
| 57 |
+
return f"**API免费额度使用情况**(已用/余额)\u3000${total_used} / ${balance}"
|
| 58 |
+
except requests.exceptions.ConnectTimeout:
|
| 59 |
+
status_text = standard_error_msg + connection_timeout_prompt + error_retrieve_prompt
|
| 60 |
+
return status_text
|
| 61 |
+
except requests.exceptions.ReadTimeout:
|
| 62 |
+
status_text = standard_error_msg + read_timeout_prompt + error_retrieve_prompt
|
| 63 |
+
return status_text
|
| 64 |
+
except Exception as e:
|
| 65 |
+
logging.error(f"获取API使用情况失败:"+str(e))
|
| 66 |
+
return standard_error_msg + error_retrieve_prompt
|
| 67 |
+
|
| 68 |
+
def get_usage_for_current_month_response(openai_api_key):
|
| 69 |
+
headers = {
|
| 70 |
+
"Content-Type": "application/json",
|
| 71 |
+
"Authorization": f"Bearer {openai_api_key}",
|
| 72 |
+
}
|
| 73 |
+
|
| 74 |
+
timeout = timeout_all
|
| 75 |
+
today = datetime.today()
|
| 76 |
+
first_day_of_month = today.replace(day=1).date()
|
| 77 |
+
last_day_of_month = get_last_day_of_month(today).date()
|
| 78 |
+
|
| 79 |
+
proxies = get_proxies()
|
| 80 |
+
response = requests.get(
|
| 81 |
+
f"{USAGE_API_URL}?start_date={first_day_of_month}&end_date={last_day_of_month}",
|
| 82 |
+
headers=headers,
|
| 83 |
+
timeout=timeout,
|
| 84 |
+
proxies=proxies,
|
| 85 |
+
)
|
| 86 |
+
|
| 87 |
+
return response
|
| 88 |
+
|
| 89 |
+
def get_dollar_usage_for_current_month(openai_api_key):
|
| 90 |
+
try:
|
| 91 |
+
response=get_usage_for_current_month_response(openai_api_key=openai_api_key)
|
| 92 |
+
usage = 0
|
| 93 |
+
upper_limit = "120" # hardcoded as 120 dollars for now
|
| 94 |
+
try:
|
| 95 |
+
usage = round(response.json().get("total_usage")/100, 2) if response.json().get(
|
| 96 |
+
"total_usage") else 0
|
| 97 |
+
except Exception as e:
|
| 98 |
+
logging.error(f"API使用情况解析失败:"+str(e))
|
| 99 |
+
return f"**本月API使用情况**(已用/限额)\u3000${usage} / ${upper_limit}"
|
| 100 |
except requests.exceptions.ConnectTimeout:
|
| 101 |
status_text = standard_error_msg + connection_timeout_prompt + error_retrieve_prompt
|
| 102 |
return status_text
|
|
|
|
| 106 |
except Exception as e:
|
| 107 |
logging.error(f"获取API使用情况失败:"+str(e))
|
| 108 |
return standard_error_msg + error_retrieve_prompt
|
| 109 |
+
|
| 110 |
+
def get_last_day_of_month(any_day):
|
| 111 |
+
# The day 28 exists in every month. 4 days later, it's always next month
|
| 112 |
+
next_month = any_day.replace(day=28) + timedelta(days=4)
|
| 113 |
+
# subtracting the number of the current day brings us back one month
|
| 114 |
+
return next_month - timedelta(days=next_month.day)
|
modules/presets.py
CHANGED
|
@@ -5,6 +5,7 @@ import gradio as gr
|
|
| 5 |
initial_prompt = "You are a helpful assistant."
|
| 6 |
API_URL = "https://api.openai.com/v1/chat/completions"
|
| 7 |
BALANCE_API_URL="https://api.openai.com/dashboard/billing/credit_grants"
|
|
|
|
| 8 |
HISTORY_DIR = "history"
|
| 9 |
TEMPLATES_DIR = "templates"
|
| 10 |
|
|
|
|
| 5 |
initial_prompt = "You are a helpful assistant."
|
| 6 |
API_URL = "https://api.openai.com/v1/chat/completions"
|
| 7 |
BALANCE_API_URL="https://api.openai.com/dashboard/billing/credit_grants"
|
| 8 |
+
USAGE_API_URL="https://api.openai.com/dashboard/billing/usage"
|
| 9 |
HISTORY_DIR = "history"
|
| 10 |
TEMPLATES_DIR = "templates"
|
| 11 |
|