Files
zeekay d650dd60f0 refactor(rebrand): langflow->flow across docs, starter-project data, CI, tests
Docs corpus (Langflow->Hanzo Flow, upstream URLs langflow-ai/langflow->hanzoai/
flow, docs.langflow.org->docs.hanzo.ai), starter-project template help-URLs, CI
workflows, and test files. Remaining 'langflow' repo-wide is now dominated by
LANGFLOW_* env-var names + langflow_ settings fields — the config-boundary layer
deliberately preserved pending a coordinated FLOW_/HANZO_ alias-with-fallback
(renaming them blind breaks every deployment).
2026-07-16 10:00:51 -07:00

101 lines
3.1 KiB
Python

"""GP (Globalization Pipeline) REST API client.
Handles HMAC authentication and common API operations.
"""
import base64
import hashlib
import hmac
import json
import os
from datetime import datetime, timezone
import requests
from dotenv import load_dotenv
load_dotenv()
BASE_URL = "https://g11n-pipeline-api.straker.global/translate/rest"
GP_USER_ID = os.getenv("GP_ADMIN_USER_ID")
GP_PASSWORD = os.getenv("GP_ADMIN_PASSWORD")
GP_INSTANCE = os.getenv("GP_INSTANCE", "flow-test")
GP_BUNDLE = os.getenv("GP_BUNDLE", "flow-ui")
TARGET_LANGS = ["fr", "ja", "es", "de", "pt", "zh-Hans"]
REQUEST_TIMEOUT = 30
VERIFY_SSL = os.getenv("GP_VERIFY_SSL", "true").lower() != "false"
def get_headers(url, method, body=None):
"""Generate GP-HMAC auth headers. url must be the full URL."""
date = datetime.now(timezone.utc)
date_string = date.strftime("%a, %d %b %Y %H:%M:%S %Z").replace("UTC", "GMT")
if method.upper() == "GET":
msg = "GET" + "\n" + url + "\n" + date_string + "\n"
else:
msg = method.upper() + "\n" + url + "\n" + date_string + "\n" + json.dumps(body)
message = bytes(msg, "ISO-8859-1")
password = bytes(GP_PASSWORD, "ISO-8859-1")
signature = hmac.new(password, msg=message, digestmod=hashlib.sha1).digest()
hmac_header = "GP-HMAC " + GP_USER_ID + ":" + base64.b64encode(signature).decode()
headers = {
"Authorization": hmac_header,
"GP-Date": date_string,
"accept": "application/json",
}
if method.upper() == "PATCH":
headers["Content-Type"] = "application/merge-patch+json"
elif method.upper() in ("PUT", "POST"):
headers["Content-Type"] = "application/json"
return headers
def list_bundles():
"""List all bundles in the GP instance."""
url = f"{BASE_URL}/{GP_INSTANCE}/v2/bundles"
response = requests.get(url, headers=get_headers(url, "GET"), verify=VERIFY_SSL, timeout=REQUEST_TIMEOUT)
response.raise_for_status()
return response.json()
def create_bundle(source_lang="en"):
"""Create a new bundle in GP."""
url = f"{BASE_URL}/{GP_INSTANCE}/v2/bundles/{GP_BUNDLE}"
body = {"sourceLanguage": source_lang, "targetLanguages": TARGET_LANGS}
response = requests.put(
url,
headers=get_headers(url, "PUT", body),
json=body,
verify=VERIFY_SSL,
timeout=REQUEST_TIMEOUT,
)
response.raise_for_status()
return response.json()
def upload_strings(strings, lang="en"):
"""Upload resource strings for a language to GP."""
url = f"{BASE_URL}/{GP_INSTANCE}/v2/bundles/{GP_BUNDLE}/{lang}"
response = requests.put(
url,
headers=get_headers(url, "PUT", strings),
json=strings,
verify=VERIFY_SSL,
timeout=REQUEST_TIMEOUT,
)
response.raise_for_status()
return response.json()
def get_strings(lang):
"""Download translated strings for a language from GP."""
url = f"{BASE_URL}/{GP_INSTANCE}/v2/bundles/{GP_BUNDLE}/{lang}"
response = requests.get(url, headers=get_headers(url, "GET"), verify=VERIFY_SSL, timeout=REQUEST_TIMEOUT)
response.raise_for_status()
return response.json()