edsl 0.1.48__py3-none-any.whl → 0.1.50__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (239) hide show
  1. edsl/__init__.py +124 -53
  2. edsl/__version__.py +1 -1
  3. edsl/agents/agent.py +21 -21
  4. edsl/agents/agent_list.py +2 -5
  5. edsl/agents/exceptions.py +119 -5
  6. edsl/base/__init__.py +10 -35
  7. edsl/base/base_class.py +71 -36
  8. edsl/base/base_exception.py +204 -0
  9. edsl/base/data_transfer_models.py +1 -1
  10. edsl/base/exceptions.py +94 -0
  11. edsl/buckets/__init__.py +15 -1
  12. edsl/buckets/bucket_collection.py +3 -4
  13. edsl/buckets/exceptions.py +75 -0
  14. edsl/buckets/model_buckets.py +1 -2
  15. edsl/buckets/token_bucket.py +11 -6
  16. edsl/buckets/token_bucket_api.py +1 -2
  17. edsl/buckets/token_bucket_client.py +9 -7
  18. edsl/caching/cache.py +7 -2
  19. edsl/caching/cache_entry.py +10 -9
  20. edsl/caching/exceptions.py +113 -7
  21. edsl/caching/remote_cache_sync.py +1 -2
  22. edsl/caching/sql_dict.py +17 -12
  23. edsl/cli.py +43 -0
  24. edsl/config/config_class.py +30 -6
  25. edsl/conversation/Conversation.py +3 -2
  26. edsl/conversation/exceptions.py +58 -0
  27. edsl/conversation/mug_negotiation.py +0 -2
  28. edsl/coop/__init__.py +20 -1
  29. edsl/coop/coop.py +129 -38
  30. edsl/coop/exceptions.py +188 -9
  31. edsl/coop/price_fetcher.py +3 -6
  32. edsl/coop/utils.py +4 -6
  33. edsl/dataset/__init__.py +5 -4
  34. edsl/dataset/dataset.py +53 -43
  35. edsl/dataset/dataset_operations_mixin.py +86 -72
  36. edsl/dataset/dataset_tree.py +9 -5
  37. edsl/dataset/display/table_display.py +0 -2
  38. edsl/dataset/display/table_renderers.py +0 -1
  39. edsl/dataset/exceptions.py +125 -0
  40. edsl/dataset/file_exports.py +18 -11
  41. edsl/dataset/r/ggplot.py +13 -6
  42. edsl/display/__init__.py +27 -0
  43. edsl/display/core.py +147 -0
  44. edsl/display/plugin.py +189 -0
  45. edsl/display/utils.py +52 -0
  46. edsl/inference_services/__init__.py +9 -1
  47. edsl/inference_services/available_model_cache_handler.py +1 -1
  48. edsl/inference_services/available_model_fetcher.py +4 -5
  49. edsl/inference_services/data_structures.py +9 -6
  50. edsl/inference_services/exceptions.py +132 -1
  51. edsl/inference_services/inference_service_abc.py +2 -2
  52. edsl/inference_services/inference_services_collection.py +2 -6
  53. edsl/inference_services/registry.py +4 -3
  54. edsl/inference_services/service_availability.py +2 -1
  55. edsl/inference_services/services/anthropic_service.py +4 -1
  56. edsl/inference_services/services/aws_bedrock.py +13 -12
  57. edsl/inference_services/services/azure_ai.py +12 -10
  58. edsl/inference_services/services/deep_infra_service.py +1 -4
  59. edsl/inference_services/services/deep_seek_service.py +1 -5
  60. edsl/inference_services/services/google_service.py +6 -2
  61. edsl/inference_services/services/groq_service.py +1 -1
  62. edsl/inference_services/services/mistral_ai_service.py +4 -2
  63. edsl/inference_services/services/ollama_service.py +1 -1
  64. edsl/inference_services/services/open_ai_service.py +7 -5
  65. edsl/inference_services/services/perplexity_service.py +6 -2
  66. edsl/inference_services/services/test_service.py +8 -7
  67. edsl/inference_services/services/together_ai_service.py +2 -3
  68. edsl/inference_services/services/xai_service.py +1 -1
  69. edsl/instructions/__init__.py +1 -1
  70. edsl/instructions/change_instruction.py +3 -2
  71. edsl/instructions/exceptions.py +61 -0
  72. edsl/instructions/instruction.py +5 -2
  73. edsl/instructions/instruction_collection.py +2 -1
  74. edsl/instructions/instruction_handler.py +4 -9
  75. edsl/interviews/ReportErrors.py +0 -3
  76. edsl/interviews/__init__.py +9 -2
  77. edsl/interviews/answering_function.py +11 -13
  78. edsl/interviews/exception_tracking.py +14 -7
  79. edsl/interviews/exceptions.py +79 -0
  80. edsl/interviews/interview.py +32 -29
  81. edsl/interviews/interview_status_dictionary.py +4 -2
  82. edsl/interviews/interview_status_log.py +2 -1
  83. edsl/interviews/interview_task_manager.py +3 -3
  84. edsl/interviews/request_token_estimator.py +3 -1
  85. edsl/interviews/statistics.py +2 -3
  86. edsl/invigilators/__init__.py +7 -1
  87. edsl/invigilators/exceptions.py +79 -0
  88. edsl/invigilators/invigilator_base.py +0 -1
  89. edsl/invigilators/invigilators.py +8 -12
  90. edsl/invigilators/prompt_constructor.py +1 -5
  91. edsl/invigilators/prompt_helpers.py +8 -4
  92. edsl/invigilators/question_instructions_prompt_builder.py +1 -1
  93. edsl/invigilators/question_option_processor.py +9 -5
  94. edsl/invigilators/question_template_replacements_builder.py +3 -2
  95. edsl/jobs/__init__.py +3 -3
  96. edsl/jobs/async_interview_runner.py +24 -22
  97. edsl/jobs/check_survey_scenario_compatibility.py +7 -6
  98. edsl/jobs/data_structures.py +7 -4
  99. edsl/jobs/exceptions.py +177 -8
  100. edsl/jobs/fetch_invigilator.py +1 -1
  101. edsl/jobs/jobs.py +72 -67
  102. edsl/jobs/jobs_checks.py +2 -3
  103. edsl/jobs/jobs_component_constructor.py +2 -2
  104. edsl/jobs/jobs_pricing_estimation.py +3 -2
  105. edsl/jobs/jobs_remote_inference_logger.py +5 -4
  106. edsl/jobs/jobs_runner_asyncio.py +1 -2
  107. edsl/jobs/jobs_runner_status.py +8 -9
  108. edsl/jobs/remote_inference.py +26 -23
  109. edsl/jobs/results_exceptions_handler.py +8 -5
  110. edsl/key_management/__init__.py +3 -1
  111. edsl/key_management/exceptions.py +62 -0
  112. edsl/key_management/key_lookup.py +1 -1
  113. edsl/key_management/key_lookup_builder.py +37 -14
  114. edsl/key_management/key_lookup_collection.py +2 -0
  115. edsl/language_models/__init__.py +1 -1
  116. edsl/language_models/exceptions.py +302 -14
  117. edsl/language_models/language_model.py +4 -7
  118. edsl/language_models/model.py +4 -4
  119. edsl/language_models/model_list.py +1 -1
  120. edsl/language_models/price_manager.py +1 -1
  121. edsl/language_models/raw_response_handler.py +14 -9
  122. edsl/language_models/registry.py +17 -21
  123. edsl/language_models/repair.py +0 -6
  124. edsl/language_models/unused/fake_openai_service.py +0 -1
  125. edsl/load_plugins.py +69 -0
  126. edsl/logger.py +146 -0
  127. edsl/notebooks/notebook.py +1 -1
  128. edsl/notebooks/notebook_to_latex.py +0 -1
  129. edsl/plugins/__init__.py +63 -0
  130. edsl/plugins/built_in/export_example.py +50 -0
  131. edsl/plugins/built_in/pig_latin.py +67 -0
  132. edsl/plugins/cli.py +372 -0
  133. edsl/plugins/cli_typer.py +283 -0
  134. edsl/plugins/exceptions.py +31 -0
  135. edsl/plugins/hookspec.py +51 -0
  136. edsl/plugins/plugin_host.py +128 -0
  137. edsl/plugins/plugin_manager.py +633 -0
  138. edsl/plugins/plugins_registry.py +168 -0
  139. edsl/prompts/__init__.py +2 -0
  140. edsl/prompts/exceptions.py +107 -5
  141. edsl/prompts/prompt.py +14 -6
  142. edsl/questions/HTMLQuestion.py +5 -11
  143. edsl/questions/Quick.py +0 -1
  144. edsl/questions/__init__.py +2 -0
  145. edsl/questions/answer_validator_mixin.py +318 -318
  146. edsl/questions/compose_questions.py +2 -2
  147. edsl/questions/descriptors.py +10 -49
  148. edsl/questions/exceptions.py +278 -22
  149. edsl/questions/loop_processor.py +7 -5
  150. edsl/questions/prompt_templates/question_list.jinja +3 -0
  151. edsl/questions/question_base.py +14 -16
  152. edsl/questions/question_base_gen_mixin.py +2 -2
  153. edsl/questions/question_base_prompts_mixin.py +9 -3
  154. edsl/questions/question_budget.py +9 -5
  155. edsl/questions/question_check_box.py +3 -5
  156. edsl/questions/question_dict.py +171 -194
  157. edsl/questions/question_extract.py +1 -1
  158. edsl/questions/question_free_text.py +4 -6
  159. edsl/questions/question_functional.py +4 -3
  160. edsl/questions/question_list.py +36 -9
  161. edsl/questions/question_matrix.py +95 -61
  162. edsl/questions/question_multiple_choice.py +6 -4
  163. edsl/questions/question_numerical.py +2 -4
  164. edsl/questions/question_registry.py +4 -2
  165. edsl/questions/register_questions_meta.py +0 -1
  166. edsl/questions/response_validator_abc.py +7 -13
  167. edsl/questions/templates/dict/answering_instructions.jinja +1 -0
  168. edsl/questions/templates/rank/question_presentation.jinja +1 -1
  169. edsl/results/__init__.py +1 -1
  170. edsl/results/exceptions.py +141 -7
  171. edsl/results/report.py +0 -1
  172. edsl/results/result.py +4 -5
  173. edsl/results/results.py +10 -51
  174. edsl/results/results_selector.py +8 -4
  175. edsl/scenarios/PdfExtractor.py +2 -2
  176. edsl/scenarios/construct_download_link.py +69 -35
  177. edsl/scenarios/directory_scanner.py +33 -14
  178. edsl/scenarios/document_chunker.py +1 -1
  179. edsl/scenarios/exceptions.py +238 -14
  180. edsl/scenarios/file_methods.py +1 -1
  181. edsl/scenarios/file_store.py +7 -3
  182. edsl/scenarios/handlers/__init__.py +17 -0
  183. edsl/scenarios/handlers/docx_file_store.py +0 -5
  184. edsl/scenarios/handlers/pdf_file_store.py +0 -1
  185. edsl/scenarios/handlers/pptx_file_store.py +0 -5
  186. edsl/scenarios/handlers/py_file_store.py +0 -1
  187. edsl/scenarios/handlers/sql_file_store.py +1 -4
  188. edsl/scenarios/handlers/sqlite_file_store.py +0 -1
  189. edsl/scenarios/handlers/txt_file_store.py +1 -1
  190. edsl/scenarios/scenario.py +0 -1
  191. edsl/scenarios/scenario_list.py +152 -18
  192. edsl/scenarios/scenario_list_pdf_tools.py +1 -0
  193. edsl/scenarios/scenario_selector.py +0 -1
  194. edsl/surveys/__init__.py +3 -4
  195. edsl/surveys/dag/__init__.py +4 -2
  196. edsl/surveys/descriptors.py +1 -1
  197. edsl/surveys/edit_survey.py +1 -0
  198. edsl/surveys/exceptions.py +165 -9
  199. edsl/surveys/memory/__init__.py +5 -3
  200. edsl/surveys/memory/memory_management.py +1 -0
  201. edsl/surveys/memory/memory_plan.py +6 -15
  202. edsl/surveys/rules/__init__.py +5 -3
  203. edsl/surveys/rules/rule.py +1 -2
  204. edsl/surveys/rules/rule_collection.py +1 -1
  205. edsl/surveys/survey.py +12 -24
  206. edsl/surveys/survey_export.py +6 -3
  207. edsl/surveys/survey_flow_visualization.py +10 -1
  208. edsl/tasks/__init__.py +2 -0
  209. edsl/tasks/question_task_creator.py +3 -3
  210. edsl/tasks/task_creators.py +1 -3
  211. edsl/tasks/task_history.py +5 -7
  212. edsl/tasks/task_status_log.py +1 -2
  213. edsl/tokens/__init__.py +3 -1
  214. edsl/tokens/token_usage.py +1 -1
  215. edsl/utilities/__init__.py +21 -1
  216. edsl/utilities/decorators.py +1 -2
  217. edsl/utilities/markdown_to_docx.py +2 -2
  218. edsl/utilities/markdown_to_pdf.py +1 -1
  219. edsl/utilities/repair_functions.py +0 -1
  220. edsl/utilities/restricted_python.py +0 -1
  221. edsl/utilities/template_loader.py +2 -3
  222. edsl/utilities/utilities.py +8 -29
  223. {edsl-0.1.48.dist-info → edsl-0.1.50.dist-info}/METADATA +32 -2
  224. edsl-0.1.50.dist-info/RECORD +363 -0
  225. edsl-0.1.50.dist-info/entry_points.txt +3 -0
  226. edsl/dataset/smart_objects.py +0 -96
  227. edsl/exceptions/BaseException.py +0 -21
  228. edsl/exceptions/__init__.py +0 -54
  229. edsl/exceptions/configuration.py +0 -16
  230. edsl/exceptions/general.py +0 -34
  231. edsl/study/ObjectEntry.py +0 -173
  232. edsl/study/ProofOfWork.py +0 -113
  233. edsl/study/SnapShot.py +0 -80
  234. edsl/study/Study.py +0 -520
  235. edsl/study/__init__.py +0 -6
  236. edsl/utilities/interface.py +0 -135
  237. edsl-0.1.48.dist-info/RECORD +0 -347
  238. {edsl-0.1.48.dist-info → edsl-0.1.50.dist-info}/LICENSE +0 -0
  239. {edsl-0.1.48.dist-info → edsl-0.1.50.dist-info}/WHEEL +0 -0
edsl/load_plugins.py ADDED
@@ -0,0 +1,69 @@
1
+ import logging
2
+
3
+ def load_plugins():
4
+ """
5
+ Load plugins for EDSL.
6
+
7
+ This function handles the discovery and loading of plugins via the pluggy library.
8
+ It searches for entry points registered under the "edsl" namespace.
9
+ """
10
+ logger = logging.getLogger("edsl")
11
+
12
+ try:
13
+ logger.info("Loading plugins")
14
+ import pluggy
15
+ import pkg_resources
16
+
17
+ logger.info("Available edsl entrypoints: %s", [ep for ep in pkg_resources.iter_entry_points("edsl")])
18
+
19
+ # Import hook specs from the plugin system
20
+ from edsl.plugins.hookspec import EDSLPluginSpec
21
+
22
+ # Create plugin manager and register specs
23
+ pm = pluggy.PluginManager("edsl")
24
+ pm.add_hookspecs(EDSLPluginSpec)
25
+
26
+ # Load all plugins
27
+ logger.info("Loading setuptools entrypoints...")
28
+ pm.load_setuptools_entrypoints("edsl")
29
+
30
+ # Get registered plugins
31
+ registered_plugins = [
32
+ plugin_name
33
+ for plugin_name, _ in pm.list_name_plugin()
34
+ if plugin_name != "EDSLHookSpecs"
35
+ ]
36
+ logger.info("Registered plugins: %s", registered_plugins)
37
+
38
+ # Get plugins and add to __all__
39
+ logger.info("Calling edsl_plugin hook...")
40
+ try:
41
+ results = pm.hook.edsl_plugin()
42
+ logger.info("Results: %s", results)
43
+ plugins = {}
44
+
45
+ if results:
46
+ for plugin in results:
47
+ if hasattr(plugin, "__name__"):
48
+ plugin_name = plugin.__name__
49
+ elif hasattr(plugin, "__class__"):
50
+ plugin_name = plugin.__class__.__name__
51
+ else:
52
+ plugin_name = f"Plugin_{len(plugins)}"
53
+
54
+ logger.info(f"Loaded plugin: {plugin_name}")
55
+ plugins[plugin_name] = plugin
56
+
57
+ return plugins
58
+ except Exception as e:
59
+ logger.error("Error calling edsl_plugin hook: %s", e)
60
+ except ImportError as e:
61
+ # pluggy not available
62
+ logger.info("pluggy not available, skipping plugin loading: %s", e)
63
+ logger.debug("pluggy not available, skipping plugin loading: %s", e)
64
+ except Exception as e:
65
+ # Error loading plugins
66
+ logger.error("Error loading plugins: %s", e)
67
+ logger.debug("Error loading plugins: %s", e)
68
+
69
+ return {}
edsl/logger.py ADDED
@@ -0,0 +1,146 @@
1
+ """
2
+ Logger module for EDSL.
3
+
4
+ This module provides a centralized logging configuration for the EDSL package.
5
+ It configures console and file logging with appropriate formatting.
6
+ """
7
+
8
+ import logging
9
+ import os
10
+ import sys
11
+ from logging.handlers import RotatingFileHandler
12
+ from pathlib import Path
13
+
14
+ # Create the logger
15
+ logger = logging.getLogger("edsl")
16
+ logger.setLevel(logging.ERROR) # Default level
17
+
18
+ # Avoid adding handlers multiple times when imported in different modules
19
+ if not logger.handlers:
20
+ # Console handler removed - logs only go to file now
21
+
22
+ # File handler - create logs directory if it doesn't exist
23
+ try:
24
+ log_dir = Path.home() / ".edsl" / "logs"
25
+ os.makedirs(log_dir, exist_ok=True)
26
+
27
+ file_handler = RotatingFileHandler(
28
+ log_dir / "edsl.log", maxBytes=5 * 1024 * 1024, backupCount=3 # 5 MB
29
+ )
30
+ file_handler.setLevel(logging.ERROR)
31
+ file_formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
32
+ file_handler.setFormatter(file_formatter)
33
+ logger.addHandler(file_handler)
34
+ except Exception as e:
35
+ # Don't fail if file logging can't be set up
36
+ # No console handler to adjust
37
+ print(f"WARNING: Could not set up file logging: {e}")
38
+
39
+
40
+ def get_logger(name):
41
+ """
42
+ Get a logger for a specific module.
43
+
44
+ Args:
45
+ name: Usually __name__ of the module
46
+
47
+ Returns:
48
+ A Logger instance configured with the EDSL settings
49
+ """
50
+ return logging.getLogger(f"edsl.{name}")
51
+
52
+
53
+ def set_level(level):
54
+ """
55
+ Set the logging level for the EDSL logger.
56
+
57
+ Args:
58
+ level: A logging level (e.g., logging.DEBUG, logging.INFO, etc.)
59
+ """
60
+ logger.setLevel(level)
61
+ for handler in logger.handlers:
62
+ handler.setLevel(level)
63
+
64
+ # Update child loggers
65
+ for logger_name in logging.root.manager.loggerDict:
66
+ if logger_name.startswith("edsl."):
67
+ logging.getLogger(logger_name).setLevel(level)
68
+
69
+
70
+ # Convenience function to avoid importing logging in every file
71
+ def debug(msg, *args, **kwargs):
72
+ logger.debug(msg, *args, **kwargs)
73
+
74
+
75
+ def info(msg, *args, **kwargs):
76
+ logger.info(msg, *args, **kwargs)
77
+
78
+
79
+ def warning(msg, *args, **kwargs):
80
+ logger.warning(msg, *args, **kwargs)
81
+
82
+
83
+ def error(msg, *args, **kwargs):
84
+ logger.error(msg, *args, **kwargs)
85
+
86
+
87
+ def critical(msg, *args, **kwargs):
88
+ logger.critical(msg, *args, **kwargs)
89
+
90
+
91
+ def exception(msg, *args, **kwargs):
92
+ """Log an exception with traceback at the ERROR level"""
93
+ logger.exception(msg, *args, **kwargs)
94
+
95
+
96
+ def configure_from_config():
97
+ """
98
+ Configure logging based on EDSL_LOG_LEVEL environment variable or config.
99
+
100
+ This function looks for the EDSL_LOG_LEVEL setting in the config and sets
101
+ the logging level accordingly. Valid values are:
102
+ - DEBUG
103
+ - INFO
104
+ - WARNING
105
+ - ERROR
106
+ - CRITICAL
107
+ If no configuration is found, the default level (ERROR) is maintained.
108
+
109
+ """
110
+ try:
111
+ import os
112
+
113
+ # First check environment variable
114
+ log_level = os.environ.get("EDSL_LOG_LEVEL")
115
+
116
+ # If not in environment, try to get from config
117
+ if not log_level:
118
+ try:
119
+ from edsl.config import CONFIG
120
+
121
+ log_level = CONFIG.EDSL_LOG_LEVEL
122
+ except (ImportError, AttributeError):
123
+ # Config might not be available or doesn't have EDSL_LOG_LEVEL
124
+ pass
125
+
126
+ if log_level:
127
+ # Convert to uppercase to match logging constants
128
+ log_level = log_level.upper()
129
+
130
+ # Map string to logging level
131
+ level_map = {
132
+ "DEBUG": logging.DEBUG,
133
+ "INFO": logging.INFO,
134
+ "WARNING": logging.WARNING,
135
+ "ERROR": logging.ERROR,
136
+ "CRITICAL": logging.CRITICAL,
137
+ }
138
+
139
+ if log_level in level_map:
140
+ set_level(level_map[log_level])
141
+ info(f"Log level set to {log_level} from configuration")
142
+ else:
143
+ warning(f"Invalid log level in configuration: {log_level}")
144
+ except Exception as e:
145
+ # Catch any exceptions to ensure logging configuration doesn't break the application
146
+ warning(f"Error configuring logging from config: {e}")
@@ -2,7 +2,7 @@
2
2
 
3
3
  from __future__ import annotations
4
4
  import json
5
- from typing import Dict, List, Optional, Union
5
+ from typing import Dict, List, Optional
6
6
  from uuid import uuid4
7
7
 
8
8
  from ..base import Base
@@ -2,7 +2,6 @@ from typing import Optional, Dict
2
2
  import os
3
3
  import nbformat
4
4
  from nbconvert.exporters import LatexExporter
5
- from nbconvert.writers import FilesWriter
6
5
 
7
6
 
8
7
  class NotebookToLaTeX:
@@ -0,0 +1,63 @@
1
+ """EDSL Plugins module for extending functionality with custom plugins."""
2
+
3
+ # Import for public API
4
+ from .plugin_host import PluginHost, get_plugin_manager
5
+ from .exceptions import (
6
+ PluginException,
7
+ PluginNotFoundError,
8
+ PluginInstallationError,
9
+ GitHubRepoError,
10
+ InvalidPluginError,
11
+ PluginMethodError,
12
+ PluginDependencyError
13
+ )
14
+ from .cli import PluginCLI
15
+ # Import the Typer CLI
16
+ from .cli_typer import app as typer_app
17
+
18
+ # Public API functions
19
+ def install_from_github(github_url, branch=None):
20
+ """Install a plugin from a GitHub repository."""
21
+ return PluginHost.install_from_github(github_url, branch)
22
+
23
+ def uninstall_plugin(plugin_name):
24
+ """Uninstall a plugin by name."""
25
+ return PluginHost.uninstall_plugin(plugin_name)
26
+
27
+ def list_plugins():
28
+ """List all installed plugins."""
29
+ return PluginHost.list_plugins()
30
+
31
+ def get_exports():
32
+ """Get objects exported to the global namespace by plugins."""
33
+ return PluginHost.get_exports()
34
+
35
+ def cli():
36
+ """Run the plugin CLI (legacy version)."""
37
+ from .cli import main
38
+ main()
39
+
40
+ def cli_typer():
41
+ """Run the Typer-based plugin CLI."""
42
+ from .cli_typer import run
43
+ run()
44
+
45
+ __all__ = [
46
+ 'PluginHost',
47
+ 'get_plugin_manager',
48
+ 'install_from_github',
49
+ 'uninstall_plugin',
50
+ 'list_plugins',
51
+ 'get_exports',
52
+ 'cli',
53
+ 'cli_typer',
54
+ 'PluginCLI',
55
+ 'typer_app',
56
+ 'PluginException',
57
+ 'PluginNotFoundError',
58
+ 'PluginInstallationError',
59
+ 'GitHubRepoError',
60
+ 'InvalidPluginError',
61
+ 'PluginMethodError',
62
+ 'PluginDependencyError'
63
+ ]
@@ -0,0 +1,50 @@
1
+ # Example plugin that demonstrates exporting objects to the global namespace
2
+ import pluggy
3
+ from typing import Dict, Any, Optional
4
+
5
+ # Define a hook implementation marker
6
+ hookimpl = pluggy.HookimplMarker("edsl")
7
+
8
+ # Create a class that will be exported to the global namespace
9
+ class ExportedClass:
10
+ """An example class exported from a plugin to the global namespace."""
11
+
12
+ def __init__(self, name="Example"):
13
+ self.name = name
14
+
15
+ def greet(self):
16
+ """Return a greeting message."""
17
+ return f"Hello from {self.name}!"
18
+
19
+ # A function to be exported to the global namespace
20
+ def exported_function(text):
21
+ """An example function exported from a plugin to the global namespace."""
22
+ return f"Processed: {text}"
23
+
24
+ class ExportExample:
25
+ """Example plugin that exports objects to the global namespace."""
26
+
27
+ @hookimpl
28
+ def plugin_name(self):
29
+ return "ExportExample"
30
+
31
+ @hookimpl
32
+ def plugin_description(self):
33
+ return "Demonstrates how to export objects to the global namespace."
34
+
35
+ @hookimpl
36
+ def edsl_plugin(self, plugin_name=None):
37
+ if plugin_name is None or plugin_name == "ExportExample":
38
+ return self
39
+
40
+ @hookimpl
41
+ def get_plugin_methods(self):
42
+ return {}
43
+
44
+ @hookimpl
45
+ def exports_to_namespace(self) -> Dict[str, Any]:
46
+ """Export objects to the global namespace."""
47
+ return {
48
+ "ExportedClass": ExportedClass,
49
+ "exported_function": exported_function
50
+ }
@@ -0,0 +1,67 @@
1
+ # edsl/plugins/text_plugins.py
2
+ import pluggy
3
+ from typing import Dict, Any, Optional
4
+
5
+ # Define a hook implementation marker
6
+ hookimpl = pluggy.HookimplMarker("edsl")
7
+
8
+ # Create an exportable class for demonstration
9
+ class PigLatinTranslator:
10
+ """A class that translates text to Pig Latin."""
11
+
12
+ @staticmethod
13
+ def translate(text):
14
+ """Translate text to Pig Latin."""
15
+ words = text.split()
16
+ result = []
17
+ for word in words:
18
+ # Simple Pig Latin rule: move first letter to end and add "ay"
19
+ if len(word) > 1:
20
+ pig_latin = word[1:] + word[0] + "ay"
21
+ result.append(pig_latin)
22
+ else:
23
+ result.append(word + "ay")
24
+ return " ".join(result)
25
+
26
+ class PigLatin:
27
+ """Text processing plugin."""
28
+
29
+ @hookimpl
30
+ def plugin_name(self):
31
+ return "PigLatin"
32
+
33
+ @hookimpl
34
+ def plugin_description(self):
35
+ return "This plugin translates text to Pig Latin."
36
+
37
+ @hookimpl
38
+ def edsl_plugin(self, plugin_name=None):
39
+ if plugin_name is None or plugin_name == "PigLatin":
40
+ return self
41
+
42
+ @hookimpl
43
+ def get_plugin_methods(self):
44
+ return {
45
+ "pig_latin": self.pig_latin
46
+ }
47
+
48
+ @hookimpl
49
+ def exports_to_namespace(self) -> Dict[str, Any]:
50
+ """Export objects to the global namespace."""
51
+ return {
52
+ "PigLatinTranslator": PigLatinTranslator
53
+ }
54
+
55
+ def pig_latin(self, survey, *args, **kwargs):
56
+ """Get pig latin translation of survey questions."""
57
+ # A simple Pig Latin translator without using the model
58
+ # This avoids needing API keys for testing
59
+
60
+ #print(f"Processing survey: {survey}")
61
+
62
+ # Translate each question text
63
+ translations = []
64
+ for question in survey.questions:
65
+ translations.append(PigLatinTranslator.translate(question.question_text))
66
+
67
+ return translations