mcli-framework 7.0.0__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 (186) hide show
  1. mcli/app/chat_cmd.py +42 -0
  2. mcli/app/commands_cmd.py +226 -0
  3. mcli/app/completion_cmd.py +216 -0
  4. mcli/app/completion_helpers.py +288 -0
  5. mcli/app/cron_test_cmd.py +697 -0
  6. mcli/app/logs_cmd.py +419 -0
  7. mcli/app/main.py +492 -0
  8. mcli/app/model/model.py +1060 -0
  9. mcli/app/model_cmd.py +227 -0
  10. mcli/app/redis_cmd.py +269 -0
  11. mcli/app/video/video.py +1114 -0
  12. mcli/app/visual_cmd.py +303 -0
  13. mcli/chat/chat.py +2409 -0
  14. mcli/chat/command_rag.py +514 -0
  15. mcli/chat/enhanced_chat.py +652 -0
  16. mcli/chat/system_controller.py +1010 -0
  17. mcli/chat/system_integration.py +1016 -0
  18. mcli/cli.py +25 -0
  19. mcli/config.toml +20 -0
  20. mcli/lib/api/api.py +586 -0
  21. mcli/lib/api/daemon_client.py +203 -0
  22. mcli/lib/api/daemon_client_local.py +44 -0
  23. mcli/lib/api/daemon_decorator.py +217 -0
  24. mcli/lib/api/mcli_decorators.py +1032 -0
  25. mcli/lib/auth/auth.py +85 -0
  26. mcli/lib/auth/aws_manager.py +85 -0
  27. mcli/lib/auth/azure_manager.py +91 -0
  28. mcli/lib/auth/credential_manager.py +192 -0
  29. mcli/lib/auth/gcp_manager.py +93 -0
  30. mcli/lib/auth/key_manager.py +117 -0
  31. mcli/lib/auth/mcli_manager.py +93 -0
  32. mcli/lib/auth/token_manager.py +75 -0
  33. mcli/lib/auth/token_util.py +1011 -0
  34. mcli/lib/config/config.py +47 -0
  35. mcli/lib/discovery/__init__.py +1 -0
  36. mcli/lib/discovery/command_discovery.py +274 -0
  37. mcli/lib/erd/erd.py +1345 -0
  38. mcli/lib/erd/generate_graph.py +453 -0
  39. mcli/lib/files/files.py +76 -0
  40. mcli/lib/fs/fs.py +109 -0
  41. mcli/lib/lib.py +29 -0
  42. mcli/lib/logger/logger.py +611 -0
  43. mcli/lib/performance/optimizer.py +409 -0
  44. mcli/lib/performance/rust_bridge.py +502 -0
  45. mcli/lib/performance/uvloop_config.py +154 -0
  46. mcli/lib/pickles/pickles.py +50 -0
  47. mcli/lib/search/cached_vectorizer.py +479 -0
  48. mcli/lib/services/data_pipeline.py +460 -0
  49. mcli/lib/services/lsh_client.py +441 -0
  50. mcli/lib/services/redis_service.py +387 -0
  51. mcli/lib/shell/shell.py +137 -0
  52. mcli/lib/toml/toml.py +33 -0
  53. mcli/lib/ui/styling.py +47 -0
  54. mcli/lib/ui/visual_effects.py +634 -0
  55. mcli/lib/watcher/watcher.py +185 -0
  56. mcli/ml/api/app.py +215 -0
  57. mcli/ml/api/middleware.py +224 -0
  58. mcli/ml/api/routers/admin_router.py +12 -0
  59. mcli/ml/api/routers/auth_router.py +244 -0
  60. mcli/ml/api/routers/backtest_router.py +12 -0
  61. mcli/ml/api/routers/data_router.py +12 -0
  62. mcli/ml/api/routers/model_router.py +302 -0
  63. mcli/ml/api/routers/monitoring_router.py +12 -0
  64. mcli/ml/api/routers/portfolio_router.py +12 -0
  65. mcli/ml/api/routers/prediction_router.py +267 -0
  66. mcli/ml/api/routers/trade_router.py +12 -0
  67. mcli/ml/api/routers/websocket_router.py +76 -0
  68. mcli/ml/api/schemas.py +64 -0
  69. mcli/ml/auth/auth_manager.py +425 -0
  70. mcli/ml/auth/models.py +154 -0
  71. mcli/ml/auth/permissions.py +302 -0
  72. mcli/ml/backtesting/backtest_engine.py +502 -0
  73. mcli/ml/backtesting/performance_metrics.py +393 -0
  74. mcli/ml/cache.py +400 -0
  75. mcli/ml/cli/main.py +398 -0
  76. mcli/ml/config/settings.py +394 -0
  77. mcli/ml/configs/dvc_config.py +230 -0
  78. mcli/ml/configs/mlflow_config.py +131 -0
  79. mcli/ml/configs/mlops_manager.py +293 -0
  80. mcli/ml/dashboard/app.py +532 -0
  81. mcli/ml/dashboard/app_integrated.py +738 -0
  82. mcli/ml/dashboard/app_supabase.py +560 -0
  83. mcli/ml/dashboard/app_training.py +615 -0
  84. mcli/ml/dashboard/cli.py +51 -0
  85. mcli/ml/data_ingestion/api_connectors.py +501 -0
  86. mcli/ml/data_ingestion/data_pipeline.py +567 -0
  87. mcli/ml/data_ingestion/stream_processor.py +512 -0
  88. mcli/ml/database/migrations/env.py +94 -0
  89. mcli/ml/database/models.py +667 -0
  90. mcli/ml/database/session.py +200 -0
  91. mcli/ml/experimentation/ab_testing.py +845 -0
  92. mcli/ml/features/ensemble_features.py +607 -0
  93. mcli/ml/features/political_features.py +676 -0
  94. mcli/ml/features/recommendation_engine.py +809 -0
  95. mcli/ml/features/stock_features.py +573 -0
  96. mcli/ml/features/test_feature_engineering.py +346 -0
  97. mcli/ml/logging.py +85 -0
  98. mcli/ml/mlops/data_versioning.py +518 -0
  99. mcli/ml/mlops/experiment_tracker.py +377 -0
  100. mcli/ml/mlops/model_serving.py +481 -0
  101. mcli/ml/mlops/pipeline_orchestrator.py +614 -0
  102. mcli/ml/models/base_models.py +324 -0
  103. mcli/ml/models/ensemble_models.py +675 -0
  104. mcli/ml/models/recommendation_models.py +474 -0
  105. mcli/ml/models/test_models.py +487 -0
  106. mcli/ml/monitoring/drift_detection.py +676 -0
  107. mcli/ml/monitoring/metrics.py +45 -0
  108. mcli/ml/optimization/portfolio_optimizer.py +834 -0
  109. mcli/ml/preprocessing/data_cleaners.py +451 -0
  110. mcli/ml/preprocessing/feature_extractors.py +491 -0
  111. mcli/ml/preprocessing/ml_pipeline.py +382 -0
  112. mcli/ml/preprocessing/politician_trading_preprocessor.py +569 -0
  113. mcli/ml/preprocessing/test_preprocessing.py +294 -0
  114. mcli/ml/scripts/populate_sample_data.py +200 -0
  115. mcli/ml/tasks.py +400 -0
  116. mcli/ml/tests/test_integration.py +429 -0
  117. mcli/ml/tests/test_training_dashboard.py +387 -0
  118. mcli/public/oi/oi.py +15 -0
  119. mcli/public/public.py +4 -0
  120. mcli/self/self_cmd.py +1246 -0
  121. mcli/workflow/daemon/api_daemon.py +800 -0
  122. mcli/workflow/daemon/async_command_database.py +681 -0
  123. mcli/workflow/daemon/async_process_manager.py +591 -0
  124. mcli/workflow/daemon/client.py +530 -0
  125. mcli/workflow/daemon/commands.py +1196 -0
  126. mcli/workflow/daemon/daemon.py +905 -0
  127. mcli/workflow/daemon/daemon_api.py +59 -0
  128. mcli/workflow/daemon/enhanced_daemon.py +571 -0
  129. mcli/workflow/daemon/process_cli.py +244 -0
  130. mcli/workflow/daemon/process_manager.py +439 -0
  131. mcli/workflow/daemon/test_daemon.py +275 -0
  132. mcli/workflow/dashboard/dashboard_cmd.py +113 -0
  133. mcli/workflow/docker/docker.py +0 -0
  134. mcli/workflow/file/file.py +100 -0
  135. mcli/workflow/gcloud/config.toml +21 -0
  136. mcli/workflow/gcloud/gcloud.py +58 -0
  137. mcli/workflow/git_commit/ai_service.py +328 -0
  138. mcli/workflow/git_commit/commands.py +430 -0
  139. mcli/workflow/lsh_integration.py +355 -0
  140. mcli/workflow/model_service/client.py +594 -0
  141. mcli/workflow/model_service/download_and_run_efficient_models.py +288 -0
  142. mcli/workflow/model_service/lightweight_embedder.py +397 -0
  143. mcli/workflow/model_service/lightweight_model_server.py +714 -0
  144. mcli/workflow/model_service/lightweight_test.py +241 -0
  145. mcli/workflow/model_service/model_service.py +1955 -0
  146. mcli/workflow/model_service/ollama_efficient_runner.py +425 -0
  147. mcli/workflow/model_service/pdf_processor.py +386 -0
  148. mcli/workflow/model_service/test_efficient_runner.py +234 -0
  149. mcli/workflow/model_service/test_example.py +315 -0
  150. mcli/workflow/model_service/test_integration.py +131 -0
  151. mcli/workflow/model_service/test_new_features.py +149 -0
  152. mcli/workflow/openai/openai.py +99 -0
  153. mcli/workflow/politician_trading/commands.py +1790 -0
  154. mcli/workflow/politician_trading/config.py +134 -0
  155. mcli/workflow/politician_trading/connectivity.py +490 -0
  156. mcli/workflow/politician_trading/data_sources.py +395 -0
  157. mcli/workflow/politician_trading/database.py +410 -0
  158. mcli/workflow/politician_trading/demo.py +248 -0
  159. mcli/workflow/politician_trading/models.py +165 -0
  160. mcli/workflow/politician_trading/monitoring.py +413 -0
  161. mcli/workflow/politician_trading/scrapers.py +966 -0
  162. mcli/workflow/politician_trading/scrapers_california.py +412 -0
  163. mcli/workflow/politician_trading/scrapers_eu.py +377 -0
  164. mcli/workflow/politician_trading/scrapers_uk.py +350 -0
  165. mcli/workflow/politician_trading/scrapers_us_states.py +438 -0
  166. mcli/workflow/politician_trading/supabase_functions.py +354 -0
  167. mcli/workflow/politician_trading/workflow.py +852 -0
  168. mcli/workflow/registry/registry.py +180 -0
  169. mcli/workflow/repo/repo.py +223 -0
  170. mcli/workflow/scheduler/commands.py +493 -0
  171. mcli/workflow/scheduler/cron_parser.py +238 -0
  172. mcli/workflow/scheduler/job.py +182 -0
  173. mcli/workflow/scheduler/monitor.py +139 -0
  174. mcli/workflow/scheduler/persistence.py +324 -0
  175. mcli/workflow/scheduler/scheduler.py +679 -0
  176. mcli/workflow/sync/sync_cmd.py +437 -0
  177. mcli/workflow/sync/test_cmd.py +314 -0
  178. mcli/workflow/videos/videos.py +242 -0
  179. mcli/workflow/wakatime/wakatime.py +11 -0
  180. mcli/workflow/workflow.py +37 -0
  181. mcli_framework-7.0.0.dist-info/METADATA +479 -0
  182. mcli_framework-7.0.0.dist-info/RECORD +186 -0
  183. mcli_framework-7.0.0.dist-info/WHEEL +5 -0
  184. mcli_framework-7.0.0.dist-info/entry_points.txt +7 -0
  185. mcli_framework-7.0.0.dist-info/licenses/LICENSE +21 -0
  186. mcli_framework-7.0.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,267 @@
1
+ """Prediction API routes"""
2
+
3
+ from typing import List, Optional
4
+ from datetime import datetime, timedelta
5
+ from uuid import UUID
6
+
7
+ from fastapi import APIRouter, Depends, HTTPException, status, Query, BackgroundTasks
8
+ from sqlalchemy.orm import Session
9
+ from pydantic import BaseModel
10
+
11
+ from mcli.ml.auth import get_current_active_user
12
+ from mcli.ml.database.session import get_db
13
+ from mcli.ml.database.models import User, Prediction, Model, StockData
14
+ from mcli.ml.api.schemas import PredictionRequest, PredictionResponse, BatchPredictionRequest
15
+ from mcli.ml.cache import cached, cache_set
16
+ from mcli.ml.models import get_model_by_id
17
+
18
+ router = APIRouter()
19
+
20
+
21
+ class PredictionInput(BaseModel):
22
+ ticker: str
23
+ features: dict
24
+ model_id: Optional[UUID] = None
25
+ horizon: int = 1 # Days ahead
26
+
27
+
28
+ @router.post("/predict", response_model=PredictionResponse)
29
+ async def create_prediction(
30
+ request: PredictionInput,
31
+ background_tasks: BackgroundTasks,
32
+ current_user: User = Depends(get_current_active_user),
33
+ db: Session = Depends(get_db)
34
+ ):
35
+ """Create a new prediction"""
36
+
37
+ # Get model (use default if not specified)
38
+ if request.model_id:
39
+ model = db.query(Model).filter(Model.id == request.model_id).first()
40
+ if not model:
41
+ raise HTTPException(
42
+ status_code=status.HTTP_404_NOT_FOUND,
43
+ detail="Model not found"
44
+ )
45
+ else:
46
+ # Get default deployed model
47
+ model = db.query(Model).filter(
48
+ Model.status == "deployed"
49
+ ).order_by(Model.deployed_at.desc()).first()
50
+
51
+ if not model:
52
+ raise HTTPException(
53
+ status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
54
+ detail="No deployed model available"
55
+ )
56
+
57
+ # Load model
58
+ ml_model = await get_model_by_id(str(model.id))
59
+
60
+ # Make prediction
61
+ import numpy as np
62
+ features_array = np.array(list(request.features.values())).reshape(1, -1)
63
+ predicted_return = float(ml_model.predict(features_array)[0])
64
+
65
+ # Calculate confidence (mock for now)
66
+ confidence_score = 0.75 + np.random.random() * 0.2
67
+
68
+ # Save prediction to database
69
+ prediction = Prediction(
70
+ model_id=model.id,
71
+ user_id=current_user.id,
72
+ ticker=request.ticker,
73
+ prediction_date=datetime.utcnow(),
74
+ target_date=datetime.utcnow() + timedelta(days=request.horizon),
75
+ predicted_return=predicted_return,
76
+ confidence_score=confidence_score,
77
+ feature_importance=request.features
78
+ )
79
+
80
+ db.add(prediction)
81
+ db.commit()
82
+ db.refresh(prediction)
83
+
84
+ # Cache prediction
85
+ cache_key = f"prediction:{prediction.id}"
86
+ await cache_set(cache_key, prediction, expire=3600)
87
+
88
+ # Background task to update stock data
89
+ background_tasks.add_task(update_stock_data, request.ticker, db)
90
+
91
+ return PredictionResponse(
92
+ id=prediction.id,
93
+ ticker=prediction.ticker,
94
+ predicted_return=prediction.predicted_return,
95
+ confidence_score=prediction.confidence_score,
96
+ target_date=prediction.target_date,
97
+ model_id=model.id,
98
+ model_name=model.name
99
+ )
100
+
101
+
102
+ @router.post("/predict/batch", response_model=List[PredictionResponse])
103
+ async def create_batch_predictions(
104
+ request: BatchPredictionRequest,
105
+ background_tasks: BackgroundTasks,
106
+ current_user: User = Depends(get_current_active_user),
107
+ db: Session = Depends(get_db)
108
+ ):
109
+ """Create predictions for multiple tickers"""
110
+ predictions = []
111
+
112
+ for ticker_data in request.tickers:
113
+ pred_input = PredictionInput(
114
+ ticker=ticker_data.ticker,
115
+ features=ticker_data.features,
116
+ model_id=request.model_id,
117
+ horizon=request.horizon
118
+ )
119
+
120
+ pred = await create_prediction(
121
+ pred_input,
122
+ background_tasks,
123
+ current_user,
124
+ db
125
+ )
126
+ predictions.append(pred)
127
+
128
+ return predictions
129
+
130
+
131
+ @router.get("/", response_model=List[PredictionResponse])
132
+ @cached(expire=60)
133
+ async def list_predictions(
134
+ skip: int = Query(0, ge=0),
135
+ limit: int = Query(100, le=1000),
136
+ ticker: Optional[str] = None,
137
+ start_date: Optional[datetime] = None,
138
+ end_date: Optional[datetime] = None,
139
+ current_user: User = Depends(get_current_active_user),
140
+ db: Session = Depends(get_db)
141
+ ):
142
+ """List user's predictions"""
143
+ query = db.query(Prediction).filter(Prediction.user_id == current_user.id)
144
+
145
+ if ticker:
146
+ query = query.filter(Prediction.ticker == ticker)
147
+
148
+ if start_date:
149
+ query = query.filter(Prediction.prediction_date >= start_date)
150
+
151
+ if end_date:
152
+ query = query.filter(Prediction.prediction_date <= end_date)
153
+
154
+ predictions = query.order_by(
155
+ Prediction.prediction_date.desc()
156
+ ).offset(skip).limit(limit).all()
157
+
158
+ return [PredictionResponse.from_orm(p) for p in predictions]
159
+
160
+
161
+ @router.get("/{prediction_id}", response_model=PredictionResponse)
162
+ @cached(expire=300)
163
+ async def get_prediction(
164
+ prediction_id: UUID,
165
+ current_user: User = Depends(get_current_active_user),
166
+ db: Session = Depends(get_db)
167
+ ):
168
+ """Get specific prediction details"""
169
+ prediction = db.query(Prediction).filter(
170
+ Prediction.id == prediction_id,
171
+ Prediction.user_id == current_user.id
172
+ ).first()
173
+
174
+ if not prediction:
175
+ raise HTTPException(
176
+ status_code=status.HTTP_404_NOT_FOUND,
177
+ detail="Prediction not found"
178
+ )
179
+
180
+ return PredictionResponse.from_orm(prediction)
181
+
182
+
183
+ @router.get("/{prediction_id}/outcome")
184
+ async def get_prediction_outcome(
185
+ prediction_id: UUID,
186
+ current_user: User = Depends(get_current_active_user),
187
+ db: Session = Depends(get_db)
188
+ ):
189
+ """Get actual outcome of a prediction"""
190
+ prediction = db.query(Prediction).filter(
191
+ Prediction.id == prediction_id,
192
+ Prediction.user_id == current_user.id
193
+ ).first()
194
+
195
+ if not prediction:
196
+ raise HTTPException(
197
+ status_code=status.HTTP_404_NOT_FOUND,
198
+ detail="Prediction not found"
199
+ )
200
+
201
+ # Check if target date has passed
202
+ if prediction.target_date > datetime.utcnow():
203
+ return {
204
+ "status": "pending",
205
+ "message": "Target date has not been reached yet",
206
+ "target_date": prediction.target_date
207
+ }
208
+
209
+ # Get actual return (mock for now)
210
+ actual_return = prediction.predicted_return + np.random.randn() * 0.02
211
+
212
+ # Update prediction with actual outcome
213
+ prediction.actual_return = actual_return
214
+ prediction.outcome_date = datetime.utcnow()
215
+ db.commit()
216
+
217
+ return {
218
+ "status": "completed",
219
+ "predicted_return": prediction.predicted_return,
220
+ "actual_return": actual_return,
221
+ "error": abs(prediction.predicted_return - actual_return),
222
+ "accuracy": 1 - abs(prediction.predicted_return - actual_return) / abs(actual_return)
223
+ }
224
+
225
+
226
+ @router.get("/recommendations/latest")
227
+ @cached(expire=300)
228
+ async def get_latest_recommendations(
229
+ limit: int = Query(10, le=50),
230
+ min_confidence: float = Query(0.7, ge=0, le=1),
231
+ current_user: User = Depends(get_current_active_user),
232
+ db: Session = Depends(get_db)
233
+ ):
234
+ """Get latest stock recommendations"""
235
+ # Get recent predictions with high confidence
236
+ predictions = db.query(Prediction).filter(
237
+ Prediction.confidence_score >= min_confidence,
238
+ Prediction.prediction_date >= datetime.utcnow() - timedelta(days=1)
239
+ ).order_by(
240
+ Prediction.confidence_score.desc(),
241
+ Prediction.predicted_return.desc()
242
+ ).limit(limit).all()
243
+
244
+ recommendations = []
245
+ for pred in predictions:
246
+ action = "buy" if pred.predicted_return > 0.02 else "hold"
247
+ if pred.predicted_return < -0.02:
248
+ action = "sell"
249
+
250
+ recommendations.append({
251
+ "ticker": pred.ticker,
252
+ "action": action,
253
+ "predicted_return": pred.predicted_return,
254
+ "confidence": pred.confidence_score,
255
+ "target_date": pred.target_date
256
+ })
257
+
258
+ return recommendations
259
+
260
+
261
+ async def update_stock_data(ticker: str, db: Session):
262
+ """Background task to update stock data"""
263
+ # In real implementation, fetch latest stock data
264
+ stock = db.query(StockData).filter(StockData.ticker == ticker).first()
265
+ if stock:
266
+ stock.last_updated = datetime.utcnow()
267
+ db.commit()
@@ -0,0 +1,12 @@
1
+ """Trading API routes"""
2
+
3
+ from fastapi import APIRouter, Depends
4
+ from mcli.ml.auth import get_current_active_user
5
+ from mcli.ml.database.models import User
6
+
7
+ router = APIRouter()
8
+
9
+ @router.get("/politician/{politician_id}")
10
+ async def get_politician_trades(politician_id: str, current_user: User = Depends(get_current_active_user)):
11
+ """Get politician trades"""
12
+ return {"politician_id": politician_id, "trades": []}
@@ -0,0 +1,76 @@
1
+ """WebSocket API routes for real-time updates"""
2
+
3
+ from fastapi import APIRouter, WebSocket, WebSocketDisconnect, Depends
4
+ from typing import Dict, Set
5
+ import json
6
+ import asyncio
7
+
8
+ from mcli.ml.logging import get_logger
9
+
10
+ router = APIRouter()
11
+ logger = get_logger(__name__)
12
+
13
+
14
+ class ConnectionManager:
15
+ """Manage WebSocket connections"""
16
+
17
+ def __init__(self):
18
+ self.active_connections: Dict[str, Set[WebSocket]] = {}
19
+
20
+ async def connect(self, websocket: WebSocket, channel: str):
21
+ await websocket.accept()
22
+ if channel not in self.active_connections:
23
+ self.active_connections[channel] = set()
24
+ self.active_connections[channel].add(websocket)
25
+
26
+ def disconnect(self, websocket: WebSocket, channel: str):
27
+ if channel in self.active_connections:
28
+ self.active_connections[channel].discard(websocket)
29
+ if not self.active_connections[channel]:
30
+ del self.active_connections[channel]
31
+
32
+ async def broadcast(self, channel: str, message: dict):
33
+ if channel in self.active_connections:
34
+ disconnected = set()
35
+ for connection in self.active_connections[channel]:
36
+ try:
37
+ await connection.send_json(message)
38
+ except:
39
+ disconnected.add(connection)
40
+
41
+ # Remove disconnected clients
42
+ for conn in disconnected:
43
+ self.disconnect(conn, channel)
44
+
45
+
46
+ manager = ConnectionManager()
47
+
48
+
49
+ @router.websocket("/predictions")
50
+ async def websocket_predictions(websocket: WebSocket):
51
+ """Real-time prediction updates"""
52
+ await manager.connect(websocket, "predictions")
53
+ try:
54
+ while True:
55
+ data = await websocket.receive_text()
56
+ # Echo back for now
57
+ await websocket.send_text(f"Echo: {data}")
58
+ except WebSocketDisconnect:
59
+ manager.disconnect(websocket, "predictions")
60
+
61
+
62
+ @router.websocket("/prices")
63
+ async def websocket_prices(websocket: WebSocket):
64
+ """Real-time price updates"""
65
+ await manager.connect(websocket, "prices")
66
+ try:
67
+ while True:
68
+ await asyncio.sleep(1)
69
+ # Send mock price update
70
+ await websocket.send_json({
71
+ "type": "price_update",
72
+ "ticker": "AAPL",
73
+ "price": 150.00 + (asyncio.get_event_loop().time() % 10)
74
+ })
75
+ except WebSocketDisconnect:
76
+ manager.disconnect(websocket, "prices")
mcli/ml/api/schemas.py ADDED
@@ -0,0 +1,64 @@
1
+ """API request/response schemas"""
2
+
3
+ from datetime import datetime
4
+ from typing import Optional, List, Dict, Any
5
+ from uuid import UUID
6
+ from pydantic import BaseModel, Field
7
+
8
+ # Model schemas
9
+ class ModelCreate(BaseModel):
10
+ name: str
11
+ model_type: str
12
+ framework: str = "pytorch"
13
+ description: Optional[str] = None
14
+ hyperparameters: Dict[str, Any] = {}
15
+
16
+ class ModelUpdate(BaseModel):
17
+ name: Optional[str] = None
18
+ description: Optional[str] = None
19
+ tags: Optional[List[str]] = None
20
+
21
+ class ModelResponse(BaseModel):
22
+ id: UUID
23
+ name: str
24
+ version: str
25
+ model_type: str
26
+ status: str
27
+ created_at: datetime
28
+ updated_at: datetime
29
+
30
+ class Config:
31
+ orm_mode = True
32
+
33
+ class ModelMetrics(BaseModel):
34
+ model_id: UUID
35
+ train_accuracy: Optional[float]
36
+ val_accuracy: Optional[float]
37
+ test_accuracy: Optional[float]
38
+ train_loss: Optional[float]
39
+ val_loss: Optional[float]
40
+ test_loss: Optional[float]
41
+ additional_metrics: Dict[str, Any]
42
+
43
+ # Prediction schemas
44
+ class PredictionRequest(BaseModel):
45
+ ticker: str
46
+ features: Dict[str, float]
47
+ model_id: Optional[UUID] = None
48
+
49
+ class BatchPredictionRequest(BaseModel):
50
+ tickers: List[PredictionRequest]
51
+ model_id: Optional[UUID] = None
52
+ horizon: int = 1
53
+
54
+ class PredictionResponse(BaseModel):
55
+ id: UUID
56
+ ticker: str
57
+ predicted_return: float
58
+ confidence_score: float
59
+ target_date: datetime
60
+ model_id: UUID
61
+ model_name: str
62
+
63
+ class Config:
64
+ orm_mode = True