mcli-framework 7.10.0__py3-none-any.whl → 7.10.2__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.

Potentially problematic release.


This version of mcli-framework might be problematic. Click here for more details.

Files changed (42) hide show
  1. mcli/lib/custom_commands.py +10 -0
  2. mcli/lib/optional_deps.py +240 -0
  3. mcli/ml/backtesting/run.py +5 -3
  4. mcli/ml/models/ensemble_models.py +1 -0
  5. mcli/ml/models/recommendation_models.py +1 -0
  6. mcli/ml/optimization/optimize.py +6 -4
  7. mcli/ml/serving/serve.py +2 -2
  8. mcli/ml/training/train.py +14 -7
  9. mcli/self/completion_cmd.py +2 -2
  10. mcli/workflow/doc_convert.py +82 -112
  11. mcli/workflow/git_commit/ai_service.py +13 -2
  12. mcli/workflow/notebook/converter.py +375 -0
  13. mcli/workflow/notebook/notebook_cmd.py +441 -0
  14. mcli/workflow/notebook/schema.py +402 -0
  15. mcli/workflow/notebook/validator.py +313 -0
  16. mcli/workflow/workflow.py +14 -0
  17. {mcli_framework-7.10.0.dist-info → mcli_framework-7.10.2.dist-info}/METADATA +37 -3
  18. {mcli_framework-7.10.0.dist-info → mcli_framework-7.10.2.dist-info}/RECORD +22 -37
  19. mcli/ml/features/political_features.py +0 -677
  20. mcli/ml/preprocessing/politician_trading_preprocessor.py +0 -570
  21. mcli/workflow/politician_trading/config.py +0 -134
  22. mcli/workflow/politician_trading/connectivity.py +0 -492
  23. mcli/workflow/politician_trading/data_sources.py +0 -654
  24. mcli/workflow/politician_trading/database.py +0 -412
  25. mcli/workflow/politician_trading/demo.py +0 -249
  26. mcli/workflow/politician_trading/models.py +0 -327
  27. mcli/workflow/politician_trading/monitoring.py +0 -413
  28. mcli/workflow/politician_trading/scrapers.py +0 -1074
  29. mcli/workflow/politician_trading/scrapers_california.py +0 -434
  30. mcli/workflow/politician_trading/scrapers_corporate_registry.py +0 -797
  31. mcli/workflow/politician_trading/scrapers_eu.py +0 -376
  32. mcli/workflow/politician_trading/scrapers_free_sources.py +0 -509
  33. mcli/workflow/politician_trading/scrapers_third_party.py +0 -373
  34. mcli/workflow/politician_trading/scrapers_uk.py +0 -378
  35. mcli/workflow/politician_trading/scrapers_us_states.py +0 -471
  36. mcli/workflow/politician_trading/seed_database.py +0 -520
  37. mcli/workflow/politician_trading/supabase_functions.py +0 -354
  38. mcli/workflow/politician_trading/workflow.py +0 -879
  39. {mcli_framework-7.10.0.dist-info → mcli_framework-7.10.2.dist-info}/WHEEL +0 -0
  40. {mcli_framework-7.10.0.dist-info → mcli_framework-7.10.2.dist-info}/entry_points.txt +0 -0
  41. {mcli_framework-7.10.0.dist-info → mcli_framework-7.10.2.dist-info}/licenses/LICENSE +0 -0
  42. {mcli_framework-7.10.0.dist-info → mcli_framework-7.10.2.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,402 @@
1
+ """
2
+ Notebook schema definitions for MCLI workflow notebooks.
3
+
4
+ This module defines the structure for Jupyter-compatible workflow notebooks
5
+ that can be edited with Monaco editor while maintaining backward compatibility
6
+ with existing MCLI workflow JSON format.
7
+ """
8
+
9
+ from dataclasses import dataclass, field
10
+ from datetime import datetime
11
+ from enum import Enum
12
+ from typing import Any, Dict, List, Optional, Union
13
+
14
+
15
+ class CellType(str, Enum):
16
+ """Types of cells in a workflow notebook."""
17
+
18
+ CODE = "code"
19
+ MARKDOWN = "markdown"
20
+ RAW = "raw"
21
+
22
+
23
+ class CellLanguage(str, Enum):
24
+ """Programming languages supported in code cells."""
25
+
26
+ PYTHON = "python"
27
+ SHELL = "shell"
28
+ BASH = "bash"
29
+ ZSH = "zsh"
30
+ FISH = "fish"
31
+
32
+
33
+ @dataclass
34
+ class CellOutput:
35
+ """Output from a cell execution."""
36
+
37
+ output_type: str # stream, execute_result, error, display_data
38
+ data: Optional[Dict[str, Any]] = None
39
+ text: Optional[List[str]] = None
40
+ name: Optional[str] = None # stdout, stderr
41
+ execution_count: Optional[int] = None
42
+ ename: Optional[str] = None # error name
43
+ evalue: Optional[str] = None # error value
44
+ traceback: Optional[List[str]] = None
45
+
46
+ def to_dict(self) -> Dict[str, Any]:
47
+ """Convert to Jupyter output format."""
48
+ result = {"output_type": self.output_type}
49
+
50
+ if self.data is not None:
51
+ result["data"] = self.data
52
+ if self.text is not None:
53
+ result["text"] = self.text
54
+ if self.name is not None:
55
+ result["name"] = self.name
56
+ if self.execution_count is not None:
57
+ result["execution_count"] = self.execution_count
58
+ if self.ename is not None:
59
+ result["ename"] = self.ename
60
+ if self.evalue is not None:
61
+ result["evalue"] = self.evalue
62
+ if self.traceback is not None:
63
+ result["traceback"] = self.traceback
64
+
65
+ return result
66
+
67
+ @classmethod
68
+ def from_dict(cls, data: Dict[str, Any]) -> "CellOutput":
69
+ """Create from Jupyter output format."""
70
+ return cls(
71
+ output_type=data["output_type"],
72
+ data=data.get("data"),
73
+ text=data.get("text"),
74
+ name=data.get("name"),
75
+ execution_count=data.get("execution_count"),
76
+ ename=data.get("ename"),
77
+ evalue=data.get("evalue"),
78
+ traceback=data.get("traceback"),
79
+ )
80
+
81
+
82
+ @dataclass
83
+ class NotebookCell:
84
+ """A cell in a workflow notebook."""
85
+
86
+ cell_type: CellType
87
+ source: Union[str, List[str]]
88
+ metadata: Dict[str, Any] = field(default_factory=dict)
89
+ outputs: List[CellOutput] = field(default_factory=list)
90
+ execution_count: Optional[int] = None
91
+ id: Optional[str] = None
92
+
93
+ def __post_init__(self):
94
+ """Normalize source to list of strings."""
95
+ if isinstance(self.source, str):
96
+ self.source = self.source.splitlines(keepends=True)
97
+
98
+ @property
99
+ def source_text(self) -> str:
100
+ """Get source as a single string."""
101
+ if isinstance(self.source, list):
102
+ return "".join(self.source)
103
+ return self.source
104
+
105
+ @property
106
+ def language(self) -> Optional[CellLanguage]:
107
+ """Get the language for code cells."""
108
+ if self.cell_type == CellType.CODE:
109
+ lang = self.metadata.get("language", "python")
110
+ try:
111
+ return CellLanguage(lang)
112
+ except ValueError:
113
+ return CellLanguage.PYTHON
114
+ return None
115
+
116
+ def to_dict(self) -> Dict[str, Any]:
117
+ """Convert to Jupyter notebook cell format."""
118
+ result = {
119
+ "cell_type": self.cell_type.value,
120
+ "metadata": self.metadata,
121
+ "source": self.source if isinstance(self.source, list) else [self.source],
122
+ }
123
+
124
+ if self.id:
125
+ result["id"] = self.id
126
+
127
+ if self.cell_type == CellType.CODE:
128
+ result["execution_count"] = self.execution_count
129
+ result["outputs"] = [output.to_dict() for output in self.outputs]
130
+
131
+ return result
132
+
133
+ @classmethod
134
+ def from_dict(cls, data: Dict[str, Any]) -> "NotebookCell":
135
+ """Create from Jupyter notebook cell format."""
136
+ cell_type = CellType(data["cell_type"])
137
+ outputs = []
138
+
139
+ if cell_type == CellType.CODE and "outputs" in data:
140
+ outputs = [CellOutput.from_dict(out) for out in data["outputs"]]
141
+
142
+ return cls(
143
+ cell_type=cell_type,
144
+ source=data["source"],
145
+ metadata=data.get("metadata", {}),
146
+ outputs=outputs,
147
+ execution_count=data.get("execution_count"),
148
+ id=data.get("id"),
149
+ )
150
+
151
+
152
+ @dataclass
153
+ class MCLIMetadata:
154
+ """MCLI-specific metadata for workflow notebooks."""
155
+
156
+ name: str
157
+ description: str = ""
158
+ group: Optional[str] = None
159
+ version: str = "1.0"
160
+ language: CellLanguage = CellLanguage.PYTHON
161
+ created_at: Optional[str] = None
162
+ updated_at: Optional[str] = None
163
+ extra: Dict[str, Any] = field(default_factory=dict)
164
+
165
+ def to_dict(self) -> Dict[str, Any]:
166
+ """Convert to dictionary format."""
167
+ result = {
168
+ "name": self.name,
169
+ "description": self.description,
170
+ "version": self.version,
171
+ "language": self.language.value,
172
+ }
173
+
174
+ if self.group:
175
+ result["group"] = self.group
176
+ if self.created_at:
177
+ result["created_at"] = self.created_at
178
+ if self.updated_at:
179
+ result["updated_at"] = self.updated_at
180
+ if self.extra:
181
+ result.update(self.extra)
182
+
183
+ return result
184
+
185
+ @classmethod
186
+ def from_dict(cls, data: Dict[str, Any]) -> "MCLIMetadata":
187
+ """Create from dictionary format."""
188
+ # Extract known fields
189
+ known_fields = {
190
+ "name",
191
+ "description",
192
+ "group",
193
+ "version",
194
+ "language",
195
+ "created_at",
196
+ "updated_at",
197
+ }
198
+ extra = {k: v for k, v in data.items() if k not in known_fields}
199
+
200
+ return cls(
201
+ name=data["name"],
202
+ description=data.get("description", ""),
203
+ group=data.get("group"),
204
+ version=data.get("version", "1.0"),
205
+ language=CellLanguage(data.get("language", "python")),
206
+ created_at=data.get("created_at"),
207
+ updated_at=data.get("updated_at"),
208
+ extra=extra,
209
+ )
210
+
211
+
212
+ @dataclass
213
+ class NotebookMetadata:
214
+ """Metadata for a workflow notebook."""
215
+
216
+ mcli: MCLIMetadata
217
+ kernelspec: Dict[str, str] = field(
218
+ default_factory=lambda: {
219
+ "display_name": "Python 3",
220
+ "language": "python",
221
+ "name": "python3",
222
+ }
223
+ )
224
+ language_info: Dict[str, Any] = field(
225
+ default_factory=lambda: {
226
+ "name": "python",
227
+ "version": "3.11.0",
228
+ "mimetype": "text/x-python",
229
+ "file_extension": ".py",
230
+ }
231
+ )
232
+ extra: Dict[str, Any] = field(default_factory=dict)
233
+
234
+ def to_dict(self) -> Dict[str, Any]:
235
+ """Convert to Jupyter metadata format."""
236
+ result = {
237
+ "mcli": self.mcli.to_dict(),
238
+ "kernelspec": self.kernelspec,
239
+ "language_info": self.language_info,
240
+ }
241
+ result.update(self.extra)
242
+ return result
243
+
244
+ @classmethod
245
+ def from_dict(cls, data: Dict[str, Any]) -> "NotebookMetadata":
246
+ """Create from Jupyter metadata format."""
247
+ # Extract known fields
248
+ mcli_data = data.get("mcli", {})
249
+ kernelspec = data.get("kernelspec", {})
250
+ language_info = data.get("language_info", {})
251
+
252
+ # Backward compatibility: if no mcli metadata, try to extract from root
253
+ if not mcli_data and "name" in data:
254
+ mcli_data = {
255
+ "name": data.get("name"),
256
+ "description": data.get("description", ""),
257
+ "group": data.get("group"),
258
+ "version": data.get("version", "1.0"),
259
+ "language": data.get("language", "python"),
260
+ "created_at": data.get("created_at"),
261
+ "updated_at": data.get("updated_at"),
262
+ }
263
+
264
+ extra = {k: v for k, v in data.items() if k not in {"mcli", "kernelspec", "language_info"}}
265
+
266
+ return cls(
267
+ mcli=MCLIMetadata.from_dict(mcli_data),
268
+ kernelspec=kernelspec or cls.__dataclass_fields__["kernelspec"].default_factory(),
269
+ language_info=language_info
270
+ or cls.__dataclass_fields__["language_info"].default_factory(),
271
+ extra=extra,
272
+ )
273
+
274
+
275
+ @dataclass
276
+ class WorkflowNotebook:
277
+ """A workflow notebook in Jupyter-compatible format."""
278
+
279
+ nbformat: int = 4
280
+ nbformat_minor: int = 5
281
+ metadata: NotebookMetadata = field(
282
+ default_factory=lambda: NotebookMetadata(mcli=MCLIMetadata(name="untitled"))
283
+ )
284
+ cells: List[NotebookCell] = field(default_factory=list)
285
+
286
+ def to_dict(self) -> Dict[str, Any]:
287
+ """Convert to Jupyter notebook JSON format."""
288
+ return {
289
+ "nbformat": self.nbformat,
290
+ "nbformat_minor": self.nbformat_minor,
291
+ "metadata": self.metadata.to_dict(),
292
+ "cells": [cell.to_dict() for cell in self.cells],
293
+ }
294
+
295
+ @classmethod
296
+ def from_dict(cls, data: Dict[str, Any]) -> "WorkflowNotebook":
297
+ """Create from Jupyter notebook JSON format."""
298
+ return cls(
299
+ nbformat=data.get("nbformat", 4),
300
+ nbformat_minor=data.get("nbformat_minor", 5),
301
+ metadata=NotebookMetadata.from_dict(data.get("metadata", {})),
302
+ cells=[NotebookCell.from_dict(cell) for cell in data.get("cells", [])],
303
+ )
304
+
305
+ def add_code_cell(
306
+ self,
307
+ source: str,
308
+ language: Optional[CellLanguage] = None,
309
+ metadata: Optional[Dict[str, Any]] = None,
310
+ ) -> NotebookCell:
311
+ """Add a code cell to the notebook."""
312
+ cell_metadata = metadata or {}
313
+ if language:
314
+ cell_metadata["language"] = language.value
315
+
316
+ cell = NotebookCell(
317
+ cell_type=CellType.CODE,
318
+ source=source,
319
+ metadata=cell_metadata,
320
+ )
321
+ self.cells.append(cell)
322
+ return cell
323
+
324
+ def add_markdown_cell(
325
+ self, source: str, metadata: Optional[Dict[str, Any]] = None
326
+ ) -> NotebookCell:
327
+ """Add a markdown cell to the notebook."""
328
+ cell = NotebookCell(
329
+ cell_type=CellType.MARKDOWN,
330
+ source=source,
331
+ metadata=metadata or {},
332
+ )
333
+ self.cells.append(cell)
334
+ return cell
335
+
336
+ @property
337
+ def code_cells(self) -> List[NotebookCell]:
338
+ """Get all code cells."""
339
+ return [cell for cell in self.cells if cell.cell_type == CellType.CODE]
340
+
341
+ @property
342
+ def markdown_cells(self) -> List[NotebookCell]:
343
+ """Get all markdown cells."""
344
+ return [cell for cell in self.cells if cell.cell_type == CellType.MARKDOWN]
345
+
346
+
347
+ # JSON Schema for validation
348
+ NOTEBOOK_SCHEMA = {
349
+ "$schema": "http://json-schema.org/draft-07/schema#",
350
+ "title": "MCLI Workflow Notebook",
351
+ "description": "Jupyter-compatible notebook format for MCLI workflows",
352
+ "type": "object",
353
+ "required": ["nbformat", "nbformat_minor", "metadata", "cells"],
354
+ "properties": {
355
+ "nbformat": {"type": "integer", "const": 4},
356
+ "nbformat_minor": {"type": "integer", "minimum": 0},
357
+ "metadata": {
358
+ "type": "object",
359
+ "required": ["mcli"],
360
+ "properties": {
361
+ "mcli": {
362
+ "type": "object",
363
+ "required": ["name"],
364
+ "properties": {
365
+ "name": {"type": "string"},
366
+ "description": {"type": "string"},
367
+ "group": {"type": "string"},
368
+ "version": {"type": "string"},
369
+ "language": {
370
+ "type": "string",
371
+ "enum": ["python", "shell", "bash", "zsh", "fish"],
372
+ },
373
+ "created_at": {"type": "string"},
374
+ "updated_at": {"type": "string"},
375
+ },
376
+ },
377
+ "kernelspec": {"type": "object"},
378
+ "language_info": {"type": "object"},
379
+ },
380
+ },
381
+ "cells": {
382
+ "type": "array",
383
+ "items": {
384
+ "type": "object",
385
+ "required": ["cell_type", "source", "metadata"],
386
+ "properties": {
387
+ "cell_type": {"type": "string", "enum": ["code", "markdown", "raw"]},
388
+ "source": {
389
+ "oneOf": [
390
+ {"type": "string"},
391
+ {"type": "array", "items": {"type": "string"}},
392
+ ]
393
+ },
394
+ "metadata": {"type": "object"},
395
+ "execution_count": {"type": ["integer", "null"]},
396
+ "outputs": {"type": "array", "items": {"type": "object"}},
397
+ "id": {"type": "string"},
398
+ },
399
+ },
400
+ },
401
+ },
402
+ }