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

[OPIK-355] [Prompt library] SDK Prompt implementation - link with experiment #590

Merged
merged 13 commits into from
Nov 8, 2024
146 changes: 84 additions & 62 deletions sdks/python/code_generation/fern/openapi/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1187,6 +1187,10 @@ paths:
in: query
schema:
type: string
- name: truncate
in: query
schema:
type: boolean
responses:
"200":
description: Spans resource
Expand Down Expand Up @@ -1391,6 +1395,10 @@ paths:
in: query
schema:
type: string
- name: truncate
in: query
schema:
type: boolean
responses:
"200":
description: Trace resource
Expand Down Expand Up @@ -2294,6 +2302,8 @@ components:
last_updated_by:
type: string
readOnly: true
prompt_version:
$ref: '#/components/schemas/PromptVersion'
FeedbackScoreAverage:
required:
- name
Expand All @@ -2305,6 +2315,41 @@ components:
value:
type: number
readOnly: true
PromptVersion:
required:
- template
type: object
properties:
id:
type: string
description: "version unique identifier, generated if absent"
format: uuid
prompt_id:
type: string
format: uuid
readOnly: true
commit:
pattern: "^[a-zA-Z0-9]{8}$"
type: string
description: "version short unique identifier, generated if absent. it must\
\ be 8 characters long"
template:
type: string
variables:
uniqueItems: true
type: array
readOnly: true
items:
type: string
readOnly: true
created_at:
type: string
format: date-time
readOnly: true
created_by:
type: string
readOnly: true
readOnly: true
Experiment_Write:
required:
- dataset_name
Expand All @@ -2319,6 +2364,16 @@ components:
type: string
metadata:
$ref: '#/components/schemas/JsonNode_Write'
prompt_version:
$ref: '#/components/schemas/PromptVersion_Write'
PromptVersion_Write:
required:
- id
type: object
properties:
id:
type: string
format: uuid
ExperimentItemsBatch:
required:
- experiment_items
Expand Down Expand Up @@ -2414,6 +2469,8 @@ components:
last_updated_by:
type: string
readOnly: true
prompt_version:
$ref: '#/components/schemas/PromptVersion_Public'
FeedbackScoreAverage_Public:
required:
- name
Expand All @@ -2425,6 +2482,33 @@ components:
value:
type: number
readOnly: true
PromptVersion_Public:
required:
- template
type: object
properties:
id:
type: string
description: "version unique identifier, generated if absent"
format: uuid
prompt_id:
type: string
format: uuid
readOnly: true
commit:
pattern: "^[a-zA-Z0-9]{8}$"
type: string
description: "version short unique identifier, generated if absent. it must\
\ be 8 characters long"
template:
type: string
created_at:
type: string
format: date-time
readOnly: true
created_by:
type: string
readOnly: true
ErrorMessage_Public:
type: object
properties:
Expand Down Expand Up @@ -3002,41 +3086,6 @@ components:
readOnly: true
latest_version:
$ref: '#/components/schemas/PromptVersion'
PromptVersion:
required:
- template
type: object
properties:
id:
type: string
description: "version unique identifier, generated if absent"
format: uuid
prompt_id:
type: string
format: uuid
readOnly: true
commit:
pattern: "^[a-zA-Z0-9]{8}$"
type: string
description: "version short unique identifier, generated if absent. it must\
\ be 8 characters long"
template:
type: string
variables:
uniqueItems: true
type: array
readOnly: true
items:
type: string
readOnly: true
created_at:
type: string
format: date-time
readOnly: true
created_by:
type: string
readOnly: true
readOnly: true
Prompt_Write:
required:
- name
Expand Down Expand Up @@ -3156,33 +3205,6 @@ components:
type: array
items:
$ref: '#/components/schemas/PromptVersion_Public'
PromptVersion_Public:
required:
- template
type: object
properties:
id:
type: string
description: "version unique identifier, generated if absent"
format: uuid
prompt_id:
type: string
format: uuid
readOnly: true
commit:
pattern: "^[a-zA-Z0-9]{8}$"
type: string
description: "version short unique identifier, generated if absent. it must\
\ be 8 characters long"
template:
type: string
created_at:
type: string
format: date-time
readOnly: true
created_by:
type: string
readOnly: true
PromptPage_Public:
type: object
properties:
Expand Down
4 changes: 3 additions & 1 deletion sdks/python/src/opik/api_objects/experiment/experiment.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from opik.rest_api.types import experiment_item as rest_experiment_item
from . import experiment_item
from .. import helpers, constants

from ... import Prompt

LOGGER = logging.getLogger(__name__)

Expand All @@ -17,11 +17,13 @@ def __init__(
name: Optional[str],
dataset_name: str,
rest_client: rest_api_client.OpikApi,
prompt: Optional[Prompt] = None,
) -> None:
self.id = id
self.name = name
self.dataset_name = dataset_name
self._rest_client = rest_client
self.prompt = prompt

def insert(self, experiment_items: List[experiment_item.ExperimentItem]) -> None:
rest_experiment_items = [
Expand Down
13 changes: 10 additions & 3 deletions sdks/python/src/opik/api_objects/opik_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -444,30 +444,37 @@ def create_experiment(
experiment.Experiment: The newly created experiment object.
"""
id = helpers.generate_id()
metadata = None
prompt_version: Optional[Dict[str, str]] = None
prompt: Optional[Prompt] = None

if isinstance(experiment_config, Mapping):
prompt = experiment_config.pop("prompt", None)
japdubengsub marked this conversation as resolved.
Show resolved Hide resolved
if prompt is not None:
prompt_version = {"id": prompt.__internal_api__version_id__}

metadata = jsonable_encoder.jsonable_encoder(experiment_config)

elif experiment_config is not None:
LOGGER.error(
"Experiment config must be dictionary, but %s was provided. Config will not be logged.",
experiment_config,
)
metadata = None
else:
metadata = None

self._rest_client.experiments.create_experiment(
name=name,
dataset_name=dataset_name,
id=id,
metadata=metadata,
prompt_version=prompt_version,
)

experiment_ = experiment.Experiment(
id=id,
name=name,
dataset_name=dataset_name,
rest_client=self._rest_client,
prompt=prompt,
)

return experiment_
Expand Down
6 changes: 5 additions & 1 deletion sdks/python/src/opik/api_objects/prompt/prompt.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ def __init__(
self._name = new_instance.name
self._prompt = new_instance.prompt
self._commit = new_instance.commit
self.__internal_api__version_id__: str = (
new_instance.__internal_api__version_id__
)
self.__internal_api__prompt_id__: str = new_instance.__internal_api__prompt_id__

@property
Expand Down Expand Up @@ -75,7 +78,8 @@ def from_fern_prompt_version(
# will not call __init__ to avoid API calls, create new instance with __new__
prompt = cls.__new__(cls)

prompt.__internal_api__prompt_id__ = prompt_version.id
prompt.__internal_api__version_id__ = prompt_version.id
prompt.__internal_api__prompt_id__ = prompt_version.prompt_id
prompt._name = name
prompt._prompt = prompt_version.template
prompt._commit = prompt_version.commit
Expand Down
2 changes: 2 additions & 0 deletions sdks/python/src/opik/rest_api/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@
PromptVersionDetail,
PromptVersionPagePublic,
PromptVersionPublic,
PromptVersionWrite,
Span,
SpanBatch,
SpanPagePublic,
Expand Down Expand Up @@ -222,6 +223,7 @@
"PromptVersionDetail",
"PromptVersionPagePublic",
"PromptVersionPublic",
"PromptVersionWrite",
"Span",
"SpanBatch",
"SpanPagePublic",
Expand Down
9 changes: 9 additions & 0 deletions sdks/python/src/opik/rest_api/experiments/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from ..types.experiment_page_public import ExperimentPagePublic
from ..types.experiment_public import ExperimentPublic
from ..types.json_node_write import JsonNodeWrite
from ..types.prompt_version_write import PromptVersionWrite

# this is used as the default value for optional parameters
OMIT = typing.cast(typing.Any, ...)
Expand Down Expand Up @@ -81,6 +82,7 @@ def create_experiment(
id: typing.Optional[str] = OMIT,
name: typing.Optional[str] = OMIT,
metadata: typing.Optional[JsonNodeWrite] = OMIT,
prompt_version: typing.Optional[PromptVersionWrite] = OMIT,
request_options: typing.Optional[RequestOptions] = None,
) -> None:
"""
Expand All @@ -96,6 +98,8 @@ def create_experiment(

metadata : typing.Optional[JsonNodeWrite]

prompt_version : typing.Optional[PromptVersionWrite]

request_options : typing.Optional[RequestOptions]
Request-specific configuration.

Expand All @@ -120,6 +124,7 @@ def create_experiment(
"dataset_name": dataset_name,
"name": name,
"metadata": metadata,
"prompt_version": prompt_version,
},
request_options=request_options,
omit=OMIT,
Expand Down Expand Up @@ -490,6 +495,7 @@ async def create_experiment(
id: typing.Optional[str] = OMIT,
name: typing.Optional[str] = OMIT,
metadata: typing.Optional[JsonNodeWrite] = OMIT,
prompt_version: typing.Optional[PromptVersionWrite] = OMIT,
request_options: typing.Optional[RequestOptions] = None,
) -> None:
"""
Expand All @@ -505,6 +511,8 @@ async def create_experiment(

metadata : typing.Optional[JsonNodeWrite]

prompt_version : typing.Optional[PromptVersionWrite]

request_options : typing.Optional[RequestOptions]
Request-specific configuration.

Expand Down Expand Up @@ -537,6 +545,7 @@ async def main() -> None:
"dataset_name": dataset_name,
"name": name,
"metadata": metadata,
"prompt_version": prompt_version,
},
request_options=request_options,
omit=OMIT,
Expand Down
Loading
Loading