(
blocks: DeepnoteBlock[],
options: { pythonInterpreter?: string } = {}
)
| 72 | * Intentionally mixing Python and SQL blocks here because we want to use just one local process invocation. |
| 73 | */ |
| 74 | export async function getBlockDependencies( |
| 75 | blocks: DeepnoteBlock[], |
| 76 | options: { pythonInterpreter?: string } = {} |
| 77 | ): Promise<BlockContentDepsWithOrder[]> { |
| 78 | const { pythonInterpreter = 'python3' } = options |
| 79 | |
| 80 | const blocksNeedingComputation = blocks |
| 81 | // Process only supported cell types |
| 82 | .filter(block => SUPPORTED_CELL_TYPES.has(block.type)) |
| 83 | // Format blocks for parser |
| 84 | .map(block => ({ |
| 85 | ...block, |
| 86 | content: block.content ?? '', |
| 87 | })) |
| 88 | |
| 89 | // Early return if no blocks need computation |
| 90 | if (blocksNeedingComputation.length === 0) { |
| 91 | return [] |
| 92 | } |
| 93 | |
| 94 | try { |
| 95 | const inputData = JSON.stringify({ blocks: blocksNeedingComputation }) |
| 96 | |
| 97 | const scriptPath = path.join(_dirname, 'scripts', 'ast-analyzer.py') |
| 98 | const outputData = await safelyCallChildProcessWithInputOutput(pythonInterpreter, [scriptPath], inputData) |
| 99 | |
| 100 | const json = JSON.parse(outputData) |
| 101 | const parsed = await AstAnalyzerResponseSchema.safeParseAsync(json) |
| 102 | if (!parsed.success) { |
| 103 | throw new AstAnalyzerInternalError( |
| 104 | `Internal parser error: unexpected output format from AST analyzer, ${parsed.error.message}` |
| 105 | ) |
| 106 | } |
| 107 | |
| 108 | const parsedData = parsed.data |
| 109 | |
| 110 | if (Array.isArray(parsedData)) { |
| 111 | const resultWithOrder = parsedData.map(block => ({ |
| 112 | ...block, |
| 113 | order: blocks.findIndex(b => b.id === block.id), |
| 114 | })) |
| 115 | |
| 116 | return resultWithOrder |
| 117 | } |
| 118 | |
| 119 | if (typeof parsedData === 'object' && parsedData !== null && 'errorMessage' in parsedData) { |
| 120 | const errorMessage = (parsedData as { errorMessage: string }).errorMessage |
| 121 | throw new AstAnalyzerInternalError( |
| 122 | `Could not build a dependency graph for this notebook due to errors in the code: ${errorMessage}` |
| 123 | ) |
| 124 | } |
| 125 | |
| 126 | throw new AstAnalyzerInternalError('Internal parser error: malformed analyzer output.') |
| 127 | } catch (error) { |
| 128 | if (error instanceof AstAnalyzerInternalError) { |
| 129 | throw error |
| 130 | } |
| 131 |
no test coverage detected