OpenRAG 0.2.4__tar.gz → 0.2.5__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.
- openrag-0.2.5/PKG-INFO +196 -0
- openrag-0.2.5/README.md +166 -0
- {openrag-0.2.4 → openrag-0.2.5}/pyproject.toml +3 -21
- {openrag-0.2.4 → openrag-0.2.5}/src/agent.py +28 -0
- {openrag-0.2.4 → openrag-0.2.5}/src/api/auth.py +52 -20
- {openrag-0.2.4 → openrag-0.2.5}/src/api/chat.py +77 -83
- {openrag-0.2.4 → openrag-0.2.5}/src/api/connector_router.py +1 -7
- {openrag-0.2.4 → openrag-0.2.5}/src/api/connectors.py +60 -39
- {openrag-0.2.4 → openrag-0.2.5}/src/api/docling.py +21 -18
- {openrag-0.2.4 → openrag-0.2.5}/src/api/documents.py +49 -40
- {openrag-0.2.4 → openrag-0.2.5}/src/api/flows.py +21 -30
- openrag-0.2.5/src/api/keys.py +123 -0
- {openrag-0.2.4 → openrag-0.2.5}/src/api/knowledge_filter.py +119 -213
- openrag-0.2.5/src/api/langflow_files.py +224 -0
- openrag-0.2.5/src/api/models.py +165 -0
- openrag-0.2.5/src/api/nudges.py +67 -0
- {openrag-0.2.4 → openrag-0.2.5}/src/api/oidc.py +25 -35
- {openrag-0.2.4 → openrag-0.2.5}/src/api/provider_health.py +15 -12
- {openrag-0.2.4 → openrag-0.2.5}/src/api/provider_validation.py +3 -13
- openrag-0.2.5/src/api/router.py +172 -0
- openrag-0.2.5/src/api/search.py +61 -0
- {openrag-0.2.4 → openrag-0.2.5}/src/api/settings.py +506 -578
- {openrag-0.2.4 → openrag-0.2.5}/src/api/tasks.py +19 -12
- {openrag-0.2.4 → openrag-0.2.5}/src/api/upload.py +69 -44
- openrag-0.2.5/src/api/v1/chat.py +216 -0
- openrag-0.2.5/src/api/v1/documents.py +113 -0
- openrag-0.2.5/src/api/v1/knowledge_filters.py +112 -0
- openrag-0.2.5/src/api/v1/models.py +81 -0
- openrag-0.2.5/src/api/v1/search.py +74 -0
- openrag-0.2.5/src/api/v1/settings.py +73 -0
- openrag-0.2.5/src/config/model_constants.py +39 -0
- {openrag-0.2.4 → openrag-0.2.5}/src/config/settings.py +98 -64
- {openrag-0.2.4 → openrag-0.2.5}/src/connectors/service.py +1 -3
- openrag-0.2.5/src/dependencies.py +218 -0
- openrag-0.2.5/src/main.py +995 -0
- {openrag-0.2.4 → openrag-0.2.5}/src/models/processors.py +5 -7
- openrag-0.2.5/src/openrag.egg-info/PKG-INFO +196 -0
- {openrag-0.2.4 → openrag-0.2.5}/src/openrag.egg-info/SOURCES.txt +9 -3
- {openrag-0.2.4 → openrag-0.2.5}/src/openrag.egg-info/requires.txt +1 -11
- {openrag-0.2.4 → openrag-0.2.5}/src/openrag.egg-info/top_level.txt +1 -2
- {openrag-0.2.4 → openrag-0.2.5}/src/services/document_service.py +7 -33
- {openrag-0.2.4 → openrag-0.2.5}/src/services/models_service.py +55 -60
- {openrag-0.2.4 → openrag-0.2.5}/src/services/task_service.py +1 -9
- {openrag-0.2.4 → openrag-0.2.5}/src/session_manager.py +18 -17
- {openrag-0.2.4 → openrag-0.2.5}/src/tui/_assets/docker-compose.yml +20 -5
- {openrag-0.2.4 → openrag-0.2.5}/src/tui/_assets/openrag-documents/openrag-documentation.pdf +0 -0
- openrag-0.2.5/src/tui/cli.py +509 -0
- openrag-0.2.5/src/tui/config_fields.py +235 -0
- {openrag-0.2.4 → openrag-0.2.5}/src/tui/main.py +42 -20
- {openrag-0.2.4 → openrag-0.2.5}/src/tui/managers/container_manager.py +55 -11
- {openrag-0.2.4 → openrag-0.2.5}/src/tui/managers/docling_manager.py +114 -42
- {openrag-0.2.4 → openrag-0.2.5}/src/tui/managers/env_manager.py +44 -22
- {openrag-0.2.4 → openrag-0.2.5}/src/tui/screens/config.py +161 -488
- {openrag-0.2.4 → openrag-0.2.5}/src/tui/screens/monitor.py +3 -13
- {openrag-0.2.4 → openrag-0.2.5}/src/tui/screens/welcome.py +10 -12
- {openrag-0.2.4 → openrag-0.2.5}/src/tui/widgets/command_modal.py +33 -3
- openrag-0.2.5/src/utils/docling_client.py +88 -0
- openrag-0.2.5/src/utils/document_processing.py +143 -0
- {openrag-0.2.4 → openrag-0.2.5}/src/utils/embedding_fields.py +2 -2
- {openrag-0.2.4 → openrag-0.2.5}/src/utils/embeddings.py +2 -2
- openrag-0.2.5/src/utils/env_utils.py +31 -0
- openrag-0.2.5/src/utils/langflow_utils.py +88 -0
- {openrag-0.2.4 → openrag-0.2.5}/src/utils/logging_config.py +27 -4
- openrag-0.2.5/src/utils/opensearch_utils.py +82 -0
- {openrag-0.2.4 → openrag-0.2.5}/src/utils/telemetry/client.py +1 -35
- openrag-0.2.5/src/utils/version_utils.py +35 -0
- openrag-0.2.4/PKG-INFO +0 -70
- openrag-0.2.4/README.md +0 -34
- openrag-0.2.4/src/api/keys.py +0 -183
- openrag-0.2.4/src/api/langflow_files.py +0 -296
- openrag-0.2.4/src/api/models.py +0 -200
- openrag-0.2.4/src/api/nudges.py +0 -72
- openrag-0.2.4/src/api/router.py +0 -209
- openrag-0.2.4/src/api/search.py +0 -53
- openrag-0.2.4/src/api/v1/chat.py +0 -301
- openrag-0.2.4/src/api/v1/documents.py +0 -150
- openrag-0.2.4/src/api/v1/knowledge_filters.py +0 -63
- openrag-0.2.4/src/api/v1/models.py +0 -111
- openrag-0.2.4/src/api/v1/search.py +0 -108
- openrag-0.2.4/src/api/v1/settings.py +0 -90
- openrag-0.2.4/src/api_key_middleware.py +0 -133
- openrag-0.2.4/src/auth_middleware.py +0 -84
- openrag-0.2.4/src/main.py +0 -1702
- openrag-0.2.4/src/openrag.egg-info/PKG-INFO +0 -70
- openrag-0.2.4/src/utils/document_processing.py +0 -446
- openrag-0.2.4/src/utils/process_pool.py +0 -13
- {openrag-0.2.4 → openrag-0.2.5}/LICENSE +0 -0
- {openrag-0.2.4 → openrag-0.2.5}/MANIFEST.in +0 -0
- {openrag-0.2.4 → openrag-0.2.5}/setup.cfg +0 -0
- {openrag-0.2.4 → openrag-0.2.5}/src/api/__init__.py +0 -0
- {openrag-0.2.4 → openrag-0.2.5}/src/api/v1/__init__.py +0 -0
- {openrag-0.2.4 → openrag-0.2.5}/src/auth_context.py +0 -0
- {openrag-0.2.4 → openrag-0.2.5}/src/config/__init__.py +0 -0
- {openrag-0.2.4 → openrag-0.2.5}/src/config/config_manager.py +0 -0
- {openrag-0.2.4 → openrag-0.2.5}/src/connectors/__init__.py +0 -0
- {openrag-0.2.4 → openrag-0.2.5}/src/connectors/base.py +0 -0
- {openrag-0.2.4 → openrag-0.2.5}/src/connectors/connection_manager.py +0 -0
- {openrag-0.2.4 → openrag-0.2.5}/src/connectors/google_drive/__init__.py +0 -0
- {openrag-0.2.4 → openrag-0.2.5}/src/connectors/google_drive/connector.py +0 -0
- {openrag-0.2.4 → openrag-0.2.5}/src/connectors/google_drive/oauth.py +0 -0
- {openrag-0.2.4 → openrag-0.2.5}/src/connectors/langflow_connector_service.py +0 -0
- {openrag-0.2.4 → openrag-0.2.5}/src/connectors/onedrive/__init__.py +0 -0
- {openrag-0.2.4 → openrag-0.2.5}/src/connectors/onedrive/connector.py +0 -0
- {openrag-0.2.4 → openrag-0.2.5}/src/connectors/onedrive/oauth.py +0 -0
- {openrag-0.2.4 → openrag-0.2.5}/src/connectors/sharepoint/__init__.py +0 -0
- {openrag-0.2.4 → openrag-0.2.5}/src/connectors/sharepoint/connector.py +0 -0
- {openrag-0.2.4 → openrag-0.2.5}/src/connectors/sharepoint/oauth.py +0 -0
- {openrag-0.2.4 → openrag-0.2.5}/src/connectors/sharepoint/utils.py +0 -0
- {openrag-0.2.4 → openrag-0.2.5}/src/models/__init__.py +0 -0
- {openrag-0.2.4 → openrag-0.2.5}/src/models/tasks.py +0 -0
- {openrag-0.2.4 → openrag-0.2.5}/src/openrag.egg-info/dependency_links.txt +0 -0
- {openrag-0.2.4 → openrag-0.2.5}/src/openrag.egg-info/entry_points.txt +0 -0
- {openrag-0.2.4 → openrag-0.2.5}/src/services/__init__.py +0 -0
- {openrag-0.2.4 → openrag-0.2.5}/src/services/api_key_service.py +0 -0
- {openrag-0.2.4 → openrag-0.2.5}/src/services/auth_service.py +0 -0
- {openrag-0.2.4 → openrag-0.2.5}/src/services/chat_service.py +0 -0
- {openrag-0.2.4 → openrag-0.2.5}/src/services/conversation_persistence_service.py +0 -0
- {openrag-0.2.4 → openrag-0.2.5}/src/services/flows_service.py +0 -0
- {openrag-0.2.4 → openrag-0.2.5}/src/services/knowledge_filter_service.py +0 -0
- {openrag-0.2.4 → openrag-0.2.5}/src/services/langflow_file_service.py +0 -0
- {openrag-0.2.4 → openrag-0.2.5}/src/services/langflow_history_service.py +0 -0
- {openrag-0.2.4 → openrag-0.2.5}/src/services/langflow_mcp_service.py +0 -0
- {openrag-0.2.4 → openrag-0.2.5}/src/services/monitor_service.py +0 -0
- {openrag-0.2.4 → openrag-0.2.5}/src/services/search_service.py +0 -0
- {openrag-0.2.4 → openrag-0.2.5}/src/services/session_ownership_service.py +0 -0
- {openrag-0.2.4 → openrag-0.2.5}/src/tui/__init__.py +0 -0
- {openrag-0.2.4 → openrag-0.2.5}/src/tui/_assets/docker-compose.gpu.yml +0 -0
- {openrag-0.2.4 → openrag-0.2.5}/src/tui/_assets/flows/components/ollama_embedding.json +0 -0
- {openrag-0.2.4 → openrag-0.2.5}/src/tui/_assets/flows/components/ollama_llm.json +0 -0
- {openrag-0.2.4 → openrag-0.2.5}/src/tui/_assets/flows/components/ollama_llm_text.json +0 -0
- {openrag-0.2.4 → openrag-0.2.5}/src/tui/_assets/flows/components/watsonx_embedding.json +0 -0
- {openrag-0.2.4 → openrag-0.2.5}/src/tui/_assets/flows/components/watsonx_llm.json +0 -0
- {openrag-0.2.4 → openrag-0.2.5}/src/tui/_assets/flows/components/watsonx_llm_text.json +0 -0
- {openrag-0.2.4 → openrag-0.2.5}/src/tui/_assets/flows/ingestion_flow.json +0 -0
- {openrag-0.2.4 → openrag-0.2.5}/src/tui/_assets/flows/openrag_agent.json +0 -0
- {openrag-0.2.4 → openrag-0.2.5}/src/tui/_assets/flows/openrag_nudges.json +0 -0
- {openrag-0.2.4 → openrag-0.2.5}/src/tui/_assets/flows/openrag_url_mcp.json +0 -0
- {openrag-0.2.4 → openrag-0.2.5}/src/tui/_assets/openrag-documents/docling.pdf +0 -0
- {openrag-0.2.4 → openrag-0.2.5}/src/tui/_assets/openrag-documents/ibm_anthropic.pdf +0 -0
- {openrag-0.2.4 → openrag-0.2.5}/src/tui/_assets/openrag-documents/warmup_ocr.pdf +0 -0
- {openrag-0.2.4 → openrag-0.2.5}/src/tui/managers/__init__.py +0 -0
- {openrag-0.2.4 → openrag-0.2.5}/src/tui/screens/__init__.py +0 -0
- {openrag-0.2.4 → openrag-0.2.5}/src/tui/screens/diagnostics.py +0 -0
- {openrag-0.2.4 → openrag-0.2.5}/src/tui/screens/logs.py +0 -0
- {openrag-0.2.4 → openrag-0.2.5}/src/tui/utils/__init__.py +0 -0
- {openrag-0.2.4 → openrag-0.2.5}/src/tui/utils/clipboard.py +0 -0
- {openrag-0.2.4 → openrag-0.2.5}/src/tui/utils/platform.py +0 -0
- {openrag-0.2.4 → openrag-0.2.5}/src/tui/utils/startup_checks.py +0 -0
- {openrag-0.2.4 → openrag-0.2.5}/src/tui/utils/validation.py +0 -0
- {openrag-0.2.4 → openrag-0.2.5}/src/tui/utils/version_check.py +0 -0
- {openrag-0.2.4 → openrag-0.2.5}/src/tui/widgets/__init__.py +0 -0
- {openrag-0.2.4 → openrag-0.2.5}/src/tui/widgets/diagnostics_notification.py +0 -0
- {openrag-0.2.4 → openrag-0.2.5}/src/tui/widgets/error_notification.py +0 -0
- {openrag-0.2.4 → openrag-0.2.5}/src/tui/widgets/factory_reset_warning_modal.py +0 -0
- {openrag-0.2.4 → openrag-0.2.5}/src/tui/widgets/flow_backup_warning_modal.py +0 -0
- {openrag-0.2.4 → openrag-0.2.5}/src/tui/widgets/prune_options_modal.py +0 -0
- {openrag-0.2.4 → openrag-0.2.5}/src/tui/widgets/upgrade_instructions_modal.py +0 -0
- {openrag-0.2.4 → openrag-0.2.5}/src/tui/widgets/version_mismatch_warning_modal.py +0 -0
- {openrag-0.2.4 → openrag-0.2.5}/src/tui/widgets/waves.py +0 -0
- {openrag-0.2.4 → openrag-0.2.5}/src/utils/__init__.py +0 -0
- {openrag-0.2.4 → openrag-0.2.5}/src/utils/acl_utils.py +0 -0
- {openrag-0.2.4 → openrag-0.2.5}/src/utils/container_utils.py +0 -0
- {openrag-0.2.4 → openrag-0.2.5}/src/utils/file_utils.py +0 -0
- {openrag-0.2.4 → openrag-0.2.5}/src/utils/gpu_detection.py +0 -0
- {openrag-0.2.4 → openrag-0.2.5}/src/utils/hash_utils.py +0 -0
- {openrag-0.2.4 → openrag-0.2.5}/src/utils/langflow_headers.py +0 -0
- {openrag-0.2.4 → openrag-0.2.5}/src/utils/opensearch_queries.py +0 -0
- {openrag-0.2.4 → openrag-0.2.5}/src/utils/paths.py +0 -0
- {openrag-0.2.4 → openrag-0.2.5}/src/utils/telemetry/__init__.py +0 -0
- {openrag-0.2.4 → openrag-0.2.5}/src/utils/telemetry/category.py +0 -0
- {openrag-0.2.4 → openrag-0.2.5}/src/utils/telemetry/message_id.py +0 -0
openrag-0.2.5/PKG-INFO
ADDED
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: openrag
|
|
3
|
+
Version: 0.2.5
|
|
4
|
+
Summary: OpenRAG is a comprehensive Retrieval-Augmented Generation platform that enables intelligent document search and AI-powered conversations.
|
|
5
|
+
Requires-Python: >=3.13
|
|
6
|
+
Description-Content-Type: text/markdown
|
|
7
|
+
License-File: LICENSE
|
|
8
|
+
Requires-Dist: agentd>=0.2.2
|
|
9
|
+
Requires-Dist: aiofiles>=24.1.0
|
|
10
|
+
Requires-Dist: cryptography>=45.0.6
|
|
11
|
+
Requires-Dist: google-api-python-client>=2.143.0
|
|
12
|
+
Requires-Dist: google-auth-httplib2>=0.2.0
|
|
13
|
+
Requires-Dist: google-auth-oauthlib>=1.2.0
|
|
14
|
+
Requires-Dist: msal>=1.29.0
|
|
15
|
+
Requires-Dist: httpx>=0.27.0
|
|
16
|
+
Requires-Dist: opensearch-py[async]>=3.0.0
|
|
17
|
+
Requires-Dist: pyjwt>=2.8.0
|
|
18
|
+
Requires-Dist: python-multipart>=0.0.20
|
|
19
|
+
Requires-Dist: fastapi>=0.115.0
|
|
20
|
+
Requires-Dist: uvicorn>=0.35.0
|
|
21
|
+
Requires-Dist: boto3>=1.35.0
|
|
22
|
+
Requires-Dist: psutil>=7.0.0
|
|
23
|
+
Requires-Dist: rich>=13.0.0
|
|
24
|
+
Requires-Dist: textual>=0.45.0
|
|
25
|
+
Requires-Dist: python-dotenv>=1.0.0
|
|
26
|
+
Requires-Dist: textual-fspicker>=0.6.0
|
|
27
|
+
Requires-Dist: structlog>=25.4.0
|
|
28
|
+
Requires-Dist: zxcvbn>=4.5.0
|
|
29
|
+
Dynamic: license-file
|
|
30
|
+
|
|
31
|
+
<div align="center">
|
|
32
|
+
|
|
33
|
+
<img src="./docs/static/img/openrag-logo-dog.svg" alt="OpenRAG Logo" width="120"/>
|
|
34
|
+
|
|
35
|
+
# OpenRAG
|
|
36
|
+
|
|
37
|
+
<h3>
|
|
38
|
+
<em>Intelligent Agent-powered document search</em>
|
|
39
|
+
</h3>
|
|
40
|
+
|
|
41
|
+
<!-- Badges -->
|
|
42
|
+
|
|
43
|
+
[](https://github.com/langflow-ai/langflow)
|
|
44
|
+
[](https://github.com/opensearch-project/OpenSearch)
|
|
45
|
+
[](https://github.com/docling-project/docling)
|
|
46
|
+
|
|
47
|
+
[](https://www.youtube.com/@OpenRAG/)
|
|
48
|
+
[](https://github.com/langflow-ai/openrag/stargazers)
|
|
49
|
+
[](https://github.com/langflow-ai/openrag/network/members)
|
|
50
|
+
|
|
51
|
+
[](https://deepwiki.com/langflow-ai/openrag)
|
|
52
|
+
|
|
53
|
+
</div>
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
OpenRAG is a comprehensive Retrieval-Augmented Generation platform that enables intelligent document search and AI-powered conversations.
|
|
58
|
+
|
|
59
|
+
Users can upload, process, and query documents through a chat interface backed by large language models and semantic search capabilities. The system utilizes Langflow for document ingestion, retrieval workflows, and intelligent nudges, providing a seamless RAG experience.
|
|
60
|
+
|
|
61
|
+
Built with [Starlette](https://github.com/Kludex/starlette) and [Next.js](https://github.com/vercel/next.js).
|
|
62
|
+
Powered by [OpenSearch](https://github.com/opensearch-project/OpenSearch), [Langflow](https://github.com/langflow-ai/langflow), and [Docling](https://github.com/docling-project/docling).
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
<div align="center">
|
|
67
|
+
<img src="./docs/static/img/openrag_readme_downsized.gif" alt="OpenRAG Demo" width="100%"/>
|
|
68
|
+
</div>
|
|
69
|
+
|
|
70
|
+
## ✨ Highlight Features
|
|
71
|
+
|
|
72
|
+
- **Pre-packaged & ready to run** - All core tools are hooked up and ready to go, just install and run
|
|
73
|
+
- **Agentic RAG workflows** - Advanced orchestration with re-ranking and multi-agent coordination
|
|
74
|
+
- **Document ingestion** - Handles messy, real-world data with intelligent parsing
|
|
75
|
+
- **Drag-and-drop workflow builder** - Visual interface powered by Langflow for rapid iteration
|
|
76
|
+
- **Modular enterprise add-ons** - Extend functionality when you need it
|
|
77
|
+
- **Enterprise search at any scale** - Powered by OpenSearch for production-grade performance
|
|
78
|
+
|
|
79
|
+
## 🔄 How OpenRAG Works
|
|
80
|
+
|
|
81
|
+
OpenRAG follows a streamlined workflow to transform your documents into intelligent, searchable knowledge:
|
|
82
|
+
|
|
83
|
+
<div align="center">
|
|
84
|
+
<img src="./docs/static/img/workflow-diagram.svg" alt="OpenRAG Workflow Diagram" width="800"/>
|
|
85
|
+
</div>
|
|
86
|
+
|
|
87
|
+
## 🚀 Install OpenRAG
|
|
88
|
+
|
|
89
|
+
To get started with OpenRAG, see the installation guides in the OpenRAG documentation:
|
|
90
|
+
|
|
91
|
+
* [Quickstart](https://docs.openr.ag/quickstart)
|
|
92
|
+
* [Install the OpenRAG Python package](https://docs.openr.ag/install-options)
|
|
93
|
+
* [Deploy self-managed services with Docker or Podman](https://docs.openr.ag/docker)
|
|
94
|
+
|
|
95
|
+
## ✨ Quick Start Workflow
|
|
96
|
+
|
|
97
|
+
<div align="center">
|
|
98
|
+
|
|
99
|
+
<img src="./docs/static/img/uv_run_openrag.png" alt="Use uv run openrag to start" width="300"/>
|
|
100
|
+
|
|
101
|
+
**1. Launch OpenRAG**
|
|
102
|
+
|
|
103
|
+
↓
|
|
104
|
+
|
|
105
|
+
<img src="./docs/static/img/add_knowledge_openrag.png" alt="Add files or folders as knowledge" width="300"/>
|
|
106
|
+
|
|
107
|
+
**2. Add Knowledge**
|
|
108
|
+
|
|
109
|
+
↓
|
|
110
|
+
|
|
111
|
+
<img src="./docs/static/img/chat_openrag.png" alt="Start Chatting with your knowledge" width="700"/>
|
|
112
|
+
|
|
113
|
+
**3. Start Chatting**
|
|
114
|
+
|
|
115
|
+
</div>
|
|
116
|
+
|
|
117
|
+
## 📦 SDKs
|
|
118
|
+
|
|
119
|
+
Integrate OpenRAG into your applications with our official SDKs:
|
|
120
|
+
|
|
121
|
+
### Python SDK
|
|
122
|
+
```bash
|
|
123
|
+
pip install openrag-sdk
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
**Quick Example:**
|
|
127
|
+
```python
|
|
128
|
+
import asyncio
|
|
129
|
+
from openrag_sdk import OpenRAGClient
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
async def main():
|
|
133
|
+
async with OpenRAGClient() as client:
|
|
134
|
+
response = await client.chat.create(message="What is RAG?")
|
|
135
|
+
print(response.response)
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
if __name__ == "__main__":
|
|
139
|
+
asyncio.run(main())
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
📖 [Full Python SDK Documentation](https://pypi.org/project/openrag-sdk/)
|
|
143
|
+
|
|
144
|
+
### TypeScript/JavaScript SDK
|
|
145
|
+
```bash
|
|
146
|
+
npm install openrag-sdk
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
**Quick Example:**
|
|
150
|
+
```typescript
|
|
151
|
+
import { OpenRAGClient } from "openrag-sdk";
|
|
152
|
+
|
|
153
|
+
const client = new OpenRAGClient();
|
|
154
|
+
const response = await client.chat.create({ message: "What is RAG?" });
|
|
155
|
+
console.log(response.response);
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
📖 [Full TypeScript/JavaScript SDK Documentation](https://www.npmjs.com/package/openrag-sdk)
|
|
159
|
+
|
|
160
|
+
## 🔌 Model Context Protocol (MCP)
|
|
161
|
+
|
|
162
|
+
Connect AI assistants like Cursor and Claude Desktop to your OpenRAG knowledge base:
|
|
163
|
+
|
|
164
|
+
```bash
|
|
165
|
+
pip install openrag-mcp
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
**Quick Example (Cursor/Claude Desktop config):**
|
|
169
|
+
```json
|
|
170
|
+
{
|
|
171
|
+
"mcpServers": {
|
|
172
|
+
"openrag": {
|
|
173
|
+
"command": "uvx",
|
|
174
|
+
"args": ["openrag-mcp"],
|
|
175
|
+
"env": {
|
|
176
|
+
"OPENRAG_URL": "http://localhost:3000",
|
|
177
|
+
"OPENRAG_API_KEY": "your_api_key_here"
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
The MCP server provides tools for RAG-enhanced chat, semantic search, and settings management.
|
|
185
|
+
|
|
186
|
+
📖 [Full MCP Documentation](https://pypi.org/project/openrag-mcp/)
|
|
187
|
+
|
|
188
|
+
## 🛠️ Development
|
|
189
|
+
|
|
190
|
+
For developers who want to [contribute to OpenRAG](https://docs.openr.ag/support/contribute) or set up a development environment, see [CONTRIBUTING.md](CONTRIBUTING.md).
|
|
191
|
+
|
|
192
|
+
## 🆘 Troubleshooting
|
|
193
|
+
|
|
194
|
+
For assistance with OpenRAG, see [Troubleshoot OpenRAG](https://docs.openr.ag/support/troubleshoot) and visit the [Discussions page](https://github.com/langflow-ai/openrag/discussions).
|
|
195
|
+
|
|
196
|
+
To report a bug or submit a feature request, visit the [Issues page](https://github.com/langflow-ai/openrag/issues).
|
openrag-0.2.5/README.md
ADDED
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
|
|
3
|
+
<img src="./docs/static/img/openrag-logo-dog.svg" alt="OpenRAG Logo" width="120"/>
|
|
4
|
+
|
|
5
|
+
# OpenRAG
|
|
6
|
+
|
|
7
|
+
<h3>
|
|
8
|
+
<em>Intelligent Agent-powered document search</em>
|
|
9
|
+
</h3>
|
|
10
|
+
|
|
11
|
+
<!-- Badges -->
|
|
12
|
+
|
|
13
|
+
[](https://github.com/langflow-ai/langflow)
|
|
14
|
+
[](https://github.com/opensearch-project/OpenSearch)
|
|
15
|
+
[](https://github.com/docling-project/docling)
|
|
16
|
+
|
|
17
|
+
[](https://www.youtube.com/@OpenRAG/)
|
|
18
|
+
[](https://github.com/langflow-ai/openrag/stargazers)
|
|
19
|
+
[](https://github.com/langflow-ai/openrag/network/members)
|
|
20
|
+
|
|
21
|
+
[](https://deepwiki.com/langflow-ai/openrag)
|
|
22
|
+
|
|
23
|
+
</div>
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
OpenRAG is a comprehensive Retrieval-Augmented Generation platform that enables intelligent document search and AI-powered conversations.
|
|
28
|
+
|
|
29
|
+
Users can upload, process, and query documents through a chat interface backed by large language models and semantic search capabilities. The system utilizes Langflow for document ingestion, retrieval workflows, and intelligent nudges, providing a seamless RAG experience.
|
|
30
|
+
|
|
31
|
+
Built with [Starlette](https://github.com/Kludex/starlette) and [Next.js](https://github.com/vercel/next.js).
|
|
32
|
+
Powered by [OpenSearch](https://github.com/opensearch-project/OpenSearch), [Langflow](https://github.com/langflow-ai/langflow), and [Docling](https://github.com/docling-project/docling).
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
<div align="center">
|
|
37
|
+
<img src="./docs/static/img/openrag_readme_downsized.gif" alt="OpenRAG Demo" width="100%"/>
|
|
38
|
+
</div>
|
|
39
|
+
|
|
40
|
+
## ✨ Highlight Features
|
|
41
|
+
|
|
42
|
+
- **Pre-packaged & ready to run** - All core tools are hooked up and ready to go, just install and run
|
|
43
|
+
- **Agentic RAG workflows** - Advanced orchestration with re-ranking and multi-agent coordination
|
|
44
|
+
- **Document ingestion** - Handles messy, real-world data with intelligent parsing
|
|
45
|
+
- **Drag-and-drop workflow builder** - Visual interface powered by Langflow for rapid iteration
|
|
46
|
+
- **Modular enterprise add-ons** - Extend functionality when you need it
|
|
47
|
+
- **Enterprise search at any scale** - Powered by OpenSearch for production-grade performance
|
|
48
|
+
|
|
49
|
+
## 🔄 How OpenRAG Works
|
|
50
|
+
|
|
51
|
+
OpenRAG follows a streamlined workflow to transform your documents into intelligent, searchable knowledge:
|
|
52
|
+
|
|
53
|
+
<div align="center">
|
|
54
|
+
<img src="./docs/static/img/workflow-diagram.svg" alt="OpenRAG Workflow Diagram" width="800"/>
|
|
55
|
+
</div>
|
|
56
|
+
|
|
57
|
+
## 🚀 Install OpenRAG
|
|
58
|
+
|
|
59
|
+
To get started with OpenRAG, see the installation guides in the OpenRAG documentation:
|
|
60
|
+
|
|
61
|
+
* [Quickstart](https://docs.openr.ag/quickstart)
|
|
62
|
+
* [Install the OpenRAG Python package](https://docs.openr.ag/install-options)
|
|
63
|
+
* [Deploy self-managed services with Docker or Podman](https://docs.openr.ag/docker)
|
|
64
|
+
|
|
65
|
+
## ✨ Quick Start Workflow
|
|
66
|
+
|
|
67
|
+
<div align="center">
|
|
68
|
+
|
|
69
|
+
<img src="./docs/static/img/uv_run_openrag.png" alt="Use uv run openrag to start" width="300"/>
|
|
70
|
+
|
|
71
|
+
**1. Launch OpenRAG**
|
|
72
|
+
|
|
73
|
+
↓
|
|
74
|
+
|
|
75
|
+
<img src="./docs/static/img/add_knowledge_openrag.png" alt="Add files or folders as knowledge" width="300"/>
|
|
76
|
+
|
|
77
|
+
**2. Add Knowledge**
|
|
78
|
+
|
|
79
|
+
↓
|
|
80
|
+
|
|
81
|
+
<img src="./docs/static/img/chat_openrag.png" alt="Start Chatting with your knowledge" width="700"/>
|
|
82
|
+
|
|
83
|
+
**3. Start Chatting**
|
|
84
|
+
|
|
85
|
+
</div>
|
|
86
|
+
|
|
87
|
+
## 📦 SDKs
|
|
88
|
+
|
|
89
|
+
Integrate OpenRAG into your applications with our official SDKs:
|
|
90
|
+
|
|
91
|
+
### Python SDK
|
|
92
|
+
```bash
|
|
93
|
+
pip install openrag-sdk
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
**Quick Example:**
|
|
97
|
+
```python
|
|
98
|
+
import asyncio
|
|
99
|
+
from openrag_sdk import OpenRAGClient
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
async def main():
|
|
103
|
+
async with OpenRAGClient() as client:
|
|
104
|
+
response = await client.chat.create(message="What is RAG?")
|
|
105
|
+
print(response.response)
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
if __name__ == "__main__":
|
|
109
|
+
asyncio.run(main())
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
📖 [Full Python SDK Documentation](https://pypi.org/project/openrag-sdk/)
|
|
113
|
+
|
|
114
|
+
### TypeScript/JavaScript SDK
|
|
115
|
+
```bash
|
|
116
|
+
npm install openrag-sdk
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
**Quick Example:**
|
|
120
|
+
```typescript
|
|
121
|
+
import { OpenRAGClient } from "openrag-sdk";
|
|
122
|
+
|
|
123
|
+
const client = new OpenRAGClient();
|
|
124
|
+
const response = await client.chat.create({ message: "What is RAG?" });
|
|
125
|
+
console.log(response.response);
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
📖 [Full TypeScript/JavaScript SDK Documentation](https://www.npmjs.com/package/openrag-sdk)
|
|
129
|
+
|
|
130
|
+
## 🔌 Model Context Protocol (MCP)
|
|
131
|
+
|
|
132
|
+
Connect AI assistants like Cursor and Claude Desktop to your OpenRAG knowledge base:
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
pip install openrag-mcp
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
**Quick Example (Cursor/Claude Desktop config):**
|
|
139
|
+
```json
|
|
140
|
+
{
|
|
141
|
+
"mcpServers": {
|
|
142
|
+
"openrag": {
|
|
143
|
+
"command": "uvx",
|
|
144
|
+
"args": ["openrag-mcp"],
|
|
145
|
+
"env": {
|
|
146
|
+
"OPENRAG_URL": "http://localhost:3000",
|
|
147
|
+
"OPENRAG_API_KEY": "your_api_key_here"
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
The MCP server provides tools for RAG-enhanced chat, semantic search, and settings management.
|
|
155
|
+
|
|
156
|
+
📖 [Full MCP Documentation](https://pypi.org/project/openrag-mcp/)
|
|
157
|
+
|
|
158
|
+
## 🛠️ Development
|
|
159
|
+
|
|
160
|
+
For developers who want to [contribute to OpenRAG](https://docs.openr.ag/support/contribute) or set up a development environment, see [CONTRIBUTING.md](CONTRIBUTING.md).
|
|
161
|
+
|
|
162
|
+
## 🆘 Troubleshooting
|
|
163
|
+
|
|
164
|
+
For assistance with OpenRAG, see [Troubleshoot OpenRAG](https://docs.openr.ag/support/troubleshoot) and visit the [Discussions page](https://github.com/langflow-ai/openrag/discussions).
|
|
165
|
+
|
|
166
|
+
To report a bug or submit a feature request, visit the [Issues page](https://github.com/langflow-ai/openrag/issues).
|
|
@@ -4,16 +4,14 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "openrag"
|
|
7
|
-
version = "0.2.
|
|
8
|
-
description = "
|
|
7
|
+
version = "0.2.5"
|
|
8
|
+
description = "OpenRAG is a comprehensive Retrieval-Augmented Generation platform that enables intelligent document search and AI-powered conversations."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.13"
|
|
11
11
|
dependencies = [
|
|
12
12
|
"agentd>=0.2.2",
|
|
13
13
|
"aiofiles>=24.1.0",
|
|
14
14
|
"cryptography>=45.0.6",
|
|
15
|
-
"docling[vlm]==2.41.0; sys_platform != 'darwin'",
|
|
16
|
-
"docling[ocrmac,vlm]==2.41.0; sys_platform == 'darwin'",
|
|
17
15
|
"google-api-python-client>=2.143.0",
|
|
18
16
|
"google-auth-httplib2>=0.2.0",
|
|
19
17
|
"google-auth-oauthlib>=1.2.0",
|
|
@@ -22,8 +20,7 @@ dependencies = [
|
|
|
22
20
|
"opensearch-py[async]>=3.0.0",
|
|
23
21
|
"pyjwt>=2.8.0",
|
|
24
22
|
"python-multipart>=0.0.20",
|
|
25
|
-
"
|
|
26
|
-
"torch>=2.7.1",
|
|
23
|
+
"fastapi>=0.115.0",
|
|
27
24
|
"uvicorn>=0.35.0",
|
|
28
25
|
"boto3>=1.35.0",
|
|
29
26
|
"psutil>=7.0.0",
|
|
@@ -32,9 +29,6 @@ dependencies = [
|
|
|
32
29
|
"python-dotenv>=1.0.0",
|
|
33
30
|
"textual-fspicker>=0.6.0",
|
|
34
31
|
"structlog>=25.4.0",
|
|
35
|
-
"docling-serve==1.5.0",
|
|
36
|
-
"docling-core==2.48.1",
|
|
37
|
-
"easyocr>=1.7.1; sys_platform != 'darwin'",
|
|
38
32
|
"zxcvbn>=4.5.0"
|
|
39
33
|
]
|
|
40
34
|
|
|
@@ -48,15 +42,3 @@ openrag = "tui.main:run_tui"
|
|
|
48
42
|
package = true
|
|
49
43
|
|
|
50
44
|
|
|
51
|
-
[tool.uv.sources]
|
|
52
|
-
torch = [
|
|
53
|
-
{ index = "pytorch-cu128", marker = "sys_platform == 'linux' and platform_machine == 'x86_64'" },
|
|
54
|
-
]
|
|
55
|
-
torchvision = [
|
|
56
|
-
{ index = "pytorch-cu128", marker = "sys_platform == 'linux' and platform_machine == 'x86_64'" },
|
|
57
|
-
]
|
|
58
|
-
|
|
59
|
-
[[tool.uv.index]]
|
|
60
|
-
name = "pytorch-cu128"
|
|
61
|
-
url = "https://download.pytorch.org/whl/cu128"
|
|
62
|
-
explicit = true
|
|
@@ -197,6 +197,18 @@ async def async_response_stream(
|
|
|
197
197
|
sample_data=str(potential_tool_fields)[:500]
|
|
198
198
|
)
|
|
199
199
|
|
|
200
|
+
# Detect response.completed event and log usage
|
|
201
|
+
if isinstance(chunk_data, dict) and chunk_data.get("type") == "response.completed":
|
|
202
|
+
response_data = chunk_data.get("response", {})
|
|
203
|
+
usage = response_data.get("usage")
|
|
204
|
+
if usage:
|
|
205
|
+
logger.info(
|
|
206
|
+
"Stream usage data",
|
|
207
|
+
input_tokens=usage.get("input_tokens"),
|
|
208
|
+
output_tokens=usage.get("output_tokens"),
|
|
209
|
+
total_tokens=usage.get("total_tokens"),
|
|
210
|
+
)
|
|
211
|
+
|
|
200
212
|
# Middleware: Detect implicit tool calls and inject standardized events
|
|
201
213
|
# This helps Granite 3.3 8b and other models that don't emit standard markers
|
|
202
214
|
if isinstance(chunk_data, dict) and not detected_tool_call:
|
|
@@ -487,6 +499,7 @@ async def async_chat_stream(
|
|
|
487
499
|
|
|
488
500
|
full_response = ""
|
|
489
501
|
response_id = None
|
|
502
|
+
usage_data = None
|
|
490
503
|
async for chunk in async_stream(
|
|
491
504
|
async_client,
|
|
492
505
|
prompt,
|
|
@@ -506,6 +519,10 @@ async def async_chat_stream(
|
|
|
506
519
|
response_id = chunk_data["id"]
|
|
507
520
|
elif "response_id" in chunk_data:
|
|
508
521
|
response_id = chunk_data["response_id"]
|
|
522
|
+
# Capture usage from response.completed event
|
|
523
|
+
if chunk_data.get("type") == "response.completed":
|
|
524
|
+
response_obj = chunk_data.get("response", {})
|
|
525
|
+
usage_data = response_obj.get("usage")
|
|
509
526
|
except:
|
|
510
527
|
pass
|
|
511
528
|
yield chunk
|
|
@@ -518,6 +535,9 @@ async def async_chat_stream(
|
|
|
518
535
|
"response_id": response_id,
|
|
519
536
|
"timestamp": datetime.now(),
|
|
520
537
|
}
|
|
538
|
+
# Store usage data if available (from response.completed event)
|
|
539
|
+
if usage_data:
|
|
540
|
+
assistant_message["response_data"] = {"usage": usage_data}
|
|
521
541
|
conversation_state["messages"].append(assistant_message)
|
|
522
542
|
|
|
523
543
|
# Store the conversation thread with its response_id
|
|
@@ -676,6 +696,7 @@ async def async_langflow_chat_stream(
|
|
|
676
696
|
|
|
677
697
|
full_response = ""
|
|
678
698
|
response_id = None
|
|
699
|
+
usage_data = None
|
|
679
700
|
collected_chunks = [] # Store all chunks for function call data
|
|
680
701
|
|
|
681
702
|
async for chunk in async_stream(
|
|
@@ -700,6 +721,10 @@ async def async_langflow_chat_stream(
|
|
|
700
721
|
response_id = chunk_data["id"]
|
|
701
722
|
elif "response_id" in chunk_data:
|
|
702
723
|
response_id = chunk_data["response_id"]
|
|
724
|
+
# Capture usage from response.completed event
|
|
725
|
+
if chunk_data.get("type") == "response.completed":
|
|
726
|
+
response_obj = chunk_data.get("response", {})
|
|
727
|
+
usage_data = response_obj.get("usage")
|
|
703
728
|
except:
|
|
704
729
|
pass
|
|
705
730
|
yield chunk
|
|
@@ -713,6 +738,9 @@ async def async_langflow_chat_stream(
|
|
|
713
738
|
"timestamp": datetime.now(),
|
|
714
739
|
"chunks": collected_chunks, # Store complete chunk data for function calls
|
|
715
740
|
}
|
|
741
|
+
# Store usage data if available (from response.completed event)
|
|
742
|
+
if usage_data:
|
|
743
|
+
assistant_message["response_data"] = {"usage": usage_data}
|
|
716
744
|
conversation_state["messages"].append(assistant_message)
|
|
717
745
|
|
|
718
746
|
# Store the conversation thread with its response_id
|
|
@@ -1,22 +1,48 @@
|
|
|
1
|
-
from
|
|
2
|
-
|
|
1
|
+
from typing import Optional
|
|
2
|
+
|
|
3
|
+
from fastapi import Depends, Request
|
|
4
|
+
from fastapi.responses import JSONResponse
|
|
3
5
|
from utils.telemetry import TelemetryClient, Category, MessageId
|
|
4
6
|
|
|
7
|
+
from dependencies import (
|
|
8
|
+
get_auth_service,
|
|
9
|
+
get_optional_user,
|
|
10
|
+
get_current_user,
|
|
11
|
+
)
|
|
12
|
+
from pydantic import BaseModel
|
|
13
|
+
from session_manager import User
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class AuthInitBody(BaseModel):
|
|
17
|
+
connector_type: str
|
|
18
|
+
purpose: str = "data_source"
|
|
19
|
+
name: Optional[str] = None
|
|
20
|
+
redirect_uri: Optional[str] = None
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class AuthCallbackBody(BaseModel):
|
|
24
|
+
connection_id: str
|
|
25
|
+
authorization_code: str
|
|
26
|
+
state: str
|
|
5
27
|
|
|
6
|
-
|
|
28
|
+
|
|
29
|
+
class TokenIntrospectBody(BaseModel):
|
|
30
|
+
token: str
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
async def auth_init(
|
|
34
|
+
body: AuthInitBody,
|
|
35
|
+
request: Request,
|
|
36
|
+
auth_service=Depends(get_auth_service),
|
|
37
|
+
user: Optional[User] = Depends(get_optional_user),
|
|
38
|
+
):
|
|
7
39
|
"""Initialize OAuth flow for authentication or data source connection"""
|
|
8
40
|
try:
|
|
9
|
-
|
|
10
|
-
connector_type = data.get("connector_type")
|
|
11
|
-
purpose = data.get("purpose", "data_source")
|
|
12
|
-
connection_name = data.get("name", f"{connector_type}_{purpose}")
|
|
13
|
-
redirect_uri = data.get("redirect_uri")
|
|
14
|
-
|
|
15
|
-
user = getattr(request.state, "user", None)
|
|
41
|
+
connection_name = body.name or f"{body.connector_type}_{body.purpose}"
|
|
16
42
|
user_id = user.user_id if user else None
|
|
17
43
|
|
|
18
44
|
result = await auth_service.init_oauth(
|
|
19
|
-
connector_type, purpose, connection_name, redirect_uri, user_id
|
|
45
|
+
body.connector_type, body.purpose, connection_name, body.redirect_uri, user_id
|
|
20
46
|
)
|
|
21
47
|
return JSONResponse(result)
|
|
22
48
|
|
|
@@ -29,16 +55,15 @@ async def auth_init(request: Request, auth_service, session_manager):
|
|
|
29
55
|
)
|
|
30
56
|
|
|
31
57
|
|
|
32
|
-
async def auth_callback(
|
|
58
|
+
async def auth_callback(
|
|
59
|
+
body: AuthCallbackBody,
|
|
60
|
+
request: Request,
|
|
61
|
+
auth_service=Depends(get_auth_service),
|
|
62
|
+
):
|
|
33
63
|
"""Handle OAuth callback - exchange authorization code for tokens"""
|
|
34
64
|
try:
|
|
35
|
-
data = await request.json()
|
|
36
|
-
connection_id = data.get("connection_id")
|
|
37
|
-
authorization_code = data.get("authorization_code")
|
|
38
|
-
state = data.get("state")
|
|
39
|
-
|
|
40
65
|
result = await auth_service.handle_oauth_callback(
|
|
41
|
-
connection_id, authorization_code, state, request
|
|
66
|
+
body.connection_id, body.authorization_code, body.state, request
|
|
42
67
|
)
|
|
43
68
|
|
|
44
69
|
await TelemetryClient.send_event(Category.AUTHENTICATION, MessageId.ORB_AUTH_OAUTH_CALLBACK)
|
|
@@ -69,13 +94,20 @@ async def auth_callback(request: Request, auth_service, session_manager):
|
|
|
69
94
|
return JSONResponse({"error": f"Callback failed: {str(e)}"}, status_code=500)
|
|
70
95
|
|
|
71
96
|
|
|
72
|
-
async def auth_me(
|
|
97
|
+
async def auth_me(
|
|
98
|
+
request: Request,
|
|
99
|
+
auth_service=Depends(get_auth_service),
|
|
100
|
+
user: Optional[User] = Depends(get_optional_user),
|
|
101
|
+
):
|
|
73
102
|
"""Get current user information"""
|
|
74
103
|
result = await auth_service.get_user_info(request)
|
|
75
104
|
return JSONResponse(result)
|
|
76
105
|
|
|
77
106
|
|
|
78
|
-
async def auth_logout(
|
|
107
|
+
async def auth_logout(
|
|
108
|
+
auth_service=Depends(get_auth_service),
|
|
109
|
+
user: User = Depends(get_current_user),
|
|
110
|
+
):
|
|
79
111
|
"""Logout user by clearing auth cookie"""
|
|
80
112
|
await TelemetryClient.send_event(Category.AUTHENTICATION, MessageId.ORB_AUTH_LOGOUT)
|
|
81
113
|
response = JSONResponse(
|