edsl 0.1.49__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.
- edsl/__init__.py +124 -53
- edsl/__version__.py +1 -1
- edsl/agents/agent.py +21 -21
- edsl/agents/agent_list.py +2 -5
- edsl/agents/exceptions.py +119 -5
- edsl/base/__init__.py +10 -35
- edsl/base/base_class.py +71 -36
- edsl/base/base_exception.py +204 -0
- edsl/base/data_transfer_models.py +1 -1
- edsl/base/exceptions.py +94 -0
- edsl/buckets/__init__.py +15 -1
- edsl/buckets/bucket_collection.py +3 -4
- edsl/buckets/exceptions.py +75 -0
- edsl/buckets/model_buckets.py +1 -2
- edsl/buckets/token_bucket.py +11 -6
- edsl/buckets/token_bucket_api.py +1 -2
- edsl/buckets/token_bucket_client.py +9 -7
- edsl/caching/cache.py +7 -2
- edsl/caching/cache_entry.py +10 -9
- edsl/caching/exceptions.py +113 -7
- edsl/caching/remote_cache_sync.py +1 -2
- edsl/caching/sql_dict.py +17 -12
- edsl/cli.py +43 -0
- edsl/config/config_class.py +30 -6
- edsl/conversation/Conversation.py +3 -2
- edsl/conversation/exceptions.py +58 -0
- edsl/conversation/mug_negotiation.py +0 -2
- edsl/coop/__init__.py +20 -1
- edsl/coop/coop.py +120 -29
- edsl/coop/exceptions.py +188 -9
- edsl/coop/price_fetcher.py +3 -6
- edsl/coop/utils.py +4 -6
- edsl/dataset/__init__.py +5 -4
- edsl/dataset/dataset.py +53 -43
- edsl/dataset/dataset_operations_mixin.py +86 -72
- edsl/dataset/dataset_tree.py +9 -5
- edsl/dataset/display/table_display.py +0 -2
- edsl/dataset/display/table_renderers.py +0 -1
- edsl/dataset/exceptions.py +125 -0
- edsl/dataset/file_exports.py +18 -11
- edsl/dataset/r/ggplot.py +13 -6
- edsl/display/__init__.py +27 -0
- edsl/display/core.py +147 -0
- edsl/display/plugin.py +189 -0
- edsl/display/utils.py +52 -0
- edsl/inference_services/__init__.py +9 -1
- edsl/inference_services/available_model_cache_handler.py +1 -1
- edsl/inference_services/available_model_fetcher.py +4 -5
- edsl/inference_services/data_structures.py +9 -6
- edsl/inference_services/exceptions.py +132 -1
- edsl/inference_services/inference_service_abc.py +2 -2
- edsl/inference_services/inference_services_collection.py +2 -6
- edsl/inference_services/registry.py +4 -3
- edsl/inference_services/service_availability.py +2 -1
- edsl/inference_services/services/anthropic_service.py +4 -1
- edsl/inference_services/services/aws_bedrock.py +13 -12
- edsl/inference_services/services/azure_ai.py +12 -10
- edsl/inference_services/services/deep_infra_service.py +1 -4
- edsl/inference_services/services/deep_seek_service.py +1 -5
- edsl/inference_services/services/google_service.py +6 -2
- edsl/inference_services/services/groq_service.py +1 -1
- edsl/inference_services/services/mistral_ai_service.py +4 -2
- edsl/inference_services/services/ollama_service.py +1 -1
- edsl/inference_services/services/open_ai_service.py +7 -5
- edsl/inference_services/services/perplexity_service.py +6 -2
- edsl/inference_services/services/test_service.py +8 -7
- edsl/inference_services/services/together_ai_service.py +2 -3
- edsl/inference_services/services/xai_service.py +1 -1
- edsl/instructions/__init__.py +1 -1
- edsl/instructions/change_instruction.py +3 -2
- edsl/instructions/exceptions.py +61 -0
- edsl/instructions/instruction.py +5 -2
- edsl/instructions/instruction_collection.py +2 -1
- edsl/instructions/instruction_handler.py +4 -9
- edsl/interviews/ReportErrors.py +0 -3
- edsl/interviews/__init__.py +9 -2
- edsl/interviews/answering_function.py +11 -13
- edsl/interviews/exception_tracking.py +14 -7
- edsl/interviews/exceptions.py +79 -0
- edsl/interviews/interview.py +32 -29
- edsl/interviews/interview_status_dictionary.py +4 -2
- edsl/interviews/interview_status_log.py +2 -1
- edsl/interviews/interview_task_manager.py +3 -3
- edsl/interviews/request_token_estimator.py +3 -1
- edsl/interviews/statistics.py +2 -3
- edsl/invigilators/__init__.py +7 -1
- edsl/invigilators/exceptions.py +79 -0
- edsl/invigilators/invigilator_base.py +0 -1
- edsl/invigilators/invigilators.py +8 -12
- edsl/invigilators/prompt_constructor.py +1 -5
- edsl/invigilators/prompt_helpers.py +8 -4
- edsl/invigilators/question_instructions_prompt_builder.py +1 -1
- edsl/invigilators/question_option_processor.py +9 -5
- edsl/invigilators/question_template_replacements_builder.py +3 -2
- edsl/jobs/__init__.py +3 -3
- edsl/jobs/async_interview_runner.py +24 -22
- edsl/jobs/check_survey_scenario_compatibility.py +7 -6
- edsl/jobs/data_structures.py +7 -4
- edsl/jobs/exceptions.py +177 -8
- edsl/jobs/fetch_invigilator.py +1 -1
- edsl/jobs/jobs.py +72 -67
- edsl/jobs/jobs_checks.py +2 -3
- edsl/jobs/jobs_component_constructor.py +2 -2
- edsl/jobs/jobs_pricing_estimation.py +3 -2
- edsl/jobs/jobs_remote_inference_logger.py +5 -4
- edsl/jobs/jobs_runner_asyncio.py +1 -2
- edsl/jobs/jobs_runner_status.py +8 -9
- edsl/jobs/remote_inference.py +26 -23
- edsl/jobs/results_exceptions_handler.py +8 -5
- edsl/key_management/__init__.py +3 -1
- edsl/key_management/exceptions.py +62 -0
- edsl/key_management/key_lookup.py +1 -1
- edsl/key_management/key_lookup_builder.py +37 -14
- edsl/key_management/key_lookup_collection.py +2 -0
- edsl/language_models/__init__.py +1 -1
- edsl/language_models/exceptions.py +302 -14
- edsl/language_models/language_model.py +4 -7
- edsl/language_models/model.py +4 -4
- edsl/language_models/model_list.py +1 -1
- edsl/language_models/price_manager.py +1 -1
- edsl/language_models/raw_response_handler.py +14 -9
- edsl/language_models/registry.py +17 -21
- edsl/language_models/repair.py +0 -6
- edsl/language_models/unused/fake_openai_service.py +0 -1
- edsl/load_plugins.py +69 -0
- edsl/logger.py +146 -0
- edsl/notebooks/notebook.py +1 -1
- edsl/notebooks/notebook_to_latex.py +0 -1
- edsl/plugins/__init__.py +63 -0
- edsl/plugins/built_in/export_example.py +50 -0
- edsl/plugins/built_in/pig_latin.py +67 -0
- edsl/plugins/cli.py +372 -0
- edsl/plugins/cli_typer.py +283 -0
- edsl/plugins/exceptions.py +31 -0
- edsl/plugins/hookspec.py +51 -0
- edsl/plugins/plugin_host.py +128 -0
- edsl/plugins/plugin_manager.py +633 -0
- edsl/plugins/plugins_registry.py +168 -0
- edsl/prompts/__init__.py +2 -0
- edsl/prompts/exceptions.py +107 -5
- edsl/prompts/prompt.py +14 -6
- edsl/questions/HTMLQuestion.py +5 -11
- edsl/questions/Quick.py +0 -1
- edsl/questions/__init__.py +2 -0
- edsl/questions/answer_validator_mixin.py +318 -318
- edsl/questions/compose_questions.py +2 -2
- edsl/questions/descriptors.py +10 -49
- edsl/questions/exceptions.py +278 -22
- edsl/questions/loop_processor.py +7 -5
- edsl/questions/prompt_templates/question_list.jinja +3 -0
- edsl/questions/question_base.py +14 -16
- edsl/questions/question_base_gen_mixin.py +2 -2
- edsl/questions/question_base_prompts_mixin.py +9 -3
- edsl/questions/question_budget.py +9 -5
- edsl/questions/question_check_box.py +3 -5
- edsl/questions/question_dict.py +171 -194
- edsl/questions/question_extract.py +1 -1
- edsl/questions/question_free_text.py +4 -6
- edsl/questions/question_functional.py +4 -3
- edsl/questions/question_list.py +36 -9
- edsl/questions/question_matrix.py +95 -61
- edsl/questions/question_multiple_choice.py +6 -4
- edsl/questions/question_numerical.py +2 -4
- edsl/questions/question_registry.py +4 -2
- edsl/questions/register_questions_meta.py +0 -1
- edsl/questions/response_validator_abc.py +7 -13
- edsl/questions/templates/dict/answering_instructions.jinja +1 -0
- edsl/questions/templates/rank/question_presentation.jinja +1 -1
- edsl/results/__init__.py +1 -1
- edsl/results/exceptions.py +141 -7
- edsl/results/report.py +0 -1
- edsl/results/result.py +4 -5
- edsl/results/results.py +10 -51
- edsl/results/results_selector.py +8 -4
- edsl/scenarios/PdfExtractor.py +2 -2
- edsl/scenarios/construct_download_link.py +69 -35
- edsl/scenarios/directory_scanner.py +33 -14
- edsl/scenarios/document_chunker.py +1 -1
- edsl/scenarios/exceptions.py +238 -14
- edsl/scenarios/file_methods.py +1 -1
- edsl/scenarios/file_store.py +7 -3
- edsl/scenarios/handlers/__init__.py +17 -0
- edsl/scenarios/handlers/docx_file_store.py +0 -5
- edsl/scenarios/handlers/pdf_file_store.py +0 -1
- edsl/scenarios/handlers/pptx_file_store.py +0 -5
- edsl/scenarios/handlers/py_file_store.py +0 -1
- edsl/scenarios/handlers/sql_file_store.py +1 -4
- edsl/scenarios/handlers/sqlite_file_store.py +0 -1
- edsl/scenarios/handlers/txt_file_store.py +1 -1
- edsl/scenarios/scenario.py +0 -1
- edsl/scenarios/scenario_list.py +152 -18
- edsl/scenarios/scenario_list_pdf_tools.py +1 -0
- edsl/scenarios/scenario_selector.py +0 -1
- edsl/surveys/__init__.py +3 -4
- edsl/surveys/dag/__init__.py +4 -2
- edsl/surveys/descriptors.py +1 -1
- edsl/surveys/edit_survey.py +1 -0
- edsl/surveys/exceptions.py +165 -9
- edsl/surveys/memory/__init__.py +5 -3
- edsl/surveys/memory/memory_management.py +1 -0
- edsl/surveys/memory/memory_plan.py +6 -15
- edsl/surveys/rules/__init__.py +5 -3
- edsl/surveys/rules/rule.py +1 -2
- edsl/surveys/rules/rule_collection.py +1 -1
- edsl/surveys/survey.py +12 -24
- edsl/surveys/survey_export.py +6 -3
- edsl/surveys/survey_flow_visualization.py +10 -1
- edsl/tasks/__init__.py +2 -0
- edsl/tasks/question_task_creator.py +3 -3
- edsl/tasks/task_creators.py +1 -3
- edsl/tasks/task_history.py +5 -7
- edsl/tasks/task_status_log.py +1 -2
- edsl/tokens/__init__.py +3 -1
- edsl/tokens/token_usage.py +1 -1
- edsl/utilities/__init__.py +21 -1
- edsl/utilities/decorators.py +1 -2
- edsl/utilities/markdown_to_docx.py +2 -2
- edsl/utilities/markdown_to_pdf.py +1 -1
- edsl/utilities/repair_functions.py +0 -1
- edsl/utilities/restricted_python.py +0 -1
- edsl/utilities/template_loader.py +2 -3
- edsl/utilities/utilities.py +8 -29
- {edsl-0.1.49.dist-info → edsl-0.1.50.dist-info}/METADATA +32 -2
- edsl-0.1.50.dist-info/RECORD +363 -0
- edsl-0.1.50.dist-info/entry_points.txt +3 -0
- edsl/dataset/smart_objects.py +0 -96
- edsl/exceptions/BaseException.py +0 -21
- edsl/exceptions/__init__.py +0 -54
- edsl/exceptions/configuration.py +0 -16
- edsl/exceptions/general.py +0 -34
- edsl/study/ObjectEntry.py +0 -173
- edsl/study/ProofOfWork.py +0 -113
- edsl/study/SnapShot.py +0 -80
- edsl/study/Study.py +0 -520
- edsl/study/__init__.py +0 -6
- edsl/utilities/interface.py +0 -135
- edsl-0.1.49.dist-info/RECORD +0 -347
- {edsl-0.1.49.dist-info → edsl-0.1.50.dist-info}/LICENSE +0 -0
- {edsl-0.1.49.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}")
|
edsl/notebooks/notebook.py
CHANGED
edsl/plugins/__init__.py
ADDED
@@ -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
|