sycommon-python-lib 0.2.0b20__tar.gz → 0.2.0b22__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.
Files changed (136) hide show
  1. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/PKG-INFO +3 -1
  2. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/pyproject.toml +3 -1
  3. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/config/Config.py +17 -0
  4. sycommon_python_lib-0.2.0b22/src/sycommon/config/ElasticsearchConfig.py +65 -0
  5. sycommon_python_lib-0.2.0b22/src/sycommon/config/RedisConfig.py +150 -0
  6. sycommon_python_lib-0.2.0b22/src/sycommon/database/elasticsearch_service.py +104 -0
  7. sycommon_python_lib-0.2.0b22/src/sycommon/database/redis_service.py +767 -0
  8. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/llm/struct_token.py +69 -0
  9. sycommon_python_lib-0.2.0b22/src/sycommon/llm/token_usage_es_service.py +539 -0
  10. sycommon_python_lib-0.2.0b22/src/sycommon/llm/token_usage_mysql_service.py +727 -0
  11. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/llm/usage_token.py +87 -4
  12. sycommon_python_lib-0.2.0b22/src/sycommon/models/token_usage.py +25 -0
  13. sycommon_python_lib-0.2.0b22/src/sycommon/models/token_usage_mysql.py +58 -0
  14. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/rabbitmq/rabbitmq_pool.py +29 -9
  15. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/services.py +38 -4
  16. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/synacos/nacos_heartbeat_manager.py +25 -5
  17. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/synacos/nacos_service_discovery.py +14 -9
  18. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon_python_lib.egg-info/PKG-INFO +3 -1
  19. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon_python_lib.egg-info/SOURCES.txt +8 -0
  20. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon_python_lib.egg-info/requires.txt +2 -0
  21. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/README.md +0 -0
  22. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/setup.cfg +0 -0
  23. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/command/__init__.py +0 -0
  24. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/command/cli.py +0 -0
  25. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/command/console.py +0 -0
  26. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/command/models.py +0 -0
  27. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/command/project.py +0 -0
  28. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/command/utils.py +0 -0
  29. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/__init__.py +0 -0
  30. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/agent/__init__.py +0 -0
  31. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/agent/examples/01_basic_agent.py +0 -0
  32. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/agent/examples/02_tool_agent.py +0 -0
  33. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/agent/examples/03_structured_output.py +0 -0
  34. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/agent/examples/04_memory_agent.py +0 -0
  35. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/agent/examples/05_streaming.py +0 -0
  36. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/agent/examples/06_multi_agent.py +0 -0
  37. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/agent/examples/07_skills_agent.py +0 -0
  38. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/agent/examples/08_middleware.py +0 -0
  39. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/agent/examples/09_interrupt.py +0 -0
  40. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/agent/examples/10_custom_llm.py +0 -0
  41. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/agent/examples/11_complex_workflow.py +0 -0
  42. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/agent/examples/12_batch_processing.py +0 -0
  43. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/agent/examples/__init__.py +0 -0
  44. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/agent/examples/middleware/01_basic_monitoring.py +0 -0
  45. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/agent/examples/middleware/02_permission_control.py +0 -0
  46. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/agent/examples/middleware/03_tool_skill_filter.py +0 -0
  47. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/agent/examples/middleware/04_caching_retry.py +0 -0
  48. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/agent/examples/middleware/05_sanitization.py +0 -0
  49. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/agent/examples/middleware/06_tracking.py +0 -0
  50. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/agent/examples/middleware/07_advanced.py +0 -0
  51. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/agent/examples/middleware/08_progressive_skills.py +0 -0
  52. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/agent/examples/middleware/__init__.py +0 -0
  53. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/agent/examples/middleware/override_examples.py +0 -0
  54. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/agent/get_agent.py +0 -0
  55. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/config/DatabaseConfig.py +0 -0
  56. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/config/EmbeddingConfig.py +0 -0
  57. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/config/LLMConfig.py +0 -0
  58. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/config/LangfuseConfig.py +0 -0
  59. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/config/MQConfig.py +0 -0
  60. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/config/RerankerConfig.py +0 -0
  61. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/config/SentryConfig.py +0 -0
  62. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/config/__init__.py +0 -0
  63. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/database/async_base_db_service.py +0 -0
  64. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/database/async_database_service.py +0 -0
  65. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/database/base_db_service.py +0 -0
  66. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/database/database_service.py +0 -0
  67. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/health/__init__.py +0 -0
  68. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/health/health_check.py +0 -0
  69. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/health/metrics.py +0 -0
  70. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/health/ping.py +0 -0
  71. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/llm/__init__.py +0 -0
  72. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/llm/embedding.py +0 -0
  73. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/llm/get_llm.py +0 -0
  74. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/llm/llm_logger.py +0 -0
  75. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/llm/llm_tokens.py +0 -0
  76. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/llm/sy_langfuse.py +0 -0
  77. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/logging/__init__.py +0 -0
  78. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/logging/async_sql_logger.py +0 -0
  79. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/logging/kafka_log.py +0 -0
  80. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/logging/logger_levels.py +0 -0
  81. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/logging/logger_wrapper.py +0 -0
  82. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/logging/sql_logger.py +0 -0
  83. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/middleware/__init__.py +0 -0
  84. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/middleware/context.py +0 -0
  85. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/middleware/cors.py +0 -0
  86. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/middleware/docs.py +0 -0
  87. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/middleware/exception.py +0 -0
  88. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/middleware/middleware.py +0 -0
  89. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/middleware/monitor_memory.py +0 -0
  90. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/middleware/mq.py +0 -0
  91. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/middleware/timeout.py +0 -0
  92. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/middleware/traceid.py +0 -0
  93. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/models/__init__.py +0 -0
  94. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/models/base_http.py +0 -0
  95. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/models/log.py +0 -0
  96. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/models/mqlistener_config.py +0 -0
  97. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/models/mqmsg_model.py +0 -0
  98. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/models/mqsend_config.py +0 -0
  99. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/models/sso_user.py +0 -0
  100. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/notice/__init__.py +0 -0
  101. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/notice/uvicorn_monitor.py +0 -0
  102. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/rabbitmq/rabbitmq_client.py +0 -0
  103. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/rabbitmq/rabbitmq_service.py +0 -0
  104. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/rabbitmq/rabbitmq_service_client_manager.py +0 -0
  105. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/rabbitmq/rabbitmq_service_connection_monitor.py +0 -0
  106. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/rabbitmq/rabbitmq_service_consumer_manager.py +0 -0
  107. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/rabbitmq/rabbitmq_service_core.py +0 -0
  108. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/rabbitmq/rabbitmq_service_producer_manager.py +0 -0
  109. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/sentry/__init__.py +0 -0
  110. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/sentry/sy_sentry.py +0 -0
  111. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/sse/__init__.py +0 -0
  112. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/sse/event.py +0 -0
  113. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/sse/sse.py +0 -0
  114. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/synacos/__init__.py +0 -0
  115. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/synacos/example.py +0 -0
  116. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/synacos/example2.py +0 -0
  117. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/synacos/feign.py +0 -0
  118. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/synacos/feign_client.py +0 -0
  119. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/synacos/nacos_client_base.py +0 -0
  120. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/synacos/nacos_config_manager.py +0 -0
  121. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/synacos/nacos_service.py +0 -0
  122. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/synacos/nacos_service_registration.py +0 -0
  123. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/synacos/param.py +0 -0
  124. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/tests/test_email.py +0 -0
  125. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/tests/test_mq.py +0 -0
  126. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/tools/__init__.py +0 -0
  127. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/tools/async_utils.py +0 -0
  128. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/tools/docs.py +0 -0
  129. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/tools/env.py +0 -0
  130. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/tools/merge_headers.py +0 -0
  131. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/tools/snowflake.py +0 -0
  132. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/tools/syemail.py +0 -0
  133. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon/tools/timing.py +0 -0
  134. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon_python_lib.egg-info/dependency_links.txt +0 -0
  135. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon_python_lib.egg-info/entry_points.txt +0 -0
  136. {sycommon_python_lib-0.2.0b20 → sycommon_python_lib-0.2.0b22}/src/sycommon_python_lib.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sycommon-python-lib
3
- Version: 0.2.0b20
3
+ Version: 0.2.0b22
4
4
  Summary: Add your description here
5
5
  Requires-Python: >=3.11
6
6
  Description-Content-Type: text/markdown
@@ -10,6 +10,7 @@ Requires-Dist: aiomysql>=0.3.2
10
10
  Requires-Dist: anyio>=4.12.1
11
11
  Requires-Dist: decorator>=5.2.1
12
12
  Requires-Dist: deepagents>=0.4.5
13
+ Requires-Dist: elasticsearch>=9.3.0
13
14
  Requires-Dist: fastapi>=0.133.1
14
15
  Requires-Dist: jinja2>=3.1.6
15
16
  Requires-Dist: kafka-python>=2.3.0
@@ -26,6 +27,7 @@ Requires-Dist: pydantic>=2.12.5
26
27
  Requires-Dist: python-dotenv>=1.2.1
27
28
  Requires-Dist: python-multipart>=0.0.22
28
29
  Requires-Dist: pyyaml>=6.0.3
30
+ Requires-Dist: redis>=7.3.0
29
31
  Requires-Dist: sentry-sdk[fastapi]>=2.53.0
30
32
  Requires-Dist: sqlalchemy[asyncio]>=2.0.47
31
33
  Requires-Dist: starlette>=0.52.1
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "sycommon-python-lib"
3
- version = "0.2.0b20"
3
+ version = "0.2.0b22"
4
4
  description = "Add your description here"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.11"
@@ -11,6 +11,7 @@ dependencies = [
11
11
  "anyio>=4.12.1",
12
12
  "decorator>=5.2.1",
13
13
  "deepagents>=0.4.5",
14
+ "elasticsearch>=9.3.0",
14
15
  "fastapi>=0.133.1",
15
16
  "jinja2>=3.1.6",
16
17
  "kafka-python>=2.3.0",
@@ -27,6 +28,7 @@ dependencies = [
27
28
  "python-dotenv>=1.2.1",
28
29
  "python-multipart>=0.0.22",
29
30
  "pyyaml>=6.0.3",
31
+ "redis>=7.3.0",
30
32
  "sentry-sdk[fastapi]>=2.53.0",
31
33
  "sqlalchemy[asyncio]>=2.0.47",
32
34
  "starlette>=0.52.1",
@@ -22,6 +22,7 @@ class Config(metaclass=SingletonMeta):
22
22
  self.reranker_configs = []
23
23
  self.sentry_configs = []
24
24
  self.langfuse_configs = []
25
+ self.elasticsearch_configs = []
25
26
  self._process_config()
26
27
 
27
28
  def get_llm_config(self, model_name):
@@ -54,6 +55,12 @@ class Config(metaclass=SingletonMeta):
54
55
  return langfuse
55
56
  raise ValueError(f"No configuration found for server: {name}")
56
57
 
58
+ def get_elasticsearch_config(self, name="default"):
59
+ for es in self.elasticsearch_configs:
60
+ if es.get('name') == name:
61
+ return es
62
+ raise ValueError(f"No configuration found for elasticsearch: {name}")
63
+
57
64
  def _process_config(self):
58
65
  llm_config_list = self.config.get('LLMConfig', [])
59
66
  for llm_config in llm_config_list:
@@ -92,6 +99,16 @@ class Config(metaclass=SingletonMeta):
92
99
  except ValueError as e:
93
100
  print(f"Invalid Sentry configuration: {e}")
94
101
 
102
+ elasticsearch_config_list = self.config.get('ElasticsearchConfig', [])
103
+ for es_config in elasticsearch_config_list:
104
+ try:
105
+ from sycommon.config.ElasticsearchConfig import ElasticsearchConfig
106
+ validated_config = ElasticsearchConfig(**es_config)
107
+ self.elasticsearch_configs.append(
108
+ validated_config.model_dump())
109
+ except ValueError as e:
110
+ print(f"Invalid Elasticsearch configuration: {e}")
111
+
95
112
  def set_attr(self, share_configs: dict):
96
113
  self.config = {**self.config, **
97
114
  share_configs.get('llm', {}), **share_configs}
@@ -0,0 +1,65 @@
1
+ from pydantic import BaseModel, Field
2
+ from typing import List
3
+ import re
4
+
5
+
6
+ class ElasticsearchConfig(BaseModel):
7
+ """Elasticsearch 配置"""
8
+ name: str = Field(default="default", description="配置名称")
9
+ uris: str = Field(..., description="ES节点地址,多个用英文逗号分隔")
10
+ username: str = Field(default="elastic", description="用户名")
11
+ password: str = Field(..., description="密码")
12
+
13
+ @property
14
+ def uri_list(self) -> List[str]:
15
+ """获取 URI 列表,自动补全 scheme 和 port"""
16
+ uris = [uri.strip() for uri in self.uris.split(",") if uri.strip()]
17
+ normalized = []
18
+ for uri in uris:
19
+ normalized.append(self._normalize_uri(uri))
20
+ return normalized
21
+
22
+ @staticmethod
23
+ def _normalize_uri(uri: str) -> str:
24
+ """
25
+ 标准化 ES URI,确保包含 scheme、host 和 port
26
+
27
+ Examples:
28
+ localhost:9200 -> http://localhost:9200
29
+ localhost -> http://localhost:9200
30
+ 10.10.6.202:9200 -> http://10.10.6.202:9200
31
+ http://localhost:9200 -> http://localhost:9200
32
+ https://localhost:9200 -> https://localhost:9200
33
+ """
34
+ uri = uri.strip()
35
+
36
+ # 已有 scheme
37
+ if uri.startswith("http://") or uri.startswith("https://"):
38
+ # 检查是否有 port
39
+ # http://localhost -> http://localhost:9200
40
+ parsed = re.match(r'(https?://)([^:/]+)(:\d+)?(.*)$', uri)
41
+ if parsed:
42
+ scheme = parsed.group(1)
43
+ host = parsed.group(2)
44
+ port = parsed.group(3)
45
+ if not port:
46
+ port = ":9200"
47
+ return f"{scheme}{host}{port}"
48
+ return uri
49
+
50
+ # 没有 scheme,默认 http
51
+ # localhost:9200 -> http://localhost:9200
52
+ # localhost -> http://localhost:9200
53
+ if ":" in uri:
54
+ # 有端口
55
+ return f"http://{uri}"
56
+ else:
57
+ # 没有端口,默认 9200
58
+ return f"http://{uri}:9200"
59
+
60
+ @classmethod
61
+ def from_config(cls, name: str = "default"):
62
+ """从配置文件获取 ES 配置"""
63
+ from sycommon.config.Config import Config
64
+ es_config = Config().get_elasticsearch_config(name)
65
+ return cls(**es_config)
@@ -0,0 +1,150 @@
1
+ from pydantic import BaseModel, Field
2
+ from typing import Optional, List
3
+ import re
4
+
5
+
6
+ class RedisPoolConfig(BaseModel):
7
+ """Redis 连接池配置(对应 Spring Lettuce Pool)"""
8
+ max_active: int = Field(default=50, description="最大活跃连接数")
9
+ max_idle: int = Field(default=10, description="最大空闲连接数")
10
+ max_wait: int = Field(default=30, description="最大等待时间(秒)")
11
+ min_idle: int = Field(default=1, description="最小空闲连接数")
12
+
13
+
14
+ class RedisSentinelConfig(BaseModel):
15
+ """Redis Sentinel 配置"""
16
+ master: str = Field(..., description="主节点名称")
17
+ nodes: List[str] = Field(default_factory=list, description="Sentinel 节点列表")
18
+ topology_refresh_interval: Optional[int] = Field(default=None, description="拓扑刷新间隔(秒)")
19
+
20
+ @classmethod
21
+ def from_dict(cls, sentinel: dict) -> "RedisSentinelConfig":
22
+ """从字典解析 Sentinel 配置"""
23
+ nodes_str = sentinel.get("nodes", "")
24
+ # 解析节点列表,支持逗号分隔
25
+ nodes = []
26
+ if nodes_str:
27
+ nodes = [n.strip() for n in nodes_str.split(",") if n.strip()]
28
+
29
+ # 解析拓扑刷新间隔
30
+ topology_refresh_interval = None
31
+ topology_refresh = sentinel.get("topologyRefresh", {})
32
+ if topology_refresh:
33
+ interval = topology_refresh.get("interval")
34
+ if interval:
35
+ topology_refresh_interval = RedisConfig._parse_duration(interval)
36
+
37
+ return cls(
38
+ master=sentinel.get("master", "mymaster"),
39
+ nodes=nodes,
40
+ topology_refresh_interval=topology_refresh_interval
41
+ )
42
+
43
+
44
+ class RedisConfig(BaseModel):
45
+ """Redis 配置(对应 Spring Redis YAML 格式)"""
46
+ host: str = Field(default="localhost", description="Redis 主机地址")
47
+ port: int = Field(default=6379, description="Redis 端口")
48
+ password: Optional[str] = Field(default=None, description="密码")
49
+ database: int = Field(default=0, description="数据库索引")
50
+ timeout: int = Field(default=60, description="超时时间(秒)")
51
+ pool: Optional[RedisPoolConfig] = Field(default=None, description="连接池配置")
52
+ sentinel: Optional[RedisSentinelConfig] = Field(default=None, description="Sentinel 配置")
53
+
54
+ @classmethod
55
+ def from_spring_yaml(cls, config: dict) -> "RedisConfig":
56
+ """
57
+ 从 Spring Redis YAML 格式解析配置
58
+
59
+ 支持两种模式:
60
+ 1. 单机模式:配置 host/port
61
+ 2. Sentinel 模式:配置 sentinel.master/nodes
62
+
63
+ Args:
64
+ config: Spring Redis 配置字典
65
+
66
+ Returns:
67
+ RedisConfig 实例
68
+ """
69
+ # 获取 spring.redis 配置
70
+ spring_config = config.get("spring", {})
71
+ redis_config = spring_config.get("redis", {})
72
+
73
+ if not redis_config:
74
+ raise ValueError("未找到 Spring Redis 配置")
75
+
76
+ # 解析超时时间(支持 "60s" 格式)
77
+ timeout = redis_config.get("timeout", 60)
78
+ if isinstance(timeout, str):
79
+ timeout = cls._parse_duration(timeout)
80
+
81
+ # 解析连接池配置
82
+ pool_config = None
83
+ lettuce = redis_config.get("lettuce", {})
84
+ pool = lettuce.get("pool", {})
85
+ if pool:
86
+ max_wait = pool.get("max-wait", 30)
87
+ if isinstance(max_wait, str):
88
+ max_wait = cls._parse_duration(max_wait)
89
+
90
+ pool_config = RedisPoolConfig(
91
+ max_active=pool.get("max-active", 50),
92
+ max_idle=pool.get("max-idle", 10),
93
+ max_wait=max_wait,
94
+ min_idle=pool.get("min-idle", 1)
95
+ )
96
+
97
+ # 解析 Sentinel 配置
98
+ sentinel_config = None
99
+ sentinel = redis_config.get("sentinel", {})
100
+ if sentinel and sentinel.get("master") and sentinel.get("nodes"):
101
+ sentinel_config = RedisSentinelConfig.from_dict(sentinel)
102
+
103
+ return cls(
104
+ host=redis_config.get("host", "localhost"),
105
+ port=redis_config.get("port", 6379),
106
+ password=redis_config.get("password"),
107
+ database=redis_config.get("database", 0),
108
+ timeout=timeout,
109
+ pool=pool_config,
110
+ sentinel=sentinel_config
111
+ )
112
+
113
+ @staticmethod
114
+ def _parse_duration(duration: str) -> int:
115
+ """
116
+ 解析持续时间字符串为秒数
117
+
118
+ Args:
119
+ duration: 持续时间字符串,如 "60s", "30s", "1m"
120
+
121
+ Returns:
122
+ 秒数
123
+ """
124
+ if not duration:
125
+ return 60
126
+
127
+ if isinstance(duration, (int, float)):
128
+ return int(duration)
129
+
130
+ # 匹配数字和单位
131
+ match = re.match(r"(\d+)([smh]?)", str(duration).strip())
132
+ if not match:
133
+ return 60
134
+
135
+ value = int(match.group(1))
136
+ unit = match.group(2) or "s"
137
+
138
+ if unit == "s":
139
+ return value
140
+ elif unit == "m":
141
+ return value * 60
142
+ elif unit == "h":
143
+ return value * 3600
144
+
145
+ return value
146
+
147
+ @property
148
+ def is_sentinel_mode(self) -> bool:
149
+ """是否为 Sentinel 模式"""
150
+ return self.sentinel is not None and len(self.sentinel.nodes) > 0
@@ -0,0 +1,104 @@
1
+ """
2
+ Elasticsearch 异步服务
3
+ 管理 ES 客户端连接,供其他业务服务使用
4
+ """
5
+ import logging
6
+ from typing import Optional, Any, List
7
+
8
+ from sycommon.config.Config import SingletonMeta
9
+
10
+
11
+ class ElasticsearchService(metaclass=SingletonMeta):
12
+ """Elasticsearch 基础服务(单例)"""
13
+ _client: Optional[Any] = None
14
+ _initialized: bool = False
15
+
16
+ def __init__(self):
17
+ pass
18
+
19
+ @classmethod
20
+ def setup(cls, config: Optional[dict] = None):
21
+ """
22
+ ES 服务初始化函数(用于 Services.plugins 传入)
23
+
24
+ 用法:
25
+ Services.plugins(
26
+ app,
27
+ elasticsearch_service=ElasticsearchService.setup
28
+ )
29
+ """
30
+ cls.init(config)
31
+
32
+ @classmethod
33
+ def init(cls, config: Optional[dict] = None):
34
+ """
35
+ 初始化 ES 连接
36
+
37
+ Args:
38
+ config: 配置字典,包含 ElasticsearchConfig 配置
39
+ """
40
+ if cls._initialized:
41
+ return
42
+
43
+ try:
44
+ from sycommon.config.ElasticsearchConfig import ElasticsearchConfig
45
+ from sycommon.config.Config import Config
46
+
47
+ # 获取 ES 配置
48
+ es_configs = Config().config.get('ElasticsearchConfig', [])
49
+ if not es_configs:
50
+ logging.info("未配置 ElasticsearchConfig,ES 服务将禁用")
51
+ return
52
+
53
+ # 使用第一个配置
54
+ es_config = ElasticsearchConfig(**es_configs[0])
55
+
56
+ # 导入 ES 客户端
57
+ try:
58
+ from elasticsearch import AsyncElasticsearch
59
+ except ImportError:
60
+ logging.warning("未安装 elasticsearch 包,请执行: pip install elasticsearch")
61
+ return
62
+
63
+ # 创建异步客户端
64
+ cls._client = AsyncElasticsearch(
65
+ hosts=es_config.uri_list,
66
+ basic_auth=(es_config.username, es_config.password),
67
+ verify_certs=False,
68
+ retry_on_timeout=True,
69
+ max_retries=3
70
+ )
71
+
72
+ cls._initialized = True
73
+ logging.info(f"ElasticsearchService 初始化成功,ES 地址: {es_config.uris}")
74
+
75
+ except Exception as e:
76
+ logging.error(f"ElasticsearchService 初始化失败: {e}", exc_info=True)
77
+
78
+ @classmethod
79
+ def get_client(cls) -> Optional[Any]:
80
+ """
81
+ 获取 ES 客户端
82
+
83
+ Returns:
84
+ AsyncElasticsearch 客户端实例,未初始化返回 None
85
+ """
86
+ return cls._client
87
+
88
+ @classmethod
89
+ def is_initialized(cls) -> bool:
90
+ """检查是否已初始化"""
91
+ return cls._initialized
92
+
93
+ @classmethod
94
+ async def close(cls):
95
+ """关闭 ES 连接"""
96
+ if cls._client:
97
+ try:
98
+ await cls._client.close()
99
+ logging.info("ElasticsearchService ES 连接已关闭")
100
+ except Exception as e:
101
+ logging.error(f"关闭 ES 连接失败: {e}")
102
+ finally:
103
+ cls._client = None
104
+ cls._initialized = False