Skip to content

Commit

Permalink
initial changes
Browse files Browse the repository at this point in the history
  • Loading branch information
tssweeney committed Dec 13, 2024
1 parent cdf6574 commit ecf543a
Show file tree
Hide file tree
Showing 9 changed files with 190 additions and 152 deletions.
8 changes: 4 additions & 4 deletions dev_docs/BaseObjectClasses.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ curl -X POST 'https://trace.wandb.ai/obj/create' \
"project_id": "user/project",
"object_id": "my_config",
"val": {...},
"set_base_object_class": "MyConfig"
"object_class": "MyConfig"
}
}'

Expand Down Expand Up @@ -162,7 +162,7 @@ Run `make synchronize-base-object-schemas` to ensure the frontend TypeScript typ
4. Now, each use case uses different parts:
1. `Python Writing`. Users can directly import these classes and use them as normal Pydantic models, which get published with `weave.publish`. The python client correct builds the requisite payload.
2. `Python Reading`. Users can `weave.ref().get()` and the weave python SDK will return the instance with the correct type. Note: we do some special handling such that the returned object is not a WeaveObject, but literally the exact pydantic class.
3. `HTTP Writing`. In cases where the client/user does not want to add the special type information, users can publish base objects by setting the `set_base_object_class` setting on `POST obj/create` to the name of the class. The weave server will validate the object against the schema, update the metadata fields, and store the object.
3. `HTTP Writing`. In cases where the client/user does not want to add the special type information, users can publish builtin objects by setting the `object_class` setting on `POST obj/create` to the name of the class. The weave server will validate the object against the schema, update the metadata fields, and store the object.
4. `HTTP Reading`. When querying for objects, the server will return the object with the correct type if the `base_object_class` metadata field is set.
5. `Frontend`. The frontend will read the zod schema from `weave-js/src/components/PagePanelComponents/Home/Browse3/pages/wfReactInterface/generatedBaseObjectClasses.zod.ts` and use that to provide compile time type safety when using `useBaseObjectInstances` and runtime type safety when using `useCreateBaseObjectInstance`.
* Note: it is critical that all techniques produce the same digest for the same data - which is tested in the tests. This way versions are not thrashed by different clients/users.
Expand All @@ -185,7 +185,7 @@ graph TD
subgraph "Trace Server"
subgraph "HTTP API"
R --> |validates using| HW["POST obj/create<br>set_base_object_class"]
R --> |validates using| HW["POST obj/create<br>object_class"]
HW --> DB[(Weave Object Store)]
HR["POST objs/query<br>base_object_classes"] --> |Filters base_object_class| DB
end
Expand All @@ -203,7 +203,7 @@ graph TD
Z --> |import| UBI["useBaseObjectInstances"]
Z --> |import| UCI["useCreateBaseObjectInstance"]
UBI --> |Filters base_object_class| HR
UCI --> |set_base_object_class| HW
UCI --> |object_class| HW
UI[React UI] --> UBI
UI --> UCI
end
Expand Down
14 changes: 7 additions & 7 deletions tests/trace/test_base_object_classes.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ def test_interface_creation(client):
"project_id": client._project_id(),
"object_id": nested_obj_id,
"val": nested_obj.model_dump(),
"set_base_object_class": "TestOnlyNestedBaseObject",
"object_class": "TestOnlyNestedBaseObject",
}
}
)
Expand All @@ -164,7 +164,7 @@ def test_interface_creation(client):
"project_id": client._project_id(),
"object_id": top_level_obj_id,
"val": top_obj.model_dump(),
"set_base_object_class": "TestOnlyExample",
"object_class": "TestOnlyExample",
}
}
)
Expand Down Expand Up @@ -271,7 +271,7 @@ def test_digest_equality(client):
"project_id": client._project_id(),
"object_id": nested_obj_id,
"val": nested_obj.model_dump(),
"set_base_object_class": "TestOnlyNestedBaseObject",
"object_class": "TestOnlyNestedBaseObject",
}
}
)
Expand Down Expand Up @@ -300,7 +300,7 @@ def test_digest_equality(client):
"project_id": client._project_id(),
"object_id": top_level_obj_id,
"val": top_obj.model_dump(),
"set_base_object_class": "TestOnlyExample",
"object_class": "TestOnlyExample",
}
}
)
Expand All @@ -322,7 +322,7 @@ def test_schema_validation(client):
"object_id": "nested_obj",
# Incorrect schema, should raise!
"val": {"a": 2},
"set_base_object_class": "TestOnlyNestedBaseObject",
"object_class": "TestOnlyNestedBaseObject",
}
}
)
Expand All @@ -340,7 +340,7 @@ def test_schema_validation(client):
"_class_name": "TestOnlyNestedBaseObject",
"_bases": ["BaseObject", "BaseModel"],
},
"set_base_object_class": "TestOnlyNestedBaseObject",
"object_class": "TestOnlyNestedBaseObject",
}
}
)
Expand All @@ -359,7 +359,7 @@ def test_schema_validation(client):
"_class_name": "TestOnlyNestedBaseObject",
"_bases": ["BaseObject", "BaseModel"],
},
"set_base_object_class": "TestOnlyExample",
"object_class": "TestOnlyExample",
}
}
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,11 +113,11 @@ export const createBaseObjectInstance = async <
req: TraceObjCreateReq<T>
): Promise<TraceObjCreateRes> => {
if (
req.obj.set_base_object_class != null &&
req.obj.set_base_object_class !== baseObjectClassName
req.obj.object_class != null &&
req.obj.object_class !== baseObjectClassName
) {
throw new Error(
`set_base_object_class must match baseObjectClassName: ${baseObjectClassName}`
`object_class must match baseObjectClassName: ${baseObjectClassName}`
);
}

Expand All @@ -138,7 +138,7 @@ export const createBaseObjectInstance = async <
...req,
obj: {
...req.obj,
set_base_object_class: baseObjectClassName,
object_class: baseObjectClassName,
},
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ export type TraceObjCreateReq<T extends any = any> = {
project_id: string;
object_id: string;
val: T;
set_base_object_class?: string;
object_class?: string;
};
};

Expand Down
121 changes: 0 additions & 121 deletions weave/trace_server/base_object_class_util.py

This file was deleted.

16 changes: 8 additions & 8 deletions weave/trace_server/clickhouse_trace_server_batched.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@
from weave.trace_server import refs_internal as ri
from weave.trace_server import trace_server_interface as tsi
from weave.trace_server.actions_worker.dispatcher import execute_batch
from weave.trace_server.base_object_class_util import process_incoming_object_val
from weave.trace_server.calls_query_builder import (
CallsQuery,
HardCodedFilter,
Expand Down Expand Up @@ -81,6 +80,7 @@
from weave.trace_server.model_providers.model_providers import (
read_model_to_provider_info_map,
)
from weave.trace_server.object_class_util import process_incoming_object_val
from weave.trace_server.orm import ParamBuilder, Row
from weave.trace_server.secret_fetcher_context import _secret_fetcher_context
from weave.trace_server.table_query_builder import (
Expand Down Expand Up @@ -563,19 +563,19 @@ def ops_query(self, req: tsi.OpQueryReq) -> tsi.OpQueryRes:
return tsi.OpQueryRes(op_objs=objs)

def obj_create(self, req: tsi.ObjCreateReq) -> tsi.ObjCreateRes:
val, base_object_class = process_incoming_object_val(
req.obj.val, req.obj.set_base_object_class
processed_result = process_incoming_object_val(
req.obj.val, req.obj.object_class
)

json_val = json.dumps(val)
processed_val = processed_result["val"]
json_val = json.dumps(processed_val)
digest = str_digest(json_val)

ch_obj = ObjCHInsertable(
project_id=req.obj.project_id,
object_id=req.obj.object_id,
kind=get_kind(val),
base_object_class=base_object_class,
refs=extract_refs_from_values(val),
kind=get_kind(processed_val),
base_object_class=processed_result["base_object_class"],
refs=extract_refs_from_values(processed_val),
val_dump=json_val,
digest=digest,
)
Expand Down
Loading

0 comments on commit ecf543a

Please sign in to comment.