edsl 0.1.39__py3-none-any.whl → 0.1.39.dev1__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.
Files changed (212) hide show
  1. edsl/Base.py +116 -197
  2. edsl/__init__.py +7 -15
  3. edsl/__version__.py +1 -1
  4. edsl/agents/Agent.py +147 -351
  5. edsl/agents/AgentList.py +73 -211
  6. edsl/agents/Invigilator.py +50 -101
  7. edsl/agents/InvigilatorBase.py +70 -62
  8. edsl/agents/PromptConstructor.py +225 -143
  9. edsl/agents/__init__.py +1 -0
  10. edsl/agents/prompt_helpers.py +3 -3
  11. edsl/auto/AutoStudy.py +5 -18
  12. edsl/auto/StageBase.py +40 -53
  13. edsl/auto/StageQuestions.py +1 -2
  14. edsl/auto/utilities.py +6 -0
  15. edsl/config.py +2 -22
  16. edsl/conversation/car_buying.py +1 -2
  17. edsl/coop/PriceFetcher.py +1 -1
  18. edsl/coop/coop.py +47 -125
  19. edsl/coop/utils.py +14 -14
  20. edsl/data/Cache.py +27 -45
  21. edsl/data/CacheEntry.py +15 -12
  22. edsl/data/CacheHandler.py +12 -31
  23. edsl/data/RemoteCacheSync.py +46 -154
  24. edsl/data/__init__.py +3 -4
  25. edsl/data_transfer_models.py +1 -2
  26. edsl/enums.py +0 -27
  27. edsl/exceptions/__init__.py +50 -50
  28. edsl/exceptions/agents.py +0 -12
  29. edsl/exceptions/questions.py +6 -24
  30. edsl/exceptions/scenarios.py +0 -7
  31. edsl/inference_services/AnthropicService.py +19 -38
  32. edsl/inference_services/AwsBedrock.py +2 -0
  33. edsl/inference_services/AzureAI.py +2 -0
  34. edsl/inference_services/GoogleService.py +12 -7
  35. edsl/inference_services/InferenceServiceABC.py +85 -18
  36. edsl/inference_services/InferenceServicesCollection.py +79 -120
  37. edsl/inference_services/MistralAIService.py +3 -0
  38. edsl/inference_services/OpenAIService.py +35 -47
  39. edsl/inference_services/PerplexityService.py +3 -0
  40. edsl/inference_services/TestService.py +10 -11
  41. edsl/inference_services/TogetherAIService.py +3 -5
  42. edsl/jobs/Answers.py +14 -1
  43. edsl/jobs/Jobs.py +431 -356
  44. edsl/jobs/JobsChecks.py +10 -35
  45. edsl/jobs/JobsPrompts.py +4 -6
  46. edsl/jobs/JobsRemoteInferenceHandler.py +133 -205
  47. edsl/jobs/buckets/BucketCollection.py +3 -44
  48. edsl/jobs/buckets/TokenBucket.py +21 -53
  49. edsl/jobs/interviews/Interview.py +408 -143
  50. edsl/jobs/runners/JobsRunnerAsyncio.py +403 -88
  51. edsl/jobs/runners/JobsRunnerStatus.py +165 -133
  52. edsl/jobs/tasks/QuestionTaskCreator.py +19 -21
  53. edsl/jobs/tasks/TaskHistory.py +18 -38
  54. edsl/jobs/tasks/task_status_enum.py +2 -0
  55. edsl/language_models/KeyLookup.py +30 -0
  56. edsl/language_models/LanguageModel.py +236 -194
  57. edsl/language_models/ModelList.py +19 -28
  58. edsl/language_models/__init__.py +2 -1
  59. edsl/language_models/registry.py +190 -0
  60. edsl/language_models/repair.py +2 -2
  61. edsl/language_models/unused/ReplicateBase.py +83 -0
  62. edsl/language_models/utilities.py +4 -5
  63. edsl/notebooks/Notebook.py +14 -19
  64. edsl/prompts/Prompt.py +39 -29
  65. edsl/questions/{answer_validator_mixin.py → AnswerValidatorMixin.py} +2 -47
  66. edsl/questions/QuestionBase.py +214 -68
  67. edsl/questions/{question_base_gen_mixin.py → QuestionBaseGenMixin.py} +50 -57
  68. edsl/questions/QuestionBasePromptsMixin.py +3 -7
  69. edsl/questions/QuestionBudget.py +1 -1
  70. edsl/questions/QuestionCheckBox.py +3 -3
  71. edsl/questions/QuestionExtract.py +7 -5
  72. edsl/questions/QuestionFreeText.py +3 -2
  73. edsl/questions/QuestionList.py +18 -10
  74. edsl/questions/QuestionMultipleChoice.py +23 -67
  75. edsl/questions/QuestionNumerical.py +4 -2
  76. edsl/questions/QuestionRank.py +17 -7
  77. edsl/questions/{response_validator_abc.py → ResponseValidatorABC.py} +26 -40
  78. edsl/questions/SimpleAskMixin.py +3 -4
  79. edsl/questions/__init__.py +1 -2
  80. edsl/questions/derived/QuestionLinearScale.py +3 -6
  81. edsl/questions/derived/QuestionTopK.py +1 -1
  82. edsl/questions/descriptors.py +3 -17
  83. edsl/questions/question_registry.py +1 -1
  84. edsl/results/CSSParameterizer.py +1 -1
  85. edsl/results/Dataset.py +7 -170
  86. edsl/results/DatasetExportMixin.py +305 -168
  87. edsl/results/DatasetTree.py +8 -28
  88. edsl/results/Result.py +206 -298
  89. edsl/results/Results.py +131 -149
  90. edsl/results/ResultsDBMixin.py +238 -0
  91. edsl/results/ResultsExportMixin.py +0 -2
  92. edsl/results/{results_selector.py → Selector.py} +13 -23
  93. edsl/results/TableDisplay.py +171 -98
  94. edsl/results/__init__.py +1 -1
  95. edsl/scenarios/FileStore.py +239 -150
  96. edsl/scenarios/Scenario.py +193 -90
  97. edsl/scenarios/ScenarioHtmlMixin.py +3 -4
  98. edsl/scenarios/{scenario_join.py → ScenarioJoin.py} +6 -10
  99. edsl/scenarios/ScenarioList.py +244 -415
  100. edsl/scenarios/ScenarioListExportMixin.py +7 -0
  101. edsl/scenarios/ScenarioListPdfMixin.py +37 -15
  102. edsl/scenarios/__init__.py +2 -1
  103. edsl/study/ObjectEntry.py +1 -1
  104. edsl/study/SnapShot.py +1 -1
  105. edsl/study/Study.py +12 -5
  106. edsl/surveys/Rule.py +4 -5
  107. edsl/surveys/RuleCollection.py +27 -25
  108. edsl/surveys/Survey.py +791 -270
  109. edsl/surveys/SurveyCSS.py +8 -20
  110. edsl/surveys/{SurveyFlowVisualization.py → SurveyFlowVisualizationMixin.py} +9 -11
  111. edsl/surveys/__init__.py +2 -4
  112. edsl/surveys/descriptors.py +2 -6
  113. edsl/surveys/instructions/ChangeInstruction.py +2 -1
  114. edsl/surveys/instructions/Instruction.py +13 -4
  115. edsl/surveys/instructions/InstructionCollection.py +6 -11
  116. edsl/templates/error_reporting/interview_details.html +1 -1
  117. edsl/templates/error_reporting/report.html +1 -1
  118. edsl/tools/plotting.py +1 -1
  119. edsl/utilities/utilities.py +23 -35
  120. {edsl-0.1.39.dist-info → edsl-0.1.39.dev1.dist-info}/METADATA +10 -12
  121. edsl-0.1.39.dev1.dist-info/RECORD +277 -0
  122. {edsl-0.1.39.dist-info → edsl-0.1.39.dev1.dist-info}/WHEEL +1 -1
  123. edsl/agents/QuestionInstructionPromptBuilder.py +0 -128
  124. edsl/agents/QuestionTemplateReplacementsBuilder.py +0 -137
  125. edsl/agents/question_option_processor.py +0 -172
  126. edsl/coop/CoopFunctionsMixin.py +0 -15
  127. edsl/coop/ExpectedParrotKeyHandler.py +0 -125
  128. edsl/exceptions/inference_services.py +0 -5
  129. edsl/inference_services/AvailableModelCacheHandler.py +0 -184
  130. edsl/inference_services/AvailableModelFetcher.py +0 -215
  131. edsl/inference_services/ServiceAvailability.py +0 -135
  132. edsl/inference_services/data_structures.py +0 -134
  133. edsl/jobs/AnswerQuestionFunctionConstructor.py +0 -223
  134. edsl/jobs/FetchInvigilator.py +0 -47
  135. edsl/jobs/InterviewTaskManager.py +0 -98
  136. edsl/jobs/InterviewsConstructor.py +0 -50
  137. edsl/jobs/JobsComponentConstructor.py +0 -189
  138. edsl/jobs/JobsRemoteInferenceLogger.py +0 -239
  139. edsl/jobs/RequestTokenEstimator.py +0 -30
  140. edsl/jobs/async_interview_runner.py +0 -138
  141. edsl/jobs/buckets/TokenBucketAPI.py +0 -211
  142. edsl/jobs/buckets/TokenBucketClient.py +0 -191
  143. edsl/jobs/check_survey_scenario_compatibility.py +0 -85
  144. edsl/jobs/data_structures.py +0 -120
  145. edsl/jobs/decorators.py +0 -35
  146. edsl/jobs/jobs_status_enums.py +0 -9
  147. edsl/jobs/loggers/HTMLTableJobLogger.py +0 -304
  148. edsl/jobs/results_exceptions_handler.py +0 -98
  149. edsl/language_models/ComputeCost.py +0 -63
  150. edsl/language_models/PriceManager.py +0 -127
  151. edsl/language_models/RawResponseHandler.py +0 -106
  152. edsl/language_models/ServiceDataSources.py +0 -0
  153. edsl/language_models/key_management/KeyLookup.py +0 -63
  154. edsl/language_models/key_management/KeyLookupBuilder.py +0 -273
  155. edsl/language_models/key_management/KeyLookupCollection.py +0 -38
  156. edsl/language_models/key_management/__init__.py +0 -0
  157. edsl/language_models/key_management/models.py +0 -131
  158. edsl/language_models/model.py +0 -256
  159. edsl/notebooks/NotebookToLaTeX.py +0 -142
  160. edsl/questions/ExceptionExplainer.py +0 -77
  161. edsl/questions/HTMLQuestion.py +0 -103
  162. edsl/questions/QuestionMatrix.py +0 -265
  163. edsl/questions/data_structures.py +0 -20
  164. edsl/questions/loop_processor.py +0 -149
  165. edsl/questions/response_validator_factory.py +0 -34
  166. edsl/questions/templates/matrix/__init__.py +0 -1
  167. edsl/questions/templates/matrix/answering_instructions.jinja +0 -5
  168. edsl/questions/templates/matrix/question_presentation.jinja +0 -20
  169. edsl/results/MarkdownToDocx.py +0 -122
  170. edsl/results/MarkdownToPDF.py +0 -111
  171. edsl/results/TextEditor.py +0 -50
  172. edsl/results/file_exports.py +0 -252
  173. edsl/results/smart_objects.py +0 -96
  174. edsl/results/table_data_class.py +0 -12
  175. edsl/results/table_renderers.py +0 -118
  176. edsl/scenarios/ConstructDownloadLink.py +0 -109
  177. edsl/scenarios/DocumentChunker.py +0 -102
  178. edsl/scenarios/DocxScenario.py +0 -16
  179. edsl/scenarios/PdfExtractor.py +0 -40
  180. edsl/scenarios/directory_scanner.py +0 -96
  181. edsl/scenarios/file_methods.py +0 -85
  182. edsl/scenarios/handlers/__init__.py +0 -13
  183. edsl/scenarios/handlers/csv.py +0 -49
  184. edsl/scenarios/handlers/docx.py +0 -76
  185. edsl/scenarios/handlers/html.py +0 -37
  186. edsl/scenarios/handlers/json.py +0 -111
  187. edsl/scenarios/handlers/latex.py +0 -5
  188. edsl/scenarios/handlers/md.py +0 -51
  189. edsl/scenarios/handlers/pdf.py +0 -68
  190. edsl/scenarios/handlers/png.py +0 -39
  191. edsl/scenarios/handlers/pptx.py +0 -105
  192. edsl/scenarios/handlers/py.py +0 -294
  193. edsl/scenarios/handlers/sql.py +0 -313
  194. edsl/scenarios/handlers/sqlite.py +0 -149
  195. edsl/scenarios/handlers/txt.py +0 -33
  196. edsl/scenarios/scenario_selector.py +0 -156
  197. edsl/surveys/ConstructDAG.py +0 -92
  198. edsl/surveys/EditSurvey.py +0 -221
  199. edsl/surveys/InstructionHandler.py +0 -100
  200. edsl/surveys/MemoryManagement.py +0 -72
  201. edsl/surveys/RuleManager.py +0 -172
  202. edsl/surveys/Simulator.py +0 -75
  203. edsl/surveys/SurveyToApp.py +0 -141
  204. edsl/utilities/PrettyList.py +0 -56
  205. edsl/utilities/is_notebook.py +0 -18
  206. edsl/utilities/is_valid_variable_name.py +0 -11
  207. edsl/utilities/remove_edsl_version.py +0 -24
  208. edsl-0.1.39.dist-info/RECORD +0 -358
  209. /edsl/questions/{register_questions_meta.py → RegisterQuestionsMeta.py} +0 -0
  210. /edsl/results/{results_fetch_mixin.py → ResultsFetchMixin.py} +0 -0
  211. /edsl/results/{results_tools_mixin.py → ResultsToolsMixin.py} +0 -0
  212. {edsl-0.1.39.dist-info → edsl-0.1.39.dev1.dist-info}/LICENSE +0 -0
edsl/surveys/SurveyCSS.py CHANGED
@@ -1,5 +1,5 @@
1
1
  from typing import Optional
2
- from edsl.utilities.remove_edsl_version import remove_edsl_version
2
+ from edsl.utilities.decorators import add_edsl_version, remove_edsl_version
3
3
 
4
4
 
5
5
  class CSSRuleMeta(type):
@@ -64,21 +64,14 @@ class CSSRule(metaclass=CSSRuleMeta):
64
64
  def __repr__(self) -> str:
65
65
  return f"CSSRule(select = {self.selector}, properties = {self.properties})"
66
66
 
67
- def to_dict(self, add_esl_version: bool = True) -> dict:
67
+ @add_edsl_version
68
+ def to_dict(self) -> dict:
68
69
  """
69
70
  >>> rule = CSSRule("survey_container", {"width": "80%", "margin": "0 auto"})
70
71
  >>> rule.to_dict()
71
- {'selector': 'survey_container', 'properties': {'width': '80%', 'margin': '0 auto'}, 'edsl_version': '...', 'edsl_class_name': '...'}
72
+ {'selector': 'survey_container', 'properties': {'width': '80%', 'margin': '0 auto'}, 'edsl_version': '...', 'edsl_class_name': 'CSSRule'}
72
73
  """
73
- d = {"selector": self.selector, "properties": self.properties}
74
-
75
- if add_esl_version:
76
- from edsl import __version__
77
-
78
- d["edsl_version"] = __version__
79
- d["edsl_class_name"] = self.__class__.__name__
80
-
81
- return d
74
+ return {"selector": self.selector, "properties": self.properties}
82
75
 
83
76
  @classmethod
84
77
  @remove_edsl_version
@@ -225,19 +218,14 @@ class SurveyCSS:
225
218
  css_lines.append(rule.generate_rule())
226
219
  return "\n".join(css_lines)
227
220
 
228
- def to_dict(self, add_edsl_version: bool = True) -> dict:
221
+ @add_edsl_version
222
+ def to_dict(self) -> dict:
229
223
  """
230
224
  >>> css = SurveyCSS(rules = []).update_style("survey_container", "width", "100%")
231
225
  >>> css.to_dict()
232
226
  {'rules': [{'selector': 'survey_container', 'properties': {'width': '100%'}, 'edsl_version': '...', 'edsl_class_name': 'CSSRule'}], 'edsl_version': '...', 'edsl_class_name': 'SurveyCSS'}
233
227
  """
234
- d = {"rules": [rule.to_dict() for rule in self.rules.values()]}
235
- if add_edsl_version:
236
- from edsl import __version__
237
-
238
- d["edsl_version"] = __version__
239
- d["edsl_class_name"] = self.__class__.__name__
240
- return d
228
+ return {"rules": [rule.to_dict() for rule in self.rules.values()]}
241
229
 
242
230
  def __repr__(self) -> str:
243
231
  return f"SurveyCSS(rules = {[rule for rule in self.rules.values()]})"
@@ -1,16 +1,14 @@
1
1
  """A mixin for visualizing the flow of a survey with parameter nodes."""
2
2
 
3
- from typing import Optional, TYPE_CHECKING
3
+ from typing import Optional
4
4
  from edsl.surveys.base import RulePriority, EndOfSurvey
5
5
  import tempfile
6
+ import os
6
7
 
7
8
 
8
- class SurveyFlowVisualization:
9
+ class SurveyFlowVisualizationMixin:
9
10
  """A mixin for visualizing the flow of a survey with parameter visualization."""
10
11
 
11
- def __init__(self, survey: "Survey"):
12
- self.survey = survey
13
-
14
12
  def show_flow(self, filename: Optional[str] = None):
15
13
  """Create an image showing the flow of users through the survey and question parameters."""
16
14
  # Create a graph object
@@ -24,7 +22,7 @@ class SurveyFlowVisualization:
24
22
  answer_refs = set() # Track answer references between questions
25
23
 
26
24
  # First pass: collect parameters and their question associations
27
- for index, question in enumerate(self.survey.questions):
25
+ for index, question in enumerate(self.questions):
28
26
  # Add the main question node
29
27
  question_node = pydot.Node(
30
28
  f"Q{index}", label=f"{question.question_name}", shape="ellipse"
@@ -71,7 +69,7 @@ class SurveyFlowVisualization:
71
69
  # Find the source question index by name
72
70
  source_q_index = next(
73
71
  i
74
- for i, q in enumerate(self.survey.questions)
72
+ for i, q in enumerate(self.questions)
75
73
  if q.question_name == source_q_name
76
74
  )
77
75
  ref_edge = pydot.Edge(
@@ -89,7 +87,7 @@ class SurveyFlowVisualization:
89
87
  )
90
88
 
91
89
  # Add edges for normal flow through the survey
92
- num_questions = len(self.survey.questions)
90
+ num_questions = len(self.questions)
93
91
  for index in range(num_questions - 1):
94
92
  graph.add_edge(pydot.Edge(f"Q{index}", f"Q{index+1}"))
95
93
 
@@ -97,7 +95,7 @@ class SurveyFlowVisualization:
97
95
 
98
96
  relevant_rules = [
99
97
  rule
100
- for rule in self.survey.rule_collection
98
+ for rule in self.rule_collection
101
99
  if rule.priority > RulePriority.DEFAULT.value
102
100
  ]
103
101
 
@@ -161,10 +159,10 @@ class SurveyFlowVisualization:
161
159
  on Ubuntu.
162
160
  """
163
161
  )
164
- from edsl.utilities.is_notebook import is_notebook
162
+ from edsl.utilities.utilities import is_notebook
165
163
 
166
164
  if is_notebook():
167
- from IPython.display import Image, display
165
+ from IPython.display import Image
168
166
 
169
167
  display(Image(tmp_file.name))
170
168
  else:
edsl/surveys/__init__.py CHANGED
@@ -1,5 +1,3 @@
1
1
  from edsl.surveys.Survey import Survey
2
- from edsl.surveys.instructions.Instruction import Instruction
3
-
4
- # from edsl.surveys.Rule import Rule
5
- # from edsl.surveys.RuleCollection import RuleCollection
2
+ from edsl.surveys.Rule import Rule
3
+ from edsl.surveys.RuleCollection import RuleCollection
@@ -1,10 +1,8 @@
1
1
  """This module contains the descriptors for the classes in the edsl package."""
2
2
 
3
3
  from abc import ABC, abstractmethod
4
- from typing import Any, TYPE_CHECKING
5
-
6
- if TYPE_CHECKING:
7
- from edsl.questions.QuestionBase import QuestionBase
4
+ from typing import Any
5
+ from edsl.questions.QuestionBase import QuestionBase
8
6
 
9
7
 
10
8
  class BaseDescriptor(ABC):
@@ -38,8 +36,6 @@ class QuestionsDescriptor(BaseDescriptor):
38
36
 
39
37
  def validate(self, value: Any, instance) -> None:
40
38
  """Validate the value. If it is invalid, raise an exception. If it is valid, do nothing."""
41
- from edsl.questions.QuestionBase import QuestionBase
42
-
43
39
  if not isinstance(value, list):
44
40
  raise TypeError("Questions must be a list.")
45
41
  if not all(isinstance(question, QuestionBase) for question in value):
@@ -1,5 +1,6 @@
1
1
  from typing import List, Optional
2
- from edsl.utilities.remove_edsl_version import remove_edsl_version
2
+
3
+ from edsl.utilities.decorators import add_edsl_version, remove_edsl_version
3
4
 
4
5
 
5
6
  class ChangeInstruction:
@@ -1,9 +1,10 @@
1
1
  from typing import Union, Optional, List, Generator, Dict
2
- from edsl.utilities.remove_edsl_version import remove_edsl_version
3
- from edsl.Base import RepresentationMixin
2
+ from edsl.questions import QuestionBase
4
3
 
4
+ from edsl.utilities.decorators import add_edsl_version, remove_edsl_version
5
5
 
6
- class Instruction(RepresentationMixin):
6
+
7
+ class Instruction:
7
8
  def __init__(
8
9
  self, name, text, preamble="You were given the following instructions:"
9
10
  ):
@@ -17,6 +18,14 @@ class Instruction(RepresentationMixin):
17
18
  def __repr__(self):
18
19
  return """Instruction(name="{}", text="{}")""".format(self.name, self.text)
19
20
 
21
+ def _repr_html_(self):
22
+ d = self.to_dict(add_edsl_version=False)
23
+ data = [[k, v] for k, v in d.items()]
24
+ from tabulate import tabulate
25
+
26
+ table = str(tabulate(data, headers=["keys", "values"], tablefmt="html"))
27
+ return f"<pre>{table}</pre>"
28
+
20
29
  @classmethod
21
30
  def example(cls) -> "Instruction":
22
31
  return cls(name="example", text="This is an example instruction.")
@@ -36,7 +45,7 @@ class Instruction(RepresentationMixin):
36
45
  return d
37
46
 
38
47
  def add_question(self, question) -> "Survey":
39
- from edsl.surveys.Survey import Survey
48
+ from edsl import Survey
40
49
 
41
50
  return Survey([self, question])
42
51
 
@@ -1,18 +1,17 @@
1
- from typing import TYPE_CHECKING, Dict, List, Generator, Union
2
- from collections import UserDict
3
-
4
1
  from edsl.surveys.instructions.Instruction import Instruction
5
2
  from edsl.surveys.instructions.ChangeInstruction import ChangeInstruction
3
+ from edsl.questions import QuestionBase
4
+ from typing import Union, Optional, List, Generator, Dict
5
+
6
6
 
7
- if TYPE_CHECKING:
8
- from edsl.questions.QuestionBase import QuestionBase
7
+ from collections import UserDict
9
8
 
10
9
 
11
10
  class InstructionCollection(UserDict):
12
11
  def __init__(
13
12
  self,
14
13
  instruction_names_to_instruction: Dict[str, Instruction],
15
- questions: List["QuestionBase"],
14
+ questions: List[QuestionBase],
16
15
  ):
17
16
  self.instruction_names_to_instruction = instruction_names_to_instruction
18
17
  self.questions = questions
@@ -25,8 +24,6 @@ class InstructionCollection(UserDict):
25
24
 
26
25
  def __getitem__(self, key):
27
26
  # in case the person uses question instead of the name
28
- from edsl.questions.QuestionBase import QuestionBase
29
-
30
27
  if isinstance(key, QuestionBase):
31
28
  key = key.name
32
29
  return self.data[key]
@@ -57,11 +54,9 @@ class InstructionCollection(UserDict):
57
54
  return instructions, changes
58
55
 
59
56
  def relevant_instructions(
60
- self, question: Union[str, "QuestionBase"]
57
+ self, question: Union[str, QuestionBase]
61
58
  ) -> Generator[Instruction, None, None]:
62
59
  ## Find all the questions that are after a given instruction
63
- from edsl.questions.QuestionBase import QuestionBase
64
-
65
60
  if isinstance(question, str):
66
61
  question_name = question
67
62
  elif isinstance(question, QuestionBase):
@@ -31,7 +31,7 @@
31
31
 
32
32
  <tr>
33
33
  <td>Human-readable question</td>
34
- <td>{{ interview.survey._get_question_by_name(question).html(
34
+ <td>{{ interview.survey.get_question(question).html(
35
35
  scenario = interview.scenario,
36
36
  agent = interview.agent,
37
37
  answers = exception_message.answers)
@@ -82,7 +82,7 @@
82
82
 
83
83
  <h2>Question</h2>
84
84
  <div class="question-detail">
85
- {{ interview.survey._get_question_by_name(question).html() }}
85
+ {{ interview.survey.get_question(question).html() }}
86
86
  </div>
87
87
 
88
88
  <h2>Scenario</h2>
edsl/tools/plotting.py CHANGED
@@ -11,7 +11,7 @@ def count_query(field):
11
11
 
12
12
 
13
13
  def get_options(results, field):
14
- question_type = results.survey._get_question_by_name(field).question_type
14
+ question_type = results.survey.get_question(field).question_type
15
15
  if question_type in ["multiple_choice", "checkbox"]:
16
16
  return results.select(f"{field}_question_options").first()
17
17
  else:
@@ -121,27 +121,27 @@ def clean_json(bad_json_str):
121
121
  return s
122
122
 
123
123
 
124
- # def data_to_html(data, replace_new_lines=False):
125
- # if "edsl_version" in data:
126
- # _ = data.pop("edsl_version")
127
- # if "edsl_class_name" in data:
128
- # _ = data.pop("edsl_class_name")
129
-
130
- # from pygments import highlight
131
- # from pygments.lexers import JsonLexer
132
- # from pygments.formatters import HtmlFormatter
133
- # from IPython.display import HTML
134
-
135
- # json_str = json.dumps(data, indent=4, cls=CustomEncoder)
136
- # formatted_json = highlight(
137
- # json_str,
138
- # JsonLexer(),
139
- # HtmlFormatter(style="default", full=False, noclasses=False),
140
- # )
141
- # if replace_new_lines:
142
- # formatted_json = formatted_json.replace("\\n", "<br>")
124
+ def data_to_html(data, replace_new_lines=False):
125
+ if "edsl_version" in data:
126
+ _ = data.pop("edsl_version")
127
+ if "edsl_class_name" in data:
128
+ _ = data.pop("edsl_class_name")
129
+
130
+ from pygments import highlight
131
+ from pygments.lexers import JsonLexer
132
+ from pygments.formatters import HtmlFormatter
133
+ from IPython.display import HTML
134
+
135
+ json_str = json.dumps(data, indent=4, cls=CustomEncoder)
136
+ formatted_json = highlight(
137
+ json_str,
138
+ JsonLexer(),
139
+ HtmlFormatter(style="default", full=False, noclasses=False),
140
+ )
141
+ if replace_new_lines:
142
+ formatted_json = formatted_json.replace("\\n", "<br>")
143
143
 
144
- # return HTML(formatted_json).data
144
+ return HTML(formatted_json).data
145
145
 
146
146
 
147
147
  def is_gzipped(file_path):
@@ -194,21 +194,15 @@ def dict_to_html(d):
194
194
 
195
195
 
196
196
  def is_notebook() -> bool:
197
- """Check if the code is running in a Jupyter notebook or Google Colab."""
197
+ """Check if the code is running in a Jupyter notebook."""
198
198
  try:
199
199
  shell = get_ipython().__class__.__name__
200
200
  if shell == "ZMQInteractiveShell":
201
201
  return True # Jupyter notebook or qtconsole
202
- elif shell == "Shell": # Google Colab's shell class
203
- import sys
204
-
205
- if "google.colab" in sys.modules:
206
- return True # Running in Google Colab
207
- return False
208
202
  elif shell == "TerminalInteractiveShell":
209
203
  return False # Terminal running IPython
210
204
  else:
211
- return False # Other type
205
+ return False # Other type (e.g., IDLE, PyCharm, etc.)
212
206
  except NameError:
213
207
  return False # Probably standard Python interpreter
214
208
 
@@ -412,13 +406,11 @@ def shorten_string(s, max_length, placeholder="..."):
412
406
  return s[:start_remove] + placeholder + s[end_remove:]
413
407
 
414
408
 
415
- def write_api_key_to_env(api_key: str) -> str:
409
+ def write_api_key_to_env(api_key: str) -> None:
416
410
  """
417
411
  Write the user's Expected Parrot key to their .env file.
418
412
 
419
413
  If a .env file doesn't exist in the current directory, one will be created.
420
-
421
- Returns a string representing the absolute path to the .env file.
422
414
  """
423
415
  from pathlib import Path
424
416
  from dotenv import set_key
@@ -430,7 +422,3 @@ def write_api_key_to_env(api_key: str) -> str:
430
422
 
431
423
  # Write API key to file
432
424
  set_key(env_path, "EXPECTED_PARROT_API_KEY", str(api_key))
433
-
434
- absolute_path_to_env = env_file.absolute().as_posix()
435
-
436
- return absolute_path_to_env
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: edsl
3
- Version: 0.1.39
3
+ Version: 0.1.39.dev1
4
4
  Summary: Create and analyze LLM-based surveys
5
5
  Home-page: https://www.expectedparrot.com/
6
6
  License: MIT
@@ -34,15 +34,12 @@ Requires-Dist: numpy (>=1.22,<2.0)
34
34
  Requires-Dist: openai (>=1.4.0,<2.0.0)
35
35
  Requires-Dist: openpyxl (>=3.1.5,<4.0.0)
36
36
  Requires-Dist: pandas (>=2.1.4,<3.0.0)
37
- Requires-Dist: platformdirs (>=4.3.6,<5.0.0)
38
37
  Requires-Dist: pydot (>=2.0.0,<3.0.0)
39
38
  Requires-Dist: pygments (>=2.17.2,<3.0.0)
40
39
  Requires-Dist: pymupdf (>=1.24.4,<2.0.0)
41
- Requires-Dist: pypdf2 (>=3.0.1,<4.0.0)
42
40
  Requires-Dist: pyreadstat (>=1.2.7,<2.0.0)
43
41
  Requires-Dist: python-docx (>=1.1.0,<2.0.0)
44
42
  Requires-Dist: python-dotenv (>=1.0.0,<2.0.0)
45
- Requires-Dist: python-pptx (>=1.0.2,<2.0.0)
46
43
  Requires-Dist: restrictedpython (>=7.1,<8.0)
47
44
  Requires-Dist: rich (>=13.7.0,<14.0.0)
48
45
  Requires-Dist: setuptools (<72.0)
@@ -87,23 +84,24 @@ q = QuestionMultipleChoice(
87
84
  # Run it with the default language model
88
85
  results = q.run()
89
86
 
90
- # Inspect the results
91
- results.select("example_question")
87
+ # Inspect the results in a dataset
88
+ results.select("example_question").print()
92
89
  ```
93
90
 
94
91
  Output:
95
92
  ```python
96
- ┏━━━━━━━━━━━━━━━━━━━━━━━━━┓
97
- ┃ answer.example_question
98
- ┡━━━━━━━━━━━━━━━━━━━━━━━━━┩
99
- │ Good │
100
- └─────────────────────────┘
93
+ ┏━━━━━━━━━━━━━━━━━━━┓
94
+ ┃ answer
95
+ ┃ .example_question ┃
96
+ ┡━━━━━━━━━━━━━━━━━━━┩
97
+ │ Good │
98
+ └───────────────────┘
101
99
  ```
102
100
 
103
101
  ## 💻 Requirements
104
102
  * EDSL is compatible with Python 3.9 - 3.12.
105
103
  * API keys for large language models that you want to use, stored in a `.env` file.
106
- See instructions on [storing API keys](https://docs.expectedparrot.com/en/latest/api_keys.html) and [activating remote inference](https://docs.expectedparrot.com/en/latest/remote_inference.html).
104
+ See instructions on [storing API keys](https://docs.expectedparrot.com/en/latest/api_keys.html).
107
105
 
108
106
  ## 💡 Contributions, feature requests & bugs
109
107
  Interested in contributing? Want us to add a new feature? Found a bug for us to squash?