a7d6d88f6f
CI / changes (push) Has been cancelled
CI / cd libs/checkpoint (push) Has been cancelled
CI / cd libs/checkpoint-conformance (push) Has been cancelled
CI / cd libs/checkpoint-postgres (push) Has been cancelled
CI / cd libs/checkpoint-sqlite (push) Has been cancelled
CI / cd libs/cli (push) Has been cancelled
CI / cd libs/prebuilt (push) Has been cancelled
CI / cd libs/sdk-py (push) Has been cancelled
CI / cd libs/langgraph (push) Has been cancelled
CI / Check SDK methods matching (push) Has been cancelled
CI / Check CLI schema hasn't changed #3.13 (push) Has been cancelled
CI / CLI integration test (push) Has been cancelled
CI / sdk-py integration test (push) Has been cancelled
CI / CI Success (push) Has been cancelled
baseline / benchmark (push) Has been cancelled
Deploy Redirects to GitHub Pages / deploy (push) Has been cancelled
106 lines
2.6 KiB
Python
106 lines
2.6 KiB
Python
import functools
|
|
import json
|
|
import os
|
|
import pathlib
|
|
import platform
|
|
import threading
|
|
import urllib.error
|
|
import urllib.request
|
|
from typing import Any, TypedDict
|
|
|
|
from langgraph_cli.constants import (
|
|
DEFAULT_CONFIG,
|
|
DEFAULT_PORT,
|
|
SUPABASE_PUBLIC_API_KEY,
|
|
SUPABASE_URL,
|
|
)
|
|
from langgraph_cli.version import __version__
|
|
|
|
|
|
class LogData(TypedDict):
|
|
os: str
|
|
os_version: str
|
|
python_version: str
|
|
cli_version: str
|
|
cli_command: str
|
|
params: dict[str, Any]
|
|
|
|
|
|
def get_anonymized_params(
|
|
kwargs: dict[str, Any], *, cli_command: str
|
|
) -> dict[str, bool | str]:
|
|
params: dict[str, bool | str] = {}
|
|
|
|
if cli_command == "deploy" and (
|
|
analytics_source := os.getenv("LANGGRAPH_CLI_ANALYTICS_SOURCE")
|
|
):
|
|
params["source"] = analytics_source
|
|
|
|
# anonymize params with values
|
|
if config := kwargs.get("config"):
|
|
if config != pathlib.Path(DEFAULT_CONFIG).resolve():
|
|
params["config"] = True
|
|
|
|
if port := kwargs.get("port"):
|
|
if port != DEFAULT_PORT:
|
|
params["port"] = True
|
|
|
|
if kwargs.get("docker_compose"):
|
|
params["docker_compose"] = True
|
|
|
|
if kwargs.get("debugger_port"):
|
|
params["debugger_port"] = True
|
|
|
|
if kwargs.get("postgres_uri"):
|
|
params["postgres_uri"] = True
|
|
|
|
# pick up exact values for boolean flags
|
|
for boolean_param in ["recreate", "pull", "watch", "wait", "verbose"]:
|
|
if kwargs.get(boolean_param):
|
|
params[boolean_param] = kwargs[boolean_param]
|
|
|
|
return params
|
|
|
|
|
|
def log_data(data: LogData) -> None:
|
|
headers = {
|
|
"Content-Type": "application/json",
|
|
"apikey": SUPABASE_PUBLIC_API_KEY,
|
|
"User-Agent": "Mozilla/5.0",
|
|
}
|
|
supabase_url = SUPABASE_URL
|
|
|
|
req = urllib.request.Request(
|
|
f"{supabase_url}/rest/v1/logs",
|
|
data=json.dumps(data).encode("utf-8"),
|
|
headers=headers,
|
|
method="POST",
|
|
)
|
|
|
|
try:
|
|
urllib.request.urlopen(req)
|
|
except urllib.error.URLError:
|
|
pass
|
|
|
|
|
|
def log_command(func):
|
|
@functools.wraps(func)
|
|
def decorator(*args, **kwargs):
|
|
if os.getenv("LANGGRAPH_CLI_NO_ANALYTICS") == "1":
|
|
return func(*args, **kwargs)
|
|
|
|
data = {
|
|
"os": platform.system(),
|
|
"os_version": platform.version(),
|
|
"python_version": platform.python_version(),
|
|
"cli_version": __version__,
|
|
"cli_command": func.__name__,
|
|
"params": get_anonymized_params(kwargs, cli_command=func.__name__),
|
|
}
|
|
|
|
background_thread = threading.Thread(target=log_data, args=(data,))
|
|
background_thread.start()
|
|
return func(*args, **kwargs)
|
|
|
|
return decorator
|