edsl 0.1.38__py3-none-any.whl → 0.1.38.dev2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- edsl/Base.py +31 -60
- edsl/__version__.py +1 -1
- edsl/agents/Agent.py +9 -18
- edsl/agents/AgentList.py +8 -59
- edsl/agents/Invigilator.py +7 -18
- edsl/agents/InvigilatorBase.py +19 -0
- edsl/agents/PromptConstructor.py +4 -5
- edsl/config.py +0 -8
- edsl/coop/coop.py +7 -74
- edsl/data/Cache.py +2 -27
- edsl/data/CacheEntry.py +3 -8
- edsl/data/RemoteCacheSync.py +19 -0
- edsl/enums.py +0 -2
- edsl/inference_services/GoogleService.py +15 -7
- edsl/inference_services/registry.py +0 -2
- edsl/jobs/Jobs.py +548 -88
- edsl/jobs/interviews/Interview.py +11 -11
- edsl/jobs/runners/JobsRunnerAsyncio.py +35 -140
- edsl/jobs/runners/JobsRunnerStatus.py +2 -0
- edsl/jobs/tasks/TaskHistory.py +16 -15
- edsl/language_models/LanguageModel.py +84 -44
- edsl/language_models/ModelList.py +1 -47
- edsl/language_models/registry.py +4 -57
- edsl/prompts/Prompt.py +3 -8
- edsl/questions/QuestionBase.py +16 -20
- edsl/questions/QuestionExtract.py +4 -3
- edsl/questions/question_registry.py +6 -36
- edsl/results/Dataset.py +15 -146
- edsl/results/DatasetExportMixin.py +217 -231
- edsl/results/DatasetTree.py +4 -134
- edsl/results/Result.py +9 -18
- edsl/results/Results.py +51 -145
- edsl/scenarios/FileStore.py +13 -187
- edsl/scenarios/Scenario.py +4 -61
- edsl/scenarios/ScenarioList.py +62 -237
- edsl/surveys/Survey.py +2 -16
- edsl/surveys/SurveyFlowVisualizationMixin.py +9 -67
- edsl/surveys/instructions/Instruction.py +0 -12
- edsl/templates/error_reporting/interview_details.html +3 -3
- edsl/templates/error_reporting/interviews.html +9 -18
- edsl/utilities/utilities.py +0 -15
- {edsl-0.1.38.dist-info → edsl-0.1.38.dev2.dist-info}/METADATA +1 -2
- {edsl-0.1.38.dist-info → edsl-0.1.38.dev2.dist-info}/RECORD +45 -53
- edsl/inference_services/PerplexityService.py +0 -163
- edsl/jobs/JobsChecks.py +0 -147
- edsl/jobs/JobsPrompts.py +0 -268
- edsl/jobs/JobsRemoteInferenceHandler.py +0 -239
- edsl/results/CSSParameterizer.py +0 -108
- edsl/results/TableDisplay.py +0 -198
- edsl/results/table_display.css +0 -78
- edsl/scenarios/ScenarioJoin.py +0 -127
- {edsl-0.1.38.dist-info → edsl-0.1.38.dev2.dist-info}/LICENSE +0 -0
- {edsl-0.1.38.dist-info → edsl-0.1.38.dev2.dist-info}/WHEEL +0 -0
edsl/scenarios/FileStore.py
CHANGED
@@ -14,87 +14,18 @@ from edsl.utilities.decorators import add_edsl_version, remove_edsl_version
|
|
14
14
|
from edsl.utilities.utilities import is_notebook
|
15
15
|
|
16
16
|
|
17
|
-
def view_csv(csv_path):
|
18
|
-
import pandas as pd
|
19
|
-
|
20
|
-
df = pd.read_csv(csv_path)
|
21
|
-
return df
|
22
|
-
|
23
|
-
|
24
|
-
def view_html(html_path):
|
25
|
-
import os
|
26
|
-
import subprocess
|
27
|
-
from IPython.display import IFrame, display, HTML
|
28
|
-
|
29
|
-
if os.path.exists(html_path):
|
30
|
-
if is_notebook():
|
31
|
-
# Display the HTML inline in Jupyter Notebook
|
32
|
-
display(IFrame(src=html_path, width=700, height=600))
|
33
|
-
display(
|
34
|
-
HTML(
|
35
|
-
f'<a href="{html_path}" target="_blank">Open HTML in a new tab</a>'
|
36
|
-
)
|
37
|
-
)
|
38
|
-
else:
|
39
|
-
try:
|
40
|
-
if (os_name := os.name) == "posix":
|
41
|
-
# Open with the default browser on macOS
|
42
|
-
subprocess.run(["open", html_path], check=True)
|
43
|
-
elif os_name == "nt":
|
44
|
-
# Open with the default browser on Windows
|
45
|
-
os.startfile(html_path)
|
46
|
-
else:
|
47
|
-
# Open with the default browser on Linux
|
48
|
-
subprocess.run(["xdg-open", html_path], check=True)
|
49
|
-
except Exception as e:
|
50
|
-
print(f"Error opening HTML file: {e}")
|
51
|
-
else:
|
52
|
-
print("HTML file was not found.")
|
53
|
-
|
54
|
-
|
55
|
-
def view_html(html_path):
|
56
|
-
import os
|
57
|
-
from IPython.display import display, HTML
|
58
|
-
|
59
|
-
if is_notebook():
|
60
|
-
with open(html_path, "r") as f:
|
61
|
-
html_content = f.read()
|
62
|
-
display(HTML(html_content))
|
63
|
-
else:
|
64
|
-
if os.path.exists(html_path):
|
65
|
-
try:
|
66
|
-
if (os_name := os.name) == "posix":
|
67
|
-
subprocess.run(["open", html_path], check=True)
|
68
|
-
elif os_name == "nt":
|
69
|
-
os.startfile(html_path)
|
70
|
-
else:
|
71
|
-
subprocess.run(["xdg-open", html_path], check=True)
|
72
|
-
except Exception as e:
|
73
|
-
print(f"Error opening file: {e}")
|
74
|
-
else:
|
75
|
-
print("File was not created successfully.")
|
76
|
-
|
77
|
-
|
78
17
|
def view_pdf(pdf_path):
|
79
18
|
import os
|
80
19
|
import subprocess
|
81
|
-
import os
|
82
|
-
from IPython.display import HTML, display
|
83
20
|
|
84
21
|
if is_notebook():
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
<
|
91
|
-
|
92
|
-
width="800px"
|
93
|
-
height="800px"
|
94
|
-
type="application/pdf"
|
95
|
-
></iframe>
|
96
|
-
"""
|
97
|
-
display(HTML(html))
|
22
|
+
from IPython.display import IFrame
|
23
|
+
from IPython.display import display, HTML
|
24
|
+
|
25
|
+
# Replace 'path/to/your/file.pdf' with the actual path to your PDF file
|
26
|
+
IFrame(pdf_path, width=700, height=600)
|
27
|
+
display(HTML(f'<a href="{pdf_path}" target="_blank">Open PDF</a>'))
|
28
|
+
return
|
98
29
|
|
99
30
|
if os.path.exists(pdf_path):
|
100
31
|
try:
|
@@ -112,8 +43,6 @@ def view_pdf(pdf_path):
|
|
112
43
|
|
113
44
|
|
114
45
|
class FileStore(Scenario):
|
115
|
-
__documentation__ = "https://docs.expectedparrot.com/en/latest/filestore.html"
|
116
|
-
|
117
46
|
def __init__(
|
118
47
|
self,
|
119
48
|
path: Optional[str] = None,
|
@@ -126,10 +55,7 @@ class FileStore(Scenario):
|
|
126
55
|
):
|
127
56
|
if path is None and "filename" in kwargs:
|
128
57
|
path = kwargs["filename"]
|
129
|
-
|
130
|
-
self._path = path # Store the original path privately
|
131
|
-
self._temp_path = None # Track any generated temporary file
|
132
|
-
|
58
|
+
self.path = path
|
133
59
|
self.suffix = suffix or path.split(".")[-1]
|
134
60
|
self.binary = binary or False
|
135
61
|
self.mime_type = (
|
@@ -139,7 +65,7 @@ class FileStore(Scenario):
|
|
139
65
|
self.external_locations = external_locations or {}
|
140
66
|
super().__init__(
|
141
67
|
{
|
142
|
-
"path": path,
|
68
|
+
"path": self.path,
|
143
69
|
"base64_string": self.base64_string,
|
144
70
|
"binary": self.binary,
|
145
71
|
"suffix": self.suffix,
|
@@ -148,110 +74,17 @@ class FileStore(Scenario):
|
|
148
74
|
}
|
149
75
|
)
|
150
76
|
|
151
|
-
@property
|
152
|
-
def path(self) -> str:
|
153
|
-
"""
|
154
|
-
Property that returns a valid path to the file content.
|
155
|
-
If the original path doesn't exist, generates a temporary file from the base64 content.
|
156
|
-
"""
|
157
|
-
# Check if original path exists and is accessible
|
158
|
-
if self._path and os.path.isfile(self._path):
|
159
|
-
return self._path
|
160
|
-
|
161
|
-
# If we already have a valid temporary file, use it
|
162
|
-
if self._temp_path and os.path.isfile(self._temp_path):
|
163
|
-
return self._temp_path
|
164
|
-
|
165
|
-
# Generate a new temporary file from base64 content
|
166
|
-
self._temp_path = self.to_tempfile(self.suffix)
|
167
|
-
return self._temp_path
|
168
|
-
|
169
77
|
def __str__(self):
|
170
78
|
return "FileStore: self.path"
|
171
79
|
|
172
80
|
@classmethod
|
173
|
-
def example(
|
174
|
-
import textwrap
|
81
|
+
def example(self):
|
175
82
|
import tempfile
|
176
83
|
|
177
|
-
|
178
|
-
|
179
|
-
from pathlib import Path
|
180
|
-
|
181
|
-
# Get package root directory
|
182
|
-
package_root = Path(__file__).parent.parent.parent
|
183
|
-
logo_path = package_root / "static" / "logo.png"
|
184
|
-
return cls(str(logo_path))
|
185
|
-
|
186
|
-
if example_type == "text":
|
187
|
-
with tempfile.NamedTemporaryFile(suffix=".txt", delete=False) as f:
|
188
|
-
f.write(b"Hello, World!")
|
189
|
-
|
190
|
-
return cls(path=f.name)
|
84
|
+
with tempfile.NamedTemporaryFile(suffix=".txt", delete=False) as f:
|
85
|
+
f.write(b"Hello, World!")
|
191
86
|
|
192
|
-
|
193
|
-
from edsl.results.Results import Results
|
194
|
-
|
195
|
-
r = Results.example()
|
196
|
-
|
197
|
-
with tempfile.NamedTemporaryFile(suffix=".csv", delete=False) as f:
|
198
|
-
r.to_csv(filename=f.name)
|
199
|
-
return cls(f.name)
|
200
|
-
|
201
|
-
elif example_type == "pdf":
|
202
|
-
pdf_string = textwrap.dedent(
|
203
|
-
"""\
|
204
|
-
%PDF-1.4
|
205
|
-
1 0 obj
|
206
|
-
<< /Type /Catalog /Pages 2 0 R >>
|
207
|
-
endobj
|
208
|
-
2 0 obj
|
209
|
-
<< /Type /Pages /Kids [3 0 R] /Count 1 >>
|
210
|
-
endobj
|
211
|
-
3 0 obj
|
212
|
-
<< /Type /Page /Parent 2 0 R /MediaBox [0 0 612 792] /Contents 4 0 R >>
|
213
|
-
endobj
|
214
|
-
4 0 obj
|
215
|
-
<< /Length 44 >>
|
216
|
-
stream
|
217
|
-
BT
|
218
|
-
/F1 24 Tf
|
219
|
-
100 700 Td
|
220
|
-
(Hello, World!) Tj
|
221
|
-
ET
|
222
|
-
endstream
|
223
|
-
endobj
|
224
|
-
5 0 obj
|
225
|
-
<< /Type /Font /Subtype /Type1 /BaseFont /Helvetica >>
|
226
|
-
endobj
|
227
|
-
6 0 obj
|
228
|
-
<< /ProcSet [/PDF /Text] /Font << /F1 5 0 R >> >>
|
229
|
-
endobj
|
230
|
-
xref
|
231
|
-
0 7
|
232
|
-
0000000000 65535 f
|
233
|
-
0000000010 00000 n
|
234
|
-
0000000053 00000 n
|
235
|
-
0000000100 00000 n
|
236
|
-
0000000173 00000 n
|
237
|
-
0000000232 00000 n
|
238
|
-
0000000272 00000 n
|
239
|
-
trailer
|
240
|
-
<< /Size 7 /Root 1 0 R >>
|
241
|
-
startxref
|
242
|
-
318
|
243
|
-
%%EOF"""
|
244
|
-
)
|
245
|
-
with tempfile.NamedTemporaryFile(suffix=".pdf", delete=False) as f:
|
246
|
-
f.write(pdf_string.encode())
|
247
|
-
|
248
|
-
return cls(f.name)
|
249
|
-
|
250
|
-
elif example_type == "html":
|
251
|
-
with tempfile.NamedTemporaryFile(suffix=".html", delete=False) as f:
|
252
|
-
f.write("<html><body><h1>Test</h1></body></html>".encode())
|
253
|
-
|
254
|
-
return cls(f.name)
|
87
|
+
return self(path=f.name)
|
255
88
|
|
256
89
|
@property
|
257
90
|
def size(self) -> int:
|
@@ -353,16 +186,9 @@ class FileStore(Scenario):
|
|
353
186
|
return temp_file.name
|
354
187
|
|
355
188
|
def view(self, max_size: int = 300) -> None:
|
356
|
-
# with self.open() as f:
|
357
|
-
if self.suffix == "csv":
|
358
|
-
return view_csv(self.path)
|
359
|
-
|
360
189
|
if self.suffix == "pdf":
|
361
190
|
view_pdf(self.path)
|
362
191
|
|
363
|
-
if self.suffix == "html":
|
364
|
-
view_html(self.path)
|
365
|
-
|
366
192
|
if self.suffix == "png" or self.suffix == "jpg" or self.suffix == "jpeg":
|
367
193
|
if is_notebook():
|
368
194
|
from IPython.display import Image
|
edsl/scenarios/Scenario.py
CHANGED
@@ -4,7 +4,6 @@ from __future__ import annotations
|
|
4
4
|
import copy
|
5
5
|
import hashlib
|
6
6
|
import os
|
7
|
-
import json
|
8
7
|
from collections import UserDict
|
9
8
|
from typing import Union, List, Optional, Generator
|
10
9
|
from uuid import uuid4
|
@@ -15,30 +14,12 @@ from edsl.utilities.decorators import add_edsl_version, remove_edsl_version
|
|
15
14
|
from edsl.exceptions.scenarios import ScenarioError
|
16
15
|
|
17
16
|
|
18
|
-
class DisplayJSON:
|
19
|
-
def __init__(self, dict):
|
20
|
-
self.text = json.dumps(dict, indent=4)
|
21
|
-
|
22
|
-
def __repr__(self):
|
23
|
-
return self.text
|
24
|
-
|
25
|
-
|
26
|
-
class DisplayYAML:
|
27
|
-
def __init__(self, dict):
|
28
|
-
import yaml
|
29
|
-
|
30
|
-
self.text = yaml.dump(dict)
|
31
|
-
|
32
|
-
def __repr__(self):
|
33
|
-
return self.text
|
34
|
-
|
35
|
-
|
36
17
|
class Scenario(Base, UserDict, ScenarioHtmlMixin):
|
37
18
|
"""A Scenario is a dictionary of keys/values.
|
38
19
|
|
39
20
|
They can be used parameterize EDSL questions."""
|
40
21
|
|
41
|
-
|
22
|
+
__doc__ = "https://docs.expectedparrot.com/en/latest/scenarios.html"
|
42
23
|
|
43
24
|
def __init__(self, data: Union[dict, None] = None, name: str = None):
|
44
25
|
"""Initialize a new Scenario.
|
@@ -156,22 +137,6 @@ class Scenario(Base, UserDict, ScenarioHtmlMixin):
|
|
156
137
|
new_scenario[key] = value
|
157
138
|
return new_scenario
|
158
139
|
|
159
|
-
def table(self, tablefmt: str = "grid") -> str:
|
160
|
-
from edsl.results.Dataset import Dataset
|
161
|
-
|
162
|
-
keys = [key for key, value in self.items()]
|
163
|
-
values = [value for key, value in self.items()]
|
164
|
-
d = Dataset([{"key": keys}, {"value": values}])
|
165
|
-
return d.table(tablefmt=tablefmt)
|
166
|
-
|
167
|
-
def json(self):
|
168
|
-
return DisplayJSON(self.to_dict(add_edsl_version=False))
|
169
|
-
|
170
|
-
def yaml(self):
|
171
|
-
import yaml
|
172
|
-
|
173
|
-
return DisplayYAML(self.to_dict(add_edsl_version=False))
|
174
|
-
|
175
140
|
def to_dict(self, add_edsl_version=True) -> dict:
|
176
141
|
"""Convert a scenario to a dictionary.
|
177
142
|
|
@@ -220,35 +185,13 @@ class Scenario(Base, UserDict, ScenarioHtmlMixin):
|
|
220
185
|
print_json(json.dumps(self.to_dict()))
|
221
186
|
|
222
187
|
def __repr__(self):
|
188
|
+
# return "Scenario(" + reprlib.repr(self.data) + ")"
|
223
189
|
return "Scenario(" + repr(self.data) + ")"
|
224
190
|
|
225
|
-
def to_dataset(self) -> "Dataset":
|
226
|
-
# d = Dataset([{'a.b':[1,2,3,4]}])
|
227
|
-
from edsl.results.Dataset import Dataset
|
228
|
-
|
229
|
-
keys = [key for key, value in self.items()]
|
230
|
-
values = [value for key, value in self.items()]
|
231
|
-
return Dataset([{"key": keys}, {"value": values}])
|
232
|
-
|
233
191
|
def _repr_html_(self):
|
234
|
-
from
|
235
|
-
import reprlib
|
236
|
-
|
237
|
-
d = self.to_dict(add_edsl_version=False)
|
238
|
-
# return self.to_dataset()
|
239
|
-
r = reprlib.Repr()
|
240
|
-
r.maxstring = 70
|
241
|
-
|
242
|
-
data = [[k, r.repr(v)] for k, v in d.items()]
|
243
|
-
from tabulate import tabulate
|
244
|
-
|
245
|
-
if hasattr(self, "__documentation__"):
|
246
|
-
footer = f"<a href='{self.__documentation__}'>(docs)</a></p>"
|
247
|
-
else:
|
248
|
-
footer = ""
|
192
|
+
from edsl.utilities.utilities import data_to_html
|
249
193
|
|
250
|
-
|
251
|
-
return f"<pre>{table}</pre>" + footer
|
194
|
+
return data_to_html(self.to_dict())
|
252
195
|
|
253
196
|
def select(self, list_of_keys: List[str]) -> "Scenario":
|
254
197
|
"""Select a subset of keys from a scenario.
|