Files
Atomizer/atomizer-dashboard/backend/api/routes/nx.py
Anto01 1c7c7aff05 feat(canvas): Add file browser, introspection, and improve node flow
Phase 1-7 of Canvas V4 Ralph Loop implementation:

Backend:
- Add /api/files routes for browsing model files
- Add /api/nx routes for NX model introspection
- Add NXIntrospector service to discover expressions and extractors
- Add health check with database status

Frontend:
- Add FileBrowser component for selecting .sim/.prt/.fem files
- Add IntrospectionPanel to discover expressions and extractors
- Update NodeConfigPanel with browse and introspect buttons
- Update schema with NODE_HANDLES for proper flow direction
- Update validation for correct DesignVar -> Model -> Solver flow
- Update useCanvasStore.addNode() to accept custom data

Flow correction: Design Variables now connect TO Model (as source),
not FROM Model. This matches the actual data flow in optimization.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-16 14:47:10 -05:00

91 lines
2.3 KiB
Python

"""
NX API Routes
Provides NX model introspection capabilities for the Canvas Builder.
"""
from fastapi import APIRouter, HTTPException
from pydantic import BaseModel
from typing import Optional
router = APIRouter()
class IntrospectRequest(BaseModel):
file_path: str
@router.post("/introspect")
async def introspect_model(request: IntrospectRequest):
"""
Introspect an NX model file to discover expressions, solver type, and dependencies.
Args:
file_path: Relative path from studies root (e.g., "M1_Mirror/study_v1/model.sim")
Returns:
Introspection result with expressions, solver_type, dependent_files, extractors
"""
try:
from api.services.nx_introspection import NXIntrospector
introspector = NXIntrospector(request.file_path)
result = introspector.introspect()
return result
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
@router.get("/expressions")
async def get_expressions(file_path: str):
"""
Get expressions from an NX model.
Args:
file_path: Relative path from studies root
Returns:
List of expressions with names, values, units
"""
try:
from api.services.nx_introspection import NXIntrospector
introspector = NXIntrospector(file_path)
result = introspector.introspect()
return {
"expressions": result.get("expressions", []),
"file_path": file_path,
"source": "introspection",
}
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
@router.get("/extractors")
async def list_extractors(solver_type: Optional[str] = None):
"""
List available extractors, optionally filtered by solver type.
Args:
solver_type: Optional solver type (SOL101, SOL103, etc.)
Returns:
List of available extractors with their descriptions
"""
from api.services.nx_introspection import NXIntrospector
# Create a dummy introspector to get extractor suggestions
class DummyIntrospector:
def __init__(self):
self.parent_dir = ""
dummy = NXIntrospector.__new__(NXIntrospector)
dummy.parent_dir = ""
extractors = dummy._suggest_extractors(solver_type)
return {
"extractors": extractors,
"solver_type": solver_type,
}