sycommon-python-lib 0.2.0b22__tar.gz → 0.2.0b24__tar.gz
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.
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/PKG-INFO +1 -1
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/pyproject.toml +1 -1
- sycommon_python_lib-0.2.0b24/src/sycommon/database/token_usage_db_service.py +180 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/llm/get_llm.py +1 -1
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/llm/struct_token.py +14 -23
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/llm/sy_langfuse.py +1 -3
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/llm/token_usage_mysql_service.py +268 -113
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/llm/usage_token.py +69 -40
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/models/token_usage_mysql.py +8 -7
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/rabbitmq/rabbitmq_pool.py +2 -2
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/synacos/nacos_heartbeat_manager.py +6 -3
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/synacos/nacos_service_discovery.py +9 -1
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon_python_lib.egg-info/PKG-INFO +1 -1
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon_python_lib.egg-info/SOURCES.txt +1 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/README.md +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/setup.cfg +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/command/__init__.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/command/cli.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/command/console.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/command/models.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/command/project.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/command/utils.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/__init__.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/agent/__init__.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/agent/examples/01_basic_agent.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/agent/examples/02_tool_agent.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/agent/examples/03_structured_output.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/agent/examples/04_memory_agent.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/agent/examples/05_streaming.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/agent/examples/06_multi_agent.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/agent/examples/07_skills_agent.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/agent/examples/08_middleware.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/agent/examples/09_interrupt.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/agent/examples/10_custom_llm.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/agent/examples/11_complex_workflow.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/agent/examples/12_batch_processing.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/agent/examples/__init__.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/agent/examples/middleware/01_basic_monitoring.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/agent/examples/middleware/02_permission_control.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/agent/examples/middleware/03_tool_skill_filter.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/agent/examples/middleware/04_caching_retry.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/agent/examples/middleware/05_sanitization.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/agent/examples/middleware/06_tracking.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/agent/examples/middleware/07_advanced.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/agent/examples/middleware/08_progressive_skills.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/agent/examples/middleware/__init__.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/agent/examples/middleware/override_examples.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/agent/get_agent.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/config/Config.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/config/DatabaseConfig.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/config/ElasticsearchConfig.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/config/EmbeddingConfig.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/config/LLMConfig.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/config/LangfuseConfig.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/config/MQConfig.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/config/RedisConfig.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/config/RerankerConfig.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/config/SentryConfig.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/config/__init__.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/database/async_base_db_service.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/database/async_database_service.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/database/base_db_service.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/database/database_service.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/database/elasticsearch_service.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/database/redis_service.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/health/__init__.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/health/health_check.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/health/metrics.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/health/ping.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/llm/__init__.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/llm/embedding.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/llm/llm_logger.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/llm/llm_tokens.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/llm/token_usage_es_service.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/logging/__init__.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/logging/async_sql_logger.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/logging/kafka_log.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/logging/logger_levels.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/logging/logger_wrapper.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/logging/sql_logger.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/middleware/__init__.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/middleware/context.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/middleware/cors.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/middleware/docs.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/middleware/exception.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/middleware/middleware.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/middleware/monitor_memory.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/middleware/mq.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/middleware/timeout.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/middleware/traceid.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/models/__init__.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/models/base_http.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/models/log.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/models/mqlistener_config.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/models/mqmsg_model.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/models/mqsend_config.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/models/sso_user.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/models/token_usage.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/notice/__init__.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/notice/uvicorn_monitor.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/rabbitmq/rabbitmq_client.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/rabbitmq/rabbitmq_service.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/rabbitmq/rabbitmq_service_client_manager.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/rabbitmq/rabbitmq_service_connection_monitor.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/rabbitmq/rabbitmq_service_consumer_manager.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/rabbitmq/rabbitmq_service_core.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/rabbitmq/rabbitmq_service_producer_manager.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/sentry/__init__.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/sentry/sy_sentry.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/services.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/sse/__init__.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/sse/event.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/sse/sse.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/synacos/__init__.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/synacos/example.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/synacos/example2.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/synacos/feign.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/synacos/feign_client.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/synacos/nacos_client_base.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/synacos/nacos_config_manager.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/synacos/nacos_service.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/synacos/nacos_service_registration.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/synacos/param.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/tests/test_email.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/tests/test_mq.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/tools/__init__.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/tools/async_utils.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/tools/docs.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/tools/env.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/tools/merge_headers.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/tools/snowflake.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/tools/syemail.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/tools/timing.py +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon_python_lib.egg-info/dependency_links.txt +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon_python_lib.egg-info/entry_points.txt +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon_python_lib.egg-info/requires.txt +0 -0
- {sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon_python_lib.egg-info/top_level.txt +0 -0
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Token 使用量记录专用数据库服务
|
|
3
|
+
独立于业务系统的数据库连接,使用 llm 配置中的数据库信息
|
|
4
|
+
"""
|
|
5
|
+
import logging
|
|
6
|
+
from contextlib import asynccontextmanager
|
|
7
|
+
from typing import Optional
|
|
8
|
+
|
|
9
|
+
from sqlalchemy import text
|
|
10
|
+
from sqlalchemy.ext.asyncio import (
|
|
11
|
+
AsyncSession,
|
|
12
|
+
async_sessionmaker,
|
|
13
|
+
create_async_engine,
|
|
14
|
+
AsyncEngine,
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
from sycommon.config.Config import SingletonMeta
|
|
18
|
+
from sycommon.config.DatabaseConfig import DatabaseConfig, convert_dict_keys
|
|
19
|
+
from sycommon.logging.kafka_log import SYLogger
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class TokenUsageDBService(metaclass=SingletonMeta):
|
|
23
|
+
"""
|
|
24
|
+
Token 使用量记录专用数据库服务
|
|
25
|
+
|
|
26
|
+
使用独立的数据库连接,连接到 shengye_platform_ai_middleware 库
|
|
27
|
+
配置来源:Config().config.get("llm", {}).get("spring", {}).get("datasource", {})
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
_engine: Optional[AsyncEngine] = None
|
|
31
|
+
_session_factory: Optional[async_sessionmaker] = None
|
|
32
|
+
_initialized: bool = False
|
|
33
|
+
|
|
34
|
+
def __init__(self):
|
|
35
|
+
pass
|
|
36
|
+
|
|
37
|
+
@classmethod
|
|
38
|
+
def init(cls) -> bool:
|
|
39
|
+
"""
|
|
40
|
+
初始化 Token 使用量记录数据库连接
|
|
41
|
+
|
|
42
|
+
从 Config().config.get("llm", {}) 中读取数据库配置
|
|
43
|
+
该配置独立于业务系统的数据库配置
|
|
44
|
+
|
|
45
|
+
Returns:
|
|
46
|
+
bool: 是否初始化成功
|
|
47
|
+
"""
|
|
48
|
+
if cls._initialized:
|
|
49
|
+
return True
|
|
50
|
+
|
|
51
|
+
try:
|
|
52
|
+
from sycommon.config.Config import Config
|
|
53
|
+
|
|
54
|
+
# 从 llm 配置中获取数据库信息
|
|
55
|
+
llm_config = Config().config.get("llm", {})
|
|
56
|
+
datasource_config = llm_config.get("spring", {}).get("datasource", None)
|
|
57
|
+
|
|
58
|
+
if not datasource_config:
|
|
59
|
+
logging.warning("TokenUsageDBService: 未找到 llm.spring.datasource 配置,Token 记录功能将禁用")
|
|
60
|
+
return False
|
|
61
|
+
|
|
62
|
+
# 转换配置键名(从 Java 风格转 Python 风格)
|
|
63
|
+
converted_dict = convert_dict_keys(datasource_config)
|
|
64
|
+
db_config = DatabaseConfig.model_validate(converted_dict)
|
|
65
|
+
|
|
66
|
+
# 创建数据库连接
|
|
67
|
+
connector = TokenUsageDBConnector(db_config)
|
|
68
|
+
cls._engine = connector.engine
|
|
69
|
+
|
|
70
|
+
# 创建 Session 工厂
|
|
71
|
+
cls._session_factory = async_sessionmaker(
|
|
72
|
+
bind=cls._engine,
|
|
73
|
+
class_=AsyncSession,
|
|
74
|
+
expire_on_commit=False
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
cls._initialized = True
|
|
78
|
+
logging.info("TokenUsageDBService 初始化成功")
|
|
79
|
+
return True
|
|
80
|
+
|
|
81
|
+
except Exception as e:
|
|
82
|
+
logging.error(f"TokenUsageDBService 初始化失败: {e}", exc_info=True)
|
|
83
|
+
return False
|
|
84
|
+
|
|
85
|
+
@classmethod
|
|
86
|
+
@asynccontextmanager
|
|
87
|
+
async def session(cls):
|
|
88
|
+
"""
|
|
89
|
+
异步数据库会话上下文管理器
|
|
90
|
+
|
|
91
|
+
自动处理会话的创建、提交、回滚和关闭
|
|
92
|
+
"""
|
|
93
|
+
if not cls._initialized:
|
|
94
|
+
cls.init()
|
|
95
|
+
|
|
96
|
+
if not cls._initialized or not cls._session_factory:
|
|
97
|
+
raise RuntimeError("TokenUsageDBService 未初始化成功,无法获取数据库会话")
|
|
98
|
+
|
|
99
|
+
async with cls._session_factory() as session:
|
|
100
|
+
try:
|
|
101
|
+
yield session
|
|
102
|
+
await session.commit()
|
|
103
|
+
except Exception as e:
|
|
104
|
+
await session.rollback()
|
|
105
|
+
SYLogger.error(f"TokenUsageDBService database operation failed: {str(e)}")
|
|
106
|
+
raise
|
|
107
|
+
|
|
108
|
+
@classmethod
|
|
109
|
+
def engine(cls) -> Optional[AsyncEngine]:
|
|
110
|
+
"""获取数据库引擎"""
|
|
111
|
+
if not cls._initialized:
|
|
112
|
+
cls.init()
|
|
113
|
+
return cls._engine
|
|
114
|
+
|
|
115
|
+
@classmethod
|
|
116
|
+
def is_initialized(cls) -> bool:
|
|
117
|
+
"""检查是否已初始化"""
|
|
118
|
+
return cls._initialized
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
class TokenUsageDBConnector(metaclass=SingletonMeta):
|
|
122
|
+
"""Token 使用量数据库连接器"""
|
|
123
|
+
|
|
124
|
+
def __init__(self, db_config: DatabaseConfig):
|
|
125
|
+
# 从 DatabaseConfig 中提取数据库连接信息
|
|
126
|
+
self.db_user = db_config.username
|
|
127
|
+
self.db_password = db_config.password
|
|
128
|
+
|
|
129
|
+
# 提取 URL 中的主机、端口和数据库名
|
|
130
|
+
url_parts = db_config.url.split('//')[1].split('/')
|
|
131
|
+
host_port = url_parts[0].split(':')
|
|
132
|
+
self.db_host = host_port[0]
|
|
133
|
+
self.db_port = host_port[1] if len(host_port) > 1 else '3306'
|
|
134
|
+
self.db_name = url_parts[1].split('?')[0]
|
|
135
|
+
|
|
136
|
+
# 提取 URL 中的参数
|
|
137
|
+
params_str = url_parts[1].split('?')[1] if len(url_parts[1].split('?')) > 1 else ''
|
|
138
|
+
params = {}
|
|
139
|
+
for param in params_str.split('&'):
|
|
140
|
+
if param:
|
|
141
|
+
key, value = param.split('=')
|
|
142
|
+
params[key] = value
|
|
143
|
+
|
|
144
|
+
# 移除不需要的参数
|
|
145
|
+
for key in ['useUnicode', 'characterEncoding', 'serverTimezone', 'zeroDateTimeBehavior']:
|
|
146
|
+
if key in params:
|
|
147
|
+
del params[key]
|
|
148
|
+
|
|
149
|
+
# 构建数据库连接 URL(使用 aiomysql 支持异步)
|
|
150
|
+
self.db_url = f'mysql+aiomysql://{self.db_user}:{self.db_password}@{self.db_host}:{self.db_port}/{self.db_name}'
|
|
151
|
+
|
|
152
|
+
# 日志中隐藏密码
|
|
153
|
+
safe_url = f'mysql+aiomysql://{self.db_user}:***@{self.db_host}:{self.db_port}/{self.db_name}'
|
|
154
|
+
SYLogger.info(f"TokenUsageDBService Database URL: {safe_url}")
|
|
155
|
+
|
|
156
|
+
# 创建异步引擎
|
|
157
|
+
self.engine = create_async_engine(
|
|
158
|
+
self.db_url,
|
|
159
|
+
connect_args=params,
|
|
160
|
+
pool_size=5, # Token 记录连接池较小
|
|
161
|
+
max_overflow=10,
|
|
162
|
+
pool_timeout=30,
|
|
163
|
+
pool_recycle=3600,
|
|
164
|
+
pool_pre_ping=True,
|
|
165
|
+
echo=False,
|
|
166
|
+
)
|
|
167
|
+
|
|
168
|
+
# 注册 SQL 日志拦截器
|
|
169
|
+
from sycommon.logging.async_sql_logger import AsyncSQLTraceLogger
|
|
170
|
+
AsyncSQLTraceLogger.setup_sql_logging(self.engine)
|
|
171
|
+
|
|
172
|
+
async def test_connection(self) -> bool:
|
|
173
|
+
"""测试数据库连接"""
|
|
174
|
+
try:
|
|
175
|
+
async with self.engine.connect() as connection:
|
|
176
|
+
await connection.execute(text("SELECT 1"))
|
|
177
|
+
return True
|
|
178
|
+
except Exception as e:
|
|
179
|
+
SYLogger.error(f"TokenUsageDBService connection test failed: {e}")
|
|
180
|
+
return False
|
{sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/llm/struct_token.py
RENAMED
|
@@ -241,7 +241,6 @@ class StructuredRunnableWithToken(Runnable):
|
|
|
241
241
|
self,
|
|
242
242
|
user_id: str,
|
|
243
243
|
token_usage: Dict[str, Any],
|
|
244
|
-
trace_id: str,
|
|
245
244
|
model: Optional[str] = None
|
|
246
245
|
):
|
|
247
246
|
"""记录 Token 使用量到 MySQL(Fire-and-forget 模式,自动初始化)"""
|
|
@@ -253,15 +252,13 @@ class StructuredRunnableWithToken(Runnable):
|
|
|
253
252
|
tenant_id = get_header_value(
|
|
254
253
|
SYLogger.get_headers(), "x-tenant-header")
|
|
255
254
|
|
|
256
|
-
|
|
255
|
+
# 调用记录服务(service_name 和 system_env 由服务内部自动获取)
|
|
256
|
+
TokenUsageMySQLService.record_sync(
|
|
257
257
|
user_id=user_id,
|
|
258
258
|
input_tokens=token_usage.get("input_tokens", 0),
|
|
259
259
|
output_tokens=token_usage.get("output_tokens", 0),
|
|
260
|
-
model=model or self.model_name,
|
|
261
|
-
|
|
262
|
-
system=get_env_var('VERSION'),
|
|
263
|
-
tenant_id=tenant_id,
|
|
264
|
-
service_name=get_env_var('VERSION')
|
|
260
|
+
model=model or self.llmConfig.model if self.llmConfig else self.model_name,
|
|
261
|
+
tenant_id=tenant_id
|
|
265
262
|
)
|
|
266
263
|
except Exception as e:
|
|
267
264
|
SYLogger.warning(f"Token 使用量记录失败: {e}")
|
|
@@ -270,7 +267,6 @@ class StructuredRunnableWithToken(Runnable):
|
|
|
270
267
|
self,
|
|
271
268
|
user_id: str,
|
|
272
269
|
token_usage: Dict[str, Any],
|
|
273
|
-
trace_id: str,
|
|
274
270
|
model: Optional[str] = None
|
|
275
271
|
):
|
|
276
272
|
"""记录 Token 使用量到 MySQL(异步,自动初始化)"""
|
|
@@ -285,16 +281,13 @@ class StructuredRunnableWithToken(Runnable):
|
|
|
285
281
|
tenant_id = get_header_value(
|
|
286
282
|
SYLogger.get_headers(), "x-tenant-header")
|
|
287
283
|
|
|
288
|
-
#
|
|
289
|
-
await TokenUsageMySQLService.
|
|
284
|
+
# 调用记录服务(service_name 和 system_env 由服务内部自动获取)
|
|
285
|
+
await TokenUsageMySQLService.record(
|
|
290
286
|
user_id=user_id,
|
|
291
287
|
input_tokens=token_usage.get("input_tokens", 0),
|
|
292
288
|
output_tokens=token_usage.get("output_tokens", 0),
|
|
293
|
-
model=model or self.model_name,
|
|
294
|
-
|
|
295
|
-
system=get_env_var('VERSION'),
|
|
296
|
-
tenant_id=tenant_id,
|
|
297
|
-
service_name=get_env_var('VERSION')
|
|
289
|
+
model=model or self.llmConfig.model if self.llmConfig else self.model_name,
|
|
290
|
+
tenant_id=tenant_id
|
|
298
291
|
)
|
|
299
292
|
except Exception as e:
|
|
300
293
|
SYLogger.warning(f"Token 使用量记录失败: {e}")
|
|
@@ -342,11 +335,10 @@ class StructuredRunnableWithToken(Runnable):
|
|
|
342
335
|
return processed_config, token_handler
|
|
343
336
|
|
|
344
337
|
def invoke(self, input: Any, config: Optional[RunnableConfig] = None, **kwargs) -> Dict[str, Any]:
|
|
345
|
-
# 获取 trace_id 和 user_id
|
|
338
|
+
# 获取 trace_id 和 user_id(只从请求头获取,没有则为空)
|
|
346
339
|
trace_id = SYLogger.get_trace_id()
|
|
347
340
|
userid = get_header_value(SYLogger.get_headers(), "x-userid-header")
|
|
348
|
-
|
|
349
|
-
user_id = userid or syVersion or get_env_var('VERSION')
|
|
341
|
+
user_id = userid if userid else None
|
|
350
342
|
|
|
351
343
|
# 判断是否启用 Langfuse
|
|
352
344
|
if self.langfuse:
|
|
@@ -364,11 +356,10 @@ class StructuredRunnableWithToken(Runnable):
|
|
|
364
356
|
return self._execute_chain(input, config, trace_id, user_id, None)
|
|
365
357
|
|
|
366
358
|
async def ainvoke(self, input: Any, config: Optional[RunnableConfig] = None, **kwargs) -> Dict[str, Any]:
|
|
367
|
-
# 获取 trace_id 和 user_id
|
|
359
|
+
# 获取 trace_id 和 user_id(只从请求头获取,没有则为空)
|
|
368
360
|
trace_id = SYLogger.get_trace_id()
|
|
369
361
|
userid = get_header_value(SYLogger.get_headers(), "x-userid-header")
|
|
370
|
-
|
|
371
|
-
user_id = userid or syVersion or get_env_var('VERSION')
|
|
362
|
+
user_id = userid if userid else None
|
|
372
363
|
|
|
373
364
|
# 判断是否启用 Langfuse
|
|
374
365
|
if self.langfuse:
|
|
@@ -428,7 +419,7 @@ class StructuredRunnableWithToken(Runnable):
|
|
|
428
419
|
structured_result._token_usage_ = token_usage
|
|
429
420
|
|
|
430
421
|
# 记录 Token 使用量到 MySQL
|
|
431
|
-
self._record_token_usage(user_id, token_usage
|
|
422
|
+
self._record_token_usage(user_id, token_usage)
|
|
432
423
|
|
|
433
424
|
return structured_result
|
|
434
425
|
except Exception as e:
|
|
@@ -489,7 +480,7 @@ class StructuredRunnableWithToken(Runnable):
|
|
|
489
480
|
structured_result._token_usage_ = token_usage
|
|
490
481
|
|
|
491
482
|
# 异步记录 Token 使用量到 MySQL
|
|
492
|
-
await self._record_token_usage_async(user_id, token_usage
|
|
483
|
+
await self._record_token_usage_async(user_id, token_usage)
|
|
493
484
|
|
|
494
485
|
return structured_result
|
|
495
486
|
except Exception as e:
|
{sycommon_python_lib-0.2.0b22 → sycommon_python_lib-0.2.0b24}/src/sycommon/llm/sy_langfuse.py
RENAMED
|
@@ -74,9 +74,7 @@ class LangfuseInitializer(metaclass=SingletonMeta):
|
|
|
74
74
|
trace_id = SYLogger.get_trace_id()
|
|
75
75
|
userid = get_header_value(
|
|
76
76
|
SYLogger.get_headers(), "x-userid-header")
|
|
77
|
-
|
|
78
|
-
SYLogger.get_headers(), "s-y-version")
|
|
79
|
-
user_id = userid or syVersion or get_env_var('VERSION')
|
|
77
|
+
user_id = userid if userid else None
|
|
80
78
|
metadata_config = {
|
|
81
79
|
"langfuse_session_id": trace_id,
|
|
82
80
|
"langfuse_user_id": user_id,
|