union-app-chat-stream 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.gitignore +16 -0
- package/PROJECT_OVERVIEW.md +187 -0
- package/app/.env +63 -0
- package/app/.env.dev +63 -0
- package/app/.env.prod.bj11 +63 -0
- package/app/.env.prod.sh20 +63 -0
- package/app/.env.prod.sz31 +63 -0
- package/app/.env.test.bj12 +63 -0
- package/app/__init__.py +42 -0
- package/app/__pycache__/__init__.cpython-312.pyc +0 -0
- package/app/__pycache__/authenticated_user.cpython-312.pyc +0 -0
- package/app/__pycache__/extensions.cpython-312.pyc +0 -0
- package/app/__pycache__/wsgi.cpython-312.pyc +0 -0
- package/app/authenticated_user.py +77 -0
- package/app/config/__pycache__/config_loader.cpython-312.pyc +0 -0
- package/app/config/__pycache__/env_config.cpython-312.pyc +0 -0
- package/app/config/__pycache__/logger_config.cpython-312.pyc +0 -0
- package/app/config/env_config.py +96 -0
- package/app/config/logger_config.py +46 -0
- package/app/manager/__init__.py +4 -0
- package/app/manager/__pycache__/__init__.cpython-312.pyc +0 -0
- package/app/manager/__pycache__/chatstream_manager.cpython-312.pyc +0 -0
- package/app/manager/__pycache__/prompts.cpython-312.pyc +0 -0
- package/app/manager/__pycache__/runtime_manager.cpython-312.pyc +0 -0
- package/app/manager/__pycache__/toolcall_manager.cpython-312.pyc +0 -0
- package/app/manager/chatstream_manager.py +90 -0
- package/app/manager/prompts.py +62 -0
- package/app/manager/runtime_manager.py +552 -0
- package/app/models/__pycache__/schemas.cpython-312.pyc +0 -0
- package/app/models/schemas.py +30 -0
- package/app/service/__init__.py +4 -0
- package/app/service/__pycache__/__init__.cpython-312.pyc +0 -0
- package/app/service/__pycache__/chat_service.cpython-312.pyc +0 -0
- package/app/service/__pycache__/llm_service.cpython-312.pyc +0 -0
- package/app/service/__pycache__/rag_service.cpython-312.pyc +0 -0
- package/app/service/__pycache__/tool_call_service.cpython-312.pyc +0 -0
- package/app/service/__pycache__/union_service.cpython-312.pyc +0 -0
- package/app/service/chat_service.py +228 -0
- package/app/service/llm_service.py +214 -0
- package/app/service/rag_service.py +866 -0
- package/app/service/union_service.py +201 -0
- package/app/utils/__init__.py +5 -0
- package/app/utils/__pycache__/__init__.cpython-312.pyc +0 -0
- package/app/utils/__pycache__/common_utils.cpython-312.pyc +0 -0
- package/app/utils/__pycache__/debug_context.cpython-312.pyc +0 -0
- package/app/utils/__pycache__/function_utils.cpython-312.pyc +0 -0
- package/app/utils/__pycache__/jwt_utils.cpython-312.pyc +0 -0
- package/app/utils/common_utils.py +169 -0
- package/app/utils/debug_context.py +16 -0
- package/app/utils/function_utils.py +274 -0
- package/app/utils/jwt_utils.py +39 -0
- package/app/views/__init__.py +6 -0
- package/app/views/__pycache__/__init__.cpython-312.pyc +0 -0
- package/app/views/__pycache__/view_chatstream.cpython-312.pyc +0 -0
- package/app/views/__pycache__/view_healthcheck.cpython-312.pyc +0 -0
- package/app/views/__pycache__/view_runtime.cpython-312.pyc +0 -0
- package/app/views/view_chatstream.py +53 -0
- package/app/views/view_healthcheck.py +14 -0
- package/app/views/view_runtime.py +72 -0
- package/app/wsgi.py +37 -0
- package/ci.yml +14 -0
- package/deploy/autoconf/templates/env.j2 +25 -0
- package/deploy/autoconf.yml +15 -0
- package/deploy/scripts/healthcheck.sh +0 -0
- package/deploy/scripts/requirements.txt +53 -0
- package/deploy/scripts/start.sh +75 -0
- package/deploy/scripts/stop.sh +31 -0
- package/knowledge/.gitkeep +0 -0
- package/knowledge/000001-biz-offline-85b99bd43b-v1.md +88 -0
- package/knowledge/000002-biz-offline-717e8d823e-v1.md +90 -0
- package/knowledge/000003-biz-offline-c963227cc8-v1.md +84 -0
- package/knowledge/000004-biz-offline-2a5868e7da-v1.md +92 -0
- package/knowledge/000005-biz-offline-f9d9cf1a88-v1.md +79 -0
- package/knowledge/000006-biz-offline-c4fa2df3bd-v1.md +77 -0
- package/knowledge/000007-biz-offline-78304b70ca-v1.md +76 -0
- package/knowledge/000008-biz-offline-987ae67b35-v1.md +75 -0
- package/knowledge/000009-biz-offline-4d656bcea3-v1.md +85 -0
- package/knowledge/000010-sop-offline-a9e1050719-v1.md +100 -0
- package/knowledge/000011-biz-offline-5de0624891-v1.md +86 -0
- package/knowledge/000012-biz-offline-7dfacccba3-v1.md +82 -0
- package/knowledge/000013-biz-offline-5e1d29d2ed-v1.md +81 -0
- package/knowledge/000014-biz-offline-1d0ed8b841-v1.md +68 -0
- package/knowledge/000015-biz-offline-8a1376ee3e-v1.md +78 -0
- package/knowledge/000016-biz-offline-c8bfc2aa08-v1.md +99 -0
- package/knowledge/000017-biz-offline-9dffb28032-v1.md +88 -0
- package/knowledge/000018-biz-offline-f935bc9a6a-v1.md +80 -0
- package/knowledge/000019-biz-offline-858b3ecd89-v1.md +86 -0
- package/knowledge/000020-biz-offline-65cb5c4f40-v1.md +113 -0
- package/knowledge/000021-biz-offline-1bf211639c-v1.md +148 -0
- package/knowledge/000022-biz-offline-8c5a637879-v1.md +140 -0
- package/knowledge/000023-biz-offline-fe872b8712-v1.md +188 -0
- package/knowledge/000024-biz-offline-a85010c500-v1.md +133 -0
- package/knowledge/000025-biz-offline-8af58a3638-v1.md +136 -0
- package/knowledge/000026-biz-offline-6754102e93-v1.md +142 -0
- package/knowledge/000027-biz-offline-ea2e5ca5f9-v1.md +150 -0
- package/knowledge/000028-scenario-offline-dab45cebb4-v1.md +136 -0
- package/knowledge/000029-scenario-offline-5b8ae5ea9f-v1.md +143 -0
- package/knowledge/000030-scenario-offline-9a82d42f3f-v1.md +136 -0
- package/knowledge/000031-scenario-offline-cc2edc0197-v1.md +122 -0
- package/knowledge/000032-scenario-offline-e5f6e5cbfa-v1.md +122 -0
- package/knowledge/000033-scenario-offline-e1955849aa-v1.md +135 -0
- package/knowledge/000034-scenario-offline-3a13d49a3a-v1.md +138 -0
- package/knowledge/000035-scenario-offline-fd5560211f-v1.md +147 -0
- package/knowledge/000036-scenario-offline-function-call-mock-v1.md +134 -0
- package/package.json +18 -0
- package/requirements.txt +53 -0
- package/tools/prompts.yaml +10 -0
- package/tools/tool_definitions.yaml +303 -0
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import jwt
|
|
2
|
+
from datetime import datetime, timedelta, timezone
|
|
3
|
+
from flask import current_app
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def generate_jwt(user: str, attributes: dict = None) -> str:
|
|
7
|
+
now = datetime.now(timezone.utc)
|
|
8
|
+
payload = {
|
|
9
|
+
'user': user,
|
|
10
|
+
'iat': now,
|
|
11
|
+
'exp': now + timedelta(seconds=current_app.config['JWT_EXPIRATION_SECOND'])
|
|
12
|
+
}
|
|
13
|
+
if attributes:
|
|
14
|
+
payload['attributes'] = attributes
|
|
15
|
+
token = jwt.encode(
|
|
16
|
+
payload,
|
|
17
|
+
current_app.config['JWT_SECRET_KEY'],
|
|
18
|
+
algorithm='HS256'
|
|
19
|
+
)
|
|
20
|
+
return token
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def verify_jwt(token: str) -> dict:
|
|
24
|
+
try:
|
|
25
|
+
payload = jwt.decode(
|
|
26
|
+
token,
|
|
27
|
+
current_app.config['JWT_SECRET_KEY'],
|
|
28
|
+
algorithms=['HS256']
|
|
29
|
+
)
|
|
30
|
+
exp = datetime.fromtimestamp(payload['exp'], tz=timezone.utc)
|
|
31
|
+
now = datetime.now(timezone.utc)
|
|
32
|
+
# is_expired = now > exp
|
|
33
|
+
is_expiring_soon = (exp - now) < timedelta(seconds=current_app.config['JWT_RENEW_SECOND'])
|
|
34
|
+
|
|
35
|
+
return payload, is_expiring_soon
|
|
36
|
+
except jwt.ExpiredSignatureError:
|
|
37
|
+
raise Exception("Token expired")
|
|
38
|
+
except jwt.InvalidTokenError:
|
|
39
|
+
raise Exception("Invalid token")
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
from pydantic import ValidationError
|
|
2
|
+
from flask import Blueprint, current_app, request, Response, jsonify, stream_with_context, g
|
|
3
|
+
|
|
4
|
+
from app.models.schemas import ChatRequest, ChatResponse
|
|
5
|
+
|
|
6
|
+
chatstream = Blueprint("chatstream", __name__, url_prefix="/chatstream/v1")
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def _sse_event(event: str, data: str) -> str:
|
|
10
|
+
return f"event: {event}\ndata: {data}\n\n"
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def _chatstream_manager():
|
|
14
|
+
return current_app.extensions["chatstream_manager"]
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@chatstream.get("/rag/check")
|
|
18
|
+
def rag_check():
|
|
19
|
+
return jsonify(_chatstream_manager().check_rag())
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
@chatstream.post("/rag/force-rebuild")
|
|
23
|
+
def rag_force_rebuild():
|
|
24
|
+
try:
|
|
25
|
+
return jsonify(_chatstream_manager().force_rebuild_rag())
|
|
26
|
+
except Exception as exc:
|
|
27
|
+
return jsonify({"detail": str(exc)}), 500
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
@chatstream.route("/chat/stream", methods=["OPTIONS", "POST"])
|
|
31
|
+
def chat_stream_endpoint():
|
|
32
|
+
if request.method == "OPTIONS":
|
|
33
|
+
return Response()
|
|
34
|
+
|
|
35
|
+
try:
|
|
36
|
+
chat_request = ChatRequest.model_validate(request.get_json(silent=True) or {})
|
|
37
|
+
except ValidationError as exc:
|
|
38
|
+
return jsonify({"detail": exc.errors()}), 422
|
|
39
|
+
|
|
40
|
+
def event_generator():
|
|
41
|
+
conversation_id = chat_request.conversation_id
|
|
42
|
+
jsessionid = g.current_user["jsessionid"]
|
|
43
|
+
for chunk in _chatstream_manager().chat_stream(conversation_id, chat_request.question, jsessionid):
|
|
44
|
+
conversation_id = chunk.conversation_id
|
|
45
|
+
yield _sse_event("message", chunk.model_dump_json(by_alias=True))
|
|
46
|
+
|
|
47
|
+
done = ChatResponse(conversationId=conversation_id, finish_reason="done")
|
|
48
|
+
yield _sse_event("done", done.model_dump_json(by_alias=True))
|
|
49
|
+
|
|
50
|
+
response = Response(stream_with_context(event_generator()), mimetype="text/event-stream")
|
|
51
|
+
response.headers.add("Cache-Control", "no-cache")
|
|
52
|
+
response.headers.add("Connection", "keep-alive")
|
|
53
|
+
return response
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
from flask import Blueprint
|
|
2
|
+
from loguru import logger
|
|
3
|
+
|
|
4
|
+
healthcheck = Blueprint('healthcheck', __name__)
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
@healthcheck.route('/healthcheck.html')
|
|
8
|
+
def health_check():
|
|
9
|
+
return "healthcheck ok"
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@healthcheck.route('/favicon.ico')
|
|
13
|
+
def index():
|
|
14
|
+
return "", 204
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Generator
|
|
4
|
+
|
|
5
|
+
from flask import Blueprint, current_app, request, Response, jsonify, g
|
|
6
|
+
from loguru import logger
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
runtime = Blueprint('runtime', __name__, url_prefix='/runtime/v1')
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def _sse_event(data: str) -> str:
|
|
13
|
+
return f"data:{data}\n\n"
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@runtime.route('/analyze', methods=['OPTIONS', 'POST'])
|
|
17
|
+
def analyze_runtime() -> Response:
|
|
18
|
+
"""
|
|
19
|
+
运行时分析接口
|
|
20
|
+
|
|
21
|
+
接收用户查询文本,通过LLM分析系统运行质量,返回流式分析结果
|
|
22
|
+
支持跨域请求(CORS)
|
|
23
|
+
|
|
24
|
+
Returns:
|
|
25
|
+
Flask Response对象,支持Server-Sent Events流式响应
|
|
26
|
+
"""
|
|
27
|
+
# 处理预检请求(OPTIONS)
|
|
28
|
+
if request.method == 'OPTIONS':
|
|
29
|
+
return Response()
|
|
30
|
+
|
|
31
|
+
try:
|
|
32
|
+
# 获取登录态凭证和前端对话ID;runtime 不保存对话上下文。
|
|
33
|
+
jsessionid = g.current_user['jsessionid']
|
|
34
|
+
json_data = request.get_json(silent=True) or {}
|
|
35
|
+
query_content = json_data.get('text')
|
|
36
|
+
conversation_id = str(json_data.get('conversationId') or "").strip()
|
|
37
|
+
|
|
38
|
+
if not query_content:
|
|
39
|
+
error_response = jsonify({'error': '查询内容不能为空'})
|
|
40
|
+
error_response.headers.add('Access-Control-Allow-Origin', '*')
|
|
41
|
+
return error_response, 400
|
|
42
|
+
|
|
43
|
+
logger.info(f"接收到运行时分析请求: {query_content}")
|
|
44
|
+
|
|
45
|
+
manager = current_app.extensions["runtime_manager"]
|
|
46
|
+
|
|
47
|
+
# 执行完整的运行时分析流程
|
|
48
|
+
def generate() -> Generator[str, None, None]:
|
|
49
|
+
"""生成流式响应"""
|
|
50
|
+
for message in manager.analyze_runtime_complete_stream(query_content, conversation_id, jsessionid):
|
|
51
|
+
yield _sse_event(message.model_dump_json(by_alias=True))
|
|
52
|
+
|
|
53
|
+
response = Response(generate(), mimetype='text/event-stream')
|
|
54
|
+
|
|
55
|
+
# 为流式响应添加CORS头部
|
|
56
|
+
response.headers.add('Access-Control-Allow-Origin', '*')
|
|
57
|
+
# SSE不需要缓存
|
|
58
|
+
response.headers.add('Cache-Control', 'no-cache')
|
|
59
|
+
response.headers.add('Connection', 'keep-alive')
|
|
60
|
+
|
|
61
|
+
return response
|
|
62
|
+
|
|
63
|
+
except KeyError as e:
|
|
64
|
+
logger.error(f"获取用户信息失败: {e}")
|
|
65
|
+
error_response = jsonify({'error': f'获取用户信息失败: {str(e)}'})
|
|
66
|
+
error_response.headers.add('Access-Control-Allow-Origin', '*')
|
|
67
|
+
return error_response, 401
|
|
68
|
+
except Exception as e:
|
|
69
|
+
logger.exception(f"分析运行时时发生异常: {e}")
|
|
70
|
+
error_response = jsonify({'error': f'服务器内部错误: {str(e)}'})
|
|
71
|
+
error_response.headers.add('Access-Control-Allow-Origin', '*')
|
|
72
|
+
return error_response, 500
|
package/app/wsgi.py
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
try:
|
|
2
|
+
from app import create_app
|
|
3
|
+
|
|
4
|
+
app = create_app()
|
|
5
|
+
|
|
6
|
+
from flask_cors import CORS
|
|
7
|
+
|
|
8
|
+
CORS(app, resources={
|
|
9
|
+
r"/.*": {
|
|
10
|
+
"origins": "*",
|
|
11
|
+
"methods": ["GET", "POST", "PUT", "DELETE", "OPTIONS", "HEAD"],
|
|
12
|
+
"allow_headers": [
|
|
13
|
+
"Content-Type",
|
|
14
|
+
"Authorization",
|
|
15
|
+
"X-Requested-With",
|
|
16
|
+
"Accept",
|
|
17
|
+
"Origin",
|
|
18
|
+
"Access-Control-Request-Method",
|
|
19
|
+
"Access-Control-Request-Headers",
|
|
20
|
+
"Cookie",
|
|
21
|
+
"X-Session-Id",
|
|
22
|
+
],
|
|
23
|
+
"expose_headers": [
|
|
24
|
+
"Content-Type",
|
|
25
|
+
"Authorization",
|
|
26
|
+
"X-Accel-Buffering",
|
|
27
|
+
],
|
|
28
|
+
"max_age": 3600,
|
|
29
|
+
}
|
|
30
|
+
})
|
|
31
|
+
except Exception:
|
|
32
|
+
raise
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
if __name__ == '__main__':
|
|
36
|
+
if 'dev' in app.config["FLASK_ENV"]:
|
|
37
|
+
app.run(debug=True, host='0.0.0.0', port=8000)
|
package/ci.yml
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
Image:
|
|
2
|
+
type : default
|
|
3
|
+
BeforeBuild:
|
|
4
|
+
script :
|
|
5
|
+
Build:
|
|
6
|
+
script :
|
|
7
|
+
AfterBuild:
|
|
8
|
+
script :
|
|
9
|
+
Package:
|
|
10
|
+
script :
|
|
11
|
+
artifacts:
|
|
12
|
+
name : union-py-app
|
|
13
|
+
version : $COMMIT_ID-$BUILD_ID
|
|
14
|
+
files : [./app,./deploy,./scripts] # seperate multiple files by comma
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
FLASK_ENV={{FLASK_ENV}}
|
|
2
|
+
CONSOLE_STDOUT={{CONSOLE_STDOUT}}
|
|
3
|
+
LOG_LEVEL={{LOG_LEVEL}}
|
|
4
|
+
SECRET_KEY=
|
|
5
|
+
|
|
6
|
+
#JSESSION配置
|
|
7
|
+
|
|
8
|
+
#联合运维服务
|
|
9
|
+
GET_USE_INFO_URL={{GET_USE_INFO_URL}}
|
|
10
|
+
GET_ORG_INFO_URL={{GET_ORG_INFO_URL}}
|
|
11
|
+
GET_JIRA_INFO_URL={{GET_JIRA_INFO_URL}}
|
|
12
|
+
GET_BIGDATA_URL={{GET_BIGDATA_URL}}
|
|
13
|
+
GET_UNION_BASE_URL={{GET_UNION_BASE_URL}}
|
|
14
|
+
|
|
15
|
+
#大模型地址
|
|
16
|
+
LLM_URL={{LLM_URL}}
|
|
17
|
+
LLM_KEY={{LLM_KEY}}
|
|
18
|
+
|
|
19
|
+
#日志
|
|
20
|
+
LOG_DIR={{LOG_DIR}}
|
|
21
|
+
|
|
22
|
+
#JWT
|
|
23
|
+
JWT_SECRET_KEY=
|
|
24
|
+
JWT_EXPIRATION_SECOND={{JWT_EXPIRATION_SECOND}}
|
|
25
|
+
JWT_RENEW_SECOND={{JWT_RENEW_SECOND}}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
union-py-app:
|
|
2
|
+
test:
|
|
3
|
+
test:
|
|
4
|
+
- template: deploy/autoconf/templates/env.j2
|
|
5
|
+
dest: env.test
|
|
6
|
+
prod:
|
|
7
|
+
bj11:
|
|
8
|
+
- template: deploy/autoconf/templates/env.j2
|
|
9
|
+
dest: env.prod
|
|
10
|
+
sh20:
|
|
11
|
+
- template: deploy/autoconf/templates/env.j2
|
|
12
|
+
dest: env.prod
|
|
13
|
+
sz31:
|
|
14
|
+
- template: deploy/autoconf/templates/env.j2
|
|
15
|
+
dest: env.prod
|
|
File without changes
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
annotated-types==0.7.0
|
|
2
|
+
anyio==4.6.2
|
|
3
|
+
blinker==1.8.2
|
|
4
|
+
certifi==2025.8.3
|
|
5
|
+
charset-normalizer==3.4.4
|
|
6
|
+
click==8.1.8
|
|
7
|
+
concurrent-log-handler==0.9.28
|
|
8
|
+
curlify==3.0.0
|
|
9
|
+
distro==1.9.0
|
|
10
|
+
dnspython==2.6.1
|
|
11
|
+
exceptiongroup==1.3.0
|
|
12
|
+
Flask==3.0.3
|
|
13
|
+
Flask-Cors==5.0.0
|
|
14
|
+
h11==0.16.0
|
|
15
|
+
h2==4.1.0
|
|
16
|
+
hpack==4.0.0
|
|
17
|
+
httpcore==1.0.9
|
|
18
|
+
httpx==0.28.1
|
|
19
|
+
Hypercorn==0.17.3
|
|
20
|
+
hyperframe==6.0.1
|
|
21
|
+
idna==3.10
|
|
22
|
+
itsdangerous==2.2.0
|
|
23
|
+
Jinja2==3.1.6
|
|
24
|
+
jiter==0.9.1
|
|
25
|
+
loguru==0.7.3
|
|
26
|
+
lxml==6.0.1
|
|
27
|
+
MarkupSafe==2.1.5
|
|
28
|
+
numpy>=2.0.0,<2.5.0
|
|
29
|
+
opencv-python>=4.13.0.90
|
|
30
|
+
openai==1.107.3
|
|
31
|
+
packaging==25.0
|
|
32
|
+
portalocker==3.0.0
|
|
33
|
+
priority==2.0.0
|
|
34
|
+
PyJWT==2.9.0
|
|
35
|
+
python-dateutil==2.9.0.post0
|
|
36
|
+
python-dotenv==1.0.1
|
|
37
|
+
pytz==2025.2
|
|
38
|
+
requests==2.32.5
|
|
39
|
+
six==1.17.0
|
|
40
|
+
sniffio==1.3.1
|
|
41
|
+
tqdm==4.67.3
|
|
42
|
+
typing_extensions==4.15.0
|
|
43
|
+
tzdata==2025.2
|
|
44
|
+
urllib3==1.26.20
|
|
45
|
+
Werkzeug==3.0.6
|
|
46
|
+
wsproto==1.2.0
|
|
47
|
+
zipp==3.20.2
|
|
48
|
+
pydantic==2.13.4
|
|
49
|
+
pyyaml==6.0.3
|
|
50
|
+
zai-sdk==0.2.2
|
|
51
|
+
chromadb==1.5.9
|
|
52
|
+
pysqlite3-binary==0.5.4
|
|
53
|
+
typer==0.15.1
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# 脚本:启动WSGI应用
|
|
3
|
+
# 功能:
|
|
4
|
+
# 1.检删除旧的union-py虚拟环境
|
|
5
|
+
# 2.创建新venv环境并安装依赖
|
|
6
|
+
# 3.启动WSGI服务
|
|
7
|
+
WSGI_APP="app.wsgi:app"
|
|
8
|
+
GUNICORN_CMD="gunicorn"
|
|
9
|
+
PYTHON="python"
|
|
10
|
+
LOG_ACCESS_FILE="/data/dataLogs/hypercorn_$(date '+%Y-%m-%d_%H_%M_%S').log"
|
|
11
|
+
|
|
12
|
+
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
|
13
|
+
VENV_DIR="$ROOT_DIR/union_py"
|
|
14
|
+
REQUIREMENTS="$ROOT_DIR/deploy/scripts/requirements.txt"
|
|
15
|
+
OFFLINK_PKGS="$ROOT_DIR/deploy/offline-packages"
|
|
16
|
+
PID_FILE="$ROOT_DIR/deploy/scripts/pid"
|
|
17
|
+
export PYTHONUNBUFFERED=1
|
|
18
|
+
export FLASK_ENV=$(head -n 1 "$ROOT_DIR/deploy/scripts/start.sh")
|
|
19
|
+
echo "切换到项目目录$ROOT_DIR 并设置FLASK_ENV环境变量:$FLASK_ENV" >> "$LOG_ACCESS_FILE"
|
|
20
|
+
#$ pip3 download -r deploy/scripts/requirements.txt --only-binary=:all: --platform manylinux2014_x86_64 --python-version 38 --abi cp38 --implementation cp -d ddd --trusted-host pypi.nucc.com
|
|
21
|
+
#wget http://mirrors.nucc.com/repo/pip.conf -O /home/nucc/.pip/pip.conf
|
|
22
|
+
#/usr/local/python3.8.5/bin/python3.8 -m pip install --upgrade pip
|
|
23
|
+
|
|
24
|
+
BIND_PORT="127.0.0.1"
|
|
25
|
+
if [[ "$FLASK_ENV" == *test* ]]; then
|
|
26
|
+
BIND_PORT="0.0.0.0"
|
|
27
|
+
fi
|
|
28
|
+
echo "开始启动,当前目录:$(pwd)...." >> "$LOG_ACCESS_FILE"
|
|
29
|
+
if [ -d "$VENV_DIR" ]; then
|
|
30
|
+
echo "删除现有环境:$VENV_DIR" >> "$LOG_ACCESS_FILE"
|
|
31
|
+
rm -rf "$VENV_DIR"
|
|
32
|
+
else
|
|
33
|
+
echo "虚拟环境$VENV_DIR 不存在,跳过删除" >> "$LOG_ACCESS_FILE"
|
|
34
|
+
fi
|
|
35
|
+
echo "开始创建虚拟环境$VENV_DIR " >> "$LOG_ACCESS_FILE"
|
|
36
|
+
$PYTHON -m venv "$VENV_DIR"
|
|
37
|
+
if [ $? -ne 0 ]; then
|
|
38
|
+
echo "创建虚拟环境$VENV_DIR 失败,请检查python3 和venv命令是否可用" >> "$LOG_ACCESS_FILE"
|
|
39
|
+
exit 1
|
|
40
|
+
fi
|
|
41
|
+
source "$VENV_DIR/bin/activate"
|
|
42
|
+
echo "虚拟环境$VENV_DIR 创建成功.并已激活虚拟环境$VENV_DIR" >> "$LOG_ACCESS_FILE"
|
|
43
|
+
|
|
44
|
+
echo "安装依赖 from $REQUIREMENTS 文件" >> "$LOG_ACCESS_FILE"
|
|
45
|
+
if [ ! -f "$REQUIREMENTS" ]; then
|
|
46
|
+
echo "$REQUIREMENTS 文件不存在,退出" >> "$LOG_ACCESS_FILE"
|
|
47
|
+
exit 1
|
|
48
|
+
fi
|
|
49
|
+
pip install \
|
|
50
|
+
--no-index \
|
|
51
|
+
--find-links "$OFFLINK_PKGS" \
|
|
52
|
+
--no-cache-dir \
|
|
53
|
+
-r "$REQUIREMENTS" || { echo "依赖安装失败,请检查离线包是否完整" >> "$LOG_ACCESS_FILE"; exit 1 ;}
|
|
54
|
+
|
|
55
|
+
echo "安装依赖完成。启动WSGI应用:$WSGI_APP" >> "$LOG_ACCESS_FILE"
|
|
56
|
+
cd "$ROOT_DIR"
|
|
57
|
+
hypercorn \
|
|
58
|
+
--workers 4 \
|
|
59
|
+
--bind "$BIND_PORT":8000 \
|
|
60
|
+
--keep-alive 2 \
|
|
61
|
+
--pid "$PID_FILE" \
|
|
62
|
+
"$WSGI_APP" \
|
|
63
|
+
>> "$LOG_ACCESS_FILE" 2>&1 &
|
|
64
|
+
echo $! >> "$LOG_ACCESS_FILE"
|
|
65
|
+
|
|
66
|
+
for i in $(seq 1 5);do
|
|
67
|
+
if [ -f "$PID_FILE" ] ;then
|
|
68
|
+
PID=$(cat "$PID_FILE" 2>/dev/null)
|
|
69
|
+
if [ -n "$PID" ] && kill -0 "$PID" 2>/dev/null ; then
|
|
70
|
+
echo "hypercorn 已启动 (PID:$PID)"
|
|
71
|
+
exit 0
|
|
72
|
+
fi
|
|
73
|
+
fi
|
|
74
|
+
sleep 1
|
|
75
|
+
done
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
|
2
|
+
|
|
3
|
+
PID_FILE="$ROOT_DIR/deploy/scripts/pid"
|
|
4
|
+
|
|
5
|
+
quiet_stop(){
|
|
6
|
+
if [ ! -f "$PID_FILE" ];then
|
|
7
|
+
return 0
|
|
8
|
+
fi
|
|
9
|
+
PID=$(cat "$PID_FILE" 2>/dev/null)
|
|
10
|
+
if [ -z "$PID" ];then
|
|
11
|
+
rm -f "$PID_FILE"
|
|
12
|
+
return 0
|
|
13
|
+
fi
|
|
14
|
+
if kill -0 "$PID" 2>/dev/null; then
|
|
15
|
+
echo "正在停止 hypercorn(PID:$PID)..."
|
|
16
|
+
kill "$PID" >/dev/null 2>&1
|
|
17
|
+
for i in {1..5}; do
|
|
18
|
+
if ! kill -0 "$PID" 2>/dev/null; then
|
|
19
|
+
echo "hypercorn(PID:$PID) 已停止"
|
|
20
|
+
rm -f "$PID_FILE"
|
|
21
|
+
return 0
|
|
22
|
+
fi
|
|
23
|
+
sleep 1
|
|
24
|
+
done
|
|
25
|
+
echo "兜底,强制停止"
|
|
26
|
+
kill -9 "$PID" 2>/dev/null
|
|
27
|
+
fi
|
|
28
|
+
rm -f "$PID_FILE"
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
quiet_stop
|
|
File without changes
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
---
|
|
2
|
+
kb_id: biz-offline-85b99bd43b-v1
|
|
3
|
+
title: Q/NUC 601-2023 网络支付清算平台 联合运维互联互通技术规范V1.3
|
|
4
|
+
doc_type: biz
|
|
5
|
+
domain: 联合运维
|
|
6
|
+
category: Q/NUC 601-2023 网络支付清算平台 联合运维互联互通技术规范V1.3
|
|
7
|
+
category_description: 本分类来源于《Q/NUC 601-2023 网络支付清算平台 联合运维互联互通技术规范V1.3》,主要覆盖:网络支付清算平台
|
|
8
|
+
联合运维互联互通技术规范;1 范围;2 规范性引用文件;3 术语和定义;3.1 网络支付清算平台 electronics payment clearing of
|
|
9
|
+
China;3.2 联合运维成员单位;3.3 报文 message;4 通讯规范。
|
|
10
|
+
category_keywords:
|
|
11
|
+
- NUC
|
|
12
|
+
- '601'
|
|
13
|
+
- '2023'
|
|
14
|
+
- 网络支付清算平台
|
|
15
|
+
- 联合运维互联互通技术规范V1.3
|
|
16
|
+
- Q/NUC 601-2023 网络支付清算平台 联合运维互联互通技术规范V1.3
|
|
17
|
+
- 联合运维互联互通技术规范
|
|
18
|
+
- 网络支付清算平台 联合运维互联互通技术规范
|
|
19
|
+
- 范围
|
|
20
|
+
- 1 范围
|
|
21
|
+
- 规范性引用文件
|
|
22
|
+
- 2 规范性引用文件
|
|
23
|
+
- 术语和定义
|
|
24
|
+
- 3 术语和定义
|
|
25
|
+
- '3.1'
|
|
26
|
+
- electronics
|
|
27
|
+
business_modules:
|
|
28
|
+
- 网络支付清算平台
|
|
29
|
+
- 联合运维互联互通技术规范V1.3
|
|
30
|
+
source_doc: 互联互通机制规范.md
|
|
31
|
+
source_version: V1.3
|
|
32
|
+
source_section: Q/NUC 601-2023 网络支付清算平台 联合运维互联互通技术规范V1.3
|
|
33
|
+
source_order: 1
|
|
34
|
+
source_pages: []
|
|
35
|
+
source_trace: section=Q/NUC 601-2023 网络支付清算平台 联合运维互联互通技术规范V1.3
|
|
36
|
+
effective_date: ''
|
|
37
|
+
owner: 联合运维知识库
|
|
38
|
+
confidentiality: 内部
|
|
39
|
+
risk_level: low
|
|
40
|
+
applicable_roles: []
|
|
41
|
+
tags:
|
|
42
|
+
- NUC
|
|
43
|
+
- '601'
|
|
44
|
+
- '2023'
|
|
45
|
+
- 网络支付清算平台
|
|
46
|
+
- 联合运维互联互通技术规范V1.3
|
|
47
|
+
- Q/NUC 601-2023 网络支付清算平台 联合运维互联互通技术规范V1.3
|
|
48
|
+
- 联合运维互联互通技术规范
|
|
49
|
+
- 网络支付清算平台 联合运维互联互通技术规范
|
|
50
|
+
- 范围
|
|
51
|
+
- 1 范围
|
|
52
|
+
- 规范性引用文件
|
|
53
|
+
- 2 规范性引用文件
|
|
54
|
+
- 术语和定义
|
|
55
|
+
- 3 术语和定义
|
|
56
|
+
- '3.1'
|
|
57
|
+
- electronics
|
|
58
|
+
status: active
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
# Q/NUC 601-2023 网络支付清算平台 联合运维互联互通技术规范V1.3
|
|
62
|
+
|
|
63
|
+
知识大类说明:
|
|
64
|
+
大类:Q/NUC 601-2023 网络支付清算平台 联合运维互联互通技术规范V1.3
|
|
65
|
+
说明:本分类来源于《Q/NUC 601-2023 网络支付清算平台 联合运维互联互通技术规范V1.3》,主要覆盖:网络支付清算平台 联合运维互联互通技术规范;1 范围;2 规范性引用文件;3 术语和定义;3.1 网络支付清算平台 electronics payment clearing of China;3.2 联合运维成员单位;3.3 报文 message;4 通讯规范。
|
|
66
|
+
关键词:NUC、601、2023、网络支付清算平台、联合运维互联互通技术规范V1.3、Q/NUC 601-2023 网络支付清算平台 联合运维互联互通技术规范V1.3、联合运维互联互通技术规范、网络支付清算平台 联合运维互联互通技术规范、范围、1 范围、规范性引用文件、2 规范性引用文件、术语和定义、3 术语和定义、3.1、electronics
|
|
67
|
+
|
|
68
|
+
## 1. 核心内容
|
|
69
|
+
|
|
70
|
+
本规范规定了联合运维成员单位通过系统对接方式接入网络支付清算平台开展联合运维工作所需报文格式、报文使用规则、报文结构及报文交换流程的等。本规范适用于联合运维成员单位通过系统对接方式接入网络支付清算平台开展联合运维工作的需求分析、系统设计和开发测试。
|
|
71
|
+
|
|
72
|
+
## 2. 适用边界
|
|
73
|
+
|
|
74
|
+
本规范适用于联合运维成员单位通过系统对接方式接入网络支付清算平台开展联合运维工作的需求分析、系统设计和开发测试。
|
|
75
|
+
|
|
76
|
+
## 3. 使用要求
|
|
77
|
+
|
|
78
|
+
暂无
|
|
79
|
+
|
|
80
|
+
## 4. 关联能力
|
|
81
|
+
|
|
82
|
+
暂无。
|
|
83
|
+
|
|
84
|
+
## 5. 来源依据
|
|
85
|
+
|
|
86
|
+
- 来源文档:互联互通机制规范.md
|
|
87
|
+
- 来源章节:Q/NUC 601-2023 网络支付清算平台 联合运维互联互通技术规范V1.3
|
|
88
|
+
- 来源说明:基于来源章节归纳,需人工复核原文一致性。
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
---
|
|
2
|
+
kb_id: biz-offline-717e8d823e-v1
|
|
3
|
+
title: Q/NUC 601-2023 网络支付清算平台 联合运维互联互通技术规范V1.3 范围
|
|
4
|
+
doc_type: biz
|
|
5
|
+
domain: 联合运维
|
|
6
|
+
category: Q/NUC 601-2023 网络支付清算平台 联合运维互联互通技术规范V1.3
|
|
7
|
+
category_description: 本分类来源于《Q/NUC 601-2023 网络支付清算平台 联合运维互联互通技术规范V1.3》,主要覆盖:网络支付清算平台
|
|
8
|
+
联合运维互联互通技术规范;1 范围;2 规范性引用文件;3 术语和定义;3.1 网络支付清算平台 electronics payment clearing of
|
|
9
|
+
China;3.2 联合运维成员单位;3.3 报文 message;4 通讯规范。
|
|
10
|
+
category_keywords:
|
|
11
|
+
- NUC
|
|
12
|
+
- '601'
|
|
13
|
+
- '2023'
|
|
14
|
+
- 网络支付清算平台
|
|
15
|
+
- 联合运维互联互通技术规范V1.3
|
|
16
|
+
- Q/NUC 601-2023 网络支付清算平台 联合运维互联互通技术规范V1.3
|
|
17
|
+
- 联合运维互联互通技术规范
|
|
18
|
+
- 网络支付清算平台 联合运维互联互通技术规范
|
|
19
|
+
- 范围
|
|
20
|
+
- 1 范围
|
|
21
|
+
- 规范性引用文件
|
|
22
|
+
- 2 规范性引用文件
|
|
23
|
+
- 术语和定义
|
|
24
|
+
- 3 术语和定义
|
|
25
|
+
- '3.1'
|
|
26
|
+
- electronics
|
|
27
|
+
business_modules:
|
|
28
|
+
- 网络支付清算平台
|
|
29
|
+
- 联合运维互联互通技术规范V1.3
|
|
30
|
+
source_doc: 互联互通机制规范.md
|
|
31
|
+
source_version: V1.3
|
|
32
|
+
source_section: 1 范围
|
|
33
|
+
source_order: 2
|
|
34
|
+
source_pages: []
|
|
35
|
+
source_trace: section=1 范围
|
|
36
|
+
effective_date: ''
|
|
37
|
+
owner: 联合运维知识库
|
|
38
|
+
confidentiality: 内部
|
|
39
|
+
risk_level: low
|
|
40
|
+
applicable_roles: []
|
|
41
|
+
tags:
|
|
42
|
+
- NUC
|
|
43
|
+
- '601'
|
|
44
|
+
- '2023'
|
|
45
|
+
- 网络支付清算平台
|
|
46
|
+
- 联合运维互联互通技术规范V1.3
|
|
47
|
+
- Q/NUC 601-2023 网络支付清算平台 联合运维互联互通技术规范V1.3
|
|
48
|
+
- 联合运维互联互通技术规范
|
|
49
|
+
- 网络支付清算平台 联合运维互联互通技术规范
|
|
50
|
+
- 范围
|
|
51
|
+
- 1 范围
|
|
52
|
+
- 规范性引用文件
|
|
53
|
+
- 2 规范性引用文件
|
|
54
|
+
- 术语和定义
|
|
55
|
+
- 3 术语和定义
|
|
56
|
+
- '3.1'
|
|
57
|
+
- electronics
|
|
58
|
+
status: active
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
# Q/NUC 601-2023 网络支付清算平台 联合运维互联互通技术规范V1.3 范围
|
|
62
|
+
|
|
63
|
+
知识大类说明:
|
|
64
|
+
大类:Q/NUC 601-2023 网络支付清算平台 联合运维互联互通技术规范V1.3
|
|
65
|
+
说明:本分类来源于《Q/NUC 601-2023 网络支付清算平台 联合运维互联互通技术规范V1.3》,主要覆盖:网络支付清算平台 联合运维互联互通技术规范;1 范围;2 规范性引用文件;3 术语和定义;3.1 网络支付清算平台 electronics payment clearing of China;3.2 联合运维成员单位;3.3 报文 message;4 通讯规范。
|
|
66
|
+
关键词:NUC、601、2023、网络支付清算平台、联合运维互联互通技术规范V1.3、Q/NUC 601-2023 网络支付清算平台 联合运维互联互通技术规范V1.3、联合运维互联互通技术规范、网络支付清算平台 联合运维互联互通技术规范、范围、1 范围、规范性引用文件、2 规范性引用文件、术语和定义、3 术语和定义、3.1、electronics
|
|
67
|
+
|
|
68
|
+
## 1. 核心内容
|
|
69
|
+
|
|
70
|
+
本规范规定了联合运维成员单位通过系统对接方式接入网络支付清算平台开展联合运维工作所需报文格式、报文使用规则、报文结构及报文交换流程的等。
|
|
71
|
+
|
|
72
|
+
本规范适用于联合运维成员单位通过系统对接方式接入网络支付清算平台开展联合运维工作的需求分析、系统设计和开发测试。
|
|
73
|
+
|
|
74
|
+
## 2. 适用边界
|
|
75
|
+
|
|
76
|
+
适用于联合运维成员单位通过系统对接方式接入网络支付清算平台开展联合运维工作的需求分析、系统设计和开发测试。
|
|
77
|
+
|
|
78
|
+
## 3. 使用要求
|
|
79
|
+
|
|
80
|
+
暂无
|
|
81
|
+
|
|
82
|
+
## 4. 关联能力
|
|
83
|
+
|
|
84
|
+
暂无。
|
|
85
|
+
|
|
86
|
+
## 5. 来源依据
|
|
87
|
+
|
|
88
|
+
- 来源文档:互联互通机制规范.md
|
|
89
|
+
- 来源章节:1 范围
|
|
90
|
+
- 来源说明:基于来源章节归纳,需人工复核原文一致性。
|