edsl 0.1.33__py3-none-any.whl → 0.1.33.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.
Files changed (63) hide show
  1. edsl/Base.py +3 -9
  2. edsl/__init__.py +0 -1
  3. edsl/__version__.py +1 -1
  4. edsl/agents/Agent.py +6 -6
  5. edsl/agents/Invigilator.py +3 -6
  6. edsl/agents/InvigilatorBase.py +27 -8
  7. edsl/agents/{PromptConstructor.py → PromptConstructionMixin.py} +29 -101
  8. edsl/config.py +34 -26
  9. edsl/coop/coop.py +2 -11
  10. edsl/data_transfer_models.py +73 -26
  11. edsl/enums.py +0 -2
  12. edsl/inference_services/GoogleService.py +1 -1
  13. edsl/inference_services/InferenceServiceABC.py +13 -44
  14. edsl/inference_services/OpenAIService.py +4 -7
  15. edsl/inference_services/TestService.py +15 -24
  16. edsl/inference_services/registry.py +0 -2
  17. edsl/jobs/Jobs.py +8 -18
  18. edsl/jobs/buckets/BucketCollection.py +15 -24
  19. edsl/jobs/buckets/TokenBucket.py +10 -64
  20. edsl/jobs/interviews/Interview.py +47 -115
  21. edsl/jobs/interviews/InterviewExceptionEntry.py +0 -2
  22. edsl/jobs/interviews/{InterviewExceptionCollection.py → interview_exception_tracking.py} +0 -16
  23. edsl/jobs/interviews/retry_management.py +39 -0
  24. edsl/jobs/runners/JobsRunnerAsyncio.py +170 -95
  25. edsl/jobs/runners/JobsRunnerStatusMixin.py +333 -0
  26. edsl/jobs/tasks/TaskHistory.py +0 -17
  27. edsl/language_models/LanguageModel.py +31 -26
  28. edsl/language_models/registry.py +9 -13
  29. edsl/questions/QuestionBase.py +14 -63
  30. edsl/questions/QuestionBudget.py +41 -93
  31. edsl/questions/QuestionFreeText.py +0 -6
  32. edsl/questions/QuestionMultipleChoice.py +23 -8
  33. edsl/questions/QuestionNumerical.py +4 -5
  34. edsl/questions/ResponseValidatorABC.py +5 -6
  35. edsl/questions/derived/QuestionLinearScale.py +1 -4
  36. edsl/questions/derived/QuestionTopK.py +1 -4
  37. edsl/questions/derived/QuestionYesNo.py +2 -8
  38. edsl/results/DatasetExportMixin.py +1 -5
  39. edsl/results/Result.py +1 -1
  40. edsl/results/Results.py +1 -4
  41. edsl/scenarios/FileStore.py +10 -71
  42. edsl/scenarios/Scenario.py +21 -86
  43. edsl/scenarios/ScenarioImageMixin.py +2 -2
  44. edsl/scenarios/ScenarioList.py +0 -13
  45. edsl/scenarios/ScenarioListPdfMixin.py +4 -150
  46. edsl/study/Study.py +0 -32
  47. edsl/surveys/Rule.py +1 -10
  48. edsl/surveys/RuleCollection.py +3 -19
  49. edsl/surveys/Survey.py +0 -7
  50. edsl/templates/error_reporting/interview_details.html +1 -6
  51. edsl/utilities/utilities.py +1 -9
  52. {edsl-0.1.33.dist-info → edsl-0.1.33.dev2.dist-info}/METADATA +1 -2
  53. {edsl-0.1.33.dist-info → edsl-0.1.33.dev2.dist-info}/RECORD +55 -61
  54. edsl/inference_services/TogetherAIService.py +0 -170
  55. edsl/jobs/runners/JobsRunnerStatus.py +0 -331
  56. edsl/questions/Quick.py +0 -41
  57. edsl/questions/templates/budget/__init__.py +0 -0
  58. edsl/questions/templates/budget/answering_instructions.jinja +0 -7
  59. edsl/questions/templates/budget/question_presentation.jinja +0 -7
  60. edsl/questions/templates/extract/__init__.py +0 -0
  61. edsl/questions/templates/rank/__init__.py +0 -0
  62. {edsl-0.1.33.dist-info → edsl-0.1.33.dev2.dist-info}/LICENSE +0 -0
  63. {edsl-0.1.33.dist-info → edsl-0.1.33.dev2.dist-info}/WHEEL +0 -0
@@ -1,60 +1,8 @@
1
1
  from __future__ import annotations
2
- from typing import Any, Optional, Union, List
3
-
4
- from pydantic import Field, BaseModel, validator
5
-
2
+ import random
3
+ from typing import Any, Optional, Union
6
4
  from edsl.questions.QuestionBase import QuestionBase
7
5
  from edsl.questions.descriptors import IntegerDescriptor, QuestionOptionsDescriptor
8
- from edsl.questions.ResponseValidatorABC import ResponseValidatorABC
9
-
10
-
11
- class BudgewResponseValidator(ResponseValidatorABC):
12
- valid_examples = []
13
-
14
- invalid_examples = []
15
-
16
- def fix(self, response, verbose=False):
17
- if verbose:
18
- print(f"Fixing list response: {response}")
19
- answer = str(response.get("answer") or response.get("generated_tokens", ""))
20
- if len(answer.split(",")) > 0:
21
- return (
22
- {"answer": answer.split(",")} | {"comment": response.get("comment")}
23
- if "comment" in response
24
- else {}
25
- )
26
-
27
-
28
- def create_budget_model(
29
- budget_sum: float, permissive: bool, question_options: List[str]
30
- ):
31
- class BudgetResponse(BaseModel):
32
- answer: List[float] = Field(
33
- ...,
34
- description="List of non-negative numbers representing budget allocation",
35
- min_items=len(question_options),
36
- max_items=len(question_options),
37
- )
38
- comment: Optional[str] = None
39
- generated_tokens: Optional[str] = None
40
-
41
- @validator("answer")
42
- def validate_answer(cls, v):
43
- if len(v) != len(question_options):
44
- raise ValueError(f"Must provide {len(question_options)} values")
45
- if any(x < 0 for x in v):
46
- raise ValueError("All values must be non-negative")
47
- total = sum(v)
48
- if not permissive and total != budget_sum:
49
- raise ValueError(f"Sum of numbers must equal {budget_sum}")
50
- elif permissive and total > budget_sum:
51
- raise ValueError(f"Sum of numbers cannot exceed {budget_sum}")
52
- return v
53
-
54
- class Config:
55
- extra = "forbid"
56
-
57
- return BudgetResponse
58
6
 
59
7
 
60
8
  class QuestionBudget(QuestionBase):
@@ -64,7 +12,7 @@ class QuestionBudget(QuestionBase):
64
12
  budget_sum: int = IntegerDescriptor(none_allowed=False)
65
13
  question_options: list[str] = QuestionOptionsDescriptor(q_budget=True)
66
14
  _response_model = None
67
- response_validator_class = BudgewResponseValidator
15
+ response_validator_class = None
68
16
 
69
17
  def __init__(
70
18
  self,
@@ -72,10 +20,8 @@ class QuestionBudget(QuestionBase):
72
20
  question_text: str,
73
21
  question_options: list[str],
74
22
  budget_sum: int,
75
- include_comment: bool = True,
76
23
  question_presentation: Optional[str] = None,
77
24
  answering_instructions: Optional[str] = None,
78
- permissive: bool = False,
79
25
  ):
80
26
  """Instantiate a new QuestionBudget.
81
27
 
@@ -90,17 +36,20 @@ class QuestionBudget(QuestionBase):
90
36
  self.budget_sum = budget_sum
91
37
  self.question_presentation = question_presentation
92
38
  self.answering_instructions = answering_instructions
93
- self.permissive = permissive
94
- self.include_comment = include_comment
95
39
 
96
- def create_response_model(self):
97
- return create_budget_model(
98
- self.budget_sum, self.permissive, self.question_options
99
- )
40
+ ################
41
+ # Answer methods
42
+ ################
43
+ def _validate_answer(self, answer: dict[str, Any]) -> dict[str, Union[int, str]]:
44
+ """Validate the answer."""
45
+ self._validate_answer_template_basic(answer)
46
+ self._validate_answer_key_value(answer, "answer", dict)
47
+ self._validate_answer_budget(answer)
48
+ return answer
100
49
 
101
50
  def _translate_answer_code_to_answer(
102
- self, answer_code, combined_dict
103
- ) -> list[dict]:
51
+ self, answer_codes: dict[str, int], scenario: "Scenario" = None
52
+ ):
104
53
  """
105
54
  Translate the answer codes to the actual answers.
106
55
 
@@ -109,35 +58,35 @@ class QuestionBudget(QuestionBase):
109
58
  This code will translate that to "a".
110
59
  """
111
60
  translated_codes = []
112
- for answer_code, question_option in zip(answer_code, self.question_options):
113
- translated_codes.append({question_option: answer_code})
61
+ for answer_code, response in answer_codes.items():
62
+ translated_codes.append({self.question_options[int(answer_code)]: response})
114
63
 
115
64
  return translated_codes
116
65
 
117
- # def _simulate_answer(self, human_readable=True):
118
- # """Simulate a valid answer for debugging purposes (what the validator expects)."""
119
- # from edsl.utilities.utilities import random_string
120
-
121
- # if human_readable:
122
- # keys = self.question_options
123
- # else:
124
- # keys = range(len(self.question_options))
125
- # remaining_budget = self.budget_sum
126
- # values = []
127
- # for _ in range(len(self.question_options)):
128
- # if _ == len(self.question_options) - 1:
129
- # # Assign remaining budget to the last value
130
- # values.append(remaining_budget)
131
- # else:
132
- # # Generate a random value between 0 and remaining budget
133
- # value = random.randint(0, remaining_budget)
134
- # values.append(value)
135
- # remaining_budget -= value
136
- # answer = dict(zip(keys, values))
137
- # return {
138
- # "answer": answer,
139
- # "comment": random_string(),
140
- # }
66
+ def _simulate_answer(self, human_readable=True):
67
+ """Simulate a valid answer for debugging purposes (what the validator expects)."""
68
+ from edsl.utilities.utilities import random_string
69
+
70
+ if human_readable:
71
+ keys = self.question_options
72
+ else:
73
+ keys = range(len(self.question_options))
74
+ remaining_budget = self.budget_sum
75
+ values = []
76
+ for _ in range(len(self.question_options)):
77
+ if _ == len(self.question_options) - 1:
78
+ # Assign remaining budget to the last value
79
+ values.append(remaining_budget)
80
+ else:
81
+ # Generate a random value between 0 and remaining budget
82
+ value = random.randint(0, remaining_budget)
83
+ values.append(value)
84
+ remaining_budget -= value
85
+ answer = dict(zip(keys, values))
86
+ return {
87
+ "answer": answer,
88
+ "comment": random_string(),
89
+ }
141
90
 
142
91
  @property
143
92
  def question_html_content(self) -> str:
@@ -184,14 +133,13 @@ class QuestionBudget(QuestionBase):
184
133
  # Helpful methods
185
134
  ################
186
135
  @classmethod
187
- def example(cls, include_comment: bool = True) -> QuestionBudget:
136
+ def example(cls) -> QuestionBudget:
188
137
  """Return an example of a budget question."""
189
138
  return cls(
190
139
  question_name="food_budget",
191
140
  question_text="How would you allocate $100?",
192
141
  question_options=["Pizza", "Ice Cream", "Burgers", "Salad"],
193
142
  budget_sum=100,
194
- include_comment=include_comment,
195
143
  )
196
144
 
197
145
 
@@ -36,12 +36,6 @@ class FreeTextResponseValidator(ResponseValidatorABC):
36
36
  ),
37
37
  ]
38
38
 
39
- def fix(self, response, verbose=False):
40
- return {
41
- "answer": str(response.get("generated_tokens")),
42
- "generated_tokens": str(response.get("generated_tokens")),
43
- }
44
-
45
39
 
46
40
  class QuestionFreeText(QuestionBase):
47
41
  """This question prompts the agent to respond with free text."""
@@ -1,14 +1,22 @@
1
1
  from __future__ import annotations
2
- from typing import Union, Literal, Optional, List, Any
3
-
2
+ from typing import Union, Literal, Optional
4
3
  from jinja2 import Template
4
+
5
5
  from pydantic import BaseModel, Field
6
+ from typing import Optional, Literal
6
7
 
7
- from edsl.scenarios.Scenario import Scenario
8
8
  from edsl.questions.QuestionBase import QuestionBase
9
9
  from edsl.questions.descriptors import QuestionOptionsDescriptor
10
10
  from edsl.questions.decorators import inject_exception
11
+
11
12
  from edsl.questions.ResponseValidatorABC import ResponseValidatorABC
13
+ from edsl.questions.ResponseValidatorABC import BaseResponse
14
+
15
+ from edsl.exceptions import QuestionAnswerValidationError
16
+
17
+ from pydantic import BaseModel, Field, create_model
18
+
19
+ from typing import List, Any, Literal
12
20
 
13
21
 
14
22
  def create_response_model(choices: List[str], permissive: bool = False):
@@ -19,6 +27,7 @@ def create_response_model(choices: List[str], permissive: bool = False):
19
27
  :param permissive: If True, any value will be accepted as an answer.
20
28
  :return: A new Pydantic model class.
21
29
  """
30
+ # Convert the choices list to a tuple for use with Literal
22
31
  choice_tuple = tuple(choices)
23
32
 
24
33
  if not permissive:
@@ -57,6 +66,16 @@ def create_response_model(choices: List[str], permissive: bool = False):
57
66
  return ChoiceResponse
58
67
 
59
68
 
69
+ def fix_multiple_choice(response, question_options, use_code, verbose=False):
70
+ """Fix the response to a multiple choice question.
71
+ Respnse is a dictionary with keys:
72
+ - answer: the answer code
73
+ - generated_tokens: the generated tokens
74
+ - comment: the comment
75
+ """
76
+ pass
77
+
78
+
60
79
  class MultipleChoiceResponseValidator(ResponseValidatorABC):
61
80
  required_params = ["question_options", "use_code"]
62
81
 
@@ -142,11 +161,6 @@ class QuestionMultipleChoice(QuestionBase):
142
161
  :param question_name: The name of the question.
143
162
  :param question_text: The text of the question.
144
163
  :param question_options: The options the agent should select from.
145
- :param include_comment: Whether to include a comment field.
146
- :param use_code: Whether to use code for the options.
147
- :param answering_instructions: Instructions for the question.
148
- :param question_presentation: The presentation of the question.
149
- :param permissive: Whether to force the answer to be one of the options.
150
164
 
151
165
  """
152
166
  self.question_name = question_name
@@ -188,6 +202,7 @@ class QuestionMultipleChoice(QuestionBase):
188
202
  'Happy'
189
203
 
190
204
  """
205
+ from edsl.scenarios.Scenario import Scenario
191
206
 
192
207
  scenario = scenario or Scenario()
193
208
 
@@ -1,6 +1,5 @@
1
1
  from __future__ import annotations
2
-
3
- # from decimal import Decimal
2
+ from decimal import Decimal
4
3
  from random import uniform
5
4
  from typing import Any, Optional, Union, Literal
6
5
 
@@ -15,8 +14,8 @@ from edsl.exceptions.questions import QuestionAnswerValidationError
15
14
 
16
15
 
17
16
  def create_numeric_response(
18
- min_value: Optional[float] = None,
19
- max_value: Optional[float] = None,
17
+ min_value: Optional[Decimal] = None,
18
+ max_value: Optional[Decimal] = None,
20
19
  permissive=False,
21
20
  ):
22
21
  field_kwargs = {}
@@ -28,7 +27,7 @@ def create_numeric_response(
28
27
  field_kwargs["le"] = max_value
29
28
 
30
29
  class ConstrainedNumericResponse(BaseModel):
31
- answer: Union[int, float] = Field(**field_kwargs)
30
+ answer: Union[Decimal] = Field(**field_kwargs)
32
31
  comment: Optional[str] = Field(None)
33
32
  generated_tokens: Optional[Any] = Field(None)
34
33
 
@@ -1,7 +1,6 @@
1
1
  from abc import ABC, abstractmethod
2
2
  from pydantic import BaseModel, Field, field_validator
3
-
4
- # from decimal import Decimal
3
+ from decimal import Decimal
5
4
  from typing import Optional, Any, List, TypedDict
6
5
 
7
6
  from edsl.exceptions import QuestionAnswerValidationError
@@ -65,7 +64,7 @@ class ResponseValidatorABC(ABC):
65
64
  >>> rv = ResponseValidatorABC.example()
66
65
  >>> rv.override_answer = {"answer": 42}
67
66
  >>> rv.validate({"answer": 23})
68
- {'answer': 42, 'comment': None, 'generated_tokens': None}
67
+ {'answer': Decimal('42'), 'comment': None, 'generated_tokens': None}
69
68
  """
70
69
  if self.exception_to_throw:
71
70
  raise self.exception_to_throw
@@ -76,7 +75,7 @@ class ResponseValidatorABC(ABC):
76
75
 
77
76
  >>> rv = ResponseValidatorABC.example("numerical")
78
77
  >>> rv._base_validate({"answer": 42})
79
- ConstrainedNumericResponse(answer=42, comment=None, generated_tokens=None)
78
+ ConstrainedNumericResponse(answer=Decimal('42'), comment=None, generated_tokens=None)
80
79
  """
81
80
  try:
82
81
  return self.response_model(**data)
@@ -98,7 +97,7 @@ class ResponseValidatorABC(ABC):
98
97
 
99
98
  >>> rv = ResponseValidatorABC.example("numerical")
100
99
  >>> rv.validate({"answer": 42})
101
- {'answer': 42, 'comment': None, 'generated_tokens': None}
100
+ {'answer': Decimal('42'), 'comment': None, 'generated_tokens': None}
102
101
  >>> rv.max_value
103
102
  86.7
104
103
  >>> rv.validate({"answer": "120"})
@@ -110,7 +109,7 @@ class ResponseValidatorABC(ABC):
110
109
  >>> q.permissive = True
111
110
  >>> rv = q.response_validator
112
111
  >>> rv.validate({"answer": "120"})
113
- {'answer': 120, 'comment': None, 'generated_tokens': None}
112
+ {'answer': Decimal('120'), 'comment': None, 'generated_tokens': None}
114
113
  >>> rv.validate({"answer": "poo"})
115
114
  Traceback (most recent call last):
116
115
  ...
@@ -22,7 +22,6 @@ class QuestionLinearScale(QuestionMultipleChoice):
22
22
  option_labels: Optional[dict[int, str]] = None,
23
23
  answering_instructions: Optional[str] = None,
24
24
  question_presentation: Optional[str] = None,
25
- include_comment: Optional[bool] = True,
26
25
  ):
27
26
  """Instantiate a new QuestionLinearScale.
28
27
 
@@ -37,7 +36,6 @@ class QuestionLinearScale(QuestionMultipleChoice):
37
36
  question_text=question_text,
38
37
  question_options=question_options,
39
38
  use_code=False, # question linear scale will have it's own code
40
- include_comment=include_comment,
41
39
  )
42
40
  self.question_options = question_options
43
41
  self.option_labels = (
@@ -51,14 +49,13 @@ class QuestionLinearScale(QuestionMultipleChoice):
51
49
  ################
52
50
  @classmethod
53
51
  @inject_exception
54
- def example(cls, include_comment: bool = True) -> QuestionLinearScale:
52
+ def example(cls) -> QuestionLinearScale:
55
53
  """Return an example of a linear scale question."""
56
54
  return cls(
57
55
  question_text="How much do you like ice cream?",
58
56
  question_options=[1, 2, 3, 4, 5],
59
57
  question_name="ice_cream",
60
58
  option_labels={1: "I hate it", 5: "I love it"},
61
- include_comment=include_comment,
62
59
  )
63
60
 
64
61
 
@@ -20,7 +20,6 @@ class QuestionTopK(QuestionCheckBox):
20
20
  max_selections: int,
21
21
  question_presentation: Optional[str] = None,
22
22
  answering_instructions: Optional[str] = None,
23
- include_comment: Optional[bool] = True,
24
23
  ):
25
24
  """Initialize the question.
26
25
 
@@ -38,7 +37,6 @@ class QuestionTopK(QuestionCheckBox):
38
37
  max_selections=max_selections,
39
38
  question_presentation=question_presentation,
40
39
  answering_instructions=answering_instructions,
41
- include_comment=include_comment,
42
40
  )
43
41
  if min_selections != max_selections:
44
42
  raise QuestionCreationValidationError(
@@ -54,7 +52,7 @@ class QuestionTopK(QuestionCheckBox):
54
52
  ################
55
53
  @classmethod
56
54
  @inject_exception
57
- def example(cls, include_comment: bool = True) -> QuestionTopK:
55
+ def example(cls) -> QuestionTopK:
58
56
  """Return an example question."""
59
57
  return cls(
60
58
  question_name="two_fruits",
@@ -62,7 +60,6 @@ class QuestionTopK(QuestionCheckBox):
62
60
  question_options=["apple", "banana", "carrot", "durian"],
63
61
  min_selections=2,
64
62
  max_selections=2,
65
- include_comment=include_comment,
66
63
  )
67
64
 
68
65
 
@@ -19,7 +19,6 @@ class QuestionYesNo(QuestionMultipleChoice):
19
19
  question_options: list[str] = ["No", "Yes"],
20
20
  answering_instructions: Optional[str] = None,
21
21
  question_presentation: Optional[str] = None,
22
- include_comment: Optional[bool] = True,
23
22
  ):
24
23
  """Instantiate a new QuestionYesNo.
25
24
 
@@ -34,7 +33,6 @@ class QuestionYesNo(QuestionMultipleChoice):
34
33
  use_code=False,
35
34
  answering_instructions=answering_instructions,
36
35
  question_presentation=question_presentation,
37
- include_comment=include_comment,
38
36
  )
39
37
  self.question_options = question_options
40
38
 
@@ -43,13 +41,9 @@ class QuestionYesNo(QuestionMultipleChoice):
43
41
  ################
44
42
  @classmethod
45
43
  @inject_exception
46
- def example(cls, include_comment: bool = True) -> QuestionYesNo:
44
+ def example(cls) -> QuestionYesNo:
47
45
  """Return an example of a yes/no question."""
48
- return cls(
49
- question_name="is_it_equal",
50
- question_text="Is 5 + 5 equal to 11?",
51
- include_comment=include_comment,
52
- )
46
+ return cls(question_name="is_it_equal", question_text="Is 5 + 5 equal to 11?")
53
47
 
54
48
 
55
49
  def main():
@@ -472,11 +472,7 @@ class DatasetExportMixin:
472
472
  from edsl import ScenarioList, Scenario
473
473
 
474
474
  list_of_dicts = self.to_dicts(remove_prefix=remove_prefix)
475
- scenarios = []
476
- for d in list_of_dicts:
477
- scenarios.append(Scenario(d))
478
- return ScenarioList(scenarios)
479
- # return ScenarioList([Scenario(d) for d in list_of_dicts])
475
+ return ScenarioList([Scenario(d) for d in list_of_dicts])
480
476
 
481
477
  def to_agent_list(self, remove_prefix: bool = True):
482
478
  """Convert the results to a list of dictionaries, one per agent.
edsl/results/Result.py CHANGED
@@ -367,7 +367,7 @@ class Result(Base, UserDict):
367
367
  "raw_model_response", {"raw_model_response": "No raw model response"}
368
368
  ),
369
369
  question_to_attributes=json_dict.get("question_to_attributes", None),
370
- generated_tokens=json_dict.get("generated_tokens", {}),
370
+ generated_tokens=json_dict.get("generated_tokens", None),
371
371
  )
372
372
  return result
373
373
 
edsl/results/Results.py CHANGED
@@ -245,9 +245,7 @@ class Results(UserList, Mixins, Base):
245
245
  )
246
246
 
247
247
  def __repr__(self) -> str:
248
- import reprlib
249
-
250
- return f"Results(data = {reprlib.repr(self.data)}, survey = {repr(self.survey)}, created_columns = {self.created_columns})"
248
+ return f"Results(data = {self.data}, survey = {repr(self.survey)}, created_columns = {self.created_columns})"
251
249
 
252
250
  def _repr_html_(self) -> str:
253
251
  from IPython.display import HTML
@@ -1091,7 +1089,6 @@ class Results(UserList, Mixins, Base):
1091
1089
  stop_on_exception=True,
1092
1090
  skip_retry=True,
1093
1091
  raise_validation_errors=True,
1094
- disable_remote_inference=True,
1095
1092
  )
1096
1093
  return results
1097
1094
 
@@ -120,22 +120,14 @@ class FileStore(Scenario):
120
120
  return info
121
121
 
122
122
  @classmethod
123
- def pull(cls, uuid, expected_parrot_url: Optional[str] = None):
124
- scenario_version = Scenario.pull(uuid, expected_parrot_url=expected_parrot_url)
123
+ def pull(cls, uuid):
124
+ scenario_version = Scenario.pull(uuid)
125
125
  return cls.from_dict(scenario_version.to_dict())
126
126
 
127
127
 
128
128
  class CSVFileStore(FileStore):
129
- def __init__(
130
- self,
131
- filename,
132
- binary: Optional[bool] = None,
133
- suffix: Optional[str] = None,
134
- base64_string: Optional[str] = None,
135
- ):
136
- super().__init__(
137
- filename, binary=binary, base64_string=base64_string, suffix=".csv"
138
- )
129
+ def __init__(self, filename):
130
+ super().__init__(filename, suffix=".csv")
139
131
 
140
132
  @classmethod
141
133
  def example(cls):
@@ -155,16 +147,8 @@ class CSVFileStore(FileStore):
155
147
 
156
148
 
157
149
  class PDFFileStore(FileStore):
158
- def __init__(
159
- self,
160
- filename,
161
- binary: Optional[bool] = None,
162
- suffix: Optional[str] = None,
163
- base64_string: Optional[str] = None,
164
- ):
165
- super().__init__(
166
- filename, binary=binary, base64_string=base64_string, suffix=".pdf"
167
- )
150
+ def __init__(self, filename):
151
+ super().__init__(filename, suffix=".pdf")
168
152
 
169
153
  def view(self):
170
154
  pdf_path = self.to_tempfile()
@@ -241,16 +225,8 @@ class PDFFileStore(FileStore):
241
225
 
242
226
 
243
227
  class PNGFileStore(FileStore):
244
- def __init__(
245
- self,
246
- filename,
247
- binary: Optional[bool] = None,
248
- suffix: Optional[str] = None,
249
- base64_string: Optional[str] = None,
250
- ):
251
- super().__init__(
252
- filename, binary=binary, base64_string=base64_string, suffix=".png"
253
- )
228
+ def __init__(self, filename):
229
+ super().__init__(filename, suffix=".png")
254
230
 
255
231
  @classmethod
256
232
  def example(cls):
@@ -275,16 +251,8 @@ class PNGFileStore(FileStore):
275
251
 
276
252
 
277
253
  class SQLiteFileStore(FileStore):
278
- def __init__(
279
- self,
280
- filename,
281
- binary: Optional[bool] = None,
282
- suffix: Optional[str] = None,
283
- base64_string: Optional[str] = None,
284
- ):
285
- super().__init__(
286
- filename, binary=binary, base64_string=base64_string, suffix=".sqlite"
287
- )
254
+ def __init__(self, filename):
255
+ super().__init__(filename, suffix=".sqlite")
288
256
 
289
257
  @classmethod
290
258
  def example(cls):
@@ -297,8 +265,6 @@ class SQLiteFileStore(FileStore):
297
265
  c.execute("""CREATE TABLE stocks (date text)""")
298
266
  conn.commit()
299
267
 
300
- return cls(f.name)
301
-
302
268
  def view(self):
303
269
  import subprocess
304
270
  import os
@@ -307,33 +273,6 @@ class SQLiteFileStore(FileStore):
307
273
  os.system(f"sqlite3 {sqlite_path}")
308
274
 
309
275
 
310
- class HTMLFileStore(FileStore):
311
- def __init__(
312
- self,
313
- filename,
314
- binary: Optional[bool] = None,
315
- suffix: Optional[str] = None,
316
- base64_string: Optional[str] = None,
317
- ):
318
- super().__init__(
319
- filename, binary=binary, base64_string=base64_string, suffix=".html"
320
- )
321
-
322
- @classmethod
323
- def example(cls):
324
- import tempfile
325
-
326
- with tempfile.NamedTemporaryFile(suffix=".html", delete=False) as f:
327
- f.write("<html><body><h1>Test</h1></body></html>".encode())
328
- return cls(f.name)
329
-
330
- def view(self):
331
- import webbrowser
332
-
333
- html_path = self.to_tempfile()
334
- webbrowser.open("file://" + html_path)
335
-
336
-
337
276
  if __name__ == "__main__":
338
277
  # file_path = "../conjure/examples/Ex11-2.sav"
339
278
  # fs = FileStore(file_path)