diff --git a/__pycache__/settings.cpython-310.pyc b/__pycache__/settings.cpython-310.pyc deleted file mode 100644 index abec7a3..0000000 Binary files a/__pycache__/settings.cpython-310.pyc and /dev/null differ diff --git a/__pycache__/settings.cpython-39.pyc b/__pycache__/settings.cpython-39.pyc deleted file mode 100644 index 0a3369e..0000000 Binary files a/__pycache__/settings.cpython-39.pyc and /dev/null differ diff --git a/logs/novel_api.log b/logs/novel_api.log index c304f75..eaa226a 100644 --- a/logs/novel_api.log +++ b/logs/novel_api.log @@ -6420,3 +6420,118 @@ INFO 2023-06-19 18:47:41,460 autoreload 636 Watching for file changes with StatR INFO 2023-06-19 18:49:42,637 autoreload 250 E:\workspace2\novel_api\novel_api\apps\chatbot\views.py changed, reloading. INFO 2023-06-19 18:49:43,883 autoreload 636 Watching for file changes with StatReloader INFO 2023-06-19 18:54:49,730 basehttp 161 "GET /api/v1/novel/ HTTP/1.1" 200 1630 +INFO 2023-06-19 18:54:52,176 basehttp 161 "GET /api/v1/novel/3/ HTTP/1.1" 200 4585 +INFO 2023-06-19 19:01:03,951 autoreload 250 E:\workspace2\novel_api\novel_api\apps\chatbot\views.py changed, reloading. +INFO 2023-06-19 19:01:05,197 autoreload 636 Watching for file changes with StatReloader +INFO 2023-06-19 19:01:53,346 autoreload 636 Watching for file changes with StatReloader +INFO 2023-06-19 20:19:11,360 autoreload 636 Watching for file changes with StatReloader +INFO 2023-06-19 20:22:33,402 autoreload 250 E:\workspace2\novel_api\novel_api\apps\chatbot\models.py changed, reloading. +INFO 2023-06-19 20:22:34,776 autoreload 636 Watching for file changes with StatReloader +INFO 2023-06-20 09:49:08,375 autoreload 636 Watching for file changes with StatReloader +INFO 2023-06-20 09:49:12,969 basehttp 161 "GET /api/v1/novel/ HTTP/1.1" 200 1630 +INFO 2023-06-20 09:49:20,652 basehttp 161 "GET /api/v1/novel/ HTTP/1.1" 200 1630 +INFO 2023-06-20 09:49:24,123 basehttp 161 "GET /api/v1/novel/3/ HTTP/1.1" 200 4585 +INFO 2023-06-20 09:49:34,349 basehttp 161 "GET /api/v1/novel/2/ HTTP/1.1" 200 7304 +INFO 2023-06-20 11:06:30,018 autoreload 250 E:\workspace2\novel_api\novel_api\apps\chatbot\models.py changed, reloading. +INFO 2023-06-20 11:06:31,428 autoreload 636 Watching for file changes with StatReloader +INFO 2023-06-20 11:08:08,382 autoreload 636 Watching for file changes with StatReloader +INFO 2023-06-20 11:11:36,311 autoreload 250 E:\workspace2\novel_api\novel_api\apps\chatbot\views.py changed, reloading. +INFO 2023-06-20 11:11:37,420 autoreload 636 Watching for file changes with StatReloader +ERROR 2023-06-20 11:12:26,013 common_exceptions 16 用户:【匿名用户】,使用:【POST】 请求,请求:【/api/v1/chatbot/get_content/】 地址,视图函数是:【】,报错了,错误是:【ChatBotView.get_content..() got an unexpected keyword argument 'index'】 +INFO 2023-06-20 11:12:26,014 basehttp 161 "POST /api/v1/chatbot/get_content/ HTTP/1.1" 200 107 +INFO 2023-06-20 11:13:18,757 autoreload 250 E:\workspace2\novel_api\novel_api\apps\chatbot\views.py changed, reloading. +INFO 2023-06-20 11:13:20,116 autoreload 636 Watching for file changes with StatReloader +ERROR 2023-06-20 11:13:21,461 common_exceptions 16 用户:【匿名用户】,使用:【POST】 请求,请求:【/api/v1/chatbot/get_content/】 地址,视图函数是:【】,报错了,错误是:【获取 token 出错:】 +INFO 2023-06-20 11:13:21,461 basehttp 161 "POST /api/v1/chatbot/get_content/ HTTP/1.1" 200 41 +INFO 2023-06-20 11:14:14,111 autoreload 250 E:\workspace2\novel_api\novel_api\apps\chatbot\models.py changed, reloading. +INFO 2023-06-20 11:14:15,483 autoreload 636 Watching for file changes with StatReloader +ERROR 2023-06-20 11:14:17,302 common_exceptions 16 用户:【匿名用户】,使用:【POST】 请求,请求:【/api/v1/chatbot/get_content/】 地址,视图函数是:【】,报错了,错误是:【获取 token 出错:】 +INFO 2023-06-20 11:14:17,303 basehttp 161 "POST /api/v1/chatbot/get_content/ HTTP/1.1" 200 41 +INFO 2023-06-20 11:14:53,051 autoreload 250 E:\workspace2\novel_api\novel_api\apps\chatbot\views.py changed, reloading. +INFO 2023-06-20 11:14:54,492 autoreload 636 Watching for file changes with StatReloader +ERROR 2023-06-20 11:14:55,601 common_exceptions 16 用户:【匿名用户】,使用:【POST】 请求,请求:【/api/v1/chatbot/get_content/】 地址,视图函数是:【】,报错了,错误是:【获取 token 出错:The fields "{'now_time'}" do not exist on the document "Access_token_pool"】 +INFO 2023-06-20 11:14:55,602 basehttp 161 "POST /api/v1/chatbot/get_content/ HTTP/1.1" 200 119 +INFO 2023-06-20 11:15:52,482 autoreload 250 E:\workspace2\novel_api\novel_api\apps\chatbot\models.py changed, reloading. +INFO 2023-06-20 11:15:53,676 autoreload 636 Watching for file changes with StatReloader +ERROR 2023-06-20 11:15:54,013 common_exceptions 16 用户:【匿名用户】,使用:【POST】 请求,请求:【/api/v1/chatbot/get_content/】 地址,视图函数是:【】,报错了,错误是:【获取 token 出错:'str' object has no attribute 'access_token'】 +INFO 2023-06-20 11:15:54,014 basehttp 161 "POST /api/v1/chatbot/get_content/ HTTP/1.1" 200 85 +INFO 2023-06-20 11:16:35,201 autoreload 250 E:\workspace2\novel_api\novel_api\apps\chatbot\models.py changed, reloading. +ERROR 2023-06-20 11:16:35,483 common_exceptions 16 用户:【匿名用户】,使用:【POST】 请求,请求:【/api/v1/chatbot/get_content/】 地址,视图函数是:【】,报错了,错误是:【获取 token 出错:'str' object has no attribute 'access_token'】 +INFO 2023-06-20 11:16:35,483 basehttp 161 "POST /api/v1/chatbot/get_content/ HTTP/1.1" 200 85 +INFO 2023-06-20 11:16:38,454 autoreload 636 Watching for file changes with StatReloader +ERROR 2023-06-20 11:16:39,859 basehttp 161 "POST /api/v1/chatbot/get_content/ HTTP/1.1" 500 59 +INFO 2023-06-20 11:17:39,520 autoreload 250 E:\workspace2\novel_api\novel_api\apps\chatbot\models.py changed, reloading. +INFO 2023-06-20 11:17:40,770 autoreload 636 Watching for file changes with StatReloader +ERROR 2023-06-20 11:17:41,417 common_exceptions 16 用户:【匿名用户】,使用:【POST】 请求,请求:【/api/v1/chatbot/get_content/】 地址,视图函数是:【】,报错了,错误是:【获取 token 出错:'str' object has no attribute 'access_token'】 +INFO 2023-06-20 11:17:41,418 basehttp 161 "POST /api/v1/chatbot/get_content/ HTTP/1.1" 200 85 +ERROR 2023-06-20 11:17:43,743 common_exceptions 16 用户:【匿名用户】,使用:【POST】 请求,请求:【/api/v1/chatbot/get_content/】 地址,视图函数是:【】,报错了,错误是:【获取 token 出错:'str' object has no attribute 'access_token'】 +INFO 2023-06-20 11:17:43,743 basehttp 161 "POST /api/v1/chatbot/get_content/ HTTP/1.1" 200 85 +INFO 2023-06-20 11:17:50,462 autoreload 250 E:\workspace2\novel_api\novel_api\apps\chatbot\models.py changed, reloading. +ERROR 2023-06-20 11:17:50,502 common_exceptions 16 用户:【匿名用户】,使用:【POST】 请求,请求:【/api/v1/chatbot/get_content/】 地址,视图函数是:【】,报错了,错误是:【获取 token 出错:'str' object has no attribute 'access_token'】 +INFO 2023-06-20 11:17:50,503 basehttp 161 "POST /api/v1/chatbot/get_content/ HTTP/1.1" 200 85 +ERROR 2023-06-20 11:17:51,103 common_exceptions 16 用户:【匿名用户】,使用:【POST】 请求,请求:【/api/v1/chatbot/get_content/】 地址,视图函数是:【】,报错了,错误是:【获取 token 出错:'str' object has no attribute 'access_token'】 +INFO 2023-06-20 11:17:51,104 basehttp 161 "POST /api/v1/chatbot/get_content/ HTTP/1.1" 200 85 +ERROR 2023-06-20 11:17:51,854 common_exceptions 16 用户:【匿名用户】,使用:【POST】 请求,请求:【/api/v1/chatbot/get_content/】 地址,视图函数是:【】,报错了,错误是:【获取 token 出错:'str' object has no attribute 'access_token'】 +INFO 2023-06-20 11:17:51,855 basehttp 161 "POST /api/v1/chatbot/get_content/ HTTP/1.1" 200 85 +ERROR 2023-06-20 11:17:52,635 common_exceptions 16 用户:【匿名用户】,使用:【POST】 请求,请求:【/api/v1/chatbot/get_content/】 地址,视图函数是:【】,报错了,错误是:【获取 token 出错:'str' object has no attribute 'access_token'】 +INFO 2023-06-20 11:17:52,636 basehttp 161 "POST /api/v1/chatbot/get_content/ HTTP/1.1" 200 85 +INFO 2023-06-20 11:17:54,401 autoreload 636 Watching for file changes with StatReloader +INFO 2023-06-20 11:17:59,122 autoreload 636 Watching for file changes with StatReloader +ERROR 2023-06-20 11:18:01,741 basehttp 161 "POST /api/v1/chatbot/get_content/ HTTP/1.1" 500 59 +ERROR 2023-06-20 11:18:35,707 basehttp 161 "POST /api/v1/chatbot/get_content/ HTTP/1.1" 500 59 +ERROR 2023-06-20 11:19:24,737 basehttp 161 "POST /api/v1/chatbot/get_content/ HTTP/1.1" 500 59 +ERROR 2023-06-20 11:21:48,537 basehttp 161 "POST /api/v1/chatbot/get_content/ HTTP/1.1" 500 59 +INFO 2023-06-20 11:21:55,044 autoreload 636 Watching for file changes with StatReloader +ERROR 2023-06-20 11:21:57,768 basehttp 161 "POST /api/v1/chatbot/get_content/ HTTP/1.1" 500 59 +ERROR 2023-06-20 11:23:37,154 basehttp 161 "POST /api/v1/chatbot/get_content/ HTTP/1.1" 500 59 +ERROR 2023-06-20 11:23:39,331 basehttp 161 "POST /api/v1/chatbot/get_content/ HTTP/1.1" 500 59 +INFO 2023-06-20 11:23:45,345 autoreload 636 Watching for file changes with StatReloader +ERROR 2023-06-20 11:23:48,523 basehttp 161 "POST /api/v1/chatbot/get_content/ HTTP/1.1" 500 59 +ERROR 2023-06-20 11:24:50,606 basehttp 161 "POST /api/v1/chatbot/get_content/ HTTP/1.1" 500 59 +INFO 2023-06-20 11:24:58,297 autoreload 636 Watching for file changes with StatReloader +ERROR 2023-06-20 11:25:03,020 basehttp 161 "POST /api/v1/chatbot/get_content/ HTTP/1.1" 500 59 +INFO 2023-06-20 11:32:51,112 autoreload 250 E:\workspace2\novel_api\novel_api\apps\chatbot\views.py changed, reloading. +INFO 2023-06-20 11:32:53,139 autoreload 636 Watching for file changes with StatReloader +ERROR 2023-06-20 11:32:56,016 common_exceptions 16 用户:【匿名用户】,使用:【POST】 请求,请求:【/api/v1/chatbot/get_content/】 地址,视图函数是:【】,报错了,错误是:【'NoneType' object is not iterable】 +INFO 2023-06-20 11:32:56,016 basehttp 161 "POST /api/v1/chatbot/get_content/ HTTP/1.1" 200 54 +INFO 2023-06-20 11:33:47,142 autoreload 250 E:\workspace2\novel_api\novel_api\apps\chatbot\views.py changed, reloading. +INFO 2023-06-20 11:33:48,506 autoreload 636 Watching for file changes with StatReloader +ERROR 2023-06-20 11:33:48,765 common_exceptions 16 用户:【匿名用户】,使用:【POST】 请求,请求:【/api/v1/chatbot/get_content/】 地址,视图函数是:【】,报错了,错误是:【'NoneType' object is not iterable】 +INFO 2023-06-20 11:33:48,766 basehttp 161 "POST /api/v1/chatbot/get_content/ HTTP/1.1" 200 54 +ERROR 2023-06-20 11:33:49,613 common_exceptions 16 用户:【匿名用户】,使用:【POST】 请求,请求:【/api/v1/chatbot/get_content/】 地址,视图函数是:【】,报错了,错误是:【'NoneType' object is not iterable】 +INFO 2023-06-20 11:33:49,614 basehttp 161 "POST /api/v1/chatbot/get_content/ HTTP/1.1" 200 54 +ERROR 2023-06-20 11:33:50,223 common_exceptions 16 用户:【匿名用户】,使用:【POST】 请求,请求:【/api/v1/chatbot/get_content/】 地址,视图函数是:【】,报错了,错误是:【'NoneType' object is not iterable】 +INFO 2023-06-20 11:33:50,223 basehttp 161 "POST /api/v1/chatbot/get_content/ HTTP/1.1" 200 54 +ERROR 2023-06-20 11:33:50,764 common_exceptions 16 用户:【匿名用户】,使用:【POST】 请求,请求:【/api/v1/chatbot/get_content/】 地址,视图函数是:【】,报错了,错误是:【'NoneType' object is not iterable】 +INFO 2023-06-20 11:33:50,764 basehttp 161 "POST /api/v1/chatbot/get_content/ HTTP/1.1" 200 54 +ERROR 2023-06-20 11:33:54,090 common_exceptions 16 用户:【匿名用户】,使用:【POST】 请求,请求:【/api/v1/chatbot/get_content/】 地址,视图函数是:【】,报错了,错误是:【'NoneType' object is not iterable】 +INFO 2023-06-20 11:33:54,091 basehttp 161 "POST /api/v1/chatbot/get_content/ HTTP/1.1" 200 54 +INFO 2023-06-20 11:34:09,513 autoreload 250 E:\workspace2\novel_api\novel_api\apps\chatbot\views.py changed, reloading. +INFO 2023-06-20 11:34:10,836 autoreload 636 Watching for file changes with StatReloader +ERROR 2023-06-20 11:34:12,650 common_exceptions 16 用户:【匿名用户】,使用:【POST】 请求,请求:【/api/v1/chatbot/get_content/】 地址,视图函数是:【】,报错了,错误是:【'NoneType' object is not iterable】 +INFO 2023-06-20 11:34:12,651 basehttp 161 "POST /api/v1/chatbot/get_content/ HTTP/1.1" 200 54 +INFO 2023-06-20 11:34:23,705 autoreload 250 E:\workspace2\novel_api\novel_api\apps\chatbot\views.py changed, reloading. +INFO 2023-06-20 11:34:24,977 autoreload 636 Watching for file changes with StatReloader +ERROR 2023-06-20 11:34:25,928 basehttp 161 "POST /api/v1/chatbot/get_content/ HTTP/1.1" 500 59 +INFO 2023-06-20 11:34:42,966 autoreload 636 Watching for file changes with StatReloader +INFO 2023-06-20 11:34:58,512 basehttp 161 "POST /api/v1/chatbot/get_content/ HTTP/1.1" 200 387630 +INFO 2023-06-20 11:35:58,348 basehttp 161 "POST /api/v1/chatbot/get_summary/ HTTP/1.1" 200 643 +ERROR 2023-06-20 11:36:08,543 basehttp 161 "POST /api/v1/chatbot/get_content/ HTTP/1.1" 500 59 +INFO 2023-06-20 11:36:10,237 basehttp 161 "POST /api/v1/chatbot/get_question_and_option/ HTTP/1.1" 200 44071 +INFO 2023-06-20 11:38:47,058 autoreload 250 E:\workspace2\novel_api\novel_api\apps\chatbot\views.py changed, reloading. +INFO 2023-06-20 11:38:48,371 autoreload 636 Watching for file changes with StatReloader +INFO 2023-06-20 11:38:52,697 autoreload 250 E:\workspace2\novel_api\novel_api\apps\chatbot\views.py changed, reloading. +INFO 2023-06-20 11:38:53,714 autoreload 636 Watching for file changes with StatReloader +INFO 2023-06-20 11:41:45,987 autoreload 636 Watching for file changes with StatReloader +ERROR 2023-06-20 11:41:53,151 basehttp 161 "POST /api/v1/chatbot/get_content/ HTTP/1.1" 500 59 +INFO 2023-06-20 11:41:53,167 basehttp 161 "POST /api/v1/chatbot/get_question_and_option/ HTTP/1.1" 200 48310 +INFO 2023-06-20 11:43:10,862 autoreload 250 E:\workspace2\novel_api\novel_api\apps\chatbot\views.py changed, reloading. +INFO 2023-06-20 11:43:12,219 autoreload 636 Watching for file changes with StatReloader +ERROR 2023-06-20 11:43:14,014 basehttp 161 "POST /api/v1/chatbot/get_content/ HTTP/1.1" 500 59 +INFO 2023-06-20 11:43:24,455 autoreload 636 Watching for file changes with StatReloader +ERROR 2023-06-20 11:43:27,566 basehttp 161 "POST /api/v1/chatbot/get_content/ HTTP/1.1" 500 59 +INFO 2023-06-20 11:44:23,529 basehttp 161 "POST /api/v1/chatbot/get_content/ HTTP/1.1" 200 471072 +INFO 2023-06-20 11:44:52,225 basehttp 161 "POST /api/v1/chatbot/get_summary/ HTTP/1.1" 200 697 +INFO 2023-06-20 11:45:03,241 basehttp 161 "POST /api/v1/chatbot/get_question_and_option/ HTTP/1.1" 200 45250 +INFO 2023-06-20 11:46:11,742 autoreload 250 E:\workspace2\novel_api\novel_api\apps\chatbot\views.py changed, reloading. +INFO 2023-06-20 11:46:13,003 autoreload 636 Watching for file changes with StatReloader diff --git a/novel_api/apps/chatbot/models.py b/novel_api/apps/chatbot/models.py index ea0a0ce..ca39cb7 100644 --- a/novel_api/apps/chatbot/models.py +++ b/novel_api/apps/chatbot/models.py @@ -1,4 +1,5 @@ import mongoengine +import datetime class Memory(mongoengine.Document): @@ -8,7 +9,16 @@ class Memory(mongoengine.Document): class Access_token_pool(mongoengine.Document): access_token = mongoengine.StringField() - now_time = mongoengine.StringField() + now_time = mongoengine.DateTimeField() + + @classmethod + def get_oldest_token(cls): + current_time = datetime.datetime.now() + oldest_token = cls.objects.order_by('now_time').first() # 未取到不会报错 + if oldest_token: + oldest_token.now_time = current_time + oldest_token.save() + return oldest_token # 如果不存在会为None class User(mongoengine.Document): @@ -22,12 +32,8 @@ class Paragraph(mongoengine.Document): class Choice(mongoengine.Document): text = mongoengine.ListField() - - - - # "novel_id": 1, # "novel_title": "我对总裁大人有偏见", # "novel_image": "https://cn.bing.com/images/search?view=detailV2&ccid=Bq5jD730&id=E91F2971887D91E927CE16AB8F45BEB8C1185543&thid=OIP.Bq5jD730RoSsMF3c1yWIWwHaJ4&mediaurl=https%3A%2F%2Fstatic.zongheng.com%2Fupload%2Fcover%2Fshucheng%2F16%2F15416195.jpg&exph=3200&expw=2400&q=%e5%b0%8f%e8%af%b4%e5%9b%be%e7%89%87&simid=608000767812436123&form=IRPRST&ck=ADD7A0A91334D779ECBD217BF7F86F67&selectedindex=2&ajaxhist=0&ajaxserp=0&vt=0&sim=11", # "novel_tag": ["言情"], -# "novel_visit": '10.0万', \ No newline at end of file +# "novel_visit": '10.0万', diff --git a/novel_api/apps/chatbot/tests.py b/novel_api/apps/chatbot/tests.py index e69de29..cc4896c 100644 --- a/novel_api/apps/chatbot/tests.py +++ b/novel_api/apps/chatbot/tests.py @@ -0,0 +1,54 @@ +import datetime +import threading +from rest_framework.exceptions import APIException +from mongoengine import Document, StringField, DateTimeField, connect + +# 连接 MongoDB 数据库 +connect('your_database_name') + +class Access_token_pool(Document): + access_token = StringField() + now_time = DateTimeField() + + @classmethod + def create_tokens(cls, num_tokens): + current_time = datetime.datetime.now() + for i in range(num_tokens): + token = cls(access_token=str(i), now_time=current_time) + token.save() + + @classmethod + def get_oldest_token(cls): + current_time = datetime.datetime.now() + oldest_token = cls.objects.order_by('now_time').first() # 未取到不会报错 + print(oldest_token) + if oldest_token: + oldest_token.now_time = current_time + oldest_token.save() + return oldest_token # 如果不存在会为None + +# token_lock = threading.Lock() # 创建互斥锁 + +def concurrent_get_token(): + try: + # with token_lock: # 使用互斥锁 + oldest_token = Access_token_pool.get_oldest_token() + print(oldest_token.access_token) + return oldest_token + except Exception as e: + APIException("获取 token 出错:", str(e)) + + +# 创建测试数据 +# Access_token_pool.create_tokens(50) + +# 模拟并发获取 token +threads = [] +for _ in range(100): + thread = threading.Thread(target=concurrent_get_token) + threads.append(thread) + thread.start() + +# 等待所有线程完成 +for thread in threads: + thread.join() diff --git a/novel_api/apps/chatbot/views.py b/novel_api/apps/chatbot/views.py index fde9620..2baa4db 100644 --- a/novel_api/apps/chatbot/views.py +++ b/novel_api/apps/chatbot/views.py @@ -1,6 +1,3 @@ -import uuid -import time - from rest_framework.exceptions import APIException from rest_framework.viewsets import ViewSet from rest_framework.decorators import action @@ -9,43 +6,33 @@ from utils.common_response import APIResponse from .models import Access_token_pool, Paragraph, Choice +# token_lock = threading.Lock() # 注释掉这两行代码,就变成了不加锁的版本 -class User(object): - - def __init__(self): - self.user_id = str(uuid.uuid4()) +def concurrent_get_token(): + try: + # with token_lock: # 注释掉这两行代码,就变成了不加锁的版本 + oldest_token = Access_token_pool.get_oldest_token() + return oldest_token.access_token + except Exception as e: + raise APIException(f"获取 token 出错:{e}") def get_response_streaming(prompt): - """ - Args: - prompt:提示词 - access_token - - Returns:流式 - """ - acp_obj = Access_token_pool.objects[0] - access_token = acp_obj.access_token + access_token = concurrent_get_token() chatbot = Chatbot(config={ "access_token": access_token, "collect_analytics": True, - # 服务器挂代理 "proxy": "socks5h://127.0.0.1:1090" }) try: result = chatbot.ask(prompt) except Exception as e: - acp_obj.delete() - raise APIException('chatgpt报错') - acp_obj.delete() - Access_token_pool(access_token=access_token, now_time=str(time.time())).save() - # 存回来 + raise APIException("chatgpt报错:", str(e)) return result def get_response(prompt): # 这个是仅仅只有总结接口使用 不会返回流式输出 - acp_obj = Access_token_pool.objects[0] - access_token = acp_obj.access_token + access_token = concurrent_get_token() chatbot = Chatbot(config={ "access_token": access_token, "collect_analytics": True, @@ -57,10 +44,7 @@ def get_response(prompt): # 这个是仅仅只有总结接口使用 不会返 message = data["message"][len(prev_text):] prev_text = data["message"] except Exception as e: - acp_obj.delete() - raise APIException('chatgpt报错') - acp_obj.delete() - Access_token_pool(access_token=access_token, now_time=str(time.time())).save() + raise APIException("chatgpt报错:", str(e)) return prev_text @@ -79,9 +63,7 @@ def get_content(self, request, *args, **kwargs): 'long_memory': '', "index": request.data.get('index', '') } - del pre_data["index"] - prompt = lambda background, relationship, character, summary, content, question, choice, long_memory: f""" 现在你是一个经验丰富的写对话小说的网文作家,你需要续写这本小说,小说的大部分内容都是对话,注意你续写的只是小说的开头部分,发展要缓慢,续写应该停在突然的地方,比如话说到一半,人物动作做到一半 续写指的是接着小说的末尾创作出新的内容,创作出的新内容与小说之前的内容不矛盾,输出时不用将小说之前内容输出!!! diff --git a/novel_api/settings/dev.py b/novel_api/settings/dev.py index f59798c..a85e6b7 100644 --- a/novel_api/settings/dev.py +++ b/novel_api/settings/dev.py @@ -89,10 +89,14 @@ } # mongodb配置 -from mongoengine import connect -from urllib.parse import quote_plus +# from mongoengine import connect +# from urllib.parse import quote_plus +# +# connect('novel_api_h5', host="mongodb://%s:%s@%s" % (quote_plus("aiwaves"), quote_plus("bxzn2023"), "47.96.122.196")) -connect('novel_api_h5', host="mongodb://%s:%s@%s" % (quote_plus("aiwaves"), quote_plus("bxzn2023"), "47.96.122.196")) +from mongoengine import connect +# 连接 MongoDB 数据库 +connect('your_database_name') # Password validation # https://docs.djangoproject.com/en/4.2/ref/settings/#auth-password-validators diff --git a/script/add_lock.py b/script/add_lock.py new file mode 100644 index 0000000..14ee2ec --- /dev/null +++ b/script/add_lock.py @@ -0,0 +1,63 @@ +import datetime +import threading +from rest_framework.exceptions import APIException +from mongoengine import Document, StringField, DateTimeField, connect + +# 连接本地 MongoDB 数据库 +connect('your_database_name') + +# # 连接远程 MongoDB 数据库 +# from mongoengine import connect +# from urllib.parse import quote_plus +# +# connect('novel_api_h5', host="mongodb://%s:%s@%s" % (quote_plus("aiwaves"), quote_plus("bxzn2023"), "47.96.122.196")) + + +class Access_token_pool(Document): + access_token = StringField() + now_time = DateTimeField() + + # @classmethod + # def create_tokens(cls, num_tokens): + # current_time = datetime.datetime.now() + # for i in range(num_tokens): + # token = cls(access_token=str(i), now_time=current_time) + # token.save() + + @classmethod + def get_oldest_token(cls): + current_time = datetime.datetime.now() + oldest_token = cls.objects.order_by('now_time').first() # 未取到不会报错 + print(oldest_token.access_token) + if oldest_token: + oldest_token.now_time = current_time + oldest_token.save() + return oldest_token # 如果不存在会为None + + + +# token_lock = threading.Lock() # 注释掉这两行代码,就变成了不加锁的版本 + +def concurrent_get_token(): + try: + # with token_lock: # 注释掉这两行代码,就变成了不加锁的版本 + oldest_token = Access_token_pool.get_oldest_token() + print(oldest_token.access_token) + return oldest_token + except Exception as e: + APIException("获取 token 出错:", str(e)) + + +# 创建测试数据 +# Access_token_pool.create_tokens(50) + +# 模拟并发获取 token +threads = [] +for _ in range(100): + thread = threading.Thread(target=concurrent_get_token) + threads.append(thread) + thread.start() + +# 等待所有线程完成 +for thread in threads: + thread.join() diff --git a/script/add_token.py b/script/add_token.py new file mode 100644 index 0000000..3ad5520 --- /dev/null +++ b/script/add_token.py @@ -0,0 +1,28 @@ +from mongoengine import Document, StringField, DateTimeField, connect +import datetime + +# 当前时间 +current_time = datetime.datetime.now() + +# 连接本地 MongoDB 数据库 +connect('your_database_name') + + +# # 连接远程 MongoDB 数据库 +# from mongoengine import connect +# from urllib.parse import quote_plus +# +# connect('novel_api_h5', host="mongodb://%s:%s@%s" % (quote_plus("aiwaves"), quote_plus("bxzn2023"), "47.96.122.196")) + +class Access_token_pool(Document): + access_token = StringField() + now_time = DateTimeField() + + +access_token = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6Ik1UaEVOVUpHTkVNMVFURTRNMEZCTWpkQ05UZzVNRFUxUlRVd1FVSkRNRU13UmtGRVFrRXpSZyJ9.eyJodHRwczovL2FwaS5vcGVuYWkuY29tL3Byb2ZpbGUiOnsiZW1haWwiOiJqaWF0a2IwNjU2QHdlcC5lbWFpbCIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlfSwiaHR0cHM6Ly9hcGkub3BlbmFpLmNvbS9hdXRoIjp7InVzZXJfaWQiOiJ1c2VyLWdGV3RRS2QxYkJuWmNsbWgzeXdrNllzSCJ9LCJpc3MiOiJodHRwczovL2F1dGgwLm9wZW5haS5jb20vIiwic3ViIjoiYXV0aDB8NjQ0YTFiMmUxZGVjOGQyZWRhOGQxZmU0IiwiYXVkIjpbImh0dHBzOi8vYXBpLm9wZW5haS5jb20vdjEiLCJodHRwczovL29wZW5haS5vcGVuYWkuYXV0aDBhcHAuY29tL3VzZXJpbmZvIl0sImlhdCI6MTY4NjExMDMzNywiZXhwIjoxNjg3MzE5OTM3LCJhenAiOiJUZEpJY2JlMTZXb1RIdE45NW55eXdoNUU0eU9vNkl0RyIsInNjb3BlIjoib3BlbmlkIHByb2ZpbGUgZW1haWwgbW9kZWwucmVhZCBtb2RlbC5yZXF1ZXN0IG9yZ2FuaXphdGlvbi5yZWFkIG9yZ2FuaXphdGlvbi53cml0ZSJ9.0fI-3RYbF1eg_kRzE3Q3QYNGa6kgOgsaPvt4m9HREjRkYFKWGVP3lBWxGQkG3553imEr2vZjETn4hyHFGj-LLYg1XpLpa-_zvhjITyzzT4flUZijFp6tzZg185WIySeXrmoKmZTxL7ij1LF1Un6Y2IRPSIbvOvugr5wWvrPZtZD0xHcgmzmj-A1xJytjM7zhdlKtaJiK_VyeR6wlTv5fLdjPWxU5nutmxSnaV6i9drR9g8HCMk2_mtckyS_zAUJIW2KQVZ81d0OFijL2aiaQiaSOtNiV2jKRr0jrm9lysUkvKDwszQMGtOZXhPR2KMWEr_nLHZpryBJdYPf3yF8E7A" +# Access_token_pool(access_token=access_token,now_time=current_time).save() + + +token_obj = Access_token_pool.objects.first() +token_obj.access_token = access_token +token_obj.save() \ No newline at end of file diff --git a/settings.py b/settings.py deleted file mode 100644 index 555e90a..0000000 --- a/settings.py +++ /dev/null @@ -1,225 +0,0 @@ -""" -Django settings for novel_api project. - -Generated by 'django-admin startproject' using Django 4.2.2. - -For more information on this file, see -https://docs.djangoproject.com/en/4.2/topics/settings/ - -For the full list of settings and their values, see -https://docs.djangoproject.com/en/4.2/ref/settings/ -""" -import os -import sys -from pathlib import Path - -# Build paths inside the project like this: BASE_DIR / 'subdir'. -BASE_DIR = Path(__file__).resolve().parent.parent -sys.path.append(str(BASE_DIR)) # 导入小项目路径 -sys.path.append(os.path.join(BASE_DIR, 'apps')) # 导入app路径 -# Quick-start development settings - unsuitable for production -# See https://docs.djangoproject.com/en/4.2/howto/deployment/checklist/ - -# SECURITY WARNING: keep the secret key used in production secret! -SECRET_KEY = 'django-insecure-fw()pe=&#w&_p_uf*+27pg9ma4-oazvg1*^s@=az4#h(6hatb*' - -# SECURITY WARNING: don't run with debug turned on in production! -DEBUG = False - -ALLOWED_HOSTS = ["*"] - -# Application definition - -INSTALLED_APPS = [ - 'django.contrib.admin', - 'django.contrib.auth', - 'django.contrib.contenttypes', - 'django.contrib.sessions', - 'django.contrib.messages', - 'django.contrib.staticfiles', - 'corsheaders', - 'novel' -] - -MIDDLEWARE = [ - 'django.middleware.security.SecurityMiddleware', - 'django.contrib.sessions.middleware.SessionMiddleware', - 'django.middleware.common.CommonMiddleware', - 'django.middleware.csrf.CsrfViewMiddleware', - 'django.contrib.auth.middleware.AuthenticationMiddleware', - 'django.contrib.messages.middleware.MessageMiddleware', - 'django.middleware.clickjacking.XFrameOptionsMiddleware', - 'corsheaders.middleware.CorsMiddleware', # 跨域中间件 -] - -ROOT_URLCONF = 'novel_api.urls' - -TEMPLATES = [ - { - 'BACKEND': 'django.template.backends.django.DjangoTemplates', - 'DIRS': [BASE_DIR / 'templates'] - , - 'APP_DIRS': True, - 'OPTIONS': { - 'context_processors': [ - 'django.template.context_processors.debug', - 'django.template.context_processors.request', - 'django.contrib.auth.context_processors.auth', - 'django.contrib.messages.context_processors.messages', - ], - }, - }, -] - -WSGI_APPLICATION = 'novel_api.wsgi.application' - -# Database -# https://docs.djangoproject.com/en/4.2/ref/settings/#databases - -# 数据库相关配置 -# name = os.environ.get('LUFFY_NAME', 'luffy') -# password = os.environ.get('LUFFY_PASSWORD', 'Luffy123?') - -DATABASES = { - 'default': { - # 下面两个其中都可以 - # 'ENGINE': 'None', - 'ENGINE': 'django.db.backends.dummy', - } -} - -# mongodb配置 -from mongoengine import connect -from urllib.parse import quote_plus -connect('dev_test', host="mongodb://%s:%s@%s" % (quote_plus("aiwaves"), quote_plus("bxzn2023"), "47.96.122.196")) - - -# Password validation -# https://docs.djangoproject.com/en/4.2/ref/settings/#auth-password-validators - -AUTH_PASSWORD_VALIDATORS = [ - { - 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', - }, - { - 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', - }, - { - 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', - }, - { - 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', - }, -] - -# Internationalization -# https://docs.djangoproject.com/en/4.2/topics/i18n/ - -LANGUAGE_CODE = 'en-us' - -TIME_ZONE = 'UTC' - -USE_I18N = True - -USE_TZ = True - -# Static files (CSS, JavaScript, Images) -# https://docs.djangoproject.com/en/4.2/howto/static-files/ - -STATIC_URL = 'static/' - -# Default primary key field type -# https://docs.djangoproject.com/en/4.2/ref/settings/#default-auto-field - -DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' - - -from mongoengine import connect -from urllib.parse import quote_plus - -connect('dev_test', host="mongodb://%s:%s@%s" % (quote_plus("aiwaves"), quote_plus("bxzn2023"), "47.96.122.196")) - - - -# 跨域配置 -CORS_ORIGIN_ALLOW_ALL = True -CORS_ALLOW_METHODS = ( - 'DELETE', - 'GET', - 'OPTIONS', - 'PATCH', - 'POST', - 'PUT', - 'VIEW', -) - -CORS_ALLOW_HEADERS = ( - 'XMLHttpRequest', - 'X_FILENAME', - 'accept-encoding', - 'authorization', - 'content-type', - 'dnt', - 'origin', - 'user-agent', - 'x-csrftoken', - 'x-requested-with', - 'Pragma', - 'token' -) - -# drf配置 -REST_FRAMEWORK = { - # 全局异常配置 - 'EXCEPTION_HANDLER': 'utils.common_exceptions.exception_handler', -} - -# 日志配置 -LOGGING = { - 'version': 1, - 'disable_existing_loggers': False, - 'formatters': { - 'verbose': { - 'format': '%(levelname)s %(asctime)s %(module)s %(lineno)d %(message)s' - }, - 'simple': { - 'format': '%(levelname)s %(module)s %(lineno)d %(message)s' - }, - }, - 'filters': { - 'require_debug_true': { - '()': 'django.utils.log.RequireDebugTrue', - }, - }, - 'handlers': { - 'console': { - # 实际开发建议使用WARNING - 'level': 'DEBUG', - 'filters': ['require_debug_true'], - 'class': 'logging.StreamHandler', - 'formatter': 'simple' - }, - 'file': { - # 实际开发建议使用ERROR - 'level': 'INFO', - 'class': 'logging.handlers.RotatingFileHandler', - # 日志位置,日志文件名,日志保存目录必须手动创建,注:这里的文件路径要注意BASE_DIR代表的是小名 - 'filename': os.path.join(BASE_DIR, "logs", "novel_api.log"), # 这里需要根据路径调整 - # 日志文件的最大值,这里我们设置300M - 'maxBytes': 300 * 1024 * 1024, - # 日志文件的数量,设置最大日志数量为10 - 'backupCount': 10, - # 日志格式:详细格式 - 'formatter': 'verbose', - # 文件内容编码 - 'encoding': 'utf-8' - }, - }, - # 日志对象 - 'loggers': { - 'django': { - 'handlers': ['console', 'file'], - 'propagate': True, # 是否让日志信息继续冒泡给其他的日志处理系统 - }, - } -}