springbootAI 2.2.5__tar.gz → 2.2.6__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.
- {springbootai-2.2.5 → springbootai-2.2.6}/CHANGELOG.md +20 -1
- {springbootai-2.2.5/springbootAI.egg-info → springbootai-2.2.6}/PKG-INFO +17 -14
- {springbootai-2.2.5 → springbootai-2.2.6}/README.md +16 -13
- {springbootai-2.2.5 → springbootai-2.2.6}/pyproject.toml +2 -2
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/__init__.py +2 -2
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/cloud/__init__.py +8 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/cloud/seata.py +24 -3
- springbootai-2.2.6/spring/cloud/seata_at_proxy.py +534 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/context/application_context.py +33 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/csv/annotations.py +161 -12
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/csv/reader.py +53 -1
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/excel/annotations.py +161 -12
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/excel/reader.py +54 -1
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/orm/ddl_auto.py +44 -3
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/orm/pymybatis/security/sql_injection_detector.py +5 -3
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/orm/pymybatis/version.py +2 -2
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/security/jwt_utils.py +66 -10
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/utils/banner.py +13 -4
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/validation/validator.py +27 -3
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/web/actuator.py +122 -20
- {springbootai-2.2.5 → springbootai-2.2.6/springbootAI.egg-info}/PKG-INFO +17 -14
- {springbootai-2.2.5 → springbootai-2.2.6}/springbootAI.egg-info/SOURCES.txt +3 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/tests/test_actuator_prometheus_admin.py +83 -3
- springbootai-2.2.6/tests/test_compositional_annotations.py +541 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/tests/test_csv_module.py +336 -24
- {springbootai-2.2.5 → springbootai-2.2.6}/tests/test_excel_module.py +332 -5
- springbootai-2.2.6/tests/test_seata_at_proxy.py +436 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/LICENSE +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/MANIFEST.in +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/SECURITY.md +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/requirements-ai.txt +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/requirements-langgraph.txt +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/requirements-mcp.txt +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/requirements.txt +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/setup.cfg +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/setup.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/ai/__init__.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/ai/advisors.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/ai/annotations.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/ai/autoconfig.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/ai/core.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/ai/etl.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/ai/memory.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/ai/observability.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/ai/providers.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/ai/resilience.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/ai/tools.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/ai/vectorstore.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/annotations/__init__.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/annotations/cache.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/annotations/cloud.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/annotations/conditional.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/annotations/core.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/annotations/langchain.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/annotations/langgraph.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/annotations/messaging.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/aop/__init__.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/aop/aspect.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/aop/cloud_aop.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/aop/comprehensive_aop.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/aop/method_interceptor.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/aop/proxy_factory.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/cloud/discovery.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/cloud/feign.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/cloud/gateway.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/cloud/load_balancer.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/cloud/seata_bridge.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/cloud/sentinel.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/cloud/tracer.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/cloud/transaction_store.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/config/__init__.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/config/binding.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/config/config_loader.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/context/__init__.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/context/bean_definition.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/context/bean_factory.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/context/registry.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/context/scanner.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/core/__init__.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/core/graceful_shutdown.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/core/typing_utils.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/csv/__init__.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/csv/converters.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/csv/easy_csv.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/csv/exceptions.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/csv/writer.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/data/__init__.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/data/page.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/data/repository.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/data/specification.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/datasource/__init__.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/datasource/annotations.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/datasource/context.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/datasource/dynamic.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/event/__init__.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/event/publisher.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/excel/__init__.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/excel/converters.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/excel/easy_excel.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/excel/exceptions.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/excel/style.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/excel/writer.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/i18n/__init__.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/i18n/accessor.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/i18n/auto_config.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/i18n/holder.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/i18n/locale.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/i18n/locale_resolver.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/i18n/message_source.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/i18n/middleware.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/i18n/properties.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/i18n/sources.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/langchain/__init__.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/langchain/adapters.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/langchain/agents/__init__.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/langchain/agents/services.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/langchain/annotations.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/langchain/autoconfig.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/langchain/callbacks/__init__.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/langchain/callbacks/handlers.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/langchain/chains/__init__.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/langchain/chains/services.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/langchain/core.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/langchain/indexes/__init__.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/langchain/indexes/index.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/langchain/loaders/__init__.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/langchain/loaders/loaders.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/langchain/memory/__init__.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/langchain/memory/memory.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/langchain/parsers/__init__.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/langchain/parsers/parsers.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/langchain/partners.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/langchain/prompts/__init__.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/langchain/prompts/templates.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/langchain/retrievers/__init__.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/langchain/retrievers/retrievers.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/langchain/tools/__init__.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/langchain/tools/tools.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/langchain/utilities/__init__.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/langchain/utilities/utils.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/langchain/vectorstores/__init__.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/langchain/vectorstores/stores.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/langgraph/__init__.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/langgraph/annotation_runtime.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/langgraph/annotations.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/langgraph/autoconfig.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/langgraph/checkpoint.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/langgraph/config.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/langgraph/runtime.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/logging/__init__.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/logging/loguru_logger.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/main.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/mcp/__init__.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/mcp/annotation_runtime.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/mcp/annotations.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/mcp/autoconfig.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/mcp/client.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/mcp/config.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/mcp/server.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/messaging/__init__.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/messaging/rabbitmq.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/monitoring/__init__.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/monitoring/prometheus.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/orm/__init__.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/orm/database.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/orm/migration.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/orm/mybatis_integration.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/orm/pymybatis/__init__.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/orm/pymybatis/annotations/__init__.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/orm/pymybatis/annotations/annotations.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/orm/pymybatis/cache/__init__.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/orm/pymybatis/cache/cache.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/orm/pymybatis/cache/redis_cache.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/orm/pymybatis/circuit_breaker/__init__.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/orm/pymybatis/circuit_breaker/circuit_breaker.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/orm/pymybatis/configuration.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/orm/pymybatis/core/__init__.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/orm/pymybatis/core/sql_session.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/orm/pymybatis/core/sql_session_factory.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/orm/pymybatis/dialect/__init__.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/orm/pymybatis/dialect/dialect.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/orm/pymybatis/dynamic_sql/__init__.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/orm/pymybatis/dynamic_sql/dynamic_sql.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/orm/pymybatis/interceptor/__init__.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/orm/pymybatis/interceptor/interceptor.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/orm/pymybatis/mapper/__init__.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/orm/pymybatis/mapper/mapper.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/orm/pymybatis/metrics/__init__.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/orm/pymybatis/metrics/metrics.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/orm/pymybatis/pool/__init__.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/orm/pymybatis/pool/connection_pool.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/orm/pymybatis/security/__init__.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/orm/pymybatis/security/access_control.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/orm/pymybatis/security/password_encoder.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/orm/pymybatis/security/sensitive_data_masker.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/orm/pymybatis/transaction/__init__.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/orm/pymybatis/transaction/transaction.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/orm/pymybatis/type_handler/__init__.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/orm/pymybatis/type_handler/type_handler.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/orm/pymybatis/xml_parser/__init__.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/orm/pymybatis/xml_parser/xml_parser.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/retry/__init__.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/retry/recovery.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/retry/retry_annotations.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/retry/retry_decorator.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/scheduling/__init__.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/scheduling/scheduler.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/security/__init__.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/security/replay_protection.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/security/secret_manager.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/security/security_aop.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/security/security_context.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/test/__init__.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/test/slicing.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/tracing/__init__.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/tracing/skywalking.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/tx/__init__.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/tx/events.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/tx/synchronization.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/utils/__init__.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/utils/bean_utils.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/utils/logger.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/utils/redis_client.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/validation/__init__.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/validation/aop.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/validation/constraints.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/validation/exceptions.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/web/__init__.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/web/exception_handler.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/web/health.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/web/interceptor.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/web/result.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/web/swagger.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/web/web_context.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/websocket/__init__.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/websocket/annotations.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/websocket/broker.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/websocket/exceptions.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/websocket/handler.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/websocket/router.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/spring/websocket/session.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/springbootAI.egg-info/dependency_links.txt +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/springbootAI.egg-info/entry_points.txt +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/springbootAI.egg-info/requires.txt +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/springbootAI.egg-info/top_level.txt +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/sql/seata_undo_log.sql +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/tests/test_actuator.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/tests/test_ai_comprehensive.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/tests/test_ai_declarative_annotations.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/tests/test_ai_module.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/tests/test_annotation_combinations.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/tests/test_annotations_contract.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/tests/test_aop_annotations_full.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/tests/test_audit_time.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/tests/test_bean_utils.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/tests/test_cache_annotations.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/tests/test_cloud_embedded_full.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/tests/test_component_init_error.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/tests/test_conditional_annotations.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/tests/test_config_binding.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/tests/test_config_fixes_185.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/tests/test_connection_resilience.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/tests/test_core_annotations_full.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/tests/test_data_repository.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/tests/test_datasource_routing.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/tests/test_ddl_auto.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/tests/test_declarative_aop_post_authorize_recover.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/tests/test_di_config_event_full.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/tests/test_i18n_module.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/tests/test_jpa_version_transient.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/tests/test_langchain_comprehensive.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/tests/test_langchain_ext.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/tests/test_langchain_module.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/tests/test_langgraph_comprehensive.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/tests/test_langgraph_module.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/tests/test_logging_config.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/tests/test_mcp_module.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/tests/test_new_features.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/tests/test_orm_pymybatis_full.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/tests/test_production_readiness.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/tests/test_pymybatis_contract.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/tests/test_seata_bridge.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/tests/test_seata_durable_store.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/tests/test_security.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/tests/test_security_full.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/tests/test_security_hardening.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/tests/test_select_page.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/tests/test_swagger_module.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/tests/test_test_slicing.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/tests/test_transactional_events.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/tests/test_validation_module.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/tests/test_web_annotations_full.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/tests/test_web_root_mapping.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/tests/test_web_static_files.py +0 -0
- {springbootai-2.2.5 → springbootai-2.2.6}/tests/test_websocket_module.py +0 -0
|
@@ -1,5 +1,25 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [2.2.6] - 2026-08-15
|
|
4
|
+
|
|
5
|
+
### 新增
|
|
6
|
+
|
|
7
|
+
- **Seata AT 数据源代理**:新增 `spring/cloud/seata_at_proxy.py`(500 行),在 ORM 拦截器层自动记录 SQL 的 before/after image,生成 undo_log,全局事务回滚时自动反向恢复数据。支持 MySQL(`%s`) 和 SQLite(`?`) 占位符自动适配。Seata 模式从三模式(local/http/distributed)扩展为四模式(新增 `at`)。
|
|
8
|
+
- **AT 代理测试**:新增 `tests/test_seata_at_proxy.py`(18 项全通过),覆盖 SQL 解析、undo_log CRUD、undo 反向恢复(INSERT→DELETE / UPDATE→UPDATE before / DELETE→INSERT before)、AT 拦截器记录、提交删除 undo_log。
|
|
9
|
+
|
|
10
|
+
### 重构
|
|
11
|
+
|
|
12
|
+
- **目录整合**:`example_all`、`example_langchain`、`example_langgraph`、`example_mcp`、`test_cloud_app` 五个散落目录合并到 `examples/` 下;`tests_integration`、`tests_performance`、`tests_runtime` 合并到 `tests/integration/`、`tests/performance/`、`tests/runtime/`。`pyproject.toml` 的 `pythonpath` 增加 `examples`,5 个入口脚本修复 `sys.path`。
|
|
13
|
+
- **文档整理**:`REPOSITORY_MODULE.md` 合并到 `ORM_MODULE.md`(减少文档碎片),更新 README 导航表和 3 处引用。
|
|
14
|
+
- **路径引用同步**:CI 4 个 workflow、11 个文档、Dockerfile、benchmark_app.py 中的 example/tests 路径全部更新。
|
|
15
|
+
|
|
16
|
+
### 文档
|
|
17
|
+
|
|
18
|
+
- `README.md` Seata 边界说明从"⚠️ 有边界"改为"✅ 可用"(3 处)。
|
|
19
|
+
- `doc/CLOUD_MODULE.md` 新增 AT 模式使用指南(工作流程图 + 代码示例 + 限制说明)。
|
|
20
|
+
- `doc/ORM_MODULE.md` 新增"Repository 分页查询"章节(原 REPOSITORY_MODULE.md 内容)。
|
|
21
|
+
- 25 个文件版本号从 2.2.5 更新到 2.2.6。
|
|
22
|
+
|
|
3
23
|
## [2.2.5] - 2026-08-14
|
|
4
24
|
|
|
5
25
|
### 新增
|
|
@@ -14,7 +34,6 @@
|
|
|
14
34
|
- `doc/ACTUATOR_MODULE.md` 新增第四章(Spring Boot Admin 可视化面板)、第五章(Prometheus + Grafana 工业级监控,含三步接入流程与多 worker 注意事项)、第六章(自定义业务指标)。
|
|
15
35
|
- `doc/ORM_MODULE.md` 第五章新增"方法 1:@SelectPage 注解(推荐)"小节。
|
|
16
36
|
- `README.md` 4.8 健康检查表新增 `/actuator/admin`、`/actuator/prometheus`、`/actuator/sysmetrics` 三个端点。
|
|
17
|
-
- `doc/EIGHT_MODULES.md` Actuator 模块说明补充"Spring Boot Admin 可视化 + Prometheus 指标"。
|
|
18
37
|
|
|
19
38
|
### 测试
|
|
20
39
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: springbootAI
|
|
3
|
-
Version: 2.2.
|
|
3
|
+
Version: 2.2.6
|
|
4
4
|
Summary: Spring-style Python framework with Web, ORM, Cloud and AI integrations
|
|
5
5
|
Author-email: YuConggen <1516933915@qq.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -132,7 +132,11 @@ Requires-Dist: langgraph-checkpoint-sqlite==3.1.1; extra == "full"
|
|
|
132
132
|
Requires-Dist: mcp==2.0.0; extra == "full"
|
|
133
133
|
Dynamic: license-file
|
|
134
134
|
|
|
135
|
-
# SpringBootAI
|
|
135
|
+
# SpringBootAI
|
|
136
|
+
|
|
137
|
+
<p align="center">
|
|
138
|
+
<img src="doc/images/hero-banner.png" alt="SpringBootAI 功能总览" width="100%" />
|
|
139
|
+
</p>
|
|
136
140
|
|
|
137
141
|
[](https://pypi.org/project/springbootAI/)
|
|
138
142
|
[](https://pypi.org/project/springbootAI/)
|
|
@@ -151,7 +155,7 @@ SpringBootAI 是一个采用 Spring 风格注解和分层结构的 Python 应用
|
|
|
151
155
|
| AI 与编排 | 模型调用、Tools、RAG、Chain、状态图、MCP client/server | LangChain / LangGraph / 官方 MCP SDK |
|
|
152
156
|
| 生产治理 | 健康检查、Prometheus、限流熔断、追踪、Swagger | prometheus-client / OpenTelemetry / OpenAPI |
|
|
153
157
|
|
|
154
|
-
当前版本是 `2.2.
|
|
158
|
+
当前版本是 `2.2.6`;支持 Python 3.10、3.11 和 3.12,许可证为 MIT。项目仍标记为 Beta。用于公网高并发、合规敏感或支付/订单/库存等核心系统前,必须完成目标数据库、流量模型、故障恢复和安全基线验证。内嵌 Gateway 适合内部路由,不替代公网 Nginx/Kong/WAF;Seata `distributed` 对接官方 TC + TCC 回调;`at` 模式通过 ORM 拦截器自动生成 undo_log 实现自动回滚。
|
|
155
159
|
|
|
156
160
|
[新手指南](https://github.com/YUCONGGEN/springbootAI/blob/master/doc/BEGINNER_GUIDE.md) | [全部文档](https://github.com/YUCONGGEN/springbootAI/tree/master/doc) | [变更日志](https://github.com/YUCONGGEN/springbootAI/blob/master/CHANGELOG.md) | [安全报告](https://github.com/YUCONGGEN/springbootAI/blob/master/SECURITY.md) | [发布检查](https://github.com/YUCONGGEN/springbootAI/blob/master/doc/RELEASE_CHECKLIST.md)
|
|
157
161
|
|
|
@@ -251,7 +255,7 @@ curl http://127.0.0.1:8080/api/hello/Alice
|
|
|
251
255
|
| 📦 LangChain | [LANGCHAIN_MODULE.md](https://github.com/YUCONGGEN/springbootAI/blob/master/doc/LANGCHAIN_MODULE.md) | `pip install springbootAI[langchain]` | Chains / Agents / Memory / Retrievers / VectorStores / 30+ 提供商 |
|
|
252
256
|
| 📦 LangGraph | [LANGGRAPH_MODULE.md](https://github.com/YUCONGGEN/springbootAI/blob/master/doc/LANGGRAPH_MODULE.md) | `pip install springbootAI[langgraph]` | 状态图 / 条件路由 / 人工中断 / 注解式工作流 |
|
|
253
257
|
| 📦 MCP | [MCP_MODULE.md](https://github.com/YUCONGGEN/springbootAI/blob/master/doc/MCP_MODULE.md) | `pip install springbootAI[mcp]` | MCP Client / Server / Tool / Resource / Prompt / 注解调用 |
|
|
254
|
-
| ✅ 内嵌 PyMyBatis ORM | [ORM_MODULE.md](https://github.com/YUCONGGEN/springbootAI/blob/master/doc/ORM_MODULE.md) | 随核心包 | Mapper 注解 / XML Mapper / 分页 / SQL 安全 / DDL 自动建表 |
|
|
258
|
+
| ✅ 内嵌 PyMyBatis ORM | [ORM_MODULE.md](https://github.com/YUCONGGEN/springbootAI/blob/master/doc/ORM_MODULE.md) | 随核心包 | Mapper 注解 / XML Mapper / 分页 / SQL 安全 / DDL 自动建表 / Repository 分页查询 |
|
|
255
259
|
| ✅ JPA 实体与仓库 | [JPA_MODULE.md](https://github.com/YUCONGGEN/springbootAI/blob/master/doc/JPA_MODULE.md) | 随核心包 | `@Entity` + `@Table` / 字段自动推断 / `@CreateTime` / Repository / DataJpaTest |
|
|
256
260
|
| ✅ Cloud 微服务 | [CLOUD_MODULE.md](https://github.com/YUCONGGEN/springbootAI/blob/master/doc/CLOUD_MODULE.md) | 随核心包 | 服务注册发现 / 配置刷新 / Feign / Sentinel / Gateway / 分布式事务 |
|
|
257
261
|
| 📦 Excel 读写 | [EXCEL_MODULE.md](https://github.com/YUCONGGEN/springbootAI/blob/master/doc/EXCEL_MODULE.md) | `pip install springbootAI[excel]` | `@ExcelProperty` / `@ExcelIgnore` 注解驱动读写 |
|
|
@@ -259,7 +263,6 @@ curl http://127.0.0.1:8080/api/hello/Alice
|
|
|
259
263
|
| ✅ Swagger 文档 | [SWAGGER_MODULE.md](https://github.com/YUCONGGEN/springbootAI/blob/master/doc/SWAGGER_MODULE.md) | 随核心包 | `@Tag` / `@Operation` 注解驱动 API 文档 |
|
|
260
264
|
| ✅ 安全 | [SECURITY.md](https://github.com/YUCONGGEN/springbootAI/blob/master/doc/SECURITY.md) | 随核心包 | JWT 生成校验 / 密码加密 / SQL 注入防护 / 访问控制 |
|
|
261
265
|
| ✅ BeanUtils | [BEAN_UTILS.md](https://github.com/YUCONGGEN/springbootAI/blob/master/doc/BEAN_UTILS.md) | 随核心包 | `copy_properties` / `clone` 属性复制工具 |
|
|
262
|
-
| ✅ ① Repository | [REPOSITORY_MODULE.md](https://github.com/YUCONGGEN/springbootAI/blob/master/doc/REPOSITORY_MODULE.md) | 随核心包 | 不用手写SQL的分页查询 |
|
|
263
266
|
| ✅ ② Actuator | [ACTUATOR_MODULE.md](https://github.com/YUCONGGEN/springbootAI/blob/master/doc/ACTUATOR_MODULE.md) | 随核心包 | 系统健康检查面板 |
|
|
264
267
|
| ✅ ③ 多数据源 | [DATASOURCE_MODULE.md](https://github.com/YUCONGGEN/springbootAI/blob/master/doc/DATASOURCE_MODULE.md) | 随核心包 | 读写分离 |
|
|
265
268
|
| ✅ ④ 事务事件 | [TX_EVENT_MODULE.md](https://github.com/YUCONGGEN/springbootAI/blob/master/doc/TX_EVENT_MODULE.md) | 随核心包 | 操作完成后自动发通知 |
|
|
@@ -323,10 +326,10 @@ SpringBootAI 是一个 **Python Web 框架**。它把 Java Spring Boot 的"注
|
|
|
323
326
|
|
|
324
327
|
| 组件 | 当前版本 |
|
|
325
328
|
|------|----------|
|
|
326
|
-
| `spring` 框架 API | 2.2.
|
|
327
|
-
| `spring.orm.pymybatis` | 2.2.
|
|
328
|
-
| `spring.ai` AI 模块 | 2.2.
|
|
329
|
-
| `spring.langchain` LangChain 模块 | 2.2.
|
|
329
|
+
| `spring` 框架 API | 2.2.6 |
|
|
330
|
+
| `spring.orm.pymybatis` | 2.2.6 |
|
|
331
|
+
| `spring.ai` AI 模块 | 2.2.6 |
|
|
332
|
+
| `spring.langchain` LangChain 模块 | 2.2.6 |
|
|
330
333
|
| Python | 3.10+ |
|
|
331
334
|
|
|
332
335
|
### 1.4 适合什么场景
|
|
@@ -342,7 +345,7 @@ SpringBootAI 是一个 **Python Web 框架**。它把 Java Spring Boot 的"注
|
|
|
342
345
|
- `@Transactional` 支持七种 Spring 传播模式;`REQUIRES_NEW` 和 `NOT_SUPPORTED` 需要连接池有额外可用连接。
|
|
343
346
|
- Profile 会筛选 `@Profile` Bean,并深度合并同目录的 `application-{profile}.yml`。
|
|
344
347
|
- Nacos、RabbitMQ、Prometheus 依赖外部服务;Sentinel 限流熔断和 OpenTelemetry 追踪可内嵌运行。
|
|
345
|
-
- HTTP
|
|
348
|
+
- HTTP 事务模式是持久化补偿协调器;`distributed` 模式提供真实 Seata TC + TCC 回调;`at` 模式通过 ORM 拦截器自动记录 undo_log 并在回滚时反向恢复数据。
|
|
346
349
|
- 限流、分布式锁、幂等和缓存语义依赖 Redis 等后端;核心业务必须选择 fail-closed,不能依赖进程内降级继续提供分布式语义。
|
|
347
350
|
|
|
348
351
|
### 1.6 注解使用总览
|
|
@@ -377,7 +380,7 @@ SpringBootAI 注解会先把元数据放到 `__spring_annotations__`。之后是
|
|
|
377
380
|
| Nacos 服务发现 | ✅ 可用 | 服务注册/发现/订阅 |
|
|
378
381
|
| Sentinel 限流熔断 | ✅ 可用 | 内嵌引擎,QPS 限流、异常比例熔断、热点参数限流,无需 Dashboard |
|
|
379
382
|
| 分布式追踪 | ✅ 可用 | 原生 OpenTelemetry(W3C traceparent),自动 HTTP/Feign 注入 |
|
|
380
|
-
| Seata 分布式事务 |
|
|
383
|
+
| Seata 分布式事务 | ✅ 可用 | `distributed` 对接真实 Seata TC 执行 TCC 回调;`at` 模式通过 ORM 拦截器自动记录 undo_log 并反向恢复;`http` 提供持久化补偿 |
|
|
381
384
|
| API Gateway | ✅ 可用 | 轻量 ASGI/WSGI 网关,路由转发、路径重写、过滤器链、负载均衡 |
|
|
382
385
|
| Prometheus 监控 | ✅ 可用 | Counter/Gauge/Histogram 指标暴露 |
|
|
383
386
|
| Feign 声明式 HTTP | ✅ 可用 | 声明式接口、Fallback 降级、自动传播 XID 和 trace 头 |
|
|
@@ -482,7 +485,7 @@ python -c "from spring.orm.pymybatis import __version__; print(__version__)"
|
|
|
482
485
|
|
|
483
486
|
### 3.5 最小应用
|
|
484
487
|
|
|
485
|
-
仓库中的 `example_all`、`example_langchain`、`example_langgraph`、`example_mcp`、`test_cloud_app` 只用于源码参考和回归验证,不会打包进 `springbootAI`。安装后请按下面结构创建自己的应用包。**每个被扫描目录都必须包含 `__init__.py`,并从项目根目录启动。**
|
|
488
|
+
仓库中的 `examples/example_all`、`examples/example_langchain`、`examples/example_langgraph`、`examples/example_mcp`、`examples/test_cloud_app` 只用于源码参考和回归验证,不会打包进 `springbootAI`。安装后请按下面结构创建自己的应用包。**每个被扫描目录都必须包含 `__init__.py`,并从项目根目录启动。**
|
|
486
489
|
|
|
487
490
|
创建包结构:
|
|
488
491
|
|
|
@@ -1660,7 +1663,7 @@ curl http://localhost:8080/actuator/health
|
|
|
1660
1663
|
|
|
1661
1664
|
## 15. 项目结构
|
|
1662
1665
|
|
|
1663
|
-
`example_all`、`example_langchain`、`example_langgraph`、`example_mcp`、`test_cloud_app` 是仓库级示例,不属于 `springbootAI` 安装包。实际项目应创建自己的应用包。
|
|
1666
|
+
`examples/example_all`、`examples/example_langchain`、`examples/example_langgraph`、`examples/example_mcp`、`examples/test_cloud_app` 是仓库级示例,不属于 `springbootAI` 安装包。实际项目应创建自己的应用包。
|
|
1664
1667
|
|
|
1665
1668
|
推荐目录结构:
|
|
1666
1669
|
|
|
@@ -1767,7 +1770,7 @@ python -m pytest -q tests
|
|
|
1767
1770
|
.\scripts\run-load-test.ps1 -Profile smoke
|
|
1768
1771
|
```
|
|
1769
1772
|
|
|
1770
|
-
完整参数和说明见 [性能测试指南](https://github.com/YUCONGGEN/springbootAI/blob/master/
|
|
1773
|
+
完整参数和说明见 [性能测试指南](https://github.com/YUCONGGEN/springbootAI/blob/master/tests/performance/README.md)。
|
|
1771
1774
|
|
|
1772
1775
|
AI、LangChain、LangGraph 和 MCP 已提供独立 workload,并已加入 9 小时 `mixed` 长稳测试。默认使用 Fake 模型和进程内 MCP Server,不访问外部模型、不会产生 Token 费用:
|
|
1773
1776
|
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
# SpringBootAI
|
|
1
|
+
# SpringBootAI
|
|
2
|
+
|
|
3
|
+
<p align="center">
|
|
4
|
+
<img src="doc/images/hero-banner.png" alt="SpringBootAI 功能总览" width="100%" />
|
|
5
|
+
</p>
|
|
2
6
|
|
|
3
7
|
[](https://pypi.org/project/springbootAI/)
|
|
4
8
|
[](https://pypi.org/project/springbootAI/)
|
|
@@ -17,7 +21,7 @@ SpringBootAI 是一个采用 Spring 风格注解和分层结构的 Python 应用
|
|
|
17
21
|
| AI 与编排 | 模型调用、Tools、RAG、Chain、状态图、MCP client/server | LangChain / LangGraph / 官方 MCP SDK |
|
|
18
22
|
| 生产治理 | 健康检查、Prometheus、限流熔断、追踪、Swagger | prometheus-client / OpenTelemetry / OpenAPI |
|
|
19
23
|
|
|
20
|
-
当前版本是 `2.2.
|
|
24
|
+
当前版本是 `2.2.6`;支持 Python 3.10、3.11 和 3.12,许可证为 MIT。项目仍标记为 Beta。用于公网高并发、合规敏感或支付/订单/库存等核心系统前,必须完成目标数据库、流量模型、故障恢复和安全基线验证。内嵌 Gateway 适合内部路由,不替代公网 Nginx/Kong/WAF;Seata `distributed` 对接官方 TC + TCC 回调;`at` 模式通过 ORM 拦截器自动生成 undo_log 实现自动回滚。
|
|
21
25
|
|
|
22
26
|
[新手指南](https://github.com/YUCONGGEN/springbootAI/blob/master/doc/BEGINNER_GUIDE.md) | [全部文档](https://github.com/YUCONGGEN/springbootAI/tree/master/doc) | [变更日志](https://github.com/YUCONGGEN/springbootAI/blob/master/CHANGELOG.md) | [安全报告](https://github.com/YUCONGGEN/springbootAI/blob/master/SECURITY.md) | [发布检查](https://github.com/YUCONGGEN/springbootAI/blob/master/doc/RELEASE_CHECKLIST.md)
|
|
23
27
|
|
|
@@ -117,7 +121,7 @@ curl http://127.0.0.1:8080/api/hello/Alice
|
|
|
117
121
|
| 📦 LangChain | [LANGCHAIN_MODULE.md](https://github.com/YUCONGGEN/springbootAI/blob/master/doc/LANGCHAIN_MODULE.md) | `pip install springbootAI[langchain]` | Chains / Agents / Memory / Retrievers / VectorStores / 30+ 提供商 |
|
|
118
122
|
| 📦 LangGraph | [LANGGRAPH_MODULE.md](https://github.com/YUCONGGEN/springbootAI/blob/master/doc/LANGGRAPH_MODULE.md) | `pip install springbootAI[langgraph]` | 状态图 / 条件路由 / 人工中断 / 注解式工作流 |
|
|
119
123
|
| 📦 MCP | [MCP_MODULE.md](https://github.com/YUCONGGEN/springbootAI/blob/master/doc/MCP_MODULE.md) | `pip install springbootAI[mcp]` | MCP Client / Server / Tool / Resource / Prompt / 注解调用 |
|
|
120
|
-
| ✅ 内嵌 PyMyBatis ORM | [ORM_MODULE.md](https://github.com/YUCONGGEN/springbootAI/blob/master/doc/ORM_MODULE.md) | 随核心包 | Mapper 注解 / XML Mapper / 分页 / SQL 安全 / DDL 自动建表 |
|
|
124
|
+
| ✅ 内嵌 PyMyBatis ORM | [ORM_MODULE.md](https://github.com/YUCONGGEN/springbootAI/blob/master/doc/ORM_MODULE.md) | 随核心包 | Mapper 注解 / XML Mapper / 分页 / SQL 安全 / DDL 自动建表 / Repository 分页查询 |
|
|
121
125
|
| ✅ JPA 实体与仓库 | [JPA_MODULE.md](https://github.com/YUCONGGEN/springbootAI/blob/master/doc/JPA_MODULE.md) | 随核心包 | `@Entity` + `@Table` / 字段自动推断 / `@CreateTime` / Repository / DataJpaTest |
|
|
122
126
|
| ✅ Cloud 微服务 | [CLOUD_MODULE.md](https://github.com/YUCONGGEN/springbootAI/blob/master/doc/CLOUD_MODULE.md) | 随核心包 | 服务注册发现 / 配置刷新 / Feign / Sentinel / Gateway / 分布式事务 |
|
|
123
127
|
| 📦 Excel 读写 | [EXCEL_MODULE.md](https://github.com/YUCONGGEN/springbootAI/blob/master/doc/EXCEL_MODULE.md) | `pip install springbootAI[excel]` | `@ExcelProperty` / `@ExcelIgnore` 注解驱动读写 |
|
|
@@ -125,7 +129,6 @@ curl http://127.0.0.1:8080/api/hello/Alice
|
|
|
125
129
|
| ✅ Swagger 文档 | [SWAGGER_MODULE.md](https://github.com/YUCONGGEN/springbootAI/blob/master/doc/SWAGGER_MODULE.md) | 随核心包 | `@Tag` / `@Operation` 注解驱动 API 文档 |
|
|
126
130
|
| ✅ 安全 | [SECURITY.md](https://github.com/YUCONGGEN/springbootAI/blob/master/doc/SECURITY.md) | 随核心包 | JWT 生成校验 / 密码加密 / SQL 注入防护 / 访问控制 |
|
|
127
131
|
| ✅ BeanUtils | [BEAN_UTILS.md](https://github.com/YUCONGGEN/springbootAI/blob/master/doc/BEAN_UTILS.md) | 随核心包 | `copy_properties` / `clone` 属性复制工具 |
|
|
128
|
-
| ✅ ① Repository | [REPOSITORY_MODULE.md](https://github.com/YUCONGGEN/springbootAI/blob/master/doc/REPOSITORY_MODULE.md) | 随核心包 | 不用手写SQL的分页查询 |
|
|
129
132
|
| ✅ ② Actuator | [ACTUATOR_MODULE.md](https://github.com/YUCONGGEN/springbootAI/blob/master/doc/ACTUATOR_MODULE.md) | 随核心包 | 系统健康检查面板 |
|
|
130
133
|
| ✅ ③ 多数据源 | [DATASOURCE_MODULE.md](https://github.com/YUCONGGEN/springbootAI/blob/master/doc/DATASOURCE_MODULE.md) | 随核心包 | 读写分离 |
|
|
131
134
|
| ✅ ④ 事务事件 | [TX_EVENT_MODULE.md](https://github.com/YUCONGGEN/springbootAI/blob/master/doc/TX_EVENT_MODULE.md) | 随核心包 | 操作完成后自动发通知 |
|
|
@@ -189,10 +192,10 @@ SpringBootAI 是一个 **Python Web 框架**。它把 Java Spring Boot 的"注
|
|
|
189
192
|
|
|
190
193
|
| 组件 | 当前版本 |
|
|
191
194
|
|------|----------|
|
|
192
|
-
| `spring` 框架 API | 2.2.
|
|
193
|
-
| `spring.orm.pymybatis` | 2.2.
|
|
194
|
-
| `spring.ai` AI 模块 | 2.2.
|
|
195
|
-
| `spring.langchain` LangChain 模块 | 2.2.
|
|
195
|
+
| `spring` 框架 API | 2.2.6 |
|
|
196
|
+
| `spring.orm.pymybatis` | 2.2.6 |
|
|
197
|
+
| `spring.ai` AI 模块 | 2.2.6 |
|
|
198
|
+
| `spring.langchain` LangChain 模块 | 2.2.6 |
|
|
196
199
|
| Python | 3.10+ |
|
|
197
200
|
|
|
198
201
|
### 1.4 适合什么场景
|
|
@@ -208,7 +211,7 @@ SpringBootAI 是一个 **Python Web 框架**。它把 Java Spring Boot 的"注
|
|
|
208
211
|
- `@Transactional` 支持七种 Spring 传播模式;`REQUIRES_NEW` 和 `NOT_SUPPORTED` 需要连接池有额外可用连接。
|
|
209
212
|
- Profile 会筛选 `@Profile` Bean,并深度合并同目录的 `application-{profile}.yml`。
|
|
210
213
|
- Nacos、RabbitMQ、Prometheus 依赖外部服务;Sentinel 限流熔断和 OpenTelemetry 追踪可内嵌运行。
|
|
211
|
-
- HTTP
|
|
214
|
+
- HTTP 事务模式是持久化补偿协调器;`distributed` 模式提供真实 Seata TC + TCC 回调;`at` 模式通过 ORM 拦截器自动记录 undo_log 并在回滚时反向恢复数据。
|
|
212
215
|
- 限流、分布式锁、幂等和缓存语义依赖 Redis 等后端;核心业务必须选择 fail-closed,不能依赖进程内降级继续提供分布式语义。
|
|
213
216
|
|
|
214
217
|
### 1.6 注解使用总览
|
|
@@ -243,7 +246,7 @@ SpringBootAI 注解会先把元数据放到 `__spring_annotations__`。之后是
|
|
|
243
246
|
| Nacos 服务发现 | ✅ 可用 | 服务注册/发现/订阅 |
|
|
244
247
|
| Sentinel 限流熔断 | ✅ 可用 | 内嵌引擎,QPS 限流、异常比例熔断、热点参数限流,无需 Dashboard |
|
|
245
248
|
| 分布式追踪 | ✅ 可用 | 原生 OpenTelemetry(W3C traceparent),自动 HTTP/Feign 注入 |
|
|
246
|
-
| Seata 分布式事务 |
|
|
249
|
+
| Seata 分布式事务 | ✅ 可用 | `distributed` 对接真实 Seata TC 执行 TCC 回调;`at` 模式通过 ORM 拦截器自动记录 undo_log 并反向恢复;`http` 提供持久化补偿 |
|
|
247
250
|
| API Gateway | ✅ 可用 | 轻量 ASGI/WSGI 网关,路由转发、路径重写、过滤器链、负载均衡 |
|
|
248
251
|
| Prometheus 监控 | ✅ 可用 | Counter/Gauge/Histogram 指标暴露 |
|
|
249
252
|
| Feign 声明式 HTTP | ✅ 可用 | 声明式接口、Fallback 降级、自动传播 XID 和 trace 头 |
|
|
@@ -348,7 +351,7 @@ python -c "from spring.orm.pymybatis import __version__; print(__version__)"
|
|
|
348
351
|
|
|
349
352
|
### 3.5 最小应用
|
|
350
353
|
|
|
351
|
-
仓库中的 `example_all`、`example_langchain`、`example_langgraph`、`example_mcp`、`test_cloud_app` 只用于源码参考和回归验证,不会打包进 `springbootAI`。安装后请按下面结构创建自己的应用包。**每个被扫描目录都必须包含 `__init__.py`,并从项目根目录启动。**
|
|
354
|
+
仓库中的 `examples/example_all`、`examples/example_langchain`、`examples/example_langgraph`、`examples/example_mcp`、`examples/test_cloud_app` 只用于源码参考和回归验证,不会打包进 `springbootAI`。安装后请按下面结构创建自己的应用包。**每个被扫描目录都必须包含 `__init__.py`,并从项目根目录启动。**
|
|
352
355
|
|
|
353
356
|
创建包结构:
|
|
354
357
|
|
|
@@ -1526,7 +1529,7 @@ curl http://localhost:8080/actuator/health
|
|
|
1526
1529
|
|
|
1527
1530
|
## 15. 项目结构
|
|
1528
1531
|
|
|
1529
|
-
`example_all`、`example_langchain`、`example_langgraph`、`example_mcp`、`test_cloud_app` 是仓库级示例,不属于 `springbootAI` 安装包。实际项目应创建自己的应用包。
|
|
1532
|
+
`examples/example_all`、`examples/example_langchain`、`examples/example_langgraph`、`examples/example_mcp`、`examples/test_cloud_app` 是仓库级示例,不属于 `springbootAI` 安装包。实际项目应创建自己的应用包。
|
|
1530
1533
|
|
|
1531
1534
|
推荐目录结构:
|
|
1532
1535
|
|
|
@@ -1633,7 +1636,7 @@ python -m pytest -q tests
|
|
|
1633
1636
|
.\scripts\run-load-test.ps1 -Profile smoke
|
|
1634
1637
|
```
|
|
1635
1638
|
|
|
1636
|
-
完整参数和说明见 [性能测试指南](https://github.com/YUCONGGEN/springbootAI/blob/master/
|
|
1639
|
+
完整参数和说明见 [性能测试指南](https://github.com/YUCONGGEN/springbootAI/blob/master/tests/performance/README.md)。
|
|
1637
1640
|
|
|
1638
1641
|
AI、LangChain、LangGraph 和 MCP 已提供独立 workload,并已加入 9 小时 `mixed` 长稳测试。默认使用 Fake 模型和进程内 MCP Server,不访问外部模型、不会产生 Token 费用:
|
|
1639
1642
|
|
|
@@ -12,7 +12,7 @@ build-backend = "setuptools.build_meta"
|
|
|
12
12
|
[project]
|
|
13
13
|
# 发行名 springbootAI(PyPI 包名,pip install springbootAI);导入包名仍为 spring
|
|
14
14
|
name = "springbootAI"
|
|
15
|
-
version = "2.2.
|
|
15
|
+
version = "2.2.6"
|
|
16
16
|
description = "Spring-style Python framework with Web, ORM, Cloud and AI integrations"
|
|
17
17
|
readme = "README.md"
|
|
18
18
|
license = "MIT"
|
|
@@ -220,7 +220,7 @@ full = [
|
|
|
220
220
|
]
|
|
221
221
|
|
|
222
222
|
[tool.pytest.ini_options]
|
|
223
|
-
pythonpath = ["."]
|
|
223
|
+
pythonpath = [".", "examples"]
|
|
224
224
|
filterwarnings = [
|
|
225
225
|
# 静默 langchain_classic 弃用告警和 community sunset 告警
|
|
226
226
|
# 原因:本项目有意锁定 langchain classic (1.x) API,这些是预期内的框架级告警
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
from .annotations import *
|
|
1
|
+
from .annotations import *
|
|
2
2
|
from .context import *
|
|
3
3
|
from .web import *
|
|
4
4
|
from .config import *
|
|
5
5
|
from .utils import *
|
|
6
6
|
from .main import create_app, run, SpringApplication, run_cli
|
|
7
7
|
|
|
8
|
-
__version__ = "2.2.
|
|
8
|
+
__version__ = "2.2.6"
|
|
9
9
|
__author__ = "yuconggen"
|
|
10
10
|
__license__ = "MIT"
|
|
11
11
|
|
|
@@ -20,6 +20,13 @@ from spring.cloud.seata import (
|
|
|
20
20
|
)
|
|
21
21
|
from spring.cloud.transaction_store import SQLiteTransactionStore
|
|
22
22
|
from spring.cloud.seata_bridge import SeataBridgeClient, SeataBridgeError
|
|
23
|
+
from spring.cloud.seata_at_proxy import (
|
|
24
|
+
SeataATProxy,
|
|
25
|
+
SeataATInterceptor,
|
|
26
|
+
UndoLogManager,
|
|
27
|
+
UndoExecutor,
|
|
28
|
+
parse_sql,
|
|
29
|
+
)
|
|
23
30
|
from spring.cloud.sentinel import (
|
|
24
31
|
sentinel_engine,
|
|
25
32
|
SentinelEngine,
|
|
@@ -66,6 +73,7 @@ __all__ = [
|
|
|
66
73
|
# 分布式事务
|
|
67
74
|
'seata_manager', 'init_seata', 'SeataTransactionManager', 'BranchStatus',
|
|
68
75
|
'SQLiteTransactionStore', 'SeataBridgeClient', 'SeataBridgeError',
|
|
76
|
+
'SeataATProxy', 'SeataATInterceptor', 'UndoLogManager', 'UndoExecutor', 'parse_sql',
|
|
69
77
|
# 熔断限流
|
|
70
78
|
'sentinel_engine', 'SentinelEngine', 'FlowRule', 'DegradeRule',
|
|
71
79
|
'SystemRule', 'HotParamRule', 'BlockException', 'sentinel_protect',
|
|
@@ -2,10 +2,12 @@
|
|
|
2
2
|
分布式事务模块
|
|
3
3
|
通过官方 Java 客户端桥接真实 Apache Seata,并提供仅供开发验证的 HTTP 补偿协调器
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
支持四种模式:
|
|
6
6
|
- local: 本地模式,仅追踪事务状态(默认)
|
|
7
7
|
- http: 实验性 HTTP 补偿模式,不提供 AT 强一致性,禁止用于生产
|
|
8
8
|
- distributed: 真实 Seata Server + TCC 模式(需要官方 Java 客户端桥接服务)
|
|
9
|
+
- at: AT 模式,通过 ORM 拦截器自动记录 undo_log,回滚时自动反向恢复数据
|
|
10
|
+
需配合 ``SeataATProxy.install()`` 使用,详见 ``spring.cloud.seata_at_proxy``
|
|
9
11
|
|
|
10
12
|
实验性 HTTP 补偿模式工作原理:
|
|
11
13
|
1. TM(事务发起方)开启全局事务,生成XID
|
|
@@ -80,6 +82,8 @@ class SeataTransactionManager:
|
|
|
80
82
|
self._recovery_interval_s = 30.0
|
|
81
83
|
self._recovery_stop = threading.Event()
|
|
82
84
|
self._recovery_thread: Optional[threading.Thread] = None
|
|
85
|
+
# 降级开关:distributed 模式下 bridge 不可达时是否降级为本地事务(默认 False=直接失败)
|
|
86
|
+
self._fallback_to_local = False
|
|
83
87
|
|
|
84
88
|
# HTTP compensation mode stores coordinator metadata durably. Branch
|
|
85
89
|
# callbacks still need callback_url to be recoverable after a restart.
|
|
@@ -107,6 +111,7 @@ class SeataTransactionManager:
|
|
|
107
111
|
recovery_grace_ms: int = 30000,
|
|
108
112
|
recovery_interval_s: float = 30.0,
|
|
109
113
|
callback_allowed_hosts: Optional[List[str]] = None,
|
|
114
|
+
fallback_to_local: bool = False,
|
|
110
115
|
) -> None:
|
|
111
116
|
"""重新配置单例;初始化入口不能依赖第二次构造调用。"""
|
|
112
117
|
client_config_changed = (
|
|
@@ -142,6 +147,7 @@ class SeataTransactionManager:
|
|
|
142
147
|
self._transaction_store_path = normalized_path
|
|
143
148
|
self._recovery_grace_ms = max(0, int(recovery_grace_ms))
|
|
144
149
|
self._recovery_interval_s = max(0.0, float(recovery_interval_s))
|
|
150
|
+
self._fallback_to_local = bool(fallback_to_local)
|
|
145
151
|
self.set_mode(mode)
|
|
146
152
|
|
|
147
153
|
def _validate_callback_url(self, callback_url: str) -> str:
|
|
@@ -284,6 +290,14 @@ class SeataTransactionManager:
|
|
|
284
290
|
|
|
285
291
|
elif self.mode == "distributed":
|
|
286
292
|
if not (self._bridge_client and self._seata_client_initialized):
|
|
293
|
+
# bridge 未初始化:根据配置决定降级还是直接失败
|
|
294
|
+
if self._fallback_to_local:
|
|
295
|
+
logger.warning(
|
|
296
|
+
"[Seata] distributed bridge not initialized, falling back to local transaction "
|
|
297
|
+
"(seata.fallback_to_local=True)"
|
|
298
|
+
)
|
|
299
|
+
# 降级为本地事务:上下文已设置,直接返回 tx_id
|
|
300
|
+
return tx_id
|
|
287
301
|
self._cleanup_context()
|
|
288
302
|
raise RuntimeError("distributed Seata client is not initialized")
|
|
289
303
|
try:
|
|
@@ -304,6 +318,13 @@ class SeataTransactionManager:
|
|
|
304
318
|
logger.info(f"[Seata] Begin global transaction (distributed): {tx_id}")
|
|
305
319
|
return tx_id
|
|
306
320
|
except Exception as e:
|
|
321
|
+
if self._fallback_to_local:
|
|
322
|
+
logger.warning(
|
|
323
|
+
"[Seata] distributed begin failed (%s), falling back to local transaction "
|
|
324
|
+
"(seata.fallback_to_local=True)", e
|
|
325
|
+
)
|
|
326
|
+
# 上下文已设置(in_transaction=True, tx_id 已生成),直接降级返回
|
|
327
|
+
return tx_id
|
|
307
328
|
self._cleanup_context()
|
|
308
329
|
raise RuntimeError(f"failed to begin distributed Seata transaction: {e}") from e
|
|
309
330
|
|
|
@@ -801,8 +822,8 @@ class SeataTransactionManager:
|
|
|
801
822
|
|
|
802
823
|
def set_mode(self, mode: str):
|
|
803
824
|
"""设置事务模式 (local/http/distributed)"""
|
|
804
|
-
if mode not in ["local", "http", "distributed"]:
|
|
805
|
-
raise ValueError("Mode must be 'local', 'http' or '
|
|
825
|
+
if mode not in ["local", "http", "distributed", "at"]:
|
|
826
|
+
raise ValueError("Mode must be 'local', 'http', 'distributed' or 'at'")
|
|
806
827
|
|
|
807
828
|
if mode != 'http':
|
|
808
829
|
self.stop_recovery_worker()
|