Repository navigation
feat(api): update API spec from langfuse/langfuse 3bd4817 #2002
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -190,6 +190,169 @@ def delete( | |
| _response = self._raw_client.delete(id, request_options=request_options) | ||
| return _response.data | ||
|
|
||
| def list_organization( | ||
| self, | ||
| *, | ||
| page: typing.Optional[int] = None, | ||
| limit: typing.Optional[int] = None, | ||
| request_options: typing.Optional[RequestOptions] = None, | ||
| ) -> PaginatedLlmConnections: | ||
| """ | ||
| Get all organization-level LLM connections. Requires an organization-scoped API key. | ||
|
|
||
| Parameters | ||
| ---------- | ||
| page : typing.Optional[int] | ||
| page number, starts at 1 | ||
|
|
||
| limit : typing.Optional[int] | ||
| limit of items per page | ||
|
|
||
| request_options : typing.Optional[RequestOptions] | ||
| Request-specific configuration. | ||
|
|
||
| Returns | ||
| ------- | ||
| PaginatedLlmConnections | ||
|
|
||
| Examples | ||
| -------- | ||
| from langfuse import LangfuseAPI | ||
|
|
||
| client = LangfuseAPI( | ||
| x_langfuse_sdk_name="YOUR_X_LANGFUSE_SDK_NAME", | ||
| x_langfuse_sdk_version="YOUR_X_LANGFUSE_SDK_VERSION", | ||
| x_langfuse_public_key="YOUR_X_LANGFUSE_PUBLIC_KEY", | ||
| username="YOUR_USERNAME", | ||
| password="YOUR_PASSWORD", | ||
| base_url="https://yourhost.com/path/to/api", | ||
| ) | ||
| client.llm_connections.list_organization() | ||
| """ | ||
| _response = self._raw_client.list_organization( | ||
| page=page, limit=limit, request_options=request_options | ||
| ) | ||
| return _response.data | ||
|
|
||
| def upsert_organization( | ||
| self, | ||
| *, | ||
| provider: str, | ||
| adapter: LlmAdapter, | ||
| secret_key: str, | ||
| base_url: typing.Optional[str] = OMIT, | ||
| custom_models: typing.Optional[typing.Sequence[str]] = OMIT, | ||
| with_default_models: typing.Optional[bool] = OMIT, | ||
| extra_headers: typing.Optional[typing.Dict[str, str]] = OMIT, | ||
| config: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, | ||
| request_options: typing.Optional[RequestOptions] = None, | ||
| ) -> LlmConnection: | ||
| """ | ||
| Create or update an organization-level LLM connection. The connection is upserted on provider and inherited by projects without a provider override. Requires an organization-scoped API key. | ||
|
|
||
| Parameters | ||
| ---------- | ||
| provider : str | ||
| Provider name (e.g., 'openai', 'my-gateway'). Must be unique in project, used for upserting. | ||
|
|
||
| adapter : LlmAdapter | ||
| The adapter used to interface with the LLM | ||
|
|
||
| secret_key : str | ||
| Secret key for the LLM API. | ||
|
|
||
| base_url : typing.Optional[str] | ||
| Custom base URL for the LLM API | ||
|
|
||
| custom_models : typing.Optional[typing.Sequence[str]] | ||
| List of custom model names | ||
|
|
||
| with_default_models : typing.Optional[bool] | ||
| Whether to include default models. Default is true. | ||
|
|
||
| extra_headers : typing.Optional[typing.Dict[str, str]] | ||
| Extra headers to send with requests | ||
|
|
||
| config : typing.Optional[typing.Dict[str, typing.Any]] | ||
| Adapter-specific configuration. Validation rules: - **Bedrock**: Required. Must be `{"region": "<aws-region>"}` (e.g., `{"region":"us-east-1"}`) - **OpenAI**: Optional. If provided, must be `{"useResponsesApi": <boolean>}` to control whether Langfuse routes calls through OpenAI's Responses API. - **VertexAI**: Optional. If provided, must be `{"location": "<gcp-location>"}` (e.g., `{"location":"us-central1"}`) - **Other adapters**: Not supported. Omit this field or set to null. | ||
|
|
||
| request_options : typing.Optional[RequestOptions] | ||
| Request-specific configuration. | ||
|
|
||
| Returns | ||
| ------- | ||
| LlmConnection | ||
|
|
||
| Examples | ||
| -------- | ||
| from langfuse import LangfuseAPI | ||
| from langfuse.llm_connections import LlmAdapter | ||
|
Comment on lines
+288
to
+289
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The new examples import Use Prompt To Fix With AIThis is a comment left during a code review.
Path: langfuse/api/llm_connections/client.py
Line: 288-289
Comment:
**New examples fail to import**
The new examples import `LangfuseAPI` and `AsyncLangfuseAPI` from `langfuse`, but those classes are exported from `langfuse.api`. The upsert examples also import `LlmAdapter` from the nonexistent `langfuse.llm_connections` package. Copying these examples fails before sending a request.
Use `from langfuse.api import LangfuseAPI` (or `AsyncLangfuseAPI`) and `from langfuse.api.llm_connections import LlmAdapter` throughout the new examples.
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly. |
||
|
|
||
| client = LangfuseAPI( | ||
| x_langfuse_sdk_name="YOUR_X_LANGFUSE_SDK_NAME", | ||
| x_langfuse_sdk_version="YOUR_X_LANGFUSE_SDK_VERSION", | ||
| x_langfuse_public_key="YOUR_X_LANGFUSE_PUBLIC_KEY", | ||
| username="YOUR_USERNAME", | ||
| password="YOUR_PASSWORD", | ||
| base_url="https://yourhost.com/path/to/api", | ||
| ) | ||
| client.llm_connections.upsert_organization( | ||
| provider="provider", | ||
| adapter=LlmAdapter.ANTHROPIC, | ||
| secret_key="secretKey", | ||
| ) | ||
| """ | ||
| _response = self._raw_client.upsert_organization( | ||
| provider=provider, | ||
| adapter=adapter, | ||
| secret_key=secret_key, | ||
| base_url=base_url, | ||
| custom_models=custom_models, | ||
| with_default_models=with_default_models, | ||
| extra_headers=extra_headers, | ||
| config=config, | ||
| request_options=request_options, | ||
| ) | ||
| return _response.data | ||
|
|
||
| def delete_organization( | ||
| self, id: str, *, request_options: typing.Optional[RequestOptions] = None | ||
| ) -> DeleteLlmConnectionResponse: | ||
| """ | ||
| Delete an organization-level LLM connection by id. Evaluators in projects without an override for the provider are automatically paused. Requires an organization-scoped API key. | ||
|
|
||
| Parameters | ||
| ---------- | ||
| id : str | ||
|
|
||
| request_options : typing.Optional[RequestOptions] | ||
| Request-specific configuration. | ||
|
|
||
| Returns | ||
| ------- | ||
| DeleteLlmConnectionResponse | ||
|
|
||
| Examples | ||
| -------- | ||
| from langfuse import LangfuseAPI | ||
|
|
||
| client = LangfuseAPI( | ||
| x_langfuse_sdk_name="YOUR_X_LANGFUSE_SDK_NAME", | ||
| x_langfuse_sdk_version="YOUR_X_LANGFUSE_SDK_VERSION", | ||
| x_langfuse_public_key="YOUR_X_LANGFUSE_PUBLIC_KEY", | ||
| username="YOUR_USERNAME", | ||
| password="YOUR_PASSWORD", | ||
| base_url="https://yourhost.com/path/to/api", | ||
| ) | ||
| client.llm_connections.delete_organization( | ||
| id="id", | ||
| ) | ||
| """ | ||
| _response = self._raw_client.delete_organization( | ||
| id, request_options=request_options | ||
| ) | ||
| return _response.data | ||
|
|
||
|
|
||
| class AsyncLlmConnectionsClient: | ||
| def __init__(self, *, client_wrapper: AsyncClientWrapper): | ||
|
|
@@ -390,3 +553,190 @@ async def main() -> None: | |
| """ | ||
| _response = await self._raw_client.delete(id, request_options=request_options) | ||
| return _response.data | ||
|
|
||
| async def list_organization( | ||
| self, | ||
| *, | ||
| page: typing.Optional[int] = None, | ||
| limit: typing.Optional[int] = None, | ||
| request_options: typing.Optional[RequestOptions] = None, | ||
| ) -> PaginatedLlmConnections: | ||
| """ | ||
| Get all organization-level LLM connections. Requires an organization-scoped API key. | ||
|
|
||
| Parameters | ||
| ---------- | ||
| page : typing.Optional[int] | ||
| page number, starts at 1 | ||
|
|
||
| limit : typing.Optional[int] | ||
| limit of items per page | ||
|
|
||
| request_options : typing.Optional[RequestOptions] | ||
| Request-specific configuration. | ||
|
|
||
| Returns | ||
| ------- | ||
| PaginatedLlmConnections | ||
|
|
||
| Examples | ||
| -------- | ||
| import asyncio | ||
|
|
||
| from langfuse import AsyncLangfuseAPI | ||
|
|
||
| client = AsyncLangfuseAPI( | ||
| x_langfuse_sdk_name="YOUR_X_LANGFUSE_SDK_NAME", | ||
| x_langfuse_sdk_version="YOUR_X_LANGFUSE_SDK_VERSION", | ||
| x_langfuse_public_key="YOUR_X_LANGFUSE_PUBLIC_KEY", | ||
| username="YOUR_USERNAME", | ||
| password="YOUR_PASSWORD", | ||
| base_url="https://yourhost.com/path/to/api", | ||
| ) | ||
|
|
||
|
|
||
| async def main() -> None: | ||
| await client.llm_connections.list_organization() | ||
|
|
||
|
|
||
| asyncio.run(main()) | ||
| """ | ||
| _response = await self._raw_client.list_organization( | ||
| page=page, limit=limit, request_options=request_options | ||
| ) | ||
| return _response.data | ||
|
|
||
| async def upsert_organization( | ||
| self, | ||
| *, | ||
| provider: str, | ||
| adapter: LlmAdapter, | ||
| secret_key: str, | ||
| base_url: typing.Optional[str] = OMIT, | ||
| custom_models: typing.Optional[typing.Sequence[str]] = OMIT, | ||
| with_default_models: typing.Optional[bool] = OMIT, | ||
| extra_headers: typing.Optional[typing.Dict[str, str]] = OMIT, | ||
| config: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, | ||
| request_options: typing.Optional[RequestOptions] = None, | ||
| ) -> LlmConnection: | ||
| """ | ||
| Create or update an organization-level LLM connection. The connection is upserted on provider and inherited by projects without a provider override. Requires an organization-scoped API key. | ||
|
|
||
| Parameters | ||
| ---------- | ||
| provider : str | ||
| Provider name (e.g., 'openai', 'my-gateway'). Must be unique in project, used for upserting. | ||
|
|
||
| adapter : LlmAdapter | ||
| The adapter used to interface with the LLM | ||
|
|
||
| secret_key : str | ||
| Secret key for the LLM API. | ||
|
|
||
| base_url : typing.Optional[str] | ||
| Custom base URL for the LLM API | ||
|
|
||
| custom_models : typing.Optional[typing.Sequence[str]] | ||
| List of custom model names | ||
|
|
||
| with_default_models : typing.Optional[bool] | ||
| Whether to include default models. Default is true. | ||
|
|
||
| extra_headers : typing.Optional[typing.Dict[str, str]] | ||
| Extra headers to send with requests | ||
|
|
||
| config : typing.Optional[typing.Dict[str, typing.Any]] | ||
| Adapter-specific configuration. Validation rules: - **Bedrock**: Required. Must be `{"region": "<aws-region>"}` (e.g., `{"region":"us-east-1"}`) - **OpenAI**: Optional. If provided, must be `{"useResponsesApi": <boolean>}` to control whether Langfuse routes calls through OpenAI's Responses API. - **VertexAI**: Optional. If provided, must be `{"location": "<gcp-location>"}` (e.g., `{"location":"us-central1"}`) - **Other adapters**: Not supported. Omit this field or set to null. | ||
|
|
||
| request_options : typing.Optional[RequestOptions] | ||
| Request-specific configuration. | ||
|
|
||
| Returns | ||
| ------- | ||
| LlmConnection | ||
|
|
||
| Examples | ||
| -------- | ||
| import asyncio | ||
|
|
||
| from langfuse import AsyncLangfuseAPI | ||
| from langfuse.llm_connections import LlmAdapter | ||
|
|
||
| client = AsyncLangfuseAPI( | ||
| x_langfuse_sdk_name="YOUR_X_LANGFUSE_SDK_NAME", | ||
| x_langfuse_sdk_version="YOUR_X_LANGFUSE_SDK_VERSION", | ||
| x_langfuse_public_key="YOUR_X_LANGFUSE_PUBLIC_KEY", | ||
| username="YOUR_USERNAME", | ||
| password="YOUR_PASSWORD", | ||
| base_url="https://yourhost.com/path/to/api", | ||
| ) | ||
|
|
||
|
|
||
| async def main() -> None: | ||
| await client.llm_connections.upsert_organization( | ||
| provider="provider", | ||
| adapter=LlmAdapter.ANTHROPIC, | ||
| secret_key="secretKey", | ||
| ) | ||
|
|
||
|
|
||
| asyncio.run(main()) | ||
| """ | ||
| _response = await self._raw_client.upsert_organization( | ||
| provider=provider, | ||
| adapter=adapter, | ||
| secret_key=secret_key, | ||
| base_url=base_url, | ||
| custom_models=custom_models, | ||
| with_default_models=with_default_models, | ||
| extra_headers=extra_headers, | ||
| config=config, | ||
| request_options=request_options, | ||
| ) | ||
| return _response.data | ||
|
|
||
| async def delete_organization( | ||
| self, id: str, *, request_options: typing.Optional[RequestOptions] = None | ||
| ) -> DeleteLlmConnectionResponse: | ||
| """ | ||
| Delete an organization-level LLM connection by id. Evaluators in projects without an override for the provider are automatically paused. Requires an organization-scoped API key. | ||
|
|
||
| Parameters | ||
| ---------- | ||
| id : str | ||
|
|
||
| request_options : typing.Optional[RequestOptions] | ||
| Request-specific configuration. | ||
|
|
||
| Returns | ||
| ------- | ||
| DeleteLlmConnectionResponse | ||
|
|
||
| Examples | ||
| -------- | ||
| import asyncio | ||
|
|
||
| from langfuse import AsyncLangfuseAPI | ||
|
|
||
| client = AsyncLangfuseAPI( | ||
| x_langfuse_sdk_name="YOUR_X_LANGFUSE_SDK_NAME", | ||
| x_langfuse_sdk_version="YOUR_X_LANGFUSE_SDK_VERSION", | ||
| x_langfuse_public_key="YOUR_X_LANGFUSE_PUBLIC_KEY", | ||
| username="YOUR_USERNAME", | ||
| password="YOUR_PASSWORD", | ||
| base_url="https://yourhost.com/path/to/api", | ||
| ) | ||
|
|
||
|
|
||
| async def main() -> None: | ||
| await client.llm_connections.delete_organization( | ||
| id="id", | ||
| ) | ||
|
|
||
|
|
||
| asyncio.run(main()) | ||
| """ | ||
| _response = await self._raw_client.delete_organization( | ||
| id, request_options=request_options | ||
| ) | ||
| return _response.data | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The new
upsert_organizationdocumentation saysprovidermust be unique in a project, although this method updates a connection shared across the organization. Users get conflicting guidance about which connection a repeated provider name updates.Change this to organization-wide uniqueness in both clients and their raw counterparts.
Prompt To Fix With AI
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!