Update app.py
Browse files
app.py
CHANGED
@@ -571,6 +571,335 @@
|
|
571 |
# cleanup_thread.start()
|
572 |
|
573 |
# # 启动Flask应用
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
574 |
# app.run(host='0.0.0.0', port=7860, debug=True)
|
575 |
#!/usr/bin/env python
|
576 |
# -*- coding: utf-8 -*-
|
@@ -768,7 +1097,7 @@ def handle_async_task(session, task_id, messages):
|
|
768 |
|
769 |
def generate_initial_response():
|
770 |
"""生成初始响应消息"""
|
771 |
-
return "
|
772 |
|
773 |
def split_message(message, max_length=500):
|
774 |
"""将长消息分段"""
|
@@ -776,6 +1105,9 @@ def split_message(message, max_length=500):
|
|
776 |
|
777 |
def append_status_message(content, has_pending_parts=False, is_processing=False):
|
778 |
"""添加状态提示信息"""
|
|
|
|
|
|
|
779 |
status_message = "\n\n-------------------"
|
780 |
if is_processing:
|
781 |
status_message += "\n请回复'查询'获取结果"
|
|
|
571 |
# cleanup_thread.start()
|
572 |
|
573 |
# # 启动Flask应用
|
574 |
+
# app.run(host='0.0.0.0', port=7860, debug=True)
|
575 |
+
# #!/usr/bin/env python
|
576 |
+
# # -*- coding: utf-8 -*-
|
577 |
+
# from flask import Flask, request, make_response
|
578 |
+
# import hashlib
|
579 |
+
# import time
|
580 |
+
# import xml.etree.ElementTree as ET
|
581 |
+
# import os
|
582 |
+
# import json
|
583 |
+
# from openai import OpenAI
|
584 |
+
# from dotenv import load_dotenv
|
585 |
+
# from markdown import markdown
|
586 |
+
# import re
|
587 |
+
# import threading
|
588 |
+
# import logging
|
589 |
+
# from datetime import datetime
|
590 |
+
# import asyncio
|
591 |
+
# from concurrent.futures import ThreadPoolExecutor
|
592 |
+
# import queue
|
593 |
+
# import uuid
|
594 |
+
|
595 |
+
# # 配置日志记录
|
596 |
+
# logging.basicConfig(
|
597 |
+
# level=logging.INFO,
|
598 |
+
# format='%(asctime)s - %(levelname)s - %(message)s',
|
599 |
+
# handlers=[
|
600 |
+
# logging.FileHandler('wechat_service.log'),
|
601 |
+
# logging.StreamHandler()
|
602 |
+
# ]
|
603 |
+
# )
|
604 |
+
|
605 |
+
# # 加载环境变量
|
606 |
+
# load_dotenv()
|
607 |
+
|
608 |
+
# app = Flask(__name__)
|
609 |
+
|
610 |
+
# # 基础配置
|
611 |
+
# TOKEN = os.getenv('TOKEN')
|
612 |
+
# API_KEY = os.getenv("API_KEY")
|
613 |
+
# BASE_URL = os.getenv("OPENAI_BASE_URL")
|
614 |
+
# client = OpenAI(api_key=API_KEY, base_url=BASE_URL)
|
615 |
+
|
616 |
+
# # 创建线程池
|
617 |
+
# executor = ThreadPoolExecutor(max_workers=10)
|
618 |
+
|
619 |
+
# def convert_markdown_to_wechat(md_text):
|
620 |
+
# """将Markdown转换为微信友好的文本格式"""
|
621 |
+
# if not md_text:
|
622 |
+
# return md_text
|
623 |
+
|
624 |
+
# # 处理标题
|
625 |
+
# md_text = re.sub(r'^# (.*?)$', r'【标题】\1', md_text, flags=re.MULTILINE)
|
626 |
+
# md_text = re.sub(r'^## (.*?)$', r'【子标题】\1', md_text, flags=re.MULTILINE)
|
627 |
+
# md_text = re.sub(r'^### (.*?)$', r'【小标题】\1', md_text, flags=re.MULTILINE)
|
628 |
+
|
629 |
+
# # 处理强调语法
|
630 |
+
# md_text = re.sub(r'\*\*(.*?)\*\*', r'『\1』', md_text) # 粗体
|
631 |
+
# md_text = re.sub(r'\*(.*?)\*', r'「\1」', md_text) # 斜体
|
632 |
+
# md_text = re.sub(r'`(.*?)`', r'「\1」', md_text) # 行内代码
|
633 |
+
|
634 |
+
# # 处理列表
|
635 |
+
# md_text = re.sub(r'^\- ', '• ', md_text, flags=re.MULTILINE) # 无序列表
|
636 |
+
# md_text = re.sub(r'^\d\. ', '○ ', md_text, flags=re.MULTILINE) # 有序列表
|
637 |
+
|
638 |
+
# # 处理代码块
|
639 |
+
# md_text = re.sub(r'```[\w]*\n(.*?)```', r'【代码开始】\n\1\n【代码结束】', md_text, flags=re.DOTALL)
|
640 |
+
|
641 |
+
# # 处理引用
|
642 |
+
# md_text = re.sub(r'^> (.*?)$', r'▎\1', md_text, flags=re.MULTILINE)
|
643 |
+
|
644 |
+
# # 处理分隔线
|
645 |
+
# md_text = re.sub(r'^-{3,}$', r'—————————', md_text, flags=re.MULTILINE)
|
646 |
+
|
647 |
+
# # 处理链接
|
648 |
+
# md_text = re.sub(r'\[(.*?)\]\((.*?)\)', r'\1(\2)', md_text)
|
649 |
+
|
650 |
+
# # 净化处理:去除多余的空行
|
651 |
+
# md_text = re.sub(r'\n{3,}', '\n\n', md_text)
|
652 |
+
|
653 |
+
# return md_text
|
654 |
+
|
655 |
+
# class AsyncResponse:
|
656 |
+
# def __init__(self):
|
657 |
+
# self.status = "processing" # processing, completed, failed
|
658 |
+
# self.result = None
|
659 |
+
# self.error = None
|
660 |
+
|
661 |
+
# class UserSession:
|
662 |
+
# def __init__(self):
|
663 |
+
# self.messages = [{"role": "system", "content": "You are a helpful assistant."}]
|
664 |
+
# self.pending_parts = []
|
665 |
+
# self.last_active = time.time()
|
666 |
+
# self.current_task = None
|
667 |
+
# self.response_queue = {}
|
668 |
+
|
669 |
+
# class SessionManager:
|
670 |
+
# def __init__(self):
|
671 |
+
# self.sessions = {}
|
672 |
+
# self.session_timeout = 3600
|
673 |
+
# self._lock = threading.Lock()
|
674 |
+
|
675 |
+
# def get_session(self, user_id):
|
676 |
+
# with self._lock:
|
677 |
+
# if user_id not in self.sessions:
|
678 |
+
# self.sessions[user_id] = UserSession()
|
679 |
+
# session = self.sessions[user_id]
|
680 |
+
# session.last_active = time.time()
|
681 |
+
# return session
|
682 |
+
|
683 |
+
# def clear_session(self, user_id):
|
684 |
+
# with self._lock:
|
685 |
+
# if user_id in self.sessions:
|
686 |
+
# self.sessions[user_id] = UserSession()
|
687 |
+
|
688 |
+
# def cleanup_expired_sessions(self):
|
689 |
+
# with self._lock:
|
690 |
+
# current_time = time.time()
|
691 |
+
# expired_users = [
|
692 |
+
# user_id for user_id, session in self.sessions.items()
|
693 |
+
# if current_time - session.last_active > self.session_timeout
|
694 |
+
# ]
|
695 |
+
# for user_id in expired_users:
|
696 |
+
# del self.sessions[user_id]
|
697 |
+
# logging.info(f"已清理过期会话: {user_id}")
|
698 |
+
|
699 |
+
# session_manager = SessionManager()
|
700 |
+
|
701 |
+
# def verify_wechat(request):
|
702 |
+
# """验证微信服务器请求"""
|
703 |
+
# data = request.args
|
704 |
+
# signature = data.get('signature')
|
705 |
+
# timestamp = data.get('timestamp')
|
706 |
+
# nonce = data.get('nonce')
|
707 |
+
# echostr = data.get('echostr')
|
708 |
+
|
709 |
+
# temp = [timestamp, nonce, TOKEN]
|
710 |
+
# temp.sort()
|
711 |
+
# temp = ''.join(temp)
|
712 |
+
|
713 |
+
# if hashlib.sha1(temp.encode('utf8')).hexdigest() == signature:
|
714 |
+
# return echostr
|
715 |
+
# return 'error', 403
|
716 |
+
|
717 |
+
# def parse_xml_message(xml_content):
|
718 |
+
# """解析微信XML消息"""
|
719 |
+
# root = ET.fromstring(xml_content)
|
720 |
+
# return {
|
721 |
+
# 'content': root.find('Content').text,
|
722 |
+
# 'from_user': root.find('FromUserName').text,
|
723 |
+
# 'to_user': root.find('ToUserName').text,
|
724 |
+
# 'msg_id': root.find('MsgId').text,
|
725 |
+
# 'create_time': root.find('CreateTime').text
|
726 |
+
# }
|
727 |
+
|
728 |
+
# def generate_response_xml(to_user, from_user, content):
|
729 |
+
# """生成回复的XML消息"""
|
730 |
+
# formatted_content = convert_markdown_to_wechat(content)
|
731 |
+
# xml_template = '''
|
732 |
+
# <xml>
|
733 |
+
# <ToUserName><![CDATA[%s]]></ToUserName>
|
734 |
+
# <FromUserName><![CDATA[%s]]></FromUserName>
|
735 |
+
# <CreateTime>%s</CreateTime>
|
736 |
+
# <MsgType><![CDATA[text]]></MsgType>
|
737 |
+
# <Content><![CDATA[%s]]></Content>
|
738 |
+
# </xml>
|
739 |
+
# '''
|
740 |
+
# response = make_response(
|
741 |
+
# xml_template % (to_user, from_user, str(int(time.time())), formatted_content)
|
742 |
+
# )
|
743 |
+
# response.content_type = 'application/xml'
|
744 |
+
# return response
|
745 |
+
|
746 |
+
# def process_long_running_task(messages):
|
747 |
+
# """处理耗时任务"""
|
748 |
+
# try:
|
749 |
+
# response = client.chat.completions.create(
|
750 |
+
# model="gpt-4o-mini",
|
751 |
+
# messages=messages,
|
752 |
+
# timeout=60
|
753 |
+
# )
|
754 |
+
# return response.choices[0].message.content
|
755 |
+
# except Exception as e:
|
756 |
+
# logging.error(f"API调用错误: {str(e)}")
|
757 |
+
# raise
|
758 |
+
|
759 |
+
# def handle_async_task(session, task_id, messages):
|
760 |
+
# """异步任务处理函数"""
|
761 |
+
# try:
|
762 |
+
# result = process_long_running_task(messages)
|
763 |
+
# session.response_queue[task_id].status = "completed"
|
764 |
+
# session.response_queue[task_id].result = result
|
765 |
+
# except Exception as e:
|
766 |
+
# session.response_queue[task_id].status = "failed"
|
767 |
+
# session.response_queue[task_id].error = str(e)
|
768 |
+
|
769 |
+
# def generate_initial_response():
|
770 |
+
# """生成初始响应消息"""
|
771 |
+
# return "您的请求正在处理中"
|
772 |
+
|
773 |
+
# def split_message(message, max_length=500):
|
774 |
+
# """将长消息分段"""
|
775 |
+
# return [message[i:i+max_length] for i in range(0, len(message), max_length)]
|
776 |
+
|
777 |
+
# def append_status_message(content, has_pending_parts=False, is_processing=False):
|
778 |
+
# """添加状态提示信息"""
|
779 |
+
# status_message = "\n\n-------------------"
|
780 |
+
# if is_processing:
|
781 |
+
# status_message += "\n请回复'查询'获取结果"
|
782 |
+
# elif has_pending_parts:
|
783 |
+
# status_message += "\n当前消息已截断,发送'继续'查看后续内容"
|
784 |
+
# status_message += "\n发送'新对话'开始新的对话"
|
785 |
+
# return content + status_message
|
786 |
+
|
787 |
+
# @app.route('/api/wx', methods=['GET', 'POST'])
|
788 |
+
# def wechatai():
|
789 |
+
# if request.method == 'GET':
|
790 |
+
# return verify_wechat(request)
|
791 |
+
|
792 |
+
# try:
|
793 |
+
# message_data = parse_xml_message(request.data)
|
794 |
+
# user_content = message_data['content'].strip()
|
795 |
+
# from_user = message_data['from_user']
|
796 |
+
# to_user = message_data['to_user']
|
797 |
+
|
798 |
+
# logging.info(f"收到用户({from_user})消息: {user_content}")
|
799 |
+
# session = session_manager.get_session(from_user)
|
800 |
+
|
801 |
+
# if user_content == '新对话':
|
802 |
+
# session_manager.clear_session(from_user)
|
803 |
+
# return generate_response_xml(
|
804 |
+
# from_user,
|
805 |
+
# to_user,
|
806 |
+
# append_status_message('已开始新的对话。请描述您的问题。')
|
807 |
+
# )
|
808 |
+
|
809 |
+
# if user_content == '继续':
|
810 |
+
# if session.pending_parts:
|
811 |
+
# next_part = session.pending_parts.pop(0)
|
812 |
+
# has_more = bool(session.pending_parts)
|
813 |
+
# return generate_response_xml(
|
814 |
+
# from_user,
|
815 |
+
# to_user,
|
816 |
+
# append_status_message(next_part, has_more)
|
817 |
+
# )
|
818 |
+
# return generate_response_xml(
|
819 |
+
# from_user,
|
820 |
+
# to_user,
|
821 |
+
# append_status_message('没有更多内容了。请继续您的问题。')
|
822 |
+
# )
|
823 |
+
|
824 |
+
# if user_content == '查询':
|
825 |
+
# if session.current_task:
|
826 |
+
# task_response = session.response_queue.get(session.current_task)
|
827 |
+
# if task_response:
|
828 |
+
# if task_response.status == "completed":
|
829 |
+
# response = task_response.result
|
830 |
+
# del session.response_queue[session.current_task]
|
831 |
+
# session.current_task = None
|
832 |
+
|
833 |
+
# if len(response) > 500:
|
834 |
+
# parts = split_message(response)
|
835 |
+
# first_part = parts.pop(0)
|
836 |
+
# session.pending_parts = parts
|
837 |
+
# return generate_response_xml(
|
838 |
+
# from_user,
|
839 |
+
# to_user,
|
840 |
+
# append_status_message(first_part, True)
|
841 |
+
# )
|
842 |
+
# return generate_response_xml(
|
843 |
+
# from_user,
|
844 |
+
# to_user,
|
845 |
+
# append_status_message(response)
|
846 |
+
# )
|
847 |
+
# elif task_response.status == "failed":
|
848 |
+
# error_message = '处理过程中出现错误,请重新提问。'
|
849 |
+
# del session.response_queue[session.current_task]
|
850 |
+
# session.current_task = None
|
851 |
+
# return generate_response_xml(
|
852 |
+
# from_user,
|
853 |
+
# to_user,
|
854 |
+
# append_status_message(error_message)
|
855 |
+
# )
|
856 |
+
# else:
|
857 |
+
# return generate_response_xml(
|
858 |
+
# from_user,
|
859 |
+
# to_user,
|
860 |
+
# append_status_message('正在处理中,请稍后再次查询。', is_processing=True)
|
861 |
+
# )
|
862 |
+
# return generate_response_xml(
|
863 |
+
# from_user,
|
864 |
+
# to_user,
|
865 |
+
# append_status_message('没有正在处理的请求。')
|
866 |
+
# )
|
867 |
+
|
868 |
+
# session.messages.append({"role": "user", "content": user_content})
|
869 |
+
|
870 |
+
# task_id = str(uuid.uuid4())
|
871 |
+
# session.current_task = task_id
|
872 |
+
# session.response_queue[task_id] = AsyncResponse()
|
873 |
+
|
874 |
+
# executor.submit(handle_async_task, session, task_id, session.messages.copy())
|
875 |
+
|
876 |
+
# return generate_response_xml(
|
877 |
+
# from_user,
|
878 |
+
# to_user,
|
879 |
+
# append_status_message(generate_initial_response(), is_processing=True)
|
880 |
+
# )
|
881 |
+
|
882 |
+
# except Exception as e:
|
883 |
+
# logging.error(f"处理请求时出错: {str(e)}")
|
884 |
+
# return generate_response_xml(
|
885 |
+
# message_data['from_user'],
|
886 |
+
# message_data['to_user'],
|
887 |
+
# append_status_message('抱歉,系统暂时出现问题,请稍后重试。')
|
888 |
+
# )
|
889 |
+
|
890 |
+
# def cleanup_sessions():
|
891 |
+
# """定期清理过期会话"""
|
892 |
+
# while True:
|
893 |
+
# time.sleep(3600)
|
894 |
+
# try:
|
895 |
+
# session_manager.cleanup_expired_sessions()
|
896 |
+
# except Exception as e:
|
897 |
+
# logging.error(f"清理会话时出错: {str(e)}")
|
898 |
+
|
899 |
+
# if __name__ == '__main__':
|
900 |
+
# cleanup_thread = threading.Thread(target=cleanup_sessions, daemon=True)
|
901 |
+
# cleanup_thread.start()
|
902 |
+
|
903 |
# app.run(host='0.0.0.0', port=7860, debug=True)
|
904 |
#!/usr/bin/env python
|
905 |
# -*- coding: utf-8 -*-
|
|
|
1097 |
|
1098 |
def generate_initial_response():
|
1099 |
"""生成初始响应消息"""
|
1100 |
+
return "您的请求正在处理中,请回复'查询'获取结果"
|
1101 |
|
1102 |
def split_message(message, max_length=500):
|
1103 |
"""将长消息分段"""
|
|
|
1105 |
|
1106 |
def append_status_message(content, has_pending_parts=False, is_processing=False):
|
1107 |
"""添加状态提示信息"""
|
1108 |
+
if "您的请求正在处理中" in content:
|
1109 |
+
return content + "\n\n-------------------\n发送'新对话'开始新的对话"
|
1110 |
+
|
1111 |
status_message = "\n\n-------------------"
|
1112 |
if is_processing:
|
1113 |
status_message += "\n请回复'查询'获取结果"
|