edsl 0.1.45__py3-none-any.whl → 0.1.47__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 (44) hide show
  1. edsl/Base.py +87 -16
  2. edsl/__version__.py +1 -1
  3. edsl/agents/PromptConstructor.py +26 -79
  4. edsl/agents/QuestionInstructionPromptBuilder.py +70 -32
  5. edsl/agents/QuestionTemplateReplacementsBuilder.py +12 -2
  6. edsl/coop/coop.py +289 -147
  7. edsl/data/Cache.py +2 -0
  8. edsl/data/CacheEntry.py +10 -2
  9. edsl/data/RemoteCacheSync.py +10 -9
  10. edsl/inference_services/AvailableModelFetcher.py +1 -1
  11. edsl/inference_services/PerplexityService.py +9 -5
  12. edsl/jobs/AnswerQuestionFunctionConstructor.py +12 -1
  13. edsl/jobs/Jobs.py +35 -17
  14. edsl/jobs/JobsComponentConstructor.py +2 -1
  15. edsl/jobs/JobsPrompts.py +49 -26
  16. edsl/jobs/JobsRemoteInferenceHandler.py +4 -5
  17. edsl/jobs/data_structures.py +3 -0
  18. edsl/jobs/interviews/Interview.py +6 -3
  19. edsl/language_models/LanguageModel.py +7 -1
  20. edsl/questions/QuestionBase.py +5 -0
  21. edsl/questions/question_base_gen_mixin.py +2 -0
  22. edsl/questions/question_registry.py +6 -7
  23. edsl/results/DatasetExportMixin.py +124 -6
  24. edsl/results/Results.py +59 -0
  25. edsl/scenarios/FileStore.py +112 -7
  26. edsl/scenarios/ScenarioList.py +283 -21
  27. edsl/study/Study.py +2 -2
  28. edsl/surveys/Survey.py +15 -20
  29. {edsl-0.1.45.dist-info → edsl-0.1.47.dist-info}/METADATA +4 -3
  30. {edsl-0.1.45.dist-info → edsl-0.1.47.dist-info}/RECORD +32 -44
  31. edsl/auto/AutoStudy.py +0 -130
  32. edsl/auto/StageBase.py +0 -243
  33. edsl/auto/StageGenerateSurvey.py +0 -178
  34. edsl/auto/StageLabelQuestions.py +0 -125
  35. edsl/auto/StagePersona.py +0 -61
  36. edsl/auto/StagePersonaDimensionValueRanges.py +0 -88
  37. edsl/auto/StagePersonaDimensionValues.py +0 -74
  38. edsl/auto/StagePersonaDimensions.py +0 -69
  39. edsl/auto/StageQuestions.py +0 -74
  40. edsl/auto/SurveyCreatorPipeline.py +0 -21
  41. edsl/auto/utilities.py +0 -218
  42. edsl/base/Base.py +0 -279
  43. {edsl-0.1.45.dist-info → edsl-0.1.47.dist-info}/LICENSE +0 -0
  44. {edsl-0.1.45.dist-info → edsl-0.1.47.dist-info}/WHEEL +0 -0
edsl/coop/coop.py CHANGED
@@ -287,19 +287,25 @@ class Coop(CoopFunctionsMixin):
287
287
  if value is None:
288
288
  return "null"
289
289
 
290
+ @staticmethod
291
+ def _is_url(url_or_uuid: Union[str, UUID]) -> bool:
292
+ return "http://" in str(url_or_uuid) or "https://" in str(url_or_uuid)
293
+
290
294
  def _resolve_uuid_or_alias(
291
- self, uuid: Union[str, UUID] = None, url: str = None
295
+ self, url_or_uuid: Union[str, UUID]
292
296
  ) -> tuple[Optional[str], Optional[str], Optional[str]]:
293
297
  """
294
298
  Resolve the uuid or alias information from a uuid or a url.
295
299
  Returns a tuple of (uuid, owner_username, alias)
296
- - For content/<uuid> URLs: returns (uuid, None, None)
297
- - For content/<username>/<alias> URLs: returns (None, username, alias)
300
+ - For content/uuid URLs: returns (uuid, None, None)
301
+ - For content/username/alias URLs: returns (None, username, alias)
298
302
  """
299
- if not url and not uuid:
303
+ if not url_or_uuid:
300
304
  raise CoopNoUUIDError("No uuid or url provided for the object.")
301
305
 
302
- if not uuid and url:
306
+ if self._is_url(url_or_uuid):
307
+ url = str(url_or_uuid)
308
+
303
309
  parts = (
304
310
  url.replace("http://", "")
305
311
  .replace("https://", "")
@@ -326,7 +332,8 @@ class Coop(CoopFunctionsMixin):
326
332
  f"Invalid URL format. The URL must end with /content/<uuid> or /content/<username>/<alias>: {url}"
327
333
  )
328
334
 
329
- return str(uuid), None, None
335
+ uuid = str(url_or_uuid)
336
+ return uuid, None, None
330
337
 
331
338
  @property
332
339
  def edsl_settings(self) -> dict:
@@ -348,6 +355,15 @@ class Coop(CoopFunctionsMixin):
348
355
  ################
349
356
  # Objects
350
357
  ################
358
+ def _get_alias_url(self, owner_username: str, alias: str) -> Union[str, None]:
359
+ """
360
+ Get the URL of an object by its owner username and alias.
361
+ """
362
+ if owner_username and alias:
363
+ return f"{self.url}/content/{owner_username}/{alias}"
364
+ else:
365
+ return None
366
+
351
367
  def create(
352
368
  self,
353
369
  object: EDSLObject,
@@ -368,7 +384,9 @@ class Coop(CoopFunctionsMixin):
368
384
  "json_string": json.dumps(
369
385
  object.to_dict(),
370
386
  default=self._json_handle_none,
371
- ),
387
+ )
388
+ if object_type != "scenario"
389
+ else "",
372
390
  "object_type": object_type,
373
391
  "visibility": visibility,
374
392
  "version": self._edsl_version,
@@ -376,19 +394,38 @@ class Coop(CoopFunctionsMixin):
376
394
  )
377
395
  self._resolve_server_response(response)
378
396
  response_json = response.json()
397
+
398
+ if object_type == "scenario":
399
+ json_data = json.dumps(
400
+ object.to_dict(),
401
+ default=self._json_handle_none,
402
+ )
403
+ headers = {"Content-Type": "application/json"}
404
+ if response_json.get("upload_signed_url"):
405
+ signed_url = response_json.get("upload_signed_url")
406
+ else:
407
+ raise Exception("No signed url provided received")
408
+
409
+ response = requests.put(
410
+ signed_url, data=json_data.encode(), headers=headers
411
+ )
412
+ owner_username = response_json.get("owner_username")
413
+ object_alias = response_json.get("alias")
414
+
379
415
  return {
380
416
  "description": response_json.get("description"),
381
417
  "object_type": object_type,
382
418
  "url": f"{self.url}/content/{response_json.get('uuid')}",
419
+ "alias_url": self._get_alias_url(owner_username, object_alias),
383
420
  "uuid": response_json.get("uuid"),
384
421
  "version": self._edsl_version,
385
422
  "visibility": response_json.get("visibility"),
423
+ "upload_signed_url": response_json.get("upload_signed_url", None),
386
424
  }
387
425
 
388
426
  def get(
389
427
  self,
390
- uuid: Union[str, UUID] = None,
391
- url: str = None,
428
+ url_or_uuid: Union[str, UUID],
392
429
  expected_object_type: Optional[ObjectType] = None,
393
430
  ) -> EDSLObject:
394
431
  """
@@ -396,13 +433,13 @@ class Coop(CoopFunctionsMixin):
396
433
  - If the object's visibility is private, the user must be the owner.
397
434
  - Optionally, check if the retrieved object is of a certain type.
398
435
 
399
- :param uuid: the uuid of the object either in str or UUID format.
400
- :param url: the url of the object (can be content/uuid or content/username/alias format).
401
- :param expected_object_type: the expected type of the object.
436
+ :param url_or_uuid: The UUID or URL of the object.
437
+ URLs can be in the form content/uuid or content/username/alias.
438
+ :param expected_object_type: The expected type of the object.
402
439
 
403
440
  :return: the object instance.
404
441
  """
405
- obj_uuid, owner_username, alias = self._resolve_uuid_or_alias(uuid, url)
442
+ obj_uuid, owner_username, alias = self._resolve_uuid_or_alias(url_or_uuid)
406
443
 
407
444
  if obj_uuid:
408
445
  response = self._send_server_request(
@@ -419,6 +456,10 @@ class Coop(CoopFunctionsMixin):
419
456
 
420
457
  self._resolve_server_response(response)
421
458
  json_string = response.json().get("json_string")
459
+ if "load_from:" in json_string[0:12]:
460
+ load_link = json_string.split("load_from:")[1]
461
+ object_data = requests.get(load_link)
462
+ json_string = object_data.text
422
463
  object_type = response.json().get("object_type")
423
464
  if expected_object_type and object_type != expected_object_type:
424
465
  raise Exception(f"Expected {expected_object_type=} but got {object_type=}")
@@ -437,28 +478,51 @@ class Coop(CoopFunctionsMixin):
437
478
  params={"type": object_type},
438
479
  )
439
480
  self._resolve_server_response(response)
440
- objects = [
441
- {
442
- "object": edsl_class.from_dict(json.loads(o.get("json_string"))),
481
+ objects = []
482
+ for o in response.json():
483
+ json_string = o.get("json_string")
484
+ ## check if load from bucket needed.
485
+ if "load_from:" in json_string[0:12]:
486
+ load_link = json_string.split("load_from:")[1]
487
+ object_data = requests.get(load_link)
488
+ json_string = object_data.text
489
+
490
+ json_string = json.loads(json_string)
491
+ object = {
492
+ "object": edsl_class.from_dict(json_string),
443
493
  "uuid": o.get("uuid"),
444
494
  "version": o.get("version"),
445
495
  "description": o.get("description"),
446
496
  "visibility": o.get("visibility"),
447
497
  "url": f"{self.url}/content/{o.get('uuid')}",
498
+ "alias_url": self._get_alias_url(
499
+ o.get("owner_username"), o.get("alias")
500
+ ),
448
501
  }
449
- for o in response.json()
450
- ]
502
+ objects.append(object)
503
+
451
504
  return objects
452
505
 
453
- def delete(self, uuid: Union[str, UUID] = None, url: str = None) -> dict:
506
+ def delete(self, url_or_uuid: Union[str, UUID]) -> dict:
454
507
  """
455
508
  Delete an object from the server.
509
+
510
+ :param url_or_uuid: The UUID or URL of the object.
511
+ URLs can be in the form content/uuid or content/username/alias.
456
512
  """
457
- obj_uuid, _, _ = self._resolve_uuid_or_alias(uuid, url)
513
+ obj_uuid, owner_username, alias = self._resolve_uuid_or_alias(url_or_uuid)
514
+
515
+ if obj_uuid:
516
+ uri = "api/v0/object"
517
+ params = {"uuid": obj_uuid}
518
+ else:
519
+ uri = "api/v0/object/alias"
520
+ params = {"owner_username": owner_username, "alias": alias}
521
+
458
522
  response = self._send_server_request(
459
- uri=f"api/v0/object",
523
+ uri=uri,
460
524
  method="DELETE",
461
- params={"uuid": obj_uuid},
525
+ params=params,
462
526
  )
463
527
 
464
528
  self._resolve_server_response(response)
@@ -466,8 +530,7 @@ class Coop(CoopFunctionsMixin):
466
530
 
467
531
  def patch(
468
532
  self,
469
- uuid: Union[str, UUID] = None,
470
- url: str = None,
533
+ url_or_uuid: Union[str, UUID],
471
534
  description: Optional[str] = None,
472
535
  alias: Optional[str] = None,
473
536
  value: Optional[EDSLObject] = None,
@@ -475,15 +538,35 @@ class Coop(CoopFunctionsMixin):
475
538
  ) -> dict:
476
539
  """
477
540
  Change the attributes of an uploaded object
478
- - Only supports visibility for now
479
- """
480
- if description is None and visibility is None and value is None:
541
+
542
+ :param url_or_uuid: The UUID or URL of the object.
543
+ URLs can be in the form content/uuid or content/username/alias.
544
+ :param description: Optional new description
545
+ :param alias: Optional new alias
546
+ :param value: Optional new object value
547
+ :param visibility: Optional new visibility setting
548
+ """
549
+ if (
550
+ description is None
551
+ and visibility is None
552
+ and value is None
553
+ and alias is None
554
+ ):
481
555
  raise Exception("Nothing to patch.")
482
- obj_uuid, _, _ = self._resolve_uuid_or_alias(uuid, url)
556
+
557
+ obj_uuid, owner_username, obj_alias = self._resolve_uuid_or_alias(url_or_uuid)
558
+
559
+ if obj_uuid:
560
+ uri = "api/v0/object"
561
+ params = {"uuid": obj_uuid}
562
+ else:
563
+ uri = "api/v0/object/alias"
564
+ params = {"owner_username": owner_username, "alias": obj_alias}
565
+
483
566
  response = self._send_server_request(
484
- uri=f"api/v0/object",
567
+ uri=uri,
485
568
  method="PATCH",
486
- params={"uuid": obj_uuid},
569
+ params=params,
487
570
  payload={
488
571
  "description": description,
489
572
  "alias": alias,
@@ -504,90 +587,146 @@ class Coop(CoopFunctionsMixin):
504
587
  ################
505
588
  # Remote Cache
506
589
  ################
507
- def remote_cache_create(
590
+ # def remote_cache_create(
591
+ # self,
592
+ # cache_entry: CacheEntry,
593
+ # visibility: VisibilityType = "private",
594
+ # description: Optional[str] = None,
595
+ # ) -> dict:
596
+ # """
597
+ # Create a single remote cache entry.
598
+ # If an entry with the same key already exists in the database, update it instead.
599
+
600
+ # :param cache_entry: The cache entry to send to the server.
601
+ # :param visibility: The visibility of the cache entry.
602
+ # :param optional description: A description for this entry in the remote cache.
603
+
604
+ # >>> entry = CacheEntry.example()
605
+ # >>> coop.remote_cache_create(cache_entry=entry)
606
+ # {'status': 'success', 'created_entry_count': 1, 'updated_entry_count': 0}
607
+ # """
608
+ # response = self._send_server_request(
609
+ # uri="api/v0/remote-cache",
610
+ # method="POST",
611
+ # payload={
612
+ # "json_string": json.dumps(cache_entry.to_dict()),
613
+ # "version": self._edsl_version,
614
+ # "visibility": visibility,
615
+ # "description": description,
616
+ # },
617
+ # )
618
+ # self._resolve_server_response(response)
619
+ # response_json = response.json()
620
+ # created_entry_count = response_json.get("created_entry_count", 0)
621
+ # if created_entry_count > 0:
622
+ # self.remote_cache_create_log(
623
+ # response,
624
+ # description="Upload new cache entries to server",
625
+ # cache_entry_count=created_entry_count,
626
+ # )
627
+ # return response.json()
628
+
629
+ # def remote_cache_create_many(
630
+ # self,
631
+ # cache_entries: list[CacheEntry],
632
+ # visibility: VisibilityType = "private",
633
+ # description: Optional[str] = None,
634
+ # ) -> dict:
635
+ # """
636
+ # Create many remote cache entries.
637
+ # If an entry with the same key already exists in the database, update it instead.
638
+
639
+ # :param cache_entries: The list of cache entries to send to the server.
640
+ # :param visibility: The visibility of the cache entries.
641
+ # :param optional description: A description for these entries in the remote cache.
642
+
643
+ # >>> entries = [CacheEntry.example(randomize=True) for _ in range(10)]
644
+ # >>> coop.remote_cache_create_many(cache_entries=entries)
645
+ # {'status': 'success', 'created_entry_count': 10, 'updated_entry_count': 0}
646
+ # """
647
+ # payload = [
648
+ # {
649
+ # "json_string": json.dumps(c.to_dict()),
650
+ # "version": self._edsl_version,
651
+ # "visibility": visibility,
652
+ # "description": description,
653
+ # }
654
+ # for c in cache_entries
655
+ # ]
656
+ # response = self._send_server_request(
657
+ # uri="api/v0/remote-cache/many",
658
+ # method="POST",
659
+ # payload=payload,
660
+ # timeout=40,
661
+ # )
662
+ # self._resolve_server_response(response)
663
+ # response_json = response.json()
664
+ # created_entry_count = response_json.get("created_entry_count", 0)
665
+ # if created_entry_count > 0:
666
+ # self.remote_cache_create_log(
667
+ # response,
668
+ # description="Upload new cache entries to server",
669
+ # cache_entry_count=created_entry_count,
670
+ # )
671
+ # return response.json()
672
+
673
+ def remote_cache_get(
508
674
  self,
509
- cache_entry: CacheEntry,
510
- visibility: VisibilityType = "private",
511
- description: Optional[str] = None,
512
- ) -> dict:
675
+ job_uuid: Optional[Union[str, UUID]] = None,
676
+ ) -> list[CacheEntry]:
513
677
  """
514
- Create a single remote cache entry.
515
- If an entry with the same key already exists in the database, update it instead.
678
+ Get all remote cache entries.
516
679
 
517
- :param cache_entry: The cache entry to send to the server.
518
- :param visibility: The visibility of the cache entry.
519
- :param optional description: A description for this entry in the remote cache.
680
+ :param optional select_keys: Only return CacheEntry objects with these keys.
520
681
 
521
- >>> entry = CacheEntry.example()
522
- >>> coop.remote_cache_create(cache_entry=entry)
523
- {'status': 'success', 'created_entry_count': 1, 'updated_entry_count': 0}
682
+ >>> coop.remote_cache_get(job_uuid="...")
683
+ [CacheEntry(...), CacheEntry(...), ...]
524
684
  """
685
+ if job_uuid is None:
686
+ raise ValueError("Must provide a job_uuid.")
525
687
  response = self._send_server_request(
526
- uri="api/v0/remote-cache",
688
+ uri="api/v0/remote-cache/get-many-by-job",
527
689
  method="POST",
528
690
  payload={
529
- "json_string": json.dumps(cache_entry.to_dict()),
530
- "version": self._edsl_version,
531
- "visibility": visibility,
532
- "description": description,
691
+ "job_uuid": str(job_uuid),
533
692
  },
693
+ timeout=40,
534
694
  )
535
695
  self._resolve_server_response(response)
536
- response_json = response.json()
537
- created_entry_count = response_json.get("created_entry_count", 0)
538
- if created_entry_count > 0:
539
- self.remote_cache_create_log(
540
- response,
541
- description="Upload new cache entries to server",
542
- cache_entry_count=created_entry_count,
543
- )
544
- return response.json()
696
+ return [
697
+ CacheEntry.from_dict(json.loads(v.get("json_string")))
698
+ for v in response.json()
699
+ ]
545
700
 
546
- def remote_cache_create_many(
701
+ def remote_cache_get_by_key(
547
702
  self,
548
- cache_entries: list[CacheEntry],
549
- visibility: VisibilityType = "private",
550
- description: Optional[str] = None,
551
- ) -> dict:
703
+ select_keys: Optional[list[str]] = None,
704
+ ) -> list[CacheEntry]:
552
705
  """
553
- Create many remote cache entries.
554
- If an entry with the same key already exists in the database, update it instead.
706
+ Get all remote cache entries.
555
707
 
556
- :param cache_entries: The list of cache entries to send to the server.
557
- :param visibility: The visibility of the cache entries.
558
- :param optional description: A description for these entries in the remote cache.
708
+ :param optional select_keys: Only return CacheEntry objects with these keys.
559
709
 
560
- >>> entries = [CacheEntry.example(randomize=True) for _ in range(10)]
561
- >>> coop.remote_cache_create_many(cache_entries=entries)
562
- {'status': 'success', 'created_entry_count': 10, 'updated_entry_count': 0}
710
+ >>> coop.remote_cache_get_by_key(selected_keys=["..."])
711
+ [CacheEntry(...), CacheEntry(...), ...]
563
712
  """
564
- payload = [
565
- {
566
- "json_string": json.dumps(c.to_dict()),
567
- "version": self._edsl_version,
568
- "visibility": visibility,
569
- "description": description,
570
- }
571
- for c in cache_entries
572
- ]
713
+ if select_keys is None or len(select_keys) == 0:
714
+ raise ValueError("Must provide a non-empty list of select_keys.")
573
715
  response = self._send_server_request(
574
- uri="api/v0/remote-cache/many",
716
+ uri="api/v0/remote-cache/get-many-by-key",
575
717
  method="POST",
576
- payload=payload,
718
+ payload={
719
+ "selected_keys": select_keys,
720
+ },
577
721
  timeout=40,
578
722
  )
579
723
  self._resolve_server_response(response)
580
- response_json = response.json()
581
- created_entry_count = response_json.get("created_entry_count", 0)
582
- if created_entry_count > 0:
583
- self.remote_cache_create_log(
584
- response,
585
- description="Upload new cache entries to server",
586
- cache_entry_count=created_entry_count,
587
- )
588
- return response.json()
724
+ return [
725
+ CacheEntry.from_dict(json.loads(v.get("json_string")))
726
+ for v in response.json()
727
+ ]
589
728
 
590
- def remote_cache_get(
729
+ def legacy_remote_cache_get(
591
730
  self,
592
731
  exclude_keys: Optional[list[str]] = None,
593
732
  select_keys: Optional[list[str]] = None,
@@ -595,9 +734,10 @@ class Coop(CoopFunctionsMixin):
595
734
  """
596
735
  Get all remote cache entries.
597
736
 
737
+ :param optional select_keys: Only return CacheEntry objects with these keys.
598
738
  :param optional exclude_keys: Exclude CacheEntry objects with these keys.
599
739
 
600
- >>> coop.remote_cache_get()
740
+ >>> coop.legacy_remote_cache_get()
601
741
  [CacheEntry(...), CacheEntry(...), ...]
602
742
  """
603
743
  if exclude_keys is None:
@@ -605,9 +745,9 @@ class Coop(CoopFunctionsMixin):
605
745
  if select_keys is None:
606
746
  select_keys = []
607
747
  response = self._send_server_request(
608
- uri="api/v0/remote-cache/get-many",
748
+ uri="api/v0/remote-cache/legacy/get-many",
609
749
  method="POST",
610
- payload={"keys": exclude_keys, "selected_keys": select_keys},
750
+ payload={"exclude_keys": exclude_keys, "selected_keys": select_keys},
611
751
  timeout=40,
612
752
  )
613
753
  self._resolve_server_response(response)
@@ -616,7 +756,7 @@ class Coop(CoopFunctionsMixin):
616
756
  for v in response.json()
617
757
  ]
618
758
 
619
- def remote_cache_get_diff(
759
+ def legacy_remote_cache_get_diff(
620
760
  self,
621
761
  client_cacheentry_keys: list[str],
622
762
  ) -> dict:
@@ -624,7 +764,7 @@ class Coop(CoopFunctionsMixin):
624
764
  Get the difference between local and remote cache entries for a user.
625
765
  """
626
766
  response = self._send_server_request(
627
- uri="api/v0/remote-cache/get-diff",
767
+ uri="api/v0/remote-cache/legacy/get-diff",
628
768
  method="POST",
629
769
  payload={"keys": client_cacheentry_keys},
630
770
  timeout=40,
@@ -642,38 +782,38 @@ class Coop(CoopFunctionsMixin):
642
782
  }
643
783
  downloaded_entry_count = len(response_dict["client_missing_cacheentries"])
644
784
  if downloaded_entry_count > 0:
645
- self.remote_cache_create_log(
785
+ self.legacy_remote_cache_create_log(
646
786
  response,
647
787
  description="Download missing cache entries to client",
648
788
  cache_entry_count=downloaded_entry_count,
649
789
  )
650
790
  return response_dict
651
791
 
652
- def remote_cache_clear(self) -> dict:
792
+ def legacy_remote_cache_clear(self) -> dict:
653
793
  """
654
794
  Clear all remote cache entries.
655
795
 
656
796
  >>> entries = [CacheEntry.example(randomize=True) for _ in range(10)]
657
- >>> coop.remote_cache_create_many(cache_entries=entries)
658
- >>> coop.remote_cache_clear()
797
+ >>> coop.legacy_remote_cache_create_many(cache_entries=entries)
798
+ >>> coop.legacy_remote_cache_clear()
659
799
  {'status': 'success', 'deleted_entry_count': 10}
660
800
  """
661
801
  response = self._send_server_request(
662
- uri="api/v0/remote-cache/delete-all",
802
+ uri="api/v0/remote-cache/legacy/delete-all",
663
803
  method="DELETE",
664
804
  )
665
805
  self._resolve_server_response(response)
666
806
  response_json = response.json()
667
807
  deleted_entry_count = response_json.get("deleted_entry_count", 0)
668
808
  if deleted_entry_count > 0:
669
- self.remote_cache_create_log(
809
+ self.legacy_remote_cache_create_log(
670
810
  response,
671
811
  description="Clear cache entries",
672
812
  cache_entry_count=deleted_entry_count,
673
813
  )
674
814
  return response.json()
675
815
 
676
- def remote_cache_create_log(
816
+ def legacy_remote_cache_create_log(
677
817
  self, response: requests.Response, description: str, cache_entry_count: int
678
818
  ) -> Union[dict, None]:
679
819
  """
@@ -682,7 +822,7 @@ class Coop(CoopFunctionsMixin):
682
822
  """
683
823
  if 200 <= response.status_code < 300:
684
824
  log_response = self._send_server_request(
685
- uri="api/v0/remote-cache-log",
825
+ uri="api/v0/remote-cache-log/legacy",
686
826
  method="POST",
687
827
  payload={
688
828
  "description": description,
@@ -692,15 +832,15 @@ class Coop(CoopFunctionsMixin):
692
832
  self._resolve_server_response(log_response)
693
833
  return response.json()
694
834
 
695
- def remote_cache_clear_log(self) -> dict:
835
+ def legacy_remote_cache_clear_log(self) -> dict:
696
836
  """
697
837
  Clear all remote cache log entries.
698
838
 
699
- >>> coop.remote_cache_clear_log()
839
+ >>> coop.legacy_remote_cache_clear_log()
700
840
  {'status': 'success'}
701
841
  """
702
842
  response = self._send_server_request(
703
- uri="api/v0/remote-cache-log/delete-all",
843
+ uri="api/v0/remote-cache-log/legacy/delete-all",
704
844
  method="DELETE",
705
845
  )
706
846
  self._resolve_server_response(response)
@@ -714,6 +854,7 @@ class Coop(CoopFunctionsMixin):
714
854
  visibility: Optional[VisibilityType] = "unlisted",
715
855
  initial_results_visibility: Optional[VisibilityType] = "unlisted",
716
856
  iterations: Optional[int] = 1,
857
+ fresh: Optional[bool] = False,
717
858
  ) -> RemoteInferenceCreationInfo:
718
859
  """
719
860
  Send a remote inference job to the server.
@@ -742,6 +883,7 @@ class Coop(CoopFunctionsMixin):
742
883
  "visibility": visibility,
743
884
  "version": self._edsl_version,
744
885
  "initial_results_visibility": initial_results_visibility,
886
+ "fresh": fresh,
745
887
  },
746
888
  )
747
889
  self._resolve_server_response(response)
@@ -1037,19 +1179,21 @@ class Coop(CoopFunctionsMixin):
1037
1179
  if console.is_terminal:
1038
1180
  # Running in a standard terminal, show the full URL
1039
1181
  if link_description:
1040
- rich_print("{link_description}\n[#38bdf8][link={url}]{url}[/link][/#38bdf8]")
1182
+ rich_print(
1183
+ "{link_description}\n[#38bdf8][link={url}]{url}[/link][/#38bdf8]"
1184
+ )
1041
1185
  else:
1042
1186
  rich_print(f"[#38bdf8][link={url}]{url}[/link][/#38bdf8]")
1043
1187
  else:
1044
1188
  # Running in an interactive environment (e.g., Jupyter Notebook), hide the URL
1045
1189
  if link_description:
1046
- rich_print(f"{link_description}\n[#38bdf8][link={url}][underline]Log in and automatically store key[/underline][/link][/#38bdf8]")
1190
+ rich_print(
1191
+ f"{link_description}\n[#38bdf8][link={url}][underline]Log in and automatically store key[/underline][/link][/#38bdf8]"
1192
+ )
1047
1193
  else:
1048
- rich_print(f"[#38bdf8][link={url}][underline]Log in and automatically store key[/underline][/link][/#38bdf8]")
1049
-
1050
-
1051
-
1052
-
1194
+ rich_print(
1195
+ f"[#38bdf8][link={url}][underline]Log in and automatically store key[/underline][/link][/#38bdf8]"
1196
+ )
1053
1197
 
1054
1198
  def _get_api_key(self, edsl_auth_token: str):
1055
1199
  """
@@ -1126,27 +1270,25 @@ def main():
1126
1270
  ##############
1127
1271
  # .. create and manipulate an object through the Coop client
1128
1272
  response = coop.create(QuestionMultipleChoice.example())
1129
- coop.get(uuid=response.get("uuid"))
1130
- coop.get(uuid=response.get("uuid"), expected_object_type="question")
1131
- coop.get(url=response.get("url"))
1273
+ coop.get(response.get("uuid"))
1274
+ coop.get(response.get("uuid"), expected_object_type="question")
1275
+ coop.get(response.get("url"))
1132
1276
  coop.create(QuestionMultipleChoice.example())
1133
1277
  coop.get_all("question")
1134
- coop.patch(uuid=response.get("uuid"), visibility="private")
1135
- coop.patch(uuid=response.get("uuid"), description="hey")
1136
- coop.patch(uuid=response.get("uuid"), value=QuestionFreeText.example())
1137
- # coop.patch(uuid=response.get("uuid"), value=Survey.example()) - should throw error
1138
- coop.get(uuid=response.get("uuid"))
1139
- coop.delete(uuid=response.get("uuid"))
1278
+ coop.patch(response.get("uuid"), visibility="private")
1279
+ coop.patch(response.get("uuid"), description="hey")
1280
+ coop.patch(response.get("uuid"), value=QuestionFreeText.example())
1281
+ # coop.patch(response.get("uuid"), value=Survey.example()) - should throw error
1282
+ coop.get(response.get("uuid"))
1283
+ coop.delete(response.get("uuid"))
1140
1284
 
1141
1285
  # .. create and manipulate an object through the class
1142
1286
  response = QuestionMultipleChoice.example().push()
1143
- QuestionMultipleChoice.pull(uuid=response.get("uuid"))
1144
- QuestionMultipleChoice.pull(url=response.get("url"))
1145
- QuestionMultipleChoice.patch(uuid=response.get("uuid"), visibility="private")
1146
- QuestionMultipleChoice.patch(uuid=response.get("uuid"), description="hey")
1147
- QuestionMultipleChoice.patch(
1148
- uuid=response.get("uuid"), value=QuestionFreeText.example()
1149
- )
1287
+ QuestionMultipleChoice.pull(response.get("uuid"))
1288
+ QuestionMultipleChoice.pull(response.get("url"))
1289
+ QuestionMultipleChoice.patch(response.get("uuid"), visibility="private")
1290
+ QuestionMultipleChoice.patch(response.get("uuid"), description="hey")
1291
+ QuestionMultipleChoice.patch(response.get("uuid"), value=QuestionFreeText.example())
1150
1292
  QuestionMultipleChoice.pull(response.get("uuid"))
1151
1293
  QuestionMultipleChoice.delete(response.get("uuid"))
1152
1294
 
@@ -1169,7 +1311,7 @@ def main():
1169
1311
  # 1. Delete existing objects
1170
1312
  existing_objects = coop.get_all(object_type)
1171
1313
  for item in existing_objects:
1172
- coop.delete(uuid=item.get("uuid"))
1314
+ coop.delete(item.get("uuid"))
1173
1315
  # 2. Create new objects
1174
1316
  example = cls.example()
1175
1317
  response_1 = coop.create(example)
@@ -1183,45 +1325,45 @@ def main():
1183
1325
  assert len(objects) == 4
1184
1326
  # 4. Try to retrieve an item that does not exist
1185
1327
  try:
1186
- coop.get(uuid=uuid4())
1328
+ coop.get(uuid4())
1187
1329
  except Exception as e:
1188
1330
  print(e)
1189
1331
  # 5. Try to retrieve all test objects by their uuids
1190
1332
  for response in [response_1, response_2, response_3, response_4]:
1191
- coop.get(uuid=response.get("uuid"))
1333
+ coop.get(response.get("uuid"))
1192
1334
  # 6. Change visibility of all objects
1193
1335
  for item in objects:
1194
- coop.patch(uuid=item.get("uuid"), visibility="private")
1336
+ coop.patch(item.get("uuid"), visibility="private")
1195
1337
  # 6. Change description of all objects
1196
1338
  for item in objects:
1197
- coop.patch(uuid=item.get("uuid"), description="hey")
1339
+ coop.patch(item.get("uuid"), description="hey")
1198
1340
  # 7. Delete all objects
1199
1341
  for item in objects:
1200
- coop.delete(uuid=item.get("uuid"))
1342
+ coop.delete(item.get("uuid"))
1201
1343
  assert len(coop.get_all(object_type)) == 0
1202
1344
 
1203
1345
  ##############
1204
1346
  # C. Remote Cache
1205
1347
  ##############
1206
1348
  # clear
1207
- coop.remote_cache_clear()
1208
- assert coop.remote_cache_get() == []
1349
+ coop.legacy_remote_cache_clear()
1350
+ assert coop.legacy_remote_cache_get() == []
1209
1351
  # create one remote cache entry
1210
1352
  cache_entry = CacheEntry.example()
1211
1353
  cache_entry.to_dict()
1212
- coop.remote_cache_create(cache_entry)
1354
+ # coop.remote_cache_create(cache_entry)
1213
1355
  # create many remote cache entries
1214
1356
  cache_entries = [CacheEntry.example(randomize=True) for _ in range(10)]
1215
- coop.remote_cache_create_many(cache_entries)
1357
+ # coop.remote_cache_create_many(cache_entries)
1216
1358
  # get all remote cache entries
1217
- coop.remote_cache_get()
1218
- coop.remote_cache_get(exclude_keys=[])
1219
- coop.remote_cache_get(exclude_keys=["a"])
1359
+ coop.legacy_remote_cache_get()
1360
+ coop.legacy_remote_cache_get(exclude_keys=[])
1361
+ coop.legacy_remote_cache_get(exclude_keys=["a"])
1220
1362
  exclude_keys = [cache_entry.key for cache_entry in cache_entries]
1221
- coop.remote_cache_get(exclude_keys)
1363
+ coop.legacy_remote_cache_get(exclude_keys)
1222
1364
  # clear
1223
- coop.remote_cache_clear()
1224
- coop.remote_cache_get()
1365
+ coop.legacy_remote_cache_clear()
1366
+ coop.legacy_remote_cache_get()
1225
1367
 
1226
1368
  ##############
1227
1369
  # D. Remote Inference
@@ -1230,4 +1372,4 @@ def main():
1230
1372
  coop.remote_inference_cost(job)
1231
1373
  job_coop_object = coop.remote_inference_create(job)
1232
1374
  job_coop_results = coop.remote_inference_get(job_coop_object.get("uuid"))
1233
- coop.get(uuid=job_coop_results.get("results_uuid"))
1375
+ coop.get(job_coop_results.get("results_uuid"))