edsl 0.1.54__py3-none-any.whl → 0.1.55__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 +8 -1
- edsl/__init__original.py +134 -0
- edsl/__version__.py +1 -1
- edsl/agents/agent.py +29 -0
- edsl/agents/agent_list.py +36 -1
- edsl/base/base_class.py +281 -151
- edsl/buckets/__init__.py +8 -3
- edsl/buckets/bucket_collection.py +9 -3
- edsl/buckets/model_buckets.py +4 -2
- edsl/buckets/token_bucket.py +2 -2
- edsl/buckets/token_bucket_client.py +5 -3
- edsl/caching/cache.py +131 -62
- edsl/caching/cache_entry.py +70 -58
- edsl/caching/sql_dict.py +17 -0
- edsl/cli.py +99 -0
- edsl/config/config_class.py +16 -0
- edsl/conversation/__init__.py +31 -0
- edsl/coop/coop.py +276 -242
- edsl/coop/coop_jobs_objects.py +59 -0
- edsl/coop/coop_objects.py +29 -0
- edsl/coop/coop_regular_objects.py +26 -0
- edsl/coop/utils.py +24 -19
- edsl/dataset/dataset.py +338 -101
- edsl/db_list/sqlite_list.py +349 -0
- edsl/inference_services/__init__.py +40 -5
- edsl/inference_services/exceptions.py +11 -0
- edsl/inference_services/services/anthropic_service.py +5 -2
- edsl/inference_services/services/aws_bedrock.py +6 -2
- edsl/inference_services/services/azure_ai.py +6 -2
- edsl/inference_services/services/google_service.py +3 -2
- edsl/inference_services/services/mistral_ai_service.py +6 -2
- edsl/inference_services/services/open_ai_service.py +6 -2
- edsl/inference_services/services/perplexity_service.py +6 -2
- edsl/inference_services/services/test_service.py +94 -5
- edsl/interviews/answering_function.py +167 -59
- edsl/interviews/interview.py +124 -72
- edsl/interviews/interview_task_manager.py +10 -0
- edsl/invigilators/invigilators.py +9 -0
- edsl/jobs/async_interview_runner.py +146 -104
- edsl/jobs/data_structures.py +6 -4
- edsl/jobs/decorators.py +61 -0
- edsl/jobs/fetch_invigilator.py +61 -18
- edsl/jobs/html_table_job_logger.py +14 -2
- edsl/jobs/jobs.py +180 -104
- edsl/jobs/jobs_component_constructor.py +2 -2
- edsl/jobs/jobs_interview_constructor.py +2 -0
- edsl/jobs/jobs_remote_inference_logger.py +4 -0
- edsl/jobs/jobs_runner_status.py +30 -25
- edsl/jobs/progress_bar_manager.py +79 -0
- edsl/jobs/remote_inference.py +35 -1
- edsl/key_management/key_lookup_builder.py +6 -1
- edsl/language_models/language_model.py +86 -6
- edsl/language_models/model.py +10 -3
- edsl/language_models/price_manager.py +45 -75
- edsl/language_models/registry.py +5 -0
- edsl/notebooks/notebook.py +77 -10
- edsl/questions/VALIDATION_README.md +134 -0
- edsl/questions/__init__.py +24 -1
- edsl/questions/exceptions.py +21 -0
- edsl/questions/question_dict.py +201 -16
- edsl/questions/question_multiple_choice_with_other.py +624 -0
- edsl/questions/question_registry.py +2 -1
- edsl/questions/templates/multiple_choice_with_other/__init__.py +0 -0
- edsl/questions/templates/multiple_choice_with_other/answering_instructions.jinja +15 -0
- edsl/questions/templates/multiple_choice_with_other/question_presentation.jinja +17 -0
- edsl/questions/validation_analysis.py +185 -0
- edsl/questions/validation_cli.py +131 -0
- edsl/questions/validation_html_report.py +404 -0
- edsl/questions/validation_logger.py +136 -0
- edsl/results/result.py +63 -16
- edsl/results/results.py +702 -171
- edsl/scenarios/construct_download_link.py +16 -3
- edsl/scenarios/directory_scanner.py +226 -226
- edsl/scenarios/file_methods.py +5 -0
- edsl/scenarios/file_store.py +117 -6
- edsl/scenarios/handlers/__init__.py +5 -1
- edsl/scenarios/handlers/mp4_file_store.py +104 -0
- edsl/scenarios/handlers/webm_file_store.py +104 -0
- edsl/scenarios/scenario.py +120 -101
- edsl/scenarios/scenario_list.py +800 -727
- edsl/scenarios/scenario_list_gc_test.py +146 -0
- edsl/scenarios/scenario_list_memory_test.py +214 -0
- edsl/scenarios/scenario_list_source_refactor.md +35 -0
- edsl/scenarios/scenario_selector.py +5 -4
- edsl/scenarios/scenario_source.py +1990 -0
- edsl/scenarios/tests/test_scenario_list_sources.py +52 -0
- edsl/surveys/survey.py +22 -0
- edsl/tasks/__init__.py +4 -2
- edsl/tasks/task_history.py +198 -36
- edsl/tests/scenarios/test_ScenarioSource.py +51 -0
- edsl/tests/scenarios/test_scenario_list_sources.py +51 -0
- edsl/utilities/__init__.py +2 -1
- edsl/utilities/decorators.py +121 -0
- edsl/utilities/memory_debugger.py +1010 -0
- {edsl-0.1.54.dist-info → edsl-0.1.55.dist-info}/METADATA +51 -76
- {edsl-0.1.54.dist-info → edsl-0.1.55.dist-info}/RECORD +99 -75
- edsl/jobs/jobs_runner_asyncio.py +0 -281
- edsl/language_models/unused/fake_openai_service.py +0 -60
- {edsl-0.1.54.dist-info → edsl-0.1.55.dist-info}/LICENSE +0 -0
- {edsl-0.1.54.dist-info → edsl-0.1.55.dist-info}/WHEEL +0 -0
- {edsl-0.1.54.dist-info → edsl-0.1.55.dist-info}/entry_points.txt +0 -0
edsl/utilities/decorators.py
CHANGED
@@ -1,6 +1,14 @@
|
|
1
1
|
import functools
|
2
2
|
import asyncio
|
3
3
|
import nest_asyncio
|
4
|
+
import os
|
5
|
+
import gc
|
6
|
+
import time
|
7
|
+
import json
|
8
|
+
import psutil
|
9
|
+
import tracemalloc
|
10
|
+
from datetime import datetime
|
11
|
+
from pathlib import Path
|
4
12
|
from edsl import __version__ as edsl_version
|
5
13
|
|
6
14
|
nest_asyncio.apply()
|
@@ -74,3 +82,116 @@ def sync_wrapper(async_func):
|
|
74
82
|
return asyncio.run(async_func(*args, **kwargs))
|
75
83
|
|
76
84
|
return wrapper
|
85
|
+
|
86
|
+
|
87
|
+
def memory_profile(func):
|
88
|
+
"""
|
89
|
+
Decorator to profile memory usage of a function.
|
90
|
+
|
91
|
+
Only activates if the EDSL_MEMORY_PROFILE environment variable is set to 'true'
|
92
|
+
or if the function name is included in the EDSL_MEMORY_PROFILE_FUNCTIONS
|
93
|
+
environment variable (comma-separated list of function names).
|
94
|
+
|
95
|
+
Example:
|
96
|
+
EDSL_MEMORY_PROFILE=true python your_script.py
|
97
|
+
EDSL_MEMORY_PROFILE_FUNCTIONS=filter,duplicate python your_script.py
|
98
|
+
"""
|
99
|
+
@functools.wraps(func)
|
100
|
+
def wrapper(*args, **kwargs):
|
101
|
+
# Check if memory profiling is enabled
|
102
|
+
profile_env = os.environ.get('EDSL_MEMORY_PROFILE', '').lower() == 'true'
|
103
|
+
profile_functions = os.environ.get('EDSL_MEMORY_PROFILE_FUNCTIONS', '')
|
104
|
+
profile_func_list = [f.strip() for f in profile_functions.split(',') if f.strip()]
|
105
|
+
|
106
|
+
# Determine if this function should be profiled
|
107
|
+
should_profile = profile_env or func.__name__ in profile_func_list
|
108
|
+
|
109
|
+
if not should_profile:
|
110
|
+
# Normal execution if profiling is disabled
|
111
|
+
return func(*args, **kwargs)
|
112
|
+
|
113
|
+
# Begin memory profiling
|
114
|
+
# Force garbage collection before measuring
|
115
|
+
gc.collect()
|
116
|
+
gc.collect()
|
117
|
+
|
118
|
+
# Get process for memory measurements
|
119
|
+
process = psutil.Process(os.getpid())
|
120
|
+
|
121
|
+
# Start memory tracking
|
122
|
+
tracemalloc.start()
|
123
|
+
|
124
|
+
# Record starting memory
|
125
|
+
memory_before = process.memory_info().rss / (1024 * 1024) # MB
|
126
|
+
snapshot1 = tracemalloc.take_snapshot()
|
127
|
+
start_time = time.time()
|
128
|
+
|
129
|
+
# Execute the function
|
130
|
+
result = func(*args, **kwargs)
|
131
|
+
|
132
|
+
# Record ending stats
|
133
|
+
end_time = time.time()
|
134
|
+
snapshot2 = tracemalloc.take_snapshot()
|
135
|
+
memory_after = process.memory_info().rss / (1024 * 1024) # MB
|
136
|
+
|
137
|
+
# Calculate differences
|
138
|
+
execution_time = end_time - start_time
|
139
|
+
memory_diff = memory_after - memory_before
|
140
|
+
|
141
|
+
# Get top memory differences
|
142
|
+
top_stats = snapshot2.compare_to(snapshot1, 'lineno')
|
143
|
+
|
144
|
+
# Prepare stats for report and JSON
|
145
|
+
timestamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
|
146
|
+
stats = {
|
147
|
+
"timestamp": timestamp,
|
148
|
+
"function": func.__qualname__,
|
149
|
+
"execution_time_seconds": execution_time,
|
150
|
+
"memory_before_mb": memory_before,
|
151
|
+
"memory_after_mb": memory_after,
|
152
|
+
"memory_diff_mb": memory_diff,
|
153
|
+
"top_allocations": [
|
154
|
+
{
|
155
|
+
"file": stat.traceback.format()[0],
|
156
|
+
"size_kb": stat.size_diff / 1024
|
157
|
+
} for stat in top_stats[:10]
|
158
|
+
]
|
159
|
+
}
|
160
|
+
|
161
|
+
# Generate console report
|
162
|
+
print("\n" + "="*60)
|
163
|
+
print(f"MEMORY PROFILE REPORT - {func.__name__}")
|
164
|
+
print("="*60)
|
165
|
+
print(f"Timestamp: {timestamp}")
|
166
|
+
print(f"Function: {func.__qualname__}")
|
167
|
+
print("-"*60)
|
168
|
+
print(f"Execution time: {execution_time:.4f} seconds")
|
169
|
+
print(f"Memory before: {memory_before:.2f} MB")
|
170
|
+
print(f"Memory after: {memory_after:.2f} MB")
|
171
|
+
print(f"Memory difference: {memory_diff:.2f} MB")
|
172
|
+
print("-"*60)
|
173
|
+
print("Top 10 memory allocations by line:")
|
174
|
+
for stat in top_stats[:10]:
|
175
|
+
print(f"{stat.traceback.format()[0]} - {stat.size_diff / 1024:.2f} KB")
|
176
|
+
print("="*60)
|
177
|
+
|
178
|
+
# Save report to file if EDSL_MEMORY_PROFILE_SAVE is true
|
179
|
+
if os.environ.get('EDSL_MEMORY_PROFILE_SAVE', '').lower() == 'true':
|
180
|
+
report_dir = Path("./benchmark_logs/memory_reports")
|
181
|
+
report_dir.mkdir(parents=True, exist_ok=True)
|
182
|
+
|
183
|
+
# Create filename with timestamp and function name
|
184
|
+
timestamp_file = datetime.now().strftime('%Y%m%d_%H%M%S')
|
185
|
+
report_path = report_dir / f"{func.__name__}_{timestamp_file}.json"
|
186
|
+
|
187
|
+
with open(report_path, 'w') as f:
|
188
|
+
json.dump(stats, f, indent=2)
|
189
|
+
|
190
|
+
print(f"Memory profile report saved to: {report_path}")
|
191
|
+
|
192
|
+
# Stop memory tracking
|
193
|
+
tracemalloc.stop()
|
194
|
+
|
195
|
+
return result
|
196
|
+
|
197
|
+
return wrapper
|