Skip to main content
LangSmith的API支持通过API密钥以编程方式访问UI中所有可用的操作,只有少数例外,这些例外已在仅用户端点中注明。
在深入阅读此内容之前,阅读以下内容可能有所帮助:
一些限制将很快被解除:
  • LangSmith SDKs 目前不支持这些组织管理操作。
  • 拥有组织管理员权限的 服务密钥 可以用于这些操作。
使用 X-Tenant-Id 标头指定要针对哪个工作区。如果该标头不存在,操作将默认为API密钥最初创建的工作区,除非它是组织范围的。如果在使用组织范围API密钥访问工作区范围资源时未指定 X-Tenant-Id,请求将因 403 Forbidden 而失败。
以下列出了一些常用的端点和用例。要查看所有可用端点的完整列表,请参阅API 文档所有请求中应包含 X-Organization-Id 标头,而特定工作区范围内的请求应包含 X-Tenant-Id 标头。

工作区

用户管理

基于角色的访问控制 (RBAC)

会员管理

RBAC 下使用 List roles 来检索这些操作的角色 ID。以下 List [organization|workspace] members 端点(如下)的响应 "id" 应用于这些操作的 identity_id 组织级别: 工作区级别:
以下参数应省略:read_only(已弃用)、passwordfull_name(仅基本认证

API密钥

安全设置

在此上下文中,“共享资源”指的是公共提示共享运行共享数据集
更新这些设置会影响组织中的所有资源
您可以在工作空间的 设置 > 共享 选项卡下更新这些设置,或通过 API 进行更新:
  • 更新组织共享设置
    • 使用 unshare_all 取消组织内 所有 共享资源的共享 - 使用 disable_public_sharing 防止未来共享资源

仅用户端点

这些端点是用户范围的,需要登录用户的JWT,因此它们只能通过UI执行。
  • /api-key/current 端点:这些端点与用户的 PAT 相关
  • /sso/email-verification/send(仅限云):此端点与 SAML SSO 相关

示例代码

以下示例代码演示了与组织管理相关的几个常见工作流程。请确保在代码中所有出现 <replace_me> 的地方进行必要的替换。
import os
import requests

def main():
    api_key = os.environ["LANGSMITH_API_KEY"]
    # LANGSMITH_ORGANIZATION_ID is not a standard environment variable in the SDK, just used for this example
    organization_id = os.environ["LANGSMITH_ORGANIZATION_ID"]
    base_url = os.environ.get("LANGSMITH_ENDPOINT")  # or "https://api.smith.langchain.com". Update appropriately for self-hosted installations or the EU region
    headers = {
        "Content-Type": "application/json",
        "X-API-Key": api_key,
        "X-Organization-Id": organization_id,
    }
    session = requests.Session()
    session.headers.update(headers)
    workspaces_path = f"{base_url}/api/v1/workspaces"
    orgs_path = f"{base_url}/api/v1/orgs/current"
    api_keys_path = f"{base_url}/api/v1/api-key"

    # Create a workspace
    workspace_res = session.post(workspaces_path, json={"display_name": "My Workspace"})
    workspace_res.raise_for_status()
    workspace = workspace_res.json()
    workspace_id = workspace["id"]
    new_workspace_headers = {
        "X-Tenant-Id": workspace_id,
    }

    # Grab roles - this includes both organization and workspace roles
    roles_res = session.get(f"{orgs_path}/roles")
    roles_res.raise_for_status()
    roles = roles_res.json()
    # system org roles are 'Organization Admin', 'Organization User'
    # system workspace roles are 'Admin', 'Editor', 'Viewer'
    org_roles_by_name = {role["display_name"]: role for role in roles if role["access_scope"] == "organization"}
    ws_roles_by_name = {role["display_name"]: role for role in roles if role["access_scope"] == "workspace"}

    # Invite a user to the org and the new workspace, as an Editor.
    # workspace_role_id is only allowed if RBAC is enabled (an enterprise feature).
    new_user_email = "<replace_me>"
    new_user_res = session.post(
        f"{orgs_path}/members",
        json={
            "email": new_user_email,
            "role_id": org_roles_by_name["Organization User"]["id"],
            "workspace_ids": [workspace_id],
            "workspace_role_id": ws_roles_by_name["Editor"]["id"],
        },
    )
    new_user_res.raise_for_status()

    # Add a user that already exists in the org to the new workspace, as a Viewer.
    # workspace_role_id is only allowed if RBAC is enabled (an enterprise feature).
    existing_user_email = "<replace_me>"
    org_members_res = session.get(f"{orgs_path}/members")
    org_members_res.raise_for_status()
    org_members = org_members_res.json()
    existing_org_member = next(
        (member for member in org_members["members"] if member["email"] == existing_user_email), None
    )
    existing_user_res = session.post(
        f"{workspaces_path}/current/members",
        json={
            "user_id": existing_org_member["user_id"],
            "workspace_ids": [workspace_id],
            "workspace_role_id": ws_roles_by_name["Viewer"]["id"],
        },
        headers=new_workspace_headers,
    )
    existing_user_res.raise_for_status()

    # List all members of the workspace
    members_res = session.get(f"{workspaces_path}/current/members", headers=new_workspace_headers)
    members_res.raise_for_status()
    members = members_res.json()
    workspace_member = next(
        (member for member in members["members"] if member["email"] == existing_user_email), None
    )

    # Update the user's workspace role to Admin (enterprise-only)
    existing_user_id = workspace_member["id"]
    update_res = session.patch(
        f"{workspaces_path}/current/members/{existing_user_id}",
        json={"role_id": ws_roles_by_name["Admin"]["id"]},
        headers=new_workspace_headers,
    )
    update_res.raise_for_status()

    # Update the user's organization role to Organization Admin
    update_res = session.patch(
        f"{orgs_path}/members/{existing_org_member['id']}",
        json={"role_id": org_roles_by_name["Organization Admin"]["id"]},
    )
    update_res.raise_for_status()

    # Create a new Service key
    api_key_res = session.post(
        api_keys_path,
        json={"description": "my key"},
        headers=new_workspace_headers,
    )
    api_key_res.raise_for_status()
    api_key_json = api_key_res.json()
    api_key = api_key_json["key"]

if __name__ == "__main__":
    main()