langchain-ai / langsmith-sdk

LangSmith Client SDK Implementations
https://smith.langchain.com/
MIT License
387 stars 71 forks source link

[Python] Make RunTree.copy() shallow #778

Closed hinthornw closed 1 week ago

hinthornw commented 3 months ago

Pydantic does some fun things where they decide they'll deep copy a model when you do .copy() if you have fields that are excluded.

from pydantic import BaseModel, Field

class Foo1(BaseModel):
    a: dict
    b: str

class Foo2(BaseModel):
    a: dict
    b: str = Field(exclude=True)

a = Foo1(a={"a": 1, "b": 2}, b="hello")
b = a.copy()
print(id(a.a) == id(b.a))  # True

c = Foo2(a={"a": 1, "b": 2}, b="hello")
d = c.copy()
print(id(c.a) == id(d.a))  # False

This usually isn't a problem but can be annoying if you have something like a generator in your inputs dict (where deep copying then would raise an exception), and it has a perf penalty.

This PR addresses this. It also lets us lazily initilaize the client so we can use a RunTree as a stand-in for a Run object in lagnchain and only ever actually get the API key validated / client created if we do enable tracing or try to access the client