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.
- edsl/Base.py +87 -16
- edsl/__version__.py +1 -1
- edsl/agents/PromptConstructor.py +26 -79
- edsl/agents/QuestionInstructionPromptBuilder.py +70 -32
- edsl/agents/QuestionTemplateReplacementsBuilder.py +12 -2
- edsl/coop/coop.py +289 -147
- edsl/data/Cache.py +2 -0
- edsl/data/CacheEntry.py +10 -2
- edsl/data/RemoteCacheSync.py +10 -9
- edsl/inference_services/AvailableModelFetcher.py +1 -1
- edsl/inference_services/PerplexityService.py +9 -5
- edsl/jobs/AnswerQuestionFunctionConstructor.py +12 -1
- edsl/jobs/Jobs.py +35 -17
- edsl/jobs/JobsComponentConstructor.py +2 -1
- edsl/jobs/JobsPrompts.py +49 -26
- edsl/jobs/JobsRemoteInferenceHandler.py +4 -5
- edsl/jobs/data_structures.py +3 -0
- edsl/jobs/interviews/Interview.py +6 -3
- edsl/language_models/LanguageModel.py +7 -1
- edsl/questions/QuestionBase.py +5 -0
- edsl/questions/question_base_gen_mixin.py +2 -0
- edsl/questions/question_registry.py +6 -7
- edsl/results/DatasetExportMixin.py +124 -6
- edsl/results/Results.py +59 -0
- edsl/scenarios/FileStore.py +112 -7
- edsl/scenarios/ScenarioList.py +283 -21
- edsl/study/Study.py +2 -2
- edsl/surveys/Survey.py +15 -20
- {edsl-0.1.45.dist-info → edsl-0.1.47.dist-info}/METADATA +4 -3
- {edsl-0.1.45.dist-info → edsl-0.1.47.dist-info}/RECORD +32 -44
- edsl/auto/AutoStudy.py +0 -130
- edsl/auto/StageBase.py +0 -243
- edsl/auto/StageGenerateSurvey.py +0 -178
- edsl/auto/StageLabelQuestions.py +0 -125
- edsl/auto/StagePersona.py +0 -61
- edsl/auto/StagePersonaDimensionValueRanges.py +0 -88
- edsl/auto/StagePersonaDimensionValues.py +0 -74
- edsl/auto/StagePersonaDimensions.py +0 -69
- edsl/auto/StageQuestions.py +0 -74
- edsl/auto/SurveyCreatorPipeline.py +0 -21
- edsl/auto/utilities.py +0 -218
- edsl/base/Base.py +0 -279
- {edsl-0.1.45.dist-info → edsl-0.1.47.dist-info}/LICENSE +0 -0
- {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,
|
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
|
297
|
-
- For content
|
300
|
+
- For content/uuid URLs: returns (uuid, None, None)
|
301
|
+
- For content/username/alias URLs: returns (None, username, alias)
|
298
302
|
"""
|
299
|
-
if not
|
303
|
+
if not url_or_uuid:
|
300
304
|
raise CoopNoUUIDError("No uuid or url provided for the object.")
|
301
305
|
|
302
|
-
if
|
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
|
-
|
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
|
-
|
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
|
400
|
-
|
401
|
-
:param expected_object_type:
|
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(
|
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
|
-
|
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
|
-
|
450
|
-
|
502
|
+
objects.append(object)
|
503
|
+
|
451
504
|
return objects
|
452
505
|
|
453
|
-
def delete(self,
|
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,
|
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=
|
523
|
+
uri=uri,
|
460
524
|
method="DELETE",
|
461
|
-
params=
|
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
|
-
|
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
|
-
|
479
|
-
|
480
|
-
|
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
|
-
|
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=
|
567
|
+
uri=uri,
|
485
568
|
method="PATCH",
|
486
|
-
params=
|
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
|
-
|
510
|
-
|
511
|
-
description: Optional[str] = None,
|
512
|
-
) -> dict:
|
675
|
+
job_uuid: Optional[Union[str, UUID]] = None,
|
676
|
+
) -> list[CacheEntry]:
|
513
677
|
"""
|
514
|
-
|
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
|
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
|
-
>>>
|
522
|
-
|
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
|
-
"
|
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
|
-
|
537
|
-
|
538
|
-
|
539
|
-
|
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
|
701
|
+
def remote_cache_get_by_key(
|
547
702
|
self,
|
548
|
-
|
549
|
-
|
550
|
-
description: Optional[str] = None,
|
551
|
-
) -> dict:
|
703
|
+
select_keys: Optional[list[str]] = None,
|
704
|
+
) -> list[CacheEntry]:
|
552
705
|
"""
|
553
|
-
|
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
|
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
|
-
>>>
|
561
|
-
|
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
|
-
|
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=
|
718
|
+
payload={
|
719
|
+
"selected_keys": select_keys,
|
720
|
+
},
|
577
721
|
timeout=40,
|
578
722
|
)
|
579
723
|
self._resolve_server_response(response)
|
580
|
-
|
581
|
-
|
582
|
-
|
583
|
-
|
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
|
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.
|
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={"
|
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
|
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.
|
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
|
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.
|
658
|
-
>>> coop.
|
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.
|
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
|
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
|
835
|
+
def legacy_remote_cache_clear_log(self) -> dict:
|
696
836
|
"""
|
697
837
|
Clear all remote cache log entries.
|
698
838
|
|
699
|
-
>>> coop.
|
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(
|
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(
|
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(
|
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(
|
1130
|
-
coop.get(
|
1131
|
-
coop.get(
|
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(
|
1135
|
-
coop.patch(
|
1136
|
-
coop.patch(
|
1137
|
-
# coop.patch(
|
1138
|
-
coop.get(
|
1139
|
-
coop.delete(
|
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(
|
1144
|
-
QuestionMultipleChoice.pull(
|
1145
|
-
QuestionMultipleChoice.patch(
|
1146
|
-
QuestionMultipleChoice.patch(
|
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(
|
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(
|
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(
|
1333
|
+
coop.get(response.get("uuid"))
|
1192
1334
|
# 6. Change visibility of all objects
|
1193
1335
|
for item in objects:
|
1194
|
-
coop.patch(
|
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(
|
1339
|
+
coop.patch(item.get("uuid"), description="hey")
|
1198
1340
|
# 7. Delete all objects
|
1199
1341
|
for item in objects:
|
1200
|
-
coop.delete(
|
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.
|
1208
|
-
assert coop.
|
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.
|
1218
|
-
coop.
|
1219
|
-
coop.
|
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.
|
1363
|
+
coop.legacy_remote_cache_get(exclude_keys)
|
1222
1364
|
# clear
|
1223
|
-
coop.
|
1224
|
-
coop.
|
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(
|
1375
|
+
coop.get(job_coop_results.get("results_uuid"))
|