trustgraph-base 2.8.0__tar.gz → 2.8.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.
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/PKG-INFO +2 -1
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/pyproject.toml +1 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/base/async_config_client.py +2 -1
- trustgraph_base-2.8.1/trustgraph/base/async_kafka_backend.py +304 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/base/async_processor.py +14 -2
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/base/audit_publisher.py +17 -1
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/base/config_client.py +12 -9
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/base/pubsub.py +22 -3
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/base/request_response_client.py +12 -4
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/base/request_response_spec.py +7 -1
- trustgraph_base-2.8.1/trustgraph/base_version.py +1 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph_base.egg-info/PKG-INFO +2 -1
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph_base.egg-info/SOURCES.txt +1 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph_base.egg-info/requires.txt +1 -0
- trustgraph_base-2.8.0/trustgraph/base_version.py +0 -1
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/README.md +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/setup.cfg +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/api/__init__.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/api/api.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/api/async_bulk_client.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/api/async_flow.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/api/async_metrics.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/api/async_socket_client.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/api/bulk_client.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/api/collection.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/api/config.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/api/exceptions.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/api/explainability.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/api/flow.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/api/knowledge.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/api/library.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/api/metrics.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/api/socket_client.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/api/types.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/base/__init__.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/base/agent_client.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/base/agent_service.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/base/async_backend.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/base/async_librarian_client.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/base/async_pulsar_backend.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/base/async_rabbitmq_backend.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/base/async_rr_wrapper.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/base/backend.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/base/cassandra_config.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/base/chunking_service.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/base/collection_config_handler.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/base/consumer.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/base/consumer_spec.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/base/document_embeddings_client.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/base/document_embeddings_query_service.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/base/document_embeddings_store_service.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/base/dynamic_tool_service.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/base/embeddings_client.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/base/embeddings_service.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/base/flow.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/base/flow_processor.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/base/graph_embeddings_client.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/base/graph_embeddings_query_service.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/base/graph_embeddings_store_service.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/base/graph_rag_client.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/base/iam_client.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/base/image_to_text_service.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/base/kafka_backend.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/base/keyword_index_client.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/base/keyword_index_service.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/base/librarian_client.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/base/librarian_spec.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/base/llm_service.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/base/logging.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/base/metrics.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/base/parameter_spec.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/base/processor_group.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/base/producer.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/base/producer_spec.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/base/prompt_client.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/base/publisher.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/base/pulsar_backend.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/base/qdrant_config.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/base/rabbitmq_backend.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/base/receiver_pool.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/base/reranker_client.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/base/reranker_service.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/base/row_embeddings_query_client.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/base/schema_compatibility.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/base/sender_pool.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/base/serialization.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/base/spec.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/base/structured_query_client.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/base/subscriber.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/base/subscriber_spec.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/base/text_completion_client.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/base/tool_client.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/base/tool_service.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/base/tool_service_client.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/base/triples_client.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/base/triples_query_service.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/base/triples_store_service.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/base/workspace_processor.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/clients/__init__.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/clients/agent_client.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/clients/base.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/clients/config_client.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/clients/document_embeddings_client.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/clients/document_rag_client.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/clients/embeddings_client.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/clients/graph_embeddings_client.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/clients/graph_rag_client.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/clients/llm_client.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/clients/prompt_client.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/clients/row_embeddings_client.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/clients/triples_query_client.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/exceptions.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/i18n/__init__.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/i18n/packs/__init__.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/i18n/packs/ar.json +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/i18n/packs/en.json +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/i18n/packs/es.json +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/i18n/packs/he.json +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/i18n/packs/hi.json +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/i18n/packs/pt.json +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/i18n/packs/ru.json +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/i18n/packs/sw.json +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/i18n/packs/tr.json +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/i18n/packs/zh-cn.json +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/knowledge/__init__.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/knowledge/defs.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/knowledge/document.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/knowledge/identifier.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/knowledge/organization.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/knowledge/publication.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/log_level.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/messaging/__init__.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/messaging/registry.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/messaging/translators/__init__.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/messaging/translators/agent.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/messaging/translators/base.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/messaging/translators/collection.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/messaging/translators/config.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/messaging/translators/diagnosis.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/messaging/translators/document_loading.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/messaging/translators/embeddings.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/messaging/translators/embeddings_query.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/messaging/translators/flow.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/messaging/translators/iam.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/messaging/translators/image_to_text.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/messaging/translators/knowledge.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/messaging/translators/library.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/messaging/translators/metadata.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/messaging/translators/nlp_query.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/messaging/translators/primitives.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/messaging/translators/prompt.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/messaging/translators/reranker.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/messaging/translators/retrieval.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/messaging/translators/rows_query.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/messaging/translators/sparql_query.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/messaging/translators/structured_query.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/messaging/translators/text_completion.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/messaging/translators/tool.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/messaging/translators/triples.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/objects/__init__.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/objects/field.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/objects/object.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/provenance/__init__.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/provenance/agent.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/provenance/namespaces.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/provenance/triples.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/provenance/uris.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/provenance/vocabulary.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/rdf.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/schema/__init__.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/schema/core/__init__.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/schema/core/metadata.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/schema/core/primitives.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/schema/core/topic.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/schema/knowledge/__init__.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/schema/knowledge/document.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/schema/knowledge/embeddings.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/schema/knowledge/graph.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/schema/knowledge/knowledge.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/schema/knowledge/nlp.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/schema/knowledge/object.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/schema/knowledge/rows.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/schema/knowledge/structured.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/schema/services/__init__.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/schema/services/agent.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/schema/services/audit.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/schema/services/collection.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/schema/services/config.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/schema/services/diagnosis.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/schema/services/flow.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/schema/services/iam.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/schema/services/image_to_text.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/schema/services/library.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/schema/services/llm.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/schema/services/lookup.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/schema/services/nlp_query.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/schema/services/prompt.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/schema/services/query.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/schema/services/reranker.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/schema/services/retrieval.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/schema/services/rows_query.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/schema/services/sparql_query.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/schema/services/storage.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/schema/services/structured_query.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph/schema/services/tool_service.py +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph_base.egg-info/dependency_links.txt +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph_base.egg-info/entry_points.txt +0 -0
- {trustgraph_base-2.8.0 → trustgraph_base-2.8.1}/trustgraph_base.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: trustgraph-base
|
|
3
|
-
Version: 2.8.
|
|
3
|
+
Version: 2.8.1
|
|
4
4
|
Summary: TrustGraph provides a means to run a pipeline of flexible AI processing components in a flexible means to achieve a processing pipeline.
|
|
5
5
|
Author-email: "trustgraph.ai" <security@trustgraph.ai>
|
|
6
6
|
Project-URL: Homepage, https://github.com/trustgraph-ai/trustgraph
|
|
@@ -15,6 +15,7 @@ Requires-Dist: python-logging-loki
|
|
|
15
15
|
Requires-Dist: pika
|
|
16
16
|
Requires-Dist: aio-pika
|
|
17
17
|
Requires-Dist: confluent-kafka
|
|
18
|
+
Requires-Dist: aiokafka
|
|
18
19
|
Requires-Dist: pyyaml
|
|
19
20
|
Requires-Dist: websockets
|
|
20
21
|
|
|
@@ -12,7 +12,7 @@ class AsyncConfigClient:
|
|
|
12
12
|
|
|
13
13
|
@classmethod
|
|
14
14
|
async def create(cls, backend, request_topic, response_topic,
|
|
15
|
-
subscription=None):
|
|
15
|
+
subscription=None, timeout=CONFIG_TIMEOUT):
|
|
16
16
|
client = await RequestResponseClient.create(
|
|
17
17
|
backend=backend,
|
|
18
18
|
request_topic=request_topic,
|
|
@@ -20,6 +20,7 @@ class AsyncConfigClient:
|
|
|
20
20
|
request_schema=ConfigRequest,
|
|
21
21
|
response_schema=ConfigResponse,
|
|
22
22
|
subscription=subscription,
|
|
23
|
+
default_timeout=timeout,
|
|
23
24
|
)
|
|
24
25
|
return cls(client)
|
|
25
26
|
|
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Async Kafka backend implementation.
|
|
3
|
+
|
|
4
|
+
Uses aiokafka for fully async Kafka operations. Each logical topic
|
|
5
|
+
maps to a Kafka topic, matching the sync Kafka backend's topology:
|
|
6
|
+
|
|
7
|
+
class:topicspace:topic → topicspace.class.topic
|
|
8
|
+
|
|
9
|
+
Producers publish to the topic directly.
|
|
10
|
+
Consumers use consumer groups for competing-consumer semantics:
|
|
11
|
+
|
|
12
|
+
- flow / request: named consumer group (competing consumers)
|
|
13
|
+
- response / notify: unique consumer group per instance, filtering
|
|
14
|
+
messages by correlation ID (all subscribers see all messages)
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
import asyncio
|
|
18
|
+
import json
|
|
19
|
+
import logging
|
|
20
|
+
import uuid
|
|
21
|
+
from typing import Any
|
|
22
|
+
|
|
23
|
+
from aiokafka import AIOKafkaProducer, AIOKafkaConsumer
|
|
24
|
+
from aiokafka.admin import AIOKafkaAdminClient, NewTopic
|
|
25
|
+
from aiokafka.errors import TopicAlreadyExistsError, UnknownTopicOrPartitionError
|
|
26
|
+
|
|
27
|
+
from .async_backend import AsyncPubSubBackend, AsyncBackendProducer
|
|
28
|
+
from .async_backend import AsyncBackendConsumer, Message
|
|
29
|
+
from .serialization import dataclass_to_dict, dict_to_dataclass
|
|
30
|
+
|
|
31
|
+
logger = logging.getLogger(__name__)
|
|
32
|
+
|
|
33
|
+
LONG_RETENTION_MS = 7 * 24 * 60 * 60 * 1000 # 7 days
|
|
34
|
+
SHORT_RETENTION_MS = 300 * 1000 # 5 minutes
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class AsyncKafkaMessage:
|
|
38
|
+
"""Wrapper for aiokafka messages to match Message protocol."""
|
|
39
|
+
|
|
40
|
+
def __init__(self, msg, schema_cls):
|
|
41
|
+
self._msg = msg
|
|
42
|
+
self._schema_cls = schema_cls
|
|
43
|
+
self._value = None
|
|
44
|
+
|
|
45
|
+
def value(self) -> Any:
|
|
46
|
+
if self._value is None:
|
|
47
|
+
data_dict = json.loads(self._msg.value.decode('utf-8'))
|
|
48
|
+
self._value = dict_to_dataclass(data_dict, self._schema_cls)
|
|
49
|
+
return self._value
|
|
50
|
+
|
|
51
|
+
def properties(self) -> dict:
|
|
52
|
+
headers = self._msg.headers or []
|
|
53
|
+
return {
|
|
54
|
+
k: v.decode('utf-8') if isinstance(v, bytes) else v
|
|
55
|
+
for k, v in headers
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
class AsyncKafkaProducer:
|
|
60
|
+
"""Async Kafka producer using aiokafka."""
|
|
61
|
+
|
|
62
|
+
def __init__(self, producer, topic_name):
|
|
63
|
+
self._producer = producer
|
|
64
|
+
self._topic_name = topic_name
|
|
65
|
+
|
|
66
|
+
async def send(self, message: Any, properties: dict = {}) -> None:
|
|
67
|
+
data_dict = dataclass_to_dict(message)
|
|
68
|
+
json_data = json.dumps(data_dict).encode('utf-8')
|
|
69
|
+
|
|
70
|
+
headers = [
|
|
71
|
+
(k, str(v).encode('utf-8'))
|
|
72
|
+
for k, v in properties.items()
|
|
73
|
+
] if properties else None
|
|
74
|
+
|
|
75
|
+
await self._producer.send_and_wait(
|
|
76
|
+
self._topic_name,
|
|
77
|
+
value=json_data,
|
|
78
|
+
headers=headers,
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
async def close(self) -> None:
|
|
82
|
+
try:
|
|
83
|
+
await self._producer.stop()
|
|
84
|
+
except BaseException:
|
|
85
|
+
pass
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
class AsyncKafkaConsumer:
|
|
89
|
+
"""Async Kafka consumer using aiokafka."""
|
|
90
|
+
|
|
91
|
+
def __init__(self, consumer, schema_cls):
|
|
92
|
+
self._consumer = consumer
|
|
93
|
+
self._schema_cls = schema_cls
|
|
94
|
+
|
|
95
|
+
async def receive(self) -> Message:
|
|
96
|
+
msg = await self._consumer.__anext__()
|
|
97
|
+
return AsyncKafkaMessage(msg, self._schema_cls)
|
|
98
|
+
|
|
99
|
+
async def acknowledge(self, message: Message) -> None:
|
|
100
|
+
if isinstance(message, AsyncKafkaMessage):
|
|
101
|
+
await self._consumer.commit()
|
|
102
|
+
|
|
103
|
+
async def negative_acknowledge(self, message: Message) -> None:
|
|
104
|
+
pass
|
|
105
|
+
|
|
106
|
+
async def close(self) -> None:
|
|
107
|
+
try:
|
|
108
|
+
await self._consumer.stop()
|
|
109
|
+
except BaseException:
|
|
110
|
+
pass
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
class AsyncKafkaBackend:
|
|
114
|
+
"""Async Kafka pub/sub backend using aiokafka.
|
|
115
|
+
|
|
116
|
+
Fully async — zero OS threads for receiving, sending, and
|
|
117
|
+
consumer/producer lifecycle.
|
|
118
|
+
"""
|
|
119
|
+
|
|
120
|
+
def __init__(
|
|
121
|
+
self, bootstrap_servers='localhost:9092',
|
|
122
|
+
security_protocol='PLAINTEXT',
|
|
123
|
+
sasl_mechanism=None,
|
|
124
|
+
sasl_username=None,
|
|
125
|
+
sasl_password=None,
|
|
126
|
+
):
|
|
127
|
+
self._bootstrap_servers = bootstrap_servers
|
|
128
|
+
self._security_protocol = security_protocol
|
|
129
|
+
self._sasl_mechanism = sasl_mechanism
|
|
130
|
+
self._sasl_username = sasl_username
|
|
131
|
+
self._sasl_password = sasl_password
|
|
132
|
+
|
|
133
|
+
self.max_consumer_concurrency = 1
|
|
134
|
+
|
|
135
|
+
logger.info(
|
|
136
|
+
f"Async Kafka backend: {bootstrap_servers} "
|
|
137
|
+
f"protocol={security_protocol}"
|
|
138
|
+
)
|
|
139
|
+
|
|
140
|
+
def _client_kwargs(self):
|
|
141
|
+
kwargs = {
|
|
142
|
+
'bootstrap_servers': self._bootstrap_servers,
|
|
143
|
+
'security_protocol': self._security_protocol,
|
|
144
|
+
}
|
|
145
|
+
if self._sasl_mechanism:
|
|
146
|
+
kwargs['sasl_mechanism'] = self._sasl_mechanism
|
|
147
|
+
if self._sasl_username:
|
|
148
|
+
kwargs['sasl_plain_username'] = self._sasl_username
|
|
149
|
+
if self._sasl_password:
|
|
150
|
+
kwargs['sasl_plain_password'] = self._sasl_password
|
|
151
|
+
return kwargs
|
|
152
|
+
|
|
153
|
+
def _parse_topic(self, topic_id: str) -> tuple[str, str, bool]:
|
|
154
|
+
"""Parse topic identifier into Kafka topic name, class, durability.
|
|
155
|
+
|
|
156
|
+
Format: class:topicspace:topic
|
|
157
|
+
Returns: (topic_name, class, durable)
|
|
158
|
+
"""
|
|
159
|
+
if ':' not in topic_id:
|
|
160
|
+
return f'tg.flow.{topic_id}', 'flow', True
|
|
161
|
+
|
|
162
|
+
parts = topic_id.split(':', 2)
|
|
163
|
+
if len(parts) != 3:
|
|
164
|
+
raise ValueError(
|
|
165
|
+
f"Invalid topic format: {topic_id}, "
|
|
166
|
+
f"expected class:topicspace:topic"
|
|
167
|
+
)
|
|
168
|
+
|
|
169
|
+
cls, topicspace, topic = parts
|
|
170
|
+
|
|
171
|
+
if cls == 'flow':
|
|
172
|
+
durable = True
|
|
173
|
+
elif cls in ('request', 'response', 'notify'):
|
|
174
|
+
durable = False
|
|
175
|
+
else:
|
|
176
|
+
raise ValueError(
|
|
177
|
+
f"Invalid topic class: {cls}, "
|
|
178
|
+
f"expected flow, request, response, or notify"
|
|
179
|
+
)
|
|
180
|
+
|
|
181
|
+
topic_name = f"{topicspace}.{cls}.{topic}".replace(':', '.')
|
|
182
|
+
|
|
183
|
+
return topic_name, cls, durable
|
|
184
|
+
|
|
185
|
+
def _retention_ms(self, cls):
|
|
186
|
+
if cls == 'flow':
|
|
187
|
+
return LONG_RETENTION_MS
|
|
188
|
+
return SHORT_RETENTION_MS
|
|
189
|
+
|
|
190
|
+
async def create_producer(
|
|
191
|
+
self, topic: str, schema: type, **options,
|
|
192
|
+
) -> AsyncBackendProducer:
|
|
193
|
+
topic_name, cls, durable = self._parse_topic(topic)
|
|
194
|
+
|
|
195
|
+
producer = AIOKafkaProducer(
|
|
196
|
+
**self._client_kwargs(),
|
|
197
|
+
acks='all' if durable else 1,
|
|
198
|
+
max_request_size=10485760,
|
|
199
|
+
)
|
|
200
|
+
await producer.start()
|
|
201
|
+
|
|
202
|
+
logger.debug(f"Created async producer: topic={topic_name}")
|
|
203
|
+
|
|
204
|
+
return AsyncKafkaProducer(producer, topic_name)
|
|
205
|
+
|
|
206
|
+
async def create_consumer(
|
|
207
|
+
self, topic: str, subscription: str, schema: type,
|
|
208
|
+
initial_position: str = 'latest', **options,
|
|
209
|
+
) -> AsyncBackendConsumer:
|
|
210
|
+
topic_name, cls, durable = self._parse_topic(topic)
|
|
211
|
+
|
|
212
|
+
if cls in ('response', 'notify'):
|
|
213
|
+
group_id = f"{subscription}-{uuid.uuid4()}"
|
|
214
|
+
auto_offset_reset = 'earliest'
|
|
215
|
+
else:
|
|
216
|
+
group_id = subscription
|
|
217
|
+
auto_offset_reset = (
|
|
218
|
+
'earliest' if initial_position == 'earliest'
|
|
219
|
+
else 'latest'
|
|
220
|
+
)
|
|
221
|
+
|
|
222
|
+
consumer = AIOKafkaConsumer(
|
|
223
|
+
topic_name,
|
|
224
|
+
**self._client_kwargs(),
|
|
225
|
+
group_id=group_id,
|
|
226
|
+
auto_offset_reset=auto_offset_reset,
|
|
227
|
+
enable_auto_commit=False,
|
|
228
|
+
max_partition_fetch_bytes=10485760,
|
|
229
|
+
session_timeout_ms=6000,
|
|
230
|
+
heartbeat_interval_ms=1000,
|
|
231
|
+
)
|
|
232
|
+
await consumer.start()
|
|
233
|
+
|
|
234
|
+
logger.debug(
|
|
235
|
+
f"Created async consumer: topic={topic_name}, "
|
|
236
|
+
f"group={group_id}, cls={cls}"
|
|
237
|
+
)
|
|
238
|
+
|
|
239
|
+
return AsyncKafkaConsumer(consumer, schema)
|
|
240
|
+
|
|
241
|
+
async def create_topic(self, topic: str) -> None:
|
|
242
|
+
topic_name, cls, durable = self._parse_topic(topic)
|
|
243
|
+
retention_ms = self._retention_ms(cls)
|
|
244
|
+
|
|
245
|
+
admin = AIOKafkaAdminClient(**self._client_kwargs())
|
|
246
|
+
try:
|
|
247
|
+
await admin.start()
|
|
248
|
+
new_topic = NewTopic(
|
|
249
|
+
topic_name,
|
|
250
|
+
num_partitions=1,
|
|
251
|
+
replication_factor=1,
|
|
252
|
+
topic_configs={
|
|
253
|
+
'retention.ms': str(retention_ms),
|
|
254
|
+
},
|
|
255
|
+
)
|
|
256
|
+
await admin.create_topics([new_topic])
|
|
257
|
+
logger.info(f"Created topic: {topic_name}")
|
|
258
|
+
except TopicAlreadyExistsError:
|
|
259
|
+
logger.debug(f"Topic already exists: {topic_name}")
|
|
260
|
+
finally:
|
|
261
|
+
await admin.close()
|
|
262
|
+
|
|
263
|
+
async def delete_topic(self, topic: str) -> None:
|
|
264
|
+
topic_name, cls, durable = self._parse_topic(topic)
|
|
265
|
+
|
|
266
|
+
admin = AIOKafkaAdminClient(**self._client_kwargs())
|
|
267
|
+
try:
|
|
268
|
+
await admin.start()
|
|
269
|
+
await admin.delete_topics([topic_name])
|
|
270
|
+
logger.info(f"Deleted topic: {topic_name}")
|
|
271
|
+
except UnknownTopicOrPartitionError:
|
|
272
|
+
logger.debug(f"Topic not found: {topic_name}")
|
|
273
|
+
except BaseException as e:
|
|
274
|
+
logger.debug(f"Topic delete for {topic_name}: {e}")
|
|
275
|
+
finally:
|
|
276
|
+
try:
|
|
277
|
+
await admin.close()
|
|
278
|
+
except BaseException:
|
|
279
|
+
pass
|
|
280
|
+
|
|
281
|
+
async def topic_exists(self, topic: str) -> bool:
|
|
282
|
+
topic_name, cls, durable = self._parse_topic(topic)
|
|
283
|
+
|
|
284
|
+
admin = AIOKafkaAdminClient(**self._client_kwargs())
|
|
285
|
+
try:
|
|
286
|
+
await admin.start()
|
|
287
|
+
metadata = await admin.describe_topics([topic_name])
|
|
288
|
+
return len(metadata) > 0
|
|
289
|
+
except UnknownTopicOrPartitionError:
|
|
290
|
+
return False
|
|
291
|
+
except BaseException:
|
|
292
|
+
return False
|
|
293
|
+
finally:
|
|
294
|
+
try:
|
|
295
|
+
await admin.close()
|
|
296
|
+
except BaseException:
|
|
297
|
+
pass
|
|
298
|
+
|
|
299
|
+
async def ensure_topic(self, topic: str) -> None:
|
|
300
|
+
if not await self.topic_exists(topic):
|
|
301
|
+
await self.create_topic(topic)
|
|
302
|
+
|
|
303
|
+
async def close(self) -> None:
|
|
304
|
+
logger.info("Async Kafka backend closed")
|
|
@@ -22,6 +22,7 @@ from . request_response_client import RequestResponseClient
|
|
|
22
22
|
from . logging import add_logging_args, setup_logging
|
|
23
23
|
|
|
24
24
|
default_config_queue = config_push_queue
|
|
25
|
+
default_config_timeout = 60
|
|
25
26
|
|
|
26
27
|
logger = logging.getLogger(__name__)
|
|
27
28
|
|
|
@@ -60,6 +61,10 @@ class AsyncProcessor:
|
|
|
60
61
|
"config_push_queue", default_config_queue
|
|
61
62
|
)
|
|
62
63
|
|
|
64
|
+
self.config_timeout = int(params.get(
|
|
65
|
+
"config_timeout", default_config_timeout
|
|
66
|
+
))
|
|
67
|
+
|
|
63
68
|
self.config_handlers = []
|
|
64
69
|
self.workspace_handlers = []
|
|
65
70
|
self.config_version = 0
|
|
@@ -83,6 +88,7 @@ class AsyncProcessor:
|
|
|
83
88
|
response_topic=config_response_queue,
|
|
84
89
|
request_schema=ConfigRequest,
|
|
85
90
|
response_schema=ConfigResponse,
|
|
91
|
+
default_timeout=self.config_timeout,
|
|
86
92
|
)
|
|
87
93
|
|
|
88
94
|
async def _fetch_type_workspace(self, client, workspace, config_type):
|
|
@@ -92,7 +98,6 @@ class AsyncProcessor:
|
|
|
92
98
|
workspace=workspace,
|
|
93
99
|
type=config_type,
|
|
94
100
|
),
|
|
95
|
-
timeout=60,
|
|
96
101
|
)
|
|
97
102
|
if resp.error:
|
|
98
103
|
raise RuntimeError(f"Config error: {resp.error.message}")
|
|
@@ -104,7 +109,6 @@ class AsyncProcessor:
|
|
|
104
109
|
operation="getkeys-all-ws",
|
|
105
110
|
type=config_type,
|
|
106
111
|
),
|
|
107
|
-
timeout=60,
|
|
108
112
|
)
|
|
109
113
|
if resp.error:
|
|
110
114
|
raise RuntimeError(f"Config error: {resp.error.message}")
|
|
@@ -433,6 +437,14 @@ class AsyncProcessor:
|
|
|
433
437
|
help='Number of concurrent workers (default: 1)',
|
|
434
438
|
)
|
|
435
439
|
|
|
440
|
+
parser.add_argument(
|
|
441
|
+
'--config-timeout',
|
|
442
|
+
type=int,
|
|
443
|
+
default=default_config_timeout,
|
|
444
|
+
help=f'Config request timeout in seconds '
|
|
445
|
+
f'(default: {default_config_timeout})',
|
|
446
|
+
)
|
|
447
|
+
|
|
436
448
|
parser.add_argument(
|
|
437
449
|
'--metrics',
|
|
438
450
|
action=argparse.BooleanOptionalAction,
|
|
@@ -13,9 +13,12 @@ logger = logging.getLogger(__name__)
|
|
|
13
13
|
|
|
14
14
|
class AuditPublisher:
|
|
15
15
|
|
|
16
|
-
def __init__(self, component_name, processor_id=None, backend=None
|
|
16
|
+
def __init__(self, component_name, processor_id=None, backend=None,
|
|
17
|
+
async_backend=None):
|
|
17
18
|
self.component_name = component_name
|
|
18
19
|
self._handle = None
|
|
20
|
+
self._async_producer = None
|
|
21
|
+
self._async_backend = async_backend
|
|
19
22
|
|
|
20
23
|
if backend is not None:
|
|
21
24
|
self._legacy_producer = Producer(
|
|
@@ -36,8 +39,19 @@ class AuditPublisher:
|
|
|
36
39
|
topic=audit_events_queue,
|
|
37
40
|
schema=AuditEvent,
|
|
38
41
|
)
|
|
42
|
+
elif self._async_backend is not None:
|
|
43
|
+
self._async_producer = await self._async_backend.create_producer(
|
|
44
|
+
topic=audit_events_queue,
|
|
45
|
+
schema=AuditEvent,
|
|
46
|
+
)
|
|
39
47
|
|
|
40
48
|
async def stop(self):
|
|
49
|
+
if self._async_producer:
|
|
50
|
+
try:
|
|
51
|
+
await self._async_producer.close()
|
|
52
|
+
except BaseException:
|
|
53
|
+
pass
|
|
54
|
+
self._async_producer = None
|
|
41
55
|
if self._handle:
|
|
42
56
|
await self._handle.unregister()
|
|
43
57
|
|
|
@@ -54,6 +68,8 @@ class AuditPublisher:
|
|
|
54
68
|
try:
|
|
55
69
|
if self._handle:
|
|
56
70
|
await self._handle.send(event)
|
|
71
|
+
elif self._async_producer:
|
|
72
|
+
await self._async_producer.send(event)
|
|
57
73
|
elif self._legacy_producer:
|
|
58
74
|
await self._legacy_producer.send(event)
|
|
59
75
|
except Exception as e:
|
|
@@ -7,7 +7,10 @@ CONFIG_TIMEOUT = 10
|
|
|
7
7
|
|
|
8
8
|
class ConfigClient(RequestResponse):
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
def __init__(self, timeout=CONFIG_TIMEOUT, **kwargs):
|
|
11
|
+
super(ConfigClient, self).__init__(default_timeout=timeout, **kwargs)
|
|
12
|
+
|
|
13
|
+
async def _request(self, timeout=None, **kwargs):
|
|
11
14
|
resp = await self.request(
|
|
12
15
|
ConfigRequest(**kwargs),
|
|
13
16
|
timeout=timeout,
|
|
@@ -18,7 +21,7 @@ class ConfigClient(RequestResponse):
|
|
|
18
21
|
)
|
|
19
22
|
return resp
|
|
20
23
|
|
|
21
|
-
async def get(self, workspace, type, key, timeout=
|
|
24
|
+
async def get(self, workspace, type, key, timeout=None):
|
|
22
25
|
"""Get a single config value. Returns the value string or None."""
|
|
23
26
|
resp = await self._request(
|
|
24
27
|
operation="get",
|
|
@@ -30,7 +33,7 @@ class ConfigClient(RequestResponse):
|
|
|
30
33
|
return resp.values[0].value
|
|
31
34
|
return None
|
|
32
35
|
|
|
33
|
-
async def put(self, workspace, type, key, value, timeout=
|
|
36
|
+
async def put(self, workspace, type, key, value, timeout=None):
|
|
34
37
|
"""Put a single config value."""
|
|
35
38
|
await self._request(
|
|
36
39
|
operation="put",
|
|
@@ -39,7 +42,7 @@ class ConfigClient(RequestResponse):
|
|
|
39
42
|
timeout=timeout,
|
|
40
43
|
)
|
|
41
44
|
|
|
42
|
-
async def put_many(self, workspace, values, timeout=
|
|
45
|
+
async def put_many(self, workspace, values, timeout=None):
|
|
43
46
|
"""Put multiple config values in a single request within a
|
|
44
47
|
single workspace. values is a list of (type, key, value) tuples."""
|
|
45
48
|
await self._request(
|
|
@@ -52,7 +55,7 @@ class ConfigClient(RequestResponse):
|
|
|
52
55
|
timeout=timeout,
|
|
53
56
|
)
|
|
54
57
|
|
|
55
|
-
async def delete(self, workspace, type, key, timeout=
|
|
58
|
+
async def delete(self, workspace, type, key, timeout=None):
|
|
56
59
|
"""Delete a single config key."""
|
|
57
60
|
await self._request(
|
|
58
61
|
operation="delete",
|
|
@@ -61,7 +64,7 @@ class ConfigClient(RequestResponse):
|
|
|
61
64
|
timeout=timeout,
|
|
62
65
|
)
|
|
63
66
|
|
|
64
|
-
async def delete_many(self, workspace, keys, timeout=
|
|
67
|
+
async def delete_many(self, workspace, keys, timeout=None):
|
|
65
68
|
"""Delete multiple config keys in a single request within a
|
|
66
69
|
single workspace. keys is a list of (type, key) tuples."""
|
|
67
70
|
await self._request(
|
|
@@ -74,7 +77,7 @@ class ConfigClient(RequestResponse):
|
|
|
74
77
|
timeout=timeout,
|
|
75
78
|
)
|
|
76
79
|
|
|
77
|
-
async def keys(self, workspace, type, timeout=
|
|
80
|
+
async def keys(self, workspace, type, timeout=None):
|
|
78
81
|
"""List all keys for a config type within a workspace."""
|
|
79
82
|
resp = await self._request(
|
|
80
83
|
operation="list",
|
|
@@ -84,7 +87,7 @@ class ConfigClient(RequestResponse):
|
|
|
84
87
|
)
|
|
85
88
|
return resp.directory
|
|
86
89
|
|
|
87
|
-
async def get_all(self, workspace, timeout=
|
|
90
|
+
async def get_all(self, workspace, timeout=None):
|
|
88
91
|
"""Return every config entry in ``workspace`` as a nested dict
|
|
89
92
|
``{type: {key: value}}``. Values are returned as the raw
|
|
90
93
|
strings stored by config-svc (typically JSON); callers parse
|
|
@@ -96,7 +99,7 @@ class ConfigClient(RequestResponse):
|
|
|
96
99
|
)
|
|
97
100
|
return resp.config
|
|
98
101
|
|
|
99
|
-
async def workspaces_for_type(self, type, timeout=
|
|
102
|
+
async def workspaces_for_type(self, type, timeout=None):
|
|
100
103
|
"""Return the set of distinct workspaces with any config of
|
|
101
104
|
the given type."""
|
|
102
105
|
resp = await self._request(
|
|
@@ -29,8 +29,8 @@ def get_async_pubsub(**config: Any) -> Any:
|
|
|
29
29
|
"""
|
|
30
30
|
Factory function to create an async pub/sub backend.
|
|
31
31
|
|
|
32
|
-
|
|
33
|
-
|
|
32
|
+
Creates the appropriate async backend based on the 'pubsub_backend'
|
|
33
|
+
config key. Supported: pulsar, rabbitmq, kafka.
|
|
34
34
|
"""
|
|
35
35
|
backend_type = config.get('pubsub_backend', 'pulsar')
|
|
36
36
|
|
|
@@ -51,10 +51,29 @@ def get_async_pubsub(**config: Any) -> Any:
|
|
|
51
51
|
password=config.get('rabbitmq_password', DEFAULT_RABBITMQ_PASSWORD),
|
|
52
52
|
vhost=config.get('rabbitmq_vhost', DEFAULT_RABBITMQ_VHOST),
|
|
53
53
|
)
|
|
54
|
+
elif backend_type == 'kafka':
|
|
55
|
+
from .async_kafka_backend import AsyncKafkaBackend
|
|
56
|
+
return AsyncKafkaBackend(
|
|
57
|
+
bootstrap_servers=config.get(
|
|
58
|
+
'kafka_bootstrap_servers', DEFAULT_KAFKA_BOOTSTRAP,
|
|
59
|
+
),
|
|
60
|
+
security_protocol=config.get(
|
|
61
|
+
'kafka_security_protocol', DEFAULT_KAFKA_PROTOCOL,
|
|
62
|
+
),
|
|
63
|
+
sasl_mechanism=config.get(
|
|
64
|
+
'kafka_sasl_mechanism', DEFAULT_KAFKA_SASL_MECHANISM,
|
|
65
|
+
),
|
|
66
|
+
sasl_username=config.get(
|
|
67
|
+
'kafka_sasl_username', DEFAULT_KAFKA_SASL_USERNAME,
|
|
68
|
+
),
|
|
69
|
+
sasl_password=config.get(
|
|
70
|
+
'kafka_sasl_password', DEFAULT_KAFKA_SASL_PASSWORD,
|
|
71
|
+
),
|
|
72
|
+
)
|
|
54
73
|
else:
|
|
55
74
|
raise ValueError(
|
|
56
75
|
f"Async backend not yet supported for: {backend_type}. "
|
|
57
|
-
f"Supported: 'pulsar', 'rabbitmq'."
|
|
76
|
+
f"Supported: 'pulsar', 'rabbitmq', 'kafka'."
|
|
58
77
|
)
|
|
59
78
|
|
|
60
79
|
|
|
@@ -33,12 +33,13 @@ class RequestResponseClient:
|
|
|
33
33
|
await client.close()
|
|
34
34
|
"""
|
|
35
35
|
|
|
36
|
-
def __init__(self):
|
|
36
|
+
def __init__(self, default_timeout=60):
|
|
37
37
|
self.producer = None
|
|
38
38
|
self.consumer = None
|
|
39
39
|
self.receiver_task = None
|
|
40
40
|
self.pending: dict[str, asyncio.Future] = {}
|
|
41
41
|
self.running = False
|
|
42
|
+
self.default_timeout = default_timeout
|
|
42
43
|
|
|
43
44
|
@classmethod
|
|
44
45
|
async def create(
|
|
@@ -49,8 +50,9 @@ class RequestResponseClient:
|
|
|
49
50
|
request_schema: type,
|
|
50
51
|
response_schema: type,
|
|
51
52
|
subscription: str | None = None,
|
|
53
|
+
default_timeout: float = 60,
|
|
52
54
|
) -> 'RequestResponseClient':
|
|
53
|
-
client = cls()
|
|
55
|
+
client = cls(default_timeout=default_timeout)
|
|
54
56
|
|
|
55
57
|
client.producer = await backend.create_producer(
|
|
56
58
|
topic=request_topic,
|
|
@@ -80,9 +82,12 @@ class RequestResponseClient:
|
|
|
80
82
|
return client
|
|
81
83
|
|
|
82
84
|
async def request(
|
|
83
|
-
self, message: Any, timeout: float =
|
|
85
|
+
self, message: Any, timeout: float | None = None,
|
|
84
86
|
properties: dict | None = None,
|
|
85
87
|
) -> Any:
|
|
88
|
+
if timeout is None:
|
|
89
|
+
timeout = self.default_timeout
|
|
90
|
+
|
|
86
91
|
request_id = str(uuid.uuid4())
|
|
87
92
|
future = asyncio.get_event_loop().create_future()
|
|
88
93
|
self.pending[request_id] = future
|
|
@@ -100,9 +105,12 @@ class RequestResponseClient:
|
|
|
100
105
|
raise
|
|
101
106
|
|
|
102
107
|
async def request_stream(
|
|
103
|
-
self, message: Any, timeout: float =
|
|
108
|
+
self, message: Any, timeout: float | None = None,
|
|
104
109
|
properties: dict | None = None,
|
|
105
110
|
):
|
|
111
|
+
if timeout is None:
|
|
112
|
+
timeout = self.default_timeout
|
|
113
|
+
|
|
106
114
|
request_id = str(uuid.uuid4())
|
|
107
115
|
queue = asyncio.Queue()
|
|
108
116
|
self.pending[request_id] = queue
|
|
@@ -21,8 +21,11 @@ class RequestResponse(Subscriber):
|
|
|
21
21
|
request_metrics,
|
|
22
22
|
response_topic, response_schema,
|
|
23
23
|
response_metrics,
|
|
24
|
+
default_timeout=300,
|
|
24
25
|
):
|
|
25
26
|
|
|
27
|
+
self.default_timeout = default_timeout
|
|
28
|
+
|
|
26
29
|
super(RequestResponse, self).__init__(
|
|
27
30
|
backend = backend,
|
|
28
31
|
subscription = subscription,
|
|
@@ -47,7 +50,10 @@ class RequestResponse(Subscriber):
|
|
|
47
50
|
await self.producer.stop()
|
|
48
51
|
await super(RequestResponse, self).stop()
|
|
49
52
|
|
|
50
|
-
async def request(self, req, timeout=
|
|
53
|
+
async def request(self, req, timeout=None, recipient=None):
|
|
54
|
+
|
|
55
|
+
if timeout is None:
|
|
56
|
+
timeout = self.default_timeout
|
|
51
57
|
|
|
52
58
|
id = str(uuid.uuid4())
|
|
53
59
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "2.8.1"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: trustgraph-base
|
|
3
|
-
Version: 2.8.
|
|
3
|
+
Version: 2.8.1
|
|
4
4
|
Summary: TrustGraph provides a means to run a pipeline of flexible AI processing components in a flexible means to achieve a processing pipeline.
|
|
5
5
|
Author-email: "trustgraph.ai" <security@trustgraph.ai>
|
|
6
6
|
Project-URL: Homepage, https://github.com/trustgraph-ai/trustgraph
|
|
@@ -15,6 +15,7 @@ Requires-Dist: python-logging-loki
|
|
|
15
15
|
Requires-Dist: pika
|
|
16
16
|
Requires-Dist: aio-pika
|
|
17
17
|
Requires-Dist: confluent-kafka
|
|
18
|
+
Requires-Dist: aiokafka
|
|
18
19
|
Requires-Dist: pyyaml
|
|
19
20
|
Requires-Dist: websockets
|
|
20
21
|
|
|
@@ -26,6 +26,7 @@ trustgraph/base/agent_client.py
|
|
|
26
26
|
trustgraph/base/agent_service.py
|
|
27
27
|
trustgraph/base/async_backend.py
|
|
28
28
|
trustgraph/base/async_config_client.py
|
|
29
|
+
trustgraph/base/async_kafka_backend.py
|
|
29
30
|
trustgraph/base/async_librarian_client.py
|
|
30
31
|
trustgraph/base/async_processor.py
|
|
31
32
|
trustgraph/base/async_pulsar_backend.py
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "2.8.0"
|
|
File without changes
|