From fff4a639952a9f80d760e34ac38b90c08568d477 Mon Sep 17 00:00:00 2001 From: Edwin Jose Date: Thu, 25 Sep 2025 15:45:32 -0400 Subject: [PATCH 1/8] Add custom headers to Langflow ingestion requests Introduces custom headers containing JWT and owner information to the Langflow ingestion API requests for improved authentication and traceability. Also refactors debug logging and formatting for better readability and error handling in the combined upload, ingest, and delete operation. --- src/services/langflow_file_service.py | 69 +++++++++++++++++---------- 1 file changed, 44 insertions(+), 25 deletions(-) diff --git a/src/services/langflow_file_service.py b/src/services/langflow_file_service.py index 132cd45e..63353874 100644 --- a/src/services/langflow_file_service.py +++ b/src/services/langflow_file_service.py @@ -130,9 +130,16 @@ class LangflowFileService: ) # Avoid logging full payload to prevent leaking sensitive data (e.g., JWT) + headers = { + "X-Langflow-Global-Var-JWT": jwt_token, + "X-Langflow-Global-Var-Owner": owner, + "X-Langflow-Global-Var-Owner-Name": owner_name, + "X-Langflow-Global-Var-Owner-Email": owner_email, + "X-Langflow-Global-Var-Connector-Type": connector_type, + } resp = await clients.langflow_request( - "POST", f"/api/v1/run/{self.flow_id_ingest}", json=payload + "POST", f"/api/v1/run/{self.flow_id_ingest}", json=payload, headers=headers ) logger.debug( "[LF] Run response", status_code=resp.status_code, reason=resp.reason_phrase @@ -168,7 +175,7 @@ class LangflowFileService: """ Combined upload, ingest, and delete operation. First uploads the file, then runs ingestion on it, then optionally deletes the file. - + Args: file_tuple: File tuple (filename, content, content_type) session_id: Optional session ID for the ingestion flow @@ -176,12 +183,12 @@ class LangflowFileService: settings: Optional UI settings to convert to component tweaks jwt_token: Optional JWT token for authentication delete_after_ingest: Whether to delete the file from Langflow after ingestion (default: True) - + Returns: Combined result with upload info, ingestion result, and deletion status """ logger.debug("[LF] Starting combined upload and ingest operation") - + # Step 1: Upload the file try: upload_result = await self.upload_user_file(file_tuple, jwt_token=jwt_token) @@ -190,10 +197,12 @@ class LangflowFileService: extra={ "file_id": upload_result.get("id"), "file_path": upload_result.get("path"), - } + }, ) except Exception as e: - logger.error("[LF] Upload failed during combined operation", extra={"error": str(e)}) + logger.error( + "[LF] Upload failed during combined operation", extra={"error": str(e)} + ) raise Exception(f"Upload failed: {str(e)}") # Step 2: Prepare for ingestion @@ -203,9 +212,11 @@ class LangflowFileService: # Convert UI settings to component tweaks if provided final_tweaks = tweaks.copy() if tweaks else {} - + if settings: - logger.debug("[LF] Applying ingestion settings", extra={"settings": settings}) + logger.debug( + "[LF] Applying ingestion settings", extra={"settings": settings} + ) # Split Text component tweaks (SplitText-QIKhg) if ( @@ -216,7 +227,9 @@ class LangflowFileService: if "SplitText-QIKhg" not in final_tweaks: final_tweaks["SplitText-QIKhg"] = {} if settings.get("chunkSize"): - final_tweaks["SplitText-QIKhg"]["chunk_size"] = settings["chunkSize"] + final_tweaks["SplitText-QIKhg"]["chunk_size"] = settings[ + "chunkSize" + ] if settings.get("chunkOverlap"): final_tweaks["SplitText-QIKhg"]["chunk_overlap"] = settings[ "chunkOverlap" @@ -228,9 +241,14 @@ class LangflowFileService: if settings.get("embeddingModel"): if "OpenAIEmbeddings-joRJ6" not in final_tweaks: final_tweaks["OpenAIEmbeddings-joRJ6"] = {} - final_tweaks["OpenAIEmbeddings-joRJ6"]["model"] = settings["embeddingModel"] + final_tweaks["OpenAIEmbeddings-joRJ6"]["model"] = settings[ + "embeddingModel" + ] - logger.debug("[LF] Final tweaks with settings applied", extra={"tweaks": final_tweaks}) + logger.debug( + "[LF] Final tweaks with settings applied", + extra={"tweaks": final_tweaks}, + ) # Step 3: Run ingestion try: @@ -244,10 +262,7 @@ class LangflowFileService: except Exception as e: logger.error( "[LF] Ingestion failed during combined operation", - extra={ - "error": str(e), - "file_path": file_path - } + extra={"error": str(e), "file_path": file_path}, ) # Note: We could optionally delete the uploaded file here if ingestion fails raise Exception(f"Ingestion failed: {str(e)}") @@ -256,10 +271,13 @@ class LangflowFileService: file_id = upload_result.get("id") delete_result = None delete_error = None - + if delete_after_ingest and file_id: try: - logger.debug("[LF] Deleting file after successful ingestion", extra={"file_id": file_id}) + logger.debug( + "[LF] Deleting file after successful ingestion", + extra={"file_id": file_id}, + ) await self.delete_user_file(file_id) delete_result = {"status": "deleted", "file_id": file_id} logger.debug("[LF] File deleted successfully") @@ -267,26 +285,27 @@ class LangflowFileService: delete_error = str(e) logger.warning( "[LF] Failed to delete file after ingestion", - extra={ - "error": delete_error, - "file_id": file_id - } + extra={"error": delete_error, "file_id": file_id}, ) - delete_result = {"status": "delete_failed", "file_id": file_id, "error": delete_error} + delete_result = { + "status": "delete_failed", + "file_id": file_id, + "error": delete_error, + } # Return combined result result = { "status": "success", "upload": upload_result, "ingestion": ingest_result, - "message": f"File '{upload_result.get('name')}' uploaded and ingested successfully" + "message": f"File '{upload_result.get('name')}' uploaded and ingested successfully", } - + if delete_after_ingest: result["deletion"] = delete_result if delete_result and delete_result.get("status") == "deleted": result["message"] += " and cleaned up" elif delete_error: result["message"] += f" (cleanup warning: {delete_error})" - + return result From ed6c4105504f5ce48173f5ab2beb751fafea7e4d Mon Sep 17 00:00:00 2001 From: Edwin Jose Date: Thu, 25 Sep 2025 18:14:11 -0400 Subject: [PATCH 2/8] Update docker-compose.yml --- docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index 67021202..be863df3 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -102,7 +102,7 @@ services: - JWT="dummy" - OPENRAG-QUERY-FILTER="{}" - OPENSEARCH_PASSWORD=${OPENSEARCH_PASSWORD} - - LANGFLOW_VARIABLES_TO_GET_FROM_ENVIRONMENT=JWT,OPENRAG-QUERY-FILTER,OPENSEARCH_PASSWORD + - LANGFLOW_VARIABLES_TO_GET_FROM_ENVIRONMENT=JWT,OPENRAG-QUERY-FILTER,OPENSEARCH_PASSWORD,OWNER,OWNER_NAME,OWNER_EMAIL,CONNECTOR_TYPE,SESSION_ID,FILE_PATH - LANGFLOW_LOG_LEVEL=DEBUG - LANGFLOW_AUTO_LOGIN=${LANGFLOW_AUTO_LOGIN} - LANGFLOW_SUPERUSER=${LANGFLOW_SUPERUSER} From 778993d64c73fb643e38d032cc1ca0317a967ab9 Mon Sep 17 00:00:00 2001 From: Edwin Jose Date: Fri, 26 Sep 2025 10:35:39 -0400 Subject: [PATCH 3/8] Update env vars and header keys for Langflow service Added OWNER, OWNER_NAME, OWNER_EMAIL, and CONNECTOR_TYPE environment variables to docker-compose.yml. Updated LANGFLOW_VARIABLES_TO_GET_FROM_ENVIRONMENT to match. Changed header keys in langflow_file_service.py to uppercase and ensured values are stringified for consistency. --- docker-compose.yml | 6 +++++- src/services/langflow_file_service.py | 14 +++++++------- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index be863df3..daa921ae 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -100,9 +100,13 @@ services: - LANGFLOW_LOAD_FLOWS_PATH=/app/flows - LANGFLOW_SECRET_KEY=${LANGFLOW_SECRET_KEY} - JWT="dummy" + - OWNER=None + - OWNER_NAME=None + - OWNER_EMAIL=None + - CONNECTOR_TYPE=system - OPENRAG-QUERY-FILTER="{}" - OPENSEARCH_PASSWORD=${OPENSEARCH_PASSWORD} - - LANGFLOW_VARIABLES_TO_GET_FROM_ENVIRONMENT=JWT,OPENRAG-QUERY-FILTER,OPENSEARCH_PASSWORD,OWNER,OWNER_NAME,OWNER_EMAIL,CONNECTOR_TYPE,SESSION_ID,FILE_PATH + - LANGFLOW_VARIABLES_TO_GET_FROM_ENVIRONMENT=JWT,OPENRAG-QUERY-FILTER,OPENSEARCH_PASSWORD,OWNER,OWNER_NAME,OWNER_EMAIL,CONNECTOR_TYPE - LANGFLOW_LOG_LEVEL=DEBUG - LANGFLOW_AUTO_LOGIN=${LANGFLOW_AUTO_LOGIN} - LANGFLOW_SUPERUSER=${LANGFLOW_SUPERUSER} diff --git a/src/services/langflow_file_service.py b/src/services/langflow_file_service.py index 63353874..39c5eac7 100644 --- a/src/services/langflow_file_service.py +++ b/src/services/langflow_file_service.py @@ -130,13 +130,13 @@ class LangflowFileService: ) # Avoid logging full payload to prevent leaking sensitive data (e.g., JWT) - headers = { - "X-Langflow-Global-Var-JWT": jwt_token, - "X-Langflow-Global-Var-Owner": owner, - "X-Langflow-Global-Var-Owner-Name": owner_name, - "X-Langflow-Global-Var-Owner-Email": owner_email, - "X-Langflow-Global-Var-Connector-Type": connector_type, - } + headers={ + "X-Langflow-Global-Var-JWT": str(jwt_token), + "X-Langflow-Global-Var-OWNER": str(owner), + "X-Langflow-Global-Var-OWNER_NAME": str(owner_name), + "X-Langflow-Global-Var-OWNER_EMAIL": str(owner_email), + "X-Langflow-Global-Var-CONNECTOR_TYPE": str(connector_type), + } resp = await clients.langflow_request( "POST", f"/api/v1/run/{self.flow_id_ingest}", json=payload, headers=headers From a7d152eca23fc5d88492a807b50644ed01e1e258 Mon Sep 17 00:00:00 2001 From: Mendon Kissling <59585235+mendonk@users.noreply.github.com> Date: Fri, 26 Sep 2025 15:59:22 -0400 Subject: [PATCH 4/8] model-selection --- docs/docs/get-started/install.mdx | 38 +++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/docs/docs/get-started/install.mdx b/docs/docs/get-started/install.mdx index 67f4ae89..1b8f625e 100644 --- a/docs/docs/get-started/install.mdx +++ b/docs/docs/get-started/install.mdx @@ -79,8 +79,42 @@ For more information on virtual environments, see [uv](https://docs.astral.sh/uv Command completed successfully ``` -7. To open the OpenRAG application, click **Open App** or press 6. -8. Continue with the Quickstart. +7. To open the OpenRAG application, click **Open App**, press 6, or navigate to `http://localhost:3000`. + The application opens. +8. Select your language model and embedding model provider, and complete the required fields. + **Your provider can only be selected once, and you must use the same provider for your language model and embedding model. + To change your selection, you must restart OpenRAG.** + + + + 9. You already entered a value for `OPENAI_API_KEY` in the TUI in Step 5, so enable **Get API key from environment variable**. + 10. Under **Advanced settings**, select your **Embedding Model** and **Language Model**. + 11. To load 2 sample PDFs, enable **Sample dataset**. + This is recommended, but not required. + 12. Click **Complete**. + + + + 9. Complete the fields for **watsonx.ai API Endpoint**, **IBM API key**, and **IBM Project ID**. + These values are found in your IBM watsonx deployment. + 10. Under **Advanced settings**, select your **Embedding Model** and **Language Model**. + 11. To load 2 sample PDFs, enable **Sample dataset**. + This is recommended, but not required. + 12. Click **Complete**. + + + + 9. Enter your Ollama server's base URL address. + The default Ollama server address is `http://localhost:11434`. + 10. Select the **Embedding Model** and **Language Model** your Ollama server is running. + 11. To load 2 sample PDFs, enable **Sample dataset**. + This is recommended, but not required. + 12. Click **Complete**. + + + + +8. Continue with the [Quickstart](/quickstart). ### Advanced Setup {#advanced-setup} From bc9f181abd7a0bc75245cb807bc64d6500645d75 Mon Sep 17 00:00:00 2001 From: Mendon Kissling <59585235+mendonk@users.noreply.github.com> Date: Fri, 26 Sep 2025 16:31:35 -0400 Subject: [PATCH 5/8] use-local-model --- docs/docs/get-started/install.mdx | 3 +++ docs/docs/get-started/quickstart.mdx | 24 ++++++++++-------------- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/docs/docs/get-started/install.mdx b/docs/docs/get-started/install.mdx index 1b8f625e..68a935fa 100644 --- a/docs/docs/get-started/install.mdx +++ b/docs/docs/get-started/install.mdx @@ -106,7 +106,10 @@ For more information on virtual environments, see [uv](https://docs.astral.sh/uv 9. Enter your Ollama server's base URL address. The default Ollama server address is `http://localhost:11434`. + Since OpenRAG is running in a container, you may need to change `localhost` to access services outside of the container. For example, change `http://localhost:11434` to `http://host.docker.internal:11434` to connect to Ollama. + OpenRAG automatically sends a test connection to your Ollama server to confirm connectivity. 10. Select the **Embedding Model** and **Language Model** your Ollama server is running. + OpenRAG automatically lists the available models from your Ollama server. 11. To load 2 sample PDFs, enable **Sample dataset**. This is recommended, but not required. 12. Click **Complete**. diff --git a/docs/docs/get-started/quickstart.mdx b/docs/docs/get-started/quickstart.mdx index 68d15aef..27361200 100644 --- a/docs/docs/get-started/quickstart.mdx +++ b/docs/docs/get-started/quickstart.mdx @@ -11,17 +11,21 @@ Get started with OpenRAG by loading your knowledge, swapping out your language m ## Prerequisites -- Install and start OpenRAG +- [Install and start OpenRAG](/install) +- [Langflow API key](/) ## Find your way around 1. In OpenRAG, click