edsl 0.1.30.dev1__tar.gz → 0.1.30.dev2__tar.gz

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 (205) hide show
  1. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/PKG-INFO +1 -1
  2. edsl-0.1.30.dev2/edsl/__version__.py +1 -0
  3. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/agents/Invigilator.py +4 -5
  4. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/data/Cache.py +13 -3
  5. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/data_transfer_models.py +4 -0
  6. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/jobs/Jobs.py +7 -0
  7. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/jobs/buckets/ModelBuckets.py +10 -0
  8. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/jobs/buckets/TokenBucket.py +20 -3
  9. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/jobs/interviews/Interview.py +7 -6
  10. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/jobs/runners/JobsRunnerAsyncio.py +2 -0
  11. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/jobs/tasks/QuestionTaskCreator.py +15 -6
  12. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/language_models/LanguageModel.py +4 -5
  13. edsl-0.1.30.dev2/edsl/scenarios/FileStore.py +283 -0
  14. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/pyproject.toml +18 -19
  15. edsl-0.1.30.dev1/edsl/__version__.py +0 -1
  16. edsl-0.1.30.dev1/edsl/scenarios/FileStore.py +0 -140
  17. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/LICENSE +0 -0
  18. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/README.md +0 -0
  19. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/Base.py +0 -0
  20. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/BaseDiff.py +0 -0
  21. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/__init__.py +0 -0
  22. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/agents/Agent.py +0 -0
  23. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/agents/AgentList.py +0 -0
  24. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/agents/InvigilatorBase.py +0 -0
  25. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/agents/PromptConstructionMixin.py +0 -0
  26. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/agents/__init__.py +0 -0
  27. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/agents/descriptors.py +0 -0
  28. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/base/Base.py +0 -0
  29. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/config.py +0 -0
  30. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/conjure/AgentConstructionMixin.py +0 -0
  31. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/conjure/Conjure.py +0 -0
  32. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/conjure/InputData.py +0 -0
  33. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/conjure/InputDataCSV.py +0 -0
  34. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/conjure/InputDataMixinQuestionStats.py +0 -0
  35. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/conjure/InputDataPyRead.py +0 -0
  36. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/conjure/InputDataSPSS.py +0 -0
  37. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/conjure/InputDataStata.py +0 -0
  38. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/conjure/QuestionOptionMixin.py +0 -0
  39. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/conjure/QuestionTypeMixin.py +0 -0
  40. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/conjure/RawQuestion.py +0 -0
  41. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/conjure/SurveyResponses.py +0 -0
  42. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/conjure/__init__.py +0 -0
  43. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/conjure/examples/placeholder.txt +0 -0
  44. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/conjure/naming_utilities.py +0 -0
  45. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/conjure/utilities.py +0 -0
  46. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/conversation/Conversation.py +0 -0
  47. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/conversation/car_buying.py +0 -0
  48. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/conversation/mug_negotiation.py +0 -0
  49. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/conversation/next_speaker_utilities.py +0 -0
  50. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/coop/__init__.py +0 -0
  51. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/coop/coop.py +0 -0
  52. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/coop/utils.py +0 -0
  53. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/data/CacheEntry.py +0 -0
  54. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/data/CacheHandler.py +0 -0
  55. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/data/SQLiteDict.py +0 -0
  56. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/data/__init__.py +0 -0
  57. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/data/orm.py +0 -0
  58. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/enums.py +0 -0
  59. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/exceptions/__init__.py +0 -0
  60. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/exceptions/agents.py +0 -0
  61. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/exceptions/configuration.py +0 -0
  62. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/exceptions/coop.py +0 -0
  63. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/exceptions/data.py +0 -0
  64. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/exceptions/general.py +0 -0
  65. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/exceptions/jobs.py +0 -0
  66. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/exceptions/language_models.py +0 -0
  67. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/exceptions/prompts.py +0 -0
  68. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/exceptions/questions.py +0 -0
  69. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/exceptions/results.py +0 -0
  70. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/exceptions/surveys.py +0 -0
  71. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/inference_services/AnthropicService.py +0 -0
  72. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/inference_services/DeepInfraService.py +0 -0
  73. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/inference_services/GoogleService.py +0 -0
  74. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/inference_services/InferenceServiceABC.py +0 -0
  75. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/inference_services/InferenceServicesCollection.py +0 -0
  76. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/inference_services/OpenAIService.py +0 -0
  77. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/inference_services/__init__.py +0 -0
  78. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/inference_services/models_available_cache.py +0 -0
  79. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/inference_services/rate_limits_cache.py +0 -0
  80. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/inference_services/registry.py +0 -0
  81. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/inference_services/write_available.py +0 -0
  82. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/jobs/Answers.py +0 -0
  83. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/jobs/__init__.py +0 -0
  84. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/jobs/buckets/BucketCollection.py +0 -0
  85. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/jobs/interviews/InterviewStatistic.py +0 -0
  86. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/jobs/interviews/InterviewStatisticsCollection.py +0 -0
  87. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/jobs/interviews/InterviewStatusDictionary.py +0 -0
  88. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/jobs/interviews/InterviewStatusLog.py +0 -0
  89. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/jobs/interviews/InterviewStatusMixin.py +0 -0
  90. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/jobs/interviews/InterviewTaskBuildingMixin.py +0 -0
  91. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/jobs/interviews/ReportErrors.py +0 -0
  92. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/jobs/interviews/interview_exception_tracking.py +0 -0
  93. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/jobs/interviews/interview_status_enum.py +0 -0
  94. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/jobs/interviews/retry_management.py +0 -0
  95. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/jobs/runners/JobsRunnerStatusData.py +0 -0
  96. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/jobs/runners/JobsRunnerStatusMixin.py +0 -0
  97. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/jobs/tasks/TaskCreators.py +0 -0
  98. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/jobs/tasks/TaskHistory.py +0 -0
  99. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/jobs/tasks/TaskStatusLog.py +0 -0
  100. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/jobs/tasks/task_management.py +0 -0
  101. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/jobs/tasks/task_status_enum.py +0 -0
  102. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/jobs/tokens/InterviewTokenUsage.py +0 -0
  103. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/jobs/tokens/TokenUsage.py +0 -0
  104. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/language_models/ModelList.py +0 -0
  105. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/language_models/RegisterLanguageModelsMeta.py +0 -0
  106. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/language_models/__init__.py +0 -0
  107. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/language_models/registry.py +0 -0
  108. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/language_models/repair.py +0 -0
  109. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/language_models/unused/ReplicateBase.py +0 -0
  110. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/notebooks/Notebook.py +0 -0
  111. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/notebooks/__init__.py +0 -0
  112. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/prompts/Prompt.py +0 -0
  113. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/prompts/QuestionInstructionsBase.py +0 -0
  114. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/prompts/__init__.py +0 -0
  115. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/prompts/library/agent_instructions.py +0 -0
  116. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/prompts/library/agent_persona.py +0 -0
  117. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/prompts/library/question_budget.py +0 -0
  118. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/prompts/library/question_checkbox.py +0 -0
  119. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/prompts/library/question_extract.py +0 -0
  120. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/prompts/library/question_freetext.py +0 -0
  121. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/prompts/library/question_linear_scale.py +0 -0
  122. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/prompts/library/question_list.py +0 -0
  123. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/prompts/library/question_multiple_choice.py +0 -0
  124. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/prompts/library/question_numerical.py +0 -0
  125. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/prompts/library/question_rank.py +0 -0
  126. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/prompts/prompt_config.py +0 -0
  127. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/prompts/registry.py +0 -0
  128. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/questions/AnswerValidatorMixin.py +0 -0
  129. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/questions/QuestionBase.py +0 -0
  130. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/questions/QuestionBudget.py +0 -0
  131. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/questions/QuestionCheckBox.py +0 -0
  132. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/questions/QuestionExtract.py +0 -0
  133. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/questions/QuestionFreeText.py +0 -0
  134. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/questions/QuestionFunctional.py +0 -0
  135. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/questions/QuestionList.py +0 -0
  136. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/questions/QuestionMultipleChoice.py +0 -0
  137. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/questions/QuestionNumerical.py +0 -0
  138. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/questions/QuestionRank.py +0 -0
  139. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/questions/RegisterQuestionsMeta.py +0 -0
  140. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/questions/SimpleAskMixin.py +0 -0
  141. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/questions/__init__.py +0 -0
  142. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/questions/compose_questions.py +0 -0
  143. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/questions/derived/QuestionLikertFive.py +0 -0
  144. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/questions/derived/QuestionLinearScale.py +0 -0
  145. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/questions/derived/QuestionTopK.py +0 -0
  146. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/questions/derived/QuestionYesNo.py +0 -0
  147. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/questions/derived/__init__.py +0 -0
  148. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/questions/descriptors.py +0 -0
  149. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/questions/question_registry.py +0 -0
  150. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/questions/settings.py +0 -0
  151. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/results/Dataset.py +0 -0
  152. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/results/DatasetExportMixin.py +0 -0
  153. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/results/Result.py +0 -0
  154. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/results/Results.py +0 -0
  155. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/results/ResultsDBMixin.py +0 -0
  156. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/results/ResultsExportMixin.py +0 -0
  157. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/results/ResultsFetchMixin.py +0 -0
  158. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/results/ResultsGGMixin.py +0 -0
  159. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/results/ResultsToolsMixin.py +0 -0
  160. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/results/__init__.py +0 -0
  161. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/scenarios/Scenario.py +0 -0
  162. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/scenarios/ScenarioHtmlMixin.py +0 -0
  163. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/scenarios/ScenarioImageMixin.py +0 -0
  164. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/scenarios/ScenarioList.py +0 -0
  165. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/scenarios/ScenarioListExportMixin.py +0 -0
  166. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/scenarios/ScenarioListPdfMixin.py +0 -0
  167. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/scenarios/__init__.py +0 -0
  168. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/shared.py +0 -0
  169. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/study/ObjectEntry.py +0 -0
  170. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/study/ProofOfWork.py +0 -0
  171. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/study/SnapShot.py +0 -0
  172. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/study/Study.py +0 -0
  173. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/study/__init__.py +0 -0
  174. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/surveys/DAG.py +0 -0
  175. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/surveys/Memory.py +0 -0
  176. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/surveys/MemoryPlan.py +0 -0
  177. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/surveys/Rule.py +0 -0
  178. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/surveys/RuleCollection.py +0 -0
  179. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/surveys/Survey.py +0 -0
  180. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/surveys/SurveyCSS.py +0 -0
  181. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/surveys/SurveyExportMixin.py +0 -0
  182. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/surveys/SurveyFlowVisualizationMixin.py +0 -0
  183. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/surveys/__init__.py +0 -0
  184. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/surveys/base.py +0 -0
  185. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/surveys/descriptors.py +0 -0
  186. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/tools/__init__.py +0 -0
  187. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/tools/clusters.py +0 -0
  188. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/tools/embeddings.py +0 -0
  189. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/tools/embeddings_plotting.py +0 -0
  190. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/tools/plotting.py +0 -0
  191. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/tools/summarize.py +0 -0
  192. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/utilities/SystemInfo.py +0 -0
  193. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/utilities/__init__.py +0 -0
  194. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/utilities/ast_utilities.py +0 -0
  195. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/utilities/data/Registry.py +0 -0
  196. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/utilities/data/__init__.py +0 -0
  197. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/utilities/data/scooter_results.json +0 -0
  198. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/utilities/decorators.py +0 -0
  199. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/utilities/gcp_bucket/__init__.py +0 -0
  200. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/utilities/gcp_bucket/cloud_storage.py +0 -0
  201. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/utilities/gcp_bucket/simple_example.py +0 -0
  202. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/utilities/interface.py +0 -0
  203. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/utilities/repair_functions.py +0 -0
  204. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/utilities/restricted_python.py +0 -0
  205. {edsl-0.1.30.dev1 → edsl-0.1.30.dev2}/edsl/utilities/utilities.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: edsl
3
- Version: 0.1.30.dev1
3
+ Version: 0.1.30.dev2
4
4
  Summary: Create and analyze LLM-based surveys
5
5
  Home-page: https://www.expectedparrot.com/
6
6
  License: MIT
@@ -0,0 +1 @@
1
+ __version__ = "0.1.30.dev2"
@@ -74,15 +74,14 @@ class InvigilatorAI(PromptConstructorMixin, InvigilatorBase):
74
74
 
75
75
  This cleans up the raw response to make it suitable to pass to AgentResponseDict.
76
76
  """
77
- # not actually used, but this removes the temptation to delete agent from the signature
78
77
  _ = agent
79
78
  try:
80
79
  response = question._validate_answer(raw_response)
81
80
  except Exception as e:
81
+ """If the response is invalid, remove it from the cache and raise the exception."""
82
82
  self._remove_from_cache(raw_response)
83
83
  raise e
84
84
 
85
- # breakpoint()
86
85
  question_dict = self.survey.question_names_to_questions()
87
86
  for other_question, answer in self.current_answers.items():
88
87
  if other_question in question_dict:
@@ -95,12 +94,10 @@ class InvigilatorAI(PromptConstructorMixin, InvigilatorBase):
95
94
  question_dict[new_question].comment = answer
96
95
 
97
96
  combined_dict = {**question_dict, **scenario}
98
- # print("combined_dict: ", combined_dict)
99
- # print("response: ", response)
100
- # breakpoint()
101
97
  answer = question._translate_answer_code_to_answer(
102
98
  response["answer"], combined_dict
103
99
  )
100
+ #breakpoint()
104
101
  data = {
105
102
  "answer": answer,
106
103
  "comment": response.get(
@@ -111,6 +108,8 @@ class InvigilatorAI(PromptConstructorMixin, InvigilatorBase):
111
108
  "cached_response": raw_response.get("cached_response", None),
112
109
  "usage": raw_response.get("usage", {}),
113
110
  "raw_model_response": raw_model_response,
111
+ "cache_used": raw_response.get("cache_used", False),
112
+ "cache_key": raw_response.get("cache_key", None),
114
113
  }
115
114
  return AgentResponseDict(**data)
116
115
 
@@ -41,6 +41,7 @@ class Cache(Base):
41
41
  data: Optional[Union["SQLiteDict", dict]] = None,
42
42
  immediate_write: bool = True,
43
43
  method=None,
44
+ verbose = False
44
45
  ):
45
46
  """
46
47
  Create two dictionaries to store the cache data.
@@ -59,6 +60,7 @@ class Cache(Base):
59
60
  self.new_entries = {}
60
61
  self.new_entries_to_write_later = {}
61
62
  self.coop = None
63
+ self.verbose = verbose
62
64
 
63
65
  self.filename = filename
64
66
  if filename and data:
@@ -122,7 +124,7 @@ class Cache(Base):
122
124
  system_prompt: str,
123
125
  user_prompt: str,
124
126
  iteration: int,
125
- ) -> Union[None, str]:
127
+ ) -> tuple(Union[None, str], str):
126
128
  """
127
129
  Fetch a value (LLM output) from the cache.
128
130
 
@@ -135,7 +137,7 @@ class Cache(Base):
135
137
  Return None if the response is not found.
136
138
 
137
139
  >>> c = Cache()
138
- >>> c.fetch(model="gpt-3", parameters="default", system_prompt="Hello", user_prompt="Hi", iteration=1) is None
140
+ >>> c.fetch(model="gpt-3", parameters="default", system_prompt="Hello", user_prompt="Hi", iteration=1)[0] is None
139
141
  True
140
142
 
141
143
 
@@ -151,8 +153,13 @@ class Cache(Base):
151
153
  )
152
154
  entry = self.data.get(key, None)
153
155
  if entry is not None:
156
+ if self.verbose:
157
+ print(f"Cache hit for key: {key}")
154
158
  self.fetched_data[key] = entry
155
- return None if entry is None else entry.output
159
+ else:
160
+ if self.verbose:
161
+ print(f"Cache miss for key: {key}")
162
+ return None if entry is None else entry.output, key
156
163
 
157
164
  def store(
158
165
  self,
@@ -354,6 +361,9 @@ class Cache(Base):
354
361
  for key, entry in self.new_entries_to_write_later.items():
355
362
  self.data[key] = entry
356
363
 
364
+ if self.filename:
365
+ self.write(self.filename)
366
+
357
367
  ####################
358
368
  # DUNDER / USEFUL
359
369
  ####################
@@ -17,6 +17,8 @@ class AgentResponseDict(UserDict):
17
17
  cached_response=None,
18
18
  raw_model_response=None,
19
19
  simple_model_raw_response=None,
20
+ cache_used=None,
21
+ cache_key=None,
20
22
  ):
21
23
  """Initialize the AgentResponseDict object."""
22
24
  usage = usage or {"prompt_tokens": 0, "completion_tokens": 0}
@@ -30,5 +32,7 @@ class AgentResponseDict(UserDict):
30
32
  "cached_response": cached_response,
31
33
  "raw_model_response": raw_model_response,
32
34
  "simple_model_raw_response": simple_model_raw_response,
35
+ "cache_used": cache_used,
36
+ "cache_key": cache_key,
33
37
  }
34
38
  )
@@ -461,6 +461,13 @@ class Jobs(Base):
461
461
  remote_inference = False
462
462
 
463
463
  if remote_inference:
464
+ from edsl.agents.Agent import Agent
465
+ from edsl.language_models.registry import Model
466
+ from edsl.results.Result import Result
467
+ from edsl.results.Results import Results
468
+ from edsl.scenarios.Scenario import Scenario
469
+ from edsl.surveys.Survey import Survey
470
+
464
471
  self._output("Remote inference activated. Sending job to server...")
465
472
  if remote_cache:
466
473
  self._output(
@@ -24,6 +24,16 @@ class ModelBuckets:
24
24
  requests_bucket=self.requests_bucket + other.requests_bucket,
25
25
  tokens_bucket=self.tokens_bucket + other.tokens_bucket,
26
26
  )
27
+
28
+ def turbo_mode_on(self):
29
+ """Set the refill rate to infinity for both buckets."""
30
+ self.requests_bucket.turbo_mode_on()
31
+ self.tokens_bucket.turbo_mode_on()
32
+
33
+ def turbo_mode_off(self):
34
+ """Restore the refill rate to its original value for both buckets."""
35
+ self.requests_bucket.turbo_mode_off()
36
+ self.tokens_bucket.turbo_mode_off()
27
37
 
28
38
  @classmethod
29
39
  def infinity_bucket(cls, model_name: str = "not_specified") -> "ModelBuckets":
@@ -17,12 +17,29 @@ class TokenBucket:
17
17
  self.bucket_name = bucket_name
18
18
  self.bucket_type = bucket_type
19
19
  self.capacity = capacity # Maximum number of tokens
20
+ self._old_capacity = capacity
20
21
  self.tokens = capacity # Current number of available tokens
21
22
  self.refill_rate = refill_rate # Rate at which tokens are refilled
23
+ self._old_refill_rate = refill_rate
22
24
  self.last_refill = time.monotonic() # Last refill time
23
-
24
25
  self.log: List[Any] = []
25
-
26
+ self.turbo_mode = False
27
+
28
+ def turbo_mode_on(self):
29
+ """Set the refill rate to infinity."""
30
+ if self.turbo_mode:
31
+ pass
32
+ else:
33
+ self.turbo_mode = True
34
+ self.capacity=float("inf")
35
+ self.refill_rate=float("inf")
36
+
37
+ def turbo_mode_off(self):
38
+ """Restore the refill rate to its original value."""
39
+ self.turbo_mode = False
40
+ self.capacity = self._old_capacity
41
+ self.refill_rate = self._old_refill_rate
42
+
26
43
  def __add__(self, other) -> "TokenBucket":
27
44
  """Combine two token buckets.
28
45
 
@@ -98,7 +115,7 @@ class TokenBucket:
98
115
  raise ValueError(msg)
99
116
  while self.tokens < amount:
100
117
  self.refill()
101
- await asyncio.sleep(0.1) # Sleep briefly to prevent busy waiting
118
+ await asyncio.sleep(0.01) # Sleep briefly to prevent busy waiting
102
119
  self.tokens -= amount
103
120
 
104
121
  now = time.monotonic()
@@ -30,14 +30,14 @@ class Interview(InterviewStatusMixin, InterviewTaskBuildingMixin):
30
30
 
31
31
  def __init__(
32
32
  self,
33
- agent: Agent,
34
- survey: Survey,
35
- scenario: Scenario,
36
- model: Type[LanguageModel],
37
- debug: bool = False,
33
+ agent: 'Agent',
34
+ survey: 'Survey',
35
+ scenario: 'Scenario',
36
+ model: Type['LanguageModel'],
37
+ debug: Optional[bool] = False,
38
38
  iteration: int = 0,
39
39
  cache: "Cache" = None,
40
- sidecar_model: LanguageModel = None,
40
+ sidecar_model: 'LanguageModel' = None,
41
41
  ):
42
42
  """Initialize the Interview instance.
43
43
 
@@ -99,6 +99,7 @@ class Interview(InterviewStatusMixin, InterviewTaskBuildingMixin):
99
99
  if model_buckets is None or hasattr(self.agent, "answer_question_directly"):
100
100
  model_buckets = ModelBuckets.infinity_bucket()
101
101
 
102
+ # FOR TESTING
102
103
  # model_buckets = ModelBuckets.infinity_bucket()
103
104
 
104
105
  ## build the tasks using the InterviewTaskBuildingMixin
@@ -88,6 +88,7 @@ class JobsRunnerAsyncio(JobsRunnerStatusMixin):
88
88
  self.total_interviews.append(interview)
89
89
 
90
90
  async def run_async(self, cache=None) -> Results:
91
+ from edsl.results.Results import Results
91
92
  if cache is None:
92
93
  self.cache = Cache()
93
94
  else:
@@ -98,6 +99,7 @@ class JobsRunnerAsyncio(JobsRunnerStatusMixin):
98
99
  return Results(survey=self.jobs.survey, data=data)
99
100
 
100
101
  def simple_run(self):
102
+ from edsl.results.Results import Results
101
103
  data = asyncio.run(self.run_async())
102
104
  return Results(survey=self.jobs.survey, data=data)
103
105
 
@@ -144,17 +144,26 @@ class QuestionTaskCreator(UserList):
144
144
  self.task_status = TaskStatus.FAILED
145
145
  raise e
146
146
 
147
- if "cached_response" in results:
148
- if results["cached_response"]:
149
- # Gives back the tokens b/c the API was not called.
150
- self.tokens_bucket.add_tokens(requested_tokens)
151
- self.requests_bucket.add_tokens(1)
152
- self.from_cache = True
147
+ ## This isn't working
148
+ #breakpoint()
149
+ if results.get('cache_used', False):
150
+ self.tokens_bucket.add_tokens(requested_tokens)
151
+ self.requests_bucket.add_tokens(1)
152
+ self.from_cache = True
153
+ #print("Turning on turbo!")
154
+ self.tokens_bucket.turbo_mode_on()
155
+ self.requests_bucket.turbo_mode_on()
156
+ else:
157
+ #breakpoint()
158
+ #print("Turning off turbo!")
159
+ self.tokens_bucket.turbo_mode_off()
160
+ self.requests_bucket.turbo_mode_off()
153
161
 
154
162
  _ = results.pop("cached_response", None)
155
163
 
156
164
  tracker = self.cached_token_usage if self.from_cache else self.new_token_usage
157
165
 
166
+
158
167
  # TODO: This is hacky. The 'func' call should return an object that definitely has a 'usage' key.
159
168
  usage = results.get("usage", {"prompt_tokens": 0, "completion_tokens": 0})
160
169
  prompt_tokens = usage.get("prompt_tokens", 0)
@@ -323,12 +323,10 @@ class LanguageModel(
323
323
  image_hash = hashlib.md5(encoded_image.encode()).hexdigest()
324
324
  cache_call_params["user_prompt"] = f"{user_prompt} {image_hash}"
325
325
 
326
- cached_response = cache.fetch(**cache_call_params)
327
-
326
+ cached_response, cache_key = cache.fetch(**cache_call_params)
328
327
  if cached_response:
329
328
  response = json.loads(cached_response)
330
329
  cache_used = True
331
- cache_key = None
332
330
  else:
333
331
  remote_call = hasattr(self, "remote") and self.remote
334
332
  f = (
@@ -340,7 +338,7 @@ class LanguageModel(
340
338
  if encoded_image:
341
339
  params["encoded_image"] = encoded_image
342
340
  response = await f(**params)
343
- cache_key = cache.store(
341
+ new_cache_key = cache.store(
344
342
  user_prompt=user_prompt,
345
343
  model=str(self.model),
346
344
  parameters=self.parameters,
@@ -348,6 +346,7 @@ class LanguageModel(
348
346
  response=response,
349
347
  iteration=iteration,
350
348
  )
349
+ assert new_cache_key == cache_key
351
350
  cache_used = False
352
351
 
353
352
  return response, cache_used, cache_key
@@ -412,7 +411,7 @@ class LanguageModel(
412
411
 
413
412
  dict_response.update(
414
413
  {
415
- "cached_used": cache_used,
414
+ "cache_used": cache_used,
416
415
  "cache_key": cache_key,
417
416
  "usage": raw_response.get("usage", {}),
418
417
  "raw_model_response": raw_response,
@@ -0,0 +1,283 @@
1
+ from edsl import Scenario
2
+ import base64
3
+ import io
4
+ import tempfile
5
+ from typing import Optional
6
+
7
+
8
+ class FileStore(Scenario):
9
+ def __init__(
10
+ self,
11
+ filename: str,
12
+ binary: Optional[bool] = None,
13
+ suffix: Optional[str] = None,
14
+ base64_string: Optional[str] = None,
15
+ ):
16
+ self.filename = filename
17
+ self.suffix = suffix or "." + filename.split(".")[-1]
18
+ self.binary = binary or False
19
+ self.base64_string = base64_string or self.encode_file_to_base64_string(
20
+ filename
21
+ )
22
+ super().__init__(
23
+ {
24
+ "filename": self.filename,
25
+ "base64_string": self.base64_string,
26
+ "binary": self.binary,
27
+ "suffix": self.suffix,
28
+ }
29
+ )
30
+
31
+ @classmethod
32
+ def from_dict(cls, d):
33
+ return cls(d["filename"], d["binary"], d["suffix"], d["base64_string"])
34
+
35
+ def __repr__(self):
36
+ return f"FileStore(filename='{self.filename}', binary='{self.binary}', 'suffix'={self.suffix})"
37
+
38
+ def encode_file_to_base64_string(self, file_path):
39
+ try:
40
+ # Attempt to open the file in text mode
41
+ with open(file_path, "r") as text_file:
42
+ # Read the text data
43
+ text_data = text_file.read()
44
+ # Encode the text data to a base64 string
45
+ base64_encoded_data = base64.b64encode(text_data.encode("utf-8"))
46
+ except UnicodeDecodeError:
47
+ # If reading as text fails, open the file in binary mode
48
+ with open(file_path, "rb") as binary_file:
49
+ # Read the binary data
50
+ binary_data = binary_file.read()
51
+ # Encode the binary data to a base64 string
52
+ base64_encoded_data = base64.b64encode(binary_data)
53
+ self.binary = True
54
+ # Convert the base64 bytes to a string
55
+ base64_string = base64_encoded_data.decode("utf-8")
56
+
57
+ return base64_string
58
+
59
+ def open(self):
60
+ if self.binary:
61
+ return self.base64_to_file(self["base64_string"], is_binary=True)
62
+ else:
63
+ return self.base64_to_text_file(self["base64_string"])
64
+
65
+ @staticmethod
66
+ def base64_to_text_file(base64_string):
67
+ # Decode the base64 string to bytes
68
+ text_data_bytes = base64.b64decode(base64_string)
69
+
70
+ # Convert bytes to string
71
+ text_data = text_data_bytes.decode("utf-8")
72
+
73
+ # Create a StringIO object from the text data
74
+ text_file = io.StringIO(text_data)
75
+
76
+ return text_file
77
+
78
+ @staticmethod
79
+ def base64_to_file(base64_string, is_binary=True):
80
+ # Decode the base64 string to bytes
81
+ file_data = base64.b64decode(base64_string)
82
+
83
+ if is_binary:
84
+ # Create a BytesIO object for binary data
85
+ return io.BytesIO(file_data)
86
+ else:
87
+ # Convert bytes to string for text data
88
+ text_data = file_data.decode("utf-8")
89
+ # Create a StringIO object for text data
90
+ return io.StringIO(text_data)
91
+
92
+
93
+ def to_tempfile(self, suffix=None):
94
+ if suffix is None:
95
+ suffix = self.suffix
96
+ if self.binary:
97
+ file_like_object = self.base64_to_file(
98
+ self["base64_string"], is_binary=True
99
+ )
100
+ else:
101
+ file_like_object = self.base64_to_text_file(self["base64_string"])
102
+
103
+ # Create a named temporary file
104
+ mode = 'wb' if self.binary else 'w'
105
+ temp_file = tempfile.NamedTemporaryFile(delete=False, suffix=suffix, mode=mode)
106
+
107
+ if self.binary:
108
+ temp_file.write(file_like_object.read())
109
+ else:
110
+ temp_file.write(file_like_object.read())
111
+
112
+ temp_file.close()
113
+
114
+ return temp_file.name
115
+
116
+ def push(self, description=None):
117
+ scenario_version = Scenario.from_dict(self.to_dict())
118
+ if description is None:
119
+ description = "File: " + self["filename"]
120
+ info = scenario_version.push(description=description)
121
+ return info
122
+
123
+ @classmethod
124
+ def pull(cls, uuid):
125
+ scenario_version = Scenario.pull(uuid)
126
+ return cls.from_dict(scenario_version.to_dict())
127
+
128
+
129
+ class CSVFileStore(FileStore):
130
+ def __init__(self, filename):
131
+ super().__init__(filename, suffix=".csv")
132
+
133
+ @classmethod
134
+ def example(cls):
135
+ from edsl.results.Results import Results
136
+ r = Results.example()
137
+ import tempfile
138
+ with tempfile.NamedTemporaryFile(suffix=".csv", delete=False) as f:
139
+ r.to_csv(filename=f.name)
140
+ return cls(f.name)
141
+
142
+ def view(self):
143
+ import pandas as pd
144
+ return pd.read_csv(self.to_tempfile())
145
+
146
+
147
+ class PDFFileStore(FileStore):
148
+ def __init__(self, filename):
149
+ super().__init__(filename, suffix=".pdf")
150
+
151
+ def view(self):
152
+ pdf_path = self.to_tempfile()
153
+ print(f"PDF path: {pdf_path}") # Print the path to ensure it exists
154
+ import os
155
+ import subprocess
156
+ if os.path.exists(pdf_path):
157
+ try:
158
+ if os.name == 'posix':
159
+ # for cool kids
160
+ subprocess.run(['open', pdf_path], check=True) # macOS
161
+ elif os.name == 'nt':
162
+ os.startfile(pdf_path) # Windows
163
+ else:
164
+ subprocess.run(['xdg-open', pdf_path], check=True) # Linux
165
+ except Exception as e:
166
+ print(f"Error opening PDF: {e}")
167
+ else:
168
+ print("PDF file was not created successfully.")
169
+
170
+ @classmethod
171
+ def example(cls):
172
+ import textwrap
173
+ pdf_string = textwrap.dedent("""\
174
+ %PDF-1.4
175
+ 1 0 obj
176
+ << /Type /Catalog /Pages 2 0 R >>
177
+ endobj
178
+ 2 0 obj
179
+ << /Type /Pages /Kids [3 0 R] /Count 1 >>
180
+ endobj
181
+ 3 0 obj
182
+ << /Type /Page /Parent 2 0 R /MediaBox [0 0 612 792] /Contents 4 0 R >>
183
+ endobj
184
+ 4 0 obj
185
+ << /Length 44 >>
186
+ stream
187
+ BT
188
+ /F1 24 Tf
189
+ 100 700 Td
190
+ (Hello, World!) Tj
191
+ ET
192
+ endstream
193
+ endobj
194
+ 5 0 obj
195
+ << /Type /Font /Subtype /Type1 /BaseFont /Helvetica >>
196
+ endobj
197
+ 6 0 obj
198
+ << /ProcSet [/PDF /Text] /Font << /F1 5 0 R >> >>
199
+ endobj
200
+ xref
201
+ 0 7
202
+ 0000000000 65535 f
203
+ 0000000010 00000 n
204
+ 0000000053 00000 n
205
+ 0000000100 00000 n
206
+ 0000000173 00000 n
207
+ 0000000232 00000 n
208
+ 0000000272 00000 n
209
+ trailer
210
+ << /Size 7 /Root 1 0 R >>
211
+ startxref
212
+ 318
213
+ %%EOF""")
214
+ import tempfile
215
+ with tempfile.NamedTemporaryFile(suffix=".pdf", delete=False) as f:
216
+ f.write(pdf_string.encode())
217
+ return cls(f.name)
218
+
219
+ class PNGFileStore(FileStore):
220
+ def __init__(self, filename):
221
+ super().__init__(filename, suffix=".png")
222
+
223
+ @classmethod
224
+ def example(cls):
225
+ import textwrap
226
+ png_string = textwrap.dedent("""\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x01\x00\x00\x00\x01\x00\x08\x06\x00\x00\x00\x1f\x15\xc4\x89\x00\x00\x00\x0cIDAT\x08\xd7c\x00\x01""")
227
+ import tempfile
228
+ with tempfile.NamedTemporaryFile(suffix=".png", delete=False) as f:
229
+ f.write(png_string.encode())
230
+ return cls(f.name)
231
+
232
+ def view(self):
233
+ import matplotlib.pyplot as plt
234
+ import matplotlib.image as mpimg
235
+ img = mpimg.imread(self.to_tempfile())
236
+ plt.imshow(img)
237
+ plt.show()
238
+
239
+ class SQLiteFileStore(FileStore):
240
+ def __init__(self, filename):
241
+ super().__init__(filename, suffix=".sqlite")
242
+
243
+ @classmethod
244
+ def example(cls):
245
+ import sqlite3
246
+ import tempfile
247
+ with tempfile.NamedTemporaryFile(suffix=".sqlite", delete=False) as f:
248
+ conn = sqlite3.connect(f.name)
249
+ c = conn.cursor()
250
+ c.execute('''CREATE TABLE stocks (date text)''')
251
+ conn.commit()
252
+
253
+ def view(self):
254
+ import subprocess
255
+ import os
256
+ sqlite_path = self.to_tempfile()
257
+ os.system(f"sqlite3 {sqlite_path}")
258
+
259
+
260
+ if __name__ == "__main__":
261
+ # file_path = "../conjure/examples/Ex11-2.sav"
262
+ # fs = FileStore(file_path)
263
+ # info = fs.push()
264
+ # print(info)
265
+
266
+ #fs = CSVFileStore.example()
267
+ #fs.to_tempfile()
268
+ # print(fs.view())
269
+
270
+ #fs = PDFFileStore.example()
271
+ #fs.view()
272
+
273
+ #fs = PDFFileStore("paper.pdf")
274
+ #fs.view()
275
+ # from edsl import Conjure
276
+
277
+ fs = PNGFileStore("robot.png")
278
+ fs.view()
279
+
280
+ # c = Conjure(datafile_name=fs.to_tempfile())
281
+ #f = PDFFileStore("paper.pdf")
282
+ # print(f.to_tempfile())
283
+ #f.push()
@@ -1,18 +1,27 @@
1
1
  [build-system]
2
2
  build-backend = "poetry.core.masonry.api"
3
- requires = ["poetry-core"]
3
+ requires = [ "poetry-core",]
4
4
 
5
5
  [tool.poetry]
6
- authors = ["Apostolos Filippas <apostolos@expectedparrot.com>", "John Horton <john@expectedparrot.com>", "Robin Horton <robin@expectedparrot.com>"]
7
- classifiers = ["Topic :: Scientific/Engineering :: Artificial Intelligence", "Topic :: Software Development :: Libraries :: Application Frameworks", "Topic :: Software Development :: Libraries :: Python Modules"]
6
+ authors = [ "Apostolos Filippas <apostolos@expectedparrot.com>", "John Horton <john@expectedparrot.com>", "Robin Horton <robin@expectedparrot.com>",]
7
+ classifiers = [ "Topic :: Scientific/Engineering :: Artificial Intelligence", "Topic :: Software Development :: Libraries :: Application Frameworks", "Topic :: Software Development :: Libraries :: Python Modules",]
8
8
  description = "Create and analyze LLM-based surveys"
9
9
  documentation = "https://docs.expectedparrot.com"
10
10
  homepage = "https://www.expectedparrot.com/"
11
- keywords = ["LLM", "social science", "surveys", "user research"]
11
+ keywords = [ "LLM", "social science", "surveys", "user research",]
12
12
  license = "MIT"
13
13
  name = "edsl"
14
14
  readme = "README.md"
15
- version = "0.1.30.dev1"
15
+ version = "0.1.30.dev2"
16
+ [[tool.poetry.packages]]
17
+ include = "edsl"
18
+
19
+ [tool.tomlsort]
20
+ all = true
21
+ in_place = true
22
+ spaces_before_inline_comment = 2
23
+ spaces_indent_inline_array = 4
24
+ trailing_comma_inline_array = true
16
25
 
17
26
  [tool.poetry.dependencies]
18
27
  python = ">=3.9.1,<3.13"
@@ -39,9 +48,12 @@ restrictedpython = "^7.1"
39
48
  pyreadstat = "^1.2.7"
40
49
 
41
50
  [tool.poetry.dependencies.black]
42
- extras = ["jupyter"]
51
+ extras = [ "jupyter",]
43
52
  version = "^24.4.2"
44
53
 
54
+ [tool.tomlsort.overrides."tool.poetry.dependencies"]
55
+ table_keys = false
56
+
45
57
  [tool.poetry.group.dev.dependencies]
46
58
  coverage = "^7.3.3"
47
59
  mypy = "^1.7.1"
@@ -64,16 +76,3 @@ sphinx-fontawesome = "^0.0.6"
64
76
  sphinx-rtd-theme = "^2.0.0"
65
77
  toml = "^0.10.2"
66
78
  toml-sort = "^0.23.1"
67
-
68
- [[tool.poetry.packages]]
69
- include = "edsl"
70
-
71
- [tool.tomlsort]
72
- all = true
73
- in_place = true
74
- spaces_before_inline_comment = 2
75
- spaces_indent_inline_array = 4
76
- trailing_comma_inline_array = true
77
-
78
- [tool.tomlsort.overrides."tool.poetry.dependencies"]
79
- table_keys = false
@@ -1 +0,0 @@
1
- __version__ = "0.1.30.dev1"