Repository navigation
Expand file tree
/
Copy pathmain.py
More file actions
188 lines (153 loc) · 7.9 KB
/
Copy pathmain.py
File metadata and controls
188 lines (153 loc) · 7.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
"""NAVIX Central Unified CLI & Server Runner.
Replaces old standalone runner scripts:
- run_server.py
- run_navix.py
- run_collectors.py
- run_collect_and_upload.py
- run_bootstrap_training_data.py
"""
from __future__ import annotations
import argparse
import json
from pathlib import Path
import sys
ROOT = Path(__file__).resolve().parent
SRC = ROOT / "src"
if str(SRC) not in sys.path:
sys.path.insert(0, str(SRC))
from navix.collectors import CollectionService
from navix.data_fabric import DataFabricService
from navix.domain import MaritimeKnowledgePlatform
from navix.feedback import FeedbackLearningService
from navix.intelligence import (
DemandSupplyEngine,
MarketIntelligenceEngine,
PortIntelligenceEngine,
RecommendationEngine,
RiskResilienceEngine,
VoyageEconomicsEngine,
)
from navix.optimization import OptimizationEngine
from navix.server import create_app
from navix.simulation import DigitalTwinSimulationEngine, SimulationScenarioInput
from navix.supabase_uploader import SupabaseUploader
from navix.training import TrainingSeedPipeline
def run_server(host: str = "127.0.0.1", port: int = 8000, debug: bool = False) -> None:
"""Launch the NAVIX Centralized Server and Port Master UI."""
print(f"Starting NAVIX Central Server on http://{host}:{port}...")
app = create_app(ROOT)
app.run(host=host, port=port, debug=debug)
def run_ingest() -> None:
"""Run Data Fabric ingestion across all raw CSV & JSON sources."""
fabric = DataFabricService(ROOT)
curated = fabric.ingest_all()
print("Ingestion complete. Curated asset summary:")
for name, rows in curated.items():
print(f" - {name}: {len(rows)} records")
def run_collect() -> None:
"""Collect public maritime sources into data/collected/latest.json."""
records = CollectionService(ROOT).collect_public_sources()
print(f"Collected {len(records)} records into data/collected/latest.json")
def run_collect_and_upload() -> None:
"""Collect public sources and upload directly to Supabase."""
records = CollectionService(ROOT).collect_public_sources()
uploader = SupabaseUploader.from_environment()
uploader.upsert_source_records(records)
print(f"Collected and uploaded {len(records)} records to Supabase")
def run_bootstrap() -> None:
"""Run historical weather/macro seed bootstrap and generate synthetic training scenarios."""
pipeline = TrainingSeedPipeline(ROOT)
hist = pipeline.bootstrap_public_history()
print(f"Bootstrapped history: {hist}")
uploader = SupabaseUploader.from_environment()
uploader.upsert_source_records(pipeline.real_seed_records())
scenarios = pipeline.generate_scenarios()
print(f"Generated synthetic scenarios: {scenarios}")
readiness = pipeline.training_readiness()
print(f"Training readiness: {readiness}")
def run_pipeline() -> None:
"""Run the complete NAVIX intelligence, simulation, optimization, and feedback loop."""
print("=== NAVIX Architecture Full Pipeline Run ===")
# 1. Data Fabric
fabric = DataFabricService(ROOT)
curated = fabric.ingest_all()
print(f"[01 Data Fabric] Ingested {len(curated)} entity types")
# 2. Maritime Knowledge Platform
platform = MaritimeKnowledgePlatform(ROOT)
print(f"[02 Maritime Knowledge Platform] Loaded canonical domain entities:")
for entity, count in platform.summary().items():
print(f" * {entity}: {count}")
# 3. Intelligence Engines
m_engine = MarketIntelligenceEngine(platform)
forecast = m_engine.forecast("AUSTRALIA", "INDIA_EAST", "PANAMAX")
print(f"[03 Market Intelligence] Freight forecast AU->IN_EAST Panamax: ${forecast.forecast_30d_usd_per_mt}/MT ({forecast.market_signal})")
port_engine = PortIntelligenceEngine(platform)
port_assess = port_engine.assess_port("INPRD")
print(f"[04 Port Intelligence] Paradip (INPRD) congestion index: {port_assess.congestion_index}, waiting days: {port_assess.estimated_waiting_days}d ({port_assess.delay_risk_category})")
ds_engine = DemandSupplyEngine(platform)
signal = ds_engine.analyze_region("AUSTRALIA", "PANAMAX")
print(f"[05 Vessel Supply & Demand] Australia Panamax tightness: {signal.market_tightness} (Ratio: {signal.supply_demand_ratio})")
econ_engine = VoyageEconomicsEngine(platform)
cargo = platform.cargo_list[0]
vessel = platform.vessels[0]
route = platform.routes[0]
est = econ_engine.calculate_voyage(cargo, vessel, route)
print(f"[06 Voyage Economics] Voyage CG001 on V001: total cost ${est.total_voyage_cost_usd:,.2f}, TCE: ${est.net_daily_tce_usd:,.2f}/day")
# 4. Simulation Engine
sim_engine = DigitalTwinSimulationEngine(platform)
sim_res = sim_engine.run_scenario(
SimulationScenarioInput(
scenario_name="+15% Fuel Spike & +2d Congestion Delay",
cargo_id=cargo.cargo_id,
vessel_id=vessel.vessel_id,
route_id=route.route_id,
bunker_price_shift_pct=15.0,
port_delay_days_add=2.0,
)
)
print(f"[07 Digital Twin & Simulation] Scenario '{sim_res.scenario_name}': Cost delta ${sim_res.cost_delta_usd:,.2f} (+{sim_res.cost_delta_pct}%)")
# 5. Optimization Engine
opt_engine = OptimizationEngine(platform)
opt_res = opt_engine.optimize_cargo_assignment(cargo.cargo_id)
opt_vessel_name = opt_res.optimal_candidate.vessel_name if opt_res.optimal_candidate else "None"
print(f"[08 Optimization Engine] Evaluated {opt_res.candidates_evaluated} candidates. Optimal vessel: {opt_vessel_name}")
# 6. Recommendation Engine
rec_engine = RecommendationEngine(platform)
rec = rec_engine.generate_recommendation_for_cargo(cargo.cargo_id)
print(f"[09 Decision & Recommendation Engine] Recommendation for {cargo.cargo_id}: Action={rec.action}, Rate=${rec.recommended_rate_usd_per_mt}/MT")
# 7. Risk Engine
risk_engine = RiskResilienceEngine(platform)
risk = risk_engine.evaluate_voyage_risk(cargo, vessel, route)
print(f"[10 Risk & Resilience Engine] Composite risk score for voyage: {risk.composite_risk_score}/100 ({risk.risk_level})")
# 8. Feedback & Learning
feedback_service = FeedbackLearningService(platform, fabric)
metrics = feedback_service.get_summary_metrics()
print(f"[12 Feedback & Learning] Outcomes logged: {metrics.total_recorded_outcomes}, Mean cost error: {metrics.mean_cost_error_pct}%, Rating: {metrics.model_accuracy_rating}")
print("\n=== Full NAVIX Decision Loop Executed Successfully ===")
def main() -> None:
parser = argparse.ArgumentParser(description="NAVIX Centralized CLI & Server Entry Point")
parser.add_argument("--server", action="store_true", help="Run the central web server & Port Master UI")
parser.add_argument("--host", type=str, default="127.0.0.1", help="Server host IP (default: 127.0.0.1)")
parser.add_argument("--port", type=int, default=8000, help="Server port (default: 8000)")
parser.add_argument("--debug", action="store_true", help="Run server in debug mode")
parser.add_argument("--ingest", action="store_true", help="Run Data Fabric ingestion across raw files")
parser.add_argument("--collect", action="store_true", help="Collect public source snapshots")
parser.add_argument("--collect-upload", action="store_true", help="Collect public sources & upload to Supabase")
parser.add_argument("--bootstrap", action="store_true", help="Bootstrap historical seeds & generate synthetic scenarios")
parser.add_argument("--pipeline", action="store_true", help="Run full end-to-end NAVIX pipeline test")
args = parser.parse_args()
if args.server:
run_server(host=args.host, port=args.port, debug=args.debug)
elif args.ingest:
run_ingest()
elif args.collect:
run_collect()
elif args.collect_upload:
run_collect_and_upload()
elif args.bootstrap:
run_bootstrap()
else:
# Default behavior if no flag passed
run_pipeline()
if __name__ == "__main__":
main()