edsl 0.1.46__py3-none-any.whl → 0.1.48__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/__init__.py +44 -39
- edsl/__version__.py +1 -1
- edsl/agents/__init__.py +4 -2
- edsl/agents/{Agent.py → agent.py} +442 -152
- edsl/agents/{AgentList.py → agent_list.py} +220 -162
- edsl/agents/descriptors.py +46 -7
- edsl/{exceptions/agents.py → agents/exceptions.py} +3 -12
- edsl/base/__init__.py +75 -0
- edsl/base/base_class.py +1303 -0
- edsl/base/data_transfer_models.py +114 -0
- edsl/base/enums.py +215 -0
- edsl/base.py +8 -0
- edsl/buckets/__init__.py +25 -0
- edsl/buckets/bucket_collection.py +324 -0
- edsl/buckets/model_buckets.py +206 -0
- edsl/buckets/token_bucket.py +502 -0
- edsl/{jobs/buckets/TokenBucketAPI.py → buckets/token_bucket_api.py} +1 -1
- edsl/buckets/token_bucket_client.py +509 -0
- edsl/caching/__init__.py +20 -0
- edsl/caching/cache.py +814 -0
- edsl/caching/cache_entry.py +427 -0
- edsl/{data/CacheHandler.py → caching/cache_handler.py} +14 -15
- edsl/caching/exceptions.py +24 -0
- edsl/caching/orm.py +30 -0
- edsl/{data/RemoteCacheSync.py → caching/remote_cache_sync.py} +3 -3
- edsl/caching/sql_dict.py +441 -0
- edsl/config/__init__.py +8 -0
- edsl/config/config_class.py +177 -0
- edsl/config.py +4 -176
- edsl/conversation/Conversation.py +7 -7
- edsl/conversation/car_buying.py +4 -4
- edsl/conversation/chips.py +6 -6
- edsl/coop/__init__.py +25 -2
- edsl/coop/coop.py +430 -113
- edsl/coop/{ExpectedParrotKeyHandler.py → ep_key_handling.py} +86 -10
- edsl/coop/exceptions.py +62 -0
- edsl/coop/price_fetcher.py +126 -0
- edsl/coop/utils.py +89 -24
- edsl/data_transfer_models.py +5 -72
- edsl/dataset/__init__.py +10 -0
- edsl/{results/Dataset.py → dataset/dataset.py} +116 -36
- edsl/dataset/dataset_operations_mixin.py +1492 -0
- edsl/{results/DatasetTree.py → dataset/dataset_tree.py} +156 -75
- edsl/{results/TableDisplay.py → dataset/display/table_display.py} +18 -7
- edsl/{results → dataset/display}/table_renderers.py +58 -2
- edsl/{results → dataset}/file_exports.py +4 -5
- edsl/{results → dataset}/smart_objects.py +2 -2
- edsl/enums.py +5 -205
- edsl/inference_services/__init__.py +5 -0
- edsl/inference_services/{AvailableModelCacheHandler.py → available_model_cache_handler.py} +2 -3
- edsl/inference_services/{AvailableModelFetcher.py → available_model_fetcher.py} +8 -14
- edsl/inference_services/data_structures.py +3 -2
- edsl/{exceptions/inference_services.py → inference_services/exceptions.py} +1 -1
- edsl/inference_services/{InferenceServiceABC.py → inference_service_abc.py} +1 -1
- edsl/inference_services/{InferenceServicesCollection.py → inference_services_collection.py} +8 -7
- edsl/inference_services/registry.py +4 -41
- edsl/inference_services/{ServiceAvailability.py → service_availability.py} +5 -25
- edsl/inference_services/services/__init__.py +31 -0
- edsl/inference_services/{AnthropicService.py → services/anthropic_service.py} +3 -3
- edsl/inference_services/{AwsBedrock.py → services/aws_bedrock.py} +2 -2
- edsl/inference_services/{AzureAI.py → services/azure_ai.py} +2 -2
- edsl/inference_services/{DeepInfraService.py → services/deep_infra_service.py} +1 -3
- edsl/inference_services/{DeepSeekService.py → services/deep_seek_service.py} +2 -4
- edsl/inference_services/{GoogleService.py → services/google_service.py} +5 -4
- edsl/inference_services/{GroqService.py → services/groq_service.py} +1 -1
- edsl/inference_services/{MistralAIService.py → services/mistral_ai_service.py} +3 -3
- edsl/inference_services/{OllamaService.py → services/ollama_service.py} +1 -7
- edsl/inference_services/{OpenAIService.py → services/open_ai_service.py} +5 -6
- edsl/inference_services/{PerplexityService.py → services/perplexity_service.py} +12 -12
- edsl/inference_services/{TestService.py → services/test_service.py} +7 -6
- edsl/inference_services/{TogetherAIService.py → services/together_ai_service.py} +2 -6
- edsl/inference_services/{XAIService.py → services/xai_service.py} +1 -1
- edsl/inference_services/write_available.py +1 -2
- edsl/instructions/__init__.py +6 -0
- edsl/{surveys/instructions/Instruction.py → instructions/instruction.py} +11 -6
- edsl/{surveys/instructions/InstructionCollection.py → instructions/instruction_collection.py} +10 -5
- edsl/{surveys/InstructionHandler.py → instructions/instruction_handler.py} +3 -3
- edsl/{jobs/interviews → interviews}/ReportErrors.py +2 -2
- edsl/interviews/__init__.py +4 -0
- edsl/{jobs/AnswerQuestionFunctionConstructor.py → interviews/answering_function.py} +45 -18
- edsl/{jobs/interviews/InterviewExceptionEntry.py → interviews/exception_tracking.py} +107 -22
- edsl/interviews/interview.py +638 -0
- edsl/{jobs/interviews/InterviewStatusDictionary.py → interviews/interview_status_dictionary.py} +21 -12
- edsl/{jobs/interviews/InterviewStatusLog.py → interviews/interview_status_log.py} +16 -7
- edsl/{jobs/InterviewTaskManager.py → interviews/interview_task_manager.py} +12 -7
- edsl/{jobs/RequestTokenEstimator.py → interviews/request_token_estimator.py} +8 -3
- edsl/{jobs/interviews/InterviewStatistic.py → interviews/statistics.py} +36 -10
- edsl/invigilators/__init__.py +38 -0
- edsl/invigilators/invigilator_base.py +477 -0
- edsl/{agents/Invigilator.py → invigilators/invigilators.py} +263 -10
- edsl/invigilators/prompt_constructor.py +476 -0
- edsl/{agents → invigilators}/prompt_helpers.py +2 -1
- edsl/{agents/QuestionInstructionPromptBuilder.py → invigilators/question_instructions_prompt_builder.py} +18 -13
- edsl/{agents → invigilators}/question_option_processor.py +96 -21
- edsl/{agents/QuestionTemplateReplacementsBuilder.py → invigilators/question_template_replacements_builder.py} +64 -12
- edsl/jobs/__init__.py +7 -1
- edsl/jobs/async_interview_runner.py +99 -35
- edsl/jobs/check_survey_scenario_compatibility.py +7 -5
- edsl/jobs/data_structures.py +153 -22
- edsl/{exceptions/jobs.py → jobs/exceptions.py} +2 -1
- edsl/jobs/{FetchInvigilator.py → fetch_invigilator.py} +4 -4
- edsl/jobs/{loggers/HTMLTableJobLogger.py → html_table_job_logger.py} +6 -2
- edsl/jobs/{Jobs.py → jobs.py} +321 -155
- edsl/jobs/{JobsChecks.py → jobs_checks.py} +15 -7
- edsl/jobs/{JobsComponentConstructor.py → jobs_component_constructor.py} +20 -17
- edsl/jobs/{InterviewsConstructor.py → jobs_interview_constructor.py} +10 -5
- edsl/jobs/jobs_pricing_estimation.py +347 -0
- edsl/jobs/{JobsRemoteInferenceLogger.py → jobs_remote_inference_logger.py} +4 -3
- edsl/jobs/jobs_runner_asyncio.py +282 -0
- edsl/jobs/{JobsRemoteInferenceHandler.py → remote_inference.py} +19 -22
- edsl/jobs/results_exceptions_handler.py +2 -2
- edsl/key_management/__init__.py +28 -0
- edsl/key_management/key_lookup.py +161 -0
- edsl/{language_models/key_management/KeyLookupBuilder.py → key_management/key_lookup_builder.py} +118 -47
- edsl/key_management/key_lookup_collection.py +82 -0
- edsl/key_management/models.py +218 -0
- edsl/language_models/__init__.py +7 -2
- edsl/language_models/{ComputeCost.py → compute_cost.py} +18 -3
- edsl/{exceptions/language_models.py → language_models/exceptions.py} +2 -1
- edsl/language_models/language_model.py +1080 -0
- edsl/language_models/model.py +10 -25
- edsl/language_models/{ModelList.py → model_list.py} +9 -14
- edsl/language_models/{RawResponseHandler.py → raw_response_handler.py} +1 -1
- edsl/language_models/{RegisterLanguageModelsMeta.py → registry.py} +1 -1
- edsl/language_models/repair.py +4 -4
- edsl/language_models/utilities.py +4 -4
- edsl/notebooks/__init__.py +3 -1
- edsl/notebooks/{Notebook.py → notebook.py} +7 -8
- edsl/prompts/__init__.py +1 -1
- edsl/{exceptions/prompts.py → prompts/exceptions.py} +3 -1
- edsl/prompts/{Prompt.py → prompt.py} +101 -95
- edsl/questions/HTMLQuestion.py +1 -1
- edsl/questions/__init__.py +154 -25
- edsl/questions/answer_validator_mixin.py +1 -1
- edsl/questions/compose_questions.py +4 -3
- edsl/questions/derived/question_likert_five.py +166 -0
- edsl/questions/derived/{QuestionLinearScale.py → question_linear_scale.py} +4 -4
- edsl/questions/derived/{QuestionTopK.py → question_top_k.py} +4 -4
- edsl/questions/derived/{QuestionYesNo.py → question_yes_no.py} +4 -5
- edsl/questions/descriptors.py +24 -30
- edsl/questions/loop_processor.py +65 -19
- edsl/questions/question_base.py +881 -0
- edsl/questions/question_base_gen_mixin.py +15 -16
- edsl/questions/{QuestionBasePromptsMixin.py → question_base_prompts_mixin.py} +2 -2
- edsl/questions/{QuestionBudget.py → question_budget.py} +3 -4
- edsl/questions/{QuestionCheckBox.py → question_check_box.py} +16 -16
- edsl/questions/{QuestionDict.py → question_dict.py} +39 -5
- edsl/questions/{QuestionExtract.py → question_extract.py} +9 -9
- edsl/questions/question_free_text.py +282 -0
- edsl/questions/{QuestionFunctional.py → question_functional.py} +6 -5
- edsl/questions/{QuestionList.py → question_list.py} +6 -7
- edsl/questions/{QuestionMatrix.py → question_matrix.py} +6 -5
- edsl/questions/{QuestionMultipleChoice.py → question_multiple_choice.py} +126 -21
- edsl/questions/{QuestionNumerical.py → question_numerical.py} +5 -5
- edsl/questions/{QuestionRank.py → question_rank.py} +6 -6
- edsl/questions/question_registry.py +10 -16
- edsl/questions/register_questions_meta.py +8 -4
- edsl/questions/response_validator_abc.py +17 -16
- edsl/results/__init__.py +4 -1
- edsl/{exceptions/results.py → results/exceptions.py} +1 -1
- edsl/results/report.py +197 -0
- edsl/results/{Result.py → result.py} +131 -45
- edsl/results/{Results.py → results.py} +420 -216
- edsl/results/results_selector.py +344 -25
- edsl/scenarios/__init__.py +30 -3
- edsl/scenarios/{ConstructDownloadLink.py → construct_download_link.py} +7 -0
- edsl/scenarios/directory_scanner.py +156 -13
- edsl/scenarios/document_chunker.py +186 -0
- edsl/scenarios/exceptions.py +101 -0
- edsl/scenarios/file_methods.py +2 -3
- edsl/scenarios/file_store.py +755 -0
- edsl/scenarios/handlers/__init__.py +14 -14
- edsl/scenarios/handlers/{csv.py → csv_file_store.py} +1 -2
- edsl/scenarios/handlers/{docx.py → docx_file_store.py} +8 -7
- edsl/scenarios/handlers/{html.py → html_file_store.py} +1 -2
- edsl/scenarios/handlers/{jpeg.py → jpeg_file_store.py} +1 -1
- edsl/scenarios/handlers/{json.py → json_file_store.py} +1 -1
- edsl/scenarios/handlers/latex_file_store.py +5 -0
- edsl/scenarios/handlers/{md.py → md_file_store.py} +1 -1
- edsl/scenarios/handlers/{pdf.py → pdf_file_store.py} +2 -2
- edsl/scenarios/handlers/{png.py → png_file_store.py} +1 -1
- edsl/scenarios/handlers/{pptx.py → pptx_file_store.py} +8 -7
- edsl/scenarios/handlers/{py.py → py_file_store.py} +1 -3
- edsl/scenarios/handlers/{sql.py → sql_file_store.py} +2 -1
- edsl/scenarios/handlers/{sqlite.py → sqlite_file_store.py} +2 -3
- edsl/scenarios/handlers/{txt.py → txt_file_store.py} +1 -1
- edsl/scenarios/scenario.py +928 -0
- edsl/scenarios/scenario_join.py +18 -5
- edsl/scenarios/{ScenarioList.py → scenario_list.py} +424 -106
- edsl/scenarios/{ScenarioListPdfMixin.py → scenario_list_pdf_tools.py} +16 -15
- edsl/scenarios/scenario_selector.py +5 -1
- edsl/study/ObjectEntry.py +2 -2
- edsl/study/SnapShot.py +5 -5
- edsl/study/Study.py +20 -21
- edsl/study/__init__.py +6 -4
- edsl/surveys/__init__.py +7 -4
- edsl/surveys/dag/__init__.py +2 -0
- edsl/surveys/{ConstructDAG.py → dag/construct_dag.py} +3 -3
- edsl/surveys/{DAG.py → dag/dag.py} +13 -10
- edsl/surveys/descriptors.py +1 -1
- edsl/surveys/{EditSurvey.py → edit_survey.py} +9 -9
- edsl/{exceptions/surveys.py → surveys/exceptions.py} +1 -2
- edsl/surveys/memory/__init__.py +3 -0
- edsl/surveys/{MemoryPlan.py → memory/memory_plan.py} +10 -9
- edsl/surveys/rules/__init__.py +3 -0
- edsl/surveys/{Rule.py → rules/rule.py} +103 -43
- edsl/surveys/{RuleCollection.py → rules/rule_collection.py} +21 -30
- edsl/surveys/{RuleManager.py → rules/rule_manager.py} +19 -13
- edsl/surveys/survey.py +1743 -0
- edsl/surveys/{SurveyExportMixin.py → survey_export.py} +22 -27
- edsl/surveys/{SurveyFlowVisualization.py → survey_flow_visualization.py} +11 -2
- edsl/surveys/{Simulator.py → survey_simulator.py} +10 -3
- edsl/tasks/__init__.py +32 -0
- edsl/{jobs/tasks/QuestionTaskCreator.py → tasks/question_task_creator.py} +115 -57
- edsl/tasks/task_creators.py +135 -0
- edsl/{jobs/tasks/TaskHistory.py → tasks/task_history.py} +86 -47
- edsl/{jobs/tasks → tasks}/task_status_enum.py +91 -7
- edsl/tasks/task_status_log.py +85 -0
- edsl/tokens/__init__.py +2 -0
- edsl/tokens/interview_token_usage.py +53 -0
- edsl/utilities/PrettyList.py +1 -1
- edsl/utilities/SystemInfo.py +25 -22
- edsl/utilities/__init__.py +29 -21
- edsl/utilities/gcp_bucket/__init__.py +2 -0
- edsl/utilities/gcp_bucket/cloud_storage.py +99 -96
- edsl/utilities/interface.py +44 -536
- edsl/{results/MarkdownToPDF.py → utilities/markdown_to_pdf.py} +13 -5
- edsl/utilities/repair_functions.py +1 -1
- {edsl-0.1.46.dist-info → edsl-0.1.48.dist-info}/METADATA +3 -2
- edsl-0.1.48.dist-info/RECORD +347 -0
- edsl/Base.py +0 -426
- edsl/BaseDiff.py +0 -260
- edsl/agents/InvigilatorBase.py +0 -260
- edsl/agents/PromptConstructor.py +0 -318
- 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/coop/PriceFetcher.py +0 -54
- edsl/data/Cache.py +0 -580
- edsl/data/CacheEntry.py +0 -230
- edsl/data/SQLiteDict.py +0 -292
- edsl/data/__init__.py +0 -5
- edsl/data/orm.py +0 -10
- edsl/exceptions/cache.py +0 -5
- edsl/exceptions/coop.py +0 -14
- edsl/exceptions/data.py +0 -14
- edsl/exceptions/scenarios.py +0 -29
- edsl/jobs/Answers.py +0 -43
- edsl/jobs/JobsPrompts.py +0 -354
- edsl/jobs/buckets/BucketCollection.py +0 -134
- edsl/jobs/buckets/ModelBuckets.py +0 -65
- edsl/jobs/buckets/TokenBucket.py +0 -283
- edsl/jobs/buckets/TokenBucketClient.py +0 -191
- edsl/jobs/interviews/Interview.py +0 -395
- edsl/jobs/interviews/InterviewExceptionCollection.py +0 -99
- edsl/jobs/interviews/InterviewStatisticsCollection.py +0 -25
- edsl/jobs/runners/JobsRunnerAsyncio.py +0 -163
- edsl/jobs/runners/JobsRunnerStatusData.py +0 -0
- edsl/jobs/tasks/TaskCreators.py +0 -64
- edsl/jobs/tasks/TaskStatusLog.py +0 -23
- edsl/jobs/tokens/InterviewTokenUsage.py +0 -27
- edsl/language_models/LanguageModel.py +0 -635
- edsl/language_models/ServiceDataSources.py +0 -0
- edsl/language_models/key_management/KeyLookup.py +0 -63
- edsl/language_models/key_management/KeyLookupCollection.py +0 -38
- edsl/language_models/key_management/models.py +0 -137
- edsl/questions/QuestionBase.py +0 -539
- edsl/questions/QuestionFreeText.py +0 -130
- edsl/questions/derived/QuestionLikertFive.py +0 -76
- edsl/results/DatasetExportMixin.py +0 -911
- edsl/results/ResultsExportMixin.py +0 -45
- edsl/results/TextEditor.py +0 -50
- edsl/results/results_fetch_mixin.py +0 -33
- edsl/results/results_tools_mixin.py +0 -98
- edsl/scenarios/DocumentChunker.py +0 -104
- edsl/scenarios/FileStore.py +0 -564
- edsl/scenarios/Scenario.py +0 -548
- edsl/scenarios/ScenarioHtmlMixin.py +0 -65
- edsl/scenarios/ScenarioListExportMixin.py +0 -45
- edsl/scenarios/handlers/latex.py +0 -5
- edsl/shared.py +0 -1
- edsl/surveys/Survey.py +0 -1306
- edsl/surveys/SurveyQualtricsImport.py +0 -284
- edsl/surveys/SurveyToApp.py +0 -141
- edsl/surveys/instructions/__init__.py +0 -0
- edsl/tools/__init__.py +0 -1
- edsl/tools/clusters.py +0 -192
- edsl/tools/embeddings.py +0 -27
- edsl/tools/embeddings_plotting.py +0 -118
- edsl/tools/plotting.py +0 -112
- edsl/tools/summarize.py +0 -18
- edsl/utilities/data/Registry.py +0 -6
- edsl/utilities/data/__init__.py +0 -1
- edsl/utilities/data/scooter_results.json +0 -1
- edsl-0.1.46.dist-info/RECORD +0 -366
- /edsl/coop/{CoopFunctionsMixin.py → coop_functions.py} +0 -0
- /edsl/{results → dataset/display}/CSSParameterizer.py +0 -0
- /edsl/{language_models/key_management → dataset/display}/__init__.py +0 -0
- /edsl/{results → dataset/display}/table_data_class.py +0 -0
- /edsl/{results → dataset/display}/table_display.css +0 -0
- /edsl/{results/ResultsGGMixin.py → dataset/r/ggplot.py} +0 -0
- /edsl/{results → dataset}/tree_explore.py +0 -0
- /edsl/{surveys/instructions/ChangeInstruction.py → instructions/change_instruction.py} +0 -0
- /edsl/{jobs/interviews → interviews}/interview_status_enum.py +0 -0
- /edsl/jobs/{runners/JobsRunnerStatus.py → jobs_runner_status.py} +0 -0
- /edsl/language_models/{PriceManager.py → price_manager.py} +0 -0
- /edsl/language_models/{fake_openai_call.py → unused/fake_openai_call.py} +0 -0
- /edsl/language_models/{fake_openai_service.py → unused/fake_openai_service.py} +0 -0
- /edsl/notebooks/{NotebookToLaTeX.py → notebook_to_latex.py} +0 -0
- /edsl/{exceptions/questions.py → questions/exceptions.py} +0 -0
- /edsl/questions/{SimpleAskMixin.py → simple_ask_mixin.py} +0 -0
- /edsl/surveys/{Memory.py → memory/memory.py} +0 -0
- /edsl/surveys/{MemoryManagement.py → memory/memory_management.py} +0 -0
- /edsl/surveys/{SurveyCSS.py → survey_css.py} +0 -0
- /edsl/{jobs/tokens/TokenUsage.py → tokens/token_usage.py} +0 -0
- /edsl/{results/MarkdownToDocx.py → utilities/markdown_to_docx.py} +0 -0
- /edsl/{TemplateLoader.py → utilities/template_loader.py} +0 -0
- {edsl-0.1.46.dist-info → edsl-0.1.48.dist-info}/LICENSE +0 -0
- {edsl-0.1.46.dist-info → edsl-0.1.48.dist-info}/WHEEL +0 -0
@@ -1,284 +0,0 @@
|
|
1
|
-
import json
|
2
|
-
import html
|
3
|
-
import re
|
4
|
-
|
5
|
-
from edsl import Question
|
6
|
-
from edsl import Survey
|
7
|
-
|
8
|
-
qualtrics_codes = {
|
9
|
-
"TE": "free_text",
|
10
|
-
"MC": "multiple_choice",
|
11
|
-
"Matrix": "matrix",
|
12
|
-
"DB": "instruction", # not quite right, but for now
|
13
|
-
"Timing": "free_text", # not quite right, but for now
|
14
|
-
}
|
15
|
-
# TE (Text Entry): Allows respondents to input a text response.
|
16
|
-
# MC (Multiple Choice): Provides respondents with a list of options to choose from.
|
17
|
-
# DB (Descriptive Text or Information): Displays text or information without requiring a response.
|
18
|
-
# Matrix: A grid-style question where respondents can evaluate multiple items using the same set of response options.
|
19
|
-
|
20
|
-
|
21
|
-
def clean_html(raw_html):
|
22
|
-
# Unescape HTML entities
|
23
|
-
clean_text = html.unescape(raw_html)
|
24
|
-
# Remove HTML tags
|
25
|
-
clean_text = re.sub(r"<.*?>", "", clean_text)
|
26
|
-
# Replace non-breaking spaces with regular spaces
|
27
|
-
clean_text = clean_text.replace("\xa0", " ")
|
28
|
-
# Optionally, strip leading/trailing spaces
|
29
|
-
clean_text = clean_text.strip()
|
30
|
-
return clean_text
|
31
|
-
|
32
|
-
|
33
|
-
class QualtricsQuestion:
|
34
|
-
def __init__(self, question_json, debug=False):
|
35
|
-
self.debug = debug
|
36
|
-
self.question_json = question_json
|
37
|
-
if self.element != "SQ":
|
38
|
-
raise ValueError("Invalid question element type")
|
39
|
-
|
40
|
-
@property
|
41
|
-
def element(self):
|
42
|
-
return self.question_json["Element"]
|
43
|
-
|
44
|
-
@property
|
45
|
-
def selector(self):
|
46
|
-
return self.question_json.get("Selector", None)
|
47
|
-
|
48
|
-
@property
|
49
|
-
def question_name(self):
|
50
|
-
return self.question_json["PrimaryAttribute"]
|
51
|
-
|
52
|
-
@property
|
53
|
-
def question_text(self):
|
54
|
-
return clean_html(self.question_json["Payload"]["QuestionText"])
|
55
|
-
|
56
|
-
@property
|
57
|
-
def raw_question_type(self):
|
58
|
-
return self.question_json["Payload"]["QuestionType"]
|
59
|
-
|
60
|
-
@property
|
61
|
-
def question_type(self):
|
62
|
-
q_type = qualtrics_codes.get(self.raw_question_type, None)
|
63
|
-
if q_type is None:
|
64
|
-
print(f"Unknown question type: {self.raw_question_type}")
|
65
|
-
return None
|
66
|
-
return q_type
|
67
|
-
|
68
|
-
@property
|
69
|
-
def choices(self):
|
70
|
-
if "Choices" in self.question_json["Payload"]:
|
71
|
-
return [
|
72
|
-
choice["Display"]
|
73
|
-
for choice in self.question_json["Payload"]["Choices"].values()
|
74
|
-
]
|
75
|
-
return None
|
76
|
-
|
77
|
-
@property
|
78
|
-
def answers(self):
|
79
|
-
if "Answers" in self.question_json["Payload"]:
|
80
|
-
return [
|
81
|
-
choice["Display"]
|
82
|
-
for choice in self.question_json["Payload"]["Choices"].values()
|
83
|
-
]
|
84
|
-
return None
|
85
|
-
|
86
|
-
def to_edsl(self):
|
87
|
-
if self.question_type == "instruction":
|
88
|
-
from edsl import Instruction
|
89
|
-
|
90
|
-
return [Instruction(text=self.question_text, name=self.question_name)]
|
91
|
-
|
92
|
-
if self.question_type == "free_text":
|
93
|
-
try:
|
94
|
-
q = Question(
|
95
|
-
**{
|
96
|
-
"question_type": self.question_type,
|
97
|
-
"question_text": self.question_text,
|
98
|
-
"question_name": self.question_name,
|
99
|
-
}
|
100
|
-
)
|
101
|
-
return [q]
|
102
|
-
except Exception as e:
|
103
|
-
return []
|
104
|
-
|
105
|
-
if self.question_type == "multiple_choice":
|
106
|
-
# Let's figure of it it's actually a checkbox question
|
107
|
-
if self.selector == "MAVR" or self.selector == "MULTIPLE":
|
108
|
-
try:
|
109
|
-
q = Question(
|
110
|
-
**{
|
111
|
-
"question_type": "checkbox",
|
112
|
-
"question_text": self.question_text,
|
113
|
-
"question_name": self.question_name,
|
114
|
-
"question_options": self.choices,
|
115
|
-
}
|
116
|
-
)
|
117
|
-
return [q]
|
118
|
-
except Exception as e:
|
119
|
-
return []
|
120
|
-
|
121
|
-
# maybe it's a linear scale!
|
122
|
-
if "<br>" in self.choices[0]:
|
123
|
-
option_labels = {}
|
124
|
-
question_options = []
|
125
|
-
for choice in self.choices:
|
126
|
-
if "<br>" in choice:
|
127
|
-
option_label, question_option = choice.split("<br>")
|
128
|
-
option_labels[int(question_option)] = option_label
|
129
|
-
question_options.append(int(question_option))
|
130
|
-
else:
|
131
|
-
question_options.append(int(choice))
|
132
|
-
try:
|
133
|
-
q = Question(
|
134
|
-
**{
|
135
|
-
"question_type": "linear_scale",
|
136
|
-
"question_text": self.question_text,
|
137
|
-
"question_name": self.question_name,
|
138
|
-
"question_options": question_options,
|
139
|
-
"option_labels": option_labels,
|
140
|
-
}
|
141
|
-
)
|
142
|
-
return [q]
|
143
|
-
except Exception as e:
|
144
|
-
if self.debug:
|
145
|
-
raise e
|
146
|
-
else:
|
147
|
-
print(e)
|
148
|
-
return []
|
149
|
-
|
150
|
-
try:
|
151
|
-
q = Question(
|
152
|
-
**{
|
153
|
-
"question_type": self.question_type,
|
154
|
-
"question_text": self.question_text,
|
155
|
-
"question_name": self.question_name,
|
156
|
-
"question_options": self.choices,
|
157
|
-
}
|
158
|
-
)
|
159
|
-
return [q]
|
160
|
-
except Exception as e:
|
161
|
-
return []
|
162
|
-
|
163
|
-
if self.question_type == "matrix":
|
164
|
-
questions = []
|
165
|
-
for index, choice in enumerate(self.choices):
|
166
|
-
try:
|
167
|
-
q = Question(
|
168
|
-
**{
|
169
|
-
"question_type": "multiple_choice",
|
170
|
-
"question_text": self.question_text + f" ({choice})",
|
171
|
-
"question_name": self.question_name + f"_{index}",
|
172
|
-
"question_options": self.answers,
|
173
|
-
}
|
174
|
-
)
|
175
|
-
questions.append(q)
|
176
|
-
except Exception as e:
|
177
|
-
continue
|
178
|
-
|
179
|
-
return questions
|
180
|
-
|
181
|
-
raise ValueError(f"Invalid question type: {self.question_type}")
|
182
|
-
|
183
|
-
|
184
|
-
class SurveyQualtricsImport:
|
185
|
-
def __init__(self, qsf_file_name: str):
|
186
|
-
self.qsf_file_name = qsf_file_name
|
187
|
-
self.question_data = self.extract_questions_from_json()
|
188
|
-
|
189
|
-
def create_survey(self):
|
190
|
-
questions = []
|
191
|
-
for qualtrics_questions in self.question_data:
|
192
|
-
questions.extend(qualtrics_questions.to_edsl())
|
193
|
-
return Survey(questions)
|
194
|
-
|
195
|
-
@property
|
196
|
-
def survey_data(self):
|
197
|
-
with open(self.qsf_file_name, "r") as f:
|
198
|
-
survey_data = json.load(f)
|
199
|
-
return survey_data
|
200
|
-
|
201
|
-
def extract_questions_from_json(self):
|
202
|
-
questions = self.survey_data["SurveyElements"]
|
203
|
-
|
204
|
-
extracted_questions = []
|
205
|
-
|
206
|
-
for question in questions:
|
207
|
-
if question["Element"] == "SQ":
|
208
|
-
extracted_questions.append(QualtricsQuestion(question))
|
209
|
-
|
210
|
-
return extracted_questions
|
211
|
-
|
212
|
-
def extract_blocks_from_json(self):
|
213
|
-
blocks = []
|
214
|
-
|
215
|
-
for element in self.survey_data["SurveyElements"]:
|
216
|
-
if element["Element"] == "BL":
|
217
|
-
for block_payload in element["Payload"]:
|
218
|
-
block_elements = [
|
219
|
-
BlockElement(be["Type"], be["QuestionID"])
|
220
|
-
for be in block_payload["BlockElements"]
|
221
|
-
]
|
222
|
-
options_data = block_payload.get("Options", {})
|
223
|
-
options = BlockOptions(
|
224
|
-
options_data.get("BlockLocking", "false"),
|
225
|
-
options_data.get("RandomizeQuestions", "false"),
|
226
|
-
options_data.get("BlockVisibility", "Collapsed"),
|
227
|
-
)
|
228
|
-
|
229
|
-
block = SurveyBlock(
|
230
|
-
block_payload["Type"],
|
231
|
-
block_payload["Description"],
|
232
|
-
block_payload["ID"],
|
233
|
-
block_elements,
|
234
|
-
options,
|
235
|
-
)
|
236
|
-
blocks.append(block)
|
237
|
-
|
238
|
-
return blocks
|
239
|
-
|
240
|
-
|
241
|
-
class SurveyBlock:
|
242
|
-
def __init__(self, block_type, description, block_id, block_elements, options):
|
243
|
-
self.block_type = block_type
|
244
|
-
self.description = description
|
245
|
-
self.block_id = block_id
|
246
|
-
self.block_elements = block_elements
|
247
|
-
self.options = options
|
248
|
-
|
249
|
-
def __repr__(self):
|
250
|
-
return f"SurveyBlock(type={self.block_type}, description={self.description}, id={self.block_id})"
|
251
|
-
|
252
|
-
|
253
|
-
class BlockElement:
|
254
|
-
def __init__(self, element_type, question_id):
|
255
|
-
self.element_type = element_type
|
256
|
-
self.question_id = question_id
|
257
|
-
|
258
|
-
def __repr__(self):
|
259
|
-
return f"BlockElement(type={self.element_type}, question_id={self.question_id})"
|
260
|
-
|
261
|
-
|
262
|
-
class BlockOptions:
|
263
|
-
def __init__(self, block_locking, randomize_questions, block_visibility):
|
264
|
-
self.block_locking = block_locking
|
265
|
-
self.randomize_questions = randomize_questions
|
266
|
-
self.block_visibility = block_visibility
|
267
|
-
|
268
|
-
def __repr__(self):
|
269
|
-
return (
|
270
|
-
f"BlockOptions(block_locking={self.block_locking}, "
|
271
|
-
f"randomize_questions={self.randomize_questions}, "
|
272
|
-
f"block_visibility={self.block_visibility})"
|
273
|
-
)
|
274
|
-
|
275
|
-
|
276
|
-
if __name__ == "__main__":
|
277
|
-
survey_creator = SurveyQualtricsImport("example.qsf")
|
278
|
-
# print(survey_creator.question_data)
|
279
|
-
# survey = survey_creator.create_survey()
|
280
|
-
# info = survey.push()
|
281
|
-
# print(info)
|
282
|
-
# questions = survey.extract_questions_from_json()
|
283
|
-
# for question in questions:
|
284
|
-
# print(question)
|
edsl/surveys/SurveyToApp.py
DELETED
@@ -1,141 +0,0 @@
|
|
1
|
-
from fastapi import FastAPI
|
2
|
-
from pydantic import BaseModel, create_model
|
3
|
-
from typing import Callable, Optional, Type, Dict, Any, List, Union
|
4
|
-
|
5
|
-
|
6
|
-
class SurveyToApp:
|
7
|
-
def __init__(self, survey):
|
8
|
-
self.survey = survey
|
9
|
-
self.app = FastAPI()
|
10
|
-
|
11
|
-
def parameters(self):
|
12
|
-
return self.survey.parameters
|
13
|
-
|
14
|
-
def create_input(self) -> Type[BaseModel]:
|
15
|
-
"""
|
16
|
-
Creates a Pydantic model based on the survey parameters.
|
17
|
-
Returns:
|
18
|
-
Type[BaseModel]: A dynamically created Pydantic model class
|
19
|
-
"""
|
20
|
-
# Get parameters from survey - now calling the method
|
21
|
-
params = self.parameters()
|
22
|
-
|
23
|
-
# Create field definitions dictionary
|
24
|
-
fields: Dict[str, Any] = {}
|
25
|
-
|
26
|
-
# Since params is a set, we'll handle each parameter directly
|
27
|
-
# Assuming each parameter in the set has the necessary attributes
|
28
|
-
for param in params:
|
29
|
-
# You might need to adjust these based on the actual parameter object structure
|
30
|
-
param_name = getattr(param, "name", str(param))
|
31
|
-
param_type = getattr(param, "type", "string")
|
32
|
-
is_required = getattr(param, "required", True)
|
33
|
-
|
34
|
-
# Map survey parameter types to Python types
|
35
|
-
type_mapping = {
|
36
|
-
"string": str,
|
37
|
-
"integer": int,
|
38
|
-
"float": float,
|
39
|
-
"boolean": bool,
|
40
|
-
"array": List,
|
41
|
-
# Add more type mappings as needed
|
42
|
-
}
|
43
|
-
|
44
|
-
# Get the Python type from mapping
|
45
|
-
python_type = type_mapping.get(param_type, str)
|
46
|
-
|
47
|
-
if is_required:
|
48
|
-
fields[param_name] = (python_type, ...)
|
49
|
-
else:
|
50
|
-
fields[param_name] = (Optional[python_type], None)
|
51
|
-
|
52
|
-
# Add the template variable 'name' that's used in the question text
|
53
|
-
fields["name"] = (str, ...)
|
54
|
-
|
55
|
-
# Create and return the Pydantic model
|
56
|
-
model_name = f"{self.survey.__class__.__name__}Model"
|
57
|
-
return create_model(model_name, **fields)
|
58
|
-
|
59
|
-
def create_route(self) -> Callable:
|
60
|
-
"""
|
61
|
-
Creates a FastAPI route handler for the survey.
|
62
|
-
Returns:
|
63
|
-
Callable: A route handler function
|
64
|
-
"""
|
65
|
-
input_model = self.create_input()
|
66
|
-
|
67
|
-
async def route_handler(input_data: input_model):
|
68
|
-
"""
|
69
|
-
Handles the API route by processing the input data through the survey.
|
70
|
-
Args:
|
71
|
-
input_data: The validated input data matching the created Pydantic model
|
72
|
-
Returns:
|
73
|
-
dict: The processed survey results
|
74
|
-
"""
|
75
|
-
# Convert Pydantic model to dict
|
76
|
-
data = input_data.dict()
|
77
|
-
print(data)
|
78
|
-
from edsl.scenarios.Scenario import Scenario
|
79
|
-
|
80
|
-
# Process the data through the survey
|
81
|
-
try:
|
82
|
-
s = Scenario(data)
|
83
|
-
results = self.survey.by(s).run()
|
84
|
-
return {
|
85
|
-
"status": "success",
|
86
|
-
"data": results.select("answer.*").to_scenario_list().to_dict(),
|
87
|
-
}
|
88
|
-
except Exception as e:
|
89
|
-
return {"status": "error", "message": str(e)}
|
90
|
-
|
91
|
-
return route_handler
|
92
|
-
|
93
|
-
def add_to_app(
|
94
|
-
self, app: FastAPI, path: str = "/survey", methods: List[str] = ["POST", "GET"]
|
95
|
-
):
|
96
|
-
"""
|
97
|
-
Adds the survey route to a FastAPI application.
|
98
|
-
Args:
|
99
|
-
app (FastAPI): The FastAPI application instance
|
100
|
-
path (str): The API endpoint path
|
101
|
-
methods (List[str]): HTTP methods to support
|
102
|
-
"""
|
103
|
-
route_handler = self.create_route()
|
104
|
-
input_model = self.create_input()
|
105
|
-
|
106
|
-
app.add_api_route(
|
107
|
-
path, route_handler, methods=methods, response_model=Dict[str, Any]
|
108
|
-
)
|
109
|
-
|
110
|
-
def create_app(self, path: str = "/survey", methods: List[str] = ["POST", "GET"]):
|
111
|
-
"""
|
112
|
-
Creates a FastAPI application with the survey route.
|
113
|
-
Args:
|
114
|
-
path (str): The API endpoint path
|
115
|
-
methods (List[str]): HTTP methods to support
|
116
|
-
Returns:
|
117
|
-
FastAPI: The FastAPI application instance
|
118
|
-
"""
|
119
|
-
app = FastAPI()
|
120
|
-
self.add_to_app(app, path=path, methods=methods)
|
121
|
-
return app
|
122
|
-
|
123
|
-
|
124
|
-
from edsl import QuestionFreeText, QuestionList
|
125
|
-
|
126
|
-
# q = QuestionFreeText(
|
127
|
-
# question_name="name_gender",
|
128
|
-
# question_text="Is this customarily a boy's name or a girl's name: {{ name}}",
|
129
|
-
# )
|
130
|
-
|
131
|
-
q = QuestionList(
|
132
|
-
question_name="examples",
|
133
|
-
question_text="Give me {{ num }} examples of {{ thing }}",
|
134
|
-
)
|
135
|
-
|
136
|
-
survey_app = SurveyToApp(q.to_survey())
|
137
|
-
|
138
|
-
if __name__ == "__main__":
|
139
|
-
import uvicorn
|
140
|
-
|
141
|
-
uvicorn.run(survey_app.create_app(path="/examples"), host="127.0.0.1", port=8000)
|
File without changes
|
edsl/tools/__init__.py
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
from edsl.tools.plotting import barchart
|
edsl/tools/clusters.py
DELETED
@@ -1,192 +0,0 @@
|
|
1
|
-
import json
|
2
|
-
import numpy as np
|
3
|
-
from sklearn.cluster import KMeans
|
4
|
-
from sklearn.manifold import TSNE
|
5
|
-
from sklearn.decomposition import PCA
|
6
|
-
from IPython.display import display_html
|
7
|
-
|
8
|
-
|
9
|
-
def compute_tsne(embeddings, cluster_labels, text_labels):
|
10
|
-
"""
|
11
|
-
Compute t-SNE on embedding vectors.
|
12
|
-
|
13
|
-
Parameters:
|
14
|
-
embeddings (np.ndarray): The embedding vectors.
|
15
|
-
cluster_labels (np.ndarray): Cluster labels for each embedding.
|
16
|
-
text_labels (list): Text labels for each embedding.
|
17
|
-
|
18
|
-
Returns:
|
19
|
-
list: List of dictionaries with x, y coordinates, cluster labels, and text labels.
|
20
|
-
"""
|
21
|
-
tsne = TSNE(n_components=2, random_state=42)
|
22
|
-
tsne_results = tsne.fit_transform(embeddings)
|
23
|
-
data = [
|
24
|
-
{
|
25
|
-
"x": float(tsne_results[i, 0]),
|
26
|
-
"y": float(tsne_results[i, 1]),
|
27
|
-
"cluster_label": str(cluster_labels[i]),
|
28
|
-
"text_label": text_labels[i],
|
29
|
-
}
|
30
|
-
for i in range(len(cluster_labels))
|
31
|
-
]
|
32
|
-
return data
|
33
|
-
|
34
|
-
|
35
|
-
def compute_pca(embeddings, cluster_labels, text_labels):
|
36
|
-
"""
|
37
|
-
Compute PCA on embedding vectors.
|
38
|
-
|
39
|
-
Parameters:
|
40
|
-
embeddings (np.ndarray): The embedding vectors.
|
41
|
-
cluster_labels (np.ndarray): Cluster labels for each embedding.
|
42
|
-
text_labels (list): Text labels for each embedding.
|
43
|
-
|
44
|
-
Returns:
|
45
|
-
list: List of dictionaries with x, y coordinates, cluster labels, and text labels.
|
46
|
-
"""
|
47
|
-
pca = PCA(n_components=2)
|
48
|
-
pca_results = pca.fit_transform(embeddings)
|
49
|
-
data = [
|
50
|
-
{
|
51
|
-
"x": float(pca_results[i, 0]),
|
52
|
-
"y": float(pca_results[i, 1]),
|
53
|
-
"cluster_label": str(cluster_labels[i]),
|
54
|
-
"text_label": text_labels[i],
|
55
|
-
}
|
56
|
-
for i in range(len(cluster_labels))
|
57
|
-
]
|
58
|
-
return data
|
59
|
-
|
60
|
-
|
61
|
-
def plot(embeddings, text_labels, n_clusters=5, method="tsne"):
|
62
|
-
"""
|
63
|
-
Perform k-means clustering and plot results in a Jupyter notebook using D3.js.
|
64
|
-
|
65
|
-
Parameters:
|
66
|
-
embeddings (np.ndarray): The embedding vectors.
|
67
|
-
text_labels (list): Text labels for each embedding.
|
68
|
-
n_clusters (int): The number of clusters to form.
|
69
|
-
method (str): The dimensionality reduction method to use ('tsne' or 'pca').
|
70
|
-
"""
|
71
|
-
# Perform k-means clustering
|
72
|
-
kmeans = KMeans(n_clusters=n_clusters, random_state=42)
|
73
|
-
cluster_labels = kmeans.fit_predict(embeddings)
|
74
|
-
|
75
|
-
# Compute dimensionality reduction
|
76
|
-
if method == "tsne":
|
77
|
-
data = compute_tsne(embeddings, cluster_labels, text_labels)
|
78
|
-
elif method == "pca":
|
79
|
-
data = compute_pca(embeddings, cluster_labels, text_labels)
|
80
|
-
else:
|
81
|
-
raise ValueError("Invalid method. Choose 'tsne' or 'pca'.")
|
82
|
-
|
83
|
-
# Convert data to JSON
|
84
|
-
data_json = json.dumps(data)
|
85
|
-
|
86
|
-
# HTML content with embedded data
|
87
|
-
html_content = f"""
|
88
|
-
<!DOCTYPE html>
|
89
|
-
<html lang="en">
|
90
|
-
<head>
|
91
|
-
<meta charset="UTF-8">
|
92
|
-
<title>t-SNE/PCA Plot with D3.js</title>
|
93
|
-
<script src="https://d3js.org/d3.v6.min.js"></script>
|
94
|
-
<style>
|
95
|
-
.tooltip {{
|
96
|
-
position: absolute;
|
97
|
-
text-align: center;
|
98
|
-
width: auto;
|
99
|
-
height: auto;
|
100
|
-
padding: 2px;
|
101
|
-
font: 12px sans-serif;
|
102
|
-
background: lightsteelblue;
|
103
|
-
border: 0px;
|
104
|
-
border-radius: 8px;
|
105
|
-
pointer-events: none;
|
106
|
-
}}
|
107
|
-
.dot {{
|
108
|
-
stroke: #000;
|
109
|
-
stroke-width: 0.5;
|
110
|
-
}}
|
111
|
-
</style>
|
112
|
-
</head>
|
113
|
-
<body>
|
114
|
-
<svg width="600" height="600"></svg>
|
115
|
-
|
116
|
-
<script>
|
117
|
-
// Embedded data
|
118
|
-
const data = {data_json};
|
119
|
-
|
120
|
-
const svg = d3.select("svg"),
|
121
|
-
width = +svg.attr("width"),
|
122
|
-
height = +svg.attr("height");
|
123
|
-
|
124
|
-
// Set up scales
|
125
|
-
const x = d3.scaleLinear()
|
126
|
-
.domain(d3.extent(data, d => d.x))
|
127
|
-
.range([0, width]);
|
128
|
-
|
129
|
-
const y = d3.scaleLinear()
|
130
|
-
.domain(d3.extent(data, d => d.y))
|
131
|
-
.range([height, 0]);
|
132
|
-
|
133
|
-
// Set up color scale
|
134
|
-
const color = d3.scaleOrdinal(d3.schemeCategory10);
|
135
|
-
|
136
|
-
// Create tooltip
|
137
|
-
const tooltip = d3.select("body").append("div")
|
138
|
-
.attr("class", "tooltip")
|
139
|
-
.style("opacity", 0);
|
140
|
-
|
141
|
-
// Create circles for each point
|
142
|
-
svg.selectAll("circle")
|
143
|
-
.data(data)
|
144
|
-
.enter().append("circle")
|
145
|
-
.attr("cx", d => x(d.x))
|
146
|
-
.attr("cy", d => y(d.y))
|
147
|
-
.attr("r", 5)
|
148
|
-
.attr("class", "dot")
|
149
|
-
.style("fill", d => color(d.cluster_label))
|
150
|
-
.on("mouseover", function(event, d) {{
|
151
|
-
tooltip.transition()
|
152
|
-
.duration(200)
|
153
|
-
.style("opacity", .9);
|
154
|
-
tooltip.html(d.text_label)
|
155
|
-
.style("left", (event.pageX + 5) + "px")
|
156
|
-
.style("top", (event.pageY - 28) + "px");
|
157
|
-
}})
|
158
|
-
.on("mouseout", function(d) {{
|
159
|
-
tooltip.transition()
|
160
|
-
.duration(500)
|
161
|
-
.style("opacity", 0);
|
162
|
-
}});
|
163
|
-
</script>
|
164
|
-
</body>
|
165
|
-
</html>
|
166
|
-
"""
|
167
|
-
|
168
|
-
# Write HTML content to a temporary file
|
169
|
-
html_file = "tsne_pca_plot.html"
|
170
|
-
with open(html_file, "w") as file:
|
171
|
-
file.write(html_content)
|
172
|
-
|
173
|
-
# Display the HTML content in an iframe within a Jupyter notebook
|
174
|
-
display_html(
|
175
|
-
f'<iframe src="{html_file}" width="600" height="600"></iframe>', raw=True
|
176
|
-
)
|
177
|
-
|
178
|
-
|
179
|
-
# Example usage
|
180
|
-
if __name__ == "__main__":
|
181
|
-
# Generate some sample data (embedding vectors)
|
182
|
-
np.random.seed(42)
|
183
|
-
embedding_vectors = np.random.rand(
|
184
|
-
100, 50
|
185
|
-
) # 100 samples with 50-dimensional embeddings
|
186
|
-
text_labels = [f"Text {i}" for i in range(100)] # Sample text labels
|
187
|
-
|
188
|
-
# Plot the clusters using t-SNE
|
189
|
-
plot(embedding_vectors, text_labels, n_clusters=5, method="tsne")
|
190
|
-
|
191
|
-
# Plot the clusters using PCA
|
192
|
-
plot(embedding_vectors, text_labels, n_clusters=5, method="pca")
|
edsl/tools/embeddings.py
DELETED
@@ -1,27 +0,0 @@
|
|
1
|
-
import openai
|
2
|
-
from dotenv import load_dotenv
|
3
|
-
import os
|
4
|
-
|
5
|
-
# Load environment variables from .env file
|
6
|
-
load_dotenv()
|
7
|
-
|
8
|
-
# Get the OpenAI API key from the environment variable
|
9
|
-
openai.api_key = os.getenv("OPENAI_API_KEY")
|
10
|
-
|
11
|
-
from openai import Client
|
12
|
-
|
13
|
-
|
14
|
-
def get_embeddings(texts):
|
15
|
-
"""
|
16
|
-
Get embeddings for a list of texts using OpenAI API.
|
17
|
-
|
18
|
-
Args:
|
19
|
-
texts (list of str): List of strings to get embeddings for.
|
20
|
-
|
21
|
-
Returns:
|
22
|
-
list of list of float: List of embeddings.
|
23
|
-
"""
|
24
|
-
client = Client()
|
25
|
-
response = client.embeddings.create(input=texts, model="text-embedding-ada-002")
|
26
|
-
embeddings = [item.embedding for item in response.data]
|
27
|
-
return embeddings
|