Skip to content

Commit cc567ed

Browse files
authored
Merge pull request #2 from explodinggradients/feat/vanilla-exp
added experiment without langfuse
2 parents c14f806 + 38ed298 commit cc567ed

File tree

7 files changed

+140
-59
lines changed

7 files changed

+140
-59
lines changed

README.md

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,6 @@ $ pip install ragas_annotator
2222

2323
## Getting Started
2424

25-
Fill me in please! Don’t forget code examples:
26-
27-
``` python
28-
1 + 1
29-
```
30-
31-
2
25+
First lets init a
26+
[`Project`](https://explodinggradients.github.io/ragas_annotator/project/core.html#project)
27+
from notion.

nbs/index.ipynb

Lines changed: 1 addition & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -57,35 +57,8 @@
5757
"cell_type": "markdown",
5858
"metadata": {},
5959
"source": [
60-
"Fill me in please! Don't forget code examples:"
60+
"First lets init a `Project` from notion."
6161
]
62-
},
63-
{
64-
"cell_type": "code",
65-
"execution_count": null,
66-
"metadata": {},
67-
"outputs": [
68-
{
69-
"data": {
70-
"text/plain": [
71-
"2"
72-
]
73-
},
74-
"execution_count": null,
75-
"metadata": {},
76-
"output_type": "execute_result"
77-
}
78-
],
79-
"source": [
80-
"1 + 1"
81-
]
82-
},
83-
{
84-
"cell_type": "code",
85-
"execution_count": null,
86-
"metadata": {},
87-
"outputs": [],
88-
"source": []
8962
}
9063
],
9164
"metadata": {

nbs/project/core.ipynb

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
"from fastcore.utils import patch\n",
4343
"\n",
4444
"from ragas_annotator.backends.notion_backend import NotionBackend\n",
45+
"from ragas_annotator.backends.factory import NotionBackendFactory\n",
4546
"from ragas_annotator.model.notion_model import NotionModel\n",
4647
"import ragas_annotator.model.notion_typing as nmt\n",
4748
"from ragas_annotator.dataset import Dataset\n",
@@ -81,10 +82,17 @@
8182
" if notion_root_page_id is None:\n",
8283
" raise ValueError(\"NOTION_ROOT_PAGE_ID is not set\")\n",
8384
"\n",
84-
" self._notion_backend = NotionBackend(\n",
85-
" notion_client=NotionClient(auth=notion_api_key),\n",
86-
" root_page_id=notion_root_page_id,\n",
87-
" )\n",
85+
" if notion_api_key == \"TEST\":\n",
86+
" self._notion_backend = NotionBackendFactory.create(\n",
87+
" root_page_id=notion_root_page_id,\n",
88+
" use_mock=True,\n",
89+
" initialize_project=True,\n",
90+
" )\n",
91+
" else:\n",
92+
" self._notion_backend = NotionBackend(\n",
93+
" notion_client=NotionClient(auth=notion_api_key),\n",
94+
" root_page_id=notion_root_page_id,\n",
95+
" )\n",
8896
" else:\n",
8997
" self._notion_backend = notion_backend\n",
9098
"\n",

nbs/project/experiments.ipynb

Lines changed: 58 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -159,12 +159,13 @@
159159
"source": [
160160
"# | export\n",
161161
"@patch\n",
162-
"def langfuse_experiment(\n",
162+
"def experiment(\n",
163163
" self: Project, experiment_model: t.Type[NotionModel], name_prefix: str = \"\"\n",
164164
"):\n",
165-
" \"\"\"Decorator for creating experiment functions.\n",
165+
" \"\"\"Decorator for creating experiment functions without Langfuse integration.\n",
166166
"\n",
167167
" Args:\n",
168+
" experiment_model: The NotionModel type to use for experiment results\n",
168169
" name_prefix: Optional prefix for experiment names\n",
169170
"\n",
170171
" Returns:\n",
@@ -174,11 +175,8 @@
174175
" def decorator(func: t.Callable) -> ExperimentProtocol:\n",
175176
" @wraps(func)\n",
176177
" async def wrapped_experiment(*args, **kwargs):\n",
177-
" # wrap the function with langfuse observation so that it can be traced\n",
178-
" # and spans inside the function can be retrieved with sync_trace()\n",
179-
" observed_func = observe(name=f\"{name_prefix}-{func.__name__}\")(func)\n",
180-
"\n",
181-
" return await observed_func(*args, **kwargs)\n",
178+
" # Simply call the function without Langfuse observation\n",
179+
" return await func(*args, **kwargs)\n",
182180
"\n",
183181
" # Add run method to the wrapped function\n",
184182
" async def run_async(dataset: Dataset, name: t.Optional[str] = None):\n",
@@ -196,7 +194,8 @@
196194
" for future in tqdm(asyncio.as_completed(tasks), total=len(tasks)):\n",
197195
" result = await future\n",
198196
" # Add each result to experiment view as it completes\n",
199-
" results.append(result) if result is not None else None\n",
197+
" if result is not None:\n",
198+
" results.append(result)\n",
200199
"\n",
201200
" # upload results to experiment view\n",
202201
" experiment_view = self.create_experiment(name=name, model=experiment_model)\n",
@@ -208,6 +207,57 @@
208207
" wrapped_experiment.__setattr__(\"run_async\", run_async)\n",
209208
" return t.cast(ExperimentProtocol, wrapped_experiment)\n",
210209
"\n",
210+
" return decorator\n"
211+
]
212+
},
213+
{
214+
"cell_type": "code",
215+
"execution_count": null,
216+
"metadata": {},
217+
"outputs": [],
218+
"source": [
219+
"# | export\n",
220+
"@patch\n",
221+
"def langfuse_experiment(\n",
222+
" self: Project, experiment_model: t.Type[NotionModel], name_prefix: str = \"\"\n",
223+
"):\n",
224+
" \"\"\"Decorator for creating experiment functions with Langfuse integration.\n",
225+
"\n",
226+
" Args:\n",
227+
" experiment_model: The NotionModel type to use for experiment results\n",
228+
" name_prefix: Optional prefix for experiment names\n",
229+
"\n",
230+
" Returns:\n",
231+
" Decorator function that wraps experiment functions with Langfuse observation\n",
232+
" \"\"\"\n",
233+
"\n",
234+
" def decorator(func: t.Callable) -> ExperimentProtocol:\n",
235+
" # First, create a base experiment wrapper\n",
236+
" base_experiment = self.experiment(experiment_model, name_prefix)(func)\n",
237+
" \n",
238+
" # Override the wrapped function to add Langfuse observation\n",
239+
" @wraps(func)\n",
240+
" async def wrapped_with_langfuse(*args, **kwargs):\n",
241+
" # wrap the function with langfuse observation\n",
242+
" observed_func = observe(name=f\"{name_prefix}-{func.__name__}\")(func)\n",
243+
" return await observed_func(*args, **kwargs)\n",
244+
" \n",
245+
" # Replace the async function to use Langfuse\n",
246+
" original_run_async = base_experiment.run_async\n",
247+
" \n",
248+
" # Use the original run_async but with the Langfuse-wrapped function\n",
249+
" async def run_async_with_langfuse(dataset: Dataset, name: t.Optional[str] = None):\n",
250+
" # Override the internal wrapped_experiment with our Langfuse version\n",
251+
" base_experiment.__wrapped__ = wrapped_with_langfuse\n",
252+
" \n",
253+
" # Call the original run_async which will now use our Langfuse-wrapped function\n",
254+
" return await original_run_async(dataset, name)\n",
255+
" \n",
256+
" # Replace the run_async method\n",
257+
" base_experiment.__setattr__(\"run_async\", run_async_with_langfuse)\n",
258+
" \n",
259+
" return t.cast(ExperimentProtocol, base_experiment)\n",
260+
"\n",
211261
" return decorator"
212262
]
213263
},

ragas_annotator/_modidx.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,8 @@
376376
'ragas_annotator/project/experiments.py'),
377377
'ragas_annotator.project.experiments.Project.create_experiment': ( 'project/experiments.html#project.create_experiment',
378378
'ragas_annotator/project/experiments.py'),
379+
'ragas_annotator.project.experiments.Project.experiment': ( 'project/experiments.html#project.experiment',
380+
'ragas_annotator/project/experiments.py'),
379381
'ragas_annotator.project.experiments.Project.get_experiment': ( 'project/experiments.html#project.get_experiment',
380382
'ragas_annotator/project/experiments.py'),
381383
'ragas_annotator.project.experiments.Project.langfuse_experiment': ( 'project/experiments.html#project.langfuse_experiment',

ragas_annotator/project/core.py

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
from fastcore.utils import patch
1414

1515
from ..backends.notion_backend import NotionBackend
16+
from ..backends.factory import NotionBackendFactory
1617
from ..model.notion_model import NotionModel
1718
import ragas_annotator.model.notion_typing as nmt
1819
from ..dataset import Dataset
@@ -45,10 +46,17 @@ def __init__(
4546
if notion_root_page_id is None:
4647
raise ValueError("NOTION_ROOT_PAGE_ID is not set")
4748

48-
self._notion_backend = NotionBackend(
49-
notion_client=NotionClient(auth=notion_api_key),
50-
root_page_id=notion_root_page_id,
51-
)
49+
if notion_api_key == "TEST":
50+
self._notion_backend = NotionBackendFactory.create(
51+
root_page_id=notion_root_page_id,
52+
use_mock=True,
53+
initialize_project=True,
54+
)
55+
else:
56+
self._notion_backend = NotionBackend(
57+
notion_client=NotionClient(auth=notion_api_key),
58+
root_page_id=notion_root_page_id,
59+
)
5260
else:
5361
self._notion_backend = notion_backend
5462

ragas_annotator/project/experiments.py

Lines changed: 52 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -90,12 +90,13 @@ async def run_async(self, name: str, dataset: Dataset): ...
9090

9191
# %% ../../nbs/project/experiments.ipynb 9
9292
@patch
93-
def langfuse_experiment(
93+
def experiment(
9494
self: Project, experiment_model: t.Type[NotionModel], name_prefix: str = ""
9595
):
96-
"""Decorator for creating experiment functions.
96+
"""Decorator for creating experiment functions without Langfuse integration.
9797
9898
Args:
99+
experiment_model: The NotionModel type to use for experiment results
99100
name_prefix: Optional prefix for experiment names
100101
101102
Returns:
@@ -105,11 +106,8 @@ def langfuse_experiment(
105106
def decorator(func: t.Callable) -> ExperimentProtocol:
106107
@wraps(func)
107108
async def wrapped_experiment(*args, **kwargs):
108-
# wrap the function with langfuse observation so that it can be traced
109-
# and spans inside the function can be retrieved with sync_trace()
110-
observed_func = observe(name=f"{name_prefix}-{func.__name__}")(func)
111-
112-
return await observed_func(*args, **kwargs)
109+
# Simply call the function without Langfuse observation
110+
return await func(*args, **kwargs)
113111

114112
# Add run method to the wrapped function
115113
async def run_async(dataset: Dataset, name: t.Optional[str] = None):
@@ -127,7 +125,8 @@ async def run_async(dataset: Dataset, name: t.Optional[str] = None):
127125
for future in tqdm(asyncio.as_completed(tasks), total=len(tasks)):
128126
result = await future
129127
# Add each result to experiment view as it completes
130-
results.append(result) if result is not None else None
128+
if result is not None:
129+
results.append(result)
131130

132131
# upload results to experiment view
133132
experiment_view = self.create_experiment(name=name, model=experiment_model)
@@ -140,3 +139,48 @@ async def run_async(dataset: Dataset, name: t.Optional[str] = None):
140139
return t.cast(ExperimentProtocol, wrapped_experiment)
141140

142141
return decorator
142+
143+
144+
# %% ../../nbs/project/experiments.ipynb 10
145+
@patch
146+
def langfuse_experiment(
147+
self: Project, experiment_model: t.Type[NotionModel], name_prefix: str = ""
148+
):
149+
"""Decorator for creating experiment functions with Langfuse integration.
150+
151+
Args:
152+
experiment_model: The NotionModel type to use for experiment results
153+
name_prefix: Optional prefix for experiment names
154+
155+
Returns:
156+
Decorator function that wraps experiment functions with Langfuse observation
157+
"""
158+
159+
def decorator(func: t.Callable) -> ExperimentProtocol:
160+
# First, create a base experiment wrapper
161+
base_experiment = self.experiment(experiment_model, name_prefix)(func)
162+
163+
# Override the wrapped function to add Langfuse observation
164+
@wraps(func)
165+
async def wrapped_with_langfuse(*args, **kwargs):
166+
# wrap the function with langfuse observation
167+
observed_func = observe(name=f"{name_prefix}-{func.__name__}")(func)
168+
return await observed_func(*args, **kwargs)
169+
170+
# Replace the async function to use Langfuse
171+
original_run_async = base_experiment.run_async
172+
173+
# Use the original run_async but with the Langfuse-wrapped function
174+
async def run_async_with_langfuse(dataset: Dataset, name: t.Optional[str] = None):
175+
# Override the internal wrapped_experiment with our Langfuse version
176+
base_experiment.__wrapped__ = wrapped_with_langfuse
177+
178+
# Call the original run_async which will now use our Langfuse-wrapped function
179+
return await original_run_async(dataset, name)
180+
181+
# Replace the run_async method
182+
base_experiment.__setattr__("run_async", run_async_with_langfuse)
183+
184+
return t.cast(ExperimentProtocol, base_experiment)
185+
186+
return decorator

0 commit comments

Comments
 (0)