diff --git a/src/phoenix/server/api/routers/evaluation_handler.py b/src/phoenix/server/api/routers/evaluation_handler.py index bddf3d6bf9..08af30d2cc 100644 --- a/src/phoenix/server/api/routers/evaluation_handler.py +++ b/src/phoenix/server/api/routers/evaluation_handler.py @@ -27,6 +27,7 @@ class EvaluationHandler(HTTPEndpoint): async def post(self, request: Request) -> Response: content_type = request.headers.get("content-type") + project_name = request.headers.get("project-name", DEFAULT_PROJECT_NAME) if content_type == "application/x-pandas-arrow": return await self._process_pyarrow(request) if content_type != "application/x-protobuf": @@ -51,7 +52,7 @@ async def post(self, request: Request) -> Response: content="Request body is invalid", status_code=HTTP_422_UNPROCESSABLE_ENTITY, ) - self.traces.put(evaluation) + self.traces.put(evaluation, project_name=project_name) return Response() async def get(self, request: Request) -> Response: diff --git a/src/phoenix/session/client.py b/src/phoenix/session/client.py index 72c71507cf..870a101d8e 100644 --- a/src/phoenix/session/client.py +++ b/src/phoenix/session/client.py @@ -140,16 +140,19 @@ def _warn_if_phoenix_is_not_running(self) -> None: f"with `import phoenix as px; px.launch_app()`" ) - def log_evaluations(self, *evals: Evaluations) -> None: + def log_evaluations(self, *evals: Evaluations, project_name: Optional[str] = None) -> None: for evaluation in evals: table = evaluation.to_pyarrow_table() sink = pa.BufferOutputStream() + headers = {"content-type": "application/x-pandas-arrow"} + if project_name: + headers["project-name"] = project_name with pa.ipc.new_stream(sink, table.schema) as writer: writer.write_table(table) self._session.post( urljoin(self._base_url, "/v1/evaluations"), data=cast(bytes, sink.getvalue().to_pybytes()), - headers={"content-type": "application/x-pandas-arrow"}, + headers=headers, ).raise_for_status()