techai-webutils 0.0.1__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.0.1/PKG-INFO +108 -0
- techai_webutils-0.0.1/README.md +62 -0
- techai_webutils-0.0.1/pyproject.toml +188 -0
- techai_webutils-0.0.1/pyproject.toml.orig +269 -0
- techai_webutils-0.0.1/src/techai_webutils/__init__.py +5 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/__init__.py +8 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/audit/__init__.py +9 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/audit/builder.py +80 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/audit/stub/__init__.py +5 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/audit/stub/sink.py +29 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/cache/__init__.py +35 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/cache/builder.py +88 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/cache/decorators.py +285 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/cache/envelope.py +51 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/cache/local/__init__.py +5 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/cache/local/cache.py +70 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/cache/null/__init__.py +5 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/cache/null/cache.py +31 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/cache/redis/__init__.py +6 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/cache/redis/cache.py +95 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/cache/types.py +27 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/chunking/__init__.py +13 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/chunking/factory.py +49 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/chunking/fixed/__init__.py +5 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/chunking/fixed/chunker.py +71 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/decorators/__init__.py +9 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/decorators/ai_enricher.py +472 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/decorators/event_stack.py +104 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/decorators/job_stack.py +77 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/decorators/metrics_proxy.py +130 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/decorators/proxy.py +481 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/email/__init__.py +13 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/email/builder.py +73 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/email/noop/__init__.py +5 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/email/noop/provider.py +19 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/email/ses/__init__.py +5 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/email/ses/provider.py +33 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/email/smtp/__init__.py +5 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/email/smtp/provider.py +27 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/embedding/__init__.py +13 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/embedding/builder.py +70 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/embedding/ollama/__init__.py +5 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/embedding/ollama/provider.py +72 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/embedding/stub/__init__.py +5 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/embedding/stub/provider.py +57 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/facts/__init__.py +9 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/facts/builder.py +91 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/facts/messaging/__init__.py +5 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/facts/messaging/publisher.py +189 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/facts/stub/__init__.py +5 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/facts/stub/publisher.py +20 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/jobs/__init__.py +23 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/jobs/builder.py +30 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/jobs/config.py +28 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/jobs/memory/__init__.py +18 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/jobs/memory/backend.py +92 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/kb_ingestion/__init__.py +6 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/kb_ingestion/bedrock/__init__.py +7 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/kb_ingestion/bedrock/ingestor.py +212 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/kb_ingestion/builder.py +58 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/kb_ingestion/decorators.py +271 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/kb_ingestion/mapping.py +73 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/kb_ingestion/noop/__init__.py +5 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/kb_ingestion/noop/ingestor.py +68 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/llm/__init__.py +5 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/llm/bedrock/__init__.py +5 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/llm/bedrock/provider.py +250 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/llm/builder.py +94 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/llm/decorators.py +188 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/llm/ollama/__init__.py +5 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/llm/ollama/provider.py +209 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/llm/stub/__init__.py +5 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/llm/stub/provider.py +103 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/lock/__init__.py +28 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/lock/builder.py +92 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/lock/memory/__init__.py +5 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/lock/memory/lock.py +46 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/lock/postgres/__init__.py +5 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/lock/postgres/lock.py +216 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/lock/runner.py +39 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/messaging/__init__.py +23 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/messaging/builder.py +72 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/messaging/config.py +49 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/messaging/memory/__init__.py +7 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/messaging/memory/broker.py +31 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/messaging/memory/publisher.py +40 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/messaging/memory/subscriber.py +73 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/messaging/sqs/__init__.py +11 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/messaging/sqs/sqs_publisher.py +97 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/messaging/sqs/sqs_subscriber.py +136 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/metadata/__init__.py +14 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/metadata/factory.py +49 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/metadata/langdetect/__init__.py +13 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/metadata/langdetect/extractor.py +70 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/parsing/__init__.py +14 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/parsing/factory.py +61 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/parsing/isolated/__init__.py +23 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/parsing/isolated/detect.py +109 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/parsing/isolated/isolated.py +274 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/parsing/isolated/markitdown_parser.py +243 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/retrieval/__init__.py +37 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/retrieval/bedrock/__init__.py +17 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/retrieval/bedrock/engine.py +230 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/retrieval/builder.py +250 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/retrieval/filtering.py +158 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/retrieval/stub/__init__.py +5 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/retrieval/stub/engine.py +42 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/retrieval/vector/__init__.py +5 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/retrieval/vector/engine.py +99 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/rpc/__init__.py +14 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/rpc/builder.py +43 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/rpc/grpc/__init__.py +5 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/rpc/grpc/client.py +51 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/rpc/grpc/errors.py +92 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/rpc/grpc/interceptors/__init__.py +35 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/rpc/grpc/interceptors/auth.py +125 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/rpc/grpc/interceptors/builder.py +81 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/rpc/grpc/interceptors/circuit_breaker.py +70 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/rpc/grpc/interceptors/logging.py +57 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/rpc/grpc/interceptors/metrics.py +42 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/rpc/grpc/interceptors/retry.py +63 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/rpc/grpc/interceptors/server_builder.py +612 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/rpc/grpc/interceptors/timeout.py +56 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/rpc/grpc/interceptors/tracing.py +41 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/rpc/grpc/interceptors/tracing_server.py +159 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/splitting/__init__.py +13 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/splitting/factory.py +48 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/splitting/kb_unit/__init__.py +8 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/splitting/kb_unit/splitter.py +156 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/storage/__init__.py +21 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/storage/builder.py +55 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/storage/config.py +46 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/storage/memory/__init__.py +5 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/storage/memory/client.py +90 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/storage/s3/__init__.py +10 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/storage/s3/s3_client.py +242 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/token_ledger/__init__.py +17 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/token_ledger/builder.py +91 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/token_ledger/cost.py +69 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/token_ledger/redis/__init__.py +5 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/token_ledger/redis/ledger.py +321 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/token_ledger/stub/__init__.py +5 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/token_ledger/stub/ledger.py +38 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/transport/__init__.py +5 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/transport/grpc/__init__.py +9 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/transport/grpc/server.py +180 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/vector/__init__.py +13 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/vector/builder.py +66 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/vector/composition.py +78 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/vector/qdrant/__init__.py +5 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/vector/qdrant/store.py +216 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/vector/stub/__init__.py +5 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/vector/stub/store.py +112 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/vector_kb/__init__.py +15 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/vector_kb/builder.py +61 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/vector_kb/vector/__init__.py +5 -0
- techai_webutils-0.0.1/src/techai_webutils/clients/vector_kb/vector/knowledge_base.py +190 -0
- techai_webutils-0.0.1/src/techai_webutils/controllers/__init__.py +26 -0
- techai_webutils-0.0.1/src/techai_webutils/controllers/adapt.py +72 -0
- techai_webutils-0.0.1/src/techai_webutils/controllers/base.py +115 -0
- techai_webutils-0.0.1/src/techai_webutils/controllers/decorators.py +255 -0
- techai_webutils-0.0.1/src/techai_webutils/core/__init__.py +1 -0
- techai_webutils-0.0.1/src/techai_webutils/core/domain/__init__.py +20 -0
- techai_webutils-0.0.1/src/techai_webutils/core/domain/metadata.py +28 -0
- techai_webutils-0.0.1/src/techai_webutils/core/domain/parser.py +92 -0
- techai_webutils-0.0.1/src/techai_webutils/core/domain/splitter.py +39 -0
- techai_webutils-0.0.1/src/techai_webutils/core/domain_types/__init__.py +25 -0
- techai_webutils-0.0.1/src/techai_webutils/core/domain_types/types.py +136 -0
- techai_webutils-0.0.1/src/techai_webutils/core/errors/__init__.py +39 -0
- techai_webutils-0.0.1/src/techai_webutils/core/errors/errors.py +276 -0
- techai_webutils-0.0.1/src/techai_webutils/core/interfaces/__init__.py +187 -0
- techai_webutils-0.0.1/src/techai_webutils/core/interfaces/adaptive_throttler.py +31 -0
- techai_webutils-0.0.1/src/techai_webutils/core/interfaces/audit.py +84 -0
- techai_webutils-0.0.1/src/techai_webutils/core/interfaces/bulkhead.py +32 -0
- techai_webutils-0.0.1/src/techai_webutils/core/interfaces/byte_cache.py +35 -0
- techai_webutils-0.0.1/src/techai_webutils/core/interfaces/cache.py +54 -0
- techai_webutils-0.0.1/src/techai_webutils/core/interfaces/chunker.py +21 -0
- techai_webutils-0.0.1/src/techai_webutils/core/interfaces/circuit_breaker.py +41 -0
- techai_webutils-0.0.1/src/techai_webutils/core/interfaces/config_loader.py +41 -0
- techai_webutils-0.0.1/src/techai_webutils/core/interfaces/crud_service.py +75 -0
- techai_webutils-0.0.1/src/techai_webutils/core/interfaces/dedup.py +26 -0
- techai_webutils-0.0.1/src/techai_webutils/core/interfaces/dlq.py +41 -0
- techai_webutils-0.0.1/src/techai_webutils/core/interfaces/document.py +64 -0
- techai_webutils-0.0.1/src/techai_webutils/core/interfaces/email.py +19 -0
- techai_webutils-0.0.1/src/techai_webutils/core/interfaces/embedding.py +38 -0
- techai_webutils-0.0.1/src/techai_webutils/core/interfaces/execution.py +291 -0
- techai_webutils-0.0.1/src/techai_webutils/core/interfaces/fact_publisher.py +26 -0
- techai_webutils-0.0.1/src/techai_webutils/core/interfaces/hedger.py +29 -0
- techai_webutils-0.0.1/src/techai_webutils/core/interfaces/jobs.py +82 -0
- techai_webutils-0.0.1/src/techai_webutils/core/interfaces/kb_ingestion.py +156 -0
- techai_webutils-0.0.1/src/techai_webutils/core/interfaces/knowledge_base.py +82 -0
- techai_webutils-0.0.1/src/techai_webutils/core/interfaces/leader.py +23 -0
- techai_webutils-0.0.1/src/techai_webutils/core/interfaces/lifecycle.py +75 -0
- techai_webutils-0.0.1/src/techai_webutils/core/interfaces/llm.py +124 -0
- techai_webutils-0.0.1/src/techai_webutils/core/interfaces/lock.py +56 -0
- techai_webutils-0.0.1/src/techai_webutils/core/interfaces/logger.py +47 -0
- techai_webutils-0.0.1/src/techai_webutils/core/interfaces/messaging.py +69 -0
- techai_webutils-0.0.1/src/techai_webutils/core/interfaces/metadata.py +22 -0
- techai_webutils-0.0.1/src/techai_webutils/core/interfaces/metrics.py +83 -0
- techai_webutils-0.0.1/src/techai_webutils/core/interfaces/op_service.py +25 -0
- techai_webutils-0.0.1/src/techai_webutils/core/interfaces/parser.py +35 -0
- techai_webutils-0.0.1/src/techai_webutils/core/interfaces/pipeline.py +47 -0
- techai_webutils-0.0.1/src/techai_webutils/core/interfaces/rate_limiter.py +22 -0
- techai_webutils-0.0.1/src/techai_webutils/core/interfaces/repository.py +85 -0
- techai_webutils-0.0.1/src/techai_webutils/core/interfaces/retrier.py +25 -0
- techai_webutils-0.0.1/src/techai_webutils/core/interfaces/retrieval.py +166 -0
- techai_webutils-0.0.1/src/techai_webutils/core/interfaces/service.py +55 -0
- techai_webutils-0.0.1/src/techai_webutils/core/interfaces/splitter.py +23 -0
- techai_webutils-0.0.1/src/techai_webutils/core/interfaces/storage.py +90 -0
- techai_webutils-0.0.1/src/techai_webutils/core/interfaces/store.py +55 -0
- techai_webutils-0.0.1/src/techai_webutils/core/interfaces/token_ledger.py +136 -0
- techai_webutils-0.0.1/src/techai_webutils/core/interfaces/tracer.py +55 -0
- techai_webutils-0.0.1/src/techai_webutils/core/interfaces/vector_store.py +94 -0
- techai_webutils-0.0.1/src/techai_webutils/core/interfaces/workflow.py +48 -0
- techai_webutils-0.0.1/src/techai_webutils/core/types/__init__.py +5 -0
- techai_webutils-0.0.1/src/techai_webutils/core/types/aws_client.py +24 -0
- techai_webutils-0.0.1/src/techai_webutils/core/types/fact.py +98 -0
- techai_webutils-0.0.1/src/techai_webutils/execution/__init__.py +49 -0
- techai_webutils-0.0.1/src/techai_webutils/execution/engine/__init__.py +5 -0
- techai_webutils-0.0.1/src/techai_webutils/execution/engine/fan_out.py +111 -0
- techai_webutils-0.0.1/src/techai_webutils/execution/engine/run.py +63 -0
- techai_webutils-0.0.1/src/techai_webutils/execution/executor/__init__.py +36 -0
- techai_webutils-0.0.1/src/techai_webutils/execution/executor/asyncio_executor.py +43 -0
- techai_webutils-0.0.1/src/techai_webutils/execution/executor/factory.py +93 -0
- techai_webutils-0.0.1/src/techai_webutils/execution/executor/pooled.py +155 -0
- techai_webutils-0.0.1/src/techai_webutils/execution/executor/ray_executor.py +62 -0
- techai_webutils-0.0.1/src/techai_webutils/execution/executor/ray_runtime.py +45 -0
- techai_webutils-0.0.1/src/techai_webutils/execution/executor/real_ray_pool.py +140 -0
- techai_webutils-0.0.1/src/techai_webutils/execution/executor/real_ray_runtime.py +124 -0
- techai_webutils-0.0.1/src/techai_webutils/execution/executor/resilient_ray_runtime.py +99 -0
- techai_webutils-0.0.1/src/techai_webutils/execution/gate/__init__.py +19 -0
- techai_webutils-0.0.1/src/techai_webutils/execution/gate/gate.py +151 -0
- techai_webutils-0.0.1/src/techai_webutils/execution/job/__init__.py +5 -0
- techai_webutils-0.0.1/src/techai_webutils/execution/job/conditional.py +47 -0
- techai_webutils-0.0.1/src/techai_webutils/execution/job/decorators/__init__.py +5 -0
- techai_webutils-0.0.1/src/techai_webutils/execution/job/decorators/builder.py +216 -0
- techai_webutils-0.0.1/src/techai_webutils/execution/job/job.py +216 -0
- techai_webutils-0.0.1/src/techai_webutils/foundation/__init__.py +1 -0
- techai_webutils-0.0.1/src/techai_webutils/foundation/config/__init__.py +35 -0
- techai_webutils-0.0.1/src/techai_webutils/foundation/config/bridge.py +289 -0
- techai_webutils-0.0.1/src/techai_webutils/foundation/config/config_loader.py +83 -0
- techai_webutils-0.0.1/src/techai_webutils/foundation/config/loader.py +121 -0
- techai_webutils-0.0.1/src/techai_webutils/foundation/config/settings.py +191 -0
- techai_webutils-0.0.1/src/techai_webutils/foundation/decorator.py +333 -0
- techai_webutils-0.0.1/src/techai_webutils/foundation/errors/__init__.py +1 -0
- techai_webutils-0.0.1/src/techai_webutils/foundation/errors/errors.py +142 -0
- techai_webutils-0.0.1/src/techai_webutils/foundation/lifecycle.py +70 -0
- techai_webutils-0.0.1/src/techai_webutils/foundation/logger/__init__.py +33 -0
- techai_webutils-0.0.1/src/techai_webutils/foundation/logger/builder.py +74 -0
- techai_webutils-0.0.1/src/techai_webutils/foundation/logger/logger.py +315 -0
- techai_webutils-0.0.1/src/techai_webutils/foundation/logger/redact.py +29 -0
- techai_webutils-0.0.1/src/techai_webutils/foundation/logger/stdlib_logger.py +132 -0
- techai_webutils-0.0.1/src/techai_webutils/foundation/metrics/__init__.py +31 -0
- techai_webutils-0.0.1/src/techai_webutils/foundation/metrics/builder.py +71 -0
- techai_webutils-0.0.1/src/techai_webutils/foundation/metrics/execution_observer.py +92 -0
- techai_webutils-0.0.1/src/techai_webutils/foundation/metrics/metrics.py +285 -0
- techai_webutils-0.0.1/src/techai_webutils/foundation/metrics/null_metrics.py +72 -0
- techai_webutils-0.0.1/src/techai_webutils/foundation/middleware/__init__.py +19 -0
- techai_webutils-0.0.1/src/techai_webutils/foundation/middleware/chain.py +35 -0
- techai_webutils-0.0.1/src/techai_webutils/foundation/middleware/http_observability.py +209 -0
- techai_webutils-0.0.1/src/techai_webutils/foundation/middleware/request_id.py +61 -0
- techai_webutils-0.0.1/src/techai_webutils/foundation/observability.py +69 -0
- techai_webutils-0.0.1/src/techai_webutils/foundation/resilience/__init__.py +27 -0
- techai_webutils-0.0.1/src/techai_webutils/foundation/resilience/adaptive_throttler.py +91 -0
- techai_webutils-0.0.1/src/techai_webutils/foundation/resilience/async_circuit_breaker.py +97 -0
- techai_webutils-0.0.1/src/techai_webutils/foundation/resilience/async_retry.py +105 -0
- techai_webutils-0.0.1/src/techai_webutils/foundation/resilience/aws_boundary.py +62 -0
- techai_webutils-0.0.1/src/techai_webutils/foundation/resilience/budget.py +59 -0
- techai_webutils-0.0.1/src/techai_webutils/foundation/resilience/bulkhead.py +198 -0
- techai_webutils-0.0.1/src/techai_webutils/foundation/resilience/circuit_breaker.py +142 -0
- techai_webutils-0.0.1/src/techai_webutils/foundation/resilience/classify.py +150 -0
- techai_webutils-0.0.1/src/techai_webutils/foundation/resilience/dedup.py +36 -0
- techai_webutils-0.0.1/src/techai_webutils/foundation/resilience/dlq.py +67 -0
- techai_webutils-0.0.1/src/techai_webutils/foundation/resilience/grpc_boundary.py +119 -0
- techai_webutils-0.0.1/src/techai_webutils/foundation/resilience/hedge.py +96 -0
- techai_webutils-0.0.1/src/techai_webutils/foundation/resilience/leader.py +22 -0
- techai_webutils-0.0.1/src/techai_webutils/foundation/resilience/per_key_rate_limiter.py +74 -0
- techai_webutils-0.0.1/src/techai_webutils/foundation/resilience/rate_limiter.py +64 -0
- techai_webutils-0.0.1/src/techai_webutils/foundation/resilience/retry.py +72 -0
- techai_webutils-0.0.1/src/techai_webutils/foundation/resilience/sqs_dlq.py +89 -0
- techai_webutils-0.0.1/src/techai_webutils/foundation/resilience/timeout.py +35 -0
- techai_webutils-0.0.1/src/techai_webutils/foundation/tracer/__init__.py +39 -0
- techai_webutils-0.0.1/src/techai_webutils/foundation/tracer/builder.py +81 -0
- techai_webutils-0.0.1/src/techai_webutils/foundation/tracer/conversation.py +98 -0
- techai_webutils-0.0.1/src/techai_webutils/foundation/tracer/null_tracer.py +42 -0
- techai_webutils-0.0.1/src/techai_webutils/foundation/tracer/tracer.py +160 -0
- techai_webutils-0.0.1/src/techai_webutils/pipelines/__init__.py +24 -0
- techai_webutils-0.0.1/src/techai_webutils/pipelines/base.py +89 -0
- techai_webutils-0.0.1/src/techai_webutils/pipelines/citations.py +57 -0
- techai_webutils-0.0.1/src/techai_webutils/pipelines/decorators.py +324 -0
- techai_webutils-0.0.1/src/techai_webutils/pipelines/generator.py +73 -0
- techai_webutils-0.0.1/src/techai_webutils/pipelines/rewriter.py +55 -0
- techai_webutils-0.0.1/src/techai_webutils/py.typed +0 -0
- techai_webutils-0.0.1/src/techai_webutils/repos/__init__.py +21 -0
- techai_webutils-0.0.1/src/techai_webutils/repos/cursor.py +51 -0
- techai_webutils-0.0.1/src/techai_webutils/repos/decorators/__init__.py +5 -0
- techai_webutils-0.0.1/src/techai_webutils/repos/decorators/builder.py +539 -0
- techai_webutils-0.0.1/src/techai_webutils/repos/errors/__init__.py +5 -0
- techai_webutils-0.0.1/src/techai_webutils/repos/errors/mapper.py +68 -0
- techai_webutils-0.0.1/src/techai_webutils/repos/repository.py +54 -0
- techai_webutils-0.0.1/src/techai_webutils/services/__init__.py +11 -0
- techai_webutils-0.0.1/src/techai_webutils/services/base.py +9 -0
- techai_webutils-0.0.1/src/techai_webutils/services/crud_service.py +50 -0
- techai_webutils-0.0.1/src/techai_webutils/services/decorators/__init__.py +5 -0
- techai_webutils-0.0.1/src/techai_webutils/services/decorators/builder.py +332 -0
- techai_webutils-0.0.1/src/techai_webutils/services/op_builder.py +226 -0
- techai_webutils-0.0.1/src/techai_webutils/workflows/__init__.py +24 -0
- techai_webutils-0.0.1/src/techai_webutils/workflows/base.py +90 -0
- techai_webutils-0.0.1/src/techai_webutils/workflows/decorators.py +338 -0
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
|
+
Name: techai-webutils
|
|
3
|
+
Version: 0.0.1
|
|
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-toolkit
|
|
39
|
+
Project-URL: Documentation, https://github.com/gt-tech-ai/knowledge-engine-toolkit
|
|
40
|
+
Project-URL: Repository, https://github.com/gt-tech-ai/knowledge-engine-toolkit
|
|
41
|
+
Provides-Extra: langdetect
|
|
42
|
+
Provides-Extra: parsing
|
|
43
|
+
Provides-Extra: postgres
|
|
44
|
+
Provides-Extra: ray
|
|
45
|
+
Description-Content-Type: text/markdown
|
|
46
|
+
|
|
47
|
+
# techai-webutils
|
|
48
|
+
|
|
49
|
+
**Development:**
|
|
50
|
+
[](https://github.com/astral-sh/uv)
|
|
51
|
+
[](https://github.com/astral-sh/ruff)
|
|
52
|
+
[](https://docs.pytest.org/)
|
|
53
|
+
[](https://github.com/gt-tech-ai/knowledge-engine-toolkit/actions/workflows/ci.yml)
|
|
54
|
+
[](https://github.com/gt-tech-ai/knowledge-engine-toolkit/commits/main/)
|
|
55
|
+
|
|
56
|
+
<!-- Content above this delimiter will be copied to the generated README.md file. DO NOT REMOVE THIS COMMENT, as it will cause regeneration to fail. -->
|
|
57
|
+
|
|
58
|
+
## Overview
|
|
59
|
+
|
|
60
|
+
`techai_webutils` is the Python mirror of the knowledge-engine-toolkit's Go substrate. It follows the same
|
|
61
|
+
layers (`core` → `foundation` (+ `execution`) → `clients` → `repos` → `services` → `pipelines` →
|
|
62
|
+
`workflows` → `controllers`) and the same rules, described in the repository's
|
|
63
|
+
[ARCHITECTURE.md](https://github.com/gt-tech-ai/knowledge-engine-toolkit/blob/main/ARCHITECTURE.md). Every
|
|
64
|
+
swappable component is a `Kind` + a config + a `new_<type>_from_config` factory, so switching a
|
|
65
|
+
backend (memory → S3, stub → Bedrock, asyncio → Ray) is a configuration change.
|
|
66
|
+
|
|
67
|
+
### How to use `techai_webutils`
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
uv add techai-webutils # or: pip install techai-webutils
|
|
71
|
+
uv add "techai-webutils[postgres]" # optional backends: ray, postgres, parsing, langdetect
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Build a component from its config at your composition root and inject it:
|
|
75
|
+
|
|
76
|
+
```python
|
|
77
|
+
from techai_webutils.clients.storage import (
|
|
78
|
+
S3Config,
|
|
79
|
+
StorageConfig,
|
|
80
|
+
StorageKind,
|
|
81
|
+
new_storage_from_config,
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
config = StorageConfig(
|
|
85
|
+
kind=StorageKind.MEMORY, # StorageKind.S3 in a deployment: same code, different config
|
|
86
|
+
s3=S3Config(endpoint="", bucket="documents", region="us-east-1"),
|
|
87
|
+
)
|
|
88
|
+
storage = new_storage_from_config(config)
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
The base install already includes the AWS, gRPC, FastAPI, Qdrant, Redis and OpenTelemetry clients.
|
|
92
|
+
The `ray`, `postgres`, `parsing` and `langdetect` extras are imported only when their backend is
|
|
93
|
+
selected, so a service installs just the extras its configuration uses.
|
|
94
|
+
|
|
95
|
+
Load layered YAML config (`base.yaml` → `{env}.yaml` → `secrets.yaml`) under an env prefix of
|
|
96
|
+
your own, and give your settings class the same `env_prefix`:
|
|
97
|
+
|
|
98
|
+
```python
|
|
99
|
+
from techai_webutils.foundation.config import initialize_config
|
|
100
|
+
|
|
101
|
+
initialize_config("config", env_prefix="MYAPP")
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Set a prefix: without one, config keys are exported under bare names (`AWS_REGION`, `DEBUG`) that
|
|
105
|
+
collide with ambient variables, such as the service links Kubernetes injects
|
|
106
|
+
(`REDIS_PORT=tcp://…`).
|
|
107
|
+
|
|
108
|
+
<!-- Content below this delimiter will be copied to the generated README.md file. DO NOT REMOVE THIS COMMENT, as it will cause regeneration to fail. -->
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# techai-webutils
|
|
2
|
+
|
|
3
|
+
**Development:**
|
|
4
|
+
[](https://github.com/astral-sh/uv)
|
|
5
|
+
[](https://github.com/astral-sh/ruff)
|
|
6
|
+
[](https://docs.pytest.org/)
|
|
7
|
+
[](https://github.com/gt-tech-ai/knowledge-engine-toolkit/actions/workflows/ci.yml)
|
|
8
|
+
[](https://github.com/gt-tech-ai/knowledge-engine-toolkit/commits/main/)
|
|
9
|
+
|
|
10
|
+
<!-- Content above this delimiter will be copied to the generated README.md file. DO NOT REMOVE THIS COMMENT, as it will cause regeneration to fail. -->
|
|
11
|
+
|
|
12
|
+
## Overview
|
|
13
|
+
|
|
14
|
+
`techai_webutils` is the Python mirror of the knowledge-engine-toolkit's Go substrate. It follows the same
|
|
15
|
+
layers (`core` → `foundation` (+ `execution`) → `clients` → `repos` → `services` → `pipelines` →
|
|
16
|
+
`workflows` → `controllers`) and the same rules, described in the repository's
|
|
17
|
+
[ARCHITECTURE.md](https://github.com/gt-tech-ai/knowledge-engine-toolkit/blob/main/ARCHITECTURE.md). Every
|
|
18
|
+
swappable component is a `Kind` + a config + a `new_<type>_from_config` factory, so switching a
|
|
19
|
+
backend (memory → S3, stub → Bedrock, asyncio → Ray) is a configuration change.
|
|
20
|
+
|
|
21
|
+
### How to use `techai_webutils`
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
uv add techai-webutils # or: pip install techai-webutils
|
|
25
|
+
uv add "techai-webutils[postgres]" # optional backends: ray, postgres, parsing, langdetect
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Build a component from its config at your composition root and inject it:
|
|
29
|
+
|
|
30
|
+
```python
|
|
31
|
+
from techai_webutils.clients.storage import (
|
|
32
|
+
S3Config,
|
|
33
|
+
StorageConfig,
|
|
34
|
+
StorageKind,
|
|
35
|
+
new_storage_from_config,
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
config = StorageConfig(
|
|
39
|
+
kind=StorageKind.MEMORY, # StorageKind.S3 in a deployment: same code, different config
|
|
40
|
+
s3=S3Config(endpoint="", bucket="documents", region="us-east-1"),
|
|
41
|
+
)
|
|
42
|
+
storage = new_storage_from_config(config)
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
The base install already includes the AWS, gRPC, FastAPI, Qdrant, Redis and OpenTelemetry clients.
|
|
46
|
+
The `ray`, `postgres`, `parsing` and `langdetect` extras are imported only when their backend is
|
|
47
|
+
selected, so a service installs just the extras its configuration uses.
|
|
48
|
+
|
|
49
|
+
Load layered YAML config (`base.yaml` → `{env}.yaml` → `secrets.yaml`) under an env prefix of
|
|
50
|
+
your own, and give your settings class the same `env_prefix`:
|
|
51
|
+
|
|
52
|
+
```python
|
|
53
|
+
from techai_webutils.foundation.config import initialize_config
|
|
54
|
+
|
|
55
|
+
initialize_config("config", env_prefix="MYAPP")
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Set a prefix: without one, config keys are exported under bare names (`AWS_REGION`, `DEBUG`) that
|
|
59
|
+
collide with ambient variables, such as the service links Kubernetes injects
|
|
60
|
+
(`REDIS_PORT=tcp://…`).
|
|
61
|
+
|
|
62
|
+
<!-- Content below this delimiter will be copied to the generated README.md file. DO NOT REMOVE THIS COMMENT, as it will cause regeneration to fail. -->
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "techai-webutils"
|
|
3
|
+
version = "0.0.1"
|
|
4
|
+
description = "techai-webutils"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
requires-python = ">= 3.12"
|
|
7
|
+
dependencies = [
|
|
8
|
+
"aiobotocore>=3.5.0",
|
|
9
|
+
"aiosmtplib>=3.0.0",
|
|
10
|
+
"fastapi>=0.136.0",
|
|
11
|
+
"grpcio>=1.80.0",
|
|
12
|
+
"grpcio-health-checking>=1.80.0",
|
|
13
|
+
"grpcio-reflection>=1.80.0",
|
|
14
|
+
"httpx>=0.28.1",
|
|
15
|
+
"opentelemetry-api>=1.41.0",
|
|
16
|
+
"opentelemetry-exporter-otlp-proto-grpc>=1.41.0",
|
|
17
|
+
"opentelemetry-sdk>=1.41.0",
|
|
18
|
+
"prometheus-client>=0.25.0",
|
|
19
|
+
"pydantic>=2.13.3",
|
|
20
|
+
"pydantic-settings>=2.14.1",
|
|
21
|
+
"qdrant-client>=1.12.0",
|
|
22
|
+
"pyyaml>=6.0.3",
|
|
23
|
+
"redis>=7.4.0",
|
|
24
|
+
"structlog>=25.5.0",
|
|
25
|
+
"tenacity>=9.1.4",
|
|
26
|
+
"uvicorn>=0.48.0",
|
|
27
|
+
"protovalidate>=2.0.0,<3",
|
|
28
|
+
]
|
|
29
|
+
classifiers = [
|
|
30
|
+
"Operating System :: MacOS",
|
|
31
|
+
"Operating System :: Microsoft :: Windows",
|
|
32
|
+
"Operating System :: POSIX :: Linux",
|
|
33
|
+
"Programming Language :: Python",
|
|
34
|
+
"Programming Language :: Python :: 3.12",
|
|
35
|
+
]
|
|
36
|
+
|
|
37
|
+
[[project.authors]]
|
|
38
|
+
name = "Tech AI at Georgia Institute of Technology"
|
|
39
|
+
|
|
40
|
+
[project.optional-dependencies]
|
|
41
|
+
ray = ["ray==2.56.1"]
|
|
42
|
+
postgres = ["asyncpg>=0.30.0"]
|
|
43
|
+
parsing = [
|
|
44
|
+
"markitdown[docx,pdf,pptx,xls,xlsx]>=0.1.6",
|
|
45
|
+
"pymupdf>=1.28.0",
|
|
46
|
+
]
|
|
47
|
+
langdetect = ["langdetect>=1.0.9"]
|
|
48
|
+
|
|
49
|
+
[project.license]
|
|
50
|
+
text = "MIT"
|
|
51
|
+
|
|
52
|
+
[project.urls]
|
|
53
|
+
Homepage = "https://github.com/gt-tech-ai/knowledge-engine-toolkit"
|
|
54
|
+
Documentation = "https://github.com/gt-tech-ai/knowledge-engine-toolkit"
|
|
55
|
+
Repository = "https://github.com/gt-tech-ai/knowledge-engine-toolkit"
|
|
56
|
+
|
|
57
|
+
[build-system]
|
|
58
|
+
requires = ["uv_build>=0.11.15,<0.12.0"]
|
|
59
|
+
build-backend = "uv_build"
|
|
60
|
+
|
|
61
|
+
[dependency-groups]
|
|
62
|
+
dev = [
|
|
63
|
+
"autogitsemver>=0.9.13",
|
|
64
|
+
"pytest>=9.0.3",
|
|
65
|
+
"pytest-asyncio>=1.0.0",
|
|
66
|
+
"pytest-cov>=7.1.0",
|
|
67
|
+
"ray==2.56.1",
|
|
68
|
+
"ruff==0.16.9",
|
|
69
|
+
"basedpyright==1.40.1",
|
|
70
|
+
"asyncpg>=0.30.0",
|
|
71
|
+
"markitdown[docx,pdf,pptx,xls,xlsx]>=0.1.6",
|
|
72
|
+
"pymupdf>=1.28.0",
|
|
73
|
+
"langdetect>=1.0.9",
|
|
74
|
+
"testcontainers[postgres,redis]>=4.14.2",
|
|
75
|
+
"ty>=0.0.38",
|
|
76
|
+
"hypothesis>=6.168.5",
|
|
77
|
+
"asyncpg-stubs==0.31.3",
|
|
78
|
+
"types-aiobotocore-lite[s3,sesv2,sqs]==3.9.0",
|
|
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 = 90
|
|
114
|
+
preview = true
|
|
115
|
+
|
|
116
|
+
[tool.ruff.lint]
|
|
117
|
+
select = ["ALL"]
|
|
118
|
+
ignore = [
|
|
119
|
+
"missing-type-args",
|
|
120
|
+
"missing-type-kwargs",
|
|
121
|
+
"blind-except",
|
|
122
|
+
"missing-trailing-comma",
|
|
123
|
+
"missing-copyright-notice",
|
|
124
|
+
"undocumented-magic-method",
|
|
125
|
+
"undocumented-public-init",
|
|
126
|
+
"blank-line-after-function",
|
|
127
|
+
"incorrect-blank-line-before-class",
|
|
128
|
+
"multi-line-summary-second-line",
|
|
129
|
+
"DOC",
|
|
130
|
+
"line-too-long",
|
|
131
|
+
"line-contains-todo",
|
|
132
|
+
"FURB",
|
|
133
|
+
"invalid-function-name",
|
|
134
|
+
"invalid-module-name",
|
|
135
|
+
"pytest-fixture-autouse",
|
|
136
|
+
"unnecessary-paren-on-raise-exception",
|
|
137
|
+
"noqa-comments",
|
|
138
|
+
"runtime-cast-value",
|
|
139
|
+
"missing-todo-author",
|
|
140
|
+
"missing-todo-link",
|
|
141
|
+
"raise-vanilla-class",
|
|
142
|
+
"try-consider-else",
|
|
143
|
+
"f-string",
|
|
144
|
+
]
|
|
145
|
+
|
|
146
|
+
[tool.ruff.lint.isort]
|
|
147
|
+
known-first-party = ["techai_webutils"]
|
|
148
|
+
|
|
149
|
+
[tool.ruff.lint.per-file-ignores]
|
|
150
|
+
"src/techai_webutils/clients/llm/bedrock/*.py" = ["invalid-argument-name"]
|
|
151
|
+
"src/techai_webutils/clients/retrieval/bedrock/*.py" = ["invalid-argument-name"]
|
|
152
|
+
"src/techai_webutils/clients/kb_ingestion/bedrock/*.py" = ["invalid-argument-name"]
|
|
153
|
+
"**/tests/**" = [
|
|
154
|
+
"S",
|
|
155
|
+
"magic-value-comparison",
|
|
156
|
+
"missing-type-function-argument",
|
|
157
|
+
"no-self-use",
|
|
158
|
+
"implicit-namespace-package",
|
|
159
|
+
"import-outside-top-level",
|
|
160
|
+
]
|
|
161
|
+
|
|
162
|
+
[tool.ruff.lint.mccabe]
|
|
163
|
+
max-complexity = 15
|
|
164
|
+
|
|
165
|
+
[tool.ruff.lint.pylint]
|
|
166
|
+
max-args = 10
|
|
167
|
+
max-branches = 20
|
|
168
|
+
max-returns = 20
|
|
169
|
+
|
|
170
|
+
[tool.pyright]
|
|
171
|
+
pythonVersion = "3.12"
|
|
172
|
+
typeCheckingMode = "strict"
|
|
173
|
+
include = [
|
|
174
|
+
"src/techai_webutils",
|
|
175
|
+
"tests",
|
|
176
|
+
]
|
|
177
|
+
|
|
178
|
+
[[tool.pyright.executionEnvironments]]
|
|
179
|
+
root = "tests"
|
|
180
|
+
reportUnknownMemberType = "none"
|
|
181
|
+
reportUnknownArgumentType = "none"
|
|
182
|
+
reportUnknownVariableType = "none"
|
|
183
|
+
reportUnknownParameterType = "none"
|
|
184
|
+
reportUnknownLambdaType = "none"
|
|
185
|
+
reportAttributeAccessIssue = "none"
|
|
186
|
+
|
|
187
|
+
[tool.uv.build-backend]
|
|
188
|
+
module-name = "techai_webutils"
|
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "techai-webutils"
|
|
3
|
+
version = "0.0.1"
|
|
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 = "README.md"
|
|
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
|
+
# new_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 a deployable that runs distributed batches 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 `ExecutorConfig.kind` is `ray`.
|
|
54
|
+
#
|
|
55
|
+
# ⚠ Ray requires the driver and the cluster to run the SAME version. Pinned EXACTLY to match the
|
|
56
|
+
# Ray testcontainer in the integration tests (rayproject/ray:2.56.1-py312) — `ray://` rejects a
|
|
57
|
+
# version mismatch, so a consumer's Ray cluster image must match this pin too. Bump this pin and the
|
|
58
|
+
# dev-group `ray` pin below together when upgrading Ray.
|
|
59
|
+
ray = ["ray==2.56.1"]
|
|
60
|
+
|
|
61
|
+
# Cross-pod single-writer lock backend (PostgresAdvisoryLock). Optional: only a deployable
|
|
62
|
+
# that needs the cross-pod lock installs `techai-webutils[postgres]`. The default in-memory lock
|
|
63
|
+
# never pulls asyncpg — the `postgres` backend impl is imported lazily by `new_lock_from_config`
|
|
64
|
+
# when `LockConfig.kind` is `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 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
|
+
# deployable that extracts document metadata 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-toolkit"
|
|
84
|
+
Documentation = "https://github.com/gt-tech-ai/knowledge-engine-toolkit"
|
|
85
|
+
Repository = "https://github.com/gt-tech-ai/knowledge-engine-toolkit"
|
|
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 so the ray:// driver matches the cluster (see the extra above).
|
|
101
|
+
"ray==2.56.1",
|
|
102
|
+
"ruff==0.16.9",
|
|
103
|
+
"basedpyright==1.40.1",
|
|
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
|
+
# hypothesis drives the property tests (e.g. the token-ledger Decimal cost arithmetic).
|
|
118
|
+
"hypothesis>=6.168.5",
|
|
119
|
+
"asyncpg-stubs==0.31.3",
|
|
120
|
+
"types-aiobotocore-lite[s3,sesv2,sqs]==3.9.0",
|
|
121
|
+
]
|
|
122
|
+
|
|
123
|
+
[tool.pytest.ini_options]
|
|
124
|
+
# tests/ is put on sys.path by pytest's default prepend import mode (there is no
|
|
125
|
+
# tests/__init__.py). Test doubles are built inline with unittest.mock in each
|
|
126
|
+
# test (spec-bound to the real core interfaces), so no shared test-double package
|
|
127
|
+
# and no pythonpath directive are needed.
|
|
128
|
+
# Hand-written unit coverage is gated at >=90%. The denominator excludes the
|
|
129
|
+
# integration-only external wrappers (gRPC server factory + OTel tracing
|
|
130
|
+
# interceptors, SQS/S3/Redis clients, OTel tracer/observability): they are carved
|
|
131
|
+
# out below (covered by the integration suite, the Python equivalent of Go's
|
|
132
|
+
# unit-only carve-outs); the genuinely unit-testable interceptor logic is tested
|
|
133
|
+
# instead of excluded.
|
|
134
|
+
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"
|
|
135
|
+
# Registered markers (enforced by --strict-markers, so a typo'd/unregistered marker
|
|
136
|
+
# now errors instead of silently passing). `integration` tests need a Docker daemon
|
|
137
|
+
# (testcontainers) and are deselected from the default unit run via `-m "not integration"`.
|
|
138
|
+
markers = [
|
|
139
|
+
"integration: real-dependency tests via testcontainers (Docker required); deselected in the unit run",
|
|
140
|
+
"slow: slow tests, deselected with --fast",
|
|
141
|
+
]
|
|
142
|
+
|
|
143
|
+
[tool.coverage.run]
|
|
144
|
+
# relative_files + a distinct (non-hidden) data file let an optional combined
|
|
145
|
+
# coverage gate merge this unit dataset with an integration dataset (see
|
|
146
|
+
# .coveragerc.combined). The unit run writes coverage_unit.dat; an integration run
|
|
147
|
+
# can write coverage_integration.dat, and `coverage combine` +
|
|
148
|
+
# `coverage report --rcfile .coveragerc.combined` merges them. No CI job runs that
|
|
149
|
+
# combined gate — it is a local check.
|
|
150
|
+
relative_files = true
|
|
151
|
+
data_file = "coverage_unit.dat"
|
|
152
|
+
|
|
153
|
+
[tool.coverage.report]
|
|
154
|
+
# Excluded from the UNIT denominator (>=90% gate is over hand-written, unit-testable
|
|
155
|
+
# logic). Each entry is either test infrastructure or a thin external-dependency
|
|
156
|
+
# wrapper whose uncovered lines are the real network/SDK calls — exercised by the
|
|
157
|
+
# integration suite, not unit tests. Mirrors Go's unit-only carve-out set.
|
|
158
|
+
#
|
|
159
|
+
# This omit is at REPORT time (not [run]) so the unit run still MEASURES the
|
|
160
|
+
# wrappers — their partial unit coverage then lands in coverage_unit.dat and can
|
|
161
|
+
# merge into the optional combined gate (.coveragerc.combined), which counts them.
|
|
162
|
+
omit = [
|
|
163
|
+
"*/clients/transport/grpc/server.py", # gRPC server factory (binds/serves) — integration
|
|
164
|
+
"*/clients/rpc/grpc/interceptors/tracing.py", # OTel client span wiring — integration/runtime
|
|
165
|
+
"*/clients/rpc/grpc/interceptors/tracing_server.py", # OTel server span wiring — integration/runtime
|
|
166
|
+
"*/clients/messaging/sqs/sqs_publisher.py", # boto3 SQS send — integration (ElasticMQ)
|
|
167
|
+
"*/clients/messaging/sqs/sqs_subscriber.py", # boto3 SQS receive loop — integration (ElasticMQ)
|
|
168
|
+
"*/foundation/resilience/sqs_dlq.py", # boto3 SQS DLQ send — integration (ElasticMQ)
|
|
169
|
+
"*/clients/storage/s3/s3_client.py", # boto3 S3 client — integration (MinIO)
|
|
170
|
+
"*/clients/llm/bedrock/*.py", # aiobotocore bedrock-runtime wrapper — integration/runtime
|
|
171
|
+
"*/clients/retrieval/bedrock/*.py", # aiobotocore bedrock-agent-runtime wrapper — integration/runtime
|
|
172
|
+
"*/clients/kb_ingestion/bedrock/*.py", # aiobotocore bedrock-agent KB ingestion — integration/runtime
|
|
173
|
+
"*/clients/email/ses/provider.py", # aiobotocore SESv2 send — E2E only (staging/prod SES)
|
|
174
|
+
"*/clients/email/smtp/provider.py", # aiosmtplib SMTP send — E2E only (dev Mailpit)
|
|
175
|
+
"*/clients/cache/redis/cache.py", # aioredis wrapper — integration (Redis)
|
|
176
|
+
"*/foundation/tracer/tracer.py", # OTel tracer SDK init — integration/runtime
|
|
177
|
+
"*/foundation/observability.py", # OTel observability bootstrap — integration/runtime
|
|
178
|
+
"*/execution/executor/real_ray_runtime.py", # ray.init + @ray.remote wrapper — integration (real Ray)
|
|
179
|
+
]
|
|
180
|
+
|
|
181
|
+
[tool.ruff]
|
|
182
|
+
line-length = 90
|
|
183
|
+
|
|
184
|
+
# preview = true enables ruff's preview rules for BOTH `ruff check` and
|
|
185
|
+
# `ruff format` (it is a top-level key, not scoped to [lint]).
|
|
186
|
+
preview = true
|
|
187
|
+
|
|
188
|
+
[tool.ruff.lint]
|
|
189
|
+
select = ["ALL"]
|
|
190
|
+
|
|
191
|
+
ignore = [
|
|
192
|
+
"missing-type-args", # Missing type annotation for `*args`
|
|
193
|
+
"missing-type-kwargs", # Missing type annotation for `**kwargs`
|
|
194
|
+
"blind-except", # Do not catch blind exception: `Exception`
|
|
195
|
+
"missing-trailing-comma", # Trailing comma missing
|
|
196
|
+
"missing-copyright-notice", # flake8-copyright: repo does not use file copyright headers
|
|
197
|
+
"undocumented-magic-method", # Missing docstring in magic method
|
|
198
|
+
"undocumented-public-init", # Missing docstring in `__init__` method
|
|
199
|
+
"blank-line-after-function", # No blank lines allowed after function docstring
|
|
200
|
+
"incorrect-blank-line-before-class", # 1 blank line before class docstring (conflicts with D211; ruff keeps D211)
|
|
201
|
+
"multi-line-summary-second-line", # Multi-line summary on second line (conflicts with D212; ruff keeps D212)
|
|
202
|
+
"DOC", # pydoclint family (preview): listed as "Consider", not adopted
|
|
203
|
+
"line-too-long", # Line too long
|
|
204
|
+
"line-contains-todo", # Line contains TODO, consider resolving the issue
|
|
205
|
+
"FURB", # refurb family (preview): listed as "Consider", not adopted
|
|
206
|
+
"invalid-function-name", # Function name `xxx` should be lowercase
|
|
207
|
+
"invalid-module-name", # Invalid module name
|
|
208
|
+
"pytest-fixture-autouse", # flake8-pytest-style (preview, no assigned rule code so it cannot be suppressed per-line via `# noqa`): autouse is a deliberate cross-cutting test pattern here — per-test env isolation and the integration-suite Docker gate — so this opinionated preview rule is deferred like DOC/FURB.
|
|
209
|
+
"unnecessary-paren-on-raise-exception", # Unnecessary parentheses on raise exception
|
|
210
|
+
"noqa-comments", # noqa-comments (preview): opinionated/stylistic rule preferring `# ruff: ignore[...]` over `# noqa`; ruff itself sanctions disabling it. We keep the universal, tool-agnostic `# noqa: <CODE>` form.
|
|
211
|
+
"runtime-cast-value", # Add quotes to type expression in `typing.cast()`
|
|
212
|
+
"missing-todo-author", # Missing author in TODO
|
|
213
|
+
"missing-todo-link", # Missing issue link for this TODO
|
|
214
|
+
"raise-vanilla-class", # Create your own exception
|
|
215
|
+
"try-consider-else", # Consider moving this statement to an `else` block
|
|
216
|
+
"f-string", # Use f-string instead of `format` call
|
|
217
|
+
]
|
|
218
|
+
|
|
219
|
+
[tool.ruff.lint.isort]
|
|
220
|
+
known-first-party = ["techai_webutils"]
|
|
221
|
+
|
|
222
|
+
[tool.ruff.lint.per-file-ignores]
|
|
223
|
+
# The bedrock clients mirror the AWS bedrock-runtime / bedrock-agent-runtime / bedrock-agent APIs, whose
|
|
224
|
+
# keyword params are camelCase (knowledgeBaseId, modelId, retrievalQuery, dataSourceId, …) — N803 does
|
|
225
|
+
# not apply to a wire mirror.
|
|
226
|
+
"src/techai_webutils/clients/llm/bedrock/*.py" = ["invalid-argument-name"]
|
|
227
|
+
"src/techai_webutils/clients/retrieval/bedrock/*.py" = ["invalid-argument-name"]
|
|
228
|
+
"src/techai_webutils/clients/kb_ingestion/bedrock/*.py" = ["invalid-argument-name"]
|
|
229
|
+
# Each entry is a rule wrong-by-design for the whole test tree.
|
|
230
|
+
"**/tests/**" = [
|
|
231
|
+
"S", # flake8-bandit: bandit is the dedicated security gate and excludes tests; fixtures use fake credentials and intentionally exercise flagged patterns (assert, e2e subprocess, bind-all in local config)
|
|
232
|
+
"magic-value-comparison", # magic-value comparisons are expected in test assertions
|
|
233
|
+
"missing-type-function-argument", # test fixtures/params need no redundant annotations (types still resolve under basedpyright)
|
|
234
|
+
"no-self-use", # pytest groups tests as methods on a class; `self` is required by the collector even when unused
|
|
235
|
+
"implicit-namespace-package", # test trees are flat implicit-namespace packages (no __init__.py), collected by pytest
|
|
236
|
+
"import-outside-top-level", # tests import the concrete implementation under test locally to keep each case's deps explicit
|
|
237
|
+
]
|
|
238
|
+
|
|
239
|
+
[tool.ruff.lint.mccabe]
|
|
240
|
+
max-complexity = 15
|
|
241
|
+
|
|
242
|
+
[tool.ruff.lint.pylint]
|
|
243
|
+
max-args = 10
|
|
244
|
+
max-branches = 20
|
|
245
|
+
max-returns = 20
|
|
246
|
+
|
|
247
|
+
# Strict type-checking over src and tests. include is an allowlist, so tests are analyzed
|
|
248
|
+
# only because they are listed here.
|
|
249
|
+
[tool.pyright]
|
|
250
|
+
pythonVersion = "3.12"
|
|
251
|
+
typeCheckingMode = "strict"
|
|
252
|
+
include = ["src/techai_webutils", "tests"]
|
|
253
|
+
|
|
254
|
+
# Mock-noise relaxation for the test tree: pytest fixtures and unittest.mock doubles are
|
|
255
|
+
# intentionally untyped, so the reportUnknown* family and the mock attribute-access probes
|
|
256
|
+
# (.assert_called_once / .await_args_list, which resolve on an autospec'd MethodType, not on
|
|
257
|
+
# the Mock) are pure noise there. src/ stays fully strict, and every other strict diagnostic
|
|
258
|
+
# (argument types, optional access, private usage) is still enforced in tests.
|
|
259
|
+
[[tool.pyright.executionEnvironments]]
|
|
260
|
+
root = "tests"
|
|
261
|
+
reportUnknownMemberType = "none"
|
|
262
|
+
reportUnknownArgumentType = "none"
|
|
263
|
+
reportUnknownVariableType = "none"
|
|
264
|
+
reportUnknownParameterType = "none"
|
|
265
|
+
reportUnknownLambdaType = "none"
|
|
266
|
+
reportAttributeAccessIssue = "none"
|
|
267
|
+
|
|
268
|
+
[tool.uv.build-backend]
|
|
269
|
+
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 tier (ARCHITECTURE.md#layers-and-import-direction):
|
|
7
|
+
core -> foundation -> clients -> repos -> services -> pipelines -> workflows -> controllers
|
|
8
|
+
"""
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"""AI audit records: a config-selected ``AuditSink`` (``stub`` built in; durable sinks injected)."""
|
|
2
|
+
|
|
3
|
+
from techai_webutils.clients.audit.builder import (
|
|
4
|
+
AuditSinkConfig,
|
|
5
|
+
AuditSinkKind,
|
|
6
|
+
new_audit_sink_from_config,
|
|
7
|
+
)
|
|
8
|
+
|
|
9
|
+
__all__ = ["AuditSinkConfig", "AuditSinkKind", "new_audit_sink_from_config"]
|