Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

draft: programmatically managing workspaces #609

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ node_modules
build
.docusaurus
docs/api
docs/evaluation
docs/evaluation
docs/administration/concepts
83 changes: 83 additions & 0 deletions docs/administration/concepts/index.mdx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { CodeTabs } from "@site/src/components/InstructionsWithCode";

# Concepts

This conceptual guide covers topics related to managing users, organizations, and workspaces within LangSmith.
Expand Down Expand Up @@ -184,6 +186,87 @@ Use [resource tags](#resource-tags) to organize resources by environment using t
permissions when we release attribute based access control (ABAC). ABAC on the resource tag will provide a fine-grained way to restrict access to production tracing projects, for example. We do not recommend that you use Workspaces for environment separation as you cannot share resources
across Workspaces. If you would like to promote a prompt from `staging` to `prod`, we recommend you use prompt tags instead. See [docs](../prompt_engineering/concepts#tags) for more information.

### Programmatically Managing Workspaces
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think a better title would be Programmatically Operating Across Workspaces or similar, since these aren't management actions, they're just standard SDK usage for the most part (minus the workspace creation)

:::info
A PAT associated with an organization admin has access to all resources within an organization. Ensure this token is only provided sparingly when organization-wide permissions is required. We also recommend rotating this PAT periodically as a security best practice.
:::

Use a [personal access token](./concepts#personal-access-tokens-pats) (PAT) associated with an [organization admin](./how_to_guides/organization_management/set_up_organization#organization-roles) to programmatically create [workspaces](./concepts#workspaces). To create a PAT, follow this [how to guide](../administration/how_to_guides/organization_management/create_account_api_key#create-an-api-key). This PAT can also be used to manage resources across your organization's workspaces (e.g. creating and deleting tracing projects, datasets, prompts, etc.).
By default, the PAT will target the workspace it was created in. To manage resources in a workspace different from the default, you can specify the desired workspace ID in the client declaration. The sample code
shows how to both create a workspace and manage resources across workspaces using an organization admin's PAT.

<CodeTabs
tabs={[
{
value: "python",
label: "Python",
language: "python",
content: `from dotenv import load_dotenv
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you include submitting a run to each workspace as well?
@hinthornw I think you've sent over code snippets for this use case, anything missing?

import requests
import langsmith as ls
from langsmith import Client
from langchain_core.prompts import ChatPromptTemplate
import os

load_dotenv()

api_key = os.environ["LANGCHAIN_API_KEY"]
organization_id = os.environ["LANGCHAIN_ORGANIZATION_ID"]
base_url = os.environ.get("LANGCHAIN_ENDPOINT") or "https://api.smith.langchain.com"

# Set headers for API request
headers = {
"Content-Type": "application/json",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: indentation

"X-API-Key": api_key,
"X-Organization-Id": organization_id,
}

session = requests.Session()
session.headers.update(headers)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe include a note that this session is shared across the SDK (pretty certain that's the case?), so be careful to avoid operating on the wrong workspace

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"

# Programmatically create a workspace
workspace_res = session.post(workspaces_path, json={"display_name": "Test Admin Workspace"})
workspace_res.raise_for_status()
workspace = workspace_res.json()
workspace_id = workspace["id"]

print("successfully created workspace with id:", workspace_id)

# Initialize LangSmith client
client = Client()

# Create a tracing project in the default workspace
project_name = "example tracing project"
project = client.create_project(project_name=project_name)

# Create a prompt in the default workspace
prompt = ChatPromptTemplate.from_template("tell me a joke about {topic}")
url = client.push_prompt("example-joke-prompt", object=prompt)

print("Successfully created prompt and tracing project in default workspace", project.id, url)

# Specify new workspace id
session.headers.update({"X-Tenant-Id": "<YOUR_WORKSPACE_ID>"})
client = ls.Client(session=session)

# Create a tracing project in the new workspace
project_name = "example tracing project"
project = client.create_project(project_name=project_name)

# Create a prompt in the new workspace
prompt = ChatPromptTemplate.from_template("tell me a joke about {topic}")
url = client.push_prompt("example-joke-prompt", object=prompt)

print("Successfully created prompt and tracing project in new workspace", project.id, url)
`,
},
]}
groupId="client-language"
/>

## Usage and Billing

### Data Retention
Expand Down
Loading