From 956bc629df4151ce65b2fca8d41fc22208df050f Mon Sep 17 00:00:00 2001 From: RamGopalSrikar Date: Tue, 24 Mar 2026 15:57:51 -0400 Subject: [PATCH] chore: remove temporary dev files from gp scripts directory Remove BACKEND_STRINGS_STRATEGY.md (internal planning doc), test_auth.py (GP auth debugging script), and en.json (dev-time string snapshot). Also add venv/ to .gitignore to prevent accidental commits of the local virtualenv. --- scripts/gp/.gitignore | 1 + scripts/gp/BACKEND_STRINGS_STRATEGY.md | 123 ------------------------- scripts/gp/en.json | 12 --- scripts/gp/test_auth.py | 73 --------------- 4 files changed, 1 insertion(+), 208 deletions(-) delete mode 100644 scripts/gp/BACKEND_STRINGS_STRATEGY.md delete mode 100644 scripts/gp/en.json delete mode 100644 scripts/gp/test_auth.py diff --git a/scripts/gp/.gitignore b/scripts/gp/.gitignore index cff554307a..939f18f755 100644 --- a/scripts/gp/.gitignore +++ b/scripts/gp/.gitignore @@ -1,3 +1,4 @@ .env __pycache__/ *.pyc +venv/ diff --git a/scripts/gp/BACKEND_STRINGS_STRATEGY.md b/scripts/gp/BACKEND_STRINGS_STRATEGY.md deleted file mode 100644 index 2c90a80b1a..0000000000 --- a/scripts/gp/BACKEND_STRINGS_STRATEGY.md +++ /dev/null @@ -1,123 +0,0 @@ -# Backend Component Strings — i18n Strategy - -## The Problem - -Component names, descriptions, and category labels shown in the Langflow UI (sidebar, node headers, tooltips) come from **Python backend metadata**, not the frontend. Examples: - -- `display_name = "Chat Input"` — shown in sidebar list and node title -- `description = "Get chat inputs from the Playground."` — shown in tooltips -- `category = "input_output"` — maps to a category group - -Because these strings originate in Python and are served via the REST API, the frontend's `t()` approach cannot translate them — by the time React renders them, they're just API response strings. - ---- - -## Where These Strings Live (Backend) - -Each component is a Python class in `src/backend/base/langflow/components/`: - -```python -class ChatInput(Component): - display_name = "Chat Input" - description = "Get chat inputs from the Playground." - icon = "MessageSquare" - name = "ChatInput" -``` - -The API endpoint `/api/v1/all` returns all component metadata, including `display_name` and `description`, to the frontend. - ---- - -## Options - -### Option A: Frontend key-based lookup (Recommended for Phase 1) - -**How it works:** -- Backend sends a stable machine key alongside display_name: e.g. `"i18n_key": "component.chatInput.displayName"` -- Frontend uses `t(component.i18n_key, { defaultValue: component.display_name })` -- If the key exists in the locale file → translated string shown -- If not → falls back to the raw `display_name` from the API (graceful degradation) - -**Backend change needed:** -- Add `i18n_key` property to the Component base class, auto-derived from class name: - ```python - @property - def i18n_key(self) -> str: - return f"component.{self.__class__.__name__}.displayName" - ``` -- Include it in the `/api/v1/all` response schema - -**Frontend change needed:** -- In `sidebarDraggableComponent.tsx` and `NodeName/index.tsx`, replace: - ```tsx - {display_name} - ``` - with: - ```tsx - {t(i18n_key, { defaultValue: display_name })} - ``` - -**New keys in en.json (example):** -```json -"component.ChatInput.displayName": "Chat Input", -"component.ChatOutput.displayName": "Chat Output", -"component.TextInput.displayName": "Text Input", -"component.OpenAIModel.displayName": "OpenAI", -... -``` - -**Pros:** Graceful fallback, no big-bang migration, GP translates these like any other key. -**Cons:** ~200+ keys to add; backend must expose i18n_key in API response. - ---- - -### Option B: Accept-Language header on the API - -**How it works:** -- Frontend sends `Accept-Language: fr` header with every API request -- Backend detects language and returns translated `display_name` / `description` directly -- Frontend renders as-is, no key lookup needed - -**Backend change needed:** -- Add Python i18n library (e.g. `babel`, `python-i18n`) or call GP API server-side -- Maintain translation files for Python strings separately from frontend locale files -- Middleware to read `Accept-Language` and translate all component metadata before returning - -**Pros:** Frontend doesn't change at all; translations fully server-side. -**Cons:** Complex backend changes; two separate translation pipelines (frontend GP + backend); harder to keep in sync. - ---- - -### Option C: Skip component names (pragmatic) - -Component names like "Chat Input", "OpenAI", "FAISS" are semi-technical product names. Many localization projects treat these as untranslatable proper nouns. Translators would leave "Chat Input" as-is in French — it's an established product term. - -**When to use:** If translators confirm these don't need localization, skip entirely. - ---- - -## Recommendation - -**Phase 1 (near-term):** Go with **Option A** — add `i18n_key` to the API response, update the 5 frontend render sites to use `t(i18n_key, { defaultValue: display_name })`, add ~200 keys to en.json, upload to GP. - -**Phase 2 (later):** Evaluate whether `description` fields also need translation (they're longer, more expensive to translate). - ---- - -## Frontend Files to Update (for Option A) - -| File | What changes | -|------|-------------| -| `src/frontend/src/pages/FlowPage/components/flowSidebarComponent/components/sidebarDraggableComponent.tsx` | `{display_name}` → `{t(i18n_key, { defaultValue: display_name })}` | -| `src/frontend/src/pages/FlowPage/components/flowSidebarComponent/components/sidebarItemsList.tsx` | tooltip display_name | -| `src/frontend/src/pages/FlowPage/components/flowSidebarComponent/components/McpSidebarGroup.tsx` | mcp display_name | -| `src/frontend/src/CustomNodes/GenericNode/components/NodeName/index.tsx` | node title display_name | -| `src/frontend/src/pages/FlowPage/components/InspectionPanel/components/EditableHeaderContent.tsx` | inspection panel display_name | - -## Backend Files to Update - -| File | What changes | -|------|-------------| -| `src/backend/base/langflow/custom/custom_component/component.py` | Add `i18n_key` property | -| `src/backend/base/langflow/api/v1/endpoints.py` | Include `i18n_key` in `/api/v1/all` response | -| All component Python files | Optionally override `i18n_key` if auto-derived name isn't clean | diff --git a/scripts/gp/en.json b/scripts/gp/en.json deleted file mode 100644 index c2e153f0e9..0000000000 --- a/scripts/gp/en.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "save_button": "Save", - "cancel_button": "Cancel", - "delete_button": "Delete", - "edit_button": "Edit", - "submit_button": "Submit", - "loading": "Loading...", - "error_message": "Something went wrong. Please try again.", - "success_message": "Operation completed successfully.", - "confirm_delete": "Are you sure you want to delete this?", - "welcome": "Welcome to Langflow" -} diff --git a/scripts/gp/test_auth.py b/scripts/gp/test_auth.py deleted file mode 100644 index 57b3bee3e8..0000000000 --- a/scripts/gp/test_auth.py +++ /dev/null @@ -1,73 +0,0 @@ -"""Test GP authentication and basic API connectivity.""" - -import base64 -import hashlib -import hmac -import json -import os -from datetime import datetime, timezone - -import requests -from dotenv import load_dotenv - -load_dotenv() - - -def calulate_hmacheader(endpoint, request_type, body): - """Calculate HMAC header dynamically.""" - date = datetime.now(timezone.utc) - date_string = date.strftime("%a, %d %b %Y %H:%M:%S %Z").replace("UTC", "GMT") - - user_id = os.getenv("GP_ADMIN_USER_ID") - password = os.getenv("GP_ADMIN_PASSWORD") - - if request_type.upper() == "GET": - body = "" - msg = "GET" + "\n" + endpoint + "\n" + date_string + "\n" + body - else: - msg = request_type.upper() + "\n" + endpoint + "\n" + date_string + "\n" + json.dumps(body) - - print(f"[DEBUG] userId : {user_id}") - print(f"[DEBUG] dateString: {date_string}") - print(f"[DEBUG] endpoint : {endpoint}") - print(f"[DEBUG] msg : {msg!r}") - - message = bytes(msg, "ISO-8859-1") - password = bytes(password, "ISO-8859-1") - - signature = hmac.new(password, msg=message, digestmod=hashlib.sha1).digest() - hmac_header = "GP-HMAC " + user_id + ":" + base64.b64encode(signature).decode() - - print(f"[DEBUG] signature : {base64.b64encode(signature).decode()}") - print(f"[DEBUG] auth : {hmac_header}") - - if request_type.upper() == "PATCH": - header = { - "Authorization": hmac_header, - "GP-Date": date_string, - "accept": "application/json", - "Content-Type": "application/merge-patch+json", - } - else: - header = { - "Authorization": hmac_header, - "GP-Date": date_string, - "accept": "application/json", - } - return header - - -# Test: List bundles -GP_INSTANCE = os.getenv("GP_INSTANCE", "langflow-test") -BASE_URL = "https://g11n-pipeline-api.straker.global/translate/rest" -endpoint = f"{BASE_URL}/{GP_INSTANCE}/v2/bundles" - -print(f"[DEBUG] full URL : {endpoint}") -print() - -headers = calulate_hmacheader(endpoint, "GET", "") -print() - -response = requests.get(endpoint, headers=headers, verify=False, timeout=30) # noqa: S501 -print(f"[DEBUG] status : {response.status_code}") -print(f"[DEBUG] response : {response.json()}")