techai-webutils 0.1.0__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.
- techai_webutils-0.1.0/PKG-INFO +46 -0
- techai_webutils-0.1.0/pyproject.toml +164 -0
- techai_webutils-0.1.0/pyproject.toml.orig +235 -0
- techai_webutils-0.1.0/src/techai_webutils/__init__.py +5 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/__init__.py +8 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/cache/__init__.py +35 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/cache/builder.py +87 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/cache/decorators.py +283 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/cache/envelope.py +51 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/cache/local/__init__.py +5 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/cache/local/cache.py +70 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/cache/null/__init__.py +5 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/cache/null/cache.py +27 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/cache/redis/__init__.py +6 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/cache/redis/cache.py +86 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/cache/types.py +27 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/chunking/__init__.py +13 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/chunking/factory.py +47 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/chunking/fixed/__init__.py +5 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/chunking/fixed/chunker.py +71 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/decorators/__init__.py +1 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/decorators/event_stack.py +99 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/decorators/job_stack.py +77 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/decorators/proxy.py +453 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/email/__init__.py +13 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/email/builder.py +68 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/email/noop/__init__.py +5 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/email/noop/provider.py +15 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/email/ses/__init__.py +5 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/email/ses/provider.py +33 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/email/smtp/__init__.py +5 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/email/smtp/provider.py +27 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/embedding/__init__.py +13 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/embedding/builder.py +66 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/embedding/ollama/__init__.py +5 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/embedding/ollama/provider.py +67 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/embedding/stub/__init__.py +5 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/embedding/stub/provider.py +57 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/jobs/__init__.py +26 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/jobs/builder.py +26 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/jobs/config.py +28 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/jobs/memory/__init__.py +18 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/jobs/memory/backend.py +92 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/kb_ingestion/__init__.py +6 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/kb_ingestion/bedrock/__init__.py +5 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/kb_ingestion/bedrock/ingestor.py +202 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/kb_ingestion/builder.py +53 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/kb_ingestion/decorators.py +259 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/kb_ingestion/mapping.py +66 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/kb_ingestion/noop/__init__.py +5 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/kb_ingestion/noop/ingestor.py +62 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/kb_registry/__init__.py +38 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/kb_registry/builder.py +84 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/kb_registry/output/__init__.py +5 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/kb_registry/output/registry.py +40 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/kb_registry/roster/__init__.py +5 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/kb_registry/roster/registry.py +77 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/kb_registry/shared/__init__.py +5 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/kb_registry/shared/registry.py +33 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/llm/__init__.py +5 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/llm/bedrock/__init__.py +5 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/llm/bedrock/provider.py +221 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/llm/builder.py +99 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/llm/decorators.py +150 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/llm/ollama/__init__.py +5 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/llm/ollama/provider.py +142 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/llm/stub/__init__.py +5 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/llm/stub/provider.py +67 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/lock/__init__.py +18 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/lock/builder.py +80 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/lock/memory/__init__.py +5 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/lock/memory/lock.py +46 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/lock/postgres/__init__.py +5 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/lock/postgres/lock.py +178 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/lock/runner.py +39 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/messaging/__init__.py +23 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/messaging/builder.py +64 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/messaging/config.py +45 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/messaging/memory/__init__.py +7 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/messaging/memory/broker.py +31 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/messaging/memory/publisher.py +40 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/messaging/memory/subscriber.py +71 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/messaging/sqs/__init__.py +11 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/messaging/sqs/sqs_publisher.py +91 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/messaging/sqs/sqs_subscriber.py +110 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/metadata/__init__.py +14 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/metadata/factory.py +47 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/metadata/langdetect/__init__.py +13 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/metadata/langdetect/extractor.py +66 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/parsing/__init__.py +14 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/parsing/factory.py +57 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/parsing/isolated/__init__.py +23 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/parsing/isolated/detect.py +109 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/parsing/isolated/isolated.py +264 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/parsing/isolated/markitdown_parser.py +200 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/retrieval/__init__.py +7 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/retrieval/bedrock/__init__.py +5 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/retrieval/bedrock/engine.py +218 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/retrieval/builder.py +128 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/retrieval/filtering.py +112 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/retrieval/stub/__init__.py +5 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/retrieval/stub/engine.py +57 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/retrieval/vector/__init__.py +5 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/retrieval/vector/engine.py +66 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/rpc/__init__.py +14 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/rpc/builder.py +42 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/rpc/grpc/__init__.py +5 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/rpc/grpc/client.py +51 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/rpc/grpc/errors.py +65 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/rpc/grpc/interceptors/__init__.py +29 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/rpc/grpc/interceptors/auth.py +90 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/rpc/grpc/interceptors/builder.py +75 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/rpc/grpc/interceptors/circuit_breaker.py +65 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/rpc/grpc/interceptors/logging.py +57 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/rpc/grpc/interceptors/metrics.py +42 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/rpc/grpc/interceptors/retry.py +63 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/rpc/grpc/interceptors/server_builder.py +493 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/rpc/grpc/interceptors/timeout.py +56 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/rpc/grpc/interceptors/tracing.py +41 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/rpc/grpc/interceptors/tracing_server.py +122 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/splitting/__init__.py +13 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/splitting/factory.py +47 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/splitting/kb_unit/__init__.py +5 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/splitting/kb_unit/splitter.py +150 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/storage/__init__.py +21 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/storage/builder.py +51 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/storage/config.py +42 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/storage/memory/__init__.py +5 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/storage/memory/client.py +88 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/storage/s3/__init__.py +10 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/storage/s3/s3_client.py +221 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/transport/__init__.py +5 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/transport/grpc/__init__.py +9 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/transport/grpc/server.py +176 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/vector/__init__.py +13 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/vector/builder.py +63 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/vector/composition.py +74 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/vector/qdrant/__init__.py +5 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/vector/qdrant/store.py +194 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/vector/stub/__init__.py +5 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/vector/stub/store.py +99 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/vector_kb/__init__.py +15 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/vector_kb/builder.py +59 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/vector_kb/vector/__init__.py +5 -0
- techai_webutils-0.1.0/src/techai_webutils/clients/vector_kb/vector/knowledge_base.py +148 -0
- techai_webutils-0.1.0/src/techai_webutils/controllers/__init__.py +28 -0
- techai_webutils-0.1.0/src/techai_webutils/controllers/adapt.py +72 -0
- techai_webutils-0.1.0/src/techai_webutils/controllers/base.py +106 -0
- techai_webutils-0.1.0/src/techai_webutils/controllers/decorators.py +246 -0
- techai_webutils-0.1.0/src/techai_webutils/core/__init__.py +1 -0
- techai_webutils-0.1.0/src/techai_webutils/core/domain/__init__.py +20 -0
- techai_webutils-0.1.0/src/techai_webutils/core/domain/metadata.py +28 -0
- techai_webutils-0.1.0/src/techai_webutils/core/domain/parser.py +92 -0
- techai_webutils-0.1.0/src/techai_webutils/core/domain/splitter.py +39 -0
- techai_webutils-0.1.0/src/techai_webutils/core/domain_types/__init__.py +27 -0
- techai_webutils-0.1.0/src/techai_webutils/core/domain_types/types.py +152 -0
- techai_webutils-0.1.0/src/techai_webutils/core/errors/__init__.py +29 -0
- techai_webutils-0.1.0/src/techai_webutils/core/errors/errors.py +197 -0
- techai_webutils-0.1.0/src/techai_webutils/core/events/__init__.py +31 -0
- techai_webutils-0.1.0/src/techai_webutils/core/events/events.py +262 -0
- techai_webutils-0.1.0/src/techai_webutils/core/interfaces/__init__.py +219 -0
- techai_webutils-0.1.0/src/techai_webutils/core/interfaces/adaptive_throttler.py +31 -0
- techai_webutils-0.1.0/src/techai_webutils/core/interfaces/auth.py +54 -0
- techai_webutils-0.1.0/src/techai_webutils/core/interfaces/bulkhead.py +32 -0
- techai_webutils-0.1.0/src/techai_webutils/core/interfaces/byte_cache.py +35 -0
- techai_webutils-0.1.0/src/techai_webutils/core/interfaces/cache.py +54 -0
- techai_webutils-0.1.0/src/techai_webutils/core/interfaces/chunker.py +21 -0
- techai_webutils-0.1.0/src/techai_webutils/core/interfaces/circuit_breaker.py +41 -0
- techai_webutils-0.1.0/src/techai_webutils/core/interfaces/config_loader.py +41 -0
- techai_webutils-0.1.0/src/techai_webutils/core/interfaces/connection.py +57 -0
- techai_webutils-0.1.0/src/techai_webutils/core/interfaces/crud_service.py +76 -0
- techai_webutils-0.1.0/src/techai_webutils/core/interfaces/dedup.py +26 -0
- techai_webutils-0.1.0/src/techai_webutils/core/interfaces/dlq.py +38 -0
- techai_webutils-0.1.0/src/techai_webutils/core/interfaces/document.py +72 -0
- techai_webutils-0.1.0/src/techai_webutils/core/interfaces/document_status.py +138 -0
- techai_webutils-0.1.0/src/techai_webutils/core/interfaces/email.py +19 -0
- techai_webutils-0.1.0/src/techai_webutils/core/interfaces/embedding.py +42 -0
- techai_webutils-0.1.0/src/techai_webutils/core/interfaces/event_publisher.py +27 -0
- techai_webutils-0.1.0/src/techai_webutils/core/interfaces/execution.py +290 -0
- techai_webutils-0.1.0/src/techai_webutils/core/interfaces/hedger.py +29 -0
- techai_webutils-0.1.0/src/techai_webutils/core/interfaces/ingestion_job_state.py +81 -0
- techai_webutils-0.1.0/src/techai_webutils/core/interfaces/jobs.py +82 -0
- techai_webutils-0.1.0/src/techai_webutils/core/interfaces/kb_ingestion.py +155 -0
- techai_webutils-0.1.0/src/techai_webutils/core/interfaces/kb_registry.py +85 -0
- techai_webutils-0.1.0/src/techai_webutils/core/interfaces/knowledge_base.py +83 -0
- techai_webutils-0.1.0/src/techai_webutils/core/interfaces/leader.py +23 -0
- techai_webutils-0.1.0/src/techai_webutils/core/interfaces/lifecycle.py +75 -0
- techai_webutils-0.1.0/src/techai_webutils/core/interfaces/llm.py +76 -0
- techai_webutils-0.1.0/src/techai_webutils/core/interfaces/lock.py +56 -0
- techai_webutils-0.1.0/src/techai_webutils/core/interfaces/logger.py +47 -0
- techai_webutils-0.1.0/src/techai_webutils/core/interfaces/messaging.py +69 -0
- techai_webutils-0.1.0/src/techai_webutils/core/interfaces/metadata.py +22 -0
- techai_webutils-0.1.0/src/techai_webutils/core/interfaces/metrics.py +79 -0
- techai_webutils-0.1.0/src/techai_webutils/core/interfaces/op_service.py +25 -0
- techai_webutils-0.1.0/src/techai_webutils/core/interfaces/parser.py +31 -0
- techai_webutils-0.1.0/src/techai_webutils/core/interfaces/pipeline.py +50 -0
- techai_webutils-0.1.0/src/techai_webutils/core/interfaces/query.py +122 -0
- techai_webutils-0.1.0/src/techai_webutils/core/interfaces/rate_limiter.py +22 -0
- techai_webutils-0.1.0/src/techai_webutils/core/interfaces/repository.py +85 -0
- techai_webutils-0.1.0/src/techai_webutils/core/interfaces/retrier.py +25 -0
- techai_webutils-0.1.0/src/techai_webutils/core/interfaces/retrieval.py +182 -0
- techai_webutils-0.1.0/src/techai_webutils/core/interfaces/service.py +56 -0
- techai_webutils-0.1.0/src/techai_webutils/core/interfaces/splitter.py +23 -0
- techai_webutils-0.1.0/src/techai_webutils/core/interfaces/storage.py +90 -0
- techai_webutils-0.1.0/src/techai_webutils/core/interfaces/store.py +56 -0
- techai_webutils-0.1.0/src/techai_webutils/core/interfaces/tracer.py +53 -0
- techai_webutils-0.1.0/src/techai_webutils/core/interfaces/vector_store.py +87 -0
- techai_webutils-0.1.0/src/techai_webutils/core/interfaces/workflow.py +51 -0
- techai_webutils-0.1.0/src/techai_webutils/execution/__init__.py +49 -0
- techai_webutils-0.1.0/src/techai_webutils/execution/engine/__init__.py +5 -0
- techai_webutils-0.1.0/src/techai_webutils/execution/engine/fan_out.py +111 -0
- techai_webutils-0.1.0/src/techai_webutils/execution/engine/run.py +61 -0
- techai_webutils-0.1.0/src/techai_webutils/execution/executor/__init__.py +36 -0
- techai_webutils-0.1.0/src/techai_webutils/execution/executor/asyncio_executor.py +37 -0
- techai_webutils-0.1.0/src/techai_webutils/execution/executor/factory.py +90 -0
- techai_webutils-0.1.0/src/techai_webutils/execution/executor/pooled.py +151 -0
- techai_webutils-0.1.0/src/techai_webutils/execution/executor/ray_executor.py +56 -0
- techai_webutils-0.1.0/src/techai_webutils/execution/executor/ray_runtime.py +43 -0
- techai_webutils-0.1.0/src/techai_webutils/execution/executor/real_ray_pool.py +114 -0
- techai_webutils-0.1.0/src/techai_webutils/execution/executor/real_ray_runtime.py +121 -0
- techai_webutils-0.1.0/src/techai_webutils/execution/executor/resilient_ray_runtime.py +93 -0
- techai_webutils-0.1.0/src/techai_webutils/execution/gate/__init__.py +19 -0
- techai_webutils-0.1.0/src/techai_webutils/execution/gate/gate.py +147 -0
- techai_webutils-0.1.0/src/techai_webutils/execution/job/__init__.py +5 -0
- techai_webutils-0.1.0/src/techai_webutils/execution/job/conditional.py +45 -0
- techai_webutils-0.1.0/src/techai_webutils/execution/job/decorators/__init__.py +5 -0
- techai_webutils-0.1.0/src/techai_webutils/execution/job/decorators/builder.py +199 -0
- techai_webutils-0.1.0/src/techai_webutils/execution/job/job.py +205 -0
- techai_webutils-0.1.0/src/techai_webutils/foundation/__init__.py +1 -0
- techai_webutils-0.1.0/src/techai_webutils/foundation/config/__init__.py +35 -0
- techai_webutils-0.1.0/src/techai_webutils/foundation/config/bridge.py +173 -0
- techai_webutils-0.1.0/src/techai_webutils/foundation/config/config_loader.py +84 -0
- techai_webutils-0.1.0/src/techai_webutils/foundation/config/loader.py +116 -0
- techai_webutils-0.1.0/src/techai_webutils/foundation/config/settings.py +145 -0
- techai_webutils-0.1.0/src/techai_webutils/foundation/decorator.py +331 -0
- techai_webutils-0.1.0/src/techai_webutils/foundation/errors/__init__.py +1 -0
- techai_webutils-0.1.0/src/techai_webutils/foundation/errors/errors.py +118 -0
- techai_webutils-0.1.0/src/techai_webutils/foundation/lifecycle.py +70 -0
- techai_webutils-0.1.0/src/techai_webutils/foundation/logger/__init__.py +31 -0
- techai_webutils-0.1.0/src/techai_webutils/foundation/logger/builder.py +74 -0
- techai_webutils-0.1.0/src/techai_webutils/foundation/logger/logger.py +263 -0
- techai_webutils-0.1.0/src/techai_webutils/foundation/logger/stdlib_logger.py +132 -0
- techai_webutils-0.1.0/src/techai_webutils/foundation/metrics/__init__.py +31 -0
- techai_webutils-0.1.0/src/techai_webutils/foundation/metrics/builder.py +71 -0
- techai_webutils-0.1.0/src/techai_webutils/foundation/metrics/execution_observer.py +89 -0
- techai_webutils-0.1.0/src/techai_webutils/foundation/metrics/metrics.py +264 -0
- techai_webutils-0.1.0/src/techai_webutils/foundation/metrics/null_metrics.py +63 -0
- techai_webutils-0.1.0/src/techai_webutils/foundation/middleware/__init__.py +19 -0
- techai_webutils-0.1.0/src/techai_webutils/foundation/middleware/chain.py +35 -0
- techai_webutils-0.1.0/src/techai_webutils/foundation/middleware/http_observability.py +209 -0
- techai_webutils-0.1.0/src/techai_webutils/foundation/middleware/request_id.py +61 -0
- techai_webutils-0.1.0/src/techai_webutils/foundation/observability.py +65 -0
- techai_webutils-0.1.0/src/techai_webutils/foundation/resilience/__init__.py +21 -0
- techai_webutils-0.1.0/src/techai_webutils/foundation/resilience/adaptive_throttler.py +86 -0
- techai_webutils-0.1.0/src/techai_webutils/foundation/resilience/async_circuit_breaker.py +94 -0
- techai_webutils-0.1.0/src/techai_webutils/foundation/resilience/async_retry.py +68 -0
- techai_webutils-0.1.0/src/techai_webutils/foundation/resilience/budget.py +59 -0
- techai_webutils-0.1.0/src/techai_webutils/foundation/resilience/bulkhead.py +197 -0
- techai_webutils-0.1.0/src/techai_webutils/foundation/resilience/circuit_breaker.py +127 -0
- techai_webutils-0.1.0/src/techai_webutils/foundation/resilience/classify.py +140 -0
- techai_webutils-0.1.0/src/techai_webutils/foundation/resilience/dedup.py +36 -0
- techai_webutils-0.1.0/src/techai_webutils/foundation/resilience/dlq.py +67 -0
- techai_webutils-0.1.0/src/techai_webutils/foundation/resilience/grpc_boundary.py +80 -0
- techai_webutils-0.1.0/src/techai_webutils/foundation/resilience/hedge.py +95 -0
- techai_webutils-0.1.0/src/techai_webutils/foundation/resilience/leader.py +17 -0
- techai_webutils-0.1.0/src/techai_webutils/foundation/resilience/per_key_rate_limiter.py +70 -0
- techai_webutils-0.1.0/src/techai_webutils/foundation/resilience/rate_limiter.py +64 -0
- techai_webutils-0.1.0/src/techai_webutils/foundation/resilience/retry.py +69 -0
- techai_webutils-0.1.0/src/techai_webutils/foundation/resilience/sqs_dlq.py +84 -0
- techai_webutils-0.1.0/src/techai_webutils/foundation/resilience/timeout.py +35 -0
- techai_webutils-0.1.0/src/techai_webutils/foundation/tracer/__init__.py +25 -0
- techai_webutils-0.1.0/src/techai_webutils/foundation/tracer/builder.py +81 -0
- techai_webutils-0.1.0/src/techai_webutils/foundation/tracer/null_tracer.py +41 -0
- techai_webutils-0.1.0/src/techai_webutils/foundation/tracer/tracer.py +153 -0
- techai_webutils-0.1.0/src/techai_webutils/pipelines/__init__.py +24 -0
- techai_webutils-0.1.0/src/techai_webutils/pipelines/base.py +80 -0
- techai_webutils-0.1.0/src/techai_webutils/pipelines/citations.py +45 -0
- techai_webutils-0.1.0/src/techai_webutils/pipelines/decorators.py +315 -0
- techai_webutils-0.1.0/src/techai_webutils/pipelines/generator.py +69 -0
- techai_webutils-0.1.0/src/techai_webutils/pipelines/rewriter.py +49 -0
- techai_webutils-0.1.0/src/techai_webutils/pipelines/title.py +52 -0
- techai_webutils-0.1.0/src/techai_webutils/py.typed +0 -0
- techai_webutils-0.1.0/src/techai_webutils/repos/__init__.py +21 -0
- techai_webutils-0.1.0/src/techai_webutils/repos/cursor.py +49 -0
- techai_webutils-0.1.0/src/techai_webutils/repos/decorators/__init__.py +5 -0
- techai_webutils-0.1.0/src/techai_webutils/repos/decorators/builder.py +525 -0
- techai_webutils-0.1.0/src/techai_webutils/repos/errors/__init__.py +5 -0
- techai_webutils-0.1.0/src/techai_webutils/repos/errors/mapper.py +68 -0
- techai_webutils-0.1.0/src/techai_webutils/repos/repository.py +54 -0
- techai_webutils-0.1.0/src/techai_webutils/services/__init__.py +12 -0
- techai_webutils-0.1.0/src/techai_webutils/services/base.py +9 -0
- techai_webutils-0.1.0/src/techai_webutils/services/crud_service.py +50 -0
- techai_webutils-0.1.0/src/techai_webutils/services/decorators/__init__.py +5 -0
- techai_webutils-0.1.0/src/techai_webutils/services/decorators/builder.py +316 -0
- techai_webutils-0.1.0/src/techai_webutils/services/op_builder.py +220 -0
- techai_webutils-0.1.0/src/techai_webutils/workflows/__init__.py +24 -0
- techai_webutils-0.1.0/src/techai_webutils/workflows/base.py +81 -0
- techai_webutils-0.1.0/src/techai_webutils/workflows/decorators.py +333 -0
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
|
+
Name: techai-webutils
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: techai-webutils
|
|
5
|
+
Author: Tech AI at Georgia Institute of Technology
|
|
6
|
+
License: MIT
|
|
7
|
+
Classifier: Operating System :: MacOS
|
|
8
|
+
Classifier: Operating System :: Microsoft :: Windows
|
|
9
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
10
|
+
Classifier: Programming Language :: Python
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
12
|
+
Requires-Dist: aiobotocore>=3.5.0
|
|
13
|
+
Requires-Dist: aiosmtplib>=3.0.0
|
|
14
|
+
Requires-Dist: fastapi>=0.136.0
|
|
15
|
+
Requires-Dist: grpcio>=1.80.0
|
|
16
|
+
Requires-Dist: grpcio-health-checking>=1.80.0
|
|
17
|
+
Requires-Dist: grpcio-reflection>=1.80.0
|
|
18
|
+
Requires-Dist: httpx>=0.28.1
|
|
19
|
+
Requires-Dist: opentelemetry-api>=1.41.0
|
|
20
|
+
Requires-Dist: opentelemetry-exporter-otlp-proto-grpc>=1.41.0
|
|
21
|
+
Requires-Dist: opentelemetry-sdk>=1.41.0
|
|
22
|
+
Requires-Dist: prometheus-client>=0.25.0
|
|
23
|
+
Requires-Dist: pydantic>=2.13.3
|
|
24
|
+
Requires-Dist: pydantic-settings>=2.14.1
|
|
25
|
+
Requires-Dist: qdrant-client>=1.12.0
|
|
26
|
+
Requires-Dist: pyyaml>=6.0.3
|
|
27
|
+
Requires-Dist: redis>=7.4.0
|
|
28
|
+
Requires-Dist: structlog>=25.5.0
|
|
29
|
+
Requires-Dist: tenacity>=9.1.4
|
|
30
|
+
Requires-Dist: uvicorn>=0.48.0
|
|
31
|
+
Requires-Dist: protovalidate>=2.0.0,<3
|
|
32
|
+
Requires-Dist: langdetect>=1.0.9 ; extra == 'langdetect'
|
|
33
|
+
Requires-Dist: markitdown[docx,pdf,pptx,xls,xlsx]>=0.1.6 ; extra == 'parsing'
|
|
34
|
+
Requires-Dist: pymupdf>=1.28.0 ; extra == 'parsing'
|
|
35
|
+
Requires-Dist: asyncpg>=0.30.0 ; extra == 'postgres'
|
|
36
|
+
Requires-Dist: ray==2.56.1 ; extra == 'ray'
|
|
37
|
+
Requires-Python: >=3.12
|
|
38
|
+
Project-URL: Homepage, https://github.com/gt-tech-ai/knowledge-engine
|
|
39
|
+
Project-URL: Documentation, https://github.com/gt-tech-ai/knowledge-engine
|
|
40
|
+
Project-URL: Repository, https://github.com/gt-tech-ai/knowledge-engine
|
|
41
|
+
Provides-Extra: langdetect
|
|
42
|
+
Provides-Extra: parsing
|
|
43
|
+
Provides-Extra: postgres
|
|
44
|
+
Provides-Extra: ray
|
|
45
|
+
Description-Content-Type: text/markdown
|
|
46
|
+
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "techai-webutils"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
description = "techai-webutils"
|
|
5
|
+
requires-python = ">= 3.12"
|
|
6
|
+
dependencies = [
|
|
7
|
+
"aiobotocore>=3.5.0",
|
|
8
|
+
"aiosmtplib>=3.0.0",
|
|
9
|
+
"fastapi>=0.136.0",
|
|
10
|
+
"grpcio>=1.80.0",
|
|
11
|
+
"grpcio-health-checking>=1.80.0",
|
|
12
|
+
"grpcio-reflection>=1.80.0",
|
|
13
|
+
"httpx>=0.28.1",
|
|
14
|
+
"opentelemetry-api>=1.41.0",
|
|
15
|
+
"opentelemetry-exporter-otlp-proto-grpc>=1.41.0",
|
|
16
|
+
"opentelemetry-sdk>=1.41.0",
|
|
17
|
+
"prometheus-client>=0.25.0",
|
|
18
|
+
"pydantic>=2.13.3",
|
|
19
|
+
"pydantic-settings>=2.14.1",
|
|
20
|
+
"qdrant-client>=1.12.0",
|
|
21
|
+
"pyyaml>=6.0.3",
|
|
22
|
+
"redis>=7.4.0",
|
|
23
|
+
"structlog>=25.5.0",
|
|
24
|
+
"tenacity>=9.1.4",
|
|
25
|
+
"uvicorn>=0.48.0",
|
|
26
|
+
"protovalidate>=2.0.0,<3",
|
|
27
|
+
]
|
|
28
|
+
classifiers = [
|
|
29
|
+
"Operating System :: MacOS",
|
|
30
|
+
"Operating System :: Microsoft :: Windows",
|
|
31
|
+
"Operating System :: POSIX :: Linux",
|
|
32
|
+
"Programming Language :: Python",
|
|
33
|
+
"Programming Language :: Python :: 3.12",
|
|
34
|
+
]
|
|
35
|
+
|
|
36
|
+
[project.readme]
|
|
37
|
+
text = ""
|
|
38
|
+
content-type = "text/markdown"
|
|
39
|
+
|
|
40
|
+
[[project.authors]]
|
|
41
|
+
name = "Tech AI at Georgia Institute of Technology"
|
|
42
|
+
|
|
43
|
+
[project.optional-dependencies]
|
|
44
|
+
ray = ["ray==2.56.1"]
|
|
45
|
+
postgres = ["asyncpg>=0.30.0"]
|
|
46
|
+
parsing = [
|
|
47
|
+
"markitdown[docx,pdf,pptx,xls,xlsx]>=0.1.6",
|
|
48
|
+
"pymupdf>=1.28.0",
|
|
49
|
+
]
|
|
50
|
+
langdetect = ["langdetect>=1.0.9"]
|
|
51
|
+
|
|
52
|
+
[project.license]
|
|
53
|
+
text = "MIT"
|
|
54
|
+
|
|
55
|
+
[project.urls]
|
|
56
|
+
Homepage = "https://github.com/gt-tech-ai/knowledge-engine"
|
|
57
|
+
Documentation = "https://github.com/gt-tech-ai/knowledge-engine"
|
|
58
|
+
Repository = "https://github.com/gt-tech-ai/knowledge-engine"
|
|
59
|
+
|
|
60
|
+
[build-system]
|
|
61
|
+
requires = ["uv_build>=0.11.15,<0.12.0"]
|
|
62
|
+
build-backend = "uv_build"
|
|
63
|
+
|
|
64
|
+
[dependency-groups]
|
|
65
|
+
dev = [
|
|
66
|
+
"autogitsemver>=0.9.13",
|
|
67
|
+
"pytest>=9.0.3",
|
|
68
|
+
"pytest-asyncio>=1.0.0",
|
|
69
|
+
"pytest-cov>=7.1.0",
|
|
70
|
+
"ray==2.56.1",
|
|
71
|
+
"ruff>=0.15.13",
|
|
72
|
+
"basedpyright>=1.31",
|
|
73
|
+
"asyncpg>=0.30.0",
|
|
74
|
+
"markitdown[docx,pdf,pptx,xls,xlsx]>=0.1.6",
|
|
75
|
+
"pymupdf>=1.28.0",
|
|
76
|
+
"langdetect>=1.0.9",
|
|
77
|
+
"testcontainers[postgres,redis]>=4.14.2",
|
|
78
|
+
"ty>=0.0.38",
|
|
79
|
+
]
|
|
80
|
+
|
|
81
|
+
[tool.pytest.ini_options]
|
|
82
|
+
addopts = "--verbose -vv --capture=no --strict-markers --cov=techai_webutils --cov-report html --cov-report term --cov-report xml:coverage.xml --cov-fail-under=90.0"
|
|
83
|
+
markers = [
|
|
84
|
+
"integration: real-dependency tests via testcontainers (Docker required); deselected in the unit run",
|
|
85
|
+
"slow: slow tests, deselected with --fast",
|
|
86
|
+
]
|
|
87
|
+
|
|
88
|
+
[tool.coverage.run]
|
|
89
|
+
relative_files = true
|
|
90
|
+
data_file = "coverage_unit.dat"
|
|
91
|
+
|
|
92
|
+
[tool.coverage.report]
|
|
93
|
+
omit = [
|
|
94
|
+
"*/clients/transport/grpc/server.py",
|
|
95
|
+
"*/clients/rpc/grpc/interceptors/tracing.py",
|
|
96
|
+
"*/clients/rpc/grpc/interceptors/tracing_server.py",
|
|
97
|
+
"*/clients/messaging/sqs/sqs_publisher.py",
|
|
98
|
+
"*/clients/messaging/sqs/sqs_subscriber.py",
|
|
99
|
+
"*/foundation/resilience/sqs_dlq.py",
|
|
100
|
+
"*/clients/storage/s3/s3_client.py",
|
|
101
|
+
"*/clients/llm/bedrock/*.py",
|
|
102
|
+
"*/clients/retrieval/bedrock/*.py",
|
|
103
|
+
"*/clients/kb_ingestion/bedrock/*.py",
|
|
104
|
+
"*/clients/email/ses/provider.py",
|
|
105
|
+
"*/clients/email/smtp/provider.py",
|
|
106
|
+
"*/clients/cache/redis/cache.py",
|
|
107
|
+
"*/foundation/tracer/tracer.py",
|
|
108
|
+
"*/foundation/observability.py",
|
|
109
|
+
"*/execution/executor/real_ray_runtime.py",
|
|
110
|
+
]
|
|
111
|
+
|
|
112
|
+
[tool.ruff]
|
|
113
|
+
line-length = 110
|
|
114
|
+
|
|
115
|
+
[tool.ruff.lint]
|
|
116
|
+
exclude = ["tests/**"]
|
|
117
|
+
select = ["ALL"]
|
|
118
|
+
ignore = [
|
|
119
|
+
"ANN002",
|
|
120
|
+
"ANN003",
|
|
121
|
+
"BLE001",
|
|
122
|
+
"COM812",
|
|
123
|
+
"CPY001",
|
|
124
|
+
"D105",
|
|
125
|
+
"D107",
|
|
126
|
+
"D202",
|
|
127
|
+
"D203",
|
|
128
|
+
"D213",
|
|
129
|
+
"E501",
|
|
130
|
+
"FIX002",
|
|
131
|
+
"I001",
|
|
132
|
+
"N802",
|
|
133
|
+
"N999",
|
|
134
|
+
"RSE102",
|
|
135
|
+
"S101",
|
|
136
|
+
"TC006",
|
|
137
|
+
"TD002",
|
|
138
|
+
"TD003",
|
|
139
|
+
"TRY002",
|
|
140
|
+
"TRY300",
|
|
141
|
+
"UP032",
|
|
142
|
+
]
|
|
143
|
+
|
|
144
|
+
[tool.ruff.lint.per-file-ignores]
|
|
145
|
+
"src/techai_webutils/clients/llm/bedrock/*.py" = ["N803"]
|
|
146
|
+
"src/techai_webutils/clients/retrieval/bedrock/*.py" = ["N803"]
|
|
147
|
+
"src/techai_webutils/clients/kb_ingestion/bedrock/*.py" = ["N803"]
|
|
148
|
+
|
|
149
|
+
[tool.ruff.lint.mccabe]
|
|
150
|
+
max-complexity = 15
|
|
151
|
+
|
|
152
|
+
[tool.ruff.lint.pylint]
|
|
153
|
+
max-args = 10
|
|
154
|
+
max-branches = 20
|
|
155
|
+
max-returns = 20
|
|
156
|
+
|
|
157
|
+
[tool.pyright]
|
|
158
|
+
pythonVersion = "3.12"
|
|
159
|
+
typeCheckingMode = "standard"
|
|
160
|
+
include = ["src/techai_webutils"]
|
|
161
|
+
exclude = ["tests"]
|
|
162
|
+
|
|
163
|
+
[tool.uv.build-backend]
|
|
164
|
+
module-name = "techai_webutils"
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "techai-webutils"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
# ^^^^^
|
|
5
|
+
# Wheel names will be generated according to this value. Do not manually modify this value; instead
|
|
6
|
+
# update it according to committed changes by running this command from the root of the repository:
|
|
7
|
+
#
|
|
8
|
+
# uv run python -m AutoGitSemVer.scripts.UpdatePythonVersion ./pyproject.toml ./src
|
|
9
|
+
|
|
10
|
+
description = "techai-webutils"
|
|
11
|
+
readme = { text = "", content-type = "text/markdown" }
|
|
12
|
+
authors = [
|
|
13
|
+
{ name = "Tech AI at Georgia Institute of Technology" }
|
|
14
|
+
]
|
|
15
|
+
requires-python = ">= 3.12"
|
|
16
|
+
dependencies = [
|
|
17
|
+
"aiobotocore>=3.5.0",
|
|
18
|
+
# aiosmtplib: async SMTP send for the SMTP email backend (clients/email/smtp); lazy-imported by
|
|
19
|
+
# email_from_config only on the SMTP path. Peer of aiobotocore (the SES backend's transport).
|
|
20
|
+
"aiosmtplib>=3.0.0",
|
|
21
|
+
"fastapi>=0.136.0",
|
|
22
|
+
"grpcio>=1.80.0",
|
|
23
|
+
"grpcio-health-checking>=1.80.0",
|
|
24
|
+
"grpcio-reflection>=1.80.0",
|
|
25
|
+
"httpx>=0.28.1",
|
|
26
|
+
"opentelemetry-api>=1.41.0",
|
|
27
|
+
"opentelemetry-exporter-otlp-proto-grpc>=1.41.0",
|
|
28
|
+
"opentelemetry-sdk>=1.41.0",
|
|
29
|
+
"prometheus-client>=0.25.0",
|
|
30
|
+
"pydantic>=2.13.3",
|
|
31
|
+
"pydantic-settings>=2.14.1",
|
|
32
|
+
"qdrant-client>=1.12.0",
|
|
33
|
+
"pyyaml>=6.0.3",
|
|
34
|
+
"redis>=7.4.0",
|
|
35
|
+
"structlog>=25.5.0",
|
|
36
|
+
"tenacity>=9.1.4",
|
|
37
|
+
"uvicorn>=0.48.0",
|
|
38
|
+
"protovalidate>=2.0.0,<3",
|
|
39
|
+
]
|
|
40
|
+
classifiers = [
|
|
41
|
+
"Operating System :: MacOS",
|
|
42
|
+
"Operating System :: Microsoft :: Windows",
|
|
43
|
+
"Operating System :: POSIX :: Linux",
|
|
44
|
+
"Programming Language :: Python",
|
|
45
|
+
"Programming Language :: Python :: 3.12",
|
|
46
|
+
]
|
|
47
|
+
|
|
48
|
+
[project.optional-dependencies]
|
|
49
|
+
# Distributed execution backend (RayExecutor + RealRayRuntime). Optional and heavy:
|
|
50
|
+
# only the S3 bulk-ingestion job installs `techai-webutils[ray]`. The default
|
|
51
|
+
# asyncio path (AsyncioExecutor) never pulls Ray — the RayRuntime protocol and
|
|
52
|
+
# RayExecutor carry no `ray` import; only RealRayRuntime does, imported lazily by
|
|
53
|
+
# `executor_from_config` when `ingestion.executor.kind: ray`.
|
|
54
|
+
#
|
|
55
|
+
# ⚠ Ray requires the driver and the cluster to run the SAME version. Pinned EXACTLY to match the
|
|
56
|
+
# `ray-head` Compose image (rayproject/ray:2.56.1-py312), the KubeRay cluster, AND the Ray
|
|
57
|
+
# testcontainer in the integration tests — `ray://` rejects a version mismatch. Bump this pin, the
|
|
58
|
+
# dev-group `ray` pin below, and the compose/KubeRay image together when upgrading Ray.
|
|
59
|
+
ray = ["ray==2.56.1"]
|
|
60
|
+
|
|
61
|
+
# Cross-pod single-writer lock backend (PostgresAdvisoryLock). Optional: only the
|
|
62
|
+
# ingestion worker installs `techai-webutils[postgres]`. The default in-memory lock never pulls
|
|
63
|
+
# asyncpg — the `postgres` backend impl is imported lazily by `lock_from_config` when
|
|
64
|
+
# `ingestion.lock.kind: postgres`.
|
|
65
|
+
postgres = ["asyncpg>=0.30.0"]
|
|
66
|
+
|
|
67
|
+
# Document-parsing backend (the `isolated` parser: MarkItDown + pymupdf). Optional and heavy: only a
|
|
68
|
+
# parse-running deployable (the ingestion worker) installs `techai-webutils[parsing]`. The
|
|
69
|
+
# `clients/parsing` factory + interface never import these — the `isolated` backend imports them
|
|
70
|
+
# lazily inside its parse methods / the forkserver, so the default import graph never pulls them.
|
|
71
|
+
parsing = ["markitdown[docx,pdf,pptx,xls,xlsx]>=0.1.6", "pymupdf>=1.28.0"]
|
|
72
|
+
|
|
73
|
+
# Language-detection backend (the `langdetect` MetadataExtractor). Optional: only a
|
|
74
|
+
# metadata-extracting deployable installs `techai-webutils[langdetect]`. The `clients/metadata`
|
|
75
|
+
# factory never imports it — the `langdetect` backend subpackage is imported lazily by
|
|
76
|
+
# `metadata_extractor_from_config`, so the default import graph never pulls it.
|
|
77
|
+
langdetect = ["langdetect>=1.0.9"]
|
|
78
|
+
|
|
79
|
+
[project.license]
|
|
80
|
+
text = "MIT"
|
|
81
|
+
|
|
82
|
+
[project.urls]
|
|
83
|
+
Homepage = "https://github.com/gt-tech-ai/knowledge-engine"
|
|
84
|
+
Documentation = "https://github.com/gt-tech-ai/knowledge-engine"
|
|
85
|
+
Repository = "https://github.com/gt-tech-ai/knowledge-engine"
|
|
86
|
+
|
|
87
|
+
[build-system]
|
|
88
|
+
requires = ["uv_build>=0.11.15,<0.12.0"]
|
|
89
|
+
build-backend = "uv_build"
|
|
90
|
+
|
|
91
|
+
[dependency-groups]
|
|
92
|
+
dev = [
|
|
93
|
+
"autogitsemver>=0.9.13",
|
|
94
|
+
"pytest>=9.0.3",
|
|
95
|
+
"pytest-asyncio>=1.0.0",
|
|
96
|
+
"pytest-cov>=7.1.0",
|
|
97
|
+
# Installed in dev/CI so basedpyright can resolve RealRayRuntime's `import ray` and the real-Ray
|
|
98
|
+
# integration tests (@pytest.mark.integration) can run against a Ray testcontainer; production
|
|
99
|
+
# consumers pull it via the `ray` extra, not this group. Pinned EXACTLY to the same version as the
|
|
100
|
+
# `ray` extra + the ray-head image so the ray:// driver matches the cluster (see the extra above).
|
|
101
|
+
"ray==2.56.1",
|
|
102
|
+
"ruff>=0.15.13",
|
|
103
|
+
"basedpyright>=1.31",
|
|
104
|
+
# asyncpg in dev so basedpyright resolves `import asyncpg` in the postgres lock backend and the
|
|
105
|
+
# real-Postgres integration test can run; production consumers pull it via the `postgres` extra.
|
|
106
|
+
"asyncpg>=0.30.0",
|
|
107
|
+
# markitdown + pymupdf in dev so basedpyright resolves the `isolated` parser backend's lazy
|
|
108
|
+
# imports and its parity tests (real conversion + real subprocess isolation) run; production
|
|
109
|
+
# consumers pull them via the `parsing` extra.
|
|
110
|
+
"markitdown[docx,pdf,pptx,xls,xlsx]>=0.1.6",
|
|
111
|
+
"pymupdf>=1.28.0",
|
|
112
|
+
# langdetect in dev so basedpyright resolves the `langdetect` metadata backend and its parity
|
|
113
|
+
# tests run; production consumers pull it via the `langdetect` extra.
|
|
114
|
+
"langdetect>=1.0.9",
|
|
115
|
+
"testcontainers[postgres,redis]>=4.14.2",
|
|
116
|
+
"ty>=0.0.38",
|
|
117
|
+
]
|
|
118
|
+
|
|
119
|
+
[tool.pytest.ini_options]
|
|
120
|
+
# tests/ is put on sys.path by pytest's default prepend import mode (there is no
|
|
121
|
+
# tests/__init__.py). Test doubles are built inline with unittest.mock in each
|
|
122
|
+
# test (spec-bound to the real core interfaces), so no shared test-double package
|
|
123
|
+
# and no pythonpath directive are needed.
|
|
124
|
+
# Phase 3: hand-written unit coverage is gated at >=90%. The earlier "91.6% vs
|
|
125
|
+
# 83.4%" pytest-vs-`python -m pytest` discrepancy did NOT reproduce (both paths
|
|
126
|
+
# measure identically) — it was a stale-`.coverage` artifact. The real driver of
|
|
127
|
+
# the sub-90 reading was the denominator: integration-only external wrappers (gRPC
|
|
128
|
+
# server factory + OTel tracing interceptors, SQS/S3/Redis clients, OTel tracer/
|
|
129
|
+
# observability). Those are carved out below (covered by the Phase-4 integration
|
|
130
|
+
# suite, the Python equivalent of Go's unit-only carve-outs); the genuinely
|
|
131
|
+
# unit-testable interceptor logic was tested instead of excluded.
|
|
132
|
+
addopts = "--verbose -vv --capture=no --strict-markers --cov=techai_webutils --cov-report html --cov-report term --cov-report xml:coverage.xml --cov-fail-under=90.0"
|
|
133
|
+
# Registered markers (enforced by --strict-markers, so a typo'd/unregistered marker
|
|
134
|
+
# now errors instead of silently passing). `integration` tests need a Docker daemon
|
|
135
|
+
# (testcontainers) and are deselected from the default unit run via `-m "not integration"`.
|
|
136
|
+
markers = [
|
|
137
|
+
"integration: real-dependency tests via testcontainers (Docker required); deselected in the unit run",
|
|
138
|
+
"slow: slow tests, deselected with --fast",
|
|
139
|
+
]
|
|
140
|
+
|
|
141
|
+
[tool.coverage.run]
|
|
142
|
+
# relative_files + a distinct (non-hidden, so GitHub upload-artifact keeps it)
|
|
143
|
+
# data file let the combined coverage GATE merge this unit dataset with the
|
|
144
|
+
# integration dataset across separate CI jobs (see the `python-coverage-gate` job
|
|
145
|
+
# + .coveragerc.combined). `search test unit --python` writes coverage_unit.dat;
|
|
146
|
+
# the integration run writes coverage_integration.dat; the gate combines them.
|
|
147
|
+
relative_files = true
|
|
148
|
+
data_file = "coverage_unit.dat"
|
|
149
|
+
|
|
150
|
+
[tool.coverage.report]
|
|
151
|
+
# Excluded from the UNIT denominator (>=90% gate is over hand-written, unit-testable
|
|
152
|
+
# logic). Each entry is either test infrastructure or a thin external-dependency
|
|
153
|
+
# wrapper whose uncovered lines are the real network/SDK calls — exercised by the
|
|
154
|
+
# Phase-4 integration suite, not unit tests. Mirrors Go's unit-only carve-out set.
|
|
155
|
+
#
|
|
156
|
+
# This omit is at REPORT time (not [run]) so the unit run still MEASURES the
|
|
157
|
+
# wrappers — their partial unit coverage then lands in .coverage.unit and merges
|
|
158
|
+
# into the combined gate (.coveragerc.combined), which counts the wrappers.
|
|
159
|
+
omit = [
|
|
160
|
+
"*/clients/transport/grpc/server.py", # gRPC server factory (binds/serves) — integration
|
|
161
|
+
"*/clients/rpc/grpc/interceptors/tracing.py", # OTel client span wiring — integration/runtime
|
|
162
|
+
"*/clients/rpc/grpc/interceptors/tracing_server.py", # OTel server span wiring — integration/runtime
|
|
163
|
+
"*/clients/messaging/sqs/sqs_publisher.py", # boto3 SQS send — integration (ElasticMQ)
|
|
164
|
+
"*/clients/messaging/sqs/sqs_subscriber.py", # boto3 SQS receive loop — integration (ElasticMQ)
|
|
165
|
+
"*/foundation/resilience/sqs_dlq.py", # boto3 SQS DLQ send — integration (ElasticMQ)
|
|
166
|
+
"*/clients/storage/s3/s3_client.py", # boto3 S3 client — integration (MinIO)
|
|
167
|
+
"*/clients/llm/bedrock/*.py", # aiobotocore bedrock-runtime wrapper — integration/runtime
|
|
168
|
+
"*/clients/retrieval/bedrock/*.py", # aiobotocore bedrock-agent-runtime wrapper — integration/runtime
|
|
169
|
+
"*/clients/kb_ingestion/bedrock/*.py", # aiobotocore bedrock-agent KB ingestion — integration/runtime
|
|
170
|
+
"*/clients/email/ses/provider.py", # aiobotocore SESv2 send — E2E only (staging/prod SES)
|
|
171
|
+
"*/clients/email/smtp/provider.py", # aiosmtplib SMTP send — E2E only (dev Mailpit)
|
|
172
|
+
"*/clients/cache/redis/cache.py", # aioredis wrapper — integration (Redis)
|
|
173
|
+
"*/foundation/tracer/tracer.py", # OTel tracer SDK init — integration/runtime
|
|
174
|
+
"*/foundation/observability.py", # OTel observability bootstrap — integration/runtime
|
|
175
|
+
"*/execution/executor/real_ray_runtime.py", # ray.init + @ray.remote wrapper — integration (real Ray)
|
|
176
|
+
]
|
|
177
|
+
|
|
178
|
+
[tool.ruff]
|
|
179
|
+
line-length = 110
|
|
180
|
+
|
|
181
|
+
[tool.ruff.lint]
|
|
182
|
+
exclude = ["tests/**"]
|
|
183
|
+
|
|
184
|
+
select = ["ALL"]
|
|
185
|
+
|
|
186
|
+
ignore = [
|
|
187
|
+
"ANN002", # Missing type annotation for `*args`
|
|
188
|
+
"ANN003", # Missing type annotation for `**kwargs`
|
|
189
|
+
"BLE001", # Do not catch blind exception: `Exception`
|
|
190
|
+
"COM812", # Trailing comma missing
|
|
191
|
+
"CPY001", # flake8-copyright: repo does not use file copyright headers
|
|
192
|
+
"D105", # Missing docstring in magic method
|
|
193
|
+
"D107", # Missing docstring in `__init__` method
|
|
194
|
+
"D202", # No blank lines allowed after function docstring
|
|
195
|
+
"D203", # 1 blank line before class docstring (conflicts with D211; ruff keeps D211)
|
|
196
|
+
"D213", # Multi-line summary on second line (conflicts with D212; ruff keeps D212)
|
|
197
|
+
"E501", # Line too long
|
|
198
|
+
"FIX002", # Line contains TODO, consider resolving the issue
|
|
199
|
+
"I001", # Import block is un-sorted or un-formatted
|
|
200
|
+
"N802", # Function name `xxx` should be lowercase
|
|
201
|
+
"N999", # Invalid module name
|
|
202
|
+
"RSE102", # Unnecessary parentheses on raise exception
|
|
203
|
+
"S101", # Use of assert detected
|
|
204
|
+
"TC006", # Add quotes to type expression in `typing.cast()`
|
|
205
|
+
"TD002", # Missing author in TODO
|
|
206
|
+
"TD003", # Missing issue link for this TODO
|
|
207
|
+
"TRY002", # Create your own exception
|
|
208
|
+
"TRY300", # Consider moving this statement to an `else` block
|
|
209
|
+
"UP032", # Use f-string instead of `format` call
|
|
210
|
+
]
|
|
211
|
+
|
|
212
|
+
[tool.ruff.lint.per-file-ignores]
|
|
213
|
+
# The bedrock clients mirror the AWS bedrock-runtime / bedrock-agent-runtime / bedrock-agent APIs, whose
|
|
214
|
+
# keyword params are camelCase (knowledgeBaseId, modelId, retrievalQuery, dataSourceId, …) — N803 does
|
|
215
|
+
# not apply to a wire mirror.
|
|
216
|
+
"src/techai_webutils/clients/llm/bedrock/*.py" = ["N803"]
|
|
217
|
+
"src/techai_webutils/clients/retrieval/bedrock/*.py" = ["N803"]
|
|
218
|
+
"src/techai_webutils/clients/kb_ingestion/bedrock/*.py" = ["N803"]
|
|
219
|
+
|
|
220
|
+
[tool.ruff.lint.mccabe]
|
|
221
|
+
max-complexity = 15
|
|
222
|
+
|
|
223
|
+
[tool.ruff.lint.pylint]
|
|
224
|
+
max-args = 10
|
|
225
|
+
max-branches = 20
|
|
226
|
+
max-returns = 20
|
|
227
|
+
|
|
228
|
+
[tool.pyright]
|
|
229
|
+
pythonVersion = "3.12"
|
|
230
|
+
typeCheckingMode = "standard"
|
|
231
|
+
include = ["src/techai_webutils"]
|
|
232
|
+
exclude = ["tests"]
|
|
233
|
+
|
|
234
|
+
[tool.uv.build-backend]
|
|
235
|
+
module-name = "techai_webutils"
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"""Clients layer - external system integration abstractions.
|
|
2
|
+
|
|
3
|
+
This layer contains gRPC client/server factories, decorators, messaging (SQS),
|
|
4
|
+
storage (S3), cache decorators, and integration code for external systems.
|
|
5
|
+
|
|
6
|
+
Clients implements the third layer in the nine-layer architecture model:
|
|
7
|
+
core -> foundation -> clients -> repos -> services -> pipelines -> workflows -> controllers
|
|
8
|
+
"""
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"""Cache client tier — config-selected backends (redis/local/null) + decorators.
|
|
2
|
+
|
|
3
|
+
Mirrors Go's ``clients/cache``: ``builder.py`` selects a backend by ``CacheKind`` and returns the
|
|
4
|
+
core ``Cache`` interface; each backend lives in its own subpackage (``redis``/``local``/``null``);
|
|
5
|
+
``decorators.py`` wraps a cache with logging + metrics. Relocated from ``foundation/cache`` (D2) so the
|
|
6
|
+
concrete backends sit at the clients tier (L2, external-system integration), matching Go.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from techai_webutils.clients.cache.builder import (
|
|
10
|
+
CacheConfig,
|
|
11
|
+
CacheKind,
|
|
12
|
+
default_config,
|
|
13
|
+
new_cache_from_config,
|
|
14
|
+
)
|
|
15
|
+
from techai_webutils.clients.cache.decorators import CacheBuilder
|
|
16
|
+
from techai_webutils.clients.cache.envelope import CacheEnvelope, decode, encode
|
|
17
|
+
from techai_webutils.clients.cache.local import LocalCache
|
|
18
|
+
from techai_webutils.clients.cache.null import NullCache
|
|
19
|
+
from techai_webutils.clients.cache.redis import RedisCache
|
|
20
|
+
from techai_webutils.clients.cache.types import FailureMode
|
|
21
|
+
|
|
22
|
+
__all__ = [
|
|
23
|
+
"CacheBuilder",
|
|
24
|
+
"CacheConfig",
|
|
25
|
+
"CacheEnvelope",
|
|
26
|
+
"CacheKind",
|
|
27
|
+
"FailureMode",
|
|
28
|
+
"LocalCache",
|
|
29
|
+
"NullCache",
|
|
30
|
+
"RedisCache",
|
|
31
|
+
"decode",
|
|
32
|
+
"default_config",
|
|
33
|
+
"encode",
|
|
34
|
+
"new_cache_from_config",
|
|
35
|
+
]
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"""Cache builder with kind enum, config dataclass, and factory function.
|
|
2
|
+
|
|
3
|
+
Creates cache instances based on configuration. Supports REDIS, LOCAL, and NULL
|
|
4
|
+
cache kinds. The factory function routes to the correct implementation based on
|
|
5
|
+
the CacheKind in the config.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
from dataclasses import dataclass
|
|
11
|
+
from enum import StrEnum
|
|
12
|
+
from typing import Any, TYPE_CHECKING
|
|
13
|
+
|
|
14
|
+
from techai_webutils.clients.cache.local import LocalCache
|
|
15
|
+
from techai_webutils.clients.cache.null import NullCache
|
|
16
|
+
from techai_webutils.clients.cache.redis import RedisCache
|
|
17
|
+
from techai_webutils.clients.cache.types import FailureMode
|
|
18
|
+
|
|
19
|
+
if TYPE_CHECKING:
|
|
20
|
+
from techai_webutils.core.interfaces.cache import Cache
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class CacheKind(StrEnum):
|
|
24
|
+
"""Available cache implementations."""
|
|
25
|
+
|
|
26
|
+
REDIS = "redis"
|
|
27
|
+
"""The Redis-backed cache (shared, cross-pod; stage/prod)."""
|
|
28
|
+
LOCAL = "local"
|
|
29
|
+
"""The in-process TTL cache (single-pod; dev/test)."""
|
|
30
|
+
NULL = "null"
|
|
31
|
+
"""The no-op cache that never stores or returns a value (caching disabled)."""
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
@dataclass
|
|
35
|
+
class CacheConfig:
|
|
36
|
+
"""Configuration for cache creation.
|
|
37
|
+
|
|
38
|
+
Attributes:
|
|
39
|
+
kind: Which cache implementation to use.
|
|
40
|
+
default_ttl: Default TTL in seconds.
|
|
41
|
+
redis_client: An async Redis client instance (required when kind is REDIS).
|
|
42
|
+
failure_mode: Redis failure mode (only used when kind is REDIS).
|
|
43
|
+
|
|
44
|
+
"""
|
|
45
|
+
|
|
46
|
+
kind: CacheKind = CacheKind.LOCAL
|
|
47
|
+
"""Selects the cache implementation (defaults to the in-process LOCAL cache)."""
|
|
48
|
+
default_ttl: int = 300
|
|
49
|
+
"""Default time-to-live for cached entries, in seconds."""
|
|
50
|
+
redis_client: Any = None
|
|
51
|
+
"""An async Redis client instance (required when ``kind`` is REDIS)."""
|
|
52
|
+
failure_mode: FailureMode = FailureMode.BYPASS
|
|
53
|
+
"""How a Redis failure is handled (only used when ``kind`` is REDIS)."""
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def default_config() -> CacheConfig:
|
|
57
|
+
"""Return a default cache config (LOCAL with 300s TTL)."""
|
|
58
|
+
return CacheConfig(kind=CacheKind.LOCAL, default_ttl=300)
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def new_cache_from_config(config: CacheConfig) -> Cache:
|
|
62
|
+
"""Create a cache instance from config.
|
|
63
|
+
|
|
64
|
+
Args:
|
|
65
|
+
config: Cache configuration specifying kind and parameters.
|
|
66
|
+
|
|
67
|
+
Returns:
|
|
68
|
+
A Cache implementation matching the requested kind.
|
|
69
|
+
|
|
70
|
+
Raises:
|
|
71
|
+
ValueError: If the kind is unknown or required parameters are missing.
|
|
72
|
+
|
|
73
|
+
"""
|
|
74
|
+
if config.kind == CacheKind.LOCAL:
|
|
75
|
+
return LocalCache(default_ttl=config.default_ttl)
|
|
76
|
+
|
|
77
|
+
if config.kind == CacheKind.NULL:
|
|
78
|
+
return NullCache()
|
|
79
|
+
|
|
80
|
+
if config.kind == CacheKind.REDIS:
|
|
81
|
+
if config.redis_client is None:
|
|
82
|
+
msg = "redis_client is required when kind is REDIS"
|
|
83
|
+
raise ValueError(msg)
|
|
84
|
+
return RedisCache(client=config.redis_client, failure_mode=config.failure_mode)
|
|
85
|
+
|
|
86
|
+
msg = f"unknown cache kind: {config.kind}"
|
|
87
|
+
raise ValueError(msg)
|