edsl 0.1.29__py3-none-any.whl → 0.1.29.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 (72) hide show
  1. edsl/Base.py +18 -18
  2. edsl/__init__.py +23 -23
  3. edsl/__version__.py +1 -1
  4. edsl/agents/Agent.py +41 -77
  5. edsl/agents/AgentList.py +9 -19
  6. edsl/agents/Invigilator.py +1 -19
  7. edsl/agents/InvigilatorBase.py +10 -15
  8. edsl/agents/PromptConstructionMixin.py +100 -342
  9. edsl/agents/descriptors.py +1 -2
  10. edsl/config.py +1 -2
  11. edsl/conjure/InputData.py +8 -39
  12. edsl/coop/coop.py +150 -187
  13. edsl/coop/utils.py +75 -43
  14. edsl/data/Cache.py +5 -19
  15. edsl/data/SQLiteDict.py +3 -11
  16. edsl/jobs/Answers.py +1 -15
  17. edsl/jobs/Jobs.py +46 -90
  18. edsl/jobs/buckets/ModelBuckets.py +2 -4
  19. edsl/jobs/buckets/TokenBucket.py +2 -1
  20. edsl/jobs/interviews/Interview.py +9 -3
  21. edsl/jobs/interviews/InterviewStatusMixin.py +3 -3
  22. edsl/jobs/interviews/InterviewTaskBuildingMixin.py +10 -15
  23. edsl/jobs/runners/JobsRunnerAsyncio.py +25 -21
  24. edsl/jobs/tasks/TaskHistory.py +3 -4
  25. edsl/language_models/LanguageModel.py +11 -5
  26. edsl/language_models/ModelList.py +1 -1
  27. edsl/language_models/repair.py +7 -8
  28. edsl/notebooks/Notebook.py +3 -40
  29. edsl/prompts/Prompt.py +19 -31
  30. edsl/questions/QuestionBase.py +13 -38
  31. edsl/questions/QuestionBudget.py +6 -5
  32. edsl/questions/QuestionCheckBox.py +3 -7
  33. edsl/questions/QuestionExtract.py +3 -5
  34. edsl/questions/QuestionFreeText.py +3 -3
  35. edsl/questions/QuestionFunctional.py +3 -0
  36. edsl/questions/QuestionList.py +4 -3
  37. edsl/questions/QuestionMultipleChoice.py +8 -16
  38. edsl/questions/QuestionNumerical.py +3 -4
  39. edsl/questions/QuestionRank.py +3 -5
  40. edsl/questions/__init__.py +3 -4
  41. edsl/questions/descriptors.py +2 -4
  42. edsl/questions/question_registry.py +31 -20
  43. edsl/questions/settings.py +1 -1
  44. edsl/results/Dataset.py +0 -31
  45. edsl/results/Result.py +74 -22
  46. edsl/results/Results.py +47 -97
  47. edsl/results/ResultsDBMixin.py +3 -7
  48. edsl/results/ResultsExportMixin.py +537 -22
  49. edsl/results/ResultsGGMixin.py +3 -3
  50. edsl/results/ResultsToolsMixin.py +5 -5
  51. edsl/scenarios/Scenario.py +6 -5
  52. edsl/scenarios/ScenarioList.py +11 -34
  53. edsl/scenarios/ScenarioListPdfMixin.py +1 -2
  54. edsl/scenarios/__init__.py +0 -1
  55. edsl/study/Study.py +9 -3
  56. edsl/surveys/MemoryPlan.py +4 -11
  57. edsl/surveys/Survey.py +7 -46
  58. edsl/surveys/SurveyExportMixin.py +2 -4
  59. edsl/surveys/SurveyFlowVisualizationMixin.py +4 -6
  60. edsl/tools/plotting.py +2 -4
  61. edsl/utilities/__init__.py +21 -21
  62. edsl/utilities/interface.py +45 -66
  63. edsl/utilities/utilities.py +13 -11
  64. {edsl-0.1.29.dist-info → edsl-0.1.29.dev2.dist-info}/METADATA +10 -11
  65. {edsl-0.1.29.dist-info → edsl-0.1.29.dev2.dist-info}/RECORD +68 -71
  66. edsl-0.1.29.dev2.dist-info/entry_points.txt +3 -0
  67. edsl/base/Base.py +0 -289
  68. edsl/results/DatasetExportMixin.py +0 -493
  69. edsl/scenarios/FileStore.py +0 -140
  70. edsl/scenarios/ScenarioListExportMixin.py +0 -32
  71. {edsl-0.1.29.dist-info → edsl-0.1.29.dev2.dist-info}/LICENSE +0 -0
  72. {edsl-0.1.29.dist-info → edsl-0.1.29.dev2.dist-info}/WHEEL +0 -0
edsl/coop/coop.py CHANGED
@@ -5,14 +5,8 @@ import requests
5
5
  from typing import Any, Optional, Union, Literal
6
6
  from uuid import UUID
7
7
  import edsl
8
- from edsl import CONFIG, CacheEntry, Jobs, Survey
9
- from edsl.coop.utils import (
10
- EDSLObject,
11
- ObjectRegistry,
12
- ObjectType,
13
- RemoteJobStatus,
14
- VisibilityType,
15
- )
8
+ from edsl import CONFIG, CacheEntry
9
+ from edsl.coop.utils import EDSLObject, ObjectRegistry, ObjectType, VisibilityType
16
10
 
17
11
 
18
12
  class Coop:
@@ -94,18 +88,6 @@ class Coop:
94
88
  if value is None:
95
89
  return "null"
96
90
 
97
- def _resolve_uuid(
98
- self, uuid: Union[str, UUID] = None, url: str = None
99
- ) -> Union[str, UUID]:
100
- """
101
- Resolve the uuid from a uuid or a url.
102
- """
103
- if not url and not uuid:
104
- raise Exception("No uuid or url provided for the object.")
105
- if not uuid and url:
106
- uuid = url.split("/")[-1]
107
- return uuid
108
-
109
91
  @property
110
92
  def edsl_settings(self) -> dict:
111
93
  """
@@ -118,6 +100,9 @@ class Coop:
118
100
  ################
119
101
  # Objects
120
102
  ################
103
+
104
+ # TODO: add URL to get and get_all methods
105
+
121
106
  def create(
122
107
  self,
123
108
  object: EDSLObject,
@@ -128,16 +113,17 @@ class Coop:
128
113
  Create an EDSL object in the Coop server.
129
114
  """
130
115
  object_type = ObjectRegistry.get_object_type_by_edsl_class(object)
116
+ object_page = ObjectRegistry.get_object_page_by_object_type(object_type)
131
117
  response = self._send_server_request(
132
118
  uri=f"api/v0/object",
133
119
  method="POST",
134
120
  payload={
135
121
  "description": description,
122
+ "object_type": object_type,
136
123
  "json_string": json.dumps(
137
124
  object.to_dict(),
138
125
  default=self._json_handle_none,
139
126
  ),
140
- "object_type": object_type,
141
127
  "visibility": visibility,
142
128
  "version": self._edsl_version,
143
129
  },
@@ -145,51 +131,73 @@ class Coop:
145
131
  self._resolve_server_response(response)
146
132
  response_json = response.json()
147
133
  return {
148
- "description": response_json.get("description"),
149
- "object_type": object_type,
150
- "url": f"{self.url}/content/{response_json.get('uuid')}",
151
134
  "uuid": response_json.get("uuid"),
152
135
  "version": self._edsl_version,
136
+ "description": response_json.get("description"),
153
137
  "visibility": response_json.get("visibility"),
138
+ "url": f"{self.url}/content/{response_json.get('uuid')}",
154
139
  }
155
140
 
156
141
  def get(
157
142
  self,
143
+ object_type: ObjectType = None,
158
144
  uuid: Union[str, UUID] = None,
159
145
  url: str = None,
160
- expected_object_type: Optional[ObjectType] = None,
146
+ exec_profile=None,
161
147
  ) -> EDSLObject:
162
148
  """
163
- Retrieve an EDSL object by its uuid or its url.
164
- - If the object's visibility is private, the user must be the owner.
165
- - Optionally, check if the retrieved object is of a certain type.
149
+ Retrieve an EDSL object either by object type & UUID, or by its url.
150
+ - The object has to belong to the user or not be private.
151
+ - Returns the initialized object class instance.
166
152
 
153
+ :param object_type: the type of object to retrieve.
167
154
  :param uuid: the uuid of the object either in str or UUID format.
168
155
  :param url: the url of the object.
169
- :param expected_object_type: the expected type of the object.
170
-
171
- :return: the object instance.
172
156
  """
173
- uuid = self._resolve_uuid(uuid, url)
157
+ if url:
158
+ object_type = url.split("/")[-2]
159
+ uuid = url.split("/")[-1]
160
+ elif not object_type and not uuid:
161
+ raise Exception("Provide either object_type & UUID, or a url.")
162
+ edsl_class = ObjectRegistry.object_type_to_edsl_class.get(object_type)
163
+ import time
164
+
165
+ start = time.time()
174
166
  response = self._send_server_request(
175
167
  uri=f"api/v0/object",
176
168
  method="GET",
177
- params={"uuid": uuid},
169
+ params={"type": object_type, "uuid": uuid},
178
170
  )
171
+ end = time.time()
172
+ if exec_profile:
173
+ print("Download exec time = ", end - start)
179
174
  self._resolve_server_response(response)
180
175
  json_string = response.json().get("json_string")
181
- object_type = response.json().get("object_type")
182
- if expected_object_type and object_type != expected_object_type:
183
- raise Exception(f"Expected {expected_object_type=} but got {object_type=}")
184
- edsl_class = ObjectRegistry.object_type_to_edsl_class.get(object_type)
185
- object = edsl_class.from_dict(json.loads(json_string))
186
- return object
176
+ start = time.time()
177
+ res_object = edsl_class.from_dict(json.loads(json_string))
178
+ end = time.time()
179
+ if exec_profile:
180
+ print("Creating object exec time = ", end - start)
181
+ return res_object
182
+
183
+ def _get_base(
184
+ self,
185
+ cls: EDSLObject,
186
+ uuid: Union[str, UUID],
187
+ exec_profile=None,
188
+ ) -> EDSLObject:
189
+ """
190
+ Used by the Base class to offer a get functionality.
191
+ """
192
+ object_type = ObjectRegistry.get_object_type_by_edsl_class(cls)
193
+ return self.get(object_type, uuid, exec_profile=exec_profile)
187
194
 
188
- def get_all(self, object_type: ObjectType) -> list[dict[str, Any]]:
195
+ def get_all(self, object_type: ObjectType) -> list[EDSLObject]:
189
196
  """
190
197
  Retrieve all objects of a certain type associated with the user.
191
198
  """
192
199
  edsl_class = ObjectRegistry.object_type_to_edsl_class.get(object_type)
200
+ object_page = ObjectRegistry.get_object_page_by_object_type(object_type)
193
201
  response = self._send_server_request(
194
202
  uri=f"api/v0/objects",
195
203
  method="GET",
@@ -209,23 +217,33 @@ class Coop:
209
217
  ]
210
218
  return objects
211
219
 
212
- def delete(self, uuid: Union[str, UUID] = None, url: str = None) -> dict:
220
+ def delete(self, object_type: ObjectType, uuid: Union[str, UUID]) -> dict:
213
221
  """
214
222
  Delete an object from the server.
215
223
  """
216
- uuid = self._resolve_uuid(uuid, url)
217
224
  response = self._send_server_request(
218
225
  uri=f"api/v0/object",
219
226
  method="DELETE",
220
- params={"uuid": uuid},
227
+ params={"type": object_type, "uuid": uuid},
221
228
  )
222
229
  self._resolve_server_response(response)
223
230
  return response.json()
224
231
 
232
+ def _delete_base(
233
+ self,
234
+ cls: EDSLObject,
235
+ uuid: Union[str, UUID],
236
+ ) -> dict:
237
+ """
238
+ Used by the Base class to offer a delete functionality.
239
+ """
240
+ object_type = ObjectRegistry.get_object_type_by_edsl_class(cls)
241
+ return self.delete(object_type, uuid)
242
+
225
243
  def patch(
226
244
  self,
227
- uuid: Union[str, UUID] = None,
228
- url: str = None,
245
+ object_type: ObjectType,
246
+ uuid: Union[str, UUID],
229
247
  description: Optional[str] = None,
230
248
  value: Optional[EDSLObject] = None,
231
249
  visibility: Optional[VisibilityType] = None,
@@ -236,11 +254,14 @@ class Coop:
236
254
  """
237
255
  if description is None and visibility is None and value is None:
238
256
  raise Exception("Nothing to patch.")
239
- uuid = self._resolve_uuid(uuid, url)
257
+ if value is not None:
258
+ value_type = ObjectRegistry.get_object_type_by_edsl_class(value)
259
+ if value_type != object_type:
260
+ raise Exception(f"Object type mismatch: {object_type=} {value_type=}")
240
261
  response = self._send_server_request(
241
262
  uri=f"api/v0/object",
242
263
  method="PATCH",
243
- params={"uuid": uuid},
264
+ params={"type": object_type, "uuid": uuid},
244
265
  payload={
245
266
  "description": description,
246
267
  "json_string": (
@@ -257,6 +278,20 @@ class Coop:
257
278
  self._resolve_server_response(response)
258
279
  return response.json()
259
280
 
281
+ def _patch_base(
282
+ self,
283
+ cls: EDSLObject,
284
+ uuid: Union[str, UUID],
285
+ description: Optional[str] = None,
286
+ value: Optional[EDSLObject] = None,
287
+ visibility: Optional[VisibilityType] = None,
288
+ ) -> dict:
289
+ """
290
+ Used by the Base class to offer a patch functionality.
291
+ """
292
+ object_type = ObjectRegistry.get_object_type_by_edsl_class(cls)
293
+ return self.patch(object_type, uuid, description, value, visibility)
294
+
260
295
  ################
261
296
  # Remote Cache
262
297
  ################
@@ -459,57 +494,9 @@ class Coop:
459
494
  ################
460
495
  # Remote Inference
461
496
  ################
462
- def remote_inference_create(
463
- self,
464
- job: Jobs,
465
- description: Optional[str] = None,
466
- status: RemoteJobStatus = "queued",
467
- visibility: Optional[VisibilityType] = "unlisted",
468
- ) -> dict:
469
- """
470
- Send a remote inference job to the server.
471
-
472
- :param job: The EDSL job to send to the server.
473
- :param optional description: A description for this entry in the remote cache.
474
- :param status: The status of the job. Should be 'queued', unless you are debugging.
475
- :param visibility: The visibility of the cache entry.
476
-
477
- >>> job = Jobs.example()
478
- >>> coop.remote_inference_create(job=job, description="My job")
479
- {'uuid': '9f8484ee-b407-40e4-9652-4133a7236c9c', 'description': 'My job', 'status': 'queued', 'visibility': 'unlisted', 'version': '0.1.29.dev4'}
480
- """
481
- response = self._send_server_request(
482
- uri="api/v0/remote-inference",
483
- method="POST",
484
- payload={
485
- "json_string": json.dumps(
486
- job.to_dict(),
487
- default=self._json_handle_none,
488
- ),
489
- "description": description,
490
- "status": status,
491
- "visibility": visibility,
492
- "version": self._edsl_version,
493
- },
494
- )
495
- self._resolve_server_response(response)
496
- response_json = response.json()
497
- return {
498
- "uuid": response_json.get("jobs_uuid"),
499
- "description": response_json.get("description"),
500
- "status": response_json.get("status"),
501
- "visibility": response_json.get("visibility"),
502
- "version": self._edsl_version,
503
- }
504
-
505
497
  def remote_inference_get(self, job_uuid: str) -> dict:
506
498
  """
507
- Get the details of a remote inference job.
508
-
509
- :param job_uuid: The UUID of the EDSL job.
510
-
511
- >>> coop.remote_inference_get("9f8484ee-b407-40e4-9652-4133a7236c9c")
512
- {'jobs_uuid': '9f8484ee-b407-40e4-9652-4133a7236c9c', 'results_uuid': 'dd708234-31bf-4fe1-8747-6e232625e026', 'results_url': 'https://www.expectedparrot.com/content/dd708234-31bf-4fe1-8747-6e232625e026', 'status': 'completed', 'reason': None, 'price': 16, 'version': '0.1.29.dev4'}
499
+ Get the results of a remote inference job.
513
500
  """
514
501
  response = self._send_server_request(
515
502
  uri="api/v0/remote-inference",
@@ -521,44 +508,13 @@ class Coop:
521
508
  return {
522
509
  "jobs_uuid": data.get("jobs_uuid"),
523
510
  "results_uuid": data.get("results_uuid"),
524
- "results_url": f"{self.url}/content/{data.get('results_uuid')}",
511
+ "results_url": "TO BE ADDED",
525
512
  "status": data.get("status"),
526
513
  "reason": data.get("reason"),
527
514
  "price": data.get("price"),
528
515
  "version": data.get("version"),
529
516
  }
530
517
 
531
- def remote_inference_cost(self, input: Union[Jobs, Survey]) -> int:
532
- """
533
- Get the cost of a remote inference job.
534
-
535
- :param input: The EDSL job to send to the server.
536
-
537
- >>> job = Jobs.example()
538
- >>> coop.remote_inference_cost(input=job)
539
- 16
540
- """
541
- if isinstance(input, Jobs):
542
- job = input
543
- elif isinstance(input, Survey):
544
- job = Jobs(survey=input)
545
- else:
546
- raise TypeError("Input must be either a Job or a Survey.")
547
-
548
- response = self._send_server_request(
549
- uri="api/v0/remote-inference/cost",
550
- method="POST",
551
- payload={
552
- "json_string": json.dumps(
553
- job.to_dict(),
554
- default=self._json_handle_none,
555
- ),
556
- },
557
- )
558
- self._resolve_server_response(response)
559
- response_json = response.json()
560
- return response_json.get("cost")
561
-
562
518
  ################
563
519
  # Remote Errors
564
520
  ################
@@ -622,65 +578,32 @@ class Coop:
622
578
  return response_json
623
579
 
624
580
 
625
- def main():
626
- """
627
- A simple example for the coop client
628
- """
581
+ if __name__ == "__main__":
582
+ from edsl.coop import Coop
583
+
584
+ # init
585
+ API_KEY = "b"
586
+ coop = Coop(api_key=API_KEY)
587
+ # basics
588
+ coop
589
+ coop.edsl_settings
590
+
591
+ ##############
592
+ # A. Objects
593
+ ##############
629
594
  from uuid import uuid4
630
595
  from edsl import (
631
596
  Agent,
632
597
  AgentList,
633
598
  Cache,
634
599
  Notebook,
635
- QuestionFreeText,
636
600
  QuestionMultipleChoice,
637
601
  Results,
638
602
  Scenario,
639
603
  ScenarioList,
640
604
  Survey,
641
605
  )
642
- from edsl.coop import Coop
643
- from edsl.data.CacheEntry import CacheEntry
644
- from edsl.jobs import Jobs
645
-
646
- # init & basics
647
- API_KEY = "b"
648
- coop = Coop(api_key=API_KEY)
649
- coop
650
- coop.edsl_settings
651
606
 
652
- ##############
653
- # A. A simple example
654
- ##############
655
- # .. create and manipulate an object through the Coop client
656
- response = coop.create(QuestionMultipleChoice.example())
657
- coop.get(uuid=response.get("uuid"))
658
- coop.get(uuid=response.get("uuid"), expected_object_type="question")
659
- coop.get(url=response.get("url"))
660
- coop.create(QuestionMultipleChoice.example())
661
- coop.get_all("question")
662
- coop.patch(uuid=response.get("uuid"), visibility="private")
663
- coop.patch(uuid=response.get("uuid"), description="hey")
664
- coop.patch(uuid=response.get("uuid"), value=QuestionFreeText.example())
665
- # coop.patch(uuid=response.get("uuid"), value=Survey.example()) - should throw error
666
- coop.get(uuid=response.get("uuid"))
667
- coop.delete(uuid=response.get("uuid"))
668
-
669
- # .. create and manipulate an object through the class
670
- response = QuestionMultipleChoice.example().push()
671
- QuestionMultipleChoice.pull(uuid=response.get("uuid"))
672
- QuestionMultipleChoice.pull(url=response.get("url"))
673
- QuestionMultipleChoice.patch(uuid=response.get("uuid"), visibility="private")
674
- QuestionMultipleChoice.patch(uuid=response.get("uuid"), description="hey")
675
- QuestionMultipleChoice.patch(
676
- uuid=response.get("uuid"), value=QuestionFreeText.example()
677
- )
678
- QuestionMultipleChoice.pull(response.get("uuid"))
679
- QuestionMultipleChoice.delete(response.get("uuid"))
680
-
681
- ##############
682
- # B. Examples with all objects
683
- ##############
684
607
  OBJECTS = [
685
608
  ("agent", Agent),
686
609
  ("agent_list", AgentList),
@@ -692,12 +615,13 @@ def main():
692
615
  ("scenario_list", ScenarioList),
693
616
  ("survey", Survey),
694
617
  ]
618
+
695
619
  for object_type, cls in OBJECTS:
696
620
  print(f"Testing {object_type} objects")
697
621
  # 1. Delete existing objects
698
622
  existing_objects = coop.get_all(object_type)
699
623
  for item in existing_objects:
700
- coop.delete(uuid=item.get("uuid"))
624
+ coop.delete(object_type=object_type, uuid=item.get("uuid"))
701
625
  # 2. Create new objects
702
626
  example = cls.example()
703
627
  response_1 = coop.create(example)
@@ -711,26 +635,51 @@ def main():
711
635
  assert len(objects) == 4
712
636
  # 4. Try to retrieve an item that does not exist
713
637
  try:
714
- coop.get(uuid=uuid4())
638
+ coop.get(object_type=object_type, uuid=uuid4())
715
639
  except Exception as e:
716
640
  print(e)
717
641
  # 5. Try to retrieve all test objects by their uuids
718
642
  for response in [response_1, response_2, response_3, response_4]:
719
- coop.get(uuid=response.get("uuid"))
643
+ coop.get(object_type=object_type, uuid=response.get("uuid"))
720
644
  # 6. Change visibility of all objects
721
645
  for item in objects:
722
- coop.patch(uuid=item.get("uuid"), visibility="private")
646
+ coop.patch(
647
+ object_type=object_type, uuid=item.get("uuid"), visibility="private"
648
+ )
723
649
  # 6. Change description of all objects
724
650
  for item in objects:
725
- coop.patch(uuid=item.get("uuid"), description="hey")
651
+ coop.patch(
652
+ object_type=object_type, uuid=item.get("uuid"), description="hey"
653
+ )
726
654
  # 7. Delete all objects
727
655
  for item in objects:
728
- coop.delete(uuid=item.get("uuid"))
656
+ coop.delete(object_type=object_type, uuid=item.get("uuid"))
729
657
  assert len(coop.get_all(object_type)) == 0
730
658
 
659
+ # a simple example
660
+ from edsl import Coop, QuestionMultipleChoice, QuestionFreeText
661
+
662
+ coop = Coop(api_key="b")
663
+ response = QuestionMultipleChoice.example().push()
664
+ QuestionMultipleChoice.pull(response.get("uuid"))
665
+ coop.patch(object_type="question", uuid=response.get("uuid"), visibility="public")
666
+ coop.patch(
667
+ object_type="question",
668
+ uuid=response.get("uuid"),
669
+ description="crazy new description",
670
+ )
671
+ coop.patch(
672
+ object_type="question",
673
+ uuid=response.get("uuid"),
674
+ value=QuestionFreeText.example(),
675
+ )
676
+ coop.delete(object_type="question", uuid=response.get("uuid"))
677
+
731
678
  ##############
732
- # C. Remote Cache
679
+ # B. Remote Cache
733
680
  ##############
681
+ from edsl.data.CacheEntry import CacheEntry
682
+
734
683
  # clear
735
684
  coop.remote_cache_clear()
736
685
  assert coop.remote_cache_get() == []
@@ -752,16 +701,30 @@ def main():
752
701
  coop.remote_cache_get()
753
702
 
754
703
  ##############
755
- # D. Remote Inference
704
+ # C. Remote Inference
756
705
  ##############
757
- job = Jobs.example()
758
- coop.remote_inference_cost(job)
759
- results = coop.remote_inference_create(job)
760
- coop.remote_inference_get(results.get("uuid"))
706
+ from edsl.jobs import Jobs
707
+
708
+ # check jobs on server (should be an empty list)
709
+ coop.get_all("job")
710
+ for job in coop.get_all("job"):
711
+ coop.delete(object_type="job", uuid=job.get("uuid"))
712
+ # post a job
713
+ response = coop.create(Jobs.example())
714
+ # get job and results
715
+ coop.remote_inference_get(response.get("uuid"))
716
+ coop.get(
717
+ object_type="results",
718
+ uuid=coop.remote_inference_get(response.get("uuid")).get("results_uuid"),
719
+ )
761
720
 
762
721
  ##############
763
- # E. Errors
722
+ # D. Errors
764
723
  ##############
724
+ from edsl import Coop
725
+
726
+ coop = Coop()
727
+ coop.api_key = "a"
765
728
  coop.error_create({"something": "This is an error message"})
766
729
  coop.api_key = None
767
730
  coop.error_create({"something": "This is an error message"})
edsl/coop/utils.py CHANGED
@@ -2,6 +2,7 @@ from edsl import (
2
2
  Agent,
3
3
  AgentList,
4
4
  Cache,
5
+ Jobs,
5
6
  Notebook,
6
7
  Results,
7
8
  Scenario,
@@ -10,12 +11,13 @@ from edsl import (
10
11
  Study,
11
12
  )
12
13
  from edsl.questions import QuestionBase
13
- from typing import Literal, Optional, Type, Union
14
+ from typing import Literal, Type, Union
14
15
 
15
16
  EDSLObject = Union[
16
17
  Agent,
17
18
  AgentList,
18
19
  Cache,
20
+ Jobs,
19
21
  Notebook,
20
22
  Type[QuestionBase],
21
23
  Results,
@@ -29,8 +31,9 @@ ObjectType = Literal[
29
31
  "agent",
30
32
  "agent_list",
31
33
  "cache",
32
- "notebook",
34
+ "job",
33
35
  "question",
36
+ "notebook",
34
37
  "results",
35
38
  "scenario",
36
39
  "scenario_list",
@@ -38,12 +41,18 @@ ObjectType = Literal[
38
41
  "study",
39
42
  ]
40
43
 
41
-
42
- RemoteJobStatus = Literal[
43
- "queued",
44
- "running",
45
- "completed",
46
- "failed",
44
+ ObjectPage = Literal[
45
+ "agents",
46
+ "agentlists",
47
+ "caches",
48
+ "jobs",
49
+ "notebooks",
50
+ "questions",
51
+ "results",
52
+ "scenarios",
53
+ "scenariolists",
54
+ "surveys",
55
+ "studies",
47
56
  ]
48
57
 
49
58
  VisibilityType = Literal[
@@ -59,21 +68,67 @@ class ObjectRegistry:
59
68
  """
60
69
 
61
70
  objects = [
62
- {"object_type": "agent", "edsl_class": Agent},
63
- {"object_type": "agent_list", "edsl_class": AgentList},
64
- {"object_type": "cache", "edsl_class": Cache},
65
- {"object_type": "question", "edsl_class": QuestionBase},
66
- {"object_type": "notebook", "edsl_class": Notebook},
67
- {"object_type": "results", "edsl_class": Results},
68
- {"object_type": "scenario", "edsl_class": Scenario},
69
- {"object_type": "scenario_list", "edsl_class": ScenarioList},
70
- {"object_type": "survey", "edsl_class": Survey},
71
- {"object_type": "study", "edsl_class": Study},
71
+ {
72
+ "object_type": "agent",
73
+ "edsl_class": Agent,
74
+ "object_page": "agents",
75
+ },
76
+ {
77
+ "object_type": "agent_list",
78
+ "edsl_class": AgentList,
79
+ "object_page": "agentlists",
80
+ },
81
+ {
82
+ "object_type": "cache",
83
+ "edsl_class": Cache,
84
+ "object_page": "caches",
85
+ },
86
+ {
87
+ "object_type": "job",
88
+ "edsl_class": Jobs,
89
+ "object_page": "jobs",
90
+ },
91
+ {
92
+ "object_type": "question",
93
+ "edsl_class": QuestionBase,
94
+ "object_page": "questions",
95
+ },
96
+ {
97
+ "object_type": "notebook",
98
+ "edsl_class": Notebook,
99
+ "object_page": "notebooks",
100
+ },
101
+ {
102
+ "object_type": "results",
103
+ "edsl_class": Results,
104
+ "object_page": "results",
105
+ },
106
+ {
107
+ "object_type": "scenario",
108
+ "edsl_class": Scenario,
109
+ "object_page": "scenarios",
110
+ },
111
+ {
112
+ "object_type": "scenario_list",
113
+ "edsl_class": ScenarioList,
114
+ "object_page": "scenariolists",
115
+ },
116
+ {
117
+ "object_type": "survey",
118
+ "edsl_class": Survey,
119
+ "object_page": "surveys",
120
+ },
121
+ {
122
+ "object_type": "study",
123
+ "edsl_class": Study,
124
+ "object_page": "studies",
125
+ },
72
126
  ]
73
127
  object_type_to_edsl_class = {o["object_type"]: o["edsl_class"] for o in objects}
74
128
  edsl_class_to_object_type = {
75
129
  o["edsl_class"].__name__: o["object_type"] for o in objects
76
130
  }
131
+ object_type_to_object_page = {o["object_type"]: o["object_page"] for o in objects}
77
132
 
78
133
  @classmethod
79
134
  def get_object_type_by_edsl_class(cls, edsl_object: EDSLObject) -> ObjectType:
@@ -96,28 +151,5 @@ class ObjectRegistry:
96
151
  return EDSL_object
97
152
 
98
153
  @classmethod
99
- def get_registry(
100
- cls,
101
- subclass_registry: Optional[dict] = None,
102
- exclude_classes: Optional[list] = None,
103
- ) -> dict:
104
- """
105
- Return the registry of objects.
106
-
107
- Exclude objects that are already registered in subclass_registry.
108
- This allows the user to isolate Coop-only objects.
109
-
110
- Also exclude objects if their class name is in the exclude_classes list.
111
- """
112
-
113
- if subclass_registry is None:
114
- subclass_registry = {}
115
- if exclude_classes is None:
116
- exclude_classes = []
117
-
118
- return {
119
- class_name: o["edsl_class"]
120
- for o in cls.objects
121
- if (class_name := o["edsl_class"].__name__) not in subclass_registry
122
- and class_name not in exclude_classes
123
- }
154
+ def get_object_page_by_object_type(cls, object_type: ObjectType) -> ObjectPage:
155
+ return cls.object_type_to_object_page.get(object_type)