diff --git a/.vscode/PythonImportHelper-v2-Completion.json b/.vscode/PythonImportHelper-v2-Completion.json new file mode 100644 index 0000000..c95f8d7 --- /dev/null +++ b/.vscode/PythonImportHelper-v2-Completion.json @@ -0,0 +1,17362 @@ +[ + { + "label": "Sequence", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Union", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Sequence", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Union", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Sequence", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Union", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Sequence", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Union", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Sequence", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Union", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Sequence", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Union", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Sequence", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Union", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Sequence", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Union", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Sequence", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Union", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Sequence", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Union", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Sequence", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Union", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Sequence", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Union", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Sequence", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Union", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Sequence", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Union", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Sequence", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Union", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Sequence", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Union", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Sequence", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Union", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Sequence", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Union", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Sequence", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Union", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Sequence", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Union", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Sequence", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Union", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Sequence", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Union", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Sequence", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Union", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Sequence", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Union", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Sequence", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Union", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "List", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Optional", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Dict", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "List", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Optional", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "List", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Dict", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "List", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Any", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Optional", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "List", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "List", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "List", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Literal", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "List", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Optional", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Dict", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Any", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "List", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Any", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Optional", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Any", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Dict", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Optional", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Type", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Optional", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Any", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "List", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "List", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Optional", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Any", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Optional", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Dict", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Any", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Optional", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Optional", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "List", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Optional", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Dict", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Any", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Optional", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Optional", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Optional", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "List", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Optional", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Any", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Optional", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Optional", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Optional", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "List", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Optional", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Dict", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Any", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Callable", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Any", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Dict", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Type", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Any", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Dict", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Dict", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Any", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "List", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Type", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Any", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Dict", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Type", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Dict", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Set", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Optional", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Dict", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Any", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "List", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Dict", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Any", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "List", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Optional", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Tuple", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Any", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Dict", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "List", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Dict", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Any", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Optional", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Protocol", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Any", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Dict", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Union", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "List", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Dict", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Any", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Dict", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Optional", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Type", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "List", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Any", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "List", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Dict", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Any", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Optional", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Dict", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Any", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Dict", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "List", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Any", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Optional", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Literal", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Protocol", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Optional", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Optional", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "List", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Dict", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Any", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "BinaryIO", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Union", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Optional", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Optional", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Dict", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Any", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "List", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Dict", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "List", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Optional", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "List", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Optional", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Dict", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Any", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "List", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Type", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Any", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Dict", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Type", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "List", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Dict", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Any", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "List", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Dict", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Any", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Union", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Optional", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Any", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Dict", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "List", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Optional", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Union", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "List", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Dict", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Any", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Optional", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Union", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "List", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Dict", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Any", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Optional", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Union", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Any", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Dict", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "List", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Optional", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Union", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Any", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "List", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Union", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Dict", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Set", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Optional", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "List", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Union", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "List", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Union", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "List", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Union", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "List", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Union", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "List", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Union", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Any", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "List", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Union", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Dict", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Set", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Optional", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "List", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Union", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Any", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Dict", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "List", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Optional", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Union", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Any", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "List", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Union", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Dict", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Set", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Optional", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "List", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Dict", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Union", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Set", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Any", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Dict", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "List", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Optional", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Union", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "List", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Union", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "List", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Dict", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Any", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "TypeAlias", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Union", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Dict", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Any", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "List", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Union", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Optional", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "List", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Dict", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Any", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Optional", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "List", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Dict", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Any", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Union", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Any", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "List", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Union", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Dict", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Set", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Optional", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "List", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Dict", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Any", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Union", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Dict", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Any", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "List", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Union", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Any", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Dict", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "List", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Optional", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Union", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Dict", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "List", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Any", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Optional", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "List", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Union", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "List", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Union", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "List", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Optional", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Union", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "List", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Union", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "List", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Union", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "List", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Union", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "List", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Dict", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Any", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Union", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Optional", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Dict", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Any", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "List", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Type", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Any", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Dict", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Type", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Any", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Literal", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Any", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "List", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Any", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "List", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "List", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Any", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Dict", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Any", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "List", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Dict", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Dict", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Any", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Dict", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "List", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Dict", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "List", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Literal", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Union", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Any", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Optional", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Optional", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "List", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Optional", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "List", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "List", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Optional", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Optional", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "List", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "List", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Optional", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Dict", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Optional", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "List", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Optional", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "List", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Optional", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "List", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Optional", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "List", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Optional", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "List", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Optional", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Optional", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "List", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Optional", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "List", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Optional", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Literal", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "List", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Optional", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "List", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Dict", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Optional", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Optional", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "List", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Optional", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "List", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Any", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Optional", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "List", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Optional", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Any", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Optional", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "List", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Optional", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "List", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Optional", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "List", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Optional", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "List", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Optional", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Optional", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "List", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Optional", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "List", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Optional", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Literal", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Optional", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "List", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Optional", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "List", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "List", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Optional", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Optional", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "op", + "importPath": "alembic", + "description": "alembic", + "isExtraImport": true, + "detail": "alembic", + "documentation": {} + }, + { + "label": "op", + "importPath": "alembic", + "description": "alembic", + "isExtraImport": true, + "detail": "alembic", + "documentation": {} + }, + { + "label": "op", + "importPath": "alembic", + "description": "alembic", + "isExtraImport": true, + "detail": "alembic", + "documentation": {} + }, + { + "label": "op", + "importPath": "alembic", + "description": "alembic", + "isExtraImport": true, + "detail": "alembic", + "documentation": {} + }, + { + "label": "op", + "importPath": "alembic", + "description": "alembic", + "isExtraImport": true, + "detail": "alembic", + "documentation": {} + }, + { + "label": "op", + "importPath": "alembic", + "description": "alembic", + "isExtraImport": true, + "detail": "alembic", + "documentation": {} + }, + { + "label": "op", + "importPath": "alembic", + "description": "alembic", + "isExtraImport": true, + "detail": "alembic", + "documentation": {} + }, + { + "label": "op", + "importPath": "alembic", + "description": "alembic", + "isExtraImport": true, + "detail": "alembic", + "documentation": {} + }, + { + "label": "op", + "importPath": "alembic", + "description": "alembic", + "isExtraImport": true, + "detail": "alembic", + "documentation": {} + }, + { + "label": "op", + "importPath": "alembic", + "description": "alembic", + "isExtraImport": true, + "detail": "alembic", + "documentation": {} + }, + { + "label": "op", + "importPath": "alembic", + "description": "alembic", + "isExtraImport": true, + "detail": "alembic", + "documentation": {} + }, + { + "label": "op", + "importPath": "alembic", + "description": "alembic", + "isExtraImport": true, + "detail": "alembic", + "documentation": {} + }, + { + "label": "op", + "importPath": "alembic", + "description": "alembic", + "isExtraImport": true, + "detail": "alembic", + "documentation": {} + }, + { + "label": "op", + "importPath": "alembic", + "description": "alembic", + "isExtraImport": true, + "detail": "alembic", + "documentation": {} + }, + { + "label": "op", + "importPath": "alembic", + "description": "alembic", + "isExtraImport": true, + "detail": "alembic", + "documentation": {} + }, + { + "label": "op", + "importPath": "alembic", + "description": "alembic", + "isExtraImport": true, + "detail": "alembic", + "documentation": {} + }, + { + "label": "op", + "importPath": "alembic", + "description": "alembic", + "isExtraImport": true, + "detail": "alembic", + "documentation": {} + }, + { + "label": "op", + "importPath": "alembic", + "description": "alembic", + "isExtraImport": true, + "detail": "alembic", + "documentation": {} + }, + { + "label": "op", + "importPath": "alembic", + "description": "alembic", + "isExtraImport": true, + "detail": "alembic", + "documentation": {} + }, + { + "label": "op", + "importPath": "alembic", + "description": "alembic", + "isExtraImport": true, + "detail": "alembic", + "documentation": {} + }, + { + "label": "op", + "importPath": "alembic", + "description": "alembic", + "isExtraImport": true, + "detail": "alembic", + "documentation": {} + }, + { + "label": "op", + "importPath": "alembic", + "description": "alembic", + "isExtraImport": true, + "detail": "alembic", + "documentation": {} + }, + { + "label": "op", + "importPath": "alembic", + "description": "alembic", + "isExtraImport": true, + "detail": "alembic", + "documentation": {} + }, + { + "label": "op", + "importPath": "alembic", + "description": "alembic", + "isExtraImport": true, + "detail": "alembic", + "documentation": {} + }, + { + "label": "op", + "importPath": "alembic", + "description": "alembic", + "isExtraImport": true, + "detail": "alembic", + "documentation": {} + }, + { + "label": "context", + "importPath": "alembic", + "description": "alembic", + "isExtraImport": true, + "detail": "alembic", + "documentation": {} + }, + { + "label": "sqlalchemy", + "kind": 6, + "isExtraImport": true, + "importPath": "sqlalchemy", + "description": "sqlalchemy", + "detail": "sqlalchemy", + "documentation": {} + }, + { + "label": "engine_from_config", + "importPath": "sqlalchemy", + "description": "sqlalchemy", + "isExtraImport": true, + "detail": "sqlalchemy", + "documentation": {} + }, + { + "label": "pool", + "importPath": "sqlalchemy", + "description": "sqlalchemy", + "isExtraImport": true, + "detail": "sqlalchemy", + "documentation": {} + }, + { + "label": "or_", + "importPath": "sqlalchemy", + "description": "sqlalchemy", + "isExtraImport": true, + "detail": "sqlalchemy", + "documentation": {} + }, + { + "label": "func", + "importPath": "sqlalchemy", + "description": "sqlalchemy", + "isExtraImport": true, + "detail": "sqlalchemy", + "documentation": {} + }, + { + "label": "or_", + "importPath": "sqlalchemy", + "description": "sqlalchemy", + "isExtraImport": true, + "detail": "sqlalchemy", + "documentation": {} + }, + { + "label": "func", + "importPath": "sqlalchemy", + "description": "sqlalchemy", + "isExtraImport": true, + "detail": "sqlalchemy", + "documentation": {} + }, + { + "label": "text", + "importPath": "sqlalchemy", + "description": "sqlalchemy", + "isExtraImport": true, + "detail": "sqlalchemy", + "documentation": {} + }, + { + "label": "String", + "importPath": "sqlalchemy", + "description": "sqlalchemy", + "isExtraImport": true, + "detail": "sqlalchemy", + "documentation": {} + }, + { + "label": "Text", + "importPath": "sqlalchemy", + "description": "sqlalchemy", + "isExtraImport": true, + "detail": "sqlalchemy", + "documentation": {} + }, + { + "label": "DateTime", + "importPath": "sqlalchemy", + "description": "sqlalchemy", + "isExtraImport": true, + "detail": "sqlalchemy", + "documentation": {} + }, + { + "label": "ForeignKey", + "importPath": "sqlalchemy", + "description": "sqlalchemy", + "isExtraImport": true, + "detail": "sqlalchemy", + "documentation": {} + }, + { + "label": "Index", + "importPath": "sqlalchemy", + "description": "sqlalchemy", + "isExtraImport": true, + "detail": "sqlalchemy", + "documentation": {} + }, + { + "label": "func", + "importPath": "sqlalchemy", + "description": "sqlalchemy", + "isExtraImport": true, + "detail": "sqlalchemy", + "documentation": {} + }, + { + "label": "JSON", + "importPath": "sqlalchemy", + "description": "sqlalchemy", + "isExtraImport": true, + "detail": "sqlalchemy", + "documentation": {} + }, + { + "label": "Column", + "importPath": "sqlalchemy", + "description": "sqlalchemy", + "isExtraImport": true, + "detail": "sqlalchemy", + "documentation": {} + }, + { + "label": "Enum", + "importPath": "sqlalchemy", + "description": "sqlalchemy", + "isExtraImport": true, + "detail": "sqlalchemy", + "documentation": {} + }, + { + "label": "LargeBinary", + "importPath": "sqlalchemy", + "description": "sqlalchemy", + "isExtraImport": true, + "detail": "sqlalchemy", + "documentation": {} + }, + { + "label": "UniqueConstraint", + "importPath": "sqlalchemy", + "description": "sqlalchemy", + "isExtraImport": true, + "detail": "sqlalchemy", + "documentation": {} + }, + { + "label": "create_engine", + "importPath": "sqlalchemy", + "description": "sqlalchemy", + "isExtraImport": true, + "detail": "sqlalchemy", + "documentation": {} + }, + { + "label": "text", + "importPath": "sqlalchemy", + "description": "sqlalchemy", + "isExtraImport": true, + "detail": "sqlalchemy", + "documentation": {} + }, + { + "label": "select", + "importPath": "sqlalchemy", + "description": "sqlalchemy", + "isExtraImport": true, + "detail": "sqlalchemy", + "documentation": {} + }, + { + "label": "postgresql", + "importPath": "sqlalchemy.dialects", + "description": "sqlalchemy.dialects", + "isExtraImport": true, + "detail": "sqlalchemy.dialects", + "documentation": {} + }, + { + "label": "postgresql", + "importPath": "sqlalchemy.dialects", + "description": "sqlalchemy.dialects", + "isExtraImport": true, + "detail": "sqlalchemy.dialects", + "documentation": {} + }, + { + "label": "postgresql", + "importPath": "sqlalchemy.dialects", + "description": "sqlalchemy.dialects", + "isExtraImport": true, + "detail": "sqlalchemy.dialects", + "documentation": {} + }, + { + "label": "postgresql", + "importPath": "sqlalchemy.dialects", + "description": "sqlalchemy.dialects", + "isExtraImport": true, + "detail": "sqlalchemy.dialects", + "documentation": {} + }, + { + "label": "postgresql", + "importPath": "sqlalchemy.dialects", + "description": "sqlalchemy.dialects", + "isExtraImport": true, + "detail": "sqlalchemy.dialects", + "documentation": {} + }, + { + "label": "postgresql", + "importPath": "sqlalchemy.dialects", + "description": "sqlalchemy.dialects", + "isExtraImport": true, + "detail": "sqlalchemy.dialects", + "documentation": {} + }, + { + "label": "postgresql", + "importPath": "sqlalchemy.dialects", + "description": "sqlalchemy.dialects", + "isExtraImport": true, + "detail": "sqlalchemy.dialects", + "documentation": {} + }, + { + "label": "postgresql", + "importPath": "sqlalchemy.dialects", + "description": "sqlalchemy.dialects", + "isExtraImport": true, + "detail": "sqlalchemy.dialects", + "documentation": {} + }, + { + "label": "postgresql", + "importPath": "sqlalchemy.dialects", + "description": "sqlalchemy.dialects", + "isExtraImport": true, + "detail": "sqlalchemy.dialects", + "documentation": {} + }, + { + "label": "os", + "kind": 6, + "isExtraImport": true, + "importPath": "os", + "description": "os", + "detail": "os", + "documentation": {} + }, + { + "label": "sys", + "kind": 6, + "isExtraImport": true, + "importPath": "sys", + "description": "sys", + "detail": "sys", + "documentation": {} + }, + { + "label": "fileConfig", + "importPath": "logging.config", + "description": "logging.config", + "isExtraImport": true, + "detail": "logging.config", + "documentation": {} + }, + { + "label": "load_dotenv", + "importPath": "dotenv", + "description": "dotenv", + "isExtraImport": true, + "detail": "dotenv", + "documentation": {} + }, + { + "label": "load_dotenv", + "importPath": "dotenv", + "description": "dotenv", + "isExtraImport": true, + "detail": "dotenv", + "documentation": {} + }, + { + "label": "load_dotenv", + "importPath": "dotenv", + "description": "dotenv", + "isExtraImport": true, + "detail": "dotenv", + "documentation": {} + }, + { + "label": "load_dotenv", + "importPath": "dotenv", + "description": "dotenv", + "isExtraImport": true, + "detail": "dotenv", + "documentation": {} + }, + { + "label": "load_dotenv", + "importPath": "dotenv", + "description": "dotenv", + "isExtraImport": true, + "detail": "dotenv", + "documentation": {} + }, + { + "label": "load_dotenv", + "importPath": "dotenv", + "description": "dotenv", + "isExtraImport": true, + "detail": "dotenv", + "documentation": {} + }, + { + "label": "load_dotenv", + "importPath": "dotenv", + "description": "dotenv", + "isExtraImport": true, + "detail": "dotenv", + "documentation": {} + }, + { + "label": "load_dotenv", + "importPath": "dotenv", + "description": "dotenv", + "isExtraImport": true, + "detail": "dotenv", + "documentation": {} + }, + { + "label": "load_dotenv", + "importPath": "dotenv", + "description": "dotenv", + "isExtraImport": true, + "detail": "dotenv", + "documentation": {} + }, + { + "label": "load_dotenv", + "importPath": "dotenv", + "description": "dotenv", + "isExtraImport": true, + "detail": "dotenv", + "documentation": {} + }, + { + "label": "load_dotenv", + "importPath": "dotenv", + "description": "dotenv", + "isExtraImport": true, + "detail": "dotenv", + "documentation": {} + }, + { + "label": "load_dotenv", + "importPath": "dotenv", + "description": "dotenv", + "isExtraImport": true, + "detail": "dotenv", + "documentation": {} + }, + { + "label": "load_dotenv", + "importPath": "dotenv", + "description": "dotenv", + "isExtraImport": true, + "detail": "dotenv", + "documentation": {} + }, + { + "label": "load_dotenv", + "importPath": "dotenv", + "description": "dotenv", + "isExtraImport": true, + "detail": "dotenv", + "documentation": {} + }, + { + "label": "load_dotenv", + "importPath": "dotenv", + "description": "dotenv", + "isExtraImport": true, + "detail": "dotenv", + "documentation": {} + }, + { + "label": "load_dotenv", + "importPath": "dotenv", + "description": "dotenv", + "isExtraImport": true, + "detail": "dotenv", + "documentation": {} + }, + { + "label": "load_dotenv", + "importPath": "dotenv", + "description": "dotenv", + "isExtraImport": true, + "detail": "dotenv", + "documentation": {} + }, + { + "label": "load_dotenv", + "importPath": "dotenv", + "description": "dotenv", + "isExtraImport": true, + "detail": "dotenv", + "documentation": {} + }, + { + "label": "load_dotenv", + "importPath": "dotenv", + "description": "dotenv", + "isExtraImport": true, + "detail": "dotenv", + "documentation": {} + }, + { + "label": "*", + "importPath": "spectragraph_core.core.models", + "description": "spectragraph_core.core.models", + "isExtraImport": true, + "detail": "spectragraph_core.core.models", + "documentation": {} + }, + { + "label": "Analysis", + "importPath": "spectragraph_core.core.models", + "description": "spectragraph_core.core.models", + "isExtraImport": true, + "detail": "spectragraph_core.core.models", + "documentation": {} + }, + { + "label": "Profile", + "importPath": "spectragraph_core.core.models", + "description": "spectragraph_core.core.models", + "isExtraImport": true, + "detail": "spectragraph_core.core.models", + "documentation": {} + }, + { + "label": "Profile", + "importPath": "spectragraph_core.core.models", + "description": "spectragraph_core.core.models", + "isExtraImport": true, + "detail": "spectragraph_core.core.models", + "documentation": {} + }, + { + "label": "Chat", + "importPath": "spectragraph_core.core.models", + "description": "spectragraph_core.core.models", + "isExtraImport": true, + "detail": "spectragraph_core.core.models", + "documentation": {} + }, + { + "label": "ChatMessage", + "importPath": "spectragraph_core.core.models", + "description": "spectragraph_core.core.models", + "isExtraImport": true, + "detail": "spectragraph_core.core.models", + "documentation": {} + }, + { + "label": "Profile", + "importPath": "spectragraph_core.core.models", + "description": "spectragraph_core.core.models", + "isExtraImport": true, + "detail": "spectragraph_core.core.models", + "documentation": {} + }, + { + "label": "CustomType", + "importPath": "spectragraph_core.core.models", + "description": "spectragraph_core.core.models", + "isExtraImport": true, + "detail": "spectragraph_core.core.models", + "documentation": {} + }, + { + "label": "Profile", + "importPath": "spectragraph_core.core.models", + "description": "spectragraph_core.core.models", + "isExtraImport": true, + "detail": "spectragraph_core.core.models", + "documentation": {} + }, + { + "label": "Log", + "importPath": "spectragraph_core.core.models", + "description": "spectragraph_core.core.models", + "isExtraImport": true, + "detail": "spectragraph_core.core.models", + "documentation": {} + }, + { + "label": "Sketch", + "importPath": "spectragraph_core.core.models", + "description": "spectragraph_core.core.models", + "isExtraImport": true, + "detail": "spectragraph_core.core.models", + "documentation": {} + }, + { + "label": "Profile", + "importPath": "spectragraph_core.core.models", + "description": "spectragraph_core.core.models", + "isExtraImport": true, + "detail": "spectragraph_core.core.models", + "documentation": {} + }, + { + "label": "Sketch", + "importPath": "spectragraph_core.core.models", + "description": "spectragraph_core.core.models", + "isExtraImport": true, + "detail": "spectragraph_core.core.models", + "documentation": {} + }, + { + "label": "Flow", + "importPath": "spectragraph_core.core.models", + "description": "spectragraph_core.core.models", + "isExtraImport": true, + "detail": "spectragraph_core.core.models", + "documentation": {} + }, + { + "label": "Profile", + "importPath": "spectragraph_core.core.models", + "description": "spectragraph_core.core.models", + "isExtraImport": true, + "detail": "spectragraph_core.core.models", + "documentation": {} + }, + { + "label": "CustomType", + "importPath": "spectragraph_core.core.models", + "description": "spectragraph_core.core.models", + "isExtraImport": true, + "detail": "spectragraph_core.core.models", + "documentation": {} + }, + { + "label": "Analysis", + "importPath": "spectragraph_core.core.models", + "description": "spectragraph_core.core.models", + "isExtraImport": true, + "detail": "spectragraph_core.core.models", + "documentation": {} + }, + { + "label": "Investigation", + "importPath": "spectragraph_core.core.models", + "description": "spectragraph_core.core.models", + "isExtraImport": true, + "detail": "spectragraph_core.core.models", + "documentation": {} + }, + { + "label": "InvestigationUserRole", + "importPath": "spectragraph_core.core.models", + "description": "spectragraph_core.core.models", + "isExtraImport": true, + "detail": "spectragraph_core.core.models", + "documentation": {} + }, + { + "label": "Profile", + "importPath": "spectragraph_core.core.models", + "description": "spectragraph_core.core.models", + "isExtraImport": true, + "detail": "spectragraph_core.core.models", + "documentation": {} + }, + { + "label": "Sketch", + "importPath": "spectragraph_core.core.models", + "description": "spectragraph_core.core.models", + "isExtraImport": true, + "detail": "spectragraph_core.core.models", + "documentation": {} + }, + { + "label": "Profile", + "importPath": "spectragraph_core.core.models", + "description": "spectragraph_core.core.models", + "isExtraImport": true, + "detail": "spectragraph_core.core.models", + "documentation": {} + }, + { + "label": "Key", + "importPath": "spectragraph_core.core.models", + "description": "spectragraph_core.core.models", + "isExtraImport": true, + "detail": "spectragraph_core.core.models", + "documentation": {} + }, + { + "label": "Scan", + "importPath": "spectragraph_core.core.models", + "description": "spectragraph_core.core.models", + "isExtraImport": true, + "detail": "spectragraph_core.core.models", + "documentation": {} + }, + { + "label": "Profile", + "importPath": "spectragraph_core.core.models", + "description": "spectragraph_core.core.models", + "isExtraImport": true, + "detail": "spectragraph_core.core.models", + "documentation": {} + }, + { + "label": "Sketch", + "importPath": "spectragraph_core.core.models", + "description": "spectragraph_core.core.models", + "isExtraImport": true, + "detail": "spectragraph_core.core.models", + "documentation": {} + }, + { + "label": "Profile", + "importPath": "spectragraph_core.core.models", + "description": "spectragraph_core.core.models", + "isExtraImport": true, + "detail": "spectragraph_core.core.models", + "documentation": {} + }, + { + "label": "CustomType", + "importPath": "spectragraph_core.core.models", + "description": "spectragraph_core.core.models", + "isExtraImport": true, + "detail": "spectragraph_core.core.models", + "documentation": {} + }, + { + "label": "Profile", + "importPath": "spectragraph_core.core.models", + "description": "spectragraph_core.core.models", + "isExtraImport": true, + "detail": "spectragraph_core.core.models", + "documentation": {} + }, + { + "label": "CustomType", + "importPath": "spectragraph_core.core.models", + "description": "spectragraph_core.core.models", + "isExtraImport": true, + "detail": "spectragraph_core.core.models", + "documentation": {} + }, + { + "label": "Profile", + "importPath": "spectragraph_core.core.models", + "description": "spectragraph_core.core.models", + "isExtraImport": true, + "detail": "spectragraph_core.core.models", + "documentation": {} + }, + { + "label": "Profile", + "importPath": "spectragraph_core.core.models", + "description": "spectragraph_core.core.models", + "isExtraImport": true, + "detail": "spectragraph_core.core.models", + "documentation": {} + }, + { + "label": "Sketch", + "importPath": "spectragraph_core.core.models", + "description": "spectragraph_core.core.models", + "isExtraImport": true, + "detail": "spectragraph_core.core.models", + "documentation": {} + }, + { + "label": "Investigation", + "importPath": "spectragraph_core.core.models", + "description": "spectragraph_core.core.models", + "isExtraImport": true, + "detail": "spectragraph_core.core.models", + "documentation": {} + }, + { + "label": "InvestigationUserRole", + "importPath": "spectragraph_core.core.models", + "description": "spectragraph_core.core.models", + "isExtraImport": true, + "detail": "spectragraph_core.core.models", + "documentation": {} + }, + { + "label": "Key", + "importPath": "spectragraph_core.core.models", + "description": "spectragraph_core.core.models", + "isExtraImport": true, + "detail": "spectragraph_core.core.models", + "documentation": {} + }, + { + "label": "uuid", + "kind": 6, + "isExtraImport": true, + "importPath": "uuid", + "description": "uuid", + "detail": "uuid", + "documentation": {} + }, + { + "label": "UUID", + "importPath": "uuid", + "description": "uuid", + "isExtraImport": true, + "detail": "uuid", + "documentation": {} + }, + { + "label": "uuid4", + "importPath": "uuid", + "description": "uuid", + "isExtraImport": true, + "detail": "uuid", + "documentation": {} + }, + { + "label": "UUID", + "importPath": "uuid", + "description": "uuid", + "isExtraImport": true, + "detail": "uuid", + "documentation": {} + }, + { + "label": "uuid4", + "importPath": "uuid", + "description": "uuid", + "isExtraImport": true, + "detail": "uuid", + "documentation": {} + }, + { + "label": "UUID", + "importPath": "uuid", + "description": "uuid", + "isExtraImport": true, + "detail": "uuid", + "documentation": {} + }, + { + "label": "UUID", + "importPath": "uuid", + "description": "uuid", + "isExtraImport": true, + "detail": "uuid", + "documentation": {} + }, + { + "label": "uuid4", + "importPath": "uuid", + "description": "uuid", + "isExtraImport": true, + "detail": "uuid", + "documentation": {} + }, + { + "label": "UUID", + "importPath": "uuid", + "description": "uuid", + "isExtraImport": true, + "detail": "uuid", + "documentation": {} + }, + { + "label": "uuid4", + "importPath": "uuid", + "description": "uuid", + "isExtraImport": true, + "detail": "uuid", + "documentation": {} + }, + { + "label": "UUID", + "importPath": "uuid", + "description": "uuid", + "isExtraImport": true, + "detail": "uuid", + "documentation": {} + }, + { + "label": "uuid4", + "importPath": "uuid", + "description": "uuid", + "isExtraImport": true, + "detail": "uuid", + "documentation": {} + }, + { + "label": "UUID", + "importPath": "uuid", + "description": "uuid", + "isExtraImport": true, + "detail": "uuid", + "documentation": {} + }, + { + "label": "UUID", + "importPath": "uuid", + "description": "uuid", + "isExtraImport": true, + "detail": "uuid", + "documentation": {} + }, + { + "label": "uuid4", + "importPath": "uuid", + "description": "uuid", + "isExtraImport": true, + "detail": "uuid", + "documentation": {} + }, + { + "label": "UUID", + "importPath": "uuid", + "description": "uuid", + "isExtraImport": true, + "detail": "uuid", + "documentation": {} + }, + { + "label": "UUID", + "importPath": "uuid", + "description": "uuid", + "isExtraImport": true, + "detail": "uuid", + "documentation": {} + }, + { + "label": "UUID", + "importPath": "uuid", + "description": "uuid", + "isExtraImport": true, + "detail": "uuid", + "documentation": {} + }, + { + "label": "UUID", + "importPath": "uuid", + "description": "uuid", + "isExtraImport": true, + "detail": "uuid", + "documentation": {} + }, + { + "label": "UUID", + "importPath": "uuid", + "description": "uuid", + "isExtraImport": true, + "detail": "uuid", + "documentation": {} + }, + { + "label": "UUID", + "importPath": "uuid", + "description": "uuid", + "isExtraImport": true, + "detail": "uuid", + "documentation": {} + }, + { + "label": "check_investigation_permission", + "importPath": "app.security.permissions", + "description": "app.security.permissions", + "isExtraImport": true, + "detail": "app.security.permissions", + "documentation": {} + }, + { + "label": "check_investigation_permission", + "importPath": "app.security.permissions", + "description": "app.security.permissions", + "isExtraImport": true, + "detail": "app.security.permissions", + "documentation": {} + }, + { + "label": "check_investigation_permission", + "importPath": "app.security.permissions", + "description": "app.security.permissions", + "isExtraImport": true, + "detail": "app.security.permissions", + "documentation": {} + }, + { + "label": "APIRouter", + "importPath": "fastapi", + "description": "fastapi", + "isExtraImport": true, + "detail": "fastapi", + "documentation": {} + }, + { + "label": "HTTPException", + "importPath": "fastapi", + "description": "fastapi", + "isExtraImport": true, + "detail": "fastapi", + "documentation": {} + }, + { + "label": "Depends", + "importPath": "fastapi", + "description": "fastapi", + "isExtraImport": true, + "detail": "fastapi", + "documentation": {} + }, + { + "label": "status", + "importPath": "fastapi", + "description": "fastapi", + "isExtraImport": true, + "detail": "fastapi", + "documentation": {} + }, + { + "label": "APIRouter", + "importPath": "fastapi", + "description": "fastapi", + "isExtraImport": true, + "detail": "fastapi", + "documentation": {} + }, + { + "label": "Depends", + "importPath": "fastapi", + "description": "fastapi", + "isExtraImport": true, + "detail": "fastapi", + "documentation": {} + }, + { + "label": "HTTPException", + "importPath": "fastapi", + "description": "fastapi", + "isExtraImport": true, + "detail": "fastapi", + "documentation": {} + }, + { + "label": "APIRouter", + "importPath": "fastapi", + "description": "fastapi", + "isExtraImport": true, + "detail": "fastapi", + "documentation": {} + }, + { + "label": "HTTPException", + "importPath": "fastapi", + "description": "fastapi", + "isExtraImport": true, + "detail": "fastapi", + "documentation": {} + }, + { + "label": "APIRouter", + "importPath": "fastapi", + "description": "fastapi", + "isExtraImport": true, + "detail": "fastapi", + "documentation": {} + }, + { + "label": "HTTPException", + "importPath": "fastapi", + "description": "fastapi", + "isExtraImport": true, + "detail": "fastapi", + "documentation": {} + }, + { + "label": "Depends", + "importPath": "fastapi", + "description": "fastapi", + "isExtraImport": true, + "detail": "fastapi", + "documentation": {} + }, + { + "label": "status", + "importPath": "fastapi", + "description": "fastapi", + "isExtraImport": true, + "detail": "fastapi", + "documentation": {} + }, + { + "label": "APIRouter", + "importPath": "fastapi", + "description": "fastapi", + "isExtraImport": true, + "detail": "fastapi", + "documentation": {} + }, + { + "label": "HTTPException", + "importPath": "fastapi", + "description": "fastapi", + "isExtraImport": true, + "detail": "fastapi", + "documentation": {} + }, + { + "label": "Depends", + "importPath": "fastapi", + "description": "fastapi", + "isExtraImport": true, + "detail": "fastapi", + "documentation": {} + }, + { + "label": "status", + "importPath": "fastapi", + "description": "fastapi", + "isExtraImport": true, + "detail": "fastapi", + "documentation": {} + }, + { + "label": "APIRouter", + "importPath": "fastapi", + "description": "fastapi", + "isExtraImport": true, + "detail": "fastapi", + "documentation": {} + }, + { + "label": "Depends", + "importPath": "fastapi", + "description": "fastapi", + "isExtraImport": true, + "detail": "fastapi", + "documentation": {} + }, + { + "label": "HTTPException", + "importPath": "fastapi", + "description": "fastapi", + "isExtraImport": true, + "detail": "fastapi", + "documentation": {} + }, + { + "label": "Request", + "importPath": "fastapi", + "description": "fastapi", + "isExtraImport": true, + "detail": "fastapi", + "documentation": {} + }, + { + "label": "APIRouter", + "importPath": "fastapi", + "description": "fastapi", + "isExtraImport": true, + "detail": "fastapi", + "documentation": {} + }, + { + "label": "HTTPException", + "importPath": "fastapi", + "description": "fastapi", + "isExtraImport": true, + "detail": "fastapi", + "documentation": {} + }, + { + "label": "Depends", + "importPath": "fastapi", + "description": "fastapi", + "isExtraImport": true, + "detail": "fastapi", + "documentation": {} + }, + { + "label": "status", + "importPath": "fastapi", + "description": "fastapi", + "isExtraImport": true, + "detail": "fastapi", + "documentation": {} + }, + { + "label": "Query", + "importPath": "fastapi", + "description": "fastapi", + "isExtraImport": true, + "detail": "fastapi", + "documentation": {} + }, + { + "label": "APIRouter", + "importPath": "fastapi", + "description": "fastapi", + "isExtraImport": true, + "detail": "fastapi", + "documentation": {} + }, + { + "label": "HTTPException", + "importPath": "fastapi", + "description": "fastapi", + "isExtraImport": true, + "detail": "fastapi", + "documentation": {} + }, + { + "label": "Depends", + "importPath": "fastapi", + "description": "fastapi", + "isExtraImport": true, + "detail": "fastapi", + "documentation": {} + }, + { + "label": "status", + "importPath": "fastapi", + "description": "fastapi", + "isExtraImport": true, + "detail": "fastapi", + "documentation": {} + }, + { + "label": "APIRouter", + "importPath": "fastapi", + "description": "fastapi", + "isExtraImport": true, + "detail": "fastapi", + "documentation": {} + }, + { + "label": "HTTPException", + "importPath": "fastapi", + "description": "fastapi", + "isExtraImport": true, + "detail": "fastapi", + "documentation": {} + }, + { + "label": "Depends", + "importPath": "fastapi", + "description": "fastapi", + "isExtraImport": true, + "detail": "fastapi", + "documentation": {} + }, + { + "label": "status", + "importPath": "fastapi", + "description": "fastapi", + "isExtraImport": true, + "detail": "fastapi", + "documentation": {} + }, + { + "label": "APIRouter", + "importPath": "fastapi", + "description": "fastapi", + "isExtraImport": true, + "detail": "fastapi", + "documentation": {} + }, + { + "label": "HTTPException", + "importPath": "fastapi", + "description": "fastapi", + "isExtraImport": true, + "detail": "fastapi", + "documentation": {} + }, + { + "label": "Depends", + "importPath": "fastapi", + "description": "fastapi", + "isExtraImport": true, + "detail": "fastapi", + "documentation": {} + }, + { + "label": "status", + "importPath": "fastapi", + "description": "fastapi", + "isExtraImport": true, + "detail": "fastapi", + "documentation": {} + }, + { + "label": "APIRouter", + "importPath": "fastapi", + "description": "fastapi", + "isExtraImport": true, + "detail": "fastapi", + "documentation": {} + }, + { + "label": "HTTPException", + "importPath": "fastapi", + "description": "fastapi", + "isExtraImport": true, + "detail": "fastapi", + "documentation": {} + }, + { + "label": "Depends", + "importPath": "fastapi", + "description": "fastapi", + "isExtraImport": true, + "detail": "fastapi", + "documentation": {} + }, + { + "label": "status", + "importPath": "fastapi", + "description": "fastapi", + "isExtraImport": true, + "detail": "fastapi", + "documentation": {} + }, + { + "label": "UploadFile", + "importPath": "fastapi", + "description": "fastapi", + "isExtraImport": true, + "detail": "fastapi", + "documentation": {} + }, + { + "label": "File", + "importPath": "fastapi", + "description": "fastapi", + "isExtraImport": true, + "detail": "fastapi", + "documentation": {} + }, + { + "label": "Form", + "importPath": "fastapi", + "description": "fastapi", + "isExtraImport": true, + "detail": "fastapi", + "documentation": {} + }, + { + "label": "BackgroundTasks", + "importPath": "fastapi", + "description": "fastapi", + "isExtraImport": true, + "detail": "fastapi", + "documentation": {} + }, + { + "label": "APIRouter", + "importPath": "fastapi", + "description": "fastapi", + "isExtraImport": true, + "detail": "fastapi", + "documentation": {} + }, + { + "label": "HTTPException", + "importPath": "fastapi", + "description": "fastapi", + "isExtraImport": true, + "detail": "fastapi", + "documentation": {} + }, + { + "label": "Depends", + "importPath": "fastapi", + "description": "fastapi", + "isExtraImport": true, + "detail": "fastapi", + "documentation": {} + }, + { + "label": "Query", + "importPath": "fastapi", + "description": "fastapi", + "isExtraImport": true, + "detail": "fastapi", + "documentation": {} + }, + { + "label": "APIRouter", + "importPath": "fastapi", + "description": "fastapi", + "isExtraImport": true, + "detail": "fastapi", + "documentation": {} + }, + { + "label": "Depends", + "importPath": "fastapi", + "description": "fastapi", + "isExtraImport": true, + "detail": "fastapi", + "documentation": {} + }, + { + "label": "Depends", + "importPath": "fastapi", + "description": "fastapi", + "isExtraImport": true, + "detail": "fastapi", + "documentation": {} + }, + { + "label": "HTTPException", + "importPath": "fastapi", + "description": "fastapi", + "isExtraImport": true, + "detail": "fastapi", + "documentation": {} + }, + { + "label": "status", + "importPath": "fastapi", + "description": "fastapi", + "isExtraImport": true, + "detail": "fastapi", + "documentation": {} + }, + { + "label": "BackgroundTasks", + "importPath": "fastapi", + "description": "fastapi", + "isExtraImport": true, + "detail": "fastapi", + "documentation": {} + }, + { + "label": "HTTPException", + "importPath": "fastapi", + "description": "fastapi", + "isExtraImport": true, + "detail": "fastapi", + "documentation": {} + }, + { + "label": "HTTPException", + "importPath": "fastapi", + "description": "fastapi", + "isExtraImport": true, + "detail": "fastapi", + "documentation": {} + }, + { + "label": "HTTPException", + "importPath": "fastapi", + "description": "fastapi", + "isExtraImport": true, + "detail": "fastapi", + "documentation": {} + }, + { + "label": "Request", + "importPath": "fastapi", + "description": "fastapi", + "isExtraImport": true, + "detail": "fastapi", + "documentation": {} + }, + { + "label": "status", + "importPath": "fastapi", + "description": "fastapi", + "isExtraImport": true, + "detail": "fastapi", + "documentation": {} + }, + { + "label": "FastAPI", + "importPath": "fastapi", + "description": "fastapi", + "isExtraImport": true, + "detail": "fastapi", + "documentation": {} + }, + { + "label": "FastAPI", + "importPath": "fastapi", + "description": "fastapi", + "isExtraImport": true, + "detail": "fastapi", + "documentation": {} + }, + { + "label": "datetime", + "importPath": "datetime", + "description": "datetime", + "isExtraImport": true, + "detail": "datetime", + "documentation": {} + }, + { + "label": "datetime", + "importPath": "datetime", + "description": "datetime", + "isExtraImport": true, + "detail": "datetime", + "documentation": {} + }, + { + "label": "datetime", + "importPath": "datetime", + "description": "datetime", + "isExtraImport": true, + "detail": "datetime", + "documentation": {} + }, + { + "label": "timedelta", + "importPath": "datetime", + "description": "datetime", + "isExtraImport": true, + "detail": "datetime", + "documentation": {} + }, + { + "label": "datetime", + "importPath": "datetime", + "description": "datetime", + "isExtraImport": true, + "detail": "datetime", + "documentation": {} + }, + { + "label": "datetime", + "importPath": "datetime", + "description": "datetime", + "isExtraImport": true, + "detail": "datetime", + "documentation": {} + }, + { + "label": "datetime", + "importPath": "datetime", + "description": "datetime", + "isExtraImport": true, + "detail": "datetime", + "documentation": {} + }, + { + "label": "timezone", + "importPath": "datetime", + "description": "datetime", + "isExtraImport": true, + "detail": "datetime", + "documentation": {} + }, + { + "label": "datetime", + "importPath": "datetime", + "description": "datetime", + "isExtraImport": true, + "detail": "datetime", + "documentation": {} + }, + { + "label": "datetime", + "importPath": "datetime", + "description": "datetime", + "isExtraImport": true, + "detail": "datetime", + "documentation": {} + }, + { + "label": "datetime", + "importPath": "datetime", + "description": "datetime", + "isExtraImport": true, + "detail": "datetime", + "documentation": {} + }, + { + "label": "datetime", + "importPath": "datetime", + "description": "datetime", + "isExtraImport": true, + "detail": "datetime", + "documentation": {} + }, + { + "label": "datetime", + "importPath": "datetime", + "description": "datetime", + "isExtraImport": true, + "detail": "datetime", + "documentation": {} + }, + { + "label": "datetime", + "importPath": "datetime", + "description": "datetime", + "isExtraImport": true, + "detail": "datetime", + "documentation": {} + }, + { + "label": "datetime", + "importPath": "datetime", + "description": "datetime", + "isExtraImport": true, + "detail": "datetime", + "documentation": {} + }, + { + "label": "datetime", + "importPath": "datetime", + "description": "datetime", + "isExtraImport": true, + "detail": "datetime", + "documentation": {} + }, + { + "label": "datetime", + "importPath": "datetime", + "description": "datetime", + "isExtraImport": true, + "detail": "datetime", + "documentation": {} + }, + { + "label": "datetime", + "importPath": "datetime", + "description": "datetime", + "isExtraImport": true, + "detail": "datetime", + "documentation": {} + }, + { + "label": "datetime", + "importPath": "datetime", + "description": "datetime", + "isExtraImport": true, + "detail": "datetime", + "documentation": {} + }, + { + "label": "timedelta", + "importPath": "datetime", + "description": "datetime", + "isExtraImport": true, + "detail": "datetime", + "documentation": {} + }, + { + "label": "datetime", + "importPath": "datetime", + "description": "datetime", + "isExtraImport": true, + "detail": "datetime", + "documentation": {} + }, + { + "label": "timezone", + "importPath": "datetime", + "description": "datetime", + "isExtraImport": true, + "detail": "datetime", + "documentation": {} + }, + { + "label": "datetime", + "importPath": "datetime", + "description": "datetime", + "isExtraImport": true, + "detail": "datetime", + "documentation": {} + }, + { + "label": "datetime", + "importPath": "datetime", + "description": "datetime", + "isExtraImport": true, + "detail": "datetime", + "documentation": {} + }, + { + "label": "datetime", + "importPath": "datetime", + "description": "datetime", + "isExtraImport": true, + "detail": "datetime", + "documentation": {} + }, + { + "label": "datetime", + "importPath": "datetime", + "description": "datetime", + "isExtraImport": true, + "detail": "datetime", + "documentation": {} + }, + { + "label": "datetime", + "importPath": "datetime", + "description": "datetime", + "isExtraImport": true, + "detail": "datetime", + "documentation": {} + }, + { + "label": "timedelta", + "importPath": "datetime", + "description": "datetime", + "isExtraImport": true, + "detail": "datetime", + "documentation": {} + }, + { + "label": "datetime", + "importPath": "datetime", + "description": "datetime", + "isExtraImport": true, + "detail": "datetime", + "documentation": {} + }, + { + "label": "datetime", + "importPath": "datetime", + "description": "datetime", + "isExtraImport": true, + "detail": "datetime", + "documentation": {} + }, + { + "label": "datetime", + "importPath": "datetime", + "description": "datetime", + "isExtraImport": true, + "detail": "datetime", + "documentation": {} + }, + { + "label": "datetime", + "importPath": "datetime", + "description": "datetime", + "isExtraImport": true, + "detail": "datetime", + "documentation": {} + }, + { + "label": "Session", + "importPath": "sqlalchemy.orm", + "description": "sqlalchemy.orm", + "isExtraImport": true, + "detail": "sqlalchemy.orm", + "documentation": {} + }, + { + "label": "Session", + "importPath": "sqlalchemy.orm", + "description": "sqlalchemy.orm", + "isExtraImport": true, + "detail": "sqlalchemy.orm", + "documentation": {} + }, + { + "label": "Session", + "importPath": "sqlalchemy.orm", + "description": "sqlalchemy.orm", + "isExtraImport": true, + "detail": "sqlalchemy.orm", + "documentation": {} + }, + { + "label": "Session", + "importPath": "sqlalchemy.orm", + "description": "sqlalchemy.orm", + "isExtraImport": true, + "detail": "sqlalchemy.orm", + "documentation": {} + }, + { + "label": "Session", + "importPath": "sqlalchemy.orm", + "description": "sqlalchemy.orm", + "isExtraImport": true, + "detail": "sqlalchemy.orm", + "documentation": {} + }, + { + "label": "Session", + "importPath": "sqlalchemy.orm", + "description": "sqlalchemy.orm", + "isExtraImport": true, + "detail": "sqlalchemy.orm", + "documentation": {} + }, + { + "label": "Session", + "importPath": "sqlalchemy.orm", + "description": "sqlalchemy.orm", + "isExtraImport": true, + "detail": "sqlalchemy.orm", + "documentation": {} + }, + { + "label": "selectinload", + "importPath": "sqlalchemy.orm", + "description": "sqlalchemy.orm", + "isExtraImport": true, + "detail": "sqlalchemy.orm", + "documentation": {} + }, + { + "label": "Session", + "importPath": "sqlalchemy.orm", + "description": "sqlalchemy.orm", + "isExtraImport": true, + "detail": "sqlalchemy.orm", + "documentation": {} + }, + { + "label": "Session", + "importPath": "sqlalchemy.orm", + "description": "sqlalchemy.orm", + "isExtraImport": true, + "detail": "sqlalchemy.orm", + "documentation": {} + }, + { + "label": "Session", + "importPath": "sqlalchemy.orm", + "description": "sqlalchemy.orm", + "isExtraImport": true, + "detail": "sqlalchemy.orm", + "documentation": {} + }, + { + "label": "Session", + "importPath": "sqlalchemy.orm", + "description": "sqlalchemy.orm", + "isExtraImport": true, + "detail": "sqlalchemy.orm", + "documentation": {} + }, + { + "label": "Session", + "importPath": "sqlalchemy.orm", + "description": "sqlalchemy.orm", + "isExtraImport": true, + "detail": "sqlalchemy.orm", + "documentation": {} + }, + { + "label": "Session", + "importPath": "sqlalchemy.orm", + "description": "sqlalchemy.orm", + "isExtraImport": true, + "detail": "sqlalchemy.orm", + "documentation": {} + }, + { + "label": "Session", + "importPath": "sqlalchemy.orm", + "description": "sqlalchemy.orm", + "isExtraImport": true, + "detail": "sqlalchemy.orm", + "documentation": {} + }, + { + "label": "DeclarativeBase", + "importPath": "sqlalchemy.orm", + "description": "sqlalchemy.orm", + "isExtraImport": true, + "detail": "sqlalchemy.orm", + "documentation": {} + }, + { + "label": "Mapped", + "importPath": "sqlalchemy.orm", + "description": "sqlalchemy.orm", + "isExtraImport": true, + "detail": "sqlalchemy.orm", + "documentation": {} + }, + { + "label": "mapped_column", + "importPath": "sqlalchemy.orm", + "description": "sqlalchemy.orm", + "isExtraImport": true, + "detail": "sqlalchemy.orm", + "documentation": {} + }, + { + "label": "relationship", + "importPath": "sqlalchemy.orm", + "description": "sqlalchemy.orm", + "isExtraImport": true, + "detail": "sqlalchemy.orm", + "documentation": {} + }, + { + "label": "sessionmaker", + "importPath": "sqlalchemy.orm", + "description": "sqlalchemy.orm", + "isExtraImport": true, + "detail": "sqlalchemy.orm", + "documentation": {} + }, + { + "label": "declarative_base", + "importPath": "sqlalchemy.orm", + "description": "sqlalchemy.orm", + "isExtraImport": true, + "detail": "sqlalchemy.orm", + "documentation": {} + }, + { + "label": "Session", + "importPath": "sqlalchemy.orm", + "description": "sqlalchemy.orm", + "isExtraImport": true, + "detail": "sqlalchemy.orm", + "documentation": {} + }, + { + "label": "Session", + "importPath": "sqlalchemy.orm", + "description": "sqlalchemy.orm", + "isExtraImport": true, + "detail": "sqlalchemy.orm", + "documentation": {} + }, + { + "label": "Session", + "importPath": "sqlalchemy.orm", + "description": "sqlalchemy.orm", + "isExtraImport": true, + "detail": "sqlalchemy.orm", + "documentation": {} + }, + { + "label": "Session", + "importPath": "sqlalchemy.orm", + "description": "sqlalchemy.orm", + "isExtraImport": true, + "detail": "sqlalchemy.orm", + "documentation": {} + }, + { + "label": "get_db", + "importPath": "spectragraph_core.core.postgre_db", + "description": "spectragraph_core.core.postgre_db", + "isExtraImport": true, + "detail": "spectragraph_core.core.postgre_db", + "documentation": {} + }, + { + "label": "get_db", + "importPath": "spectragraph_core.core.postgre_db", + "description": "spectragraph_core.core.postgre_db", + "isExtraImport": true, + "detail": "spectragraph_core.core.postgre_db", + "documentation": {} + }, + { + "label": "get_db", + "importPath": "spectragraph_core.core.postgre_db", + "description": "spectragraph_core.core.postgre_db", + "isExtraImport": true, + "detail": "spectragraph_core.core.postgre_db", + "documentation": {} + }, + { + "label": "get_db", + "importPath": "spectragraph_core.core.postgre_db", + "description": "spectragraph_core.core.postgre_db", + "isExtraImport": true, + "detail": "spectragraph_core.core.postgre_db", + "documentation": {} + }, + { + "label": "get_db", + "importPath": "spectragraph_core.core.postgre_db", + "description": "spectragraph_core.core.postgre_db", + "isExtraImport": true, + "detail": "spectragraph_core.core.postgre_db", + "documentation": {} + }, + { + "label": "get_db", + "importPath": "spectragraph_core.core.postgre_db", + "description": "spectragraph_core.core.postgre_db", + "isExtraImport": true, + "detail": "spectragraph_core.core.postgre_db", + "documentation": {} + }, + { + "label": "get_db", + "importPath": "spectragraph_core.core.postgre_db", + "description": "spectragraph_core.core.postgre_db", + "isExtraImport": true, + "detail": "spectragraph_core.core.postgre_db", + "documentation": {} + }, + { + "label": "get_db", + "importPath": "spectragraph_core.core.postgre_db", + "description": "spectragraph_core.core.postgre_db", + "isExtraImport": true, + "detail": "spectragraph_core.core.postgre_db", + "documentation": {} + }, + { + "label": "get_db", + "importPath": "spectragraph_core.core.postgre_db", + "description": "spectragraph_core.core.postgre_db", + "isExtraImport": true, + "detail": "spectragraph_core.core.postgre_db", + "documentation": {} + }, + { + "label": "get_db", + "importPath": "spectragraph_core.core.postgre_db", + "description": "spectragraph_core.core.postgre_db", + "isExtraImport": true, + "detail": "spectragraph_core.core.postgre_db", + "documentation": {} + }, + { + "label": "get_db", + "importPath": "spectragraph_core.core.postgre_db", + "description": "spectragraph_core.core.postgre_db", + "isExtraImport": true, + "detail": "spectragraph_core.core.postgre_db", + "documentation": {} + }, + { + "label": "get_db", + "importPath": "spectragraph_core.core.postgre_db", + "description": "spectragraph_core.core.postgre_db", + "isExtraImport": true, + "detail": "spectragraph_core.core.postgre_db", + "documentation": {} + }, + { + "label": "get_db", + "importPath": "spectragraph_core.core.postgre_db", + "description": "spectragraph_core.core.postgre_db", + "isExtraImport": true, + "detail": "spectragraph_core.core.postgre_db", + "documentation": {} + }, + { + "label": "ensure_db_connection", + "importPath": "spectragraph_core.core.postgre_db", + "description": "spectragraph_core.core.postgre_db", + "isExtraImport": true, + "detail": "spectragraph_core.core.postgre_db", + "documentation": {} + }, + { + "label": "engine", + "importPath": "spectragraph_core.core.postgre_db", + "description": "spectragraph_core.core.postgre_db", + "isExtraImport": true, + "detail": "spectragraph_core.core.postgre_db", + "documentation": {} + }, + { + "label": "DatabaseUnavailableError", + "importPath": "spectragraph_core.core.postgre_db", + "description": "spectragraph_core.core.postgre_db", + "isExtraImport": true, + "detail": "spectragraph_core.core.postgre_db", + "documentation": {} + }, + { + "label": "ensure_db_connection", + "importPath": "spectragraph_core.core.postgre_db", + "description": "spectragraph_core.core.postgre_db", + "isExtraImport": true, + "detail": "spectragraph_core.core.postgre_db", + "documentation": {} + }, + { + "label": "DatabaseUnavailableError", + "importPath": "spectragraph_core.core.postgre_db", + "description": "spectragraph_core.core.postgre_db", + "isExtraImport": true, + "detail": "spectragraph_core.core.postgre_db", + "documentation": {} + }, + { + "label": "get_current_user", + "importPath": "app.api.deps", + "description": "app.api.deps", + "isExtraImport": true, + "detail": "app.api.deps", + "documentation": {} + }, + { + "label": "get_current_user", + "importPath": "app.api.deps", + "description": "app.api.deps", + "isExtraImport": true, + "detail": "app.api.deps", + "documentation": {} + }, + { + "label": "get_current_user", + "importPath": "app.api.deps", + "description": "app.api.deps", + "isExtraImport": true, + "detail": "app.api.deps", + "documentation": {} + }, + { + "label": "get_current_user", + "importPath": "app.api.deps", + "description": "app.api.deps", + "isExtraImport": true, + "detail": "app.api.deps", + "documentation": {} + }, + { + "label": "get_current_user", + "importPath": "app.api.deps", + "description": "app.api.deps", + "isExtraImport": true, + "detail": "app.api.deps", + "documentation": {} + }, + { + "label": "get_current_user", + "importPath": "app.api.deps", + "description": "app.api.deps", + "isExtraImport": true, + "detail": "app.api.deps", + "documentation": {} + }, + { + "label": "get_current_user", + "importPath": "app.api.deps", + "description": "app.api.deps", + "isExtraImport": true, + "detail": "app.api.deps", + "documentation": {} + }, + { + "label": "get_current_user", + "importPath": "app.api.deps", + "description": "app.api.deps", + "isExtraImport": true, + "detail": "app.api.deps", + "documentation": {} + }, + { + "label": "get_current_user", + "importPath": "app.api.deps", + "description": "app.api.deps", + "isExtraImport": true, + "detail": "app.api.deps", + "documentation": {} + }, + { + "label": "get_current_user", + "importPath": "app.api.deps", + "description": "app.api.deps", + "isExtraImport": true, + "detail": "app.api.deps", + "documentation": {} + }, + { + "label": "get_current_user", + "importPath": "app.api.deps", + "description": "app.api.deps", + "isExtraImport": true, + "detail": "app.api.deps", + "documentation": {} + }, + { + "label": "AnalysisRead", + "importPath": "app.api.schemas.analysis", + "description": "app.api.schemas.analysis", + "isExtraImport": true, + "detail": "app.api.schemas.analysis", + "documentation": {} + }, + { + "label": "AnalysisCreate", + "importPath": "app.api.schemas.analysis", + "description": "app.api.schemas.analysis", + "isExtraImport": true, + "detail": "app.api.schemas.analysis", + "documentation": {} + }, + { + "label": "AnalysisUpdate", + "importPath": "app.api.schemas.analysis", + "description": "app.api.schemas.analysis", + "isExtraImport": true, + "detail": "app.api.schemas.analysis", + "documentation": {} + }, + { + "label": "AnalysisListResponse", + "importPath": "app.api.schemas.analysis", + "description": "app.api.schemas.analysis", + "isExtraImport": true, + "detail": "app.api.schemas.analysis", + "documentation": {} + }, + { + "label": "PaginationMetadata", + "importPath": "app.api.schemas.analysis", + "description": "app.api.schemas.analysis", + "isExtraImport": true, + "detail": "app.api.schemas.analysis", + "documentation": {} + }, + { + "label": "OAuth2PasswordRequestForm", + "importPath": "fastapi.security", + "description": "fastapi.security", + "isExtraImport": true, + "detail": "fastapi.security", + "documentation": {} + }, + { + "label": "OAuth2PasswordBearer", + "importPath": "fastapi.security", + "description": "fastapi.security", + "isExtraImport": true, + "detail": "fastapi.security", + "documentation": {} + }, + { + "label": "SQLAlchemyError", + "importPath": "sqlalchemy.exc", + "description": "sqlalchemy.exc", + "isExtraImport": true, + "detail": "sqlalchemy.exc", + "documentation": {} + }, + { + "label": "IntegrityError", + "importPath": "sqlalchemy.exc", + "description": "sqlalchemy.exc", + "isExtraImport": true, + "detail": "sqlalchemy.exc", + "documentation": {} + }, + { + "label": "OperationalError", + "importPath": "sqlalchemy.exc", + "description": "sqlalchemy.exc", + "isExtraImport": true, + "detail": "sqlalchemy.exc", + "documentation": {} + }, + { + "label": "OperationalError", + "importPath": "sqlalchemy.exc", + "description": "sqlalchemy.exc", + "isExtraImport": true, + "detail": "sqlalchemy.exc", + "documentation": {} + }, + { + "label": "verify_password", + "importPath": "spectragraph_core.core.auth", + "description": "spectragraph_core.core.auth", + "isExtraImport": true, + "detail": "spectragraph_core.core.auth", + "documentation": {} + }, + { + "label": "create_access_token", + "importPath": "spectragraph_core.core.auth", + "description": "spectragraph_core.core.auth", + "isExtraImport": true, + "detail": "spectragraph_core.core.auth", + "documentation": {} + }, + { + "label": "get_password_hash", + "importPath": "spectragraph_core.core.auth", + "description": "spectragraph_core.core.auth", + "isExtraImport": true, + "detail": "spectragraph_core.core.auth", + "documentation": {} + }, + { + "label": "ALGORITHM", + "importPath": "spectragraph_core.core.auth", + "description": "spectragraph_core.core.auth", + "isExtraImport": true, + "detail": "spectragraph_core.core.auth", + "documentation": {} + }, + { + "label": "create_access_token", + "importPath": "spectragraph_core.core.auth", + "description": "spectragraph_core.core.auth", + "isExtraImport": true, + "detail": "spectragraph_core.core.auth", + "documentation": {} + }, + { + "label": "verify_password", + "importPath": "spectragraph_core.core.auth", + "description": "spectragraph_core.core.auth", + "isExtraImport": true, + "detail": "spectragraph_core.core.auth", + "documentation": {} + }, + { + "label": "get_password_hash", + "importPath": "spectragraph_core.core.auth", + "description": "spectragraph_core.core.auth", + "isExtraImport": true, + "detail": "spectragraph_core.core.auth", + "documentation": {} + }, + { + "label": "ACCESS_TOKEN_EXPIRE_MINUTES", + "importPath": "spectragraph_core.core.auth", + "description": "spectragraph_core.core.auth", + "isExtraImport": true, + "detail": "spectragraph_core.core.auth", + "documentation": {} + }, + { + "label": "AUTH_SECRET", + "importPath": "spectragraph_core.core.auth", + "description": "spectragraph_core.core.auth", + "isExtraImport": true, + "detail": "spectragraph_core.core.auth", + "documentation": {} + }, + { + "label": "ALGORITHM", + "importPath": "spectragraph_core.core.auth", + "description": "spectragraph_core.core.auth", + "isExtraImport": true, + "detail": "spectragraph_core.core.auth", + "documentation": {} + }, + { + "label": "ProfileCreate", + "importPath": "app.api.schemas.profile", + "description": "app.api.schemas.profile", + "isExtraImport": true, + "detail": "app.api.schemas.profile", + "documentation": {} + }, + { + "label": "StreamingResponse", + "importPath": "fastapi.responses", + "description": "fastapi.responses", + "isExtraImport": true, + "detail": "fastapi.responses", + "documentation": {} + }, + { + "label": "JSONResponse", + "importPath": "fastapi.responses", + "description": "fastapi.responses", + "isExtraImport": true, + "detail": "fastapi.responses", + "documentation": {} + }, + { + "label": "BaseModel", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "BaseModel", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "BaseModel", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "Field", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "BaseModel", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "BaseModel", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "TypeAdapter", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "UUID4", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "BaseModel", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "BaseModel", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "UUID4", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "BaseModel", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "BaseModel", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "UUID4", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "Field", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "field_validator", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "UUID4", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "BaseModel", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "UUID4", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "BaseModel", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "UUID4", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "BaseModel", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "UUID4", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "BaseModel", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "UUID4", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "BaseModel", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "UUID4", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "BaseModel", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "EmailStr", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "UUID4", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "BaseModel", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "UUID4", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "BaseModel", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "UUID4", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "BaseModel", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "BaseModel", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "create_model", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "EmailStr", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "Field", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "field_validator", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "TypeAdapter", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "BaseModel", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "BaseModel", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "BaseModel", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "TypeAdapter", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "ValidationError", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "ValidationError", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "BaseModel", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "Field", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "create_model", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "TypeAdapter", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "BaseModel", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "Field", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "TypeAdapter", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "BaseModel", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "BaseModel", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "BaseModel", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "TypeAdapter", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "TypeAdapter", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "BaseModel", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "Field", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "BaseModel", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "TypeAdapter", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "BaseModel", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "BaseModel", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "BaseModel", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "TypeAdapter", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "HttpUrl", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "BaseModel", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "Field", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "BaseModel", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "Field", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "BaseModel", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "Field", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "BaseModel", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "Field", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "BaseModel", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "Field", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "BaseModel", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "BaseModel", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "Field", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "BaseModel", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "IPvAnyNetwork", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "Field", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "BaseModel", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "Field", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "BaseModel", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "Field", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "BaseModel", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "Field", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "BaseModel", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "Field", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "BaseModel", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "Field", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "Field", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "BaseModel", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "Field", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "BaseModel", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "Field", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "BaseModel", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "Field", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "HttpUrl", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "BaseModel", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "Field", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "BaseModel", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "Field", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "BaseModel", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "Field", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "BaseModel", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "Field", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "BaseModel", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "Field", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "BaseModel", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "Field", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "BaseModel", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "Field", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "BaseModel", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "Field", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "BaseModel", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "Field", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "BaseModel", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "Field", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "BaseModel", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "Field", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "BaseModel", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "Field", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "BaseModel", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "Field", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "BaseModel", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "Field", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "BaseModel", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "Field", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "BaseModel", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "Field", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "HttpUrl", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "BaseModel", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "Field", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "BaseModel", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "Field", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "BaseModel", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "Field", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "HttpUrl", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "BaseModel", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "Field", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "Mistral", + "importPath": "mistralai", + "description": "mistralai", + "isExtraImport": true, + "detail": "mistralai", + "documentation": {} + }, + { + "label": "UserMessage", + "importPath": "mistralai.models", + "description": "mistralai.models", + "isExtraImport": true, + "detail": "mistralai.models", + "documentation": {} + }, + { + "label": "AssistantMessage", + "importPath": "mistralai.models", + "description": "mistralai.models", + "isExtraImport": true, + "detail": "mistralai.models", + "documentation": {} + }, + { + "label": "SystemMessage", + "importPath": "mistralai.models", + "description": "mistralai.models", + "isExtraImport": true, + "detail": "mistralai.models", + "documentation": {} + }, + { + "label": "json", + "kind": 6, + "isExtraImport": true, + "importPath": "json", + "description": "json", + "detail": "json", + "documentation": {} + }, + { + "label": "ChatCreate", + "importPath": "app.api.schemas.chat", + "description": "app.api.schemas.chat", + "isExtraImport": true, + "detail": "app.api.schemas.chat", + "documentation": {} + }, + { + "label": "ChatRead", + "importPath": "app.api.schemas.chat", + "description": "app.api.schemas.chat", + "isExtraImport": true, + "detail": "app.api.schemas.chat", + "documentation": {} + }, + { + "label": "CustomTypeCreate", + "importPath": "app.api.schemas.custom_type", + "description": "app.api.schemas.custom_type", + "isExtraImport": true, + "detail": "app.api.schemas.custom_type", + "documentation": {} + }, + { + "label": "CustomTypeUpdate", + "importPath": "app.api.schemas.custom_type", + "description": "app.api.schemas.custom_type", + "isExtraImport": true, + "detail": "app.api.schemas.custom_type", + "documentation": {} + }, + { + "label": "CustomTypeRead", + "importPath": "app.api.schemas.custom_type", + "description": "app.api.schemas.custom_type", + "isExtraImport": true, + "detail": "app.api.schemas.custom_type", + "documentation": {} + }, + { + "label": "CustomTypeValidatePayload", + "importPath": "app.api.schemas.custom_type", + "description": "app.api.schemas.custom_type", + "isExtraImport": true, + "detail": "app.api.schemas.custom_type", + "documentation": {} + }, + { + "label": "CustomTypeValidateResponse", + "importPath": "app.api.schemas.custom_type", + "description": "app.api.schemas.custom_type", + "isExtraImport": true, + "detail": "app.api.schemas.custom_type", + "documentation": {} + }, + { + "label": "validate_json_schema", + "importPath": "app.utils.custom_types", + "description": "app.utils.custom_types", + "isExtraImport": true, + "detail": "app.utils.custom_types", + "documentation": {} + }, + { + "label": "validate_payload_against_schema", + "importPath": "app.utils.custom_types", + "description": "app.utils.custom_types", + "isExtraImport": true, + "detail": "app.utils.custom_types", + "documentation": {} + }, + { + "label": "calculate_schema_checksum", + "importPath": "app.utils.custom_types", + "description": "app.utils.custom_types", + "isExtraImport": true, + "detail": "app.utils.custom_types", + "documentation": {} + }, + { + "label": "event_emitter", + "importPath": "spectragraph_core.core.events", + "description": "spectragraph_core.core.events", + "isExtraImport": true, + "detail": "spectragraph_core.core.events", + "documentation": {} + }, + { + "label": "EventSourceResponse", + "importPath": "sse_starlette.sse", + "description": "sse_starlette.sse", + "isExtraImport": true, + "detail": "sse_starlette.sse", + "documentation": {} + }, + { + "label": "Event", + "importPath": "spectragraph_core.core.types", + "description": "spectragraph_core.core.types", + "isExtraImport": true, + "detail": "spectragraph_core.core.types", + "documentation": {} + }, + { + "label": "Node", + "importPath": "spectragraph_core.core.types", + "description": "spectragraph_core.core.types", + "isExtraImport": true, + "detail": "spectragraph_core.core.types", + "documentation": {} + }, + { + "label": "Edge", + "importPath": "spectragraph_core.core.types", + "description": "spectragraph_core.core.types", + "isExtraImport": true, + "detail": "spectragraph_core.core.types", + "documentation": {} + }, + { + "label": "FlowStep", + "importPath": "spectragraph_core.core.types", + "description": "spectragraph_core.core.types", + "isExtraImport": true, + "detail": "spectragraph_core.core.types", + "documentation": {} + }, + { + "label": "FlowBranch", + "importPath": "spectragraph_core.core.types", + "description": "spectragraph_core.core.types", + "isExtraImport": true, + "detail": "spectragraph_core.core.types", + "documentation": {} + }, + { + "label": "Role", + "importPath": "spectragraph_core.core.types", + "description": "spectragraph_core.core.types", + "isExtraImport": true, + "detail": "spectragraph_core.core.types", + "documentation": {} + }, + { + "label": "Node", + "importPath": "spectragraph_core.core.types", + "description": "spectragraph_core.core.types", + "isExtraImport": true, + "detail": "spectragraph_core.core.types", + "documentation": {} + }, + { + "label": "Edge", + "importPath": "spectragraph_core.core.types", + "description": "spectragraph_core.core.types", + "isExtraImport": true, + "detail": "spectragraph_core.core.types", + "documentation": {} + }, + { + "label": "FlowBranch", + "importPath": "spectragraph_core.core.types", + "description": "spectragraph_core.core.types", + "isExtraImport": true, + "detail": "spectragraph_core.core.types", + "documentation": {} + }, + { + "label": "Role", + "importPath": "spectragraph_core.core.types", + "description": "spectragraph_core.core.types", + "isExtraImport": true, + "detail": "spectragraph_core.core.types", + "documentation": {} + }, + { + "label": "Role", + "importPath": "spectragraph_core.core.types", + "description": "spectragraph_core.core.types", + "isExtraImport": true, + "detail": "spectragraph_core.core.types", + "documentation": {} + }, + { + "label": "asyncio", + "kind": 6, + "isExtraImport": true, + "importPath": "asyncio", + "description": "asyncio", + "detail": "asyncio", + "documentation": {} + }, + { + "label": "extract_input_schema_flow", + "importPath": "spectragraph_core.utils", + "description": "spectragraph_core.utils", + "isExtraImport": true, + "detail": "spectragraph_core.utils", + "documentation": {} + }, + { + "label": "flatten", + "importPath": "spectragraph_core.utils", + "description": "spectragraph_core.utils", + "isExtraImport": true, + "detail": "spectragraph_core.utils", + "documentation": {} + }, + { + "label": "to_json_serializable", + "importPath": "spectragraph_core.utils", + "description": "spectragraph_core.utils", + "isExtraImport": true, + "detail": "spectragraph_core.utils", + "documentation": {} + }, + { + "label": "to_json_serializable", + "importPath": "spectragraph_core.utils", + "description": "spectragraph_core.utils", + "isExtraImport": true, + "detail": "spectragraph_core.utils", + "documentation": {} + }, + { + "label": "is_valid_asn", + "importPath": "spectragraph_core.utils", + "description": "spectragraph_core.utils", + "isExtraImport": true, + "detail": "spectragraph_core.utils", + "documentation": {} + }, + { + "label": "parse_asn", + "importPath": "spectragraph_core.utils", + "description": "spectragraph_core.utils", + "isExtraImport": true, + "detail": "spectragraph_core.utils", + "documentation": {} + }, + { + "label": "is_valid_domain", + "importPath": "spectragraph_core.utils", + "description": "spectragraph_core.utils", + "isExtraImport": true, + "detail": "spectragraph_core.utils", + "documentation": {} + }, + { + "label": "is_valid_domain", + "importPath": "spectragraph_core.utils", + "description": "spectragraph_core.utils", + "isExtraImport": true, + "detail": "spectragraph_core.utils", + "documentation": {} + }, + { + "label": "is_root_domain", + "importPath": "spectragraph_core.utils", + "description": "spectragraph_core.utils", + "isExtraImport": true, + "detail": "spectragraph_core.utils", + "documentation": {} + }, + { + "label": "is_valid_domain", + "importPath": "spectragraph_core.utils", + "description": "spectragraph_core.utils", + "isExtraImport": true, + "detail": "spectragraph_core.utils", + "documentation": {} + }, + { + "label": "is_root_domain", + "importPath": "spectragraph_core.utils", + "description": "spectragraph_core.utils", + "isExtraImport": true, + "detail": "spectragraph_core.utils", + "documentation": {} + }, + { + "label": "is_valid_domain", + "importPath": "spectragraph_core.utils", + "description": "spectragraph_core.utils", + "isExtraImport": true, + "detail": "spectragraph_core.utils", + "documentation": {} + }, + { + "label": "is_valid_domain", + "importPath": "spectragraph_core.utils", + "description": "spectragraph_core.utils", + "isExtraImport": true, + "detail": "spectragraph_core.utils", + "documentation": {} + }, + { + "label": "is_valid_domain", + "importPath": "spectragraph_core.utils", + "description": "spectragraph_core.utils", + "isExtraImport": true, + "detail": "spectragraph_core.utils", + "documentation": {} + }, + { + "label": "is_valid_ip", + "importPath": "spectragraph_core.utils", + "description": "spectragraph_core.utils", + "isExtraImport": true, + "detail": "spectragraph_core.utils", + "documentation": {} + }, + { + "label": "is_valid_ip", + "importPath": "spectragraph_core.utils", + "description": "spectragraph_core.utils", + "isExtraImport": true, + "detail": "spectragraph_core.utils", + "documentation": {} + }, + { + "label": "resolve_type", + "importPath": "spectragraph_core.utils", + "description": "spectragraph_core.utils", + "isExtraImport": true, + "detail": "spectragraph_core.utils", + "documentation": {} + }, + { + "label": "is_valid_ip", + "importPath": "spectragraph_core.utils", + "description": "spectragraph_core.utils", + "isExtraImport": true, + "detail": "spectragraph_core.utils", + "documentation": {} + }, + { + "label": "is_valid_domain", + "importPath": "spectragraph_core.utils", + "description": "spectragraph_core.utils", + "isExtraImport": true, + "detail": "spectragraph_core.utils", + "documentation": {} + }, + { + "label": "is_root_domain", + "importPath": "spectragraph_core.utils", + "description": "spectragraph_core.utils", + "isExtraImport": true, + "detail": "spectragraph_core.utils", + "documentation": {} + }, + { + "label": "is_valid_number", + "importPath": "spectragraph_core.utils", + "description": "spectragraph_core.utils", + "isExtraImport": true, + "detail": "spectragraph_core.utils", + "documentation": {} + }, + { + "label": "is_valid_username", + "importPath": "spectragraph_core.utils", + "description": "spectragraph_core.utils", + "isExtraImport": true, + "detail": "spectragraph_core.utils", + "documentation": {} + }, + { + "label": "is_valid_username", + "importPath": "spectragraph_core.utils", + "description": "spectragraph_core.utils", + "isExtraImport": true, + "detail": "spectragraph_core.utils", + "documentation": {} + }, + { + "label": "is_valid_domain", + "importPath": "spectragraph_core.utils", + "description": "spectragraph_core.utils", + "isExtraImport": true, + "detail": "spectragraph_core.utils", + "documentation": {} + }, + { + "label": "TransformRegistry", + "importPath": "spectragraph_core.core.registry", + "description": "spectragraph_core.core.registry", + "isExtraImport": true, + "detail": "spectragraph_core.core.registry", + "documentation": {} + }, + { + "label": "TransformRegistry", + "importPath": "spectragraph_core.core.registry", + "description": "spectragraph_core.core.registry", + "isExtraImport": true, + "detail": "spectragraph_core.core.registry", + "documentation": {} + }, + { + "label": "TransformRegistry", + "importPath": "spectragraph_core.core.registry", + "description": "spectragraph_core.core.registry", + "isExtraImport": true, + "detail": "spectragraph_core.core.registry", + "documentation": {} + }, + { + "label": "celery", + "importPath": "spectragraph_core.core.celery", + "description": "spectragraph_core.core.celery", + "isExtraImport": true, + "detail": "spectragraph_core.core.celery", + "documentation": {} + }, + { + "label": "celery", + "importPath": "spectragraph_core.core.celery", + "description": "spectragraph_core.core.celery", + "isExtraImport": true, + "detail": "spectragraph_core.core.celery", + "documentation": {} + }, + { + "label": "Domain", + "importPath": "spectragraph_types", + "description": "spectragraph_types", + "isExtraImport": true, + "detail": "spectragraph_types", + "documentation": {} + }, + { + "label": "Phrase", + "importPath": "spectragraph_types", + "description": "spectragraph_types", + "isExtraImport": true, + "detail": "spectragraph_types", + "documentation": {} + }, + { + "label": "Ip", + "importPath": "spectragraph_types", + "description": "spectragraph_types", + "isExtraImport": true, + "detail": "spectragraph_types", + "documentation": {} + }, + { + "label": "SocialProfile", + "importPath": "spectragraph_types", + "description": "spectragraph_types", + "isExtraImport": true, + "detail": "spectragraph_types", + "documentation": {} + }, + { + "label": "Organization", + "importPath": "spectragraph_types", + "description": "spectragraph_types", + "isExtraImport": true, + "detail": "spectragraph_types", + "documentation": {} + }, + { + "label": "Email", + "importPath": "spectragraph_types", + "description": "spectragraph_types", + "isExtraImport": true, + "detail": "spectragraph_types", + "documentation": {} + }, + { + "label": "Phone", + "importPath": "spectragraph_types", + "description": "spectragraph_types", + "isExtraImport": true, + "detail": "spectragraph_types", + "documentation": {} + }, + { + "label": "ASN", + "importPath": "spectragraph_types", + "description": "spectragraph_types", + "isExtraImport": true, + "detail": "spectragraph_types", + "documentation": {} + }, + { + "label": "CIDR", + "importPath": "spectragraph_types", + "description": "spectragraph_types", + "isExtraImport": true, + "detail": "spectragraph_types", + "documentation": {} + }, + { + "label": "CryptoWallet", + "importPath": "spectragraph_types", + "description": "spectragraph_types", + "isExtraImport": true, + "detail": "spectragraph_types", + "documentation": {} + }, + { + "label": "CryptoWalletTransaction", + "importPath": "spectragraph_types", + "description": "spectragraph_types", + "isExtraImport": true, + "detail": "spectragraph_types", + "documentation": {} + }, + { + "label": "CryptoNFT", + "importPath": "spectragraph_types", + "description": "spectragraph_types", + "isExtraImport": true, + "detail": "spectragraph_types", + "documentation": {} + }, + { + "label": "Website", + "importPath": "spectragraph_types", + "description": "spectragraph_types", + "isExtraImport": true, + "detail": "spectragraph_types", + "documentation": {} + }, + { + "label": "Individual", + "importPath": "spectragraph_types", + "description": "spectragraph_types", + "isExtraImport": true, + "detail": "spectragraph_types", + "documentation": {} + }, + { + "label": "Domain", + "importPath": "spectragraph_types", + "description": "spectragraph_types", + "isExtraImport": true, + "detail": "spectragraph_types", + "documentation": {} + }, + { + "label": "Ip", + "importPath": "spectragraph_types", + "description": "spectragraph_types", + "isExtraImport": true, + "detail": "spectragraph_types", + "documentation": {} + }, + { + "label": "SocialProfile", + "importPath": "spectragraph_types", + "description": "spectragraph_types", + "isExtraImport": true, + "detail": "spectragraph_types", + "documentation": {} + }, + { + "label": "Organization", + "importPath": "spectragraph_types", + "description": "spectragraph_types", + "isExtraImport": true, + "detail": "spectragraph_types", + "documentation": {} + }, + { + "label": "Email", + "importPath": "spectragraph_types", + "description": "spectragraph_types", + "isExtraImport": true, + "detail": "spectragraph_types", + "documentation": {} + }, + { + "label": "ASN", + "importPath": "spectragraph_types", + "description": "spectragraph_types", + "isExtraImport": true, + "detail": "spectragraph_types", + "documentation": {} + }, + { + "label": "CIDR", + "importPath": "spectragraph_types", + "description": "spectragraph_types", + "isExtraImport": true, + "detail": "spectragraph_types", + "documentation": {} + }, + { + "label": "CryptoWallet", + "importPath": "spectragraph_types", + "description": "spectragraph_types", + "isExtraImport": true, + "detail": "spectragraph_types", + "documentation": {} + }, + { + "label": "CryptoWalletTransaction", + "importPath": "spectragraph_types", + "description": "spectragraph_types", + "isExtraImport": true, + "detail": "spectragraph_types", + "documentation": {} + }, + { + "label": "CryptoNFT", + "importPath": "spectragraph_types", + "description": "spectragraph_types", + "isExtraImport": true, + "detail": "spectragraph_types", + "documentation": {} + }, + { + "label": "Website", + "importPath": "spectragraph_types", + "description": "spectragraph_types", + "isExtraImport": true, + "detail": "spectragraph_types", + "documentation": {} + }, + { + "label": "Individual", + "importPath": "spectragraph_types", + "description": "spectragraph_types", + "isExtraImport": true, + "detail": "spectragraph_types", + "documentation": {} + }, + { + "label": "Phone", + "importPath": "spectragraph_types", + "description": "spectragraph_types", + "isExtraImport": true, + "detail": "spectragraph_types", + "documentation": {} + }, + { + "label": "Leak", + "importPath": "spectragraph_types", + "description": "spectragraph_types", + "isExtraImport": true, + "detail": "spectragraph_types", + "documentation": {} + }, + { + "label": "Username", + "importPath": "spectragraph_types", + "description": "spectragraph_types", + "isExtraImport": true, + "detail": "spectragraph_types", + "documentation": {} + }, + { + "label": "Credential", + "importPath": "spectragraph_types", + "description": "spectragraph_types", + "isExtraImport": true, + "detail": "spectragraph_types", + "documentation": {} + }, + { + "label": "Session", + "importPath": "spectragraph_types", + "description": "spectragraph_types", + "isExtraImport": true, + "detail": "spectragraph_types", + "documentation": {} + }, + { + "label": "DNSRecord", + "importPath": "spectragraph_types", + "description": "spectragraph_types", + "isExtraImport": true, + "detail": "spectragraph_types", + "documentation": {} + }, + { + "label": "SSLCertificate", + "importPath": "spectragraph_types", + "description": "spectragraph_types", + "isExtraImport": true, + "detail": "spectragraph_types", + "documentation": {} + }, + { + "label": "Device", + "importPath": "spectragraph_types", + "description": "spectragraph_types", + "isExtraImport": true, + "detail": "spectragraph_types", + "documentation": {} + }, + { + "label": "Document", + "importPath": "spectragraph_types", + "description": "spectragraph_types", + "isExtraImport": true, + "detail": "spectragraph_types", + "documentation": {} + }, + { + "label": "File", + "importPath": "spectragraph_types", + "description": "spectragraph_types", + "isExtraImport": true, + "detail": "spectragraph_types", + "documentation": {} + }, + { + "label": "Message", + "importPath": "spectragraph_types", + "description": "spectragraph_types", + "isExtraImport": true, + "detail": "spectragraph_types", + "documentation": {} + }, + { + "label": "Malware", + "importPath": "spectragraph_types", + "description": "spectragraph_types", + "isExtraImport": true, + "detail": "spectragraph_types", + "documentation": {} + }, + { + "label": "Weapon", + "importPath": "spectragraph_types", + "description": "spectragraph_types", + "isExtraImport": true, + "detail": "spectragraph_types", + "documentation": {} + }, + { + "label": "BankAccount", + "importPath": "spectragraph_types", + "description": "spectragraph_types", + "isExtraImport": true, + "detail": "spectragraph_types", + "documentation": {} + }, + { + "label": "CreditCard", + "importPath": "spectragraph_types", + "description": "spectragraph_types", + "isExtraImport": true, + "detail": "spectragraph_types", + "documentation": {} + }, + { + "label": "WebTracker", + "importPath": "spectragraph_types", + "description": "spectragraph_types", + "isExtraImport": true, + "detail": "spectragraph_types", + "documentation": {} + }, + { + "label": "Phrase", + "importPath": "spectragraph_types", + "description": "spectragraph_types", + "isExtraImport": true, + "detail": "spectragraph_types", + "documentation": {} + }, + { + "label": "Location", + "importPath": "spectragraph_types", + "description": "spectragraph_types", + "isExtraImport": true, + "detail": "spectragraph_types", + "documentation": {} + }, + { + "label": "FlowRead", + "importPath": "app.api.schemas.flow", + "description": "app.api.schemas.flow", + "isExtraImport": true, + "detail": "app.api.schemas.flow", + "documentation": {} + }, + { + "label": "FlowCreate", + "importPath": "app.api.schemas.flow", + "description": "app.api.schemas.flow", + "isExtraImport": true, + "detail": "app.api.schemas.flow", + "documentation": {} + }, + { + "label": "FlowUpdate", + "importPath": "app.api.schemas.flow", + "description": "app.api.schemas.flow", + "isExtraImport": true, + "detail": "app.api.schemas.flow", + "documentation": {} + }, + { + "label": "InvestigationRead", + "importPath": "app.api.schemas.investigation", + "description": "app.api.schemas.investigation", + "isExtraImport": true, + "detail": "app.api.schemas.investigation", + "documentation": {} + }, + { + "label": "InvestigationCreate", + "importPath": "app.api.schemas.investigation", + "description": "app.api.schemas.investigation", + "isExtraImport": true, + "detail": "app.api.schemas.investigation", + "documentation": {} + }, + { + "label": "InvestigationUpdate", + "importPath": "app.api.schemas.investigation", + "description": "app.api.schemas.investigation", + "isExtraImport": true, + "detail": "app.api.schemas.investigation", + "documentation": {} + }, + { + "label": "SketchRead", + "importPath": "app.api.schemas.sketch", + "description": "app.api.schemas.sketch", + "isExtraImport": true, + "detail": "app.api.schemas.sketch", + "documentation": {} + }, + { + "label": "SketchCreate", + "importPath": "app.api.schemas.sketch", + "description": "app.api.schemas.sketch", + "isExtraImport": true, + "detail": "app.api.schemas.sketch", + "documentation": {} + }, + { + "label": "SketchRead", + "importPath": "app.api.schemas.sketch", + "description": "app.api.schemas.sketch", + "isExtraImport": true, + "detail": "app.api.schemas.sketch", + "documentation": {} + }, + { + "label": "SketchUpdate", + "importPath": "app.api.schemas.sketch", + "description": "app.api.schemas.sketch", + "isExtraImport": true, + "detail": "app.api.schemas.sketch", + "documentation": {} + }, + { + "label": "neo4j_connection", + "importPath": "spectragraph_core.core.graph_db", + "description": "spectragraph_core.core.graph_db", + "isExtraImport": true, + "detail": "spectragraph_core.core.graph_db", + "documentation": {} + }, + { + "label": "neo4j_connection", + "importPath": "spectragraph_core.core.graph_db", + "description": "spectragraph_core.core.graph_db", + "isExtraImport": true, + "detail": "spectragraph_core.core.graph_db", + "documentation": {} + }, + { + "label": "Neo4jConnection", + "importPath": "spectragraph_core.core.graph_db", + "description": "spectragraph_core.core.graph_db", + "isExtraImport": true, + "detail": "spectragraph_core.core.graph_db", + "documentation": {} + }, + { + "label": "Neo4jConnection", + "importPath": "spectragraph_core.core.graph_db", + "description": "spectragraph_core.core.graph_db", + "isExtraImport": true, + "detail": "spectragraph_core.core.graph_db", + "documentation": {} + }, + { + "label": "Neo4jConnection", + "importPath": "spectragraph_core.core.graph_db", + "description": "spectragraph_core.core.graph_db", + "isExtraImport": true, + "detail": "spectragraph_core.core.graph_db", + "documentation": {} + }, + { + "label": "Neo4jConnection", + "importPath": "spectragraph_core.core.graph_db", + "description": "spectragraph_core.core.graph_db", + "isExtraImport": true, + "detail": "spectragraph_core.core.graph_db", + "documentation": {} + }, + { + "label": "Neo4jConnection", + "importPath": "spectragraph_core.core.graph_db", + "description": "spectragraph_core.core.graph_db", + "isExtraImport": true, + "detail": "spectragraph_core.core.graph_db", + "documentation": {} + }, + { + "label": "Neo4jConnection", + "importPath": "spectragraph_core.core.graph_db", + "description": "spectragraph_core.core.graph_db", + "isExtraImport": true, + "detail": "spectragraph_core.core.graph_db", + "documentation": {} + }, + { + "label": "Neo4jConnection", + "importPath": "spectragraph_core.core.graph_db", + "description": "spectragraph_core.core.graph_db", + "isExtraImport": true, + "detail": "spectragraph_core.core.graph_db", + "documentation": {} + }, + { + "label": "Neo4jConnection", + "importPath": "spectragraph_core.core.graph_db", + "description": "spectragraph_core.core.graph_db", + "isExtraImport": true, + "detail": "spectragraph_core.core.graph_db", + "documentation": {} + }, + { + "label": "Neo4jConnection", + "importPath": "spectragraph_core.core.graph_db", + "description": "spectragraph_core.core.graph_db", + "isExtraImport": true, + "detail": "spectragraph_core.core.graph_db", + "documentation": {} + }, + { + "label": "Neo4jConnection", + "importPath": "spectragraph_core.core.graph_db", + "description": "spectragraph_core.core.graph_db", + "isExtraImport": true, + "detail": "spectragraph_core.core.graph_db", + "documentation": {} + }, + { + "label": "Neo4jConnection", + "importPath": "spectragraph_core.core.graph_db", + "description": "spectragraph_core.core.graph_db", + "isExtraImport": true, + "detail": "spectragraph_core.core.graph_db", + "documentation": {} + }, + { + "label": "Neo4jConnection", + "importPath": "spectragraph_core.core.graph_db", + "description": "spectragraph_core.core.graph_db", + "isExtraImport": true, + "detail": "spectragraph_core.core.graph_db", + "documentation": {} + }, + { + "label": "Neo4jConnection", + "importPath": "spectragraph_core.core.graph_db", + "description": "spectragraph_core.core.graph_db", + "isExtraImport": true, + "detail": "spectragraph_core.core.graph_db", + "documentation": {} + }, + { + "label": "Neo4jConnection", + "importPath": "spectragraph_core.core.graph_db", + "description": "spectragraph_core.core.graph_db", + "isExtraImport": true, + "detail": "spectragraph_core.core.graph_db", + "documentation": {} + }, + { + "label": "Neo4jConnection", + "importPath": "spectragraph_core.core.graph_db", + "description": "spectragraph_core.core.graph_db", + "isExtraImport": true, + "detail": "spectragraph_core.core.graph_db", + "documentation": {} + }, + { + "label": "Neo4jConnection", + "importPath": "spectragraph_core.core.graph_db", + "description": "spectragraph_core.core.graph_db", + "isExtraImport": true, + "detail": "spectragraph_core.core.graph_db", + "documentation": {} + }, + { + "label": "GraphRepository", + "importPath": "spectragraph_core.core.graph_repository", + "description": "spectragraph_core.core.graph_repository", + "isExtraImport": true, + "detail": "spectragraph_core.core.graph_repository", + "documentation": {} + }, + { + "label": "GraphRepository", + "importPath": "spectragraph_core.core.graph_repository", + "description": "spectragraph_core.core.graph_repository", + "isExtraImport": true, + "detail": "spectragraph_core.core.graph_repository", + "documentation": {} + }, + { + "label": "Vault", + "importPath": "spectragraph_core.core.vault", + "description": "spectragraph_core.core.vault", + "isExtraImport": true, + "detail": "spectragraph_core.core.vault", + "documentation": {} + }, + { + "label": "Vault", + "importPath": "spectragraph_core.core.vault", + "description": "spectragraph_core.core.vault", + "isExtraImport": true, + "detail": "spectragraph_core.core.vault", + "documentation": {} + }, + { + "label": "VaultProtocol", + "importPath": "spectragraph_core.core.vault", + "description": "spectragraph_core.core.vault", + "isExtraImport": true, + "detail": "spectragraph_core.core.vault", + "documentation": {} + }, + { + "label": "KeyRead", + "importPath": "app.api.schemas.key", + "description": "app.api.schemas.key", + "isExtraImport": true, + "detail": "app.api.schemas.key", + "documentation": {} + }, + { + "label": "KeyCreate", + "importPath": "app.api.schemas.key", + "description": "app.api.schemas.key", + "isExtraImport": true, + "detail": "app.api.schemas.key", + "documentation": {} + }, + { + "label": "ScanRead", + "importPath": "app.api.schemas.scan", + "description": "app.api.schemas.scan", + "isExtraImport": true, + "detail": "app.api.schemas.scan", + "documentation": {} + }, + { + "label": "parse_file", + "importPath": "spectragraph_core.imports", + "description": "spectragraph_core.imports", + "isExtraImport": true, + "detail": "spectragraph_core.imports", + "documentation": {} + }, + { + "label": "parse_file", + "importPath": "spectragraph_core.imports", + "description": "spectragraph_core.imports", + "isExtraImport": true, + "detail": "spectragraph_core.imports", + "documentation": {} + }, + { + "label": "update_sketch_timestamp", + "importPath": "app.api.sketch_utils", + "description": "app.api.sketch_utils", + "isExtraImport": true, + "detail": "app.api.sketch_utils", + "documentation": {} + }, + { + "label": "JWTError", + "importPath": "jose", + "description": "jose", + "isExtraImport": true, + "detail": "jose", + "documentation": {} + }, + { + "label": "jwt", + "importPath": "jose", + "description": "jose", + "isExtraImport": true, + "detail": "jose", + "documentation": {} + }, + { + "label": "jwt", + "importPath": "jose", + "description": "jose", + "isExtraImport": true, + "detail": "jose", + "documentation": {} + }, + { + "label": "jwt", + "importPath": "jose", + "description": "jose", + "isExtraImport": true, + "detail": "jose", + "documentation": {} + }, + { + "label": "wraps", + "importPath": "functools", + "description": "functools", + "isExtraImport": true, + "detail": "functools", + "documentation": {} + }, + { + "label": "hashlib", + "kind": 6, + "isExtraImport": true, + "importPath": "hashlib", + "description": "hashlib", + "detail": "hashlib", + "documentation": {} + }, + { + "label": "Draft7Validator", + "importPath": "jsonschema", + "description": "jsonschema", + "isExtraImport": true, + "detail": "jsonschema", + "documentation": {} + }, + { + "label": "ValidationError", + "importPath": "jsonschema", + "description": "jsonschema", + "isExtraImport": true, + "detail": "jsonschema", + "documentation": {} + }, + { + "label": "RequestValidationError", + "importPath": "fastapi.exceptions", + "description": "fastapi.exceptions", + "isExtraImport": true, + "detail": "fastapi.exceptions", + "documentation": {} + }, + { + "label": "RequestValidationError", + "importPath": "fastapi.exceptions", + "description": "fastapi.exceptions", + "isExtraImport": true, + "detail": "fastapi.exceptions", + "documentation": {} + }, + { + "label": "HTTPException", + "importPath": "starlette.exceptions", + "description": "starlette.exceptions", + "isExtraImport": true, + "detail": "starlette.exceptions", + "documentation": {} + }, + { + "label": "HTTPException", + "importPath": "starlette.exceptions", + "description": "starlette.exceptions", + "isExtraImport": true, + "detail": "starlette.exceptions", + "documentation": {} + }, + { + "label": "logging", + "kind": 6, + "isExtraImport": true, + "importPath": "logging", + "description": "logging", + "detail": "logging", + "documentation": {} + }, + { + "label": "CORSMiddleware", + "importPath": "fastapi.middleware.cors", + "description": "fastapi.middleware.cors", + "isExtraImport": true, + "detail": "fastapi.middleware.cors", + "documentation": {} + }, + { + "label": "time", + "kind": 6, + "isExtraImport": true, + "importPath": "time", + "description": "time", + "detail": "time", + "documentation": {} + }, + { + "label": "auth", + "importPath": "app.api.routes", + "description": "app.api.routes", + "isExtraImport": true, + "detail": "app.api.routes", + "documentation": {} + }, + { + "label": "investigations", + "importPath": "app.api.routes", + "description": "app.api.routes", + "isExtraImport": true, + "detail": "app.api.routes", + "documentation": {} + }, + { + "label": "sketches", + "importPath": "app.api.routes", + "description": "app.api.routes", + "isExtraImport": true, + "detail": "app.api.routes", + "documentation": {} + }, + { + "label": "flows", + "importPath": "app.api.routes", + "description": "app.api.routes", + "isExtraImport": true, + "detail": "app.api.routes", + "documentation": {} + }, + { + "label": "events", + "importPath": "app.api.routes", + "description": "app.api.routes", + "isExtraImport": true, + "detail": "app.api.routes", + "documentation": {} + }, + { + "label": "analysis", + "importPath": "app.api.routes", + "description": "app.api.routes", + "isExtraImport": true, + "detail": "app.api.routes", + "documentation": {} + }, + { + "label": "chat", + "importPath": "app.api.routes", + "description": "app.api.routes", + "isExtraImport": true, + "detail": "app.api.routes", + "documentation": {} + }, + { + "label": "scan", + "importPath": "app.api.routes", + "description": "app.api.routes", + "isExtraImport": true, + "detail": "app.api.routes", + "documentation": {} + }, + { + "label": "keys", + "importPath": "app.api.routes", + "description": "app.api.routes", + "isExtraImport": true, + "detail": "app.api.routes", + "documentation": {} + }, + { + "label": "types", + "importPath": "app.api.routes", + "description": "app.api.routes", + "isExtraImport": true, + "detail": "app.api.routes", + "documentation": {} + }, + { + "label": "custom_types", + "importPath": "app.api.routes", + "description": "app.api.routes", + "isExtraImport": true, + "detail": "app.api.routes", + "documentation": {} + }, + { + "label": "setup_logging", + "importPath": "app.logging_config", + "description": "app.logging_config", + "isExtraImport": true, + "detail": "app.logging_config", + "documentation": {} + }, + { + "label": "global_exception_handler", + "importPath": "app.exceptions", + "description": "app.exceptions", + "isExtraImport": true, + "detail": "app.exceptions", + "documentation": {} + }, + { + "label": "http_exception_handler", + "importPath": "app.exceptions", + "description": "app.exceptions", + "isExtraImport": true, + "detail": "app.exceptions", + "documentation": {} + }, + { + "label": "validation_exception_handler", + "importPath": "app.exceptions", + "description": "app.exceptions", + "isExtraImport": true, + "detail": "app.exceptions", + "documentation": {} + }, + { + "label": "urlparse", + "importPath": "urllib.parse", + "description": "urllib.parse", + "isExtraImport": true, + "detail": "urllib.parse", + "documentation": {} + }, + { + "label": "urlparse", + "importPath": "urllib.parse", + "description": "urllib.parse", + "isExtraImport": true, + "detail": "urllib.parse", + "documentation": {} + }, + { + "label": "urlparse", + "importPath": "urllib.parse", + "description": "urllib.parse", + "isExtraImport": true, + "detail": "urllib.parse", + "documentation": {} + }, + { + "label": "urlparse", + "importPath": "urllib.parse", + "description": "urllib.parse", + "isExtraImport": true, + "detail": "urllib.parse", + "documentation": {} + }, + { + "label": "urljoin", + "importPath": "urllib.parse", + "description": "urllib.parse", + "isExtraImport": true, + "detail": "urllib.parse", + "documentation": {} + }, + { + "label": "urljoin", + "importPath": "urllib.parse", + "description": "urllib.parse", + "isExtraImport": true, + "detail": "urllib.parse", + "documentation": {} + }, + { + "label": "urlparse", + "importPath": "urllib.parse", + "description": "urllib.parse", + "isExtraImport": true, + "detail": "urllib.parse", + "documentation": {} + }, + { + "label": "urlparse", + "importPath": "urllib.parse", + "description": "urllib.parse", + "isExtraImport": true, + "detail": "urllib.parse", + "documentation": {} + }, + { + "label": "urlparse", + "importPath": "urllib.parse", + "description": "urllib.parse", + "isExtraImport": true, + "detail": "urllib.parse", + "documentation": {} + }, + { + "label": "urlparse", + "importPath": "urllib.parse", + "description": "urllib.parse", + "isExtraImport": true, + "detail": "urllib.parse", + "documentation": {} + }, + { + "label": "urlparse", + "importPath": "urllib.parse", + "description": "urllib.parse", + "isExtraImport": true, + "detail": "urllib.parse", + "documentation": {} + }, + { + "label": "phonenumbers", + "kind": 6, + "isExtraImport": true, + "importPath": "phonenumbers", + "description": "phonenumbers", + "detail": "phonenumbers", + "documentation": {} + }, + { + "label": "NumberParseException", + "importPath": "phonenumbers", + "description": "phonenumbers", + "isExtraImport": true, + "detail": "phonenumbers", + "documentation": {} + }, + { + "label": "NumberParseException", + "importPath": "phonenumbers", + "description": "phonenumbers", + "isExtraImport": true, + "detail": "phonenumbers", + "documentation": {} + }, + { + "label": "NumberParseException", + "importPath": "phonenumbers", + "description": "phonenumbers", + "isExtraImport": true, + "detail": "phonenumbers", + "documentation": {} + }, + { + "label": "ipaddress", + "kind": 6, + "isExtraImport": true, + "importPath": "ipaddress", + "description": "ipaddress", + "detail": "ipaddress", + "documentation": {} + }, + { + "label": "re", + "kind": 6, + "isExtraImport": true, + "importPath": "re", + "description": "re", + "detail": "re", + "documentation": {} + }, + { + "label": "ssl", + "kind": 6, + "isExtraImport": true, + "importPath": "ssl", + "description": "ssl", + "detail": "ssl", + "documentation": {} + }, + { + "label": "socket", + "kind": 6, + "isExtraImport": true, + "importPath": "socket", + "description": "socket", + "detail": "socket", + "documentation": {} + }, + { + "label": "inspect", + "kind": 6, + "isExtraImport": true, + "importPath": "inspect", + "description": "inspect", + "detail": "inspect", + "documentation": {} + }, + { + "label": "CryptContext", + "importPath": "passlib.context", + "description": "passlib.context", + "isExtraImport": true, + "detail": "passlib.context", + "documentation": {} + }, + { + "label": "Celery", + "importPath": "celery", + "description": "celery", + "isExtraImport": true, + "detail": "celery", + "documentation": {} + }, + { + "label": "states", + "importPath": "celery", + "description": "celery", + "isExtraImport": true, + "detail": "celery", + "documentation": {} + }, + { + "label": "states", + "importPath": "celery", + "description": "celery", + "isExtraImport": true, + "detail": "celery", + "documentation": {} + }, + { + "label": "enum", + "kind": 6, + "isExtraImport": true, + "importPath": "enum", + "description": "enum", + "detail": "enum", + "documentation": {} + }, + { + "label": "Enum", + "importPath": "enum", + "description": "enum", + "isExtraImport": true, + "detail": "enum", + "documentation": {} + }, + { + "label": "redis.asyncio", + "kind": 6, + "isExtraImport": true, + "importPath": "redis.asyncio", + "description": "redis.asyncio", + "detail": "redis.asyncio", + "documentation": {} + }, + { + "label": "Lock", + "importPath": "threading", + "description": "threading", + "isExtraImport": true, + "detail": "threading", + "documentation": {} + }, + { + "label": "GraphDatabase", + "importPath": "neo4j", + "description": "neo4j", + "isExtraImport": true, + "detail": "neo4j", + "documentation": {} + }, + { + "label": "Driver", + "importPath": "neo4j", + "description": "neo4j", + "isExtraImport": true, + "detail": "neo4j", + "documentation": {} + }, + { + "label": "Session", + "importPath": "neo4j", + "description": "neo4j", + "isExtraImport": true, + "detail": "neo4j", + "documentation": {} + }, + { + "label": "UUID", + "importPath": "sqlalchemy.dialects.postgresql", + "description": "sqlalchemy.dialects.postgresql", + "isExtraImport": true, + "detail": "sqlalchemy.dialects.postgresql", + "documentation": {} + }, + { + "label": "ARRAY", + "importPath": "sqlalchemy.dialects.postgresql", + "description": "sqlalchemy.dialects.postgresql", + "isExtraImport": true, + "detail": "sqlalchemy.dialects.postgresql", + "documentation": {} + }, + { + "label": "JSONB", + "importPath": "sqlalchemy.dialects.postgresql", + "description": "sqlalchemy.dialects.postgresql", + "isExtraImport": true, + "detail": "sqlalchemy.dialects.postgresql", + "documentation": {} + }, + { + "label": "EventLevel", + "importPath": "spectragraph_core.core.enums", + "description": "spectragraph_core.core.enums", + "isExtraImport": true, + "detail": "spectragraph_core.core.enums", + "documentation": {} + }, + { + "label": "Transform", + "importPath": "spectragraph_core.core.transform_base", + "description": "spectragraph_core.core.transform_base", + "isExtraImport": true, + "detail": "spectragraph_core.core.transform_base", + "documentation": {} + }, + { + "label": "Transform", + "importPath": "spectragraph_core.core.transform_base", + "description": "spectragraph_core.core.transform_base", + "isExtraImport": true, + "detail": "spectragraph_core.core.transform_base", + "documentation": {} + }, + { + "label": "Transform", + "importPath": "spectragraph_core.core.transform_base", + "description": "spectragraph_core.core.transform_base", + "isExtraImport": true, + "detail": "spectragraph_core.core.transform_base", + "documentation": {} + }, + { + "label": "Transform", + "importPath": "spectragraph_core.core.transform_base", + "description": "spectragraph_core.core.transform_base", + "isExtraImport": true, + "detail": "spectragraph_core.core.transform_base", + "documentation": {} + }, + { + "label": "Transform", + "importPath": "spectragraph_core.core.transform_base", + "description": "spectragraph_core.core.transform_base", + "isExtraImport": true, + "detail": "spectragraph_core.core.transform_base", + "documentation": {} + }, + { + "label": "Transform", + "importPath": "spectragraph_core.core.transform_base", + "description": "spectragraph_core.core.transform_base", + "isExtraImport": true, + "detail": "spectragraph_core.core.transform_base", + "documentation": {} + }, + { + "label": "Transform", + "importPath": "spectragraph_core.core.transform_base", + "description": "spectragraph_core.core.transform_base", + "isExtraImport": true, + "detail": "spectragraph_core.core.transform_base", + "documentation": {} + }, + { + "label": "Transform", + "importPath": "spectragraph_core.core.transform_base", + "description": "spectragraph_core.core.transform_base", + "isExtraImport": true, + "detail": "spectragraph_core.core.transform_base", + "documentation": {} + }, + { + "label": "Transform", + "importPath": "spectragraph_core.core.transform_base", + "description": "spectragraph_core.core.transform_base", + "isExtraImport": true, + "detail": "spectragraph_core.core.transform_base", + "documentation": {} + }, + { + "label": "Transform", + "importPath": "spectragraph_core.core.transform_base", + "description": "spectragraph_core.core.transform_base", + "isExtraImport": true, + "detail": "spectragraph_core.core.transform_base", + "documentation": {} + }, + { + "label": "Transform", + "importPath": "spectragraph_core.core.transform_base", + "description": "spectragraph_core.core.transform_base", + "isExtraImport": true, + "detail": "spectragraph_core.core.transform_base", + "documentation": {} + }, + { + "label": "Transform", + "importPath": "spectragraph_core.core.transform_base", + "description": "spectragraph_core.core.transform_base", + "isExtraImport": true, + "detail": "spectragraph_core.core.transform_base", + "documentation": {} + }, + { + "label": "Transform", + "importPath": "spectragraph_core.core.transform_base", + "description": "spectragraph_core.core.transform_base", + "isExtraImport": true, + "detail": "spectragraph_core.core.transform_base", + "documentation": {} + }, + { + "label": "Transform", + "importPath": "spectragraph_core.core.transform_base", + "description": "spectragraph_core.core.transform_base", + "isExtraImport": true, + "detail": "spectragraph_core.core.transform_base", + "documentation": {} + }, + { + "label": "Transform", + "importPath": "spectragraph_core.core.transform_base", + "description": "spectragraph_core.core.transform_base", + "isExtraImport": true, + "detail": "spectragraph_core.core.transform_base", + "documentation": {} + }, + { + "label": "Transform", + "importPath": "spectragraph_core.core.transform_base", + "description": "spectragraph_core.core.transform_base", + "isExtraImport": true, + "detail": "spectragraph_core.core.transform_base", + "documentation": {} + }, + { + "label": "Transform", + "importPath": "spectragraph_core.core.transform_base", + "description": "spectragraph_core.core.transform_base", + "isExtraImport": true, + "detail": "spectragraph_core.core.transform_base", + "documentation": {} + }, + { + "label": "Transform", + "importPath": "spectragraph_core.core.transform_base", + "description": "spectragraph_core.core.transform_base", + "isExtraImport": true, + "detail": "spectragraph_core.core.transform_base", + "documentation": {} + }, + { + "label": "Transform", + "importPath": "spectragraph_core.core.transform_base", + "description": "spectragraph_core.core.transform_base", + "isExtraImport": true, + "detail": "spectragraph_core.core.transform_base", + "documentation": {} + }, + { + "label": "Transform", + "importPath": "spectragraph_core.core.transform_base", + "description": "spectragraph_core.core.transform_base", + "isExtraImport": true, + "detail": "spectragraph_core.core.transform_base", + "documentation": {} + }, + { + "label": "Transform", + "importPath": "spectragraph_core.core.transform_base", + "description": "spectragraph_core.core.transform_base", + "isExtraImport": true, + "detail": "spectragraph_core.core.transform_base", + "documentation": {} + }, + { + "label": "Transform", + "importPath": "spectragraph_core.core.transform_base", + "description": "spectragraph_core.core.transform_base", + "isExtraImport": true, + "detail": "spectragraph_core.core.transform_base", + "documentation": {} + }, + { + "label": "Transform", + "importPath": "spectragraph_core.core.transform_base", + "description": "spectragraph_core.core.transform_base", + "isExtraImport": true, + "detail": "spectragraph_core.core.transform_base", + "documentation": {} + }, + { + "label": "Transform", + "importPath": "spectragraph_core.core.transform_base", + "description": "spectragraph_core.core.transform_base", + "isExtraImport": true, + "detail": "spectragraph_core.core.transform_base", + "documentation": {} + }, + { + "label": "Transform", + "importPath": "spectragraph_core.core.transform_base", + "description": "spectragraph_core.core.transform_base", + "isExtraImport": true, + "detail": "spectragraph_core.core.transform_base", + "documentation": {} + }, + { + "label": "Transform", + "importPath": "spectragraph_core.core.transform_base", + "description": "spectragraph_core.core.transform_base", + "isExtraImport": true, + "detail": "spectragraph_core.core.transform_base", + "documentation": {} + }, + { + "label": "Transform", + "importPath": "spectragraph_core.core.transform_base", + "description": "spectragraph_core.core.transform_base", + "isExtraImport": true, + "detail": "spectragraph_core.core.transform_base", + "documentation": {} + }, + { + "label": "Transform", + "importPath": "spectragraph_core.core.transform_base", + "description": "spectragraph_core.core.transform_base", + "isExtraImport": true, + "detail": "spectragraph_core.core.transform_base", + "documentation": {} + }, + { + "label": "Transform", + "importPath": "spectragraph_core.core.transform_base", + "description": "spectragraph_core.core.transform_base", + "isExtraImport": true, + "detail": "spectragraph_core.core.transform_base", + "documentation": {} + }, + { + "label": "Transform", + "importPath": "spectragraph_core.core.transform_base", + "description": "spectragraph_core.core.transform_base", + "isExtraImport": true, + "detail": "spectragraph_core.core.transform_base", + "documentation": {} + }, + { + "label": "Transform", + "importPath": "spectragraph_core.core.transform_base", + "description": "spectragraph_core.core.transform_base", + "isExtraImport": true, + "detail": "spectragraph_core.core.transform_base", + "documentation": {} + }, + { + "label": "Transform", + "importPath": "spectragraph_core.core.transform_base", + "description": "spectragraph_core.core.transform_base", + "isExtraImport": true, + "detail": "spectragraph_core.core.transform_base", + "documentation": {} + }, + { + "label": "Transform", + "importPath": "spectragraph_core.core.transform_base", + "description": "spectragraph_core.core.transform_base", + "isExtraImport": true, + "detail": "spectragraph_core.core.transform_base", + "documentation": {} + }, + { + "label": "Transform", + "importPath": "spectragraph_core.core.transform_base", + "description": "spectragraph_core.core.transform_base", + "isExtraImport": true, + "detail": "spectragraph_core.core.transform_base", + "documentation": {} + }, + { + "label": "Transform", + "importPath": "spectragraph_core.core.transform_base", + "description": "spectragraph_core.core.transform_base", + "isExtraImport": true, + "detail": "spectragraph_core.core.transform_base", + "documentation": {} + }, + { + "label": "Transform", + "importPath": "spectragraph_core.core.transform_base", + "description": "spectragraph_core.core.transform_base", + "isExtraImport": true, + "detail": "spectragraph_core.core.transform_base", + "documentation": {} + }, + { + "label": "ABC", + "importPath": "abc", + "description": "abc", + "isExtraImport": true, + "detail": "abc", + "documentation": {} + }, + { + "label": "abstractmethod", + "importPath": "abc", + "description": "abc", + "isExtraImport": true, + "detail": "abc", + "documentation": {} + }, + { + "label": "ABC", + "importPath": "abc", + "description": "abc", + "isExtraImport": true, + "detail": "abc", + "documentation": {} + }, + { + "label": "abstractmethod", + "importPath": "abc", + "description": "abc", + "isExtraImport": true, + "detail": "abc", + "documentation": {} + }, + { + "label": "ConfigDict", + "importPath": "pydantic.config", + "description": "pydantic.config", + "isExtraImport": true, + "detail": "pydantic.config", + "documentation": {} + }, + { + "label": "warnings", + "kind": 6, + "isExtraImport": true, + "importPath": "warnings", + "description": "warnings", + "detail": "warnings", + "documentation": {} + }, + { + "label": "Str", + "importPath": "ast", + "description": "ast", + "isExtraImport": true, + "detail": "ast", + "documentation": {} + }, + { + "label": "base64", + "kind": 6, + "isExtraImport": true, + "importPath": "base64", + "description": "base64", + "detail": "base64", + "documentation": {} + }, + { + "label": "binascii", + "kind": 6, + "isExtraImport": true, + "importPath": "binascii", + "description": "binascii", + "detail": "binascii", + "documentation": {} + }, + { + "label": "HKDF", + "importPath": "cryptography.hazmat.primitives.kdf.hkdf", + "description": "cryptography.hazmat.primitives.kdf.hkdf", + "isExtraImport": true, + "detail": "cryptography.hazmat.primitives.kdf.hkdf", + "documentation": {} + }, + { + "label": "hashes", + "importPath": "cryptography.hazmat.primitives", + "description": "cryptography.hazmat.primitives", + "isExtraImport": true, + "detail": "cryptography.hazmat.primitives", + "documentation": {} + }, + { + "label": "AESGCM", + "importPath": "cryptography.hazmat.primitives.ciphers.aead", + "description": "cryptography.hazmat.primitives.ciphers.aead", + "isExtraImport": true, + "detail": "cryptography.hazmat.primitives.ciphers.aead", + "documentation": {} + }, + { + "label": "csv", + "kind": 6, + "isExtraImport": true, + "importPath": "csv", + "description": "csv", + "detail": "csv", + "documentation": {} + }, + { + "label": "io", + "kind": 6, + "isExtraImport": true, + "importPath": "io", + "description": "io", + "detail": "io", + "documentation": {} + }, + { + "label": "dataclass", + "importPath": "dataclasses", + "description": "dataclasses", + "isExtraImport": true, + "detail": "dataclasses", + "documentation": {} + }, + { + "label": "Path", + "importPath": "pathlib", + "description": "pathlib", + "isExtraImport": true, + "detail": "pathlib", + "documentation": {} + }, + { + "label": "Path", + "importPath": "pathlib", + "description": "pathlib", + "isExtraImport": true, + "detail": "pathlib", + "documentation": {} + }, + { + "label": "Path", + "importPath": "pathlib", + "description": "pathlib", + "isExtraImport": true, + "detail": "pathlib", + "documentation": {} + }, + { + "label": "Path", + "importPath": "pathlib", + "description": "pathlib", + "isExtraImport": true, + "detail": "pathlib", + "documentation": {} + }, + { + "label": "redis", + "kind": 6, + "isExtraImport": true, + "importPath": "redis", + "description": "redis", + "detail": "redis", + "documentation": {} + }, + { + "label": "pytest", + "kind": 6, + "isExtraImport": true, + "importPath": "pytest", + "description": "pytest", + "detail": "pytest", + "documentation": {} + }, + { + "label": "detect_entity_type", + "importPath": "spectragraph_core.imports.entity_detection", + "description": "spectragraph_core.imports.entity_detection", + "isExtraImport": true, + "detail": "spectragraph_core.imports.entity_detection", + "documentation": {} + }, + { + "label": "is_email", + "importPath": "spectragraph_core.imports.entity_detection", + "description": "spectragraph_core.imports.entity_detection", + "isExtraImport": true, + "detail": "spectragraph_core.imports.entity_detection", + "documentation": {} + }, + { + "label": "is_domain", + "importPath": "spectragraph_core.imports.entity_detection", + "description": "spectragraph_core.imports.entity_detection", + "isExtraImport": true, + "detail": "spectragraph_core.imports.entity_detection", + "documentation": {} + }, + { + "label": "is_ip_address", + "importPath": "spectragraph_core.imports.entity_detection", + "description": "spectragraph_core.imports.entity_detection", + "isExtraImport": true, + "detail": "spectragraph_core.imports.entity_detection", + "documentation": {} + }, + { + "label": "is_website", + "importPath": "spectragraph_core.imports.entity_detection", + "description": "spectragraph_core.imports.entity_detection", + "isExtraImport": true, + "detail": "spectragraph_core.imports.entity_detection", + "documentation": {} + }, + { + "label": "is_phone", + "importPath": "spectragraph_core.imports.entity_detection", + "description": "spectragraph_core.imports.entity_detection", + "isExtraImport": true, + "detail": "spectragraph_core.imports.entity_detection", + "documentation": {} + }, + { + "label": "is_asn", + "importPath": "spectragraph_core.imports.entity_detection", + "description": "spectragraph_core.imports.entity_detection", + "isExtraImport": true, + "detail": "spectragraph_core.imports.entity_detection", + "documentation": {} + }, + { + "label": "is_username", + "importPath": "spectragraph_core.imports.entity_detection", + "description": "spectragraph_core.imports.entity_detection", + "isExtraImport": true, + "detail": "spectragraph_core.imports.entity_detection", + "documentation": {} + }, + { + "label": "get_default_label", + "importPath": "spectragraph_core.imports.entity_detection", + "description": "spectragraph_core.imports.entity_detection", + "isExtraImport": true, + "detail": "spectragraph_core.imports.entity_detection", + "documentation": {} + }, + { + "label": "Mock", + "importPath": "unittest.mock", + "description": "unittest.mock", + "isExtraImport": true, + "detail": "unittest.mock", + "documentation": {} + }, + { + "label": "MagicMock", + "importPath": "unittest.mock", + "description": "unittest.mock", + "isExtraImport": true, + "detail": "unittest.mock", + "documentation": {} + }, + { + "label": "patch", + "importPath": "unittest.mock", + "description": "unittest.mock", + "isExtraImport": true, + "detail": "unittest.mock", + "documentation": {} + }, + { + "label": "Mock", + "importPath": "unittest.mock", + "description": "unittest.mock", + "isExtraImport": true, + "detail": "unittest.mock", + "documentation": {} + }, + { + "label": "MagicMock", + "importPath": "unittest.mock", + "description": "unittest.mock", + "isExtraImport": true, + "detail": "unittest.mock", + "documentation": {} + }, + { + "label": "MagicMock", + "importPath": "unittest.mock", + "description": "unittest.mock", + "isExtraImport": true, + "detail": "unittest.mock", + "documentation": {} + }, + { + "label": "call", + "importPath": "unittest.mock", + "description": "unittest.mock", + "isExtraImport": true, + "detail": "unittest.mock", + "documentation": {} + }, + { + "label": "patch", + "importPath": "unittest.mock", + "description": "unittest.mock", + "isExtraImport": true, + "detail": "unittest.mock", + "documentation": {} + }, + { + "label": "Mock", + "importPath": "unittest.mock", + "description": "unittest.mock", + "isExtraImport": true, + "detail": "unittest.mock", + "documentation": {} + }, + { + "label": "Mock", + "importPath": "unittest.mock", + "description": "unittest.mock", + "isExtraImport": true, + "detail": "unittest.mock", + "documentation": {} + }, + { + "label": "patch", + "importPath": "unittest.mock", + "description": "unittest.mock", + "isExtraImport": true, + "detail": "unittest.mock", + "documentation": {} + }, + { + "label": "patch", + "importPath": "unittest.mock", + "description": "unittest.mock", + "isExtraImport": true, + "detail": "unittest.mock", + "documentation": {} + }, + { + "label": "MagicMock", + "importPath": "unittest.mock", + "description": "unittest.mock", + "isExtraImport": true, + "detail": "unittest.mock", + "documentation": {} + }, + { + "label": "Mock", + "importPath": "unittest.mock", + "description": "unittest.mock", + "isExtraImport": true, + "detail": "unittest.mock", + "documentation": {} + }, + { + "label": "Mock", + "importPath": "unittest.mock", + "description": "unittest.mock", + "isExtraImport": true, + "detail": "unittest.mock", + "documentation": {} + }, + { + "label": "patch", + "importPath": "unittest.mock", + "description": "unittest.mock", + "isExtraImport": true, + "detail": "unittest.mock", + "documentation": {} + }, + { + "label": "AsyncMock", + "importPath": "unittest.mock", + "description": "unittest.mock", + "isExtraImport": true, + "detail": "unittest.mock", + "documentation": {} + }, + { + "label": "patch", + "importPath": "unittest.mock", + "description": "unittest.mock", + "isExtraImport": true, + "detail": "unittest.mock", + "documentation": {} + }, + { + "label": "MagicMock", + "importPath": "unittest.mock", + "description": "unittest.mock", + "isExtraImport": true, + "detail": "unittest.mock", + "documentation": {} + }, + { + "label": "Mock", + "importPath": "unittest.mock", + "description": "unittest.mock", + "isExtraImport": true, + "detail": "unittest.mock", + "documentation": {} + }, + { + "label": "MagicMock", + "importPath": "unittest.mock", + "description": "unittest.mock", + "isExtraImport": true, + "detail": "unittest.mock", + "documentation": {} + }, + { + "label": "CIDR", + "importPath": "spectragraph_types.cidr", + "description": "spectragraph_types.cidr", + "isExtraImport": true, + "detail": "spectragraph_types.cidr", + "documentation": {} + }, + { + "label": "CIDR", + "importPath": "spectragraph_types.cidr", + "description": "spectragraph_types.cidr", + "isExtraImport": true, + "detail": "spectragraph_types.cidr", + "documentation": {} + }, + { + "label": "CIDR", + "importPath": "spectragraph_types.cidr", + "description": "spectragraph_types.cidr", + "isExtraImport": true, + "detail": "spectragraph_types.cidr", + "documentation": {} + }, + { + "label": "CIDR", + "importPath": "spectragraph_types.cidr", + "description": "spectragraph_types.cidr", + "isExtraImport": true, + "detail": "spectragraph_types.cidr", + "documentation": {} + }, + { + "label": "ASN", + "importPath": "spectragraph_types.asn", + "description": "spectragraph_types.asn", + "isExtraImport": true, + "detail": "spectragraph_types.asn", + "documentation": {} + }, + { + "label": "ASN", + "importPath": "spectragraph_types.asn", + "description": "spectragraph_types.asn", + "isExtraImport": true, + "detail": "spectragraph_types.asn", + "documentation": {} + }, + { + "label": "ASN", + "importPath": "spectragraph_types.asn", + "description": "spectragraph_types.asn", + "isExtraImport": true, + "detail": "spectragraph_types.asn", + "documentation": {} + }, + { + "label": "ASN", + "importPath": "spectragraph_types.asn", + "description": "spectragraph_types.asn", + "isExtraImport": true, + "detail": "spectragraph_types.asn", + "documentation": {} + }, + { + "label": "ASN", + "importPath": "spectragraph_types.asn", + "description": "spectragraph_types.asn", + "isExtraImport": true, + "detail": "spectragraph_types.asn", + "documentation": {} + }, + { + "label": "ASN", + "importPath": "spectragraph_types.asn", + "description": "spectragraph_types.asn", + "isExtraImport": true, + "detail": "spectragraph_types.asn", + "documentation": {} + }, + { + "label": "Logger", + "importPath": "spectragraph_core.core.logger", + "description": "spectragraph_core.core.logger", + "isExtraImport": true, + "detail": "spectragraph_core.core.logger", + "documentation": {} + }, + { + "label": "Logger", + "importPath": "spectragraph_core.core.logger", + "description": "spectragraph_core.core.logger", + "isExtraImport": true, + "detail": "spectragraph_core.core.logger", + "documentation": {} + }, + { + "label": "Logger", + "importPath": "spectragraph_core.core.logger", + "description": "spectragraph_core.core.logger", + "isExtraImport": true, + "detail": "spectragraph_core.core.logger", + "documentation": {} + }, + { + "label": "Logger", + "importPath": "spectragraph_core.core.logger", + "description": "spectragraph_core.core.logger", + "isExtraImport": true, + "detail": "spectragraph_core.core.logger", + "documentation": {} + }, + { + "label": "Logger", + "importPath": "spectragraph_core.core.logger", + "description": "spectragraph_core.core.logger", + "isExtraImport": true, + "detail": "spectragraph_core.core.logger", + "documentation": {} + }, + { + "label": "Logger", + "importPath": "spectragraph_core.core.logger", + "description": "spectragraph_core.core.logger", + "isExtraImport": true, + "detail": "spectragraph_core.core.logger", + "documentation": {} + }, + { + "label": "Logger", + "importPath": "spectragraph_core.core.logger", + "description": "spectragraph_core.core.logger", + "isExtraImport": true, + "detail": "spectragraph_core.core.logger", + "documentation": {} + }, + { + "label": "Logger", + "importPath": "spectragraph_core.core.logger", + "description": "spectragraph_core.core.logger", + "isExtraImport": true, + "detail": "spectragraph_core.core.logger", + "documentation": {} + }, + { + "label": "Logger", + "importPath": "spectragraph_core.core.logger", + "description": "spectragraph_core.core.logger", + "isExtraImport": true, + "detail": "spectragraph_core.core.logger", + "documentation": {} + }, + { + "label": "Logger", + "importPath": "spectragraph_core.core.logger", + "description": "spectragraph_core.core.logger", + "isExtraImport": true, + "detail": "spectragraph_core.core.logger", + "documentation": {} + }, + { + "label": "Logger", + "importPath": "spectragraph_core.core.logger", + "description": "spectragraph_core.core.logger", + "isExtraImport": true, + "detail": "spectragraph_core.core.logger", + "documentation": {} + }, + { + "label": "Logger", + "importPath": "spectragraph_core.core.logger", + "description": "spectragraph_core.core.logger", + "isExtraImport": true, + "detail": "spectragraph_core.core.logger", + "documentation": {} + }, + { + "label": "Logger", + "importPath": "spectragraph_core.core.logger", + "description": "spectragraph_core.core.logger", + "isExtraImport": true, + "detail": "spectragraph_core.core.logger", + "documentation": {} + }, + { + "label": "Logger", + "importPath": "spectragraph_core.core.logger", + "description": "spectragraph_core.core.logger", + "isExtraImport": true, + "detail": "spectragraph_core.core.logger", + "documentation": {} + }, + { + "label": "Logger", + "importPath": "spectragraph_core.core.logger", + "description": "spectragraph_core.core.logger", + "isExtraImport": true, + "detail": "spectragraph_core.core.logger", + "documentation": {} + }, + { + "label": "Logger", + "importPath": "spectragraph_core.core.logger", + "description": "spectragraph_core.core.logger", + "isExtraImport": true, + "detail": "spectragraph_core.core.logger", + "documentation": {} + }, + { + "label": "Logger", + "importPath": "spectragraph_core.core.logger", + "description": "spectragraph_core.core.logger", + "isExtraImport": true, + "detail": "spectragraph_core.core.logger", + "documentation": {} + }, + { + "label": "Logger", + "importPath": "spectragraph_core.core.logger", + "description": "spectragraph_core.core.logger", + "isExtraImport": true, + "detail": "spectragraph_core.core.logger", + "documentation": {} + }, + { + "label": "Logger", + "importPath": "spectragraph_core.core.logger", + "description": "spectragraph_core.core.logger", + "isExtraImport": true, + "detail": "spectragraph_core.core.logger", + "documentation": {} + }, + { + "label": "Logger", + "importPath": "spectragraph_core.core.logger", + "description": "spectragraph_core.core.logger", + "isExtraImport": true, + "detail": "spectragraph_core.core.logger", + "documentation": {} + }, + { + "label": "Logger", + "importPath": "spectragraph_core.core.logger", + "description": "spectragraph_core.core.logger", + "isExtraImport": true, + "detail": "spectragraph_core.core.logger", + "documentation": {} + }, + { + "label": "Logger", + "importPath": "spectragraph_core.core.logger", + "description": "spectragraph_core.core.logger", + "isExtraImport": true, + "detail": "spectragraph_core.core.logger", + "documentation": {} + }, + { + "label": "Logger", + "importPath": "spectragraph_core.core.logger", + "description": "spectragraph_core.core.logger", + "isExtraImport": true, + "detail": "spectragraph_core.core.logger", + "documentation": {} + }, + { + "label": "Logger", + "importPath": "spectragraph_core.core.logger", + "description": "spectragraph_core.core.logger", + "isExtraImport": true, + "detail": "spectragraph_core.core.logger", + "documentation": {} + }, + { + "label": "Logger", + "importPath": "spectragraph_core.core.logger", + "description": "spectragraph_core.core.logger", + "isExtraImport": true, + "detail": "spectragraph_core.core.logger", + "documentation": {} + }, + { + "label": "Logger", + "importPath": "spectragraph_core.core.logger", + "description": "spectragraph_core.core.logger", + "isExtraImport": true, + "detail": "spectragraph_core.core.logger", + "documentation": {} + }, + { + "label": "Logger", + "importPath": "spectragraph_core.core.logger", + "description": "spectragraph_core.core.logger", + "isExtraImport": true, + "detail": "spectragraph_core.core.logger", + "documentation": {} + }, + { + "label": "Logger", + "importPath": "spectragraph_core.core.logger", + "description": "spectragraph_core.core.logger", + "isExtraImport": true, + "detail": "spectragraph_core.core.logger", + "documentation": {} + }, + { + "label": "Logger", + "importPath": "spectragraph_core.core.logger", + "description": "spectragraph_core.core.logger", + "isExtraImport": true, + "detail": "spectragraph_core.core.logger", + "documentation": {} + }, + { + "label": "Logger", + "importPath": "spectragraph_core.core.logger", + "description": "spectragraph_core.core.logger", + "isExtraImport": true, + "detail": "spectragraph_core.core.logger", + "documentation": {} + }, + { + "label": "Logger", + "importPath": "spectragraph_core.core.logger", + "description": "spectragraph_core.core.logger", + "isExtraImport": true, + "detail": "spectragraph_core.core.logger", + "documentation": {} + }, + { + "label": "Logger", + "importPath": "spectragraph_core.core.logger", + "description": "spectragraph_core.core.logger", + "isExtraImport": true, + "detail": "spectragraph_core.core.logger", + "documentation": {} + }, + { + "label": "AsnmapTool", + "importPath": "tools.network.asnmap", + "description": "tools.network.asnmap", + "isExtraImport": true, + "detail": "tools.network.asnmap", + "documentation": {} + }, + { + "label": "AsnmapTool", + "importPath": "tools.network.asnmap", + "description": "tools.network.asnmap", + "isExtraImport": true, + "detail": "tools.network.asnmap", + "documentation": {} + }, + { + "label": "AsnmapTool", + "importPath": "tools.network.asnmap", + "description": "tools.network.asnmap", + "isExtraImport": true, + "detail": "tools.network.asnmap", + "documentation": {} + }, + { + "label": "AsnmapTool", + "importPath": "tools.network.asnmap", + "description": "tools.network.asnmap", + "isExtraImport": true, + "detail": "tools.network.asnmap", + "documentation": {} + }, + { + "label": "Ip", + "importPath": "spectragraph_types.ip", + "description": "spectragraph_types.ip", + "isExtraImport": true, + "detail": "spectragraph_types.ip", + "documentation": {} + }, + { + "label": "Ip", + "importPath": "spectragraph_types.ip", + "description": "spectragraph_types.ip", + "isExtraImport": true, + "detail": "spectragraph_types.ip", + "documentation": {} + }, + { + "label": "Ip", + "importPath": "spectragraph_types.ip", + "description": "spectragraph_types.ip", + "isExtraImport": true, + "detail": "spectragraph_types.ip", + "documentation": {} + }, + { + "label": "Ip", + "importPath": "spectragraph_types.ip", + "description": "spectragraph_types.ip", + "isExtraImport": true, + "detail": "spectragraph_types.ip", + "documentation": {} + }, + { + "label": "Ip", + "importPath": "spectragraph_types.ip", + "description": "spectragraph_types.ip", + "isExtraImport": true, + "detail": "spectragraph_types.ip", + "documentation": {} + }, + { + "label": "Ip", + "importPath": "spectragraph_types.ip", + "description": "spectragraph_types.ip", + "isExtraImport": true, + "detail": "spectragraph_types.ip", + "documentation": {} + }, + { + "label": "Ip", + "importPath": "spectragraph_types.ip", + "description": "spectragraph_types.ip", + "isExtraImport": true, + "detail": "spectragraph_types.ip", + "documentation": {} + }, + { + "label": "Ip", + "importPath": "spectragraph_types.ip", + "description": "spectragraph_types.ip", + "isExtraImport": true, + "detail": "spectragraph_types.ip", + "documentation": {} + }, + { + "label": "Ip", + "importPath": "spectragraph_types.ip", + "description": "spectragraph_types.ip", + "isExtraImport": true, + "detail": "spectragraph_types.ip", + "documentation": {} + }, + { + "label": "Ip", + "importPath": "spectragraph_types.ip", + "description": "spectragraph_types.ip", + "isExtraImport": true, + "detail": "spectragraph_types.ip", + "documentation": {} + }, + { + "label": "Ip", + "importPath": "spectragraph_types.ip", + "description": "spectragraph_types.ip", + "isExtraImport": true, + "detail": "spectragraph_types.ip", + "documentation": {} + }, + { + "label": "Ip", + "importPath": "spectragraph_types.ip", + "description": "spectragraph_types.ip", + "isExtraImport": true, + "detail": "spectragraph_types.ip", + "documentation": {} + }, + { + "label": "MapcidrTool", + "importPath": "tools.network.mapcidr", + "description": "tools.network.mapcidr", + "isExtraImport": true, + "detail": "tools.network.mapcidr", + "documentation": {} + }, + { + "label": "requests", + "kind": 6, + "isExtraImport": true, + "importPath": "requests", + "description": "requests", + "detail": "requests", + "documentation": {} + }, + { + "label": "CryptoWallet", + "importPath": "spectragraph_types.wallet", + "description": "spectragraph_types.wallet", + "isExtraImport": true, + "detail": "spectragraph_types.wallet", + "documentation": {} + }, + { + "label": "CryptoNFT", + "importPath": "spectragraph_types.wallet", + "description": "spectragraph_types.wallet", + "isExtraImport": true, + "detail": "spectragraph_types.wallet", + "documentation": {} + }, + { + "label": "CryptoWallet", + "importPath": "spectragraph_types.wallet", + "description": "spectragraph_types.wallet", + "isExtraImport": true, + "detail": "spectragraph_types.wallet", + "documentation": {} + }, + { + "label": "CryptoWalletTransaction", + "importPath": "spectragraph_types.wallet", + "description": "spectragraph_types.wallet", + "isExtraImport": true, + "detail": "spectragraph_types.wallet", + "documentation": {} + }, + { + "label": "CryptoWallet", + "importPath": "spectragraph_types.wallet", + "description": "spectragraph_types.wallet", + "isExtraImport": true, + "detail": "spectragraph_types.wallet", + "documentation": {} + }, + { + "label": "CryptoNFT", + "importPath": "spectragraph_types.wallet", + "description": "spectragraph_types.wallet", + "isExtraImport": true, + "detail": "spectragraph_types.wallet", + "documentation": {} + }, + { + "label": "CryptoWallet", + "importPath": "spectragraph_types.wallet", + "description": "spectragraph_types.wallet", + "isExtraImport": true, + "detail": "spectragraph_types.wallet", + "documentation": {} + }, + { + "label": "CryptoWalletTransaction", + "importPath": "spectragraph_types.wallet", + "description": "spectragraph_types.wallet", + "isExtraImport": true, + "detail": "spectragraph_types.wallet", + "documentation": {} + }, + { + "label": "requests.exceptions", + "kind": 6, + "isExtraImport": true, + "importPath": "requests.exceptions", + "description": "requests.exceptions", + "detail": "requests.exceptions", + "documentation": {} + }, + { + "label": "Domain", + "importPath": "spectragraph_types.domain", + "description": "spectragraph_types.domain", + "isExtraImport": true, + "detail": "spectragraph_types.domain", + "documentation": {} + }, + { + "label": "Domain", + "importPath": "spectragraph_types.domain", + "description": "spectragraph_types.domain", + "isExtraImport": true, + "detail": "spectragraph_types.domain", + "documentation": {} + }, + { + "label": "Domain", + "importPath": "spectragraph_types.domain", + "description": "spectragraph_types.domain", + "isExtraImport": true, + "detail": "spectragraph_types.domain", + "documentation": {} + }, + { + "label": "Domain", + "importPath": "spectragraph_types.domain", + "description": "spectragraph_types.domain", + "isExtraImport": true, + "detail": "spectragraph_types.domain", + "documentation": {} + }, + { + "label": "Domain", + "importPath": "spectragraph_types.domain", + "description": "spectragraph_types.domain", + "isExtraImport": true, + "detail": "spectragraph_types.domain", + "documentation": {} + }, + { + "label": "Domain", + "importPath": "spectragraph_types.domain", + "description": "spectragraph_types.domain", + "isExtraImport": true, + "detail": "spectragraph_types.domain", + "documentation": {} + }, + { + "label": "Domain", + "importPath": "spectragraph_types.domain", + "description": "spectragraph_types.domain", + "isExtraImport": true, + "detail": "spectragraph_types.domain", + "documentation": {} + }, + { + "label": "Domain", + "importPath": "spectragraph_types.domain", + "description": "spectragraph_types.domain", + "isExtraImport": true, + "detail": "spectragraph_types.domain", + "documentation": {} + }, + { + "label": "Domain", + "importPath": "spectragraph_types.domain", + "description": "spectragraph_types.domain", + "isExtraImport": true, + "detail": "spectragraph_types.domain", + "documentation": {} + }, + { + "label": "Domain", + "importPath": "spectragraph_types.domain", + "description": "spectragraph_types.domain", + "isExtraImport": true, + "detail": "spectragraph_types.domain", + "documentation": {} + }, + { + "label": "Domain", + "importPath": "spectragraph_types.domain", + "description": "spectragraph_types.domain", + "isExtraImport": true, + "detail": "spectragraph_types.domain", + "documentation": {} + }, + { + "label": "Domain", + "importPath": "spectragraph_types.domain", + "description": "spectragraph_types.domain", + "isExtraImport": true, + "detail": "spectragraph_types.domain", + "documentation": {} + }, + { + "label": "Domain", + "importPath": "spectragraph_types.domain", + "description": "spectragraph_types.domain", + "isExtraImport": true, + "detail": "spectragraph_types.domain", + "documentation": {} + }, + { + "label": "Domain", + "importPath": "spectragraph_types.domain", + "description": "spectragraph_types.domain", + "isExtraImport": true, + "detail": "spectragraph_types.domain", + "documentation": {} + }, + { + "label": "Domain", + "importPath": "spectragraph_types.domain", + "description": "spectragraph_types.domain", + "isExtraImport": true, + "detail": "spectragraph_types.domain", + "documentation": {} + }, + { + "label": "Domain", + "importPath": "spectragraph_types.domain", + "description": "spectragraph_types.domain", + "isExtraImport": true, + "detail": "spectragraph_types.domain", + "documentation": {} + }, + { + "label": "Domain", + "importPath": "spectragraph_types.domain", + "description": "spectragraph_types.domain", + "isExtraImport": true, + "detail": "spectragraph_types.domain", + "documentation": {} + }, + { + "label": "Domain", + "importPath": "spectragraph_types.domain", + "description": "spectragraph_types.domain", + "isExtraImport": true, + "detail": "spectragraph_types.domain", + "documentation": {} + }, + { + "label": "Domain", + "importPath": "spectragraph_types.domain", + "description": "spectragraph_types.domain", + "isExtraImport": true, + "detail": "spectragraph_types.domain", + "documentation": {} + }, + { + "label": "Individual", + "importPath": "spectragraph_types.individual", + "description": "spectragraph_types.individual", + "isExtraImport": true, + "detail": "spectragraph_types.individual", + "documentation": {} + }, + { + "label": "Individual", + "importPath": "spectragraph_types.individual", + "description": "spectragraph_types.individual", + "isExtraImport": true, + "detail": "spectragraph_types.individual", + "documentation": {} + }, + { + "label": "Individual", + "importPath": "spectragraph_types.individual", + "description": "spectragraph_types.individual", + "isExtraImport": true, + "detail": "spectragraph_types.individual", + "documentation": {} + }, + { + "label": "Individual", + "importPath": "spectragraph_types.individual", + "description": "spectragraph_types.individual", + "isExtraImport": true, + "detail": "spectragraph_types.individual", + "documentation": {} + }, + { + "label": "Individual", + "importPath": "spectragraph_types.individual", + "description": "spectragraph_types.individual", + "isExtraImport": true, + "detail": "spectragraph_types.individual", + "documentation": {} + }, + { + "label": "Organization", + "importPath": "spectragraph_types.organization", + "description": "spectragraph_types.organization", + "isExtraImport": true, + "detail": "spectragraph_types.organization", + "documentation": {} + }, + { + "label": "Organization", + "importPath": "spectragraph_types.organization", + "description": "spectragraph_types.organization", + "isExtraImport": true, + "detail": "spectragraph_types.organization", + "documentation": {} + }, + { + "label": "Organization", + "importPath": "spectragraph_types.organization", + "description": "spectragraph_types.organization", + "isExtraImport": true, + "detail": "spectragraph_types.organization", + "documentation": {} + }, + { + "label": "Organization", + "importPath": "spectragraph_types.organization", + "description": "spectragraph_types.organization", + "isExtraImport": true, + "detail": "spectragraph_types.organization", + "documentation": {} + }, + { + "label": "Organization", + "importPath": "spectragraph_types.organization", + "description": "spectragraph_types.organization", + "isExtraImport": true, + "detail": "spectragraph_types.organization", + "documentation": {} + }, + { + "label": "Organization", + "importPath": "spectragraph_types.organization", + "description": "spectragraph_types.organization", + "isExtraImport": true, + "detail": "spectragraph_types.organization", + "documentation": {} + }, + { + "label": "Organization", + "importPath": "spectragraph_types.organization", + "description": "spectragraph_types.organization", + "isExtraImport": true, + "detail": "spectragraph_types.organization", + "documentation": {} + }, + { + "label": "Location", + "importPath": "spectragraph_types.address", + "description": "spectragraph_types.address", + "isExtraImport": true, + "detail": "spectragraph_types.address", + "documentation": {} + }, + { + "label": "Location", + "importPath": "spectragraph_types.address", + "description": "spectragraph_types.address", + "isExtraImport": true, + "detail": "spectragraph_types.address", + "documentation": {} + }, + { + "label": "Location", + "importPath": "spectragraph_types.address", + "description": "spectragraph_types.address", + "isExtraImport": true, + "detail": "spectragraph_types.address", + "documentation": {} + }, + { + "label": "Location", + "importPath": "spectragraph_types.address", + "description": "spectragraph_types.address", + "isExtraImport": true, + "detail": "spectragraph_types.address", + "documentation": {} + }, + { + "label": "WhoxyTool", + "importPath": "tools.network.whoxy", + "description": "tools.network.whoxy", + "isExtraImport": true, + "detail": "tools.network.whoxy", + "documentation": {} + }, + { + "label": "WhoxyTool", + "importPath": "tools.network.whoxy", + "description": "tools.network.whoxy", + "isExtraImport": true, + "detail": "tools.network.whoxy", + "documentation": {} + }, + { + "label": "WhoxyTool", + "importPath": "tools.network.whoxy", + "description": "tools.network.whoxy", + "isExtraImport": true, + "detail": "tools.network.whoxy", + "documentation": {} + }, + { + "label": "WhoxyTool", + "importPath": "tools.network.whoxy", + "description": "tools.network.whoxy", + "isExtraImport": true, + "detail": "tools.network.whoxy", + "documentation": {} + }, + { + "label": "WhoxyTool", + "importPath": "tools.network.whoxy", + "description": "tools.network.whoxy", + "isExtraImport": true, + "detail": "tools.network.whoxy", + "documentation": {} + }, + { + "label": "is_valid_domain", + "importPath": "spectragraph_transforms.utils", + "description": "spectragraph_transforms.utils", + "isExtraImport": true, + "detail": "spectragraph_transforms.utils", + "documentation": {} + }, + { + "label": "get_root_domain", + "importPath": "spectragraph_transforms.utils", + "description": "spectragraph_transforms.utils", + "isExtraImport": true, + "detail": "spectragraph_transforms.utils", + "documentation": {} + }, + { + "label": "SubfinderTool", + "importPath": "tools.network.subfinder", + "description": "tools.network.subfinder", + "isExtraImport": true, + "detail": "tools.network.subfinder", + "documentation": {} + }, + { + "label": "SubfinderTool", + "importPath": "tools.network.subfinder", + "description": "tools.network.subfinder", + "isExtraImport": true, + "detail": "tools.network.subfinder", + "documentation": {} + }, + { + "label": "Website", + "importPath": "spectragraph_types.website", + "description": "spectragraph_types.website", + "isExtraImport": true, + "detail": "spectragraph_types.website", + "documentation": {} + }, + { + "label": "Website", + "importPath": "spectragraph_types.website", + "description": "spectragraph_types.website", + "isExtraImport": true, + "detail": "spectragraph_types.website", + "documentation": {} + }, + { + "label": "Website", + "importPath": "spectragraph_types.website", + "description": "spectragraph_types.website", + "isExtraImport": true, + "detail": "spectragraph_types.website", + "documentation": {} + }, + { + "label": "Website", + "importPath": "spectragraph_types.website", + "description": "spectragraph_types.website", + "isExtraImport": true, + "detail": "spectragraph_types.website", + "documentation": {} + }, + { + "label": "Website", + "importPath": "spectragraph_types.website", + "description": "spectragraph_types.website", + "isExtraImport": true, + "detail": "spectragraph_types.website", + "documentation": {} + }, + { + "label": "Website", + "importPath": "spectragraph_types.website", + "description": "spectragraph_types.website", + "isExtraImport": true, + "detail": "spectragraph_types.website", + "documentation": {} + }, + { + "label": "Website", + "importPath": "spectragraph_types.website", + "description": "spectragraph_types.website", + "isExtraImport": true, + "detail": "spectragraph_types.website", + "documentation": {} + }, + { + "label": "whois", + "kind": 6, + "isExtraImport": true, + "importPath": "whois", + "description": "whois", + "detail": "whois", + "documentation": {} + }, + { + "label": "Whois", + "importPath": "spectragraph_types.whois", + "description": "spectragraph_types.whois", + "isExtraImport": true, + "detail": "spectragraph_types.whois", + "documentation": {} + }, + { + "label": "Email", + "importPath": "spectragraph_types.email", + "description": "spectragraph_types.email", + "isExtraImport": true, + "detail": "spectragraph_types.email", + "documentation": {} + }, + { + "label": "Email", + "importPath": "spectragraph_types.email", + "description": "spectragraph_types.email", + "isExtraImport": true, + "detail": "spectragraph_types.email", + "documentation": {} + }, + { + "label": "Email", + "importPath": "spectragraph_types.email", + "description": "spectragraph_types.email", + "isExtraImport": true, + "detail": "spectragraph_types.email", + "documentation": {} + }, + { + "label": "Email", + "importPath": "spectragraph_types.email", + "description": "spectragraph_types.email", + "isExtraImport": true, + "detail": "spectragraph_types.email", + "documentation": {} + }, + { + "label": "Email", + "importPath": "spectragraph_types.email", + "description": "spectragraph_types.email", + "isExtraImport": true, + "detail": "spectragraph_types.email", + "documentation": {} + }, + { + "label": "Email", + "importPath": "spectragraph_types.email", + "description": "spectragraph_types.email", + "isExtraImport": true, + "detail": "spectragraph_types.email", + "documentation": {} + }, + { + "label": "Email", + "importPath": "spectragraph_types.email", + "description": "spectragraph_types.email", + "isExtraImport": true, + "detail": "spectragraph_types.email", + "documentation": {} + }, + { + "label": "Gravatar", + "importPath": "spectragraph_types.gravatar", + "description": "spectragraph_types.gravatar", + "isExtraImport": true, + "detail": "spectragraph_types.gravatar", + "documentation": {} + }, + { + "label": "Gravatar", + "importPath": "spectragraph_types.gravatar", + "description": "spectragraph_types.gravatar", + "isExtraImport": true, + "detail": "spectragraph_types.gravatar", + "documentation": {} + }, + { + "label": "Breach", + "importPath": "spectragraph_types.breach", + "description": "spectragraph_types.breach", + "isExtraImport": true, + "detail": "spectragraph_types.breach", + "documentation": {} + }, + { + "label": "Breach", + "importPath": "spectragraph_types.breach", + "description": "spectragraph_types.breach", + "isExtraImport": true, + "detail": "spectragraph_types.breach", + "documentation": {} + }, + { + "label": "Breach", + "importPath": "spectragraph_types.breach", + "description": "spectragraph_types.breach", + "isExtraImport": true, + "detail": "spectragraph_types.breach", + "documentation": {} + }, + { + "label": "SireneTool", + "importPath": "tools.organizations.sirene", + "description": "tools.organizations.sirene", + "isExtraImport": true, + "detail": "tools.organizations.sirene", + "documentation": {} + }, + { + "label": "SireneTool", + "importPath": "tools.organizations.sirene", + "description": "tools.organizations.sirene", + "isExtraImport": true, + "detail": "tools.organizations.sirene", + "documentation": {} + }, + { + "label": "SireneTool", + "importPath": "tools.organizations.sirene", + "description": "tools.organizations.sirene", + "isExtraImport": true, + "detail": "tools.organizations.sirene", + "documentation": {} + }, + { + "label": "hibpwned", + "kind": 6, + "isExtraImport": true, + "importPath": "hibpwned", + "description": "hibpwned", + "detail": "hibpwned", + "documentation": {} + }, + { + "label": "aiohttp", + "kind": 6, + "isExtraImport": true, + "importPath": "aiohttp", + "description": "aiohttp", + "detail": "aiohttp", + "documentation": {} + }, + { + "label": "subprocess", + "kind": 6, + "isExtraImport": true, + "importPath": "subprocess", + "description": "subprocess", + "detail": "subprocess", + "documentation": {} + }, + { + "label": "Phone", + "importPath": "spectragraph_types.phone", + "description": "spectragraph_types.phone", + "isExtraImport": true, + "detail": "spectragraph_types.phone", + "documentation": {} + }, + { + "label": "Phone", + "importPath": "spectragraph_types.phone", + "description": "spectragraph_types.phone", + "isExtraImport": true, + "detail": "spectragraph_types.phone", + "documentation": {} + }, + { + "label": "Phone", + "importPath": "spectragraph_types.phone", + "description": "spectragraph_types.phone", + "isExtraImport": true, + "detail": "spectragraph_types.phone", + "documentation": {} + }, + { + "label": "httpx", + "kind": 6, + "isExtraImport": true, + "importPath": "httpx", + "description": "httpx", + "detail": "httpx", + "documentation": {} + }, + { + "label": "TransformError", + "importPath": "spectragraph_core.exceptions", + "description": "spectragraph_core.exceptions", + "isExtraImport": true, + "detail": "spectragraph_core.exceptions", + "documentation": {} + }, + { + "label": "TransformError", + "importPath": "spectragraph_core.exceptions", + "description": "spectragraph_core.exceptions", + "isExtraImport": true, + "detail": "spectragraph_core.exceptions", + "documentation": {} + }, + { + "label": "SocialProfile", + "importPath": "spectragraph_types.social", + "description": "spectragraph_types.social", + "isExtraImport": true, + "detail": "spectragraph_types.social", + "documentation": {} + }, + { + "label": "SocialProfile", + "importPath": "spectragraph_types.social", + "description": "spectragraph_types.social", + "isExtraImport": true, + "detail": "spectragraph_types.social", + "documentation": {} + }, + { + "label": "SocialProfile", + "importPath": "spectragraph_types.social", + "description": "spectragraph_types.social", + "isExtraImport": true, + "detail": "spectragraph_types.social", + "documentation": {} + }, + { + "label": "ReconCrawlTool", + "importPath": "tools.network.reconcrawl", + "description": "tools.network.reconcrawl", + "isExtraImport": true, + "detail": "tools.network.reconcrawl", + "documentation": {} + }, + { + "label": "ReconCrawlTool", + "importPath": "tools.network.reconcrawl", + "description": "tools.network.reconcrawl", + "isExtraImport": true, + "detail": "tools.network.reconcrawl", + "documentation": {} + }, + { + "label": "Crawler", + "importPath": "reconspread", + "description": "reconspread", + "isExtraImport": true, + "detail": "reconspread", + "documentation": {} + }, + { + "label": "Phrase", + "importPath": "spectragraph_types.phrase", + "description": "spectragraph_types.phrase", + "isExtraImport": true, + "detail": "spectragraph_types.phrase", + "documentation": {} + }, + { + "label": "BeautifulSoup", + "importPath": "bs4", + "description": "bs4", + "isExtraImport": true, + "detail": "bs4", + "documentation": {} + }, + { + "label": "WebTracker", + "importPath": "spectragraph_types.web_tracker", + "description": "spectragraph_types.web_tracker", + "isExtraImport": true, + "detail": "spectragraph_types.web_tracker", + "documentation": {} + }, + { + "label": "TrackingCodeExtractor", + "importPath": "recontrack", + "description": "recontrack", + "isExtraImport": true, + "detail": "recontrack", + "documentation": {} + }, + { + "label": "from_env", + "importPath": "docker", + "description": "docker", + "isExtraImport": true, + "detail": "docker", + "documentation": {} + }, + { + "label": "DockerClient", + "importPath": "docker", + "description": "docker", + "isExtraImport": true, + "detail": "docker", + "documentation": {} + }, + { + "label": "ImageNotFound", + "importPath": "docker.errors", + "description": "docker.errors", + "isExtraImport": true, + "detail": "docker.errors", + "documentation": {} + }, + { + "label": "APIError", + "importPath": "docker.errors", + "description": "docker.errors", + "isExtraImport": true, + "detail": "docker.errors", + "documentation": {} + }, + { + "label": "DockerException", + "importPath": "docker.errors", + "description": "docker.errors", + "isExtraImport": true, + "detail": "docker.errors", + "documentation": {} + }, + { + "label": "HttpxTool", + "importPath": "tools.network.httpx", + "description": "tools.network.httpx", + "isExtraImport": true, + "detail": "tools.network.httpx", + "documentation": {} + }, + { + "label": "CryptoWalletAddressToNFTs", + "importPath": "spectragraph_transforms.crypto.wallet_to_nfts", + "description": "spectragraph_transforms.crypto.wallet_to_nfts", + "isExtraImport": true, + "detail": "spectragraph_transforms.crypto.wallet_to_nfts", + "documentation": {} + }, + { + "label": "CryptoWalletAddressToTransactions", + "importPath": "spectragraph_transforms.crypto.wallet_to_transactions", + "description": "spectragraph_transforms.crypto.wallet_to_transactions", + "isExtraImport": true, + "detail": "spectragraph_transforms.crypto.wallet_to_transactions", + "documentation": {} + }, + { + "label": "ResolveTransform", + "importPath": "spectragraph_transforms.domains.resolve", + "description": "spectragraph_transforms.domains.resolve", + "isExtraImport": true, + "detail": "spectragraph_transforms.domains.resolve", + "documentation": {} + }, + { + "label": "ResolveTransform", + "importPath": "spectragraph_transforms.domains.resolve", + "description": "spectragraph_transforms.domains.resolve", + "isExtraImport": true, + "detail": "spectragraph_transforms.domains.resolve", + "documentation": {} + }, + { + "label": "SubdomainTransform", + "importPath": "spectragraph_transforms.domains.subdomains", + "description": "spectragraph_transforms.domains.subdomains", + "isExtraImport": true, + "detail": "spectragraph_transforms.domains.subdomains", + "documentation": {} + }, + { + "label": "DomainToHistoryTransform", + "importPath": "spectragraph_transforms.domain.to_history", + "description": "spectragraph_transforms.domain.to_history", + "isExtraImport": true, + "detail": "spectragraph_transforms.domain.to_history", + "documentation": {} + }, + { + "label": "DomainToHistoryTransform", + "importPath": "spectragraph_transforms.domain.to_history", + "description": "spectragraph_transforms.domain.to_history", + "isExtraImport": true, + "detail": "spectragraph_transforms.domain.to_history", + "documentation": {} + }, + { + "label": "WhoisTransform", + "importPath": "spectragraph_transforms.domains.whois", + "description": "spectragraph_transforms.domains.whois", + "isExtraImport": true, + "detail": "spectragraph_transforms.domains.whois", + "documentation": {} + }, + { + "label": "EmailToGravatarTransform", + "importPath": "spectragraph_transforms.emails.to_gravatar", + "description": "spectragraph_transforms.emails.to_gravatar", + "isExtraImport": true, + "detail": "spectragraph_transforms.emails.to_gravatar", + "documentation": {} + }, + { + "label": "EmailToBreachesTransform", + "importPath": "spectragraph_transforms.emails.to_leaks", + "description": "spectragraph_transforms.emails.to_leaks", + "isExtraImport": true, + "detail": "spectragraph_transforms.emails.to_leaks", + "documentation": {} + }, + { + "label": "AsnToCidrsTransform", + "importPath": "spectragraph_transforms.ips.asn_to_cidrs", + "description": "spectragraph_transforms.ips.asn_to_cidrs", + "isExtraImport": true, + "detail": "spectragraph_transforms.ips.asn_to_cidrs", + "documentation": {} + }, + { + "label": "CidrToIpsTransform", + "importPath": "spectragraph_transforms.ips.cidr_to_ips", + "description": "spectragraph_transforms.ips.cidr_to_ips", + "isExtraImport": true, + "detail": "spectragraph_transforms.ips.cidr_to_ips", + "documentation": {} + }, + { + "label": "TestLogger", + "importPath": "tests.logger", + "description": "tests.logger", + "isExtraImport": true, + "detail": "tests.logger", + "documentation": {} + }, + { + "label": "TestLogger", + "importPath": "tests.logger", + "description": "tests.logger", + "isExtraImport": true, + "detail": "tests.logger", + "documentation": {} + }, + { + "label": "TestLogger", + "importPath": "tests.logger", + "description": "tests.logger", + "isExtraImport": true, + "detail": "tests.logger", + "documentation": {} + }, + { + "label": "IpToAsnTransform", + "importPath": "spectragraph_transforms.ips.ip_to_asn", + "description": "spectragraph_transforms.ips.ip_to_asn", + "isExtraImport": true, + "detail": "spectragraph_transforms.ips.ip_to_asn", + "documentation": {} + }, + { + "label": "IpToInfosTransform", + "importPath": "spectragraph_transforms.ips.geolocation", + "description": "spectragraph_transforms.ips.geolocation", + "isExtraImport": true, + "detail": "spectragraph_transforms.ips.geolocation", + "documentation": {} + }, + { + "label": "OrgToInfosTransform", + "importPath": "spectragraph_transforms.organizations.to_infos", + "description": "spectragraph_transforms.organizations.to_infos", + "isExtraImport": true, + "detail": "spectragraph_transforms.organizations.to_infos", + "documentation": {} + }, + { + "label": "MaigretTransform", + "importPath": "spectragraph_transforms.socials.maigret", + "description": "spectragraph_transforms.socials.maigret", + "isExtraImport": true, + "detail": "spectragraph_transforms.socials.maigret", + "documentation": {} + }, + { + "label": "WebsiteToLinks", + "importPath": "spectragraph_transforms.websites.to_links", + "description": "spectragraph_transforms.websites.to_links", + "isExtraImport": true, + "detail": "spectragraph_transforms.websites.to_links", + "documentation": {} + }, + { + "label": "GitHubRepoTransform", + "importPath": "spectragraph_transforms.social.github_repo", + "description": "spectragraph_transforms.social.github_repo", + "isExtraImport": true, + "detail": "spectragraph_transforms.social.github_repo", + "documentation": {} + }, + { + "label": "GitHubRepoParams", + "importPath": "spectragraph_transforms.social.github_repo", + "description": "spectragraph_transforms.social.github_repo", + "isExtraImport": true, + "detail": "spectragraph_transforms.social.github_repo", + "documentation": {} + }, + { + "label": "GitHubRepoTransform", + "importPath": "spectragraph_transforms.social.github_repo", + "description": "spectragraph_transforms.social.github_repo", + "isExtraImport": true, + "detail": "spectragraph_transforms.social.github_repo", + "documentation": {} + }, + { + "label": "IndividualToDomainsTransform", + "importPath": "spectragraph_transforms.individual.to_domains", + "description": "spectragraph_transforms.individual.to_domains", + "isExtraImport": true, + "detail": "spectragraph_transforms.individual.to_domains", + "documentation": {} + }, + { + "label": "EmailToDomainsTransform", + "importPath": "spectragraph_transforms.email.to_domains", + "description": "spectragraph_transforms.email.to_domains", + "isExtraImport": true, + "detail": "spectragraph_transforms.email.to_domains", + "documentation": {} + }, + { + "label": "CryptoWalletAddressToNFTs", + "importPath": "spectragraph_transforms.crypto.to_nfts", + "description": "spectragraph_transforms.crypto.to_nfts", + "isExtraImport": true, + "detail": "spectragraph_transforms.crypto.to_nfts", + "documentation": {} + }, + { + "label": "CryptoWalletAddressToTransactions", + "importPath": "spectragraph_transforms.crypto.to_transactions", + "description": "spectragraph_transforms.crypto.to_transactions", + "isExtraImport": true, + "detail": "spectragraph_transforms.crypto.to_transactions", + "documentation": {} + }, + { + "label": "EmailToBreachesTransform", + "importPath": "spectragraph_transforms.email.to_leaks", + "description": "spectragraph_transforms.email.to_leaks", + "isExtraImport": true, + "detail": "spectragraph_transforms.email.to_leaks", + "documentation": {} + }, + { + "label": "upgrade", + "kind": 2, + "importPath": "spectragraph-api.alembic.versions.0160b0f70a02_add_context_to_chat_message", + "description": "spectragraph-api.alembic.versions.0160b0f70a02_add_context_to_chat_message", + "peekOfCode": "def upgrade() -> None:\n \"\"\"Upgrade schema.\"\"\"\n # ### commands auto generated by Alembic - please adjust! ###\n op.add_column('messages', sa.Column('context', sa.JSON(), nullable=True))\n # ### end Alembic commands ###\ndef downgrade() -> None:\n \"\"\"Downgrade schema.\"\"\"\n # ### commands auto generated by Alembic - please adjust! ###\n op.drop_column('messages', 'context')\n # ### end Alembic commands ###", + "detail": "spectragraph-api.alembic.versions.0160b0f70a02_add_context_to_chat_message", + "documentation": {} + }, + { + "label": "downgrade", + "kind": 2, + "importPath": "spectragraph-api.alembic.versions.0160b0f70a02_add_context_to_chat_message", + "description": "spectragraph-api.alembic.versions.0160b0f70a02_add_context_to_chat_message", + "peekOfCode": "def downgrade() -> None:\n \"\"\"Downgrade schema.\"\"\"\n # ### commands auto generated by Alembic - please adjust! ###\n op.drop_column('messages', 'context')\n # ### end Alembic commands ###", + "detail": "spectragraph-api.alembic.versions.0160b0f70a02_add_context_to_chat_message", + "documentation": {} + }, + { + "label": "upgrade", + "kind": 2, + "importPath": "spectragraph-api.alembic.versions.0ab8ee0a782c_add_cascade_delete_to_messages", + "description": "spectragraph-api.alembic.versions.0ab8ee0a782c_add_cascade_delete_to_messages", + "peekOfCode": "def upgrade() -> None:\n \"\"\"Upgrade schema.\"\"\"\n # ### commands auto generated by Alembic - please adjust! ###\n pass\n # ### end Alembic commands ###\ndef downgrade() -> None:\n \"\"\"Downgrade schema.\"\"\"\n # ### commands auto generated by Alembic - please adjust! ###\n pass\n # ### end Alembic commands ###", + "detail": "spectragraph-api.alembic.versions.0ab8ee0a782c_add_cascade_delete_to_messages", + "documentation": {} + }, + { + "label": "downgrade", + "kind": 2, + "importPath": "spectragraph-api.alembic.versions.0ab8ee0a782c_add_cascade_delete_to_messages", + "description": "spectragraph-api.alembic.versions.0ab8ee0a782c_add_cascade_delete_to_messages", + "peekOfCode": "def downgrade() -> None:\n \"\"\"Downgrade schema.\"\"\"\n # ### commands auto generated by Alembic - please adjust! ###\n pass\n # ### end Alembic commands ###", + "detail": "spectragraph-api.alembic.versions.0ab8ee0a782c_add_cascade_delete_to_messages", + "documentation": {} + }, + { + "label": "upgrade", + "kind": 2, + "importPath": "spectragraph-api.alembic.versions.1098b7a5eabc_change_keys_structure_with_iv_salt_", + "description": "spectragraph-api.alembic.versions.1098b7a5eabc_change_keys_structure_with_iv_salt_", + "peekOfCode": "def upgrade() -> None:\n \"\"\"Upgrade schema.\"\"\"\n op.execute(\"TRUNCATE TABLE keys\")\n # ### commands auto generated by Alembic - please adjust! ###\n op.add_column('keys', sa.Column('ciphertext', sa.LargeBinary(), nullable=False))\n op.add_column('keys', sa.Column('iv', sa.LargeBinary(), nullable=False))\n op.add_column('keys', sa.Column('salt', sa.LargeBinary(), nullable=False))\n op.add_column('keys', sa.Column('key_version', sa.String(), nullable=False))\n op.alter_column('keys', 'owner_id',\n existing_type=sa.UUID(),", + "detail": "spectragraph-api.alembic.versions.1098b7a5eabc_change_keys_structure_with_iv_salt_", + "documentation": {} + }, + { + "label": "downgrade", + "kind": 2, + "importPath": "spectragraph-api.alembic.versions.1098b7a5eabc_change_keys_structure_with_iv_salt_", + "description": "spectragraph-api.alembic.versions.1098b7a5eabc_change_keys_structure_with_iv_salt_", + "peekOfCode": "def downgrade() -> None:\n \"\"\"Downgrade schema.\"\"\"\n # ### commands auto generated by Alembic - please adjust! ###\n op.add_column('keys', sa.Column('encrypted_key', sa.VARCHAR(), autoincrement=False, nullable=False))\n op.alter_column('keys', 'created_at',\n existing_type=postgresql.TIMESTAMP(timezone=True),\n nullable=True,\n existing_server_default=sa.text('now()'))\n op.alter_column('keys', 'owner_id',\n existing_type=sa.UUID(),", + "detail": "spectragraph-api.alembic.versions.1098b7a5eabc_change_keys_structure_with_iv_salt_", + "documentation": {} + }, + { + "label": "upgrade", + "kind": 2, + "importPath": "spectragraph-api.alembic.versions.1d0f26dbbef5_add_passive_delete_v2", + "description": "spectragraph-api.alembic.versions.1d0f26dbbef5_add_passive_delete_v2", + "peekOfCode": "def upgrade() -> None:\n \"\"\"Upgrade schema.\"\"\"\n # ### commands auto generated by Alembic - please adjust! ###\n pass\n # ### end Alembic commands ###\ndef downgrade() -> None:\n \"\"\"Downgrade schema.\"\"\"\n # ### commands auto generated by Alembic - please adjust! ###\n pass\n # ### end Alembic commands ###", + "detail": "spectragraph-api.alembic.versions.1d0f26dbbef5_add_passive_delete_v2", + "documentation": {} + }, + { + "label": "downgrade", + "kind": 2, + "importPath": "spectragraph-api.alembic.versions.1d0f26dbbef5_add_passive_delete_v2", + "description": "spectragraph-api.alembic.versions.1d0f26dbbef5_add_passive_delete_v2", + "peekOfCode": "def downgrade() -> None:\n \"\"\"Downgrade schema.\"\"\"\n # ### commands auto generated by Alembic - please adjust! ###\n pass\n # ### end Alembic commands ###", + "detail": "spectragraph-api.alembic.versions.1d0f26dbbef5_add_passive_delete_v2", + "documentation": {} + }, + { + "label": "upgrade", + "kind": 2, + "importPath": "spectragraph-api.alembic.versions.2da47dbd4a52_add_cascade_delete_to_scans_and_logs", + "description": "spectragraph-api.alembic.versions.2da47dbd4a52_add_cascade_delete_to_scans_and_logs", + "peekOfCode": "def upgrade() -> None:\n \"\"\"Upgrade schema.\"\"\"\n # ### commands auto generated by Alembic - please adjust! ###\n op.alter_column('scans', 'status',\n existing_type=postgresql.ENUM('PENDING', 'RUNNING', 'COMPLETED', 'FAILED', name='transformstatus'),\n nullable=True)\n op.drop_constraint('scans_sketch_id_fkey', 'scans', type_='foreignkey')\n op.create_foreign_key(None, 'scans', 'sketches', ['sketch_id'], ['id'], onupdate='CASCADE', ondelete='CASCADE')\n # ### end Alembic commands ###\ndef downgrade() -> None:", + "detail": "spectragraph-api.alembic.versions.2da47dbd4a52_add_cascade_delete_to_scans_and_logs", + "documentation": {} + }, + { + "label": "downgrade", + "kind": 2, + "importPath": "spectragraph-api.alembic.versions.2da47dbd4a52_add_cascade_delete_to_scans_and_logs", + "description": "spectragraph-api.alembic.versions.2da47dbd4a52_add_cascade_delete_to_scans_and_logs", + "peekOfCode": "def downgrade() -> None:\n \"\"\"Downgrade schema.\"\"\"\n # ### commands auto generated by Alembic - please adjust! ###\n op.drop_constraint(None, 'scans', type_='foreignkey')\n op.create_foreign_key('scans_sketch_id_fkey', 'scans', 'sketches', ['sketch_id'], ['id'])\n op.alter_column('scans', 'status',\n existing_type=postgresql.ENUM('PENDING', 'RUNNING', 'COMPLETED', 'FAILED', name='transformstatus'),\n nullable=False)\n # ### end Alembic commands ###", + "detail": "spectragraph-api.alembic.versions.2da47dbd4a52_add_cascade_delete_to_scans_and_logs", + "documentation": {} + }, + { + "label": "upgrade", + "kind": 2, + "importPath": "spectragraph-api.alembic.versions.40ece72583b7_add_email_and_hashed_password_to_profile", + "description": "spectragraph-api.alembic.versions.40ece72583b7_add_email_and_hashed_password_to_profile", + "peekOfCode": "def upgrade() -> None:\n \"\"\"Upgrade schema.\"\"\"\n # ### commands auto generated by Alembic - please adjust! ###\n op.add_column('profiles', sa.Column('email', sa.String(), nullable=False))\n op.add_column('profiles', sa.Column('hashed_password', sa.String(), nullable=False))\n op.add_column('profiles', sa.Column('is_active', sa.Boolean(), nullable=False))\n op.create_unique_constraint(None, 'profiles', ['email'])\n # ### end Alembic commands ###\ndef downgrade() -> None:\n \"\"\"Downgrade schema.\"\"\"", + "detail": "spectragraph-api.alembic.versions.40ece72583b7_add_email_and_hashed_password_to_profile", + "documentation": {} + }, + { + "label": "downgrade", + "kind": 2, + "importPath": "spectragraph-api.alembic.versions.40ece72583b7_add_email_and_hashed_password_to_profile", + "description": "spectragraph-api.alembic.versions.40ece72583b7_add_email_and_hashed_password_to_profile", + "peekOfCode": "def downgrade() -> None:\n \"\"\"Downgrade schema.\"\"\"\n # ### commands auto generated by Alembic - please adjust! ###\n op.drop_constraint(None, 'profiles', type_='unique')\n op.drop_column('profiles', 'is_active')\n op.drop_column('profiles', 'hashed_password')\n op.drop_column('profiles', 'email')\n # ### end Alembic commands ###", + "detail": "spectragraph-api.alembic.versions.40ece72583b7_add_email_and_hashed_password_to_profile", + "documentation": {} + }, + { + "label": "upgrade", + "kind": 2, + "importPath": "spectragraph-api.alembic.versions.661ff8ef4425_rename_transforms_to_flows", + "description": "spectragraph-api.alembic.versions.661ff8ef4425_rename_transforms_to_flows", + "peekOfCode": "def upgrade() -> None:\n \"\"\"Upgrade schema.\"\"\"\n # Rename the table from 'transforms' to 'flows'\n op.rename_table('transforms', 'flows')\n # Rename the column from 'transform_schema' to 'flow_schema'\n op.alter_column('flows', 'transform_schema', new_column_name='flow_schema')\ndef downgrade() -> None:\n \"\"\"Downgrade schema.\"\"\"\n # Rename the column back from 'flow_schema' to 'transform_schema'\n op.alter_column('flows', 'flow_schema', new_column_name='transform_schema')", + "detail": "spectragraph-api.alembic.versions.661ff8ef4425_rename_transforms_to_flows", + "documentation": {} + }, + { + "label": "downgrade", + "kind": 2, + "importPath": "spectragraph-api.alembic.versions.661ff8ef4425_rename_transforms_to_flows", + "description": "spectragraph-api.alembic.versions.661ff8ef4425_rename_transforms_to_flows", + "peekOfCode": "def downgrade() -> None:\n \"\"\"Downgrade schema.\"\"\"\n # Rename the column back from 'flow_schema' to 'transform_schema'\n op.alter_column('flows', 'flow_schema', new_column_name='transform_schema')\n # Rename the table back from 'flows' to 'transforms'\n op.rename_table('flows', 'transforms')", + "detail": "spectragraph-api.alembic.versions.661ff8ef4425_rename_transforms_to_flows", + "documentation": {} + }, + { + "label": "upgrade", + "kind": 2, + "importPath": "spectragraph-api.alembic.versions.6be831edfda7_add_investigation_roles_permissions", + "description": "spectragraph-api.alembic.versions.6be831edfda7_add_investigation_roles_permissions", + "peekOfCode": "def upgrade() -> None:\n \"\"\"Upgrade schema.\"\"\"\n # ### commands auto generated by Alembic - please adjust! ###\n op.add_column('investigation_user_roles', sa.Column('roles', postgresql.ARRAY(sa.Enum('OWNER', 'EDITOR', 'VIEWER', name='role_enum', create_constraint=True)), server_default='{}', nullable=False))\n op.drop_column('investigation_user_roles', 'role')\n # ### end Alembic commands ###\ndef downgrade() -> None:\n \"\"\"Downgrade schema.\"\"\"\n # ### commands auto generated by Alembic - please adjust! ###\n op.add_column('investigation_user_roles', sa.Column('role', postgresql.ENUM('OWNER', 'EDITOR', 'VIEWER', name='role_enum'), autoincrement=False, nullable=False))", + "detail": "spectragraph-api.alembic.versions.6be831edfda7_add_investigation_roles_permissions", + "documentation": {} + }, + { + "label": "downgrade", + "kind": 2, + "importPath": "spectragraph-api.alembic.versions.6be831edfda7_add_investigation_roles_permissions", + "description": "spectragraph-api.alembic.versions.6be831edfda7_add_investigation_roles_permissions", + "peekOfCode": "def downgrade() -> None:\n \"\"\"Downgrade schema.\"\"\"\n # ### commands auto generated by Alembic - please adjust! ###\n op.add_column('investigation_user_roles', sa.Column('role', postgresql.ENUM('OWNER', 'EDITOR', 'VIEWER', name='role_enum'), autoincrement=False, nullable=False))\n op.drop_column('investigation_user_roles', 'roles')\n # ### end Alembic commands ###", + "detail": "spectragraph-api.alembic.versions.6be831edfda7_add_investigation_roles_permissions", + "documentation": {} + }, + { + "label": "upgrade", + "kind": 2, + "importPath": "spectragraph-api.alembic.versions.6dfa83113ad7_change_content_colum_of_log_to_json", + "description": "spectragraph-api.alembic.versions.6dfa83113ad7_change_content_colum_of_log_to_json", + "peekOfCode": "def upgrade() -> None:\n \"\"\"Upgrade schema.\"\"\"\n # 1. Crée le nouveau type ENUM\n op.execute(\"\"\"\n CREATE TYPE eventlevel AS ENUM (\n 'INFO', 'WARNING', 'FAILED', 'SUCCESS', 'DEBUG',\n 'PENDING', 'RUNNING', 'COMPLETED', 'GRAPH_APPEND'\n )\n \"\"\")\n # 2. Change 'logs.content' de TEXT à JSONB", + "detail": "spectragraph-api.alembic.versions.6dfa83113ad7_change_content_colum_of_log_to_json", + "documentation": {} + }, + { + "label": "downgrade", + "kind": 2, + "importPath": "spectragraph-api.alembic.versions.6dfa83113ad7_change_content_colum_of_log_to_json", + "description": "spectragraph-api.alembic.versions.6dfa83113ad7_change_content_colum_of_log_to_json", + "peekOfCode": "def downgrade() -> None:\n \"\"\"Downgrade schema.\"\"\"\n # 1. Revert 'scans.status' to old ENUM type\n op.execute(\"\"\"\n ALTER TABLE scans\n ALTER COLUMN status TYPE transformstatus\n USING status::text::transformstatus\n \"\"\")\n # 2. Revert 'logs.type' back to VARCHAR\n op.execute(\"\"\"", + "detail": "spectragraph-api.alembic.versions.6dfa83113ad7_change_content_colum_of_log_to_json", + "documentation": {} + }, + { + "label": "upgrade", + "kind": 2, + "importPath": "spectragraph-api.alembic.versions.6e49acfb3816_add_investigation_roles_permissions", + "description": "spectragraph-api.alembic.versions.6e49acfb3816_add_investigation_roles_permissions", + "peekOfCode": "def upgrade() -> None:\n \"\"\"Upgrade schema.\"\"\"\n # ### commands auto generated by Alembic - please adjust! ###\n op.create_table('investigation_user_roles',\n sa.Column('id', sa.UUID(), nullable=False),\n sa.Column('user_id', sa.UUID(), nullable=False),\n sa.Column('investigation_id', sa.UUID(), nullable=False),\n sa.Column('role', sa.Enum('OWNER', 'EDITOR', 'VIEWER', name='role_enum', create_constraint=True), nullable=False),\n sa.ForeignKeyConstraint(['investigation_id'], ['investigations.id'], onupdate='CASCADE', ondelete='CASCADE'),\n sa.ForeignKeyConstraint(['user_id'], ['profiles.id'], onupdate='CASCADE', ondelete='CASCADE'),", + "detail": "spectragraph-api.alembic.versions.6e49acfb3816_add_investigation_roles_permissions", + "documentation": {} + }, + { + "label": "downgrade", + "kind": 2, + "importPath": "spectragraph-api.alembic.versions.6e49acfb3816_add_investigation_roles_permissions", + "description": "spectragraph-api.alembic.versions.6e49acfb3816_add_investigation_roles_permissions", + "peekOfCode": "def downgrade() -> None:\n \"\"\"Downgrade schema.\"\"\"\n # ### commands auto generated by Alembic - please adjust! ###\n op.create_table('investigations_profiles',\n sa.Column('id', sa.UUID(), autoincrement=False, nullable=False),\n sa.Column('created_at', postgresql.TIMESTAMP(timezone=True), server_default=sa.text('now()'), autoincrement=False, nullable=True),\n sa.Column('investigation_id', sa.UUID(), autoincrement=False, nullable=True),\n sa.Column('profile_id', sa.UUID(), autoincrement=False, nullable=True),\n sa.Column('role', sa.VARCHAR(), server_default=sa.text(\"'member'::character varying\"), autoincrement=False, nullable=True),\n sa.ForeignKeyConstraint(['investigation_id'], ['investigations.id'], name='investigations_profiles_investigation_id_fkey', onupdate='CASCADE', ondelete='CASCADE'),", + "detail": "spectragraph-api.alembic.versions.6e49acfb3816_add_investigation_roles_permissions", + "documentation": {} + }, + { + "label": "upgrade", + "kind": 2, + "importPath": "spectragraph-api.alembic.versions.71a3e5b4db2a_update_scan_status_enum", + "description": "spectragraph-api.alembic.versions.71a3e5b4db2a_update_scan_status_enum", + "peekOfCode": "def upgrade() -> None:\n \"\"\"Upgrade schema.\"\"\"\n # Create the enum type first using raw SQL to ensure it exists\n op.execute(\"CREATE TYPE transformstatus AS ENUM ('PENDING', 'RUNNING', 'COMPLETED', 'FAILED')\")\n # Add new columns\n op.add_column('scans', sa.Column('started_at', sa.DateTime(), nullable=True))\n op.add_column('scans', sa.Column('completed_at', sa.DateTime(), nullable=True))\n op.add_column('scans', sa.Column('error', sa.Text(), nullable=True))\n op.add_column('scans', sa.Column('details', sa.JSON(), nullable=True))\n # Add new status column with enum type", + "detail": "spectragraph-api.alembic.versions.71a3e5b4db2a_update_scan_status_enum", + "documentation": {} + }, + { + "label": "downgrade", + "kind": 2, + "importPath": "spectragraph-api.alembic.versions.71a3e5b4db2a_update_scan_status_enum", + "description": "spectragraph-api.alembic.versions.71a3e5b4db2a_update_scan_status_enum", + "peekOfCode": "def downgrade() -> None:\n \"\"\"Downgrade schema.\"\"\"\n # Add back old columns\n op.add_column('scans', sa.Column('created_at', postgresql.TIMESTAMP(timezone=True), server_default=sa.text('now()'), autoincrement=False, nullable=True))\n op.add_column('scans', sa.Column('results', postgresql.JSON(astext_type=sa.Text()), autoincrement=False, nullable=True))\n op.add_column('scans', sa.Column('values', postgresql.ARRAY(sa.TEXT()), autoincrement=False, nullable=True))\n # Add new VARCHAR status column\n op.add_column('scans', sa.Column('status_old', sa.String(), nullable=True))\n # Copy data from enum status to VARCHAR status\n op.execute(\"UPDATE scans SET status_old = status::VARCHAR\")", + "detail": "spectragraph-api.alembic.versions.71a3e5b4db2a_update_scan_status_enum", + "documentation": {} + }, + { + "label": "upgrade", + "kind": 2, + "importPath": "spectragraph-api.alembic.versions.76f5436251e3_add_relationship_between_investigations_", + "description": "spectragraph-api.alembic.versions.76f5436251e3_add_relationship_between_investigations_", + "peekOfCode": "def upgrade() -> None:\n \"\"\"Upgrade schema.\"\"\"\n # ### commands auto generated by Alembic - please adjust! ###\n pass\n # ### end Alembic commands ###\ndef downgrade() -> None:\n \"\"\"Downgrade schema.\"\"\"\n # ### commands auto generated by Alembic - please adjust! ###\n pass\n # ### end Alembic commands ###", + "detail": "spectragraph-api.alembic.versions.76f5436251e3_add_relationship_between_investigations_", + "documentation": {} + }, + { + "label": "downgrade", + "kind": 2, + "importPath": "spectragraph-api.alembic.versions.76f5436251e3_add_relationship_between_investigations_", + "description": "spectragraph-api.alembic.versions.76f5436251e3_add_relationship_between_investigations_", + "peekOfCode": "def downgrade() -> None:\n \"\"\"Downgrade schema.\"\"\"\n # ### commands auto generated by Alembic - please adjust! ###\n pass\n # ### end Alembic commands ###", + "detail": "spectragraph-api.alembic.versions.76f5436251e3_add_relationship_between_investigations_", + "documentation": {} + }, + { + "label": "upgrade", + "kind": 2, + "importPath": "spectragraph-api.alembic.versions.8173aba964e7_add_custom_types_table", + "description": "spectragraph-api.alembic.versions.8173aba964e7_add_custom_types_table", + "peekOfCode": "def upgrade() -> None:\n \"\"\"Upgrade schema.\"\"\"\n # ### commands auto generated by Alembic - please adjust! ###\n op.create_table('custom_types',\n sa.Column('id', sa.UUID(), nullable=False),\n sa.Column('name', sa.Text(), nullable=False),\n sa.Column('owner_id', sa.UUID(), nullable=False),\n sa.Column('schema', postgresql.JSONB(astext_type=sa.Text()), nullable=False),\n sa.Column('status', sa.String(), server_default='draft', nullable=False),\n sa.Column('checksum', sa.String(), nullable=True),", + "detail": "spectragraph-api.alembic.versions.8173aba964e7_add_custom_types_table", + "documentation": {} + }, + { + "label": "downgrade", + "kind": 2, + "importPath": "spectragraph-api.alembic.versions.8173aba964e7_add_custom_types_table", + "description": "spectragraph-api.alembic.versions.8173aba964e7_add_custom_types_table", + "peekOfCode": "def downgrade() -> None:\n \"\"\"Downgrade schema.\"\"\"\n # ### commands auto generated by Alembic - please adjust! ###\n op.drop_index('idx_custom_types_status', table_name='custom_types')\n op.drop_index('idx_custom_types_owner_id', table_name='custom_types')\n op.drop_index('idx_custom_types_name', table_name='custom_types')\n op.drop_table('custom_types')\n # ### end Alembic commands ###", + "detail": "spectragraph-api.alembic.versions.8173aba964e7_add_custom_types_table", + "documentation": {} + }, + { + "label": "upgrade", + "kind": 2, + "importPath": "spectragraph-api.alembic.versions.8ac522441108_add_chat_and_chat_message", + "description": "spectragraph-api.alembic.versions.8ac522441108_add_chat_and_chat_message", + "peekOfCode": "def upgrade() -> None:\n \"\"\"Upgrade schema.\"\"\"\n # ### commands auto generated by Alembic - please adjust! ###\n op.create_table('chats',\n sa.Column('id', sa.UUID(), nullable=False),\n sa.Column('title', sa.Text(), nullable=False),\n sa.Column('description', sa.Text(), nullable=True),\n sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=True),\n sa.Column('last_updated_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=True),\n sa.Column('owner_id', sa.UUID(), nullable=True),", + "detail": "spectragraph-api.alembic.versions.8ac522441108_add_chat_and_chat_message", + "documentation": {} + }, + { + "label": "downgrade", + "kind": 2, + "importPath": "spectragraph-api.alembic.versions.8ac522441108_add_chat_and_chat_message", + "description": "spectragraph-api.alembic.versions.8ac522441108_add_chat_and_chat_message", + "peekOfCode": "def downgrade() -> None:\n \"\"\"Downgrade schema.\"\"\"\n # ### commands auto generated by Alembic - please adjust! ###\n op.drop_index('idx_messages_chat_id', table_name='messages')\n op.drop_table('messages')\n op.drop_index('idx_chats_owner_id', table_name='chats')\n op.drop_index('idx_chats_investigation_id', table_name='chats')\n op.drop_table('chats')\n # ### end Alembic commands ###", + "detail": "spectragraph-api.alembic.versions.8ac522441108_add_chat_and_chat_message", + "documentation": {} + }, + { + "label": "upgrade", + "kind": 2, + "importPath": "spectragraph-api.alembic.versions.8d0e12b68d1e_fix_backpopulate_issue", + "description": "spectragraph-api.alembic.versions.8d0e12b68d1e_fix_backpopulate_issue", + "peekOfCode": "def upgrade() -> None:\n \"\"\"Upgrade schema.\"\"\"\n # ### commands auto generated by Alembic - please adjust! ###\n pass\n # ### end Alembic commands ###\ndef downgrade() -> None:\n \"\"\"Downgrade schema.\"\"\"\n # ### commands auto generated by Alembic - please adjust! ###\n pass\n # ### end Alembic commands ###", + "detail": "spectragraph-api.alembic.versions.8d0e12b68d1e_fix_backpopulate_issue", + "documentation": {} + }, + { + "label": "downgrade", + "kind": 2, + "importPath": "spectragraph-api.alembic.versions.8d0e12b68d1e_fix_backpopulate_issue", + "description": "spectragraph-api.alembic.versions.8d0e12b68d1e_fix_backpopulate_issue", + "peekOfCode": "def downgrade() -> None:\n \"\"\"Downgrade schema.\"\"\"\n # ### commands auto generated by Alembic - please adjust! ###\n pass\n # ### end Alembic commands ###", + "detail": "spectragraph-api.alembic.versions.8d0e12b68d1e_fix_backpopulate_issue", + "documentation": {} + }, + { + "label": "upgrade", + "kind": 2, + "importPath": "spectragraph-api.alembic.versions.965b56353b4c_initial_migration", + "description": "spectragraph-api.alembic.versions.965b56353b4c_initial_migration", + "peekOfCode": "def upgrade() -> None:\n \"\"\"Upgrade schema.\"\"\"\n # ### commands auto generated by Alembic - please adjust! ###\n op.create_table('profiles',\n sa.Column('id', sa.UUID(), nullable=False),\n sa.Column('first_name', sa.Text(), nullable=True),\n sa.Column('last_name', sa.Text(), nullable=True),\n sa.Column('avatar_url', sa.Text(), nullable=True),\n sa.PrimaryKeyConstraint('id')\n )", + "detail": "spectragraph-api.alembic.versions.965b56353b4c_initial_migration", + "documentation": {} + }, + { + "label": "downgrade", + "kind": 2, + "importPath": "spectragraph-api.alembic.versions.965b56353b4c_initial_migration", + "description": "spectragraph-api.alembic.versions.965b56353b4c_initial_migration", + "peekOfCode": "def downgrade() -> None:\n \"\"\"Downgrade schema.\"\"\"\n # ### commands auto generated by Alembic - please adjust! ###\n op.drop_table('logs')\n op.drop_index('investigations_profiles_unique_profile_investigation', table_name='sketches_profiles')\n op.drop_index('idx_sketches_profiles_sketch_id', table_name='sketches_profiles')\n op.drop_index('idx_sketches_profiles_profile_id', table_name='sketches_profiles')\n op.drop_table('sketches_profiles')\n op.drop_index('idx_scans_sketch_id', table_name='scans')\n op.drop_table('scans')", + "detail": "spectragraph-api.alembic.versions.965b56353b4c_initial_migration", + "documentation": {} + }, + { + "label": "upgrade", + "kind": 2, + "importPath": "spectragraph-api.alembic.versions.9a3b9a199aa8_drop_third_party_keys_create_keys_table", + "description": "spectragraph-api.alembic.versions.9a3b9a199aa8_drop_third_party_keys_create_keys_table", + "peekOfCode": "def upgrade() -> None:\n \"\"\"Upgrade schema.\"\"\"\n # Drop the old third_party_keys table if it exists\n op.drop_table('third_party_keys')\n # Create the new keys table\n op.create_table('keys',\n sa.Column('id', postgresql.UUID(as_uuid=True), nullable=False),\n sa.Column('name', sa.String(), nullable=False),\n sa.Column('owner_id', postgresql.UUID(as_uuid=True), nullable=True),\n sa.Column('encrypted_key', sa.String(), nullable=False),", + "detail": "spectragraph-api.alembic.versions.9a3b9a199aa8_drop_third_party_keys_create_keys_table", + "documentation": {} + }, + { + "label": "downgrade", + "kind": 2, + "importPath": "spectragraph-api.alembic.versions.9a3b9a199aa8_drop_third_party_keys_create_keys_table", + "description": "spectragraph-api.alembic.versions.9a3b9a199aa8_drop_third_party_keys_create_keys_table", + "peekOfCode": "def downgrade() -> None:\n \"\"\"Downgrade schema.\"\"\"\n # Drop the keys table\n op.drop_index('idx_keys_service', table_name='keys')\n op.drop_index('idx_keys_owner_id', table_name='keys')\n op.drop_table('keys')\n # Recreate the third_party_keys table\n op.create_table('third_party_keys',\n sa.Column('id', postgresql.UUID(as_uuid=True), nullable=False),\n sa.Column('service', sa.String(), nullable=False),", + "detail": "spectragraph-api.alembic.versions.9a3b9a199aa8_drop_third_party_keys_create_keys_table", + "documentation": {} + }, + { + "label": "upgrade", + "kind": 2, + "importPath": "spectragraph-api.alembic.versions.afdaf9aa539c_add_passive_delete", + "description": "spectragraph-api.alembic.versions.afdaf9aa539c_add_passive_delete", + "peekOfCode": "def upgrade() -> None:\n \"\"\"Upgrade schema.\"\"\"\n # ### commands auto generated by Alembic - please adjust! ###\n pass\n # ### end Alembic commands ###\ndef downgrade() -> None:\n \"\"\"Downgrade schema.\"\"\"\n # ### commands auto generated by Alembic - please adjust! ###\n pass\n # ### end Alembic commands ###", + "detail": "spectragraph-api.alembic.versions.afdaf9aa539c_add_passive_delete", + "documentation": {} + }, + { + "label": "downgrade", + "kind": 2, + "importPath": "spectragraph-api.alembic.versions.afdaf9aa539c_add_passive_delete", + "description": "spectragraph-api.alembic.versions.afdaf9aa539c_add_passive_delete", + "peekOfCode": "def downgrade() -> None:\n \"\"\"Downgrade schema.\"\"\"\n # ### commands auto generated by Alembic - please adjust! ###\n pass\n # ### end Alembic commands ###", + "detail": "spectragraph-api.alembic.versions.afdaf9aa539c_add_passive_delete", + "documentation": {} + }, + { + "label": "upgrade", + "kind": 2, + "importPath": "spectragraph-api.alembic.versions.ba3d00e11612_add_cascade_delete_to_scans_and_logs", + "description": "spectragraph-api.alembic.versions.ba3d00e11612_add_cascade_delete_to_scans_and_logs", + "peekOfCode": "def upgrade() -> None:\n \"\"\"Upgrade schema.\"\"\"\n # ### commands auto generated by Alembic - please adjust! ###\n op.alter_column('scans', 'sketch_id',\n existing_type=sa.UUID(),\n nullable=True)\n # ### end Alembic commands ###\ndef downgrade() -> None:\n \"\"\"Downgrade schema.\"\"\"\n # ### commands auto generated by Alembic - please adjust! ###", + "detail": "spectragraph-api.alembic.versions.ba3d00e11612_add_cascade_delete_to_scans_and_logs", + "documentation": {} + }, + { + "label": "downgrade", + "kind": 2, + "importPath": "spectragraph-api.alembic.versions.ba3d00e11612_add_cascade_delete_to_scans_and_logs", + "description": "spectragraph-api.alembic.versions.ba3d00e11612_add_cascade_delete_to_scans_and_logs", + "peekOfCode": "def downgrade() -> None:\n \"\"\"Downgrade schema.\"\"\"\n # ### commands auto generated by Alembic - please adjust! ###\n op.alter_column('scans', 'sketch_id',\n existing_type=sa.UUID(),\n nullable=False)\n # ### end Alembic commands ###", + "detail": "spectragraph-api.alembic.versions.ba3d00e11612_add_cascade_delete_to_scans_and_logs", + "documentation": {} + }, + { + "label": "upgrade", + "kind": 2, + "importPath": "spectragraph-api.alembic.versions.c82bf6af92e5_add_investigation_roles_permissions", + "description": "spectragraph-api.alembic.versions.c82bf6af92e5_add_investigation_roles_permissions", + "peekOfCode": "def upgrade() -> None:\n \"\"\"Upgrade schema.\"\"\"\n # ### commands auto generated by Alembic - please adjust! ###\n pass\n # ### end Alembic commands ###\ndef downgrade() -> None:\n \"\"\"Downgrade schema.\"\"\"\n # ### commands auto generated by Alembic - please adjust! ###\n pass\n # ### end Alembic commands ###", + "detail": "spectragraph-api.alembic.versions.c82bf6af92e5_add_investigation_roles_permissions", + "documentation": {} + }, + { + "label": "downgrade", + "kind": 2, + "importPath": "spectragraph-api.alembic.versions.c82bf6af92e5_add_investigation_roles_permissions", + "description": "spectragraph-api.alembic.versions.c82bf6af92e5_add_investigation_roles_permissions", + "peekOfCode": "def downgrade() -> None:\n \"\"\"Downgrade schema.\"\"\"\n # ### commands auto generated by Alembic - please adjust! ###\n pass\n # ### end Alembic commands ###", + "detail": "spectragraph-api.alembic.versions.c82bf6af92e5_add_investigation_roles_permissions", + "documentation": {} + }, + { + "label": "upgrade", + "kind": 2, + "importPath": "spectragraph-api.alembic.versions.d0a8e5b5a7b9_add_relationship_between_investigations_", + "description": "spectragraph-api.alembic.versions.d0a8e5b5a7b9_add_relationship_between_investigations_", + "peekOfCode": "def upgrade() -> None:\n \"\"\"Upgrade schema.\"\"\"\n # ### commands auto generated by Alembic - please adjust! ###\n pass\n # ### end Alembic commands ###\ndef downgrade() -> None:\n \"\"\"Downgrade schema.\"\"\"\n # ### commands auto generated by Alembic - please adjust! ###\n pass\n # ### end Alembic commands ###", + "detail": "spectragraph-api.alembic.versions.d0a8e5b5a7b9_add_relationship_between_investigations_", + "documentation": {} + }, + { + "label": "downgrade", + "kind": 2, + "importPath": "spectragraph-api.alembic.versions.d0a8e5b5a7b9_add_relationship_between_investigations_", + "description": "spectragraph-api.alembic.versions.d0a8e5b5a7b9_add_relationship_between_investigations_", + "peekOfCode": "def downgrade() -> None:\n \"\"\"Downgrade schema.\"\"\"\n # ### commands auto generated by Alembic - please adjust! ###\n pass\n # ### end Alembic commands ###", + "detail": "spectragraph-api.alembic.versions.d0a8e5b5a7b9_add_relationship_between_investigations_", + "documentation": {} + }, + { + "label": "upgrade", + "kind": 2, + "importPath": "spectragraph-api.alembic.versions.d39941278a91_init", + "description": "spectragraph-api.alembic.versions.d39941278a91_init", + "peekOfCode": "def upgrade() -> None:\n \"\"\"Upgrade schema.\"\"\"\n # ### commands auto generated by Alembic - please adjust! ###\n pass\n # ### end Alembic commands ###\ndef downgrade() -> None:\n \"\"\"Downgrade schema.\"\"\"\n # ### commands auto generated by Alembic - please adjust! ###\n pass\n # ### end Alembic commands ###", + "detail": "spectragraph-api.alembic.versions.d39941278a91_init", + "documentation": {} + }, + { + "label": "downgrade", + "kind": 2, + "importPath": "spectragraph-api.alembic.versions.d39941278a91_init", + "description": "spectragraph-api.alembic.versions.d39941278a91_init", + "peekOfCode": "def downgrade() -> None:\n \"\"\"Downgrade schema.\"\"\"\n # ### commands auto generated by Alembic - please adjust! ###\n pass\n # ### end Alembic commands ###", + "detail": "spectragraph-api.alembic.versions.d39941278a91_init", + "documentation": {} + }, + { + "label": "upgrade", + "kind": 2, + "importPath": "spectragraph-api.alembic.versions.e403a4152f6b_add_third_party_keys_table", + "description": "spectragraph-api.alembic.versions.e403a4152f6b_add_third_party_keys_table", + "peekOfCode": "def upgrade() -> None:\n \"\"\"Upgrade schema.\"\"\"\n # ### commands auto generated by Alembic - please adjust! ###\n op.create_table('third_party_keys',\n sa.Column('id', sa.UUID(), nullable=False),\n sa.Column('service', sa.String(), nullable=False),\n sa.Column('owner_id', sa.UUID(), nullable=True),\n sa.Column('encrypted_key', sa.String(), nullable=False),\n sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=True),\n sa.ForeignKeyConstraint(['owner_id'], ['profiles.id'], onupdate='CASCADE', ondelete='CASCADE'),", + "detail": "spectragraph-api.alembic.versions.e403a4152f6b_add_third_party_keys_table", + "documentation": {} + }, + { + "label": "downgrade", + "kind": 2, + "importPath": "spectragraph-api.alembic.versions.e403a4152f6b_add_third_party_keys_table", + "description": "spectragraph-api.alembic.versions.e403a4152f6b_add_third_party_keys_table", + "peekOfCode": "def downgrade() -> None:\n \"\"\"Downgrade schema.\"\"\"\n # ### commands auto generated by Alembic - please adjust! ###\n op.drop_index('idx_keys_service', table_name='third_party_keys')\n op.drop_index('idx_keys_owner_id', table_name='third_party_keys')\n op.drop_table('third_party_keys')\n # ### end Alembic commands ###", + "detail": "spectragraph-api.alembic.versions.e403a4152f6b_add_third_party_keys_table", + "documentation": {} + }, + { + "label": "upgrade", + "kind": 2, + "importPath": "spectragraph-api.alembic.versions.fa0ab51b2f64_add_analysis_model_and_investigation_", + "description": "spectragraph-api.alembic.versions.fa0ab51b2f64_add_analysis_model_and_investigation_", + "peekOfCode": "def upgrade() -> None:\n \"\"\"Upgrade schema.\"\"\"\n # ### commands auto generated by Alembic - please adjust! ###\n op.create_table('analyses',\n sa.Column('id', sa.UUID(), nullable=False),\n sa.Column('title', sa.Text(), nullable=False),\n sa.Column('description', sa.Text(), nullable=True),\n sa.Column('content', sa.JSON(), nullable=True),\n sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=True),\n sa.Column('last_updated_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=True),", + "detail": "spectragraph-api.alembic.versions.fa0ab51b2f64_add_analysis_model_and_investigation_", + "documentation": {} + }, + { + "label": "downgrade", + "kind": 2, + "importPath": "spectragraph-api.alembic.versions.fa0ab51b2f64_add_analysis_model_and_investigation_", + "description": "spectragraph-api.alembic.versions.fa0ab51b2f64_add_analysis_model_and_investigation_", + "peekOfCode": "def downgrade() -> None:\n \"\"\"Downgrade schema.\"\"\"\n # ### commands auto generated by Alembic - please adjust! ###\n op.drop_index('idx_analyses_owner_id', table_name='analyses')\n op.drop_index('idx_analyses_investigation_id', table_name='analyses')\n op.drop_table('analyses')\n # ### end Alembic commands ###", + "detail": "spectragraph-api.alembic.versions.fa0ab51b2f64_add_analysis_model_and_investigation_", + "documentation": {} + }, + { + "label": "upgrade", + "kind": 2, + "importPath": "spectragraph-api.alembic.versions.faceebd6a580_remove_scan_id_of_logs", + "description": "spectragraph-api.alembic.versions.faceebd6a580_remove_scan_id_of_logs", + "peekOfCode": "def upgrade() -> None:\n \"\"\"Upgrade schema.\"\"\"\n # ### commands auto generated by Alembic - please adjust! ###\n op.drop_constraint('logs_scan_id_fkey', 'logs', type_='foreignkey')\n op.drop_column('logs', 'scan_id')\n # ### end Alembic commands ###\ndef downgrade() -> None:\n \"\"\"Downgrade schema.\"\"\"\n # ### commands auto generated by Alembic - please adjust! ###\n op.add_column('logs', sa.Column('scan_id', sa.UUID(), autoincrement=False, nullable=True))", + "detail": "spectragraph-api.alembic.versions.faceebd6a580_remove_scan_id_of_logs", + "documentation": {} + }, + { + "label": "downgrade", + "kind": 2, + "importPath": "spectragraph-api.alembic.versions.faceebd6a580_remove_scan_id_of_logs", + "description": "spectragraph-api.alembic.versions.faceebd6a580_remove_scan_id_of_logs", + "peekOfCode": "def downgrade() -> None:\n \"\"\"Downgrade schema.\"\"\"\n # ### commands auto generated by Alembic - please adjust! ###\n op.add_column('logs', sa.Column('scan_id', sa.UUID(), autoincrement=False, nullable=True))\n op.create_foreign_key('logs_scan_id_fkey', 'logs', 'scans', ['scan_id'], ['id'], ondelete='CASCADE')\n # ### end Alembic commands ###", + "detail": "spectragraph-api.alembic.versions.faceebd6a580_remove_scan_id_of_logs", + "documentation": {} + }, + { + "label": "run_migrations_offline", + "kind": 2, + "importPath": "spectragraph-api.alembic.env", + "description": "spectragraph-api.alembic.env", + "peekOfCode": "def run_migrations_offline() -> None:\n \"\"\"Run migrations in 'offline' mode.\"\"\"\n url = config.get_main_option(\"sqlalchemy.url\")\n context.configure(\n url=url,\n target_metadata=target_metadata,\n literal_binds=True,\n dialect_opts={\"paramstyle\": \"named\"},\n )\n with context.begin_transaction():", + "detail": "spectragraph-api.alembic.env", + "documentation": {} + }, + { + "label": "run_migrations_online", + "kind": 2, + "importPath": "spectragraph-api.alembic.env", + "description": "spectragraph-api.alembic.env", + "peekOfCode": "def run_migrations_online() -> None:\n \"\"\"Run migrations in 'online' mode.\"\"\"\n connectable = engine_from_config(\n config.get_section(config.config_ini_section),\n prefix=\"sqlalchemy.\",\n poolclass=pool.NullPool,\n )\n with connectable.connect() as connection:\n context.configure(connection=connection, target_metadata=target_metadata)\n with context.begin_transaction():", + "detail": "spectragraph-api.alembic.env", + "documentation": {} + }, + { + "label": "config", + "kind": 5, + "importPath": "spectragraph-api.alembic.env", + "description": "spectragraph-api.alembic.env", + "peekOfCode": "config = context.config\nif config.config_file_name is not None:\n fileConfig(config.config_file_name)\ndatabase_url = os.getenv(\"DATABASE_URL\")\nif not database_url:\n raise RuntimeError(\"DATABASE_URL is not defined in .env\")\nconfig.set_main_option(\"sqlalchemy.url\", database_url)\ntarget_metadata = Base.metadata\ndef run_migrations_offline() -> None:\n \"\"\"Run migrations in 'offline' mode.\"\"\"", + "detail": "spectragraph-api.alembic.env", + "documentation": {} + }, + { + "label": "database_url", + "kind": 5, + "importPath": "spectragraph-api.alembic.env", + "description": "spectragraph-api.alembic.env", + "peekOfCode": "database_url = os.getenv(\"DATABASE_URL\")\nif not database_url:\n raise RuntimeError(\"DATABASE_URL is not defined in .env\")\nconfig.set_main_option(\"sqlalchemy.url\", database_url)\ntarget_metadata = Base.metadata\ndef run_migrations_offline() -> None:\n \"\"\"Run migrations in 'offline' mode.\"\"\"\n url = config.get_main_option(\"sqlalchemy.url\")\n context.configure(\n url=url,", + "detail": "spectragraph-api.alembic.env", + "documentation": {} + }, + { + "label": "target_metadata", + "kind": 5, + "importPath": "spectragraph-api.alembic.env", + "description": "spectragraph-api.alembic.env", + "peekOfCode": "target_metadata = Base.metadata\ndef run_migrations_offline() -> None:\n \"\"\"Run migrations in 'offline' mode.\"\"\"\n url = config.get_main_option(\"sqlalchemy.url\")\n context.configure(\n url=url,\n target_metadata=target_metadata,\n literal_binds=True,\n dialect_opts={\"paramstyle\": \"named\"},\n )", + "detail": "spectragraph-api.alembic.env", + "documentation": {} + }, + { + "label": "get_analyses", + "kind": 2, + "importPath": "spectragraph-api.app.api.routes.analysis", + "description": "spectragraph-api.app.api.routes.analysis", + "peekOfCode": "def get_analyses(\n skip: int = 0,limit: int = 90,search: Optional[str] = None,\n db: Session = Depends(get_db), current_user: Profile = Depends(get_current_user)\n): \n MAX_LIMIT = 100\n if limit > MAX_LIMIT :\n raise HTTPException(status_code= status.HTTP_400_BAD_REQUEST, detail=f\"Limit for analyses cannot exceed {MAX_LIMIT}\")\n query= db.query(Analysis).filter(Analysis.owner_id == current_user.id)\n if search:\n search_filter= or_(Analysis.title.ilike(f\"%{search}%\"),Analysis.description.ilike(f\"%{search}%\"))", + "detail": "spectragraph-api.app.api.routes.analysis", + "documentation": {} + }, + { + "label": "create_analysis", + "kind": 2, + "importPath": "spectragraph-api.app.api.routes.analysis", + "description": "spectragraph-api.app.api.routes.analysis", + "peekOfCode": "def create_analysis(\n payload: AnalysisCreate,\n db: Session = Depends(get_db),\n current_user: Profile = Depends(get_current_user),\n):\n check_investigation_permission(\n current_user.id, payload.investigation_id, actions=[\"create\"], db=db\n )\n new_analysis = Analysis(\n id=uuid4(),", + "detail": "spectragraph-api.app.api.routes.analysis", + "documentation": {} + }, + { + "label": "get_analysis_by_id", + "kind": 2, + "importPath": "spectragraph-api.app.api.routes.analysis", + "description": "spectragraph-api.app.api.routes.analysis", + "peekOfCode": "def get_analysis_by_id(\n analysis_id: UUID,\n db: Session = Depends(get_db),\n current_user: Profile = Depends(get_current_user),\n):\n analysis = (\n db.query(Analysis)\n .filter(Analysis.id == analysis_id)\n .first()\n )", + "detail": "spectragraph-api.app.api.routes.analysis", + "documentation": {} + }, + { + "label": "get_analyses_by_investigation", + "kind": 2, + "importPath": "spectragraph-api.app.api.routes.analysis", + "description": "spectragraph-api.app.api.routes.analysis", + "peekOfCode": "def get_analyses_by_investigation(\n investigation_id: UUID,\n db: Session = Depends(get_db),\n current_user: Profile = Depends(get_current_user),\n):\n check_investigation_permission(\n current_user.id, investigation_id, actions=[\"read\"], db=db\n )\n analyses = (\n db.query(Analysis)", + "detail": "spectragraph-api.app.api.routes.analysis", + "documentation": {} + }, + { + "label": "update_analysis", + "kind": 2, + "importPath": "spectragraph-api.app.api.routes.analysis", + "description": "spectragraph-api.app.api.routes.analysis", + "peekOfCode": "def update_analysis(\n analysis_id: UUID,\n payload: AnalysisUpdate,\n db: Session = Depends(get_db),\n current_user: Profile = Depends(get_current_user),\n):\n analysis = (\n db.query(Analysis)\n .filter(Analysis.id == analysis_id)\n .first()", + "detail": "spectragraph-api.app.api.routes.analysis", + "documentation": {} + }, + { + "label": "delete_analysis", + "kind": 2, + "importPath": "spectragraph-api.app.api.routes.analysis", + "description": "spectragraph-api.app.api.routes.analysis", + "peekOfCode": "def delete_analysis(\n analysis_id: UUID,\n db: Session = Depends(get_db),\n current_user: Profile = Depends(get_current_user),\n):\n analysis = (\n db.query(Analysis)\n .filter(Analysis.id == analysis_id)\n .first()\n )", + "detail": "spectragraph-api.app.api.routes.analysis", + "documentation": {} + }, + { + "label": "router", + "kind": 5, + "importPath": "spectragraph-api.app.api.routes.analysis", + "description": "spectragraph-api.app.api.routes.analysis", + "peekOfCode": "router = APIRouter()\n# Get the list of all analyses for the current user\n@router.get(\"\", response_model=AnalysisListResponse)\ndef get_analyses(\n skip: int = 0,limit: int = 90,search: Optional[str] = None,\n db: Session = Depends(get_db), current_user: Profile = Depends(get_current_user)\n): \n MAX_LIMIT = 100\n if limit > MAX_LIMIT :\n raise HTTPException(status_code= status.HTTP_400_BAD_REQUEST, detail=f\"Limit for analyses cannot exceed {MAX_LIMIT}\")", + "detail": "spectragraph-api.app.api.routes.analysis", + "documentation": {} + }, + { + "label": "login_for_access_token", + "kind": 2, + "importPath": "spectragraph-api.app.api.routes.auth", + "description": "spectragraph-api.app.api.routes.auth", + "peekOfCode": "def login_for_access_token(\n form_data: OAuth2PasswordRequestForm = Depends(), db: Session = Depends(get_db)\n):\n try:\n user = db.query(Profile).filter(Profile.email == form_data.username).first()\n if not user or not verify_password(form_data.password, user.hashed_password):\n raise HTTPException(status_code=400, detail=\"Incorrect email or password\")\n access_token = create_access_token(data={\"sub\": user.email})\n return {\n \"access_token\": access_token,", + "detail": "spectragraph-api.app.api.routes.auth", + "documentation": {} + }, + { + "label": "register", + "kind": 2, + "importPath": "spectragraph-api.app.api.routes.auth", + "description": "spectragraph-api.app.api.routes.auth", + "peekOfCode": "def register(user: ProfileCreate, db: Session = Depends(get_db)):\n try:\n existing_user = db.query(Profile).filter(Profile.email == user.email).first()\n if existing_user:\n raise HTTPException(status_code=400, detail=\"Email already registered\")\n hashed_password = get_password_hash(user.password)\n new_user = Profile(email=user.email, hashed_password=hashed_password)\n db.add(new_user)\n db.commit()\n db.refresh(new_user)", + "detail": "spectragraph-api.app.api.routes.auth", + "documentation": {} + }, + { + "label": "router", + "kind": 5, + "importPath": "spectragraph-api.app.api.routes.auth", + "description": "spectragraph-api.app.api.routes.auth", + "peekOfCode": "router = APIRouter()\n@router.post(\"/token\")\ndef login_for_access_token(\n form_data: OAuth2PasswordRequestForm = Depends(), db: Session = Depends(get_db)\n):\n try:\n user = db.query(Profile).filter(Profile.email == form_data.username).first()\n if not user or not verify_password(form_data.password, user.hashed_password):\n raise HTTPException(status_code=400, detail=\"Incorrect email or password\")\n access_token = create_access_token(data={\"sub\": user.email})", + "detail": "spectragraph-api.app.api.routes.auth", + "documentation": {} + }, + { + "label": "ChatRequest", + "kind": 6, + "importPath": "spectragraph-api.app.api.routes.chat", + "description": "spectragraph-api.app.api.routes.chat", + "peekOfCode": "class ChatRequest(BaseModel):\n prompt: str\n context: Optional[List[Dict]] = None\n# Get all chats\n@router.get(\"/\", response_model=List[ChatRead])\ndef get_chats(\n db: Session = Depends(get_db), current_user: Profile = Depends(get_current_user)\n):\n chats = db.query(Chat).filter(Chat.owner_id == current_user.id).all()\n # Sort messages for each chat by created_at in ascending order", + "detail": "spectragraph-api.app.api.routes.chat", + "documentation": {} + }, + { + "label": "clean_context", + "kind": 2, + "importPath": "spectragraph-api.app.api.routes.chat", + "description": "spectragraph-api.app.api.routes.chat", + "peekOfCode": "def clean_context(context: List[Dict]) -> List[Dict]:\n print(context)\n \"\"\"Remove unnecessary keys from context data.\"\"\"\n cleaned = []\n for item in context:\n if isinstance(item, dict):\n # Create a copy and remove unwanted keys\n cleaned_item = item[\"data\"].copy()\n # Remove top-level keys\n cleaned_item.pop(\"id\", None)", + "detail": "spectragraph-api.app.api.routes.chat", + "documentation": {} + }, + { + "label": "get_chats", + "kind": 2, + "importPath": "spectragraph-api.app.api.routes.chat", + "description": "spectragraph-api.app.api.routes.chat", + "peekOfCode": "def get_chats(\n db: Session = Depends(get_db), current_user: Profile = Depends(get_current_user)\n):\n chats = db.query(Chat).filter(Chat.owner_id == current_user.id).all()\n # Sort messages for each chat by created_at in ascending order\n for chat in chats:\n chat.messages.sort(key=lambda x: x.created_at)\n return chats\n# @router.get(\"/delete-all\", status_code=status.HTTP_204_NO_CONTENT)\n# def delete_all_chat(db: Session = Depends(get_db)):", + "detail": "spectragraph-api.app.api.routes.chat", + "documentation": {} + }, + { + "label": "get_chats_by_investigation", + "kind": 2, + "importPath": "spectragraph-api.app.api.routes.chat", + "description": "spectragraph-api.app.api.routes.chat", + "peekOfCode": "def get_chats_by_investigation(\n investigation_id: UUID,\n db: Session = Depends(get_db),\n current_user: Profile = Depends(get_current_user),\n):\n chats = (\n db.query(Chat)\n .filter(\n Chat.investigation_id == investigation_id, Chat.owner_id == current_user.id\n )", + "detail": "spectragraph-api.app.api.routes.chat", + "documentation": {} + }, + { + "label": "create_chat", + "kind": 2, + "importPath": "spectragraph-api.app.api.routes.chat", + "description": "spectragraph-api.app.api.routes.chat", + "peekOfCode": "def create_chat(\n payload: ChatCreate,\n db: Session = Depends(get_db),\n current_user: Profile = Depends(get_current_user),\n):\n new_chat = Chat(\n id=uuid4(),\n title=payload.title,\n description=payload.description,\n owner_id=current_user.id,", + "detail": "spectragraph-api.app.api.routes.chat", + "documentation": {} + }, + { + "label": "get_chat_by_id", + "kind": 2, + "importPath": "spectragraph-api.app.api.routes.chat", + "description": "spectragraph-api.app.api.routes.chat", + "peekOfCode": "def get_chat_by_id(\n chat_id: UUID,\n db: Session = Depends(get_db),\n current_user: Profile = Depends(get_current_user),\n):\n chat = (\n db.query(Chat)\n .filter(Chat.id == chat_id, Chat.owner_id == current_user.id)\n .first()\n )", + "detail": "spectragraph-api.app.api.routes.chat", + "documentation": {} + }, + { + "label": "delete_chat", + "kind": 2, + "importPath": "spectragraph-api.app.api.routes.chat", + "description": "spectragraph-api.app.api.routes.chat", + "peekOfCode": "def delete_chat(\n chat_id: UUID,\n db: Session = Depends(get_db),\n current_user: Profile = Depends(get_current_user),\n):\n chat = (\n db.query(Chat)\n .filter(Chat.id == chat_id, Chat.owner_id == current_user.id)\n .first()\n )", + "detail": "spectragraph-api.app.api.routes.chat", + "documentation": {} + }, + { + "label": "router", + "kind": 5, + "importPath": "spectragraph-api.app.api.routes.chat", + "description": "spectragraph-api.app.api.routes.chat", + "peekOfCode": "router = APIRouter()\ndef clean_context(context: List[Dict]) -> List[Dict]:\n print(context)\n \"\"\"Remove unnecessary keys from context data.\"\"\"\n cleaned = []\n for item in context:\n if isinstance(item, dict):\n # Create a copy and remove unwanted keys\n cleaned_item = item[\"data\"].copy()\n # Remove top-level keys", + "detail": "spectragraph-api.app.api.routes.chat", + "documentation": {} + }, + { + "label": "create_custom_type", + "kind": 2, + "importPath": "spectragraph-api.app.api.routes.custom_types", + "description": "spectragraph-api.app.api.routes.custom_types", + "peekOfCode": "def create_custom_type(\n custom_type: CustomTypeCreate,\n db: Session = Depends(get_db),\n current_user: Profile = Depends(get_current_user),\n):\n \"\"\"\n Create a new custom type.\n Validates the JSON Schema and stores it in the database.\n \"\"\"\n # Validate the JSON Schema", + "detail": "spectragraph-api.app.api.routes.custom_types", + "documentation": {} + }, + { + "label": "list_custom_types", + "kind": 2, + "importPath": "spectragraph-api.app.api.routes.custom_types", + "description": "spectragraph-api.app.api.routes.custom_types", + "peekOfCode": "def list_custom_types(\n status: str = None,\n db: Session = Depends(get_db),\n current_user: Profile = Depends(get_current_user),\n):\n \"\"\"\n List all custom types for the current user.\n Can be filtered by status (draft, published, archived).\n \"\"\"\n query = db.query(CustomType).filter(CustomType.owner_id == current_user.id)", + "detail": "spectragraph-api.app.api.routes.custom_types", + "documentation": {} + }, + { + "label": "get_custom_type", + "kind": 2, + "importPath": "spectragraph-api.app.api.routes.custom_types", + "description": "spectragraph-api.app.api.routes.custom_types", + "peekOfCode": "def get_custom_type(\n id: UUID,\n db: Session = Depends(get_db),\n current_user: Profile = Depends(get_current_user),\n):\n \"\"\"Get a specific custom type by ID.\"\"\"\n custom_type = (\n db.query(CustomType)\n .filter(CustomType.id == id, CustomType.owner_id == current_user.id)\n .first()", + "detail": "spectragraph-api.app.api.routes.custom_types", + "documentation": {} + }, + { + "label": "get_custom_type_schema", + "kind": 2, + "importPath": "spectragraph-api.app.api.routes.custom_types", + "description": "spectragraph-api.app.api.routes.custom_types", + "peekOfCode": "def get_custom_type_schema(\n id: UUID,\n db: Session = Depends(get_db),\n current_user: Profile = Depends(get_current_user),\n):\n \"\"\"Get the raw JSON Schema for a custom type.\"\"\"\n custom_type = (\n db.query(CustomType)\n .filter(CustomType.id == id, CustomType.owner_id == current_user.id)\n .first()", + "detail": "spectragraph-api.app.api.routes.custom_types", + "documentation": {} + }, + { + "label": "update_custom_type", + "kind": 2, + "importPath": "spectragraph-api.app.api.routes.custom_types", + "description": "spectragraph-api.app.api.routes.custom_types", + "peekOfCode": "def update_custom_type(\n id: UUID,\n update_data: CustomTypeUpdate,\n db: Session = Depends(get_db),\n current_user: Profile = Depends(get_current_user),\n):\n \"\"\"\n Update a custom type.\n If the schema is changed, a new checksum is calculated.\n \"\"\"", + "detail": "spectragraph-api.app.api.routes.custom_types", + "documentation": {} + }, + { + "label": "delete_custom_type", + "kind": 2, + "importPath": "spectragraph-api.app.api.routes.custom_types", + "description": "spectragraph-api.app.api.routes.custom_types", + "peekOfCode": "def delete_custom_type(\n id: UUID,\n db: Session = Depends(get_db),\n current_user: Profile = Depends(get_current_user),\n):\n \"\"\"Delete a custom type.\"\"\"\n custom_type = (\n db.query(CustomType)\n .filter(CustomType.id == id, CustomType.owner_id == current_user.id)\n .first()", + "detail": "spectragraph-api.app.api.routes.custom_types", + "documentation": {} + }, + { + "label": "validate_payload", + "kind": 2, + "importPath": "spectragraph-api.app.api.routes.custom_types", + "description": "spectragraph-api.app.api.routes.custom_types", + "peekOfCode": "def validate_payload(\n id: UUID,\n payload_data: CustomTypeValidatePayload,\n db: Session = Depends(get_db),\n current_user: Profile = Depends(get_current_user),\n):\n \"\"\"\n Validate a payload against a custom type's schema.\n This is useful for testing before publishing a type.\n \"\"\"", + "detail": "spectragraph-api.app.api.routes.custom_types", + "documentation": {} + }, + { + "label": "router", + "kind": 5, + "importPath": "spectragraph-api.app.api.routes.custom_types", + "description": "spectragraph-api.app.api.routes.custom_types", + "peekOfCode": "router = APIRouter()\n@router.post(\"\", response_model=CustomTypeRead, status_code=status.HTTP_201_CREATED)\ndef create_custom_type(\n custom_type: CustomTypeCreate,\n db: Session = Depends(get_db),\n current_user: Profile = Depends(get_current_user),\n):\n \"\"\"\n Create a new custom type.\n Validates the JSON Schema and stores it in the database.", + "detail": "spectragraph-api.app.api.routes.custom_types", + "documentation": {} + }, + { + "label": "get_logs_by_sketch", + "kind": 2, + "importPath": "spectragraph-api.app.api.routes.events", + "description": "spectragraph-api.app.api.routes.events", + "peekOfCode": "def get_logs_by_sketch(\n sketch_id: str,\n limit: int = 100,\n since: datetime | None = None,\n db: Session = Depends(get_db),\n # current_user: Profile = Depends(get_current_user)\n):\n \"\"\"Get historical logs for a specific sketch with optional filtering\"\"\"\n # Check if sketch exists\n sketch = db.query(Sketch).filter(Sketch.id == sketch_id).first()", + "detail": "spectragraph-api.app.api.routes.events", + "documentation": {} + }, + { + "label": "delete_scan_logs", + "kind": 2, + "importPath": "spectragraph-api.app.api.routes.events", + "description": "spectragraph-api.app.api.routes.events", + "peekOfCode": "def delete_scan_logs(\n sketch_id: str,\n db: Session = Depends(get_db),\n current_user: Profile = Depends(get_current_user),\n):\n \"\"\"Delete all logs for a specific scan\"\"\"\n try:\n db.query(Log).filter(Log.sketch_id == sketch_id).delete()\n db.commit()\n return {\"message\": f\"All logs have been deleted successfully\"}", + "detail": "spectragraph-api.app.api.routes.events", + "documentation": {} + }, + { + "label": "router", + "kind": 5, + "importPath": "spectragraph-api.app.api.routes.events", + "description": "spectragraph-api.app.api.routes.events", + "peekOfCode": "router = APIRouter()\n@router.get(\"/sketch/{sketch_id}/logs\")\ndef get_logs_by_sketch(\n sketch_id: str,\n limit: int = 100,\n since: datetime | None = None,\n db: Session = Depends(get_db),\n # current_user: Profile = Depends(get_current_user)\n):\n \"\"\"Get historical logs for a specific sketch with optional filtering\"\"\"", + "detail": "spectragraph-api.app.api.routes.events", + "documentation": {} + }, + { + "label": "FlowComputationRequest", + "kind": 6, + "importPath": "spectragraph-api.app.api.routes.flows", + "description": "spectragraph-api.app.api.routes.flows", + "peekOfCode": "class FlowComputationRequest(BaseModel):\n nodes: List[Node]\n edges: List[Edge]\n inputType: Optional[str] = None\nclass FlowComputationResponse(BaseModel):\n flowBranches: List[FlowBranch]\n initialData: Any\nclass StepSimulationRequest(BaseModel):\n flowBranches: List[FlowBranch]\n currentStepIndex: int", + "detail": "spectragraph-api.app.api.routes.flows", + "documentation": {} + }, + { + "label": "FlowComputationResponse", + "kind": 6, + "importPath": "spectragraph-api.app.api.routes.flows", + "description": "spectragraph-api.app.api.routes.flows", + "peekOfCode": "class FlowComputationResponse(BaseModel):\n flowBranches: List[FlowBranch]\n initialData: Any\nclass StepSimulationRequest(BaseModel):\n flowBranches: List[FlowBranch]\n currentStepIndex: int\nclass launchFlowPayload(BaseModel):\n values: List[str]\n sketch_id: str\nrouter = APIRouter()", + "detail": "spectragraph-api.app.api.routes.flows", + "documentation": {} + }, + { + "label": "StepSimulationRequest", + "kind": 6, + "importPath": "spectragraph-api.app.api.routes.flows", + "description": "spectragraph-api.app.api.routes.flows", + "peekOfCode": "class StepSimulationRequest(BaseModel):\n flowBranches: List[FlowBranch]\n currentStepIndex: int\nclass launchFlowPayload(BaseModel):\n values: List[str]\n sketch_id: str\nrouter = APIRouter()\n@router.get(\"/\", response_model=List[FlowRead])\ndef get_flows(\n category: Optional[str] = Query(None),", + "detail": "spectragraph-api.app.api.routes.flows", + "documentation": {} + }, + { + "label": "launchFlowPayload", + "kind": 6, + "importPath": "spectragraph-api.app.api.routes.flows", + "description": "spectragraph-api.app.api.routes.flows", + "peekOfCode": "class launchFlowPayload(BaseModel):\n values: List[str]\n sketch_id: str\nrouter = APIRouter()\n@router.get(\"/\", response_model=List[FlowRead])\ndef get_flows(\n category: Optional[str] = Query(None),\n db: Session = Depends(get_db),\n current_user: Profile = Depends(get_current_user),\n):", + "detail": "spectragraph-api.app.api.routes.flows", + "documentation": {} + }, + { + "label": "get_flows", + "kind": 2, + "importPath": "spectragraph-api.app.api.routes.flows", + "description": "spectragraph-api.app.api.routes.flows", + "peekOfCode": "def get_flows(\n category: Optional[str] = Query(None),\n db: Session = Depends(get_db),\n current_user: Profile = Depends(get_current_user),\n):\n if not category or category.lower() == \"undefined\":\n return db.query(Flow).order_by(Flow.last_updated_at.desc()).all()\n custom_type = (\n db.query(CustomType)\n .filter(", + "detail": "spectragraph-api.app.api.routes.flows", + "documentation": {} + }, + { + "label": "create_flow", + "kind": 2, + "importPath": "spectragraph-api.app.api.routes.flows", + "description": "spectragraph-api.app.api.routes.flows", + "peekOfCode": "def create_flow(\n payload: FlowCreate,\n db: Session = Depends(get_db),\n current_user: Profile = Depends(get_current_user),\n):\n new_flow = Flow(\n id=uuid4(),\n name=payload.name,\n description=payload.description,\n category=payload.category,", + "detail": "spectragraph-api.app.api.routes.flows", + "documentation": {} + }, + { + "label": "get_flow_by_id", + "kind": 2, + "importPath": "spectragraph-api.app.api.routes.flows", + "description": "spectragraph-api.app.api.routes.flows", + "peekOfCode": "def get_flow_by_id(\n flow_id: UUID,\n db: Session = Depends(get_db),\n current_user: Profile = Depends(get_current_user),\n):\n flow = db.query(Flow).filter(Flow.id == flow_id).first()\n if not flow:\n raise HTTPException(status_code=404, detail=\"flow not found\")\n return flow\n# Update a flow by ID", + "detail": "spectragraph-api.app.api.routes.flows", + "documentation": {} + }, + { + "label": "update_flow", + "kind": 2, + "importPath": "spectragraph-api.app.api.routes.flows", + "description": "spectragraph-api.app.api.routes.flows", + "peekOfCode": "def update_flow(\n flow_id: UUID,\n payload: FlowUpdate,\n db: Session = Depends(get_db),\n current_user: Profile = Depends(get_current_user),\n):\n flow = db.query(Flow).filter(Flow.id == flow_id).first()\n if not flow:\n raise HTTPException(status_code=404, detail=\"flow not found\")\n update_data = payload.model_dump(exclude_unset=True)", + "detail": "spectragraph-api.app.api.routes.flows", + "documentation": {} + }, + { + "label": "delete_flow", + "kind": 2, + "importPath": "spectragraph-api.app.api.routes.flows", + "description": "spectragraph-api.app.api.routes.flows", + "peekOfCode": "def delete_flow(\n flow_id: UUID,\n db: Session = Depends(get_db),\n current_user: Profile = Depends(get_current_user),\n):\n flow = db.query(Flow).filter(Flow.id == flow_id).first()\n if not flow:\n raise HTTPException(status_code=404, detail=\"flow not found\")\n db.delete(flow)\n db.commit()", + "detail": "spectragraph-api.app.api.routes.flows", + "documentation": {} + }, + { + "label": "compute_flows", + "kind": 2, + "importPath": "spectragraph-api.app.api.routes.flows", + "description": "spectragraph-api.app.api.routes.flows", + "peekOfCode": "def compute_flows(\n request: FlowComputationRequest, current_user: Profile = Depends(get_current_user)\n):\n initial_data = generate_sample_data(request.inputType or \"string\")\n flow_branches = compute_flow_branches(initial_data, request.nodes, request.edges)\n return FlowComputationResponse(flowBranches=flow_branches, initialData=initial_data)\ndef generate_sample_data(type_str: str) -> Any:\n type_str = type_str.lower() if type_str else \"string\"\n if type_str == \"string\":\n return \"sample_text\"", + "detail": "spectragraph-api.app.api.routes.flows", + "documentation": {} + }, + { + "label": "generate_sample_data", + "kind": 2, + "importPath": "spectragraph-api.app.api.routes.flows", + "description": "spectragraph-api.app.api.routes.flows", + "peekOfCode": "def generate_sample_data(type_str: str) -> Any:\n type_str = type_str.lower() if type_str else \"string\"\n if type_str == \"string\":\n return \"sample_text\"\n elif type_str == \"number\":\n return 42\n elif type_str == \"boolean\":\n return True\n elif type_str == \"array\":\n return [1, 2, 3]", + "detail": "spectragraph-api.app.api.routes.flows", + "documentation": {} + }, + { + "label": "compute_flow_branches", + "kind": 2, + "importPath": "spectragraph-api.app.api.routes.flows", + "description": "spectragraph-api.app.api.routes.flows", + "peekOfCode": "def compute_flow_branches(\n initial_value: Any, nodes: List[Node], edges: List[Edge]\n) -> List[FlowBranch]:\n \"\"\"Computes flow branches based on nodes and edges with proper DFS traversal\"\"\"\n # Find input nodes (starting points)\n input_nodes = [node for node in nodes if node.data.get(\"type\") == \"type\"]\n if not input_nodes:\n return [\n FlowBranch(\n id=\"error\",", + "detail": "spectragraph-api.app.api.routes.flows", + "documentation": {} + }, + { + "label": "process_node_data", + "kind": 2, + "importPath": "spectragraph-api.app.api.routes.flows", + "description": "spectragraph-api.app.api.routes.flows", + "peekOfCode": "def process_node_data(node: Node, inputs: Dict[str, Any]) -> Dict[str, Any]:\n \"\"\"Traite les données de nœud en fonction du type de nœud et des entrées\"\"\"\n outputs = {}\n output_types = node.data[\"outputs\"].get(\"properties\", [])\n for output in output_types:\n output_name = output.get(\"name\", \"output\")\n class_name = node.data.get(\"class_name\", \"\")\n # For simulation purposes, we'll return a placeholder value based on the transform type\n if class_name in [\"ReverseResolveTransform\", \"ResolveTransform\"]:\n # IP/Domain resolution transforms", + "detail": "spectragraph-api.app.api.routes.flows", + "documentation": {} + }, + { + "label": "router", + "kind": 5, + "importPath": "spectragraph-api.app.api.routes.flows", + "description": "spectragraph-api.app.api.routes.flows", + "peekOfCode": "router = APIRouter()\n@router.get(\"/\", response_model=List[FlowRead])\ndef get_flows(\n category: Optional[str] = Query(None),\n db: Session = Depends(get_db),\n current_user: Profile = Depends(get_current_user),\n):\n if not category or category.lower() == \"undefined\":\n return db.query(Flow).order_by(Flow.last_updated_at.desc()).all()\n custom_type = (", + "detail": "spectragraph-api.app.api.routes.flows", + "documentation": {} + }, + { + "label": "get_user_accessible_investigations", + "kind": 2, + "importPath": "spectragraph-api.app.api.routes.investigations", + "description": "spectragraph-api.app.api.routes.investigations", + "peekOfCode": "def get_user_accessible_investigations(\n user_id: str, db: Session, allowed_roles: list[Role] = None\n) -> list[Investigation]:\n \"\"\"\n Returns all investigations accessible to user depending on its roles\n \"\"\"\n query = db.query(Investigation).join(\n InvestigationUserRole,\n InvestigationUserRole.investigation_id == Investigation.id,\n )", + "detail": "spectragraph-api.app.api.routes.investigations", + "documentation": {} + }, + { + "label": "get_investigations", + "kind": 2, + "importPath": "spectragraph-api.app.api.routes.investigations", + "description": "spectragraph-api.app.api.routes.investigations", + "peekOfCode": "def get_investigations(\n db: Session = Depends(get_db),\n current_user: Profile = Depends(get_current_user),\n):\n \"\"\"\n Récupère toutes les investigations accessibles à l'utilisateur\n selon ses rôles (OWNER, EDITOR, VIEWER).\n \"\"\"\n allowed_roles_for_read = [Role.OWNER, Role.EDITOR, Role.VIEWER]\n investigations = get_user_accessible_investigations(", + "detail": "spectragraph-api.app.api.routes.investigations", + "documentation": {} + }, + { + "label": "create_investigation", + "kind": 2, + "importPath": "spectragraph-api.app.api.routes.investigations", + "description": "spectragraph-api.app.api.routes.investigations", + "peekOfCode": "def create_investigation(\n payload: InvestigationCreate,\n db: Session = Depends(get_db),\n current_user: Profile = Depends(get_current_user),\n):\n new_investigation = Investigation(\n id=uuid4(),\n name=payload.name,\n description=payload.description or payload.name,\n owner_id=current_user.id,", + "detail": "spectragraph-api.app.api.routes.investigations", + "documentation": {} + }, + { + "label": "get_investigation_by_id", + "kind": 2, + "importPath": "spectragraph-api.app.api.routes.investigations", + "description": "spectragraph-api.app.api.routes.investigations", + "peekOfCode": "def get_investigation_by_id(\n investigation_id: UUID,\n db: Session = Depends(get_db),\n current_user: Profile = Depends(get_current_user),\n):\n check_investigation_permission(current_user.id, investigation_id, actions=[\"read\"], db=db)\n investigation = (\n db.query(Investigation)\n .options(\n selectinload(Investigation.sketches),", + "detail": "spectragraph-api.app.api.routes.investigations", + "documentation": {} + }, + { + "label": "get_sketches_by_investigation", + "kind": 2, + "importPath": "spectragraph-api.app.api.routes.investigations", + "description": "spectragraph-api.app.api.routes.investigations", + "peekOfCode": "def get_sketches_by_investigation(\n investigation_id: UUID,\n db: Session = Depends(get_db),\n current_user: Profile = Depends(get_current_user),\n):\n sketches = (\n db.query(Sketch).filter(Sketch.investigation_id == investigation_id).all()\n )\n if not sketches:\n raise HTTPException(", + "detail": "spectragraph-api.app.api.routes.investigations", + "documentation": {} + }, + { + "label": "update_investigation", + "kind": 2, + "importPath": "spectragraph-api.app.api.routes.investigations", + "description": "spectragraph-api.app.api.routes.investigations", + "peekOfCode": "def update_investigation(\n investigation_id: UUID,\n payload: InvestigationUpdate,\n db: Session = Depends(get_db),\n current_user: Profile = Depends(get_current_user),\n):\n investigation = (\n db.query(Investigation).filter(Investigation.id == investigation_id).first()\n )\n if not investigation:", + "detail": "spectragraph-api.app.api.routes.investigations", + "documentation": {} + }, + { + "label": "delete_investigation", + "kind": 2, + "importPath": "spectragraph-api.app.api.routes.investigations", + "description": "spectragraph-api.app.api.routes.investigations", + "peekOfCode": "def delete_investigation(\n investigation_id: UUID,\n db: Session = Depends(get_db),\n current_user: Profile = Depends(get_current_user),\n):\n investigation = (\n db.query(Investigation)\n .filter(\n Investigation.id == investigation_id,\n Investigation.owner_id == current_user.id,", + "detail": "spectragraph-api.app.api.routes.investigations", + "documentation": {} + }, + { + "label": "router", + "kind": 5, + "importPath": "spectragraph-api.app.api.routes.investigations", + "description": "spectragraph-api.app.api.routes.investigations", + "peekOfCode": "router = APIRouter()\ndef get_user_accessible_investigations(\n user_id: str, db: Session, allowed_roles: list[Role] = None\n) -> list[Investigation]:\n \"\"\"\n Returns all investigations accessible to user depending on its roles\n \"\"\"\n query = db.query(Investigation).join(\n InvestigationUserRole,\n InvestigationUserRole.investigation_id == Investigation.id,", + "detail": "spectragraph-api.app.api.routes.investigations", + "documentation": {} + }, + { + "label": "get_keys", + "kind": 2, + "importPath": "spectragraph-api.app.api.routes.keys", + "description": "spectragraph-api.app.api.routes.keys", + "peekOfCode": "def get_keys(\n db: Session = Depends(get_db), current_user: Profile = Depends(get_current_user)\n):\n keys = db.query(Key).filter(Key.owner_id == current_user.id).all()\n response_data = [\n KeyRead(\n id=key.id,\n owner_id=key.owner_id,\n name=key.name,\n created_at=key.created_at,", + "detail": "spectragraph-api.app.api.routes.keys", + "documentation": {} + }, + { + "label": "get_key_by_id", + "kind": 2, + "importPath": "spectragraph-api.app.api.routes.keys", + "description": "spectragraph-api.app.api.routes.keys", + "peekOfCode": "def get_key_by_id(\n id: UUID,\n db: Session = Depends(get_db),\n current_user: Profile = Depends(get_current_user),\n):\n key = db.query(Key).filter(Key.id == id, Key.owner_id == current_user.id).first()\n if not key:\n raise HTTPException(status_code=404, detail=\"Key not found\")\n # Create a response with obfuscated key\n response_data = KeyRead(", + "detail": "spectragraph-api.app.api.routes.keys", + "documentation": {} + }, + { + "label": "create_key", + "kind": 2, + "importPath": "spectragraph-api.app.api.routes.keys", + "description": "spectragraph-api.app.api.routes.keys", + "peekOfCode": "def create_key(\n payload: KeyCreate,\n db: Session = Depends(get_db),\n current_user: Profile = Depends(get_current_user),\n):\n try:\n vault = Vault(db=db, owner_id=current_user.id)\n key = vault.set_secret(vault_ref=payload.name, plain_key=payload.key)\n if not key:\n raise HTTPException(", + "detail": "spectragraph-api.app.api.routes.keys", + "documentation": {} + }, + { + "label": "delete_key", + "kind": 2, + "importPath": "spectragraph-api.app.api.routes.keys", + "description": "spectragraph-api.app.api.routes.keys", + "peekOfCode": "def delete_key(\n id: UUID,\n db: Session = Depends(get_db),\n current_user: Profile = Depends(get_current_user),\n):\n key = db.query(Key).filter(Key.id == id, Key.owner_id == current_user.id).first()\n if not key:\n raise HTTPException(status_code=404, detail=\"Key not found\")\n db.delete(key)\n db.commit()", + "detail": "spectragraph-api.app.api.routes.keys", + "documentation": {} + }, + { + "label": "router", + "kind": 5, + "importPath": "spectragraph-api.app.api.routes.keys", + "description": "spectragraph-api.app.api.routes.keys", + "peekOfCode": "router = APIRouter()\n# Get the list of all keys for a user, just the public method for viewing\n@router.get(\"\", response_model=List[KeyRead])\ndef get_keys(\n db: Session = Depends(get_db), current_user: Profile = Depends(get_current_user)\n):\n keys = db.query(Key).filter(Key.owner_id == current_user.id).all()\n response_data = [\n KeyRead(\n id=key.id,", + "detail": "spectragraph-api.app.api.routes.keys", + "documentation": {} + }, + { + "label": "get_scans", + "kind": 2, + "importPath": "spectragraph-api.app.api.routes.scan", + "description": "spectragraph-api.app.api.routes.scan", + "peekOfCode": "def get_scans(\n db: Session = Depends(get_db), current_user: Profile = Depends(get_current_user)\n):\n scans = db.query(Scan).all()\n return scans\n# Get a scan by ID\n@router.get(\"/{id}\", response_model=ScanRead)\ndef get_scan_by_id(\n id: UUID,\n db: Session = Depends(get_db),", + "detail": "spectragraph-api.app.api.routes.scan", + "documentation": {} + }, + { + "label": "get_scan_by_id", + "kind": 2, + "importPath": "spectragraph-api.app.api.routes.scan", + "description": "spectragraph-api.app.api.routes.scan", + "peekOfCode": "def get_scan_by_id(\n id: UUID,\n db: Session = Depends(get_db),\n current_user: Profile = Depends(get_current_user),\n):\n scan = db.query(Scan).filter(Scan.id == id).first()\n if not scan:\n raise HTTPException(status_code=404, detail=\"Transform not found\")\n return scan\n# Delete a scan by ID", + "detail": "spectragraph-api.app.api.routes.scan", + "documentation": {} + }, + { + "label": "delete_scan", + "kind": 2, + "importPath": "spectragraph-api.app.api.routes.scan", + "description": "spectragraph-api.app.api.routes.scan", + "peekOfCode": "def delete_scan(db: Session = Depends(get_db)):\n db.query(Scan).delete()\n db.commit()\n return None\n# Delete a scan by ID\n@router.delete(\"/{id}\", status_code=status.HTTP_204_NO_CONTENT)\ndef delete_scan(\n id: UUID,\n db: Session = Depends(get_db),\n current_user: Profile = Depends(get_current_user),", + "detail": "spectragraph-api.app.api.routes.scan", + "documentation": {} + }, + { + "label": "delete_scan", + "kind": 2, + "importPath": "spectragraph-api.app.api.routes.scan", + "description": "spectragraph-api.app.api.routes.scan", + "peekOfCode": "def delete_scan(\n id: UUID,\n db: Session = Depends(get_db),\n current_user: Profile = Depends(get_current_user),\n):\n scan = (\n db.query(Scan).filter(Scan.id == id, Scan.owner_id == current_user.id).first()\n )\n if not scan:\n raise HTTPException(status_code=404, detail=\"Scan not found\")", + "detail": "spectragraph-api.app.api.routes.scan", + "documentation": {} + }, + { + "label": "router", + "kind": 5, + "importPath": "spectragraph-api.app.api.routes.scan", + "description": "spectragraph-api.app.api.routes.scan", + "peekOfCode": "router = APIRouter()\n# Get the list of all scans\n@router.get(\n \"\",\n response_model=List[ScanRead],\n)\ndef get_scans(\n db: Session = Depends(get_db), current_user: Profile = Depends(get_current_user)\n):\n scans = db.query(Scan).all()", + "detail": "spectragraph-api.app.api.routes.scan", + "documentation": {} + }, + { + "label": "NodeData", + "kind": 6, + "importPath": "spectragraph-api.app.api.routes.sketches", + "description": "spectragraph-api.app.api.routes.sketches", + "peekOfCode": "class NodeData(BaseModel):\n label: str = Field(default=\"Node\", description=\"Label/name of the node\")\n color: str = Field(default=\"Node\", description=\"Color of the node\")\n type: str = Field(default=\"Node\", description=\"Type of the node\")\n # Add any other specific data fields that might be common across nodes\n class Config:\n extra = \"allow\" # Accept any additional fields\nclass NodeInput(BaseModel):\n type: str = Field(..., description=\"Type of the node\")\n data: NodeData = Field(", + "detail": "spectragraph-api.app.api.routes.sketches", + "documentation": {} + }, + { + "label": "NodeInput", + "kind": 6, + "importPath": "spectragraph-api.app.api.routes.sketches", + "description": "spectragraph-api.app.api.routes.sketches", + "peekOfCode": "class NodeInput(BaseModel):\n type: str = Field(..., description=\"Type of the node\")\n data: NodeData = Field(\n default_factory=NodeData, description=\"Additional data for the node\"\n )\ndef dict_to_cypher_props(props: dict, prefix: str = \"\") -> str:\n return \", \".join(f\"{key}: ${prefix}{key}\" for key in props)\nclass NodeDeleteInput(BaseModel):\n nodeIds: List[str]\nclass NodeEditInput(BaseModel):", + "detail": "spectragraph-api.app.api.routes.sketches", + "documentation": {} + }, + { + "label": "NodeDeleteInput", + "kind": 6, + "importPath": "spectragraph-api.app.api.routes.sketches", + "description": "spectragraph-api.app.api.routes.sketches", + "peekOfCode": "class NodeDeleteInput(BaseModel):\n nodeIds: List[str]\nclass NodeEditInput(BaseModel):\n nodeId: str\n data: NodeData = Field(\n default_factory=NodeData, description=\"Updated data for the node\"\n )\nclass NodeMergeInput(BaseModel):\n id: str\n data: NodeData = Field(", + "detail": "spectragraph-api.app.api.routes.sketches", + "documentation": {} + }, + { + "label": "NodeEditInput", + "kind": 6, + "importPath": "spectragraph-api.app.api.routes.sketches", + "description": "spectragraph-api.app.api.routes.sketches", + "peekOfCode": "class NodeEditInput(BaseModel):\n nodeId: str\n data: NodeData = Field(\n default_factory=NodeData, description=\"Updated data for the node\"\n )\nclass NodeMergeInput(BaseModel):\n id: str\n data: NodeData = Field(\n default_factory=NodeData, description=\"Updated data for the node\"\n )", + "detail": "spectragraph-api.app.api.routes.sketches", + "documentation": {} + }, + { + "label": "NodeMergeInput", + "kind": 6, + "importPath": "spectragraph-api.app.api.routes.sketches", + "description": "spectragraph-api.app.api.routes.sketches", + "peekOfCode": "class NodeMergeInput(BaseModel):\n id: str\n data: NodeData = Field(\n default_factory=NodeData, description=\"Updated data for the node\"\n )\n@router.post(\"/create\", response_model=SketchRead, status_code=status.HTTP_201_CREATED)\ndef create_sketch(\n data: SketchCreate,\n db: Session = Depends(get_db),\n current_user: Profile = Depends(get_current_user),", + "detail": "spectragraph-api.app.api.routes.sketches", + "documentation": {} + }, + { + "label": "RelationInput", + "kind": 6, + "importPath": "spectragraph-api.app.api.routes.sketches", + "description": "spectragraph-api.app.api.routes.sketches", + "peekOfCode": "class RelationInput(BaseModel):\n source: str\n target: str\n type: Literal[\"one-way\", \"two-way\"]\n label: str = \"RELATED_TO\" # Optionnel : nom de la relation\n@router.post(\"/{sketch_id}/relations/add\")\n@update_sketch_timestamp\ndef add_edge(\n sketch_id: str,\n relation: RelationInput,", + "detail": "spectragraph-api.app.api.routes.sketches", + "documentation": {} + }, + { + "label": "EntityPreviewModel", + "kind": 6, + "importPath": "spectragraph-api.app.api.routes.sketches", + "description": "spectragraph-api.app.api.routes.sketches", + "peekOfCode": "class EntityPreviewModel(BaseModel):\n \"\"\"Preview model for a single entity.\"\"\"\n row_index: int\n data: Dict[str, Any]\n detected_type: str\n primary_value: str\n confidence: str\nclass AnalyzeFileResponse(BaseModel):\n \"\"\"Response model for file analysis.\"\"\"\n entities: List[EntityPreviewModel]", + "detail": "spectragraph-api.app.api.routes.sketches", + "documentation": {} + }, + { + "label": "AnalyzeFileResponse", + "kind": 6, + "importPath": "spectragraph-api.app.api.routes.sketches", + "description": "spectragraph-api.app.api.routes.sketches", + "peekOfCode": "class AnalyzeFileResponse(BaseModel):\n \"\"\"Response model for file analysis.\"\"\"\n entities: List[EntityPreviewModel]\n total_entities: int\n type_distribution: Dict[str, int]\n columns: List[str]\n@router.post(\"/{sketch_id}/import/analyze\", response_model=AnalyzeFileResponse)\nasync def analyze_import_file(\n sketch_id: str,\n file: UploadFile = File(...),", + "detail": "spectragraph-api.app.api.routes.sketches", + "documentation": {} + }, + { + "label": "EntityMapping", + "kind": 6, + "importPath": "spectragraph-api.app.api.routes.sketches", + "description": "spectragraph-api.app.api.routes.sketches", + "peekOfCode": "class EntityMapping(BaseModel):\n \"\"\"Mapping configuration for an entity (row).\"\"\"\n row_index: int\n entity_type: str\n include: bool = True\n label: Optional[str] = None\n data: Optional[Dict[str, Any]] = None # Edited data from frontend\nclass ImportExecuteResponse(BaseModel):\n \"\"\"Response model for import execution.\"\"\"\n status: str", + "detail": "spectragraph-api.app.api.routes.sketches", + "documentation": {} + }, + { + "label": "ImportExecuteResponse", + "kind": 6, + "importPath": "spectragraph-api.app.api.routes.sketches", + "description": "spectragraph-api.app.api.routes.sketches", + "peekOfCode": "class ImportExecuteResponse(BaseModel):\n \"\"\"Response model for import execution.\"\"\"\n status: str\n nodes_created: int\n nodes_skipped: int\n errors: List[str]\n@router.post(\"/{sketch_id}/import/execute\", response_model=ImportExecuteResponse)\n@update_sketch_timestamp\nasync def execute_import(\n sketch_id: str,", + "detail": "spectragraph-api.app.api.routes.sketches", + "documentation": {} + }, + { + "label": "dict_to_cypher_props", + "kind": 2, + "importPath": "spectragraph-api.app.api.routes.sketches", + "description": "spectragraph-api.app.api.routes.sketches", + "peekOfCode": "def dict_to_cypher_props(props: dict, prefix: str = \"\") -> str:\n return \", \".join(f\"{key}: ${prefix}{key}\" for key in props)\nclass NodeDeleteInput(BaseModel):\n nodeIds: List[str]\nclass NodeEditInput(BaseModel):\n nodeId: str\n data: NodeData = Field(\n default_factory=NodeData, description=\"Updated data for the node\"\n )\nclass NodeMergeInput(BaseModel):", + "detail": "spectragraph-api.app.api.routes.sketches", + "documentation": {} + }, + { + "label": "create_sketch", + "kind": 2, + "importPath": "spectragraph-api.app.api.routes.sketches", + "description": "spectragraph-api.app.api.routes.sketches", + "peekOfCode": "def create_sketch(\n data: SketchCreate,\n db: Session = Depends(get_db),\n current_user: Profile = Depends(get_current_user),\n):\n sketch_data = data.dict()\n check_investigation_permission(\n current_user.id, sketch_data.get(\"investigation_id\"), actions=[\"create\"], db=db\n )\n sketch_data[\"owner_id\"] = current_user.id", + "detail": "spectragraph-api.app.api.routes.sketches", + "documentation": {} + }, + { + "label": "list_sketches", + "kind": 2, + "importPath": "spectragraph-api.app.api.routes.sketches", + "description": "spectragraph-api.app.api.routes.sketches", + "peekOfCode": "def list_sketches(\n db: Session = Depends(get_db), current_user: Profile = Depends(get_current_user)\n):\n return db.query(Sketch).filter(Sketch.owner_id == current_user.id).all()\n@router.get(\"/{sketch_id}\")\ndef get_sketch_by_id(\n sketch_id: UUID,\n db: Session = Depends(get_db),\n current_user: Profile = Depends(get_current_user),\n):", + "detail": "spectragraph-api.app.api.routes.sketches", + "documentation": {} + }, + { + "label": "get_sketch_by_id", + "kind": 2, + "importPath": "spectragraph-api.app.api.routes.sketches", + "description": "spectragraph-api.app.api.routes.sketches", + "peekOfCode": "def get_sketch_by_id(\n sketch_id: UUID,\n db: Session = Depends(get_db),\n current_user: Profile = Depends(get_current_user),\n):\n sketch = db.query(Sketch).filter(Sketch.id == sketch_id).first()\n if not sketch:\n raise HTTPException(status_code=404, detail=\"Sketch not found\")\n check_investigation_permission(\n current_user.id, sketch.investigation_id, actions=[\"read\"], db=db", + "detail": "spectragraph-api.app.api.routes.sketches", + "documentation": {} + }, + { + "label": "update_sketch", + "kind": 2, + "importPath": "spectragraph-api.app.api.routes.sketches", + "description": "spectragraph-api.app.api.routes.sketches", + "peekOfCode": "def update_sketch(\n id: UUID,\n payload: SketchUpdate,\n db: Session = Depends(get_db),\n current_user: Profile = Depends(get_current_user),\n):\n sketch = (\n db.query(Sketch)\n .filter(Sketch.id == id)\n .first()", + "detail": "spectragraph-api.app.api.routes.sketches", + "documentation": {} + }, + { + "label": "delete_sketch", + "kind": 2, + "importPath": "spectragraph-api.app.api.routes.sketches", + "description": "spectragraph-api.app.api.routes.sketches", + "peekOfCode": "def delete_sketch(\n id: UUID,\n db: Session = Depends(get_db),\n current_user: Profile = Depends(get_current_user),\n):\n sketch = (\n db.query(Sketch)\n .filter(Sketch.id == id)\n .first()\n )", + "detail": "spectragraph-api.app.api.routes.sketches", + "documentation": {} + }, + { + "label": "add_node", + "kind": 2, + "importPath": "spectragraph-api.app.api.routes.sketches", + "description": "spectragraph-api.app.api.routes.sketches", + "peekOfCode": "def add_node(\n sketch_id: str,\n node: NodeInput,\n background_tasks: BackgroundTasks,\n db: Session = Depends(get_db),\n current_user: Profile = Depends(get_current_user),\n):\n sketch = db.query(Sketch).filter(Sketch.id == sketch_id).first()\n if not sketch:\n raise HTTPException(status_code=404, detail=\"Sketch not found\")", + "detail": "spectragraph-api.app.api.routes.sketches", + "documentation": {} + }, + { + "label": "add_edge", + "kind": 2, + "importPath": "spectragraph-api.app.api.routes.sketches", + "description": "spectragraph-api.app.api.routes.sketches", + "peekOfCode": "def add_edge(\n sketch_id: str,\n relation: RelationInput,\n background_tasks: BackgroundTasks,\n db: Session = Depends(get_db),\n current_user: Profile = Depends(get_current_user),\n):\n sketch = db.query(Sketch).filter(Sketch.id == sketch_id).first()\n if not sketch:\n raise HTTPException(status_code=404, detail=\"Sketch not found\")", + "detail": "spectragraph-api.app.api.routes.sketches", + "documentation": {} + }, + { + "label": "edit_node", + "kind": 2, + "importPath": "spectragraph-api.app.api.routes.sketches", + "description": "spectragraph-api.app.api.routes.sketches", + "peekOfCode": "def edit_node(\n sketch_id: str,\n node_edit: NodeEditInput,\n background_tasks: BackgroundTasks,\n db: Session = Depends(get_db),\n current_user: Profile = Depends(get_current_user),\n):\n # First verify the sketch exists and belongs to the user\n sketch = db.query(Sketch).filter(Sketch.id == sketch_id).first()\n if not sketch:", + "detail": "spectragraph-api.app.api.routes.sketches", + "documentation": {} + }, + { + "label": "delete_nodes", + "kind": 2, + "importPath": "spectragraph-api.app.api.routes.sketches", + "description": "spectragraph-api.app.api.routes.sketches", + "peekOfCode": "def delete_nodes(\n sketch_id: str,\n nodes: NodeDeleteInput,\n background_tasks: BackgroundTasks,\n db: Session = Depends(get_db),\n current_user: Profile = Depends(get_current_user),\n):\n # First verify the sketch exists and belongs to the user\n sketch = db.query(Sketch).filter(Sketch.id == sketch_id).first()\n if not sketch:", + "detail": "spectragraph-api.app.api.routes.sketches", + "documentation": {} + }, + { + "label": "merge_nodes", + "kind": 2, + "importPath": "spectragraph-api.app.api.routes.sketches", + "description": "spectragraph-api.app.api.routes.sketches", + "peekOfCode": "def merge_nodes(\n sketch_id: str,\n oldNodes: List[str],\n newNode: NodeMergeInput,\n background_tasks: BackgroundTasks,\n db: Session = Depends(get_db),\n current_user: Profile = Depends(get_current_user),\n):\n # 1. Verify the sketch exists\n sketch = db.query(Sketch).filter(Sketch.id == sketch_id).first()", + "detail": "spectragraph-api.app.api.routes.sketches", + "documentation": {} + }, + { + "label": "get_related_nodes", + "kind": 2, + "importPath": "spectragraph-api.app.api.routes.sketches", + "description": "spectragraph-api.app.api.routes.sketches", + "peekOfCode": "def get_related_nodes(\n sketch_id: str,\n node_id: str,\n db: Session = Depends(get_db),\n current_user: Profile = Depends(get_current_user)\n):\n # First verify the sketch exists and belongs to the user\n sketch = db.query(Sketch).filter(Sketch.id == sketch_id).first()\n if not sketch:\n raise HTTPException(status_code=404, detail=\"Sketch not found\")", + "detail": "spectragraph-api.app.api.routes.sketches", + "documentation": {} + }, + { + "label": "router", + "kind": 5, + "importPath": "spectragraph-api.app.api.routes.sketches", + "description": "spectragraph-api.app.api.routes.sketches", + "peekOfCode": "router = APIRouter()\nclass NodeData(BaseModel):\n label: str = Field(default=\"Node\", description=\"Label/name of the node\")\n color: str = Field(default=\"Node\", description=\"Color of the node\")\n type: str = Field(default=\"Node\", description=\"Type of the node\")\n # Add any other specific data fields that might be common across nodes\n class Config:\n extra = \"allow\" # Accept any additional fields\nclass NodeInput(BaseModel):\n type: str = Field(..., description=\"Type of the node\")", + "detail": "spectragraph-api.app.api.routes.sketches", + "documentation": {} + }, + { + "label": "FlowComputationRequest", + "kind": 6, + "importPath": "spectragraph-api.app.api.routes.transforms", + "description": "spectragraph-api.app.api.routes.transforms", + "peekOfCode": "class FlowComputationRequest(BaseModel):\n nodes: List[Node]\n edges: List[Edge]\n inputType: Optional[str] = None\nclass FlowComputationResponse(BaseModel):\n flowBranches: List[FlowBranch]\n initialData: Any\nclass StepSimulationRequest(BaseModel):\n flowBranches: List[FlowBranch]\n currentStepIndex: int", + "detail": "spectragraph-api.app.api.routes.transforms", + "documentation": {} + }, + { + "label": "FlowComputationResponse", + "kind": 6, + "importPath": "spectragraph-api.app.api.routes.transforms", + "description": "spectragraph-api.app.api.routes.transforms", + "peekOfCode": "class FlowComputationResponse(BaseModel):\n flowBranches: List[FlowBranch]\n initialData: Any\nclass StepSimulationRequest(BaseModel):\n flowBranches: List[FlowBranch]\n currentStepIndex: int\nclass launchTransformPayload(BaseModel):\n values: List[str]\n sketch_id: str\nrouter = APIRouter()", + "detail": "spectragraph-api.app.api.routes.transforms", + "documentation": {} + }, + { + "label": "StepSimulationRequest", + "kind": 6, + "importPath": "spectragraph-api.app.api.routes.transforms", + "description": "spectragraph-api.app.api.routes.transforms", + "peekOfCode": "class StepSimulationRequest(BaseModel):\n flowBranches: List[FlowBranch]\n currentStepIndex: int\nclass launchTransformPayload(BaseModel):\n values: List[str]\n sketch_id: str\nrouter = APIRouter()\n# Get the list of all transforms\n@router.get(\"/\")\ndef get_transforms(", + "detail": "spectragraph-api.app.api.routes.transforms", + "documentation": {} + }, + { + "label": "launchTransformPayload", + "kind": 6, + "importPath": "spectragraph-api.app.api.routes.transforms", + "description": "spectragraph-api.app.api.routes.transforms", + "peekOfCode": "class launchTransformPayload(BaseModel):\n values: List[str]\n sketch_id: str\nrouter = APIRouter()\n# Get the list of all transforms\n@router.get(\"/\")\ndef get_transforms(\n category: Optional[str] = Query(None),\n db: Session = Depends(get_db),\n current_user: Profile = Depends(get_current_user),", + "detail": "spectragraph-api.app.api.routes.transforms", + "documentation": {} + }, + { + "label": "get_transforms", + "kind": 2, + "importPath": "spectragraph-api.app.api.routes.transforms", + "description": "spectragraph-api.app.api.routes.transforms", + "peekOfCode": "def get_transforms(\n category: Optional[str] = Query(None),\n db: Session = Depends(get_db),\n current_user: Profile = Depends(get_current_user),\n):\n if not category or category.lower() == \"undefined\":\n return TransformRegistry.list(exclude=[\"n8n_connector\"])\n # Si catégorie custom\n custom_type = (\n db.query(CustomType)", + "detail": "spectragraph-api.app.api.routes.transforms", + "documentation": {} + }, + { + "label": "router", + "kind": 5, + "importPath": "spectragraph-api.app.api.routes.transforms", + "description": "spectragraph-api.app.api.routes.transforms", + "peekOfCode": "router = APIRouter()\n# Get the list of all transforms\n@router.get(\"/\")\ndef get_transforms(\n category: Optional[str] = Query(None),\n db: Session = Depends(get_db),\n current_user: Profile = Depends(get_current_user),\n):\n if not category or category.lower() == \"undefined\":\n return TransformRegistry.list(exclude=[\"n8n_connector\"])", + "detail": "spectragraph-api.app.api.routes.transforms", + "documentation": {} + }, + { + "label": "extract_input_schema", + "kind": 2, + "importPath": "spectragraph-api.app.api.routes.types", + "description": "spectragraph-api.app.api.routes.types", + "peekOfCode": "def extract_input_schema(\n model: Type[BaseModel], label_key: str, icon: Optional[str] = None\n) -> Dict[str, Any]:\n adapter = TypeAdapter(model)\n schema = adapter.json_schema()\n # Use the main schema properties, not the $defs\n type_name = model.__name__\n details = schema\n return {\n \"id\": uuid4(),", + "detail": "spectragraph-api.app.api.routes.types", + "documentation": {} + }, + { + "label": "resolve_field", + "kind": 2, + "importPath": "spectragraph-api.app.api.routes.types", + "description": "spectragraph-api.app.api.routes.types", + "peekOfCode": "def resolve_field(prop: str, details: dict, schema: dict = None) -> Dict:\n \"\"\"_summary_\n The fields can sometimes contain nested complex objects, like:\n - Organization having Individual[] as dirigeants, so we want to skip those.\n Args:\n details (dict): _description_\n schema_context (dict, optional): _description_. Defaults to None.\n Returns:\n str: _description_\n \"\"\"", + "detail": "spectragraph-api.app.api.routes.types", + "documentation": {} + }, + { + "label": "has_enum", + "kind": 2, + "importPath": "spectragraph-api.app.api.routes.types", + "description": "spectragraph-api.app.api.routes.types", + "peekOfCode": "def has_enum(schema: dict) -> bool:\n any_of = schema.get(\"anyOf\", [])\n return any(isinstance(entry, dict) and \"enum\" in entry for entry in any_of)\ndef is_required(schema: dict) -> bool:\n any_of = schema.get(\"anyOf\", [])\n return not any(entry == {\"type\": \"null\"} for entry in any_of)\ndef get_enum_values(schema: dict) -> list:\n enum_values = []\n for entry in schema.get(\"anyOf\", []):\n if isinstance(entry, dict) and \"enum\" in entry:", + "detail": "spectragraph-api.app.api.routes.types", + "documentation": {} + }, + { + "label": "is_required", + "kind": 2, + "importPath": "spectragraph-api.app.api.routes.types", + "description": "spectragraph-api.app.api.routes.types", + "peekOfCode": "def is_required(schema: dict) -> bool:\n any_of = schema.get(\"anyOf\", [])\n return not any(entry == {\"type\": \"null\"} for entry in any_of)\ndef get_enum_values(schema: dict) -> list:\n enum_values = []\n for entry in schema.get(\"anyOf\", []):\n if isinstance(entry, dict) and \"enum\" in entry:\n enum_values.extend(entry[\"enum\"])\n return enum_values", + "detail": "spectragraph-api.app.api.routes.types", + "documentation": {} + }, + { + "label": "get_enum_values", + "kind": 2, + "importPath": "spectragraph-api.app.api.routes.types", + "description": "spectragraph-api.app.api.routes.types", + "peekOfCode": "def get_enum_values(schema: dict) -> list:\n enum_values = []\n for entry in schema.get(\"anyOf\", []):\n if isinstance(entry, dict) and \"enum\" in entry:\n enum_values.extend(entry[\"enum\"])\n return enum_values", + "detail": "spectragraph-api.app.api.routes.types", + "documentation": {} + }, + { + "label": "router", + "kind": 5, + "importPath": "spectragraph-api.app.api.routes.types", + "description": "spectragraph-api.app.api.routes.types", + "peekOfCode": "router = APIRouter()\n# Returns the \"types\" for the sketches\n@router.get(\"/\")\nasync def get_types_list(\n db: Session = Depends(get_db),\n current_user: Profile = Depends(get_current_user)\n):\n types = [\n {\n \"id\": uuid4(),", + "detail": "spectragraph-api.app.api.routes.types", + "documentation": {} + }, + { + "label": "AnalysisCreate", + "kind": 6, + "importPath": "spectragraph-api.app.api.schemas.analysis", + "description": "spectragraph-api.app.api.schemas.analysis", + "peekOfCode": "class AnalysisCreate(BaseModel):\n title: str\n description: Optional[str] = None\n content: Optional[Any] = None\n owner_id: Optional[UUID4] = None\n investigation_id: Optional[UUID4] = None\nclass AnalysisRead(ORMBase):\n id: UUID4\n title: str\n description: Optional[str]", + "detail": "spectragraph-api.app.api.schemas.analysis", + "documentation": {} + }, + { + "label": "AnalysisRead", + "kind": 6, + "importPath": "spectragraph-api.app.api.schemas.analysis", + "description": "spectragraph-api.app.api.schemas.analysis", + "peekOfCode": "class AnalysisRead(ORMBase):\n id: UUID4\n title: str\n description: Optional[str]\n content: Optional[Any]\n created_at: datetime\n last_updated_at: datetime\n owner_id: Optional[UUID4]\n investigation_id: Optional[UUID4]\nclass AnalysisUpdate(BaseModel):", + "detail": "spectragraph-api.app.api.schemas.analysis", + "documentation": {} + }, + { + "label": "AnalysisUpdate", + "kind": 6, + "importPath": "spectragraph-api.app.api.schemas.analysis", + "description": "spectragraph-api.app.api.schemas.analysis", + "peekOfCode": "class AnalysisUpdate(BaseModel):\n title: Optional[str] = None\n description: Optional[str] = None\n content: Optional[Any] = None\n last_updated_at: Optional[datetime] = None\n owner_id: Optional[UUID4] = None\n investigation_id: Optional[UUID4] = None\nclass PaginationMetadata(BaseModel):\n total_count: int\n limit: int", + "detail": "spectragraph-api.app.api.schemas.analysis", + "documentation": {} + }, + { + "label": "PaginationMetadata", + "kind": 6, + "importPath": "spectragraph-api.app.api.schemas.analysis", + "description": "spectragraph-api.app.api.schemas.analysis", + "peekOfCode": "class PaginationMetadata(BaseModel):\n total_count: int\n limit: int\n skip: int\n has_next: bool\nclass AnalysisListResponse(BaseModel):\n items: List[AnalysisRead]\n metadata: PaginationMetadata", + "detail": "spectragraph-api.app.api.schemas.analysis", + "documentation": {} + }, + { + "label": "AnalysisListResponse", + "kind": 6, + "importPath": "spectragraph-api.app.api.schemas.analysis", + "description": "spectragraph-api.app.api.schemas.analysis", + "peekOfCode": "class AnalysisListResponse(BaseModel):\n items: List[AnalysisRead]\n metadata: PaginationMetadata", + "detail": "spectragraph-api.app.api.schemas.analysis", + "documentation": {} + }, + { + "label": "ORMBase", + "kind": 6, + "importPath": "spectragraph-api.app.api.schemas.base", + "description": "spectragraph-api.app.api.schemas.base", + "peekOfCode": "class ORMBase(BaseModel):\n class Config:\n from_attributes = True", + "detail": "spectragraph-api.app.api.schemas.base", + "documentation": {} + }, + { + "label": "ChatMessageRead", + "kind": 6, + "importPath": "spectragraph-api.app.api.schemas.chat", + "description": "spectragraph-api.app.api.schemas.chat", + "peekOfCode": "class ChatMessageRead(BaseModel):\n id: UUID4\n content: Optional[Any] = None\n is_bot: bool\n created_at: datetime\n chat_id: UUID4\n context: Optional[Any] = None\n class Config:\n from_attributes = True\nclass ChatCreate(BaseModel):", + "detail": "spectragraph-api.app.api.schemas.chat", + "documentation": {} + }, + { + "label": "ChatCreate", + "kind": 6, + "importPath": "spectragraph-api.app.api.schemas.chat", + "description": "spectragraph-api.app.api.schemas.chat", + "peekOfCode": "class ChatCreate(BaseModel):\n title: str\n description: Optional[str] = None\n owner_id: Optional[UUID4] = None\n investigation_id: Optional[UUID4] = None\nclass ChatRead(ORMBase):\n id: UUID4\n title: str\n description: Optional[str]\n created_at: datetime", + "detail": "spectragraph-api.app.api.schemas.chat", + "documentation": {} + }, + { + "label": "ChatRead", + "kind": 6, + "importPath": "spectragraph-api.app.api.schemas.chat", + "description": "spectragraph-api.app.api.schemas.chat", + "peekOfCode": "class ChatRead(ORMBase):\n id: UUID4\n title: str\n description: Optional[str]\n created_at: datetime\n last_updated_at: datetime\n owner_id: Optional[UUID4]\n investigation_id: Optional[UUID4]\n messages: List[ChatMessageRead]", + "detail": "spectragraph-api.app.api.schemas.chat", + "documentation": {} + }, + { + "label": "CustomTypeCreate", + "kind": 6, + "importPath": "spectragraph-api.app.api.schemas.custom_type", + "description": "spectragraph-api.app.api.schemas.custom_type", + "peekOfCode": "class CustomTypeCreate(BaseModel):\n \"\"\"Schema for creating a new custom type.\"\"\"\n name: str = Field(..., min_length=1, max_length=255, description=\"Name of the custom type\")\n json_schema: Dict[str, Any] = Field(..., description=\"JSON Schema definition\", alias=\"schema\")\n description: Optional[str] = Field(None, description=\"Optional description of the custom type\")\n status: Optional[str] = Field(\"draft\", description=\"Status: draft or published\")\n class Config:\n populate_by_name = True\n @field_validator('status')\n @classmethod", + "detail": "spectragraph-api.app.api.schemas.custom_type", + "documentation": {} + }, + { + "label": "CustomTypeUpdate", + "kind": 6, + "importPath": "spectragraph-api.app.api.schemas.custom_type", + "description": "spectragraph-api.app.api.schemas.custom_type", + "peekOfCode": "class CustomTypeUpdate(BaseModel):\n \"\"\"Schema for updating an existing custom type.\"\"\"\n name: Optional[str] = Field(None, min_length=1, max_length=255)\n json_schema: Optional[Dict[str, Any]] = Field(None, alias=\"schema\")\n description: Optional[str] = None\n status: Optional[str] = None\n class Config:\n populate_by_name = True\n @field_validator('status')\n @classmethod", + "detail": "spectragraph-api.app.api.schemas.custom_type", + "documentation": {} + }, + { + "label": "CustomTypeRead", + "kind": 6, + "importPath": "spectragraph-api.app.api.schemas.custom_type", + "description": "spectragraph-api.app.api.schemas.custom_type", + "peekOfCode": "class CustomTypeRead(ORMBase):\n \"\"\"Schema for reading a custom type.\"\"\"\n id: UUID4\n name: str\n owner_id: UUID4\n json_schema: Dict[str, Any] = Field(..., alias=\"schema\")\n status: str\n checksum: Optional[str]\n description: Optional[str]\n created_at: datetime", + "detail": "spectragraph-api.app.api.schemas.custom_type", + "documentation": {} + }, + { + "label": "CustomTypeValidatePayload", + "kind": 6, + "importPath": "spectragraph-api.app.api.schemas.custom_type", + "description": "spectragraph-api.app.api.schemas.custom_type", + "peekOfCode": "class CustomTypeValidatePayload(BaseModel):\n \"\"\"Schema for validating a payload against a custom type schema.\"\"\"\n payload: Dict[str, Any] = Field(..., description=\"Data to validate against the schema\")\nclass CustomTypeValidateResponse(BaseModel):\n \"\"\"Response schema for validation.\"\"\"\n valid: bool\n errors: Optional[list[str]] = None", + "detail": "spectragraph-api.app.api.schemas.custom_type", + "documentation": {} + }, + { + "label": "CustomTypeValidateResponse", + "kind": 6, + "importPath": "spectragraph-api.app.api.schemas.custom_type", + "description": "spectragraph-api.app.api.schemas.custom_type", + "peekOfCode": "class CustomTypeValidateResponse(BaseModel):\n \"\"\"Response schema for validation.\"\"\"\n valid: bool\n errors: Optional[list[str]] = None", + "detail": "spectragraph-api.app.api.schemas.custom_type", + "documentation": {} + }, + { + "label": "FeedbackCreate", + "kind": 6, + "importPath": "spectragraph-api.app.api.schemas.feedback", + "description": "spectragraph-api.app.api.schemas.feedback", + "peekOfCode": "class FeedbackCreate(BaseModel):\n content: Optional[str] = None\n owner_id: Optional[UUID4] = None\nclass FeedbackRead(ORMBase):\n id: int\n created_at: datetime\n content: Optional[str] = None\n owner_id: Optional[UUID4]", + "detail": "spectragraph-api.app.api.schemas.feedback", + "documentation": {} + }, + { + "label": "FeedbackRead", + "kind": 6, + "importPath": "spectragraph-api.app.api.schemas.feedback", + "description": "spectragraph-api.app.api.schemas.feedback", + "peekOfCode": "class FeedbackRead(ORMBase):\n id: int\n created_at: datetime\n content: Optional[str] = None\n owner_id: Optional[UUID4]", + "detail": "spectragraph-api.app.api.schemas.feedback", + "documentation": {} + }, + { + "label": "FlowCreate", + "kind": 6, + "importPath": "spectragraph-api.app.api.schemas.flow", + "description": "spectragraph-api.app.api.schemas.flow", + "peekOfCode": "class FlowCreate(BaseModel):\n name: str\n description: Optional[str] = None\n category: Optional[List[str]] = None\n flow_schema: Optional[Dict[str, Any]] = None\nclass FlowRead(ORMBase):\n id: UUID4\n name: str\n description: Optional[str]\n category: Optional[List[str]]", + "detail": "spectragraph-api.app.api.schemas.flow", + "documentation": {} + }, + { + "label": "FlowRead", + "kind": 6, + "importPath": "spectragraph-api.app.api.schemas.flow", + "description": "spectragraph-api.app.api.schemas.flow", + "peekOfCode": "class FlowRead(ORMBase):\n id: UUID4\n name: str\n description: Optional[str]\n category: Optional[List[str]]\n flow_schema: Optional[Dict[str, Any]]\n created_at: datetime\n last_updated_at: datetime\nclass FlowUpdate(BaseModel):\n name: Optional[str] = None", + "detail": "spectragraph-api.app.api.schemas.flow", + "documentation": {} + }, + { + "label": "FlowUpdate", + "kind": 6, + "importPath": "spectragraph-api.app.api.schemas.flow", + "description": "spectragraph-api.app.api.schemas.flow", + "peekOfCode": "class FlowUpdate(BaseModel):\n name: Optional[str] = None\n description: Optional[str] = None\n category: Optional[List[str]] = None\n flow_schema: Optional[Dict[str, Any]] = None", + "detail": "spectragraph-api.app.api.schemas.flow", + "documentation": {} + }, + { + "label": "InvestigationCreate", + "kind": 6, + "importPath": "spectragraph-api.app.api.schemas.investigation", + "description": "spectragraph-api.app.api.schemas.investigation", + "peekOfCode": "class InvestigationCreate(BaseModel):\n name: str\n description: str\n owner_id: Optional[UUID4] = None\n status: Optional[str] = \"active\"\nclass InvestigationRead(ORMBase):\n id: UUID4\n created_at: datetime\n name: str\n description: str", + "detail": "spectragraph-api.app.api.schemas.investigation", + "documentation": {} + }, + { + "label": "InvestigationRead", + "kind": 6, + "importPath": "spectragraph-api.app.api.schemas.investigation", + "description": "spectragraph-api.app.api.schemas.investigation", + "peekOfCode": "class InvestigationRead(ORMBase):\n id: UUID4\n created_at: datetime\n name: str\n description: str\n owner_id: Optional[UUID4]\n last_updated_at: datetime\n status: str\n owner: Optional[ProfileRead] = None\n sketches: list[SketchRead] = []", + "detail": "spectragraph-api.app.api.schemas.investigation", + "documentation": {} + }, + { + "label": "InvestigationProfileCreate", + "kind": 6, + "importPath": "spectragraph-api.app.api.schemas.investigation", + "description": "spectragraph-api.app.api.schemas.investigation", + "peekOfCode": "class InvestigationProfileCreate(BaseModel):\n investigation_id: UUID4\n profile_id: UUID4\n role: Optional[str] = \"member\"\nclass InvestigationProfileRead(ORMBase):\n id: int\n created_at: datetime\n investigation_id: UUID4\n profile_id: UUID4\n role: str", + "detail": "spectragraph-api.app.api.schemas.investigation", + "documentation": {} + }, + { + "label": "InvestigationProfileRead", + "kind": 6, + "importPath": "spectragraph-api.app.api.schemas.investigation", + "description": "spectragraph-api.app.api.schemas.investigation", + "peekOfCode": "class InvestigationProfileRead(ORMBase):\n id: int\n created_at: datetime\n investigation_id: UUID4\n profile_id: UUID4\n role: str\nclass InvestigationUpdate(BaseModel):\n name: str\n description: Optional[str] = None\n last_updated_at: datetime", + "detail": "spectragraph-api.app.api.schemas.investigation", + "documentation": {} + }, + { + "label": "InvestigationUpdate", + "kind": 6, + "importPath": "spectragraph-api.app.api.schemas.investigation", + "description": "spectragraph-api.app.api.schemas.investigation", + "peekOfCode": "class InvestigationUpdate(BaseModel):\n name: str\n description: Optional[str] = None\n last_updated_at: datetime\n status: str", + "detail": "spectragraph-api.app.api.schemas.investigation", + "documentation": {} + }, + { + "label": "InvestigationProfileCreate", + "kind": 6, + "importPath": "spectragraph-api.app.api.schemas.investigation_profiles", + "description": "spectragraph-api.app.api.schemas.investigation_profiles", + "peekOfCode": "class InvestigationProfileCreate(BaseModel):\n investigation_id: UUID4\n profile_id: UUID4\n role: Optional[str] = \"member\"\nclass InvestigationProfileRead(ORMBase):\n id: int\n created_at: datetime\n investigation_id: UUID4\n profile_id: UUID4\n role: str", + "detail": "spectragraph-api.app.api.schemas.investigation_profiles", + "documentation": {} + }, + { + "label": "InvestigationProfileRead", + "kind": 6, + "importPath": "spectragraph-api.app.api.schemas.investigation_profiles", + "description": "spectragraph-api.app.api.schemas.investigation_profiles", + "peekOfCode": "class InvestigationProfileRead(ORMBase):\n id: int\n created_at: datetime\n investigation_id: UUID4\n profile_id: UUID4\n role: str", + "detail": "spectragraph-api.app.api.schemas.investigation_profiles", + "documentation": {} + }, + { + "label": "KeyCreate", + "kind": 6, + "importPath": "spectragraph-api.app.api.schemas.key", + "description": "spectragraph-api.app.api.schemas.key", + "peekOfCode": "class KeyCreate(BaseModel):\n key: str\n name: str\nclass KeyRead(ORMBase):\n id: UUID4\n owner_id: UUID4\n name: str\n created_at: datetime", + "detail": "spectragraph-api.app.api.schemas.key", + "documentation": {} + }, + { + "label": "KeyRead", + "kind": 6, + "importPath": "spectragraph-api.app.api.schemas.key", + "description": "spectragraph-api.app.api.schemas.key", + "peekOfCode": "class KeyRead(ORMBase):\n id: UUID4\n owner_id: UUID4\n name: str\n created_at: datetime", + "detail": "spectragraph-api.app.api.schemas.key", + "documentation": {} + }, + { + "label": "ProfileCreate", + "kind": 6, + "importPath": "spectragraph-api.app.api.schemas.profile", + "description": "spectragraph-api.app.api.schemas.profile", + "peekOfCode": "class ProfileCreate(BaseModel):\n email: EmailStr\n password: str\nclass ProfileRead(ORMBase):\n id: UUID4\n first_name: Optional[str]\n last_name: Optional[str]\n avatar_url: Optional[str]", + "detail": "spectragraph-api.app.api.schemas.profile", + "documentation": {} + }, + { + "label": "ProfileRead", + "kind": 6, + "importPath": "spectragraph-api.app.api.schemas.profile", + "description": "spectragraph-api.app.api.schemas.profile", + "peekOfCode": "class ProfileRead(ORMBase):\n id: UUID4\n first_name: Optional[str]\n last_name: Optional[str]\n avatar_url: Optional[str]", + "detail": "spectragraph-api.app.api.schemas.profile", + "documentation": {} + }, + { + "label": "ScanCreate", + "kind": 6, + "importPath": "spectragraph-api.app.api.schemas.scan", + "description": "spectragraph-api.app.api.schemas.scan", + "peekOfCode": "class ScanCreate(BaseModel):\n values: Optional[List[str]] = None\n sketch_id: Optional[UUID4] = None\n status: Optional[str] = None\n results: Optional[Any] = None\nclass ScanRead(ORMBase):\n id: UUID4\n sketch_id: Optional[UUID4]\n status: Optional[str]", + "detail": "spectragraph-api.app.api.schemas.scan", + "documentation": {} + }, + { + "label": "ScanRead", + "kind": 6, + "importPath": "spectragraph-api.app.api.schemas.scan", + "description": "spectragraph-api.app.api.schemas.scan", + "peekOfCode": "class ScanRead(ORMBase):\n id: UUID4\n sketch_id: Optional[UUID4]\n status: Optional[str]", + "detail": "spectragraph-api.app.api.schemas.scan", + "documentation": {} + }, + { + "label": "SketchCreate", + "kind": 6, + "importPath": "spectragraph-api.app.api.schemas.sketch", + "description": "spectragraph-api.app.api.schemas.sketch", + "peekOfCode": "class SketchCreate(BaseModel):\n title: str\n description: str\n owner_id: Optional[UUID4] = None\n investigation_id: UUID4\n status: Optional[str] = \"active\"\nclass SketchRead(ORMBase):\n id: UUID4\n title: str\n description: str", + "detail": "spectragraph-api.app.api.schemas.sketch", + "documentation": {} + }, + { + "label": "SketchRead", + "kind": 6, + "importPath": "spectragraph-api.app.api.schemas.sketch", + "description": "spectragraph-api.app.api.schemas.sketch", + "peekOfCode": "class SketchRead(ORMBase):\n id: UUID4\n title: str\n description: str\n created_at: datetime\n owner_id: Optional[UUID4]\n investigation_id: UUID4\n last_updated_at: datetime\n status: str\nclass SketchProfileCreate(BaseModel):", + "detail": "spectragraph-api.app.api.schemas.sketch", + "documentation": {} + }, + { + "label": "SketchProfileCreate", + "kind": 6, + "importPath": "spectragraph-api.app.api.schemas.sketch", + "description": "spectragraph-api.app.api.schemas.sketch", + "peekOfCode": "class SketchProfileCreate(BaseModel):\n sketch_id: UUID4\n profile_id: UUID4\n role: Optional[str] = \"editor\"\nclass SketchProfileRead(ORMBase):\n id: int\n created_at: datetime\n sketch_id: UUID4\n profile_id: UUID4\n role: str", + "detail": "spectragraph-api.app.api.schemas.sketch", + "documentation": {} + }, + { + "label": "SketchProfileRead", + "kind": 6, + "importPath": "spectragraph-api.app.api.schemas.sketch", + "description": "spectragraph-api.app.api.schemas.sketch", + "peekOfCode": "class SketchProfileRead(ORMBase):\n id: int\n created_at: datetime\n sketch_id: UUID4\n profile_id: UUID4\n role: str\nclass SketchUpdate(BaseModel):\n title: Optional[str] = None\n description: Optional[str] = None\n owner_id: Optional[UUID] = None", + "detail": "spectragraph-api.app.api.schemas.sketch", + "documentation": {} + }, + { + "label": "SketchUpdate", + "kind": 6, + "importPath": "spectragraph-api.app.api.schemas.sketch", + "description": "spectragraph-api.app.api.schemas.sketch", + "peekOfCode": "class SketchUpdate(BaseModel):\n title: Optional[str] = None\n description: Optional[str] = None\n owner_id: Optional[UUID] = None\n status: Optional[str] = None\n investigation_id: Optional[UUID] = None\nclass SketchIn(BaseModel):\n title: Optional[str] = None\n description: Optional[str] = None\n owner_id: Optional[UUID] = None", + "detail": "spectragraph-api.app.api.schemas.sketch", + "documentation": {} + }, + { + "label": "SketchIn", + "kind": 6, + "importPath": "spectragraph-api.app.api.schemas.sketch", + "description": "spectragraph-api.app.api.schemas.sketch", + "peekOfCode": "class SketchIn(BaseModel):\n title: Optional[str] = None\n description: Optional[str] = None\n owner_id: Optional[UUID] = None\n status: Optional[str] = \"active\"\n investigation_id: UUID # requis", + "detail": "spectragraph-api.app.api.schemas.sketch", + "documentation": {} + }, + { + "label": "TransformCreate", + "kind": 6, + "importPath": "spectragraph-api.app.api.schemas.transform", + "description": "spectragraph-api.app.api.schemas.transform", + "peekOfCode": "class TransformCreate(BaseModel):\n name: str\n description: Optional[str] = None\n category: Optional[List[str]] = None\nclass TransformRead(ORMBase):\n id: UUID4\n name: str\n class_name: str\n description: Optional[str]\n category: Optional[List[str]]", + "detail": "spectragraph-api.app.api.schemas.transform", + "documentation": {} + }, + { + "label": "TransformRead", + "kind": 6, + "importPath": "spectragraph-api.app.api.schemas.transform", + "description": "spectragraph-api.app.api.schemas.transform", + "peekOfCode": "class TransformRead(ORMBase):\n id: UUID4\n name: str\n class_name: str\n description: Optional[str]\n category: Optional[List[str]]\n flow_schema: Optional[Dict[str, Any]]\nclass TransformUpdate(BaseModel):\n name: Optional[str] = None\n class_name: str = None", + "detail": "spectragraph-api.app.api.schemas.transform", + "documentation": {} + }, + { + "label": "TransformUpdate", + "kind": 6, + "importPath": "spectragraph-api.app.api.schemas.transform", + "description": "spectragraph-api.app.api.schemas.transform", + "peekOfCode": "class TransformUpdate(BaseModel):\n name: Optional[str] = None\n class_name: str = None\n description: Optional[str] = None\n category: Optional[List[str]] = None", + "detail": "spectragraph-api.app.api.schemas.transform", + "documentation": {} + }, + { + "label": "get_current_user", + "kind": 2, + "importPath": "spectragraph-api.app.api.deps", + "description": "spectragraph-api.app.api.deps", + "peekOfCode": "def get_current_user(\n token: str = Depends(oauth2_scheme), db: Session = Depends(get_db)\n) -> Profile:\n credentials_exception = HTTPException(\n status_code=status.HTTP_401_UNAUTHORIZED,\n detail=\"Could not validate credentials\",\n headers={\"WWW-Authenticate\": \"Bearer\"},\n )\n try:\n payload = jwt.decode(token, AUTH_SECRET, algorithms=[ALGORITHM])", + "detail": "spectragraph-api.app.api.deps", + "documentation": {} + }, + { + "label": "AUTH_SECRET", + "kind": 5, + "importPath": "spectragraph-api.app.api.deps", + "description": "spectragraph-api.app.api.deps", + "peekOfCode": "AUTH_SECRET = os.getenv(\"AUTH_SECRET\")\nload_dotenv()\noauth2_scheme = OAuth2PasswordBearer(tokenUrl=\"token\")\ndef get_current_user(\n token: str = Depends(oauth2_scheme), db: Session = Depends(get_db)\n) -> Profile:\n credentials_exception = HTTPException(\n status_code=status.HTTP_401_UNAUTHORIZED,\n detail=\"Could not validate credentials\",\n headers={\"WWW-Authenticate\": \"Bearer\"},", + "detail": "spectragraph-api.app.api.deps", + "documentation": {} + }, + { + "label": "oauth2_scheme", + "kind": 5, + "importPath": "spectragraph-api.app.api.deps", + "description": "spectragraph-api.app.api.deps", + "peekOfCode": "oauth2_scheme = OAuth2PasswordBearer(tokenUrl=\"token\")\ndef get_current_user(\n token: str = Depends(oauth2_scheme), db: Session = Depends(get_db)\n) -> Profile:\n credentials_exception = HTTPException(\n status_code=status.HTTP_401_UNAUTHORIZED,\n detail=\"Could not validate credentials\",\n headers={\"WWW-Authenticate\": \"Bearer\"},\n )\n try:", + "detail": "spectragraph-api.app.api.deps", + "documentation": {} + }, + { + "label": "update_sketch_last_modified", + "kind": 2, + "importPath": "spectragraph-api.app.api.sketch_utils", + "description": "spectragraph-api.app.api.sketch_utils", + "peekOfCode": "def update_sketch_last_modified(db: Session, sketch_id: str | UUID) -> None:\n \"\"\"\n Update the last_updated_at timestamp for a sketch and its parent investigation.\n This function is designed to be run as a background task to avoid\n blocking the response. It updates both the sketch's and its parent\n investigation's last_updated_at fields to the current time.\n Args:\n db: SQLAlchemy database session\n sketch_id: The ID of the sketch to update\n \"\"\"", + "detail": "spectragraph-api.app.api.sketch_utils", + "documentation": {} + }, + { + "label": "update_sketch_timestamp", + "kind": 2, + "importPath": "spectragraph-api.app.api.sketch_utils", + "description": "spectragraph-api.app.api.sketch_utils", + "peekOfCode": "def update_sketch_timestamp(func: Callable) -> Callable:\n \"\"\"\n Decorator to automatically update sketch's last_updated_at timestamp.\n This decorator:\n 1. Extracts the sketch_id from route parameters\n 2. Schedules a background task to update last_updated_at\n 3. Returns the response immediately (non-blocking)\n Usage:\n @router.post(\"/{sketch_id}/nodes/add\")\n @update_sketch_timestamp", + "detail": "spectragraph-api.app.api.sketch_utils", + "documentation": {} + }, + { + "label": "can_user", + "kind": 2, + "importPath": "spectragraph-api.app.security.permissions", + "description": "spectragraph-api.app.security.permissions", + "peekOfCode": "def can_user(roles: list[Role], actions: list[str]) -> bool:\n \"\"\"\n Vérifie si au moins un rôle de la liste autorise au moins une action de la liste.\n \"\"\"\n for role in roles:\n for action in actions:\n if role == Role.OWNER:\n return True\n if role == Role.EDITOR and action in [\"read\", \"create\", \"update\"]:\n return True", + "detail": "spectragraph-api.app.security.permissions", + "documentation": {} + }, + { + "label": "check_investigation_permission", + "kind": 2, + "importPath": "spectragraph-api.app.security.permissions", + "description": "spectragraph-api.app.security.permissions", + "peekOfCode": "def check_investigation_permission(user_id: str, investigation_id: str, actions: list[str], db):\n role_entry = (\n db.query(InvestigationUserRole)\n .filter_by(user_id=user_id, investigation_id=investigation_id)\n .first()\n )\n if not role_entry or not can_user(role_entry.roles, actions):\n raise HTTPException(status_code=403, detail=\"Forbidden\")\n return True", + "detail": "spectragraph-api.app.security.permissions", + "documentation": {} + }, + { + "label": "validate_json_schema", + "kind": 2, + "importPath": "spectragraph-api.app.utils.custom_types", + "description": "spectragraph-api.app.utils.custom_types", + "peekOfCode": "def validate_json_schema(schema: Dict[str, Any]) -> None:\n \"\"\"\n Validate that a schema is a valid JSON Schema.\n Args:\n schema: The JSON Schema to validate\n Raises:\n HTTPException: If the schema is invalid\n \"\"\"\n try:\n Draft7Validator.check_schema(schema)", + "detail": "spectragraph-api.app.utils.custom_types", + "documentation": {} + }, + { + "label": "validate_payload_against_schema", + "kind": 2, + "importPath": "spectragraph-api.app.utils.custom_types", + "description": "spectragraph-api.app.utils.custom_types", + "peekOfCode": "def validate_payload_against_schema(payload: Dict[str, Any], schema: Dict[str, Any]) -> tuple[bool, list[str]]:\n \"\"\"\n Validate a payload against a JSON Schema.\n Args:\n payload: The data to validate\n schema: The JSON Schema to validate against\n Returns:\n Tuple of (is_valid, error_messages)\n \"\"\"\n validator = Draft7Validator(schema)", + "detail": "spectragraph-api.app.utils.custom_types", + "documentation": {} + }, + { + "label": "calculate_schema_checksum", + "kind": 2, + "importPath": "spectragraph-api.app.utils.custom_types", + "description": "spectragraph-api.app.utils.custom_types", + "peekOfCode": "def calculate_schema_checksum(schema: Dict[str, Any]) -> str:\n \"\"\"\n Calculate a checksum for a schema to detect changes.\n Args:\n schema: The JSON Schema\n Returns:\n SHA256 checksum of the schema\n \"\"\"\n schema_str = json.dumps(schema, sort_keys=True)\n return hashlib.sha256(schema_str.encode()).hexdigest()", + "detail": "spectragraph-api.app.utils.custom_types", + "documentation": {} + }, + { + "label": "jsonschema_to_pydantic", + "kind": 2, + "importPath": "spectragraph-api.app.utils.custom_types", + "description": "spectragraph-api.app.utils.custom_types", + "peekOfCode": "def jsonschema_to_pydantic(schema: Dict[str, Any], model_name: str = \"DynamicModel\") -> Type[BaseModel]:\n \"\"\"\n Convert a JSON Schema to a Pydantic model.\n Args:\n schema: The JSON Schema definition\n model_name: Name for the generated Pydantic model\n Returns:\n A dynamically created Pydantic model class\n Raises:\n HTTPException: If conversion fails", + "detail": "spectragraph-api.app.utils.custom_types", + "documentation": {} + }, + { + "label": "TYPE_MAP", + "kind": 5, + "importPath": "spectragraph-api.app.utils.custom_types", + "description": "spectragraph-api.app.utils.custom_types", + "peekOfCode": "TYPE_MAP = {\n \"string\": str,\n \"integer\": int,\n \"number\": float,\n \"boolean\": bool,\n \"object\": dict,\n \"array\": list,\n \"null\": type(None),\n}\n# Mapping of JSON Schema formats to Pydantic types", + "detail": "spectragraph-api.app.utils.custom_types", + "documentation": {} + }, + { + "label": "FORMAT_MAP", + "kind": 5, + "importPath": "spectragraph-api.app.utils.custom_types", + "description": "spectragraph-api.app.utils.custom_types", + "peekOfCode": "FORMAT_MAP = {\n \"email\": EmailStr,\n \"uri\": str,\n \"uuid\": str,\n \"date\": str,\n \"date-time\": str,\n}\n# Whitelist of allowed JSON Schema types for security\nALLOWED_TYPES = {\"string\", \"integer\", \"number\", \"boolean\", \"object\", \"array\"}\ndef validate_json_schema(schema: Dict[str, Any]) -> None:", + "detail": "spectragraph-api.app.utils.custom_types", + "documentation": {} + }, + { + "label": "ALLOWED_TYPES", + "kind": 5, + "importPath": "spectragraph-api.app.utils.custom_types", + "description": "spectragraph-api.app.utils.custom_types", + "peekOfCode": "ALLOWED_TYPES = {\"string\", \"integer\", \"number\", \"boolean\", \"object\", \"array\"}\ndef validate_json_schema(schema: Dict[str, Any]) -> None:\n \"\"\"\n Validate that a schema is a valid JSON Schema.\n Args:\n schema: The JSON Schema to validate\n Raises:\n HTTPException: If the schema is invalid\n \"\"\"\n try:", + "detail": "spectragraph-api.app.utils.custom_types", + "documentation": {} + }, + { + "label": "logger", + "kind": 5, + "importPath": "spectragraph-api.app.exceptions", + "description": "spectragraph-api.app.exceptions", + "peekOfCode": "logger = logging.getLogger(__name__)\nasync def global_exception_handler(request: Request, exc: Exception) -> JSONResponse:\n logger.error(f\"Global exception: {str(exc)}\", exc_info=True)\n return JSONResponse(\n status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,\n content={\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred. Please verify your request or contact support.\",", + "detail": "spectragraph-api.app.exceptions", + "documentation": {} + }, + { + "label": "JSONFormatter", + "kind": 6, + "importPath": "spectragraph-api.app.logging_config", + "description": "spectragraph-api.app.logging_config", + "peekOfCode": "class JSONFormatter(logging.Formatter):\n def format(self, record: logging.LogRecord) -> str:\n log_record: Dict[str, Any] = {\n \"timestamp\": self.formatTime(record, self.datefmt),\n \"level\": record.levelname,\n \"message\": record.getMessage(),\n \"module\": record.module,\n \"funcName\": record.funcName,\n \"lineNo\": record.lineno,\n }", + "detail": "spectragraph-api.app.logging_config", + "documentation": {} + }, + { + "label": "setup_logging", + "kind": 2, + "importPath": "spectragraph-api.app.logging_config", + "description": "spectragraph-api.app.logging_config", + "peekOfCode": "def setup_logging():\n root_logger = logging.getLogger()\n root_logger.setLevel(logging.INFO)\n handler = logging.StreamHandler(sys.stdout)\n formatter = JSONFormatter()\n handler.setFormatter(formatter)\n root_logger.handlers = []\n root_logger.addHandler(handler)\n for logger_name in [\"uvicorn\", \"uvicorn.access\", \"uvicorn.error\"]:\n logger = logging.getLogger(logger_name)", + "detail": "spectragraph-api.app.logging_config", + "documentation": {} + }, + { + "label": "URI", + "kind": 5, + "importPath": "spectragraph-api.app.main", + "description": "spectragraph-api.app.main", + "peekOfCode": "URI = os.getenv(\"NEO4J_URI_BOLT\")\nUSERNAME = os.getenv(\"NEO4J_USERNAME\")\nPASSWORD = os.getenv(\"NEO4J_PASSWORD\")\norigins = [\n \"*\",\n]\nsetup_logging()\napp = FastAPI()\nneo4j_connection = Neo4jConnection(URI, USERNAME, PASSWORD)\n@app.on_event(\"startup\")", + "detail": "spectragraph-api.app.main", + "documentation": {} + }, + { + "label": "USERNAME", + "kind": 5, + "importPath": "spectragraph-api.app.main", + "description": "spectragraph-api.app.main", + "peekOfCode": "USERNAME = os.getenv(\"NEO4J_USERNAME\")\nPASSWORD = os.getenv(\"NEO4J_PASSWORD\")\norigins = [\n \"*\",\n]\nsetup_logging()\napp = FastAPI()\nneo4j_connection = Neo4jConnection(URI, USERNAME, PASSWORD)\n@app.on_event(\"startup\")\nasync def startup_db_check():", + "detail": "spectragraph-api.app.main", + "documentation": {} + }, + { + "label": "PASSWORD", + "kind": 5, + "importPath": "spectragraph-api.app.main", + "description": "spectragraph-api.app.main", + "peekOfCode": "PASSWORD = os.getenv(\"NEO4J_PASSWORD\")\norigins = [\n \"*\",\n]\nsetup_logging()\napp = FastAPI()\nneo4j_connection = Neo4jConnection(URI, USERNAME, PASSWORD)\n@app.on_event(\"startup\")\nasync def startup_db_check():\n logger = logging.getLogger(__name__)", + "detail": "spectragraph-api.app.main", + "documentation": {} + }, + { + "label": "origins", + "kind": 5, + "importPath": "spectragraph-api.app.main", + "description": "spectragraph-api.app.main", + "peekOfCode": "origins = [\n \"*\",\n]\nsetup_logging()\napp = FastAPI()\nneo4j_connection = Neo4jConnection(URI, USERNAME, PASSWORD)\n@app.on_event(\"startup\")\nasync def startup_db_check():\n logger = logging.getLogger(__name__)\n try:", + "detail": "spectragraph-api.app.main", + "documentation": {} + }, + { + "label": "app", + "kind": 5, + "importPath": "spectragraph-api.app.main", + "description": "spectragraph-api.app.main", + "peekOfCode": "app = FastAPI()\nneo4j_connection = Neo4jConnection(URI, USERNAME, PASSWORD)\n@app.on_event(\"startup\")\nasync def startup_db_check():\n logger = logging.getLogger(__name__)\n try:\n ensure_db_connection()\n except DatabaseUnavailableError as exc:\n logger.error(\"Database unavailable on startup: %s\", exc)\n # exit cleanly for local/dev environment", + "detail": "spectragraph-api.app.main", + "documentation": {} + }, + { + "label": "neo4j_connection", + "kind": 5, + "importPath": "spectragraph-api.app.main", + "description": "spectragraph-api.app.main", + "peekOfCode": "neo4j_connection = Neo4jConnection(URI, USERNAME, PASSWORD)\n@app.on_event(\"startup\")\nasync def startup_db_check():\n logger = logging.getLogger(__name__)\n try:\n ensure_db_connection()\n except DatabaseUnavailableError as exc:\n logger.error(\"Database unavailable on startup: %s\", exc)\n # exit cleanly for local/dev environment\n sys.exit(1)", + "detail": "spectragraph-api.app.main", + "documentation": {} + }, + { + "label": "is_valid_ip", + "kind": 2, + "importPath": "spectragraph-api.app.utils", + "description": "spectragraph-api.app.utils", + "peekOfCode": "def is_valid_ip(address: str) -> bool:\n try:\n ipaddress.ip_address(address)\n return True\n except ValueError:\n return False\ndef is_valid_username(username: str) -> bool:\n if not re.match(r\"^[a-zA-Z0-9_-]{3,30}$\", username):\n return False\n return True", + "detail": "spectragraph-api.app.utils", + "documentation": {} + }, + { + "label": "is_valid_username", + "kind": 2, + "importPath": "spectragraph-api.app.utils", + "description": "spectragraph-api.app.utils", + "peekOfCode": "def is_valid_username(username: str) -> bool:\n if not re.match(r\"^[a-zA-Z0-9_-]{3,30}$\", username):\n return False\n return True\ndef is_valid_email(email: str) -> bool:\n if not re.match(r\"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$\", email):\n return False\n return True\ndef is_valid_domain(url_or_domain: str) -> str:\n try:", + "detail": "spectragraph-api.app.utils", + "documentation": {} + }, + { + "label": "is_valid_email", + "kind": 2, + "importPath": "spectragraph-api.app.utils", + "description": "spectragraph-api.app.utils", + "peekOfCode": "def is_valid_email(email: str) -> bool:\n if not re.match(r\"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$\", email):\n return False\n return True\ndef is_valid_domain(url_or_domain: str) -> str:\n try:\n parsed = urlparse(\n url_or_domain if \"://\" in url_or_domain else \"http://\" + url_or_domain\n )\n hostname = parsed.hostname or url_or_domain", + "detail": "spectragraph-api.app.utils", + "documentation": {} + }, + { + "label": "is_valid_domain", + "kind": 2, + "importPath": "spectragraph-api.app.utils", + "description": "spectragraph-api.app.utils", + "peekOfCode": "def is_valid_domain(url_or_domain: str) -> str:\n try:\n parsed = urlparse(\n url_or_domain if \"://\" in url_or_domain else \"http://\" + url_or_domain\n )\n hostname = parsed.hostname or url_or_domain\n if not hostname or \".\" not in hostname:\n return False\n if not re.match(r\"^[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$\", hostname):\n return False", + "detail": "spectragraph-api.app.utils", + "documentation": {} + }, + { + "label": "is_root_domain", + "kind": 2, + "importPath": "spectragraph-api.app.utils", + "description": "spectragraph-api.app.utils", + "peekOfCode": "def is_root_domain(domain: str) -> bool:\n \"\"\"\n Determine if a domain is a root domain or subdomain.\n Args:\n domain: The domain string to check\n Returns:\n True if it's a root domain (e.g., example.com), False if it's a subdomain (e.g., sub.example.com)\n \"\"\"\n try:\n # Remove protocol if present", + "detail": "spectragraph-api.app.utils", + "documentation": {} + }, + { + "label": "is_valid_number", + "kind": 2, + "importPath": "spectragraph-api.app.utils", + "description": "spectragraph-api.app.utils", + "peekOfCode": "def is_valid_number(phone: str, region: str = \"FR\") -> None:\n \"\"\"\n Validates a phone number. Raises InvalidPhoneNumberError if invalid.\n - `region` should be ISO 3166-1 alpha-2 country code (e.g., 'FR' for France)\n \"\"\"\n try:\n parsed = phonenumbers.parse(phone, region)\n if not phonenumbers.is_valid_number(parsed):\n return False\n except NumberParseException:", + "detail": "spectragraph-api.app.utils", + "documentation": {} + }, + { + "label": "parse_asn", + "kind": 2, + "importPath": "spectragraph-api.app.utils", + "description": "spectragraph-api.app.utils", + "peekOfCode": "def parse_asn(asn: str) -> int:\n if not is_valid_asn(asn):\n raise ValueError(f\"Invalid ASN format: {asn}\")\n return int(re.sub(r\"(?i)^AS\", \"\", asn))\ndef is_valid_asn(asn: str) -> bool:\n if not re.fullmatch(r\"(AS)?\\d+\", asn, re.IGNORECASE):\n return False\n asn_num = int(re.sub(r\"(?i)^AS\", \"\", asn))\n return 0 <= asn_num <= 4294967295\ndef resolve_type(details: dict, schema_context: dict = None) -> str:", + "detail": "spectragraph-api.app.utils", + "documentation": {} + }, + { + "label": "is_valid_asn", + "kind": 2, + "importPath": "spectragraph-api.app.utils", + "description": "spectragraph-api.app.utils", + "peekOfCode": "def is_valid_asn(asn: str) -> bool:\n if not re.fullmatch(r\"(AS)?\\d+\", asn, re.IGNORECASE):\n return False\n asn_num = int(re.sub(r\"(?i)^AS\", \"\", asn))\n return 0 <= asn_num <= 4294967295\ndef resolve_type(details: dict, schema_context: dict = None) -> str:\n if \"anyOf\" in details:\n types = []\n for option in details[\"anyOf\"]:\n if \"$ref\" in option:", + "detail": "spectragraph-api.app.utils", + "documentation": {} + }, + { + "label": "resolve_type", + "kind": 2, + "importPath": "spectragraph-api.app.utils", + "description": "spectragraph-api.app.utils", + "peekOfCode": "def resolve_type(details: dict, schema_context: dict = None) -> str:\n if \"anyOf\" in details:\n types = []\n for option in details[\"anyOf\"]:\n if \"$ref\" in option:\n ref = option[\"$ref\"].split(\"/\")[-1]\n types.append(ref)\n elif option.get(\"type\") == \"array\":\n # Handle array types within anyOf\n item_type = resolve_type(option.get(\"items\", {}), schema_context)", + "detail": "spectragraph-api.app.utils", + "documentation": {} + }, + { + "label": "extract_input_schema_flow", + "kind": 2, + "importPath": "spectragraph-api.app.utils", + "description": "spectragraph-api.app.utils", + "peekOfCode": "def extract_input_schema_flow(model: Type[BaseModel]) -> Dict[str, Any]:\n adapter = TypeAdapter(model)\n schema = adapter.json_schema()\n # Use the main schema properties, not the $defs\n type_name = model.__name__\n details = schema\n return {\n \"class_name\": model.__name__,\n \"name\": model.__name__,\n \"module\": model.__module__,", + "detail": "spectragraph-api.app.utils", + "documentation": {} + }, + { + "label": "get_domain_from_ssl", + "kind": 2, + "importPath": "spectragraph-api.app.utils", + "description": "spectragraph-api.app.utils", + "peekOfCode": "def get_domain_from_ssl(ip: str, port: int = 443) -> str | None:\n try:\n context = ssl.create_default_context()\n with socket.create_connection((ip, port), timeout=3) as sock:\n with context.wrap_socket(sock, server_hostname=ip) as ssock:\n cert = ssock.getpeercert()\n subject = cert.get(\"subject\", [])\n for entry in subject:\n if entry[0][0] == \"commonName\":\n return entry[0][1]", + "detail": "spectragraph-api.app.utils", + "documentation": {} + }, + { + "label": "extract_transform", + "kind": 2, + "importPath": "spectragraph-api.app.utils", + "description": "spectragraph-api.app.utils", + "peekOfCode": "def extract_transform(transform: Dict[str, Any]) -> Dict[str, Any]:\n nodes = transform[\"nodes\"]\n edges = transform[\"edges\"]\n input_node = next((node for node in nodes if node[\"data\"][\"type\"] == \"type\"), None)\n if not input_node:\n raise ValueError(\"No input node found.\")\n input_output = input_node[\"data\"][\"outputs\"]\n node_lookup = {node[\"id\"]: node for node in nodes}\n transforms = []\n for edge in edges:", + "detail": "spectragraph-api.app.utils", + "documentation": {} + }, + { + "label": "get_label_color", + "kind": 2, + "importPath": "spectragraph-api.app.utils", + "description": "spectragraph-api.app.utils", + "peekOfCode": "def get_label_color(label: str) -> str:\n color_map = {\"subdomain\": \"#A5ABB6\", \"domain\": \"#68BDF6\", \"default\": \"#A5ABB6\"}\n return color_map.get(label, color_map[\"default\"])\ndef flatten(data_dict, prefix=\"\"):\n \"\"\"\n Flattens a dictionary to contain only Neo4j-compatible property values.\n Neo4j supports primitive types (string, number, boolean) and arrays of those types.\n Args:\n data_dict (dict): Dictionary to flatten\n Returns:", + "detail": "spectragraph-api.app.utils", + "documentation": {} + }, + { + "label": "flatten", + "kind": 2, + "importPath": "spectragraph-api.app.utils", + "description": "spectragraph-api.app.utils", + "peekOfCode": "def flatten(data_dict, prefix=\"\"):\n \"\"\"\n Flattens a dictionary to contain only Neo4j-compatible property values.\n Neo4j supports primitive types (string, number, boolean) and arrays of those types.\n Args:\n data_dict (dict): Dictionary to flatten\n Returns:\n dict: Flattened dictionary with only Neo4j-compatible values\n \"\"\"\n flattened = {}", + "detail": "spectragraph-api.app.utils", + "documentation": {} + }, + { + "label": "get_inline_relationships", + "kind": 2, + "importPath": "spectragraph-api.app.utils", + "description": "spectragraph-api.app.utils", + "peekOfCode": "def get_inline_relationships(nodes: List[Any], edges: List[Any]) -> List[str]:\n \"\"\"\n Get the inline relationships for a list of nodes and edges.\n \"\"\"\n relationships = []\n for edge in edges:\n source = next((node for node in nodes if node[\"id\"] == edge[\"source\"]), None)\n target = next((node for node in nodes if node[\"id\"] == edge[\"target\"]), None)\n if source and target:\n relationships.append({\"source\": source, \"edge\": edge, \"target\": target})", + "detail": "spectragraph-api.app.utils", + "documentation": {} + }, + { + "label": "to_json_serializable", + "kind": 2, + "importPath": "spectragraph-api.app.utils", + "description": "spectragraph-api.app.utils", + "peekOfCode": "def to_json_serializable(obj):\n \"\"\"Convert any object to a JSON-serializable format.\"\"\"\n import json\n from pydantic import BaseModel\n try:\n # Test if already JSON serializable\n json.dumps(obj)\n return obj\n except (TypeError, ValueError):\n # Handle common cases", + "detail": "spectragraph-api.app.utils", + "documentation": {} + }, + { + "label": "verify_password", + "kind": 2, + "importPath": "spectragraph-core.src.spectragraph_core.core.auth", + "description": "spectragraph-core.src.spectragraph_core.core.auth", + "peekOfCode": "def verify_password(plain_password: str, hashed_password: str) -> bool:\n return pwd_context.verify(plain_password, hashed_password)\ndef get_password_hash(password: str) -> str:\n return pwd_context.hash(password)\ndef create_access_token(data: dict, expires_delta: timedelta | None = None):\n to_encode = data.copy()\n expire = datetime.utcnow() + (\n expires_delta or timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)\n )\n to_encode.update({\"exp\": expire})", + "detail": "spectragraph-core.src.spectragraph_core.core.auth", + "documentation": {} + }, + { + "label": "get_password_hash", + "kind": 2, + "importPath": "spectragraph-core.src.spectragraph_core.core.auth", + "description": "spectragraph-core.src.spectragraph_core.core.auth", + "peekOfCode": "def get_password_hash(password: str) -> str:\n return pwd_context.hash(password)\ndef create_access_token(data: dict, expires_delta: timedelta | None = None):\n to_encode = data.copy()\n expire = datetime.utcnow() + (\n expires_delta or timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)\n )\n to_encode.update({\"exp\": expire})\n encoded_jwt = jwt.encode(to_encode, AUTH_SECRET, algorithm=ALGORITHM)\n return encoded_jwt", + "detail": "spectragraph-core.src.spectragraph_core.core.auth", + "documentation": {} + }, + { + "label": "create_access_token", + "kind": 2, + "importPath": "spectragraph-core.src.spectragraph_core.core.auth", + "description": "spectragraph-core.src.spectragraph_core.core.auth", + "peekOfCode": "def create_access_token(data: dict, expires_delta: timedelta | None = None):\n to_encode = data.copy()\n expire = datetime.utcnow() + (\n expires_delta or timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)\n )\n to_encode.update({\"exp\": expire})\n encoded_jwt = jwt.encode(to_encode, AUTH_SECRET, algorithm=ALGORITHM)\n return encoded_jwt", + "detail": "spectragraph-core.src.spectragraph_core.core.auth", + "documentation": {} + }, + { + "label": "AUTH_SECRET", + "kind": 5, + "importPath": "spectragraph-core.src.spectragraph_core.core.auth", + "description": "spectragraph-core.src.spectragraph_core.core.auth", + "peekOfCode": "AUTH_SECRET = os.getenv(\"AUTH_SECRET\")\nif not AUTH_SECRET:\n raise ValueError(\n \"AUTH_SECRET environment variable is not set. Please set it in your .env file.\"\n )\nALGORITHM = \"HS256\"\nACCESS_TOKEN_EXPIRE_MINUTES = 60 # 60 minutes = 1 hour\npwd_context = CryptContext(schemes=[\"bcrypt\"], deprecated=\"auto\")\ndef verify_password(plain_password: str, hashed_password: str) -> bool:\n return pwd_context.verify(plain_password, hashed_password)", + "detail": "spectragraph-core.src.spectragraph_core.core.auth", + "documentation": {} + }, + { + "label": "ALGORITHM", + "kind": 5, + "importPath": "spectragraph-core.src.spectragraph_core.core.auth", + "description": "spectragraph-core.src.spectragraph_core.core.auth", + "peekOfCode": "ALGORITHM = \"HS256\"\nACCESS_TOKEN_EXPIRE_MINUTES = 60 # 60 minutes = 1 hour\npwd_context = CryptContext(schemes=[\"bcrypt\"], deprecated=\"auto\")\ndef verify_password(plain_password: str, hashed_password: str) -> bool:\n return pwd_context.verify(plain_password, hashed_password)\ndef get_password_hash(password: str) -> str:\n return pwd_context.hash(password)\ndef create_access_token(data: dict, expires_delta: timedelta | None = None):\n to_encode = data.copy()\n expire = datetime.utcnow() + (", + "detail": "spectragraph-core.src.spectragraph_core.core.auth", + "documentation": {} + }, + { + "label": "ACCESS_TOKEN_EXPIRE_MINUTES", + "kind": 5, + "importPath": "spectragraph-core.src.spectragraph_core.core.auth", + "description": "spectragraph-core.src.spectragraph_core.core.auth", + "peekOfCode": "ACCESS_TOKEN_EXPIRE_MINUTES = 60 # 60 minutes = 1 hour\npwd_context = CryptContext(schemes=[\"bcrypt\"], deprecated=\"auto\")\ndef verify_password(plain_password: str, hashed_password: str) -> bool:\n return pwd_context.verify(plain_password, hashed_password)\ndef get_password_hash(password: str) -> str:\n return pwd_context.hash(password)\ndef create_access_token(data: dict, expires_delta: timedelta | None = None):\n to_encode = data.copy()\n expire = datetime.utcnow() + (\n expires_delta or timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)", + "detail": "spectragraph-core.src.spectragraph_core.core.auth", + "documentation": {} + }, + { + "label": "pwd_context", + "kind": 5, + "importPath": "spectragraph-core.src.spectragraph_core.core.auth", + "description": "spectragraph-core.src.spectragraph_core.core.auth", + "peekOfCode": "pwd_context = CryptContext(schemes=[\"bcrypt\"], deprecated=\"auto\")\ndef verify_password(plain_password: str, hashed_password: str) -> bool:\n return pwd_context.verify(plain_password, hashed_password)\ndef get_password_hash(password: str) -> str:\n return pwd_context.hash(password)\ndef create_access_token(data: dict, expires_delta: timedelta | None = None):\n to_encode = data.copy()\n expire = datetime.utcnow() + (\n expires_delta or timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)\n )", + "detail": "spectragraph-core.src.spectragraph_core.core.auth", + "documentation": {} + }, + { + "label": "celery", + "kind": 5, + "importPath": "spectragraph-core.src.spectragraph_core.core.celery", + "description": "spectragraph-core.src.spectragraph_core.core.celery", + "peekOfCode": "celery = Celery(\n \"spectragraph\",\n broker=settings.CELERY_BROKER_URL,\n backend=settings.CELERY_RESULT_BACKEND,\n include=[\n \"spectragraph_core.tasks.event\",\n \"spectragraph_core.tasks.transform\",\n \"spectragraph_core.tasks.flow\",\n ],\n)", + "detail": "spectragraph-core.src.spectragraph_core.core.celery", + "documentation": {} + }, + { + "label": "Settings", + "kind": 6, + "importPath": "spectragraph-core.src.spectragraph_core.core.config", + "description": "spectragraph-core.src.spectragraph_core.core.config", + "peekOfCode": "class Settings:\n CELERY_BROKER_URL = os.environ[\"REDIS_URL\"]\n CELERY_RESULT_BACKEND = os.environ[\"REDIS_URL\"]\nsettings = Settings()", + "detail": "spectragraph-core.src.spectragraph_core.core.config", + "documentation": {} + }, + { + "label": "settings", + "kind": 5, + "importPath": "spectragraph-core.src.spectragraph_core.core.config", + "description": "spectragraph-core.src.spectragraph_core.core.config", + "peekOfCode": "settings = Settings()", + "detail": "spectragraph-core.src.spectragraph_core.core.config", + "documentation": {} + }, + { + "label": "EventLevel", + "kind": 6, + "importPath": "spectragraph-core.src.spectragraph_core.core.enums", + "description": "spectragraph-core.src.spectragraph_core.core.enums", + "peekOfCode": "class EventLevel(str, Enum):\n # Standard log levels\n INFO = \"INFO\"\n WARNING = \"WARNING\"\n FAILED = \"FAILED\"\n SUCCESS = \"SUCCESS\"\n DEBUG = \"DEBUG\"\n # Transform-specific statuses\n PENDING = \"PENDING\"\n RUNNING = \"RUNNING\"", + "detail": "spectragraph-core.src.spectragraph_core.core.enums", + "documentation": {} + }, + { + "label": "EventEmitter", + "kind": 6, + "importPath": "spectragraph-core.src.spectragraph_core.core.events", + "description": "spectragraph-core.src.spectragraph_core.core.events", + "peekOfCode": "class EventEmitter:\n def __init__(self):\n self.id = uuid.uuid4()\n self.redis = redis.from_url(os.environ[\"REDIS_URL\"])\n self.pubsubs: Dict[str, redis.client.PubSub] = {}\n async def subscribe(self, channel: str):\n \"\"\"Subscribe to Redis channel\"\"\"\n if channel not in self.pubsubs:\n pubsub = self.redis.pubsub()\n await pubsub.subscribe(channel)", + "detail": "spectragraph-core.src.spectragraph_core.core.events", + "documentation": {} + }, + { + "label": "init_events", + "kind": 2, + "importPath": "spectragraph-core.src.spectragraph_core.core.events", + "description": "spectragraph-core.src.spectragraph_core.core.events", + "peekOfCode": "def init_events(app: FastAPI):\n \"\"\"Initialize the event system in the FastAPI app\"\"\"\n print(\"[EventEmitter] Events initialized in FastAPI app\")", + "detail": "spectragraph-core.src.spectragraph_core.core.events", + "documentation": {} + }, + { + "label": "event_emitter", + "kind": 5, + "importPath": "spectragraph-core.src.spectragraph_core.core.events", + "description": "spectragraph-core.src.spectragraph_core.core.events", + "peekOfCode": "event_emitter = EventEmitter()\ndef init_events(app: FastAPI):\n \"\"\"Initialize the event system in the FastAPI app\"\"\"\n print(\"[EventEmitter] Events initialized in FastAPI app\")", + "detail": "spectragraph-core.src.spectragraph_core.core.events", + "documentation": {} + }, + { + "label": "Neo4jConnection", + "kind": 6, + "importPath": "spectragraph-core.src.spectragraph_core.core.graph_db", + "description": "spectragraph-core.src.spectragraph_core.core.graph_db", + "peekOfCode": "class Neo4jConnection:\n \"\"\"\n Singleton Neo4j connection manager with proper connection pooling.\n This class implements the Singleton pattern to ensure only one Neo4j driver\n instance exists throughout the application lifecycle, providing efficient\n connection pooling and resource management.\n \"\"\"\n _instance: Optional['Neo4jConnection'] = None\n _lock: Lock = Lock()\n _driver: Optional[Driver] = None", + "detail": "spectragraph-core.src.spectragraph_core.core.graph_db", + "documentation": {} + }, + { + "label": "GraphRepository", + "kind": 6, + "importPath": "spectragraph-core.src.spectragraph_core.core.graph_repository", + "description": "spectragraph-core.src.spectragraph_core.core.graph_repository", + "peekOfCode": "class GraphRepository:\n \"\"\"\n Repository for Neo4j graph database operations.\n This class follows the Repository pattern, providing a clean abstraction\n over Neo4j operations and handling batching for improved performance.\n \"\"\"\n def __init__(self, neo4j_connection: Optional[Neo4jConnection] = None):\n \"\"\"\n Initialize the graph repository.\n Args:", + "detail": "spectragraph-core.src.spectragraph_core.core.graph_repository", + "documentation": {} + }, + { + "label": "GraphSerializer", + "kind": 6, + "importPath": "spectragraph-core.src.spectragraph_core.core.graph_serializer", + "description": "spectragraph-core.src.spectragraph_core.core.graph_serializer", + "peekOfCode": "class GraphSerializer:\n \"\"\"\n Handles serialization of complex objects to Neo4j-compatible types.\n This class is responsible for converting Pydantic models, nested objects,\n and other complex types into primitive types that can be stored in Neo4j.\n \"\"\"\n @staticmethod\n def serialize_properties(properties: Dict[str, Any]) -> Dict[str, Any]:\n \"\"\"\n Convert properties to Neo4j-compatible values.", + "detail": "spectragraph-core.src.spectragraph_core.core.graph_serializer", + "documentation": {} + }, + { + "label": "LoggerProtocol", + "kind": 6, + "importPath": "spectragraph-core.src.spectragraph_core.core.graph_service", + "description": "spectragraph-core.src.spectragraph_core.core.graph_service", + "peekOfCode": "class LoggerProtocol(Protocol):\n \"\"\"Protocol for logger implementations.\"\"\"\n @staticmethod\n def graph_append(sketch_id: str, message: Dict[str, Any]) -> None:\n \"\"\"Log a graph append message.\"\"\"\n ...\nclass GraphService:\n \"\"\"\n High-level service for graph operations.\n This service provides a clean interface for transform operations,", + "detail": "spectragraph-core.src.spectragraph_core.core.graph_service", + "documentation": {} + }, + { + "label": "GraphService", + "kind": 6, + "importPath": "spectragraph-core.src.spectragraph_core.core.graph_service", + "description": "spectragraph-core.src.spectragraph_core.core.graph_service", + "peekOfCode": "class GraphService:\n \"\"\"\n High-level service for graph operations.\n This service provides a clean interface for transform operations,\n handling both graph persistence and logging with proper separation of concerns.\n \"\"\"\n def __init__(\n self,\n sketch_id: str,\n neo4j_connection: Optional[Neo4jConnection] = None,", + "detail": "spectragraph-core.src.spectragraph_core.core.graph_service", + "documentation": {} + }, + { + "label": "create_graph_service", + "kind": 2, + "importPath": "spectragraph-core.src.spectragraph_core.core.graph_service", + "description": "spectragraph-core.src.spectragraph_core.core.graph_service", + "peekOfCode": "def create_graph_service(\n sketch_id: str,\n neo4j_connection: Optional[Neo4jConnection] = None,\n enable_batching: bool = True\n) -> GraphService:\n \"\"\"\n Factory function to create a GraphService instance.\n Args:\n sketch_id: Investigation sketch ID\n neo4j_connection: Optional Neo4j connection", + "detail": "spectragraph-core.src.spectragraph_core.core.graph_service", + "documentation": {} + }, + { + "label": "Logger", + "kind": 6, + "importPath": "spectragraph-core.src.spectragraph_core.core.logger", + "description": "spectragraph-core.src.spectragraph_core.core.logger", + "peekOfCode": "class Logger:\n @staticmethod\n def _create_log(\n sketch_id: Union[str, UUID], level: EventLevel, content: str\n ) -> Log:\n \"\"\"Create a log entry in the database\"\"\"\n db = next(get_db())\n try:\n log = Log(sketch_id=str(sketch_id), type=level.value, content=content)\n db.add(log)", + "detail": "spectragraph-core.src.spectragraph_core.core.logger", + "documentation": {} + }, + { + "label": "logger", + "kind": 5, + "importPath": "spectragraph-core.src.spectragraph_core.core.logger", + "description": "spectragraph-core.src.spectragraph_core.core.logger", + "peekOfCode": "logger = logging.getLogger(__name__)\nclass Logger:\n @staticmethod\n def _create_log(\n sketch_id: Union[str, UUID], level: EventLevel, content: str\n ) -> Log:\n \"\"\"Create a log entry in the database\"\"\"\n db = next(get_db())\n try:\n log = Log(sketch_id=str(sketch_id), type=level.value, content=content)", + "detail": "spectragraph-core.src.spectragraph_core.core.logger", + "documentation": {} + }, + { + "label": "Base", + "kind": 6, + "importPath": "spectragraph-core.src.spectragraph_core.core.models", + "description": "spectragraph-core.src.spectragraph_core.core.models", + "peekOfCode": "class Base(DeclarativeBase):\n pass\nclass Feedback(Base):\n __tablename__ = \"feedbacks\"\n id: Mapped[uuid.UUID] = mapped_column(primary_key=True)\n created_at = mapped_column(DateTime(timezone=True), server_default=func.now())\n content = mapped_column(Text, nullable=True)\n owner_id = mapped_column(\n PGUUID(as_uuid=True), ForeignKey(\"profiles.id\"), nullable=True\n )", + "detail": "spectragraph-core.src.spectragraph_core.core.models", + "documentation": {} + }, + { + "label": "Feedback", + "kind": 6, + "importPath": "spectragraph-core.src.spectragraph_core.core.models", + "description": "spectragraph-core.src.spectragraph_core.core.models", + "peekOfCode": "class Feedback(Base):\n __tablename__ = \"feedbacks\"\n id: Mapped[uuid.UUID] = mapped_column(primary_key=True)\n created_at = mapped_column(DateTime(timezone=True), server_default=func.now())\n content = mapped_column(Text, nullable=True)\n owner_id = mapped_column(\n PGUUID(as_uuid=True), ForeignKey(\"profiles.id\"), nullable=True\n )\nclass Investigation(Base):\n __tablename__ = \"investigations\"", + "detail": "spectragraph-core.src.spectragraph_core.core.models", + "documentation": {} + }, + { + "label": "Investigation", + "kind": 6, + "importPath": "spectragraph-core.src.spectragraph_core.core.models", + "description": "spectragraph-core.src.spectragraph_core.core.models", + "peekOfCode": "class Investigation(Base):\n __tablename__ = \"investigations\"\n id: Mapped[uuid.UUID] = mapped_column(\n PGUUID(as_uuid=True), primary_key=True, default=uuid.uuid4\n )\n created_at = mapped_column(DateTime(timezone=True), server_default=func.now())\n name = mapped_column(Text)\n description = mapped_column(Text)\n owner_id = mapped_column(\n PGUUID(as_uuid=True),", + "detail": "spectragraph-core.src.spectragraph_core.core.models", + "documentation": {} + }, + { + "label": "Log", + "kind": 6, + "importPath": "spectragraph-core.src.spectragraph_core.core.models", + "description": "spectragraph-core.src.spectragraph_core.core.models", + "peekOfCode": "class Log(Base):\n __tablename__ = \"logs\"\n id: Mapped[uuid.UUID] = mapped_column(\n PGUUID(as_uuid=True), primary_key=True, default=uuid.uuid4\n )\n content = mapped_column(JSONB, nullable=True)\n created_at = mapped_column(DateTime(timezone=True), server_default=func.now())\n sketch_id = mapped_column(\n PGUUID(as_uuid=True),\n ForeignKey(\"sketches.id\", onupdate=\"CASCADE\", ondelete=\"CASCADE\"),", + "detail": "spectragraph-core.src.spectragraph_core.core.models", + "documentation": {} + }, + { + "label": "Profile", + "kind": 6, + "importPath": "spectragraph-core.src.spectragraph_core.core.models", + "description": "spectragraph-core.src.spectragraph_core.core.models", + "peekOfCode": "class Profile(Base):\n __tablename__ = \"profiles\"\n id: Mapped[uuid.UUID] = mapped_column(\n PGUUID(as_uuid=True), primary_key=True, default=uuid.uuid4\n )\n first_name = mapped_column(Text, nullable=True)\n last_name = mapped_column(Text, nullable=True)\n avatar_url = mapped_column(Text, nullable=True)\n email: Mapped[str] = mapped_column(String, unique=True, nullable=False)\n hashed_password: Mapped[str] = mapped_column(String, nullable=False)", + "detail": "spectragraph-core.src.spectragraph_core.core.models", + "documentation": {} + }, + { + "label": "Scan", + "kind": 6, + "importPath": "spectragraph-core.src.spectragraph_core.core.models", + "description": "spectragraph-core.src.spectragraph_core.core.models", + "peekOfCode": "class Scan(Base):\n __tablename__ = \"scans\"\n id: Mapped[uuid.UUID] = mapped_column(\n PGUUID(as_uuid=True), primary_key=True, default=uuid.uuid4\n )\n sketch_id: Mapped[uuid.UUID] = mapped_column(\n PGUUID(as_uuid=True),\n ForeignKey(\"sketches.id\", onupdate=\"CASCADE\", ondelete=\"CASCADE\"),\n nullable=True,\n )", + "detail": "spectragraph-core.src.spectragraph_core.core.models", + "documentation": {} + }, + { + "label": "Sketch", + "kind": 6, + "importPath": "spectragraph-core.src.spectragraph_core.core.models", + "description": "spectragraph-core.src.spectragraph_core.core.models", + "peekOfCode": "class Sketch(Base):\n __tablename__ = \"sketches\"\n id: Mapped[uuid.UUID] = mapped_column(\n PGUUID(as_uuid=True), primary_key=True, default=uuid.uuid4\n )\n title = mapped_column(Text)\n description = mapped_column(Text)\n created_at = mapped_column(DateTime(timezone=True), server_default=func.now())\n owner_id = mapped_column(\n PGUUID(as_uuid=True),", + "detail": "spectragraph-core.src.spectragraph_core.core.models", + "documentation": {} + }, + { + "label": "SketchesProfiles", + "kind": 6, + "importPath": "spectragraph-core.src.spectragraph_core.core.models", + "description": "spectragraph-core.src.spectragraph_core.core.models", + "peekOfCode": "class SketchesProfiles(Base):\n __tablename__ = \"sketches_profiles\"\n id: Mapped[uuid.UUID] = mapped_column(primary_key=True)\n created_at = mapped_column(DateTime(timezone=True), server_default=func.now())\n profile_id = mapped_column(\n PGUUID(as_uuid=True),\n ForeignKey(\"profiles.id\", onupdate=\"CASCADE\", ondelete=\"CASCADE\"),\n )\n sketch_id = mapped_column(\n PGUUID(as_uuid=True),", + "detail": "spectragraph-core.src.spectragraph_core.core.models", + "documentation": {} + }, + { + "label": "Flow", + "kind": 6, + "importPath": "spectragraph-core.src.spectragraph_core.core.models", + "description": "spectragraph-core.src.spectragraph_core.core.models", + "peekOfCode": "class Flow(Base):\n __tablename__ = \"flows\"\n id: Mapped[uuid.UUID] = mapped_column(\n PGUUID(as_uuid=True), primary_key=True, default=uuid.uuid4\n )\n name = mapped_column(Text, nullable=False)\n description = mapped_column(Text, nullable=True)\n category = mapped_column(ARRAY(Text), nullable=True)\n flow_schema = mapped_column(JSON, nullable=True)\n created_at = mapped_column(DateTime(timezone=True), server_default=func.now())", + "detail": "spectragraph-core.src.spectragraph_core.core.models", + "documentation": {} + }, + { + "label": "Analysis", + "kind": 6, + "importPath": "spectragraph-core.src.spectragraph_core.core.models", + "description": "spectragraph-core.src.spectragraph_core.core.models", + "peekOfCode": "class Analysis(Base):\n __tablename__ = \"analyses\"\n id: Mapped[uuid.UUID] = mapped_column(\n PGUUID(as_uuid=True), primary_key=True, default=uuid.uuid4\n )\n title = mapped_column(Text, nullable=False)\n description = mapped_column(Text, nullable=True)\n content = mapped_column(JSON, nullable=True)\n created_at = mapped_column(DateTime(timezone=True), server_default=func.now())\n last_updated_at = mapped_column(DateTime(timezone=True), server_default=func.now())", + "detail": "spectragraph-core.src.spectragraph_core.core.models", + "documentation": {} + }, + { + "label": "Chat", + "kind": 6, + "importPath": "spectragraph-core.src.spectragraph_core.core.models", + "description": "spectragraph-core.src.spectragraph_core.core.models", + "peekOfCode": "class Chat(Base):\n __tablename__ = \"chats\"\n id: Mapped[uuid.UUID] = mapped_column(\n PGUUID(as_uuid=True), primary_key=True, default=uuid.uuid4\n )\n title = mapped_column(Text, nullable=False)\n description = mapped_column(Text, nullable=True)\n created_at = mapped_column(DateTime(timezone=True), server_default=func.now())\n last_updated_at = mapped_column(DateTime(timezone=True), server_default=func.now())\n owner_id = mapped_column(", + "detail": "spectragraph-core.src.spectragraph_core.core.models", + "documentation": {} + }, + { + "label": "ChatMessage", + "kind": 6, + "importPath": "spectragraph-core.src.spectragraph_core.core.models", + "description": "spectragraph-core.src.spectragraph_core.core.models", + "peekOfCode": "class ChatMessage(Base):\n __tablename__ = \"messages\"\n id: Mapped[uuid.UUID] = mapped_column(\n PGUUID(as_uuid=True), primary_key=True, default=uuid.uuid4\n )\n content = mapped_column(JSON, nullable=True)\n context = mapped_column(JSON, nullable=True)\n is_bot: Mapped[bool] = mapped_column(default=False)\n created_at = mapped_column(DateTime(timezone=True), server_default=func.now())\n chat_id = mapped_column(", + "detail": "spectragraph-core.src.spectragraph_core.core.models", + "documentation": {} + }, + { + "label": "Key", + "kind": 6, + "importPath": "spectragraph-core.src.spectragraph_core.core.models", + "description": "spectragraph-core.src.spectragraph_core.core.models", + "peekOfCode": "class Key(Base):\n __tablename__ = \"keys\"\n id: Mapped[uuid.UUID] = mapped_column(\n PGUUID(as_uuid=True), primary_key=True, default=uuid.uuid4\n )\n name: Mapped[str] = mapped_column(String, nullable=False) # ex: \"shodan\", \"whocy\"\n owner_id: Mapped[uuid.UUID] = mapped_column(\n PGUUID(as_uuid=True),\n ForeignKey(\"profiles.id\", onupdate=\"CASCADE\", ondelete=\"CASCADE\"),\n nullable=False,", + "detail": "spectragraph-core.src.spectragraph_core.core.models", + "documentation": {} + }, + { + "label": "InvestigationUserRole", + "kind": 6, + "importPath": "spectragraph-core.src.spectragraph_core.core.models", + "description": "spectragraph-core.src.spectragraph_core.core.models", + "peekOfCode": "class InvestigationUserRole(Base):\n __tablename__ = \"investigation_user_roles\"\n id: Mapped[uuid.UUID] = mapped_column(\n PGUUID(as_uuid=True),\n primary_key=True,\n default=uuid.uuid4,\n )\n user_id: Mapped[uuid.UUID] = mapped_column(\n PGUUID(as_uuid=True),\n ForeignKey(\"profiles.id\", onupdate=\"CASCADE\", ondelete=\"CASCADE\"),", + "detail": "spectragraph-core.src.spectragraph_core.core.models", + "documentation": {} + }, + { + "label": "CustomType", + "kind": 6, + "importPath": "spectragraph-core.src.spectragraph_core.core.models", + "description": "spectragraph-core.src.spectragraph_core.core.models", + "peekOfCode": "class CustomType(Base):\n __tablename__ = \"custom_types\"\n id: Mapped[uuid.UUID] = mapped_column(\n PGUUID(as_uuid=True), primary_key=True, default=uuid.uuid4\n )\n name: Mapped[str] = mapped_column(Text, nullable=False)\n owner_id: Mapped[uuid.UUID] = mapped_column(\n PGUUID(as_uuid=True),\n ForeignKey(\"profiles.id\", onupdate=\"CASCADE\", ondelete=\"CASCADE\"),\n nullable=False,", + "detail": "spectragraph-core.src.spectragraph_core.core.models", + "documentation": {} + }, + { + "label": "FlowOrchestrator", + "kind": 6, + "importPath": "spectragraph-core.src.spectragraph_core.core.orchestrator", + "description": "spectragraph-core.src.spectragraph_core.core.orchestrator", + "peekOfCode": "class FlowOrchestrator(Transform):\n \"\"\"\n Orchestrator for running a list of transforms.\n \"\"\"\n def __init__(\n self,\n sketch_id: str,\n scan_id: str,\n transform_branches: List[FlowBranch],\n neo4j_conn=None,", + "detail": "spectragraph-core.src.spectragraph_core.core.orchestrator", + "documentation": {} + }, + { + "label": "DatabaseUnavailableError", + "kind": 6, + "importPath": "spectragraph-core.src.spectragraph_core.core.postgre_db", + "description": "spectragraph-core.src.spectragraph_core.core.postgre_db", + "peekOfCode": "class DatabaseUnavailableError(RuntimeError):\n pass\ndef _mask_password(dsn: str) -> str:\n try:\n # naive mask: replace password between : and @ in the authority\n if \"@\" in dsn and \":\" in dsn.split(\"@\")[0]:\n left, rest = dsn.split(\"@\", 1)\n if \":\" in left:\n user, _ = left.split(\":\", 1)\n return f\"{user}:****@{rest}\"", + "detail": "spectragraph-core.src.spectragraph_core.core.postgre_db", + "documentation": {} + }, + { + "label": "ensure_db_connection", + "kind": 2, + "importPath": "spectragraph-core.src.spectragraph_core.core.postgre_db", + "description": "spectragraph-core.src.spectragraph_core.core.postgre_db", + "peekOfCode": "def ensure_db_connection(max_retries: int = 5, base_delay: float = 1.0) -> None:\n \"\"\"Try connecting to Postgres with exponential backoff. Raises DatabaseUnavailableError.\n Designed for local/dev startup checks to provide actionable feedback when DB is missing.\n \"\"\"\n env = os.getenv(\"ENV\", \"development\")\n masked = _mask_password(DATABASE_URL)\n for attempt in range(1, max_retries + 1):\n try:\n with engine.connect() as conn:\n conn.execute(text(\"SELECT 1\"))", + "detail": "spectragraph-core.src.spectragraph_core.core.postgre_db", + "documentation": {} + }, + { + "label": "get_db", + "kind": 2, + "importPath": "spectragraph-core.src.spectragraph_core.core.postgre_db", + "description": "spectragraph-core.src.spectragraph_core.core.postgre_db", + "peekOfCode": "def get_db() -> Session:\n db = SessionLocal()\n try:\n yield db\n finally:\n db.close()", + "detail": "spectragraph-core.src.spectragraph_core.core.postgre_db", + "documentation": {} + }, + { + "label": "DATABASE_URL", + "kind": 5, + "importPath": "spectragraph-core.src.spectragraph_core.core.postgre_db", + "description": "spectragraph-core.src.spectragraph_core.core.postgre_db", + "peekOfCode": "DATABASE_URL = os.getenv(\"DATABASE_URL\", \"postgresql://localhost:5432/spectragraph\")\nlogger = logging.getLogger(__name__)\nengine = create_engine(DATABASE_URL, pool_pre_ping=True)\nSessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)\nBase = declarative_base()\nclass DatabaseUnavailableError(RuntimeError):\n pass\ndef _mask_password(dsn: str) -> str:\n try:\n # naive mask: replace password between : and @ in the authority", + "detail": "spectragraph-core.src.spectragraph_core.core.postgre_db", + "documentation": {} + }, + { + "label": "logger", + "kind": 5, + "importPath": "spectragraph-core.src.spectragraph_core.core.postgre_db", + "description": "spectragraph-core.src.spectragraph_core.core.postgre_db", + "peekOfCode": "logger = logging.getLogger(__name__)\nengine = create_engine(DATABASE_URL, pool_pre_ping=True)\nSessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)\nBase = declarative_base()\nclass DatabaseUnavailableError(RuntimeError):\n pass\ndef _mask_password(dsn: str) -> str:\n try:\n # naive mask: replace password between : and @ in the authority\n if \"@\" in dsn and \":\" in dsn.split(\"@\")[0]:", + "detail": "spectragraph-core.src.spectragraph_core.core.postgre_db", + "documentation": {} + }, + { + "label": "engine", + "kind": 5, + "importPath": "spectragraph-core.src.spectragraph_core.core.postgre_db", + "description": "spectragraph-core.src.spectragraph_core.core.postgre_db", + "peekOfCode": "engine = create_engine(DATABASE_URL, pool_pre_ping=True)\nSessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)\nBase = declarative_base()\nclass DatabaseUnavailableError(RuntimeError):\n pass\ndef _mask_password(dsn: str) -> str:\n try:\n # naive mask: replace password between : and @ in the authority\n if \"@\" in dsn and \":\" in dsn.split(\"@\")[0]:\n left, rest = dsn.split(\"@\", 1)", + "detail": "spectragraph-core.src.spectragraph_core.core.postgre_db", + "documentation": {} + }, + { + "label": "SessionLocal", + "kind": 5, + "importPath": "spectragraph-core.src.spectragraph_core.core.postgre_db", + "description": "spectragraph-core.src.spectragraph_core.core.postgre_db", + "peekOfCode": "SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)\nBase = declarative_base()\nclass DatabaseUnavailableError(RuntimeError):\n pass\ndef _mask_password(dsn: str) -> str:\n try:\n # naive mask: replace password between : and @ in the authority\n if \"@\" in dsn and \":\" in dsn.split(\"@\")[0]:\n left, rest = dsn.split(\"@\", 1)\n if \":\" in left:", + "detail": "spectragraph-core.src.spectragraph_core.core.postgre_db", + "documentation": {} + }, + { + "label": "Base", + "kind": 5, + "importPath": "spectragraph-core.src.spectragraph_core.core.postgre_db", + "description": "spectragraph-core.src.spectragraph_core.core.postgre_db", + "peekOfCode": "Base = declarative_base()\nclass DatabaseUnavailableError(RuntimeError):\n pass\ndef _mask_password(dsn: str) -> str:\n try:\n # naive mask: replace password between : and @ in the authority\n if \"@\" in dsn and \":\" in dsn.split(\"@\")[0]:\n left, rest = dsn.split(\"@\", 1)\n if \":\" in left:\n user, _ = left.split(\":\", 1)", + "detail": "spectragraph-core.src.spectragraph_core.core.postgre_db", + "documentation": {} + }, + { + "label": "TransformRegistry", + "kind": 6, + "importPath": "spectragraph-core.src.spectragraph_core.core.registry", + "description": "spectragraph-core.src.spectragraph_core.core.registry", + "peekOfCode": "class TransformRegistry:\n _transforms: Dict[str, Type[Transform]] = {}\n @classmethod\n def register(cls, transform_class: Type[Transform]) -> None:\n cls._transforms[transform_class.name()] = transform_class\n @classmethod\n def transform_exists(cls, name: str) -> bool:\n return name in cls._transforms\n @classmethod\n def get_transform(", + "detail": "spectragraph-core.src.spectragraph_core.core.registry", + "documentation": {} + }, + { + "label": "InvalidTransformParams", + "kind": 6, + "importPath": "spectragraph-core.src.spectragraph_core.core.transform_base", + "description": "spectragraph-core.src.spectragraph_core.core.transform_base", + "peekOfCode": "class InvalidTransformParams(Exception):\n pass\ndef build_params_model(params_schema: list) -> BaseModel:\n \"\"\"\n Build a strict Pydantic model from a params_schema.\n Unknown fields will raise a validation error.\n Note: Vault secrets are always optional in the Pydantic model to allow\n for deferred configuration. Required validation happens after vault resolution.\n \"\"\"\n fields: Dict[str, Any] = {}", + "detail": "spectragraph-core.src.spectragraph_core.core.transform_base", + "documentation": {} + }, + { + "label": "Transform", + "kind": 6, + "importPath": "spectragraph-core.src.spectragraph_core.core.transform_base", + "description": "spectragraph-core.src.spectragraph_core.core.transform_base", + "peekOfCode": "class Transform(ABC):\n \"\"\"\n Abstract base class for all transforms.\n ## InputType and OutputType Pattern\n Transforms only need to define InputType and OutputType as class attributes.\n The base class automatically handles schema generation:\n ```python\n from typing import List\n from spectragraph_types import Domain\n from spectragraph_types import Ip", + "detail": "spectragraph-core.src.spectragraph_core.core.transform_base", + "documentation": {} + }, + { + "label": "build_params_model", + "kind": 2, + "importPath": "spectragraph-core.src.spectragraph_core.core.transform_base", + "description": "spectragraph-core.src.spectragraph_core.core.transform_base", + "peekOfCode": "def build_params_model(params_schema: list) -> BaseModel:\n \"\"\"\n Build a strict Pydantic model from a params_schema.\n Unknown fields will raise a validation error.\n Note: Vault secrets are always optional in the Pydantic model to allow\n for deferred configuration. Required validation happens after vault resolution.\n \"\"\"\n fields: Dict[str, Any] = {}\n for param in params_schema:\n name = param[\"name\"]", + "detail": "spectragraph-core.src.spectragraph_core.core.transform_base", + "documentation": {} + }, + { + "label": "Event", + "kind": 6, + "importPath": "spectragraph-core.src.spectragraph_core.core.types", + "description": "spectragraph-core.src.spectragraph_core.core.types", + "peekOfCode": "class Event(BaseModel):\n id: str = Field(..., description=\"Unique identifier for the event\")\n sketch_id: str = Field(..., description=\"ID of the sketch\")\n type: EventLevel = Field(..., description=\"Type of event\")\n payload: Dict[str, Any] = Field(..., description=\"Payload of the event\")\n created_at: datetime = Field(\n default_factory=datetime.now, description=\"Timestamp when the event was created\"\n )\nclass Node(BaseModel):\n \"\"\"Represents a node in a transformation flow with position and data.\"\"\"", + "detail": "spectragraph-core.src.spectragraph_core.core.types", + "documentation": {} + }, + { + "label": "Node", + "kind": 6, + "importPath": "spectragraph-core.src.spectragraph_core.core.types", + "description": "spectragraph-core.src.spectragraph_core.core.types", + "peekOfCode": "class Node(BaseModel):\n \"\"\"Represents a node in a transformation flow with position and data.\"\"\"\n id: str = Field(..., description=\"Unique identifier for the node\", title=\"Node ID\")\n data: Dict[str, Any] = Field(\n ..., description=\"Data payload associated with the node\", title=\"Node Data\"\n )\n position: Optional[Dict[str, float]] = Field(\n None, description=\"X and Y coordinates for node positioning\", title=\"Position\"\n )\n type: Optional[str] = Field(", + "detail": "spectragraph-core.src.spectragraph_core.core.types", + "documentation": {} + }, + { + "label": "Edge", + "kind": 6, + "importPath": "spectragraph-core.src.spectragraph_core.core.types", + "description": "spectragraph-core.src.spectragraph_core.core.types", + "peekOfCode": "class Edge(BaseModel):\n \"\"\"Represents an edge connecting two nodes in a transformation flow.\"\"\"\n id: str = Field(..., description=\"Unique identifier for the edge\", title=\"Edge ID\")\n data: Optional[Dict[str, Any]] = Field(\n None, description=\"Data payload associated with the edge\", title=\"Edge Data\"\n )\n source: str = Field(..., description=\"ID of the source node\", title=\"Source Node\")\n target: str = Field(..., description=\"ID of the target node\", title=\"Target Node\")\n sourceHandle: Optional[str] = Field(\n None, description=\"Handle ID on the source node\", title=\"Source Handle\"", + "detail": "spectragraph-core.src.spectragraph_core.core.types", + "documentation": {} + }, + { + "label": "FlowStep", + "kind": 6, + "importPath": "spectragraph-core.src.spectragraph_core.core.types", + "description": "spectragraph-core.src.spectragraph_core.core.types", + "peekOfCode": "class FlowStep(BaseModel):\n \"\"\"Represents a single step in a transformation flow with execution status.\"\"\"\n nodeId: str = Field(..., description=\"ID of the associated node\", title=\"Node ID\")\n params: Optional[Dict[str, Any]] = Field(\n None, description=\"Parameters for the step\", title=\"Parameters\"\n )\n type: Literal[\"type\", \"transform\"] = Field(\n ...,\n description=\"Type of step - either type transformation or transform\",\n title=\"Step Type\",", + "detail": "spectragraph-core.src.spectragraph_core.core.types", + "documentation": {} + }, + { + "label": "FlowBranch", + "kind": 6, + "importPath": "spectragraph-core.src.spectragraph_core.core.types", + "description": "spectragraph-core.src.spectragraph_core.core.types", + "peekOfCode": "class FlowBranch(BaseModel):\n \"\"\"Represents a branch containing a sequence of transformation steps.\"\"\"\n id: str = Field(\n ..., description=\"Unique identifier for the branch\", title=\"Branch ID\"\n )\n name: str = Field(\n ..., description=\"Human-readable name of the branch\", title=\"Branch Name\"\n )\n steps: List[FlowStep] = Field(\n ..., description=\"List of steps in this branch\", title=\"Steps\"", + "detail": "spectragraph-core.src.spectragraph_core.core.types", + "documentation": {} + }, + { + "label": "Role", + "kind": 6, + "importPath": "spectragraph-core.src.spectragraph_core.core.types", + "description": "spectragraph-core.src.spectragraph_core.core.types", + "peekOfCode": "class Role(str, enum.Enum):\n OWNER = \"owner\"\n EDITOR = \"editor\"\n VIEWER = \"viewer\"", + "detail": "spectragraph-core.src.spectragraph_core.core.types", + "documentation": {} + }, + { + "label": "VaultProtocol", + "kind": 6, + "importPath": "spectragraph-core.src.spectragraph_core.core.vault", + "description": "spectragraph-core.src.spectragraph_core.core.vault", + "peekOfCode": "class VaultProtocol(Protocol):\n def get_secret(self, vault_ref: str) -> Optional[str]: ...\n def set_secret(self, vault_ref: str, plain_key: str) -> Key: ...\nclass Vault(VaultProtocol):\n def __init__(self, db: Session, owner_id: uuid.UUID):\n if not owner_id:\n raise ValueError(\"owner_id is required to use the vault.\")\n self.db = db\n self.owner_id = str(owner_id)\n self.version = \"V1\"", + "detail": "spectragraph-core.src.spectragraph_core.core.vault", + "documentation": {} + }, + { + "label": "Vault", + "kind": 6, + "importPath": "spectragraph-core.src.spectragraph_core.core.vault", + "description": "spectragraph-core.src.spectragraph_core.core.vault", + "peekOfCode": "class Vault(VaultProtocol):\n def __init__(self, db: Session, owner_id: uuid.UUID):\n if not owner_id:\n raise ValueError(\"owner_id is required to use the vault.\")\n self.db = db\n self.owner_id = str(owner_id)\n self.version = \"V1\"\n def _get_master_key(self) -> bytes:\n \"\"\"\n Retrieve the master key", + "detail": "spectragraph-core.src.spectragraph_core.core.vault", + "documentation": {} + }, + { + "label": "detect_entity_type", + "kind": 2, + "importPath": "spectragraph-core.src.spectragraph_core.imports.entity_detection", + "description": "spectragraph-core.src.spectragraph_core.imports.entity_detection", + "peekOfCode": "def detect_entity_type(value: str) -> Optional[str]:\n \"\"\"\n Detect entity type based on value pattern.\n Returns the detected entity type or None if no match.\n Args:\n value: The string value to analyze\n Returns:\n Entity type string (e.g., \"Email\", \"Domain\", \"IP\") or None\n \"\"\"\n if not value or not isinstance(value, str):", + "detail": "spectragraph-core.src.spectragraph_core.imports.entity_detection", + "documentation": {} + }, + { + "label": "is_email", + "kind": 2, + "importPath": "spectragraph-core.src.spectragraph_core.imports.entity_detection", + "description": "spectragraph-core.src.spectragraph_core.imports.entity_detection", + "peekOfCode": "def is_email(value: str) -> bool:\n \"\"\"Check if value matches email pattern.\"\"\"\n email_pattern = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$'\n return bool(re.match(email_pattern, value))\ndef is_domain(value: str) -> bool:\n \"\"\"Check if value matches domain pattern.\"\"\"\n # Basic domain pattern: contains dots and valid characters\n domain_pattern = r'^(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\\.)+[a-zA-Z]{2,}$'\n return bool(re.match(domain_pattern, value))\ndef is_ip_address(value: str) -> bool:", + "detail": "spectragraph-core.src.spectragraph_core.imports.entity_detection", + "documentation": {} + }, + { + "label": "is_domain", + "kind": 2, + "importPath": "spectragraph-core.src.spectragraph_core.imports.entity_detection", + "description": "spectragraph-core.src.spectragraph_core.imports.entity_detection", + "peekOfCode": "def is_domain(value: str) -> bool:\n \"\"\"Check if value matches domain pattern.\"\"\"\n # Basic domain pattern: contains dots and valid characters\n domain_pattern = r'^(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\\.)+[a-zA-Z]{2,}$'\n return bool(re.match(domain_pattern, value))\ndef is_ip_address(value: str) -> bool:\n \"\"\"Check if value is a valid IPv4 or IPv6 address.\"\"\"\n try:\n ipaddress.ip_address(value)\n return True", + "detail": "spectragraph-core.src.spectragraph_core.imports.entity_detection", + "documentation": {} + }, + { + "label": "is_ip_address", + "kind": 2, + "importPath": "spectragraph-core.src.spectragraph_core.imports.entity_detection", + "description": "spectragraph-core.src.spectragraph_core.imports.entity_detection", + "peekOfCode": "def is_ip_address(value: str) -> bool:\n \"\"\"Check if value is a valid IPv4 or IPv6 address.\"\"\"\n try:\n ipaddress.ip_address(value)\n return True\n except ValueError:\n return False\ndef is_website(value: str) -> bool:\n \"\"\"Check if value matches URL/website pattern.\"\"\"\n url_pattern = r'^https?://'", + "detail": "spectragraph-core.src.spectragraph_core.imports.entity_detection", + "documentation": {} + }, + { + "label": "is_website", + "kind": 2, + "importPath": "spectragraph-core.src.spectragraph_core.imports.entity_detection", + "description": "spectragraph-core.src.spectragraph_core.imports.entity_detection", + "peekOfCode": "def is_website(value: str) -> bool:\n \"\"\"Check if value matches URL/website pattern.\"\"\"\n url_pattern = r'^https?://'\n return bool(re.match(url_pattern, value, re.IGNORECASE))\ndef is_phone(value: str) -> bool:\n \"\"\"Check if value matches phone number pattern.\"\"\"\n # Remove common separators for checking\n cleaned = re.sub(r'[\\s\\-\\(\\)\\.]', '', value)\n # Check if it's mostly digits and has reasonable length\n phone_pattern = r'^\\+?[0-9]{7,15}$'", + "detail": "spectragraph-core.src.spectragraph_core.imports.entity_detection", + "documentation": {} + }, + { + "label": "is_phone", + "kind": 2, + "importPath": "spectragraph-core.src.spectragraph_core.imports.entity_detection", + "description": "spectragraph-core.src.spectragraph_core.imports.entity_detection", + "peekOfCode": "def is_phone(value: str) -> bool:\n \"\"\"Check if value matches phone number pattern.\"\"\"\n # Remove common separators for checking\n cleaned = re.sub(r'[\\s\\-\\(\\)\\.]', '', value)\n # Check if it's mostly digits and has reasonable length\n phone_pattern = r'^\\+?[0-9]{7,15}$'\n return bool(re.match(phone_pattern, cleaned))\ndef is_asn(value: str) -> bool:\n \"\"\"Check if value matches ASN pattern.\"\"\"\n asn_pattern = r'^AS\\d+$'", + "detail": "spectragraph-core.src.spectragraph_core.imports.entity_detection", + "documentation": {} + }, + { + "label": "is_asn", + "kind": 2, + "importPath": "spectragraph-core.src.spectragraph_core.imports.entity_detection", + "description": "spectragraph-core.src.spectragraph_core.imports.entity_detection", + "peekOfCode": "def is_asn(value: str) -> bool:\n \"\"\"Check if value matches ASN pattern.\"\"\"\n asn_pattern = r'^AS\\d+$'\n return bool(re.match(asn_pattern, value, re.IGNORECASE))\ndef is_username(value: str) -> bool:\n \"\"\"Check if value matches username pattern (social media style).\"\"\"\n # Matches @username format or simple alphanumeric with underscores\n username_pattern = r'^@?[a-zA-Z0-9_]{3,30}$'\n if re.match(username_pattern, value):\n # Additional check: starts with @ or is not purely numeric", + "detail": "spectragraph-core.src.spectragraph_core.imports.entity_detection", + "documentation": {} + }, + { + "label": "is_username", + "kind": 2, + "importPath": "spectragraph-core.src.spectragraph_core.imports.entity_detection", + "description": "spectragraph-core.src.spectragraph_core.imports.entity_detection", + "peekOfCode": "def is_username(value: str) -> bool:\n \"\"\"Check if value matches username pattern (social media style).\"\"\"\n # Matches @username format or simple alphanumeric with underscores\n username_pattern = r'^@?[a-zA-Z0-9_]{3,30}$'\n if re.match(username_pattern, value):\n # Additional check: starts with @ or is not purely numeric\n return value.startswith('@') or not value.lstrip('@').isdigit()\n return False\ndef get_default_label(entity_type: str, value: str) -> str:\n \"\"\"", + "detail": "spectragraph-core.src.spectragraph_core.imports.entity_detection", + "documentation": {} + }, + { + "label": "get_default_label", + "kind": 2, + "importPath": "spectragraph-core.src.spectragraph_core.imports.entity_detection", + "description": "spectragraph-core.src.spectragraph_core.imports.entity_detection", + "peekOfCode": "def get_default_label(entity_type: str, value: str) -> str:\n \"\"\"\n Get default label for an entity based on its type and value.\n Args:\n entity_type: The detected or selected entity type\n value: The entity value\n Returns:\n Default label string\n \"\"\"\n # For most types, the value itself is a good label", + "detail": "spectragraph-core.src.spectragraph_core.imports.entity_detection", + "documentation": {} + }, + { + "label": "DETECTORS", + "kind": 5, + "importPath": "spectragraph-core.src.spectragraph_core.imports.entity_detection", + "description": "spectragraph-core.src.spectragraph_core.imports.entity_detection", + "peekOfCode": "DETECTORS = [\n (\"Email\", lambda v: is_email(v)),\n (\"IP\", lambda v: is_ip_address(v)),\n (\"Website\", lambda v: is_website(v)),\n (\"Domain\", lambda v: is_domain(v)),\n (\"Phone\", lambda v: is_phone(v)),\n (\"ASN\", lambda v: is_asn(v)),\n (\"Username\", lambda v: is_username(v)),\n]\ndef detect_entity_type(value: str) -> Optional[str]:", + "detail": "spectragraph-core.src.spectragraph_core.imports.entity_detection", + "documentation": {} + }, + { + "label": "EntityPreview", + "kind": 6, + "importPath": "spectragraph-core.src.spectragraph_core.imports.file_parser", + "description": "spectragraph-core.src.spectragraph_core.imports.file_parser", + "peekOfCode": "class EntityPreview:\n \"\"\"Preview of a single entity to be imported.\"\"\"\n row_index: int\n \"\"\"Index of the row (0-based).\"\"\"\n data: Dict[str, Any]\n \"\"\"All column data as key-value pairs.\"\"\"\n detected_type: str\n \"\"\"Detected entity type (e.g., \"Email\", \"Domain\").\"\"\"\n primary_value: str\n \"\"\"Primary identifier value for the entity.\"\"\"", + "detail": "spectragraph-core.src.spectragraph_core.imports.file_parser", + "documentation": {} + }, + { + "label": "FileParseResult", + "kind": 6, + "importPath": "spectragraph-core.src.spectragraph_core.imports.file_parser", + "description": "spectragraph-core.src.spectragraph_core.imports.file_parser", + "peekOfCode": "class FileParseResult:\n \"\"\"Result of parsing an import file.\"\"\"\n entities: List[EntityPreview]\n \"\"\"List of detected entities from the file.\"\"\"\n total_entities: int\n \"\"\"Total number of entities (rows).\"\"\"\n type_distribution: Dict[str, int]\n \"\"\"Distribution of detected types: {type_name: count}.\"\"\"\n columns: List[str]\n \"\"\"Column names found in the file (for reference).\"\"\"", + "detail": "spectragraph-core.src.spectragraph_core.imports.file_parser", + "documentation": {} + }, + { + "label": "parse_file", + "kind": 2, + "importPath": "spectragraph-core.src.spectragraph_core.imports.file_parser", + "description": "spectragraph-core.src.spectragraph_core.imports.file_parser", + "peekOfCode": "def parse_file(\n file_content: Union[bytes, BinaryIO],\n filename: str,\n max_preview_rows: int = 100,\n) -> FileParseResult:\n \"\"\"\n Parse an uploaded file and analyze its contents.\n Each row is treated as a single entity.\n Args:\n file_content: File content as bytes or file-like object", + "detail": "spectragraph-core.src.spectragraph_core.imports.file_parser", + "documentation": {} + }, + { + "label": "detect_entity_type_from_row", + "kind": 2, + "importPath": "spectragraph-core.src.spectragraph_core.imports.type_matcher", + "description": "spectragraph-core.src.spectragraph_core.imports.type_matcher", + "peekOfCode": "def detect_entity_type_from_row(row_data: Dict[str, Any]) -> Optional[str]:\n \"\"\"\n Detect the most likely entity type for a row of data.\n Args:\n row_data: Dictionary of column_name: value pairs\n Returns:\n Entity type name (e.g., \"Email\", \"Domain\", \"Ip\") or None\n \"\"\"\n if not row_data:\n return None", + "detail": "spectragraph-core.src.spectragraph_core.imports.type_matcher", + "documentation": {} + }, + { + "label": "get_primary_identifier", + "kind": 2, + "importPath": "spectragraph-core.src.spectragraph_core.imports.type_matcher", + "description": "spectragraph-core.src.spectragraph_core.imports.type_matcher", + "peekOfCode": "def get_primary_identifier(row_data: Dict[str, Any], entity_type: str) -> Optional[str]:\n \"\"\"\n Get the primary identifier value for an entity based on its type.\n Args:\n row_data: Dictionary of column_name: value pairs\n entity_type: The detected entity type\n Returns:\n The primary identifier value (e.g., email address, domain name, IP)\n \"\"\"\n normalized_data = {k.lower().strip(): v for k, v in row_data.items() if v}", + "detail": "spectragraph-core.src.spectragraph_core.imports.type_matcher", + "documentation": {} + }, + { + "label": "emit_event_task", + "kind": 2, + "importPath": "spectragraph-core.src.spectragraph_core.tasks.event", + "description": "spectragraph-core.src.spectragraph_core.tasks.event", + "peekOfCode": "def emit_event_task(log_id: str, sketch_id: str, log_type: EventLevel, content: Dict):\n \"\"\"Celery task to emit a log event\"\"\"\n try:\n event = Event(\n id=log_id, sketch_id=sketch_id, type=log_type, payload=content\n ).model_dump_json()\n redis_client = redis.from_url(os.environ[\"REDIS_URL\"])\n redis_client.publish(sketch_id, event)\n except Exception as e:\n raise", + "detail": "spectragraph-core.src.spectragraph_core.tasks.event", + "documentation": {} + }, + { + "label": "logger", + "kind": 5, + "importPath": "spectragraph-core.src.spectragraph_core.tasks.event", + "description": "spectragraph-core.src.spectragraph_core.tasks.event", + "peekOfCode": "logger = logging.getLogger(__name__)\n@celery.task(name=\"emit_event\")\ndef emit_event_task(log_id: str, sketch_id: str, log_type: EventLevel, content: Dict):\n \"\"\"Celery task to emit a log event\"\"\"\n try:\n event = Event(\n id=log_id, sketch_id=sketch_id, type=log_type, payload=content\n ).model_dump_json()\n redis_client = redis.from_url(os.environ[\"REDIS_URL\"])\n redis_client.publish(sketch_id, event)", + "detail": "spectragraph-core.src.spectragraph_core.tasks.event", + "documentation": {} + }, + { + "label": "run_flow", + "kind": 2, + "importPath": "spectragraph-core.src.spectragraph_core.tasks.flow", + "description": "spectragraph-core.src.spectragraph_core.tasks.flow", + "peekOfCode": "def run_flow(\n self,\n transform_branches,\n values: List[str],\n sketch_id: str | None,\n owner_id: Optional[str] = None,\n):\n session = SessionLocal()\n try:\n if not transform_branches:", + "detail": "spectragraph-core.src.spectragraph_core.tasks.flow", + "documentation": {} + }, + { + "label": "URI", + "kind": 5, + "importPath": "spectragraph-core.src.spectragraph_core.tasks.flow", + "description": "spectragraph-core.src.spectragraph_core.tasks.flow", + "peekOfCode": "URI = os.getenv(\"NEO4J_URI_BOLT\")\nUSERNAME = os.getenv(\"NEO4J_USERNAME\")\nPASSWORD = os.getenv(\"NEO4J_PASSWORD\")\nneo4j_connection = Neo4jConnection(URI, USERNAME, PASSWORD)\ndb: Session = next(get_db())\nlogger = Logger()\n@celery.task(name=\"run_flow\", bind=True)\ndef run_flow(\n self,\n transform_branches,", + "detail": "spectragraph-core.src.spectragraph_core.tasks.flow", + "documentation": {} + }, + { + "label": "USERNAME", + "kind": 5, + "importPath": "spectragraph-core.src.spectragraph_core.tasks.flow", + "description": "spectragraph-core.src.spectragraph_core.tasks.flow", + "peekOfCode": "USERNAME = os.getenv(\"NEO4J_USERNAME\")\nPASSWORD = os.getenv(\"NEO4J_PASSWORD\")\nneo4j_connection = Neo4jConnection(URI, USERNAME, PASSWORD)\ndb: Session = next(get_db())\nlogger = Logger()\n@celery.task(name=\"run_flow\", bind=True)\ndef run_flow(\n self,\n transform_branches,\n values: List[str],", + "detail": "spectragraph-core.src.spectragraph_core.tasks.flow", + "documentation": {} + }, + { + "label": "PASSWORD", + "kind": 5, + "importPath": "spectragraph-core.src.spectragraph_core.tasks.flow", + "description": "spectragraph-core.src.spectragraph_core.tasks.flow", + "peekOfCode": "PASSWORD = os.getenv(\"NEO4J_PASSWORD\")\nneo4j_connection = Neo4jConnection(URI, USERNAME, PASSWORD)\ndb: Session = next(get_db())\nlogger = Logger()\n@celery.task(name=\"run_flow\", bind=True)\ndef run_flow(\n self,\n transform_branches,\n values: List[str],\n sketch_id: str | None,", + "detail": "spectragraph-core.src.spectragraph_core.tasks.flow", + "documentation": {} + }, + { + "label": "neo4j_connection", + "kind": 5, + "importPath": "spectragraph-core.src.spectragraph_core.tasks.flow", + "description": "spectragraph-core.src.spectragraph_core.tasks.flow", + "peekOfCode": "neo4j_connection = Neo4jConnection(URI, USERNAME, PASSWORD)\ndb: Session = next(get_db())\nlogger = Logger()\n@celery.task(name=\"run_flow\", bind=True)\ndef run_flow(\n self,\n transform_branches,\n values: List[str],\n sketch_id: str | None,\n owner_id: Optional[str] = None,", + "detail": "spectragraph-core.src.spectragraph_core.tasks.flow", + "documentation": {} + }, + { + "label": "logger", + "kind": 5, + "importPath": "spectragraph-core.src.spectragraph_core.tasks.flow", + "description": "spectragraph-core.src.spectragraph_core.tasks.flow", + "peekOfCode": "logger = Logger()\n@celery.task(name=\"run_flow\", bind=True)\ndef run_flow(\n self,\n transform_branches,\n values: List[str],\n sketch_id: str | None,\n owner_id: Optional[str] = None,\n):\n session = SessionLocal()", + "detail": "spectragraph-core.src.spectragraph_core.tasks.flow", + "documentation": {} + }, + { + "label": "run_transform", + "kind": 2, + "importPath": "spectragraph-core.src.spectragraph_core.tasks.transform", + "description": "spectragraph-core.src.spectragraph_core.tasks.transform", + "peekOfCode": "def run_transform(\n self,\n transform_name: str,\n values: List[str],\n sketch_id: str | None,\n owner_id: Optional[str] = None,\n):\n session = SessionLocal()\n try:\n scan_id = uuid.UUID(self.request.id)", + "detail": "spectragraph-core.src.spectragraph_core.tasks.transform", + "documentation": {} + }, + { + "label": "URI", + "kind": 5, + "importPath": "spectragraph-core.src.spectragraph_core.tasks.transform", + "description": "spectragraph-core.src.spectragraph_core.tasks.transform", + "peekOfCode": "URI = os.getenv(\"NEO4J_URI_BOLT\")\nUSERNAME = os.getenv(\"NEO4J_USERNAME\")\nPASSWORD = os.getenv(\"NEO4J_PASSWORD\")\nneo4j_connection = Neo4jConnection(URI, USERNAME, PASSWORD)\ndb: Session = next(get_db())\nlogger = Logger()\n@celery.task(name=\"run_transform\", bind=True)\ndef run_transform(\n self,\n transform_name: str,", + "detail": "spectragraph-core.src.spectragraph_core.tasks.transform", + "documentation": {} + }, + { + "label": "USERNAME", + "kind": 5, + "importPath": "spectragraph-core.src.spectragraph_core.tasks.transform", + "description": "spectragraph-core.src.spectragraph_core.tasks.transform", + "peekOfCode": "USERNAME = os.getenv(\"NEO4J_USERNAME\")\nPASSWORD = os.getenv(\"NEO4J_PASSWORD\")\nneo4j_connection = Neo4jConnection(URI, USERNAME, PASSWORD)\ndb: Session = next(get_db())\nlogger = Logger()\n@celery.task(name=\"run_transform\", bind=True)\ndef run_transform(\n self,\n transform_name: str,\n values: List[str],", + "detail": "spectragraph-core.src.spectragraph_core.tasks.transform", + "documentation": {} + }, + { + "label": "PASSWORD", + "kind": 5, + "importPath": "spectragraph-core.src.spectragraph_core.tasks.transform", + "description": "spectragraph-core.src.spectragraph_core.tasks.transform", + "peekOfCode": "PASSWORD = os.getenv(\"NEO4J_PASSWORD\")\nneo4j_connection = Neo4jConnection(URI, USERNAME, PASSWORD)\ndb: Session = next(get_db())\nlogger = Logger()\n@celery.task(name=\"run_transform\", bind=True)\ndef run_transform(\n self,\n transform_name: str,\n values: List[str],\n sketch_id: str | None,", + "detail": "spectragraph-core.src.spectragraph_core.tasks.transform", + "documentation": {} + }, + { + "label": "neo4j_connection", + "kind": 5, + "importPath": "spectragraph-core.src.spectragraph_core.tasks.transform", + "description": "spectragraph-core.src.spectragraph_core.tasks.transform", + "peekOfCode": "neo4j_connection = Neo4jConnection(URI, USERNAME, PASSWORD)\ndb: Session = next(get_db())\nlogger = Logger()\n@celery.task(name=\"run_transform\", bind=True)\ndef run_transform(\n self,\n transform_name: str,\n values: List[str],\n sketch_id: str | None,\n owner_id: Optional[str] = None,", + "detail": "spectragraph-core.src.spectragraph_core.tasks.transform", + "documentation": {} + }, + { + "label": "logger", + "kind": 5, + "importPath": "spectragraph-core.src.spectragraph_core.tasks.transform", + "description": "spectragraph-core.src.spectragraph_core.tasks.transform", + "peekOfCode": "logger = Logger()\n@celery.task(name=\"run_transform\", bind=True)\ndef run_transform(\n self,\n transform_name: str,\n values: List[str],\n sketch_id: str | None,\n owner_id: Optional[str] = None,\n):\n session = SessionLocal()", + "detail": "spectragraph-core.src.spectragraph_core.tasks.transform", + "documentation": {} + }, + { + "label": "TestPasswordHashing", + "kind": 6, + "importPath": "spectragraph-core.src.spectragraph_core.tests.test_auth", + "description": "spectragraph-core.src.spectragraph_core.tests.test_auth", + "peekOfCode": "class TestPasswordHashing:\n \"\"\"Test password hashing and verification.\"\"\"\n def test_password_hash_and_verify(self):\n \"\"\"Test that password hashing and verification works correctly.\"\"\"\n password = \"test_password_123\"\n hashed = get_password_hash(password)\n # Hashed password should be different from plain password\n assert hashed != password\n # Verification should succeed with correct password\n assert verify_password(password, hashed) is True", + "detail": "spectragraph-core.src.spectragraph_core.tests.test_auth", + "documentation": {} + }, + { + "label": "TestTokenGeneration", + "kind": 6, + "importPath": "spectragraph-core.src.spectragraph_core.tests.test_auth", + "description": "spectragraph-core.src.spectragraph_core.tests.test_auth", + "peekOfCode": "class TestTokenGeneration:\n \"\"\"Test JWT token generation and expiration.\"\"\"\n def test_token_expiration_is_60_minutes(self):\n \"\"\"\n Test that ACCESS_TOKEN_EXPIRE_MINUTES is set to 60 minutes (1 hour).\n This is a security requirement - tokens should not be valid for too long.\n Previously this was incorrectly set to 3600 minutes (60 hours).\n \"\"\"\n assert ACCESS_TOKEN_EXPIRE_MINUTES == 60, (\n f\"Token expiration should be 60 minutes, but is set to \"", + "detail": "spectragraph-core.src.spectragraph_core.tests.test_auth", + "documentation": {} + }, + { + "label": "os.environ['AUTH_SECRET']", + "kind": 5, + "importPath": "spectragraph-core.src.spectragraph_core.tests.test_auth", + "description": "spectragraph-core.src.spectragraph_core.tests.test_auth", + "peekOfCode": "os.environ['AUTH_SECRET'] = 'test_secret_for_testing_only'\nfrom jose import jwt\nfrom spectragraph_core.core.auth import (\n create_access_token,\n verify_password,\n get_password_hash,\n ACCESS_TOKEN_EXPIRE_MINUTES,\n AUTH_SECRET,\n ALGORITHM,\n)", + "detail": "spectragraph-core.src.spectragraph_core.tests.test_auth", + "documentation": {} + }, + { + "label": "is_valid_ip", + "kind": 2, + "importPath": "spectragraph-core.src.spectragraph_core.utils", + "description": "spectragraph-core.src.spectragraph_core.utils", + "peekOfCode": "def is_valid_ip(address: str) -> bool:\n try:\n ipaddress.ip_address(address)\n return True\n except ValueError:\n return False\ndef is_valid_username(username: str) -> bool:\n if not re.match(r\"^[a-zA-Z0-9_-]{3,30}$\", username):\n return False\n return True", + "detail": "spectragraph-core.src.spectragraph_core.utils", + "documentation": {} + }, + { + "label": "is_valid_username", + "kind": 2, + "importPath": "spectragraph-core.src.spectragraph_core.utils", + "description": "spectragraph-core.src.spectragraph_core.utils", + "peekOfCode": "def is_valid_username(username: str) -> bool:\n if not re.match(r\"^[a-zA-Z0-9_-]{3,30}$\", username):\n return False\n return True\ndef is_valid_email(email: str) -> bool:\n if not re.match(r\"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$\", email):\n return False\n return True\ndef is_valid_domain(url_or_domain: str) -> str:\n try:", + "detail": "spectragraph-core.src.spectragraph_core.utils", + "documentation": {} + }, + { + "label": "is_valid_email", + "kind": 2, + "importPath": "spectragraph-core.src.spectragraph_core.utils", + "description": "spectragraph-core.src.spectragraph_core.utils", + "peekOfCode": "def is_valid_email(email: str) -> bool:\n if not re.match(r\"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$\", email):\n return False\n return True\ndef is_valid_domain(url_or_domain: str) -> str:\n try:\n parsed = urlparse(\n url_or_domain if \"://\" in url_or_domain else \"http://\" + url_or_domain\n )\n hostname = parsed.hostname or url_or_domain", + "detail": "spectragraph-core.src.spectragraph_core.utils", + "documentation": {} + }, + { + "label": "is_valid_domain", + "kind": 2, + "importPath": "spectragraph-core.src.spectragraph_core.utils", + "description": "spectragraph-core.src.spectragraph_core.utils", + "peekOfCode": "def is_valid_domain(url_or_domain: str) -> str:\n try:\n parsed = urlparse(\n url_or_domain if \"://\" in url_or_domain else \"http://\" + url_or_domain\n )\n hostname = parsed.hostname or url_or_domain\n if not hostname or \".\" not in hostname:\n return False\n if not re.match(r\"^[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$\", hostname):\n return False", + "detail": "spectragraph-core.src.spectragraph_core.utils", + "documentation": {} + }, + { + "label": "is_root_domain", + "kind": 2, + "importPath": "spectragraph-core.src.spectragraph_core.utils", + "description": "spectragraph-core.src.spectragraph_core.utils", + "peekOfCode": "def is_root_domain(domain: str) -> bool:\n \"\"\"\n Determine if a domain is a root domain or subdomain.\n Args:\n domain: The domain string to check\n Returns:\n True if it's a root domain (e.g., example.com), False if it's a subdomain (e.g., sub.example.com)\n \"\"\"\n try:\n # Remove protocol if present", + "detail": "spectragraph-core.src.spectragraph_core.utils", + "documentation": {} + }, + { + "label": "is_valid_number", + "kind": 2, + "importPath": "spectragraph-core.src.spectragraph_core.utils", + "description": "spectragraph-core.src.spectragraph_core.utils", + "peekOfCode": "def is_valid_number(phone: str, region: str = \"FR\") -> None:\n \"\"\"\n Validates a phone number. Raises InvalidPhoneNumberError if invalid.\n - `region` should be ISO 3166-1 alpha-2 country code (e.g., 'FR' for France)\n \"\"\"\n try:\n parsed = phonenumbers.parse(phone, region)\n if not phonenumbers.is_valid_number(parsed):\n return False\n except NumberParseException:", + "detail": "spectragraph-core.src.spectragraph_core.utils", + "documentation": {} + }, + { + "label": "parse_asn", + "kind": 2, + "importPath": "spectragraph-core.src.spectragraph_core.utils", + "description": "spectragraph-core.src.spectragraph_core.utils", + "peekOfCode": "def parse_asn(asn: str) -> int:\n if not is_valid_asn(asn):\n raise ValueError(f\"Invalid ASN format: {asn}\")\n return int(re.sub(r\"(?i)^AS\", \"\", asn))\ndef is_valid_asn(asn: str) -> bool:\n if not re.fullmatch(r\"(AS)?\\d+\", asn, re.IGNORECASE):\n return False\n asn_num = int(re.sub(r\"(?i)^AS\", \"\", asn))\n return 0 <= asn_num <= 4294967295\ndef resolve_type(details: dict, schema_context: dict = None) -> str:", + "detail": "spectragraph-core.src.spectragraph_core.utils", + "documentation": {} + }, + { + "label": "is_valid_asn", + "kind": 2, + "importPath": "spectragraph-core.src.spectragraph_core.utils", + "description": "spectragraph-core.src.spectragraph_core.utils", + "peekOfCode": "def is_valid_asn(asn: str) -> bool:\n if not re.fullmatch(r\"(AS)?\\d+\", asn, re.IGNORECASE):\n return False\n asn_num = int(re.sub(r\"(?i)^AS\", \"\", asn))\n return 0 <= asn_num <= 4294967295\ndef resolve_type(details: dict, schema_context: dict = None) -> str:\n if \"anyOf\" in details:\n types = []\n for option in details[\"anyOf\"]:\n if \"$ref\" in option:", + "detail": "spectragraph-core.src.spectragraph_core.utils", + "documentation": {} + }, + { + "label": "resolve_type", + "kind": 2, + "importPath": "spectragraph-core.src.spectragraph_core.utils", + "description": "spectragraph-core.src.spectragraph_core.utils", + "peekOfCode": "def resolve_type(details: dict, schema_context: dict = None) -> str:\n if \"anyOf\" in details:\n types = []\n for option in details[\"anyOf\"]:\n if \"$ref\" in option:\n ref = option[\"$ref\"].split(\"/\")[-1]\n types.append(ref)\n elif option.get(\"type\") == \"array\":\n # Handle array types within anyOf\n item_type = resolve_type(option.get(\"items\", {}), schema_context)", + "detail": "spectragraph-core.src.spectragraph_core.utils", + "documentation": {} + }, + { + "label": "extract_input_schema_flow", + "kind": 2, + "importPath": "spectragraph-core.src.spectragraph_core.utils", + "description": "spectragraph-core.src.spectragraph_core.utils", + "peekOfCode": "def extract_input_schema_flow(model: Type[BaseModel]) -> Dict[str, Any]:\n adapter = TypeAdapter(model)\n schema = adapter.json_schema()\n # Use the main schema properties, not the $defs\n type_name = model.__name__\n details = schema\n return {\n \"class_name\": model.__name__,\n \"name\": model.__name__,\n \"module\": model.__module__,", + "detail": "spectragraph-core.src.spectragraph_core.utils", + "documentation": {} + }, + { + "label": "get_domain_from_ssl", + "kind": 2, + "importPath": "spectragraph-core.src.spectragraph_core.utils", + "description": "spectragraph-core.src.spectragraph_core.utils", + "peekOfCode": "def get_domain_from_ssl(ip: str, port: int = 443) -> str | None:\n try:\n context = ssl.create_default_context()\n with socket.create_connection((ip, port), timeout=3) as sock:\n with context.wrap_socket(sock, server_hostname=ip) as ssock:\n cert = ssock.getpeercert()\n subject = cert.get(\"subject\", [])\n for entry in subject:\n if entry[0][0] == \"commonName\":\n return entry[0][1]", + "detail": "spectragraph-core.src.spectragraph_core.utils", + "documentation": {} + }, + { + "label": "extract_transform", + "kind": 2, + "importPath": "spectragraph-core.src.spectragraph_core.utils", + "description": "spectragraph-core.src.spectragraph_core.utils", + "peekOfCode": "def extract_transform(transform: Dict[str, Any]) -> Dict[str, Any]:\n nodes = transform[\"nodes\"]\n edges = transform[\"edges\"]\n input_node = next((node for node in nodes if node[\"data\"][\"type\"] == \"type\"), None)\n if not input_node:\n raise ValueError(\"No input node found.\")\n input_output = input_node[\"data\"][\"outputs\"]\n node_lookup = {node[\"id\"]: node for node in nodes}\n transforms = []\n for edge in edges:", + "detail": "spectragraph-core.src.spectragraph_core.utils", + "documentation": {} + }, + { + "label": "get_label_color", + "kind": 2, + "importPath": "spectragraph-core.src.spectragraph_core.utils", + "description": "spectragraph-core.src.spectragraph_core.utils", + "peekOfCode": "def get_label_color(label: str) -> str:\n color_map = {\"subdomain\": \"#A5ABB6\", \"domain\": \"#68BDF6\", \"default\": \"#A5ABB6\"}\n return color_map.get(label, color_map[\"default\"])\ndef flatten(data_dict, prefix=\"\"):\n \"\"\"\n Flattens a dictionary to contain only Neo4j-compatible property values.\n Neo4j supports primitive types (string, number, boolean) and arrays of those types.\n Args:\n data_dict (dict): Dictionary to flatten\n Returns:", + "detail": "spectragraph-core.src.spectragraph_core.utils", + "documentation": {} + }, + { + "label": "flatten", + "kind": 2, + "importPath": "spectragraph-core.src.spectragraph_core.utils", + "description": "spectragraph-core.src.spectragraph_core.utils", + "peekOfCode": "def flatten(data_dict, prefix=\"\"):\n \"\"\"\n Flattens a dictionary to contain only Neo4j-compatible property values.\n Neo4j supports primitive types (string, number, boolean) and arrays of those types.\n Args:\n data_dict (dict): Dictionary to flatten\n Returns:\n dict: Flattened dictionary with only Neo4j-compatible values\n \"\"\"\n flattened = {}", + "detail": "spectragraph-core.src.spectragraph_core.utils", + "documentation": {} + }, + { + "label": "get_inline_relationships", + "kind": 2, + "importPath": "spectragraph-core.src.spectragraph_core.utils", + "description": "spectragraph-core.src.spectragraph_core.utils", + "peekOfCode": "def get_inline_relationships(nodes: List[Any], edges: List[Any]) -> List[str]:\n \"\"\"\n Get the inline relationships for a list of nodes and edges.\n \"\"\"\n relationships = []\n for edge in edges:\n source = next((node for node in nodes if node[\"id\"] == edge[\"source\"]), None)\n target = next((node for node in nodes if node[\"id\"] == edge[\"target\"]), None)\n if source and target:\n relationships.append({\"source\": source, \"edge\": edge, \"target\": target})", + "detail": "spectragraph-core.src.spectragraph_core.utils", + "documentation": {} + }, + { + "label": "to_json_serializable", + "kind": 2, + "importPath": "spectragraph-core.src.spectragraph_core.utils", + "description": "spectragraph-core.src.spectragraph_core.utils", + "peekOfCode": "def to_json_serializable(obj):\n \"\"\"Convert any object to a JSON-serializable format.\"\"\"\n import json\n from pydantic import BaseModel\n try:\n # Test if already JSON serializable\n json.dumps(obj)\n return obj\n except (TypeError, ValueError):\n # Handle common cases", + "detail": "spectragraph-core.src.spectragraph_core.utils", + "documentation": {} + }, + { + "label": "TestEmailDetection", + "kind": 6, + "importPath": "spectragraph-core.tests.import.test_entity_detection", + "description": "spectragraph-core.tests.import.test_entity_detection", + "peekOfCode": "class TestEmailDetection:\n \"\"\"Tests for email detection.\"\"\"\n def test_valid_emails(self):\n \"\"\"Test detection of valid email addresses.\"\"\"\n valid_emails = [\n \"user@example.com\",\n \"test.user@domain.co.uk\",\n \"admin+tag@company.org\",\n \"user_name@sub.domain.com\",\n \"123@numbers.com\",", + "detail": "spectragraph-core.tests.import.test_entity_detection", + "documentation": {} + }, + { + "label": "TestDomainDetection", + "kind": 6, + "importPath": "spectragraph-core.tests.import.test_entity_detection", + "description": "spectragraph-core.tests.import.test_entity_detection", + "peekOfCode": "class TestDomainDetection:\n \"\"\"Tests for domain detection.\"\"\"\n def test_valid_domains(self):\n \"\"\"Test detection of valid domains.\"\"\"\n valid_domains = [\n \"example.com\",\n \"sub.domain.com\",\n \"my-domain.co.uk\",\n \"test123.org\",\n \"a.b.c.d.example.com\",", + "detail": "spectragraph-core.tests.import.test_entity_detection", + "documentation": {} + }, + { + "label": "TestIPAddressDetection", + "kind": 6, + "importPath": "spectragraph-core.tests.import.test_entity_detection", + "description": "spectragraph-core.tests.import.test_entity_detection", + "peekOfCode": "class TestIPAddressDetection:\n \"\"\"Tests for IP address detection.\"\"\"\n def test_valid_ipv4(self):\n \"\"\"Test detection of valid IPv4 addresses.\"\"\"\n valid_ips = [\n \"192.168.1.1\",\n \"10.0.0.1\",\n \"172.16.0.1\",\n \"8.8.8.8\",\n \"255.255.255.255\",", + "detail": "spectragraph-core.tests.import.test_entity_detection", + "documentation": {} + }, + { + "label": "TestWebsiteDetection", + "kind": 6, + "importPath": "spectragraph-core.tests.import.test_entity_detection", + "description": "spectragraph-core.tests.import.test_entity_detection", + "peekOfCode": "class TestWebsiteDetection:\n \"\"\"Tests for website/URL detection.\"\"\"\n def test_valid_websites(self):\n \"\"\"Test detection of valid URLs.\"\"\"\n valid_urls = [\n \"http://example.com\",\n \"https://www.example.com\",\n \"http://sub.domain.com/path\",\n \"https://example.com:8080/path?query=value\",\n ]", + "detail": "spectragraph-core.tests.import.test_entity_detection", + "documentation": {} + }, + { + "label": "TestPhoneDetection", + "kind": 6, + "importPath": "spectragraph-core.tests.import.test_entity_detection", + "description": "spectragraph-core.tests.import.test_entity_detection", + "peekOfCode": "class TestPhoneDetection:\n \"\"\"Tests for phone number detection.\"\"\"\n def test_valid_phones(self):\n \"\"\"Test detection of valid phone numbers.\"\"\"\n valid_phones = [\n \"+1234567890\",\n \"123-456-7890\",\n \"(123) 456-7890\",\n \"+44 20 7123 4567\",\n \"555.123.4567\",", + "detail": "spectragraph-core.tests.import.test_entity_detection", + "documentation": {} + }, + { + "label": "TestASNDetection", + "kind": 6, + "importPath": "spectragraph-core.tests.import.test_entity_detection", + "description": "spectragraph-core.tests.import.test_entity_detection", + "peekOfCode": "class TestASNDetection:\n \"\"\"Tests for ASN detection.\"\"\"\n def test_valid_asns(self):\n \"\"\"Test detection of valid ASNs.\"\"\"\n valid_asns = [\n \"AS13335\",\n \"as64512\",\n \"AS1\",\n \"AS4294967295\",\n ]", + "detail": "spectragraph-core.tests.import.test_entity_detection", + "documentation": {} + }, + { + "label": "TestUsernameDetection", + "kind": 6, + "importPath": "spectragraph-core.tests.import.test_entity_detection", + "description": "spectragraph-core.tests.import.test_entity_detection", + "peekOfCode": "class TestUsernameDetection:\n \"\"\"Tests for username detection.\"\"\"\n def test_valid_usernames(self):\n \"\"\"Test detection of valid usernames.\"\"\"\n valid_usernames = [\n \"@john_doe\",\n \"@user123\",\n \"username\",\n \"user_name_123\",\n ]", + "detail": "spectragraph-core.tests.import.test_entity_detection", + "documentation": {} + }, + { + "label": "TestDetectionPriority", + "kind": 6, + "importPath": "spectragraph-core.tests.import.test_entity_detection", + "description": "spectragraph-core.tests.import.test_entity_detection", + "peekOfCode": "class TestDetectionPriority:\n \"\"\"Tests for detection priority and edge cases.\"\"\"\n def test_email_vs_username(self):\n \"\"\"Email should take priority over username.\"\"\"\n assert detect_entity_type(\"user@example.com\") == \"Email\"\n def test_url_vs_domain(self):\n \"\"\"URL should take priority over domain.\"\"\"\n assert detect_entity_type(\"http://example.com\") == \"Website\"\n assert detect_entity_type(\"example.com\") == \"Domain\"\n def test_ip_vs_domain(self):", + "detail": "spectragraph-core.tests.import.test_entity_detection", + "documentation": {} + }, + { + "label": "TestGetDefaultLabel", + "kind": 6, + "importPath": "spectragraph-core.tests.import.test_entity_detection", + "description": "spectragraph-core.tests.import.test_entity_detection", + "peekOfCode": "class TestGetDefaultLabel:\n \"\"\"Tests for get_default_label function.\"\"\"\n def test_email_label(self):\n \"\"\"Test label generation for email.\"\"\"\n assert get_default_label(\"Email\", \"user@example.com\") == \"user@example.com\"\n def test_domain_label(self):\n \"\"\"Test label generation for domain.\"\"\"\n assert get_default_label(\"Domain\", \"example.com\") == \"example.com\"\n def test_ip_label(self):\n \"\"\"Test label generation for IP.\"\"\"", + "detail": "spectragraph-core.tests.import.test_entity_detection", + "documentation": {} + }, + { + "label": "TestEntityBasedImportWorkflow", + "kind": 6, + "importPath": "spectragraph-core.tests.import.test_import_integration", + "description": "spectragraph-core.tests.import.test_import_integration", + "peekOfCode": "class TestEntityBasedImportWorkflow:\n \"\"\"Integration tests for entity-based import workflow.\"\"\"\n def test_full_entity_workflow(self):\n \"\"\"Test complete workflow: parse file -> detect entities -> prepare for import.\"\"\"\n # Step 1: User uploads a CSV file (each row = one entity)\n csv_content = b\"\"\"email,name,department\nadmin@example.com,John Admin,IT\nuser@test.org,Jane User,HR\nsecurity@company.com,Bob Security,Security\n\"\"\"", + "detail": "spectragraph-core.tests.import.test_import_integration", + "documentation": {} + }, + { + "label": "TestRealWorldEntityScenarios", + "kind": 6, + "importPath": "spectragraph-core.tests.import.test_import_integration", + "description": "spectragraph-core.tests.import.test_import_integration", + "peekOfCode": "class TestRealWorldEntityScenarios:\n \"\"\"Real-world scenario tests with entity-based approach.\"\"\"\n def test_organization_import(self):\n \"\"\"Test importing organizations with metadata.\"\"\"\n csv_content = b\"\"\"name,industry,country,employees\nGoogle,Technology,USA,150000\nMicrosoft,Software,USA,220000\nApple,Technology,USA,164000\n\"\"\"\n result = parse_file(csv_content, \"orgs.csv\")", + "detail": "spectragraph-core.tests.import.test_import_integration", + "documentation": {} + }, + { + "label": "TestTypeDistribution", + "kind": 6, + "importPath": "spectragraph-core.tests.import.test_import_integration", + "description": "spectragraph-core.tests.import.test_import_integration", + "peekOfCode": "class TestTypeDistribution:\n \"\"\"Tests for type distribution in entity-based approach.\"\"\"\n def test_mixed_entity_types(self):\n \"\"\"Test file with multiple entity types.\"\"\"\n txt_content = b\"\"\"example.com\ntest.org\nuser@example.com\nadmin@test.org\n192.168.1.1\n10.0.0.1", + "detail": "spectragraph-core.tests.import.test_import_integration", + "documentation": {} + }, + { + "label": "TestEdgeCases", + "kind": 6, + "importPath": "spectragraph-core.tests.import.test_import_integration", + "description": "spectragraph-core.tests.import.test_import_integration", + "peekOfCode": "class TestEdgeCases:\n \"\"\"Edge case tests for entity-based import.\"\"\"\n def test_single_column_csv(self):\n \"\"\"Test CSV with single column.\"\"\"\n csv_content = b\"\"\"email\nuser@example.com\nadmin@test.org\n\"\"\"\n result = parse_file(csv_content, \"single_column.csv\")\n assert result.total_entities == 2", + "detail": "spectragraph-core.tests.import.test_import_integration", + "documentation": {} + }, + { + "label": "MockTransform", + "kind": 6, + "importPath": "spectragraph-core.tests.vault.test_transform_vault_integration", + "description": "spectragraph-core.tests.vault.test_transform_vault_integration", + "peekOfCode": "class MockTransform(Transform):\n \"\"\"Mock transform for testing.\"\"\"\n InputType = List[str]\n OutputType = List[str]\n @classmethod\n def name(cls) -> str:\n return \"mock_transform\"\n @classmethod\n def category(cls) -> str:\n return \"Test\"", + "detail": "spectragraph-core.tests.vault.test_transform_vault_integration", + "documentation": {} + }, + { + "label": "TestResolveParams", + "kind": 6, + "importPath": "spectragraph-core.tests.vault.test_transform_vault_integration", + "description": "spectragraph-core.tests.vault.test_transform_vault_integration", + "peekOfCode": "class TestResolveParams:\n \"\"\"Tests for resolve_params() method.\"\"\"\n def test_resolve_vault_secret_by_name(self, transform, mock_vault):\n \"\"\"Test resolving a vault secret by parameter name.\"\"\"\n secret_value = \"my-api-key-12345\"\n mock_vault.get_secret.return_value = secret_value\n resolved = transform.resolve_params()\n # Should try to get by name \"TEST_API_KEY\"\n assert mock_vault.get_secret.called\n assert \"TEST_API_KEY\" in resolved", + "detail": "spectragraph-core.tests.vault.test_transform_vault_integration", + "documentation": {} + }, + { + "label": "TestGetSecret", + "kind": 6, + "importPath": "spectragraph-core.tests.vault.test_transform_vault_integration", + "description": "spectragraph-core.tests.vault.test_transform_vault_integration", + "peekOfCode": "class TestGetSecret:\n \"\"\"Tests for get_secret() method.\"\"\"\n @pytest.mark.asyncio\n async def test_get_secret_found(self, transform, mock_vault):\n \"\"\"Test get_secret when secret is in resolved params.\"\"\"\n secret_value = \"my-api-key-12345\"\n mock_vault.get_secret.return_value = secret_value\n # Run async_init to resolve params\n await transform.async_init()\n # Get the secret", + "detail": "spectragraph-core.tests.vault.test_transform_vault_integration", + "documentation": {} + }, + { + "label": "TestAsyncInit", + "kind": 6, + "importPath": "spectragraph-core.tests.vault.test_transform_vault_integration", + "description": "spectragraph-core.tests.vault.test_transform_vault_integration", + "peekOfCode": "class TestAsyncInit:\n \"\"\"Tests for async_init() method.\"\"\"\n @pytest.mark.asyncio\n async def test_async_init_calls_resolve_params(self, transform, mock_vault):\n \"\"\"Test that async_init calls resolve_params.\"\"\"\n secret_value = \"my-api-key-12345\"\n mock_vault.get_secret.return_value = secret_value\n # Run async_init\n await transform.async_init()\n # Params should be resolved and stored", + "detail": "spectragraph-core.tests.vault.test_transform_vault_integration", + "documentation": {} + }, + { + "label": "TestTransformExecuteWithVault", + "kind": 6, + "importPath": "spectragraph-core.tests.vault.test_transform_vault_integration", + "description": "spectragraph-core.tests.vault.test_transform_vault_integration", + "peekOfCode": "class TestTransformExecuteWithVault:\n \"\"\"Tests for execute() method with vault integration.\"\"\"\n @pytest.mark.asyncio\n async def test_execute_resolves_vault_secrets(self, transform, mock_vault):\n \"\"\"Test that execute resolves vault secrets before scan.\"\"\"\n secret_value = \"my-api-key-12345\"\n mock_vault.get_secret.return_value = secret_value\n # Execute the transform\n result = await transform.execute([\"test\"])\n # Vault secret should be resolved", + "detail": "spectragraph-core.tests.vault.test_transform_vault_integration", + "documentation": {} + }, + { + "label": "mock_vault", + "kind": 2, + "importPath": "spectragraph-core.tests.vault.test_transform_vault_integration", + "description": "spectragraph-core.tests.vault.test_transform_vault_integration", + "peekOfCode": "def mock_vault():\n \"\"\"Create a mock vault instance.\"\"\"\n vault = Mock()\n vault.get_secret = Mock()\n return vault\n@pytest.fixture\ndef sketch_id():\n \"\"\"Create a test sketch ID.\"\"\"\n return str(uuid.uuid4())\n@pytest.fixture", + "detail": "spectragraph-core.tests.vault.test_transform_vault_integration", + "documentation": {} + }, + { + "label": "sketch_id", + "kind": 2, + "importPath": "spectragraph-core.tests.vault.test_transform_vault_integration", + "description": "spectragraph-core.tests.vault.test_transform_vault_integration", + "peekOfCode": "def sketch_id():\n \"\"\"Create a test sketch ID.\"\"\"\n return str(uuid.uuid4())\n@pytest.fixture\ndef transform(mock_vault, sketch_id):\n \"\"\"Create a MockTransform instance with vault.\"\"\"\n return MockTransform(\n sketch_id=sketch_id,\n scan_id=\"scan_123\",\n vault=mock_vault,", + "detail": "spectragraph-core.tests.vault.test_transform_vault_integration", + "documentation": {} + }, + { + "label": "transform", + "kind": 2, + "importPath": "spectragraph-core.tests.vault.test_transform_vault_integration", + "description": "spectragraph-core.tests.vault.test_transform_vault_integration", + "peekOfCode": "def transform(mock_vault, sketch_id):\n \"\"\"Create a MockTransform instance with vault.\"\"\"\n return MockTransform(\n sketch_id=sketch_id,\n scan_id=\"scan_123\",\n vault=mock_vault,\n params={},\n )\nclass TestResolveParams:\n \"\"\"Tests for resolve_params() method.\"\"\"", + "detail": "spectragraph-core.tests.vault.test_transform_vault_integration", + "documentation": {} + }, + { + "label": "TestVaultInitialization", + "kind": 6, + "importPath": "spectragraph-core.tests.vault.test_vault", + "description": "spectragraph-core.tests.vault.test_vault", + "peekOfCode": "class TestVaultInitialization:\n \"\"\"Tests for Vault initialization.\"\"\"\n def test_vault_requires_owner_id(self, mock_db):\n \"\"\"Test that Vault requires an owner_id.\"\"\"\n with pytest.raises(ValueError, match=\"owner_id is required\"):\n Vault(db=mock_db, owner_id=None)\n def test_vault_initialization_success(self, mock_db, owner_id):\n \"\"\"Test successful Vault initialization.\"\"\"\n vault = Vault(db=mock_db, owner_id=owner_id)\n assert vault.db == mock_db", + "detail": "spectragraph-core.tests.vault.test_vault", + "documentation": {} + }, + { + "label": "TestVaultSetSecret", + "kind": 6, + "importPath": "spectragraph-core.tests.vault.test_vault", + "description": "spectragraph-core.tests.vault.test_vault", + "peekOfCode": "class TestVaultSetSecret:\n \"\"\"Tests for Vault.set_secret() method.\"\"\"\n def test_set_secret_creates_key(self, vault, mock_db):\n \"\"\"Test that set_secret creates a new Key in the database.\"\"\"\n vault_ref = \"TEST_API_KEY\"\n plain_key = \"my-secret-api-key-12345\"\n vault.set_secret(vault_ref, plain_key)\n # Verify that db.add, db.commit, and db.refresh were called\n assert mock_db.add.called\n assert mock_db.commit.called", + "detail": "spectragraph-core.tests.vault.test_vault", + "documentation": {} + }, + { + "label": "TestVaultGetSecret", + "kind": 6, + "importPath": "spectragraph-core.tests.vault.test_vault", + "description": "spectragraph-core.tests.vault.test_vault", + "peekOfCode": "class TestVaultGetSecret:\n \"\"\"Tests for Vault.get_secret() method.\"\"\"\n def test_get_secret_by_name_found(self, vault, mock_db, owner_id):\n \"\"\"Test getting a secret by name when it exists.\"\"\"\n vault_ref = \"TEST_API_KEY\"\n plain_key = \"my-secret-api-key-12345\"\n # Set a secret first to get encrypted data\n real_vault = Vault(db=MagicMock(), owner_id=owner_id)\n encrypted_data = real_vault._encrypt_key(plain_key)\n # Create a mock Key object", + "detail": "spectragraph-core.tests.vault.test_vault", + "documentation": {} + }, + { + "label": "TestVaultEncryptionDecryption", + "kind": 6, + "importPath": "spectragraph-core.tests.vault.test_vault", + "description": "spectragraph-core.tests.vault.test_vault", + "peekOfCode": "class TestVaultEncryptionDecryption:\n \"\"\"Tests for encryption and decryption methods.\"\"\"\n def test_encrypt_decrypt_roundtrip(self, vault):\n \"\"\"Test that encryption and decryption work correctly.\"\"\"\n plaintext = \"my-secret-api-key-12345\"\n # Encrypt\n encrypted_data = vault._encrypt_key(plaintext)\n assert \"ciphertext\" in encrypted_data\n assert \"iv\" in encrypted_data\n assert \"salt\" in encrypted_data", + "detail": "spectragraph-core.tests.vault.test_vault", + "documentation": {} + }, + { + "label": "mock_db", + "kind": 2, + "importPath": "spectragraph-core.tests.vault.test_vault", + "description": "spectragraph-core.tests.vault.test_vault", + "peekOfCode": "def mock_db():\n \"\"\"Create a mock database session.\"\"\"\n return Mock()\n@pytest.fixture\ndef owner_id():\n \"\"\"Create a test owner ID.\"\"\"\n return uuid.uuid4()\n@pytest.fixture\ndef vault(mock_db, owner_id):\n \"\"\"Create a Vault instance with mocked database.\"\"\"", + "detail": "spectragraph-core.tests.vault.test_vault", + "documentation": {} + }, + { + "label": "owner_id", + "kind": 2, + "importPath": "spectragraph-core.tests.vault.test_vault", + "description": "spectragraph-core.tests.vault.test_vault", + "peekOfCode": "def owner_id():\n \"\"\"Create a test owner ID.\"\"\"\n return uuid.uuid4()\n@pytest.fixture\ndef vault(mock_db, owner_id):\n \"\"\"Create a Vault instance with mocked database.\"\"\"\n return Vault(db=mock_db, owner_id=owner_id)\n@pytest.fixture(autouse=True)\ndef mock_master_key(monkeypatch):\n \"\"\"Mock the master key environment variable.\"\"\"", + "detail": "spectragraph-core.tests.vault.test_vault", + "documentation": {} + }, + { + "label": "vault", + "kind": 2, + "importPath": "spectragraph-core.tests.vault.test_vault", + "description": "spectragraph-core.tests.vault.test_vault", + "peekOfCode": "def vault(mock_db, owner_id):\n \"\"\"Create a Vault instance with mocked database.\"\"\"\n return Vault(db=mock_db, owner_id=owner_id)\n@pytest.fixture(autouse=True)\ndef mock_master_key(monkeypatch):\n \"\"\"Mock the master key environment variable.\"\"\"\n # Use a base64-encoded 32-byte key\n test_key = \"base64:qnHTmwYb+uoygIw9MsRMY22vS5YPchY+QOi/E79GAvM=\"\n monkeypatch.setenv(\"MASTER_VAULT_KEY_V1\", test_key)\nclass TestVaultInitialization:", + "detail": "spectragraph-core.tests.vault.test_vault", + "documentation": {} + }, + { + "label": "mock_master_key", + "kind": 2, + "importPath": "spectragraph-core.tests.vault.test_vault", + "description": "spectragraph-core.tests.vault.test_vault", + "peekOfCode": "def mock_master_key(monkeypatch):\n \"\"\"Mock the master key environment variable.\"\"\"\n # Use a base64-encoded 32-byte key\n test_key = \"base64:qnHTmwYb+uoygIw9MsRMY22vS5YPchY+QOi/E79GAvM=\"\n monkeypatch.setenv(\"MASTER_VAULT_KEY_V1\", test_key)\nclass TestVaultInitialization:\n \"\"\"Tests for Vault initialization.\"\"\"\n def test_vault_requires_owner_id(self, mock_db):\n \"\"\"Test that Vault requires an owner_id.\"\"\"\n with pytest.raises(ValueError, match=\"owner_id is required\"):", + "detail": "spectragraph-core.tests.vault.test_vault", + "documentation": {} + }, + { + "label": "setup_test_environment", + "kind": 2, + "importPath": "spectragraph-core.tests.conftest", + "description": "spectragraph-core.tests.conftest", + "peekOfCode": "def setup_test_environment(monkeypatch):\n \"\"\"Set up test environment variables.\"\"\"\n # Set a test master key for vault tests\n test_key = \"base64:qnHTmwYb+uoygIw9MsRMY22vS5YPchY+QOi/E79GAvM=\"\n monkeypatch.setenv(\"MASTER_VAULT_KEY_V1\", test_key)\n@pytest.fixture(autouse=True)\ndef mock_logger(monkeypatch):\n \"\"\"Mock the Logger to avoid database calls during tests.\"\"\"\n from unittest.mock import MagicMock\n mock = MagicMock()", + "detail": "spectragraph-core.tests.conftest", + "documentation": {} + }, + { + "label": "mock_logger", + "kind": 2, + "importPath": "spectragraph-core.tests.conftest", + "description": "spectragraph-core.tests.conftest", + "peekOfCode": "def mock_logger(monkeypatch):\n \"\"\"Mock the Logger to avoid database calls during tests.\"\"\"\n from unittest.mock import MagicMock\n mock = MagicMock()\n monkeypatch.setattr(\"spectragraph_core.core.logger.Logger\", mock)\n return mock", + "detail": "spectragraph-core.tests.conftest", + "documentation": {} + }, + { + "label": "mock_engine", + "kind": 2, + "importPath": "spectragraph-core.tests.test_postgre_db", + "description": "spectragraph-core.tests.test_postgre_db", + "peekOfCode": "def mock_engine(monkeypatch):\n mock = MagicMock()\n monkeypatch.setattr(\"spectragraph_core.core.postgre_db.engine\", mock)\n return mock\n@pytest.fixture\ndef mock_logger(monkeypatch):\n mock = MagicMock()\n monkeypatch.setattr(\"spectragraph_core.core.postgre_db.logger\", mock)\n return mock\ndef test_ensure_db_connection_success(mock_engine, mock_logger):", + "detail": "spectragraph-core.tests.test_postgre_db", + "documentation": {} + }, + { + "label": "mock_logger", + "kind": 2, + "importPath": "spectragraph-core.tests.test_postgre_db", + "description": "spectragraph-core.tests.test_postgre_db", + "peekOfCode": "def mock_logger(monkeypatch):\n mock = MagicMock()\n monkeypatch.setattr(\"spectragraph_core.core.postgre_db.logger\", mock)\n return mock\ndef test_ensure_db_connection_success(mock_engine, mock_logger):\n \"\"\"Test successful connection.\"\"\"\n ensure_db_connection(max_retries=1)\n mock_engine.connect.assert_called_once()\n mock_logger.info.assert_called()\ndef test_ensure_db_connection_retry(mock_engine, mock_logger):", + "detail": "spectragraph-core.tests.test_postgre_db", + "documentation": {} + }, + { + "label": "test_ensure_db_connection_success", + "kind": 2, + "importPath": "spectragraph-core.tests.test_postgre_db", + "description": "spectragraph-core.tests.test_postgre_db", + "peekOfCode": "def test_ensure_db_connection_success(mock_engine, mock_logger):\n \"\"\"Test successful connection.\"\"\"\n ensure_db_connection(max_retries=1)\n mock_engine.connect.assert_called_once()\n mock_logger.info.assert_called()\ndef test_ensure_db_connection_retry(mock_engine, mock_logger):\n \"\"\"Test retry logic: fail once, then succeed.\"\"\"\n # Simulate one failure then success\n mock_engine.connect.side_effect = [OperationalError(\"Select 1\", None, Exception(\"Fail\")), MagicMock()]\n # Needs at least 2 retries to succeed on second attempt", + "detail": "spectragraph-core.tests.test_postgre_db", + "documentation": {} + }, + { + "label": "test_ensure_db_connection_retry", + "kind": 2, + "importPath": "spectragraph-core.tests.test_postgre_db", + "description": "spectragraph-core.tests.test_postgre_db", + "peekOfCode": "def test_ensure_db_connection_retry(mock_engine, mock_logger):\n \"\"\"Test retry logic: fail once, then succeed.\"\"\"\n # Simulate one failure then success\n mock_engine.connect.side_effect = [OperationalError(\"Select 1\", None, Exception(\"Fail\")), MagicMock()]\n # Needs at least 2 retries to succeed on second attempt\n ensure_db_connection(max_retries=3, base_delay=0.01)\n assert mock_engine.connect.call_count == 2\n mock_logger.warning.assert_called() # Should indicate retry\n mock_logger.info.assert_called() # Finally succeed\ndef test_ensure_db_connection_fail_retries(mock_engine, mock_logger):", + "detail": "spectragraph-core.tests.test_postgre_db", + "documentation": {} + }, + { + "label": "test_ensure_db_connection_fail_retries", + "kind": 2, + "importPath": "spectragraph-core.tests.test_postgre_db", + "description": "spectragraph-core.tests.test_postgre_db", + "peekOfCode": "def test_ensure_db_connection_fail_retries(mock_engine, mock_logger):\n \"\"\"Test failure after max retries.\"\"\"\n mock_engine.connect.side_effect = OperationalError(\"Select 1\", None, Exception(\"Fail\"))\n with pytest.raises(DatabaseUnavailableError):\n ensure_db_connection(max_retries=2, base_delay=0.01)\n assert mock_engine.connect.call_count == 2\n mock_logger.error.assert_called()\ndef test_diagnostics_generic_failure(mock_engine, mock_logger):\n \"\"\"Test actionable advice is logged on failure.\"\"\"\n error = OperationalError(\"select 1\", None, Exception(\"connection refused\"))", + "detail": "spectragraph-core.tests.test_postgre_db", + "documentation": {} + }, + { + "label": "test_diagnostics_generic_failure", + "kind": 2, + "importPath": "spectragraph-core.tests.test_postgre_db", + "description": "spectragraph-core.tests.test_postgre_db", + "peekOfCode": "def test_diagnostics_generic_failure(mock_engine, mock_logger):\n \"\"\"Test actionable advice is logged on failure.\"\"\"\n error = OperationalError(\"select 1\", None, Exception(\"connection refused\"))\n mock_engine.connect.side_effect = error\n with pytest.raises(DatabaseUnavailableError):\n ensure_db_connection(max_retries=1, base_delay=0.01)\n # Check if we logged the helpful message\n found = False\n for call_args in mock_logger.error.call_args_list:\n args, _ = call_args", + "detail": "spectragraph-core.tests.test_postgre_db", + "documentation": {} + }, + { + "label": "AsnToCidrsTransform", + "kind": 6, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.asn.to_cidrs", + "description": "spectragraph-transforms.src.spectragraph_transforms.asn.to_cidrs", + "peekOfCode": "class AsnToCidrsTransform(Transform):\n \"\"\"[ASNMAP] Takes an ASN and returns its corresponding CIDRs.\"\"\"\n # Define types as class attributes - base class handles schema generation automatically\n InputType = List[ASN]\n OutputType = List[CIDR]\n def __init__(\n self,\n sketch_id: Optional[str] = None,\n scan_id: Optional[str] = None,\n neo4j_conn: Optional[Neo4jConnection] = None,", + "detail": "spectragraph-transforms.src.spectragraph_transforms.asn.to_cidrs", + "documentation": {} + }, + { + "label": "InputType", + "kind": 5, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.asn.to_cidrs", + "description": "spectragraph-transforms.src.spectragraph_transforms.asn.to_cidrs", + "peekOfCode": "InputType = AsnToCidrsTransform.InputType\nOutputType = AsnToCidrsTransform.OutputType", + "detail": "spectragraph-transforms.src.spectragraph_transforms.asn.to_cidrs", + "documentation": {} + }, + { + "label": "OutputType", + "kind": 5, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.asn.to_cidrs", + "description": "spectragraph-transforms.src.spectragraph_transforms.asn.to_cidrs", + "peekOfCode": "OutputType = AsnToCidrsTransform.OutputType", + "detail": "spectragraph-transforms.src.spectragraph_transforms.asn.to_cidrs", + "documentation": {} + }, + { + "label": "CidrToIpsTransform", + "kind": 6, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.cidr.to_ips", + "description": "spectragraph-transforms.src.spectragraph_transforms.cidr.to_ips", + "peekOfCode": "class CidrToIpsTransform(Transform):\n \"\"\"[MAPCIDR] Takes a CIDR and returns its corresponding IP addresses.\"\"\"\n # Define types as class attributes - base class handles schema generation automatically\n InputType = List[CIDR]\n OutputType = List[Ip]\n def __init__(\n self,\n sketch_id: Optional[str] = None,\n scan_id: Optional[str] = None,\n neo4j_conn: Optional[Neo4jConnection] = None,", + "detail": "spectragraph-transforms.src.spectragraph_transforms.cidr.to_ips", + "documentation": {} + }, + { + "label": "InputType", + "kind": 5, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.cidr.to_ips", + "description": "spectragraph-transforms.src.spectragraph_transforms.cidr.to_ips", + "peekOfCode": "InputType = CidrToIpsTransform.InputType\nOutputType = CidrToIpsTransform.OutputType", + "detail": "spectragraph-transforms.src.spectragraph_transforms.cidr.to_ips", + "documentation": {} + }, + { + "label": "OutputType", + "kind": 5, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.cidr.to_ips", + "description": "spectragraph-transforms.src.spectragraph_transforms.cidr.to_ips", + "peekOfCode": "OutputType = CidrToIpsTransform.OutputType", + "detail": "spectragraph-transforms.src.spectragraph_transforms.cidr.to_ips", + "documentation": {} + }, + { + "label": "CryptoWalletAddressToNFTs", + "kind": 6, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.crypto.to_nfts", + "description": "spectragraph-transforms.src.spectragraph_transforms.crypto.to_nfts", + "peekOfCode": "class CryptoWalletAddressToNFTs(Transform):\n \"\"\"[ETHERSCAN] Resolve NFTs for a wallet address (ETH).\"\"\"\n # Define types as class attributes - base class handles schema generation automatically\n InputType = List[CryptoWallet]\n OutputType = List[CryptoNFT]\n def __init__(\n self,\n sketch_id: Optional[str] = None,\n scan_id: Optional[str] = None,\n neo4j_conn: Optional[Neo4jConnection] = None,", + "detail": "spectragraph-transforms.src.spectragraph_transforms.crypto.to_nfts", + "documentation": {} + }, + { + "label": "InputType", + "kind": 5, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.crypto.to_nfts", + "description": "spectragraph-transforms.src.spectragraph_transforms.crypto.to_nfts", + "peekOfCode": "InputType = CryptoWalletAddressToNFTs.InputType\nOutputType = CryptoWalletAddressToNFTs.OutputType", + "detail": "spectragraph-transforms.src.spectragraph_transforms.crypto.to_nfts", + "documentation": {} + }, + { + "label": "OutputType", + "kind": 5, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.crypto.to_nfts", + "description": "spectragraph-transforms.src.spectragraph_transforms.crypto.to_nfts", + "peekOfCode": "OutputType = CryptoWalletAddressToNFTs.OutputType", + "detail": "spectragraph-transforms.src.spectragraph_transforms.crypto.to_nfts", + "documentation": {} + }, + { + "label": "CryptoWalletAddressToTransactions", + "kind": 6, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.crypto.to_transactions", + "description": "spectragraph-transforms.src.spectragraph_transforms.crypto.to_transactions", + "peekOfCode": "class CryptoWalletAddressToTransactions(Transform):\n \"\"\"[ETHERSCAN] Resolve transactions for a wallet address (ETH).\"\"\"\n # Define types as class attributes - base class handles schema generation automatically\n InputType = List[CryptoWallet]\n OutputType = List[CryptoWalletTransaction]\n def __init__(\n self,\n sketch_id: Optional[str] = None,\n scan_id: Optional[str] = None,\n neo4j_conn: Optional[Neo4jConnection] = None,", + "detail": "spectragraph-transforms.src.spectragraph_transforms.crypto.to_transactions", + "documentation": {} + }, + { + "label": "wei_to_eth", + "kind": 2, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.crypto.to_transactions", + "description": "spectragraph-transforms.src.spectragraph_transforms.crypto.to_transactions", + "peekOfCode": "def wei_to_eth(wei_str):\n return int(wei_str) / 10**18\nclass CryptoWalletAddressToTransactions(Transform):\n \"\"\"[ETHERSCAN] Resolve transactions for a wallet address (ETH).\"\"\"\n # Define types as class attributes - base class handles schema generation automatically\n InputType = List[CryptoWallet]\n OutputType = List[CryptoWalletTransaction]\n def __init__(\n self,\n sketch_id: Optional[str] = None,", + "detail": "spectragraph-transforms.src.spectragraph_transforms.crypto.to_transactions", + "documentation": {} + }, + { + "label": "InputType", + "kind": 5, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.crypto.to_transactions", + "description": "spectragraph-transforms.src.spectragraph_transforms.crypto.to_transactions", + "peekOfCode": "InputType = CryptoWalletAddressToTransactions.InputType\nOutputType = CryptoWalletAddressToTransactions.OutputType", + "detail": "spectragraph-transforms.src.spectragraph_transforms.crypto.to_transactions", + "documentation": {} + }, + { + "label": "OutputType", + "kind": 5, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.crypto.to_transactions", + "description": "spectragraph-transforms.src.spectragraph_transforms.crypto.to_transactions", + "peekOfCode": "OutputType = CryptoWalletAddressToTransactions.OutputType", + "detail": "spectragraph-transforms.src.spectragraph_transforms.crypto.to_transactions", + "documentation": {} + }, + { + "label": "DomainToAsnTransform", + "kind": 6, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.domain.to_asn", + "description": "spectragraph-transforms.src.spectragraph_transforms.domain.to_asn", + "peekOfCode": "class DomainToAsnTransform(Transform):\n \"\"\"[ASNMAP] Takes a domain and returns its corresponding ASN.\"\"\"\n # Define types as class attributes - base class handles schema generation automatically\n InputType = List[Domain]\n OutputType = List[ASN]\n def __init__(\n self,\n sketch_id: Optional[str] = None,\n scan_id: Optional[str] = None,\n neo4j_conn: Optional[Neo4jConnection] = None,", + "detail": "spectragraph-transforms.src.spectragraph_transforms.domain.to_asn", + "documentation": {} + }, + { + "label": "InputType", + "kind": 5, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.domain.to_asn", + "description": "spectragraph-transforms.src.spectragraph_transforms.domain.to_asn", + "peekOfCode": "InputType = DomainToAsnTransform.InputType\nOutputType = DomainToAsnTransform.OutputType", + "detail": "spectragraph-transforms.src.spectragraph_transforms.domain.to_asn", + "documentation": {} + }, + { + "label": "OutputType", + "kind": 5, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.domain.to_asn", + "description": "spectragraph-transforms.src.spectragraph_transforms.domain.to_asn", + "peekOfCode": "OutputType = DomainToAsnTransform.OutputType", + "detail": "spectragraph-transforms.src.spectragraph_transforms.domain.to_asn", + "documentation": {} + }, + { + "label": "DomainToHistoryTransform", + "kind": 6, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.domain.to_history", + "description": "spectragraph-transforms.src.spectragraph_transforms.domain.to_history", + "peekOfCode": "class DomainToHistoryTransform(Transform):\n \"\"\"[WHOXY] Takes a domain and returns history infos about it (history, organization, owners, emails, etc.).\"\"\"\n # Define types as class attributes - base class handles schema generation automatically\n InputType = List[Domain]\n OutputType = List[Domain]\n def __init__(\n self,\n sketch_id: Optional[str] = None,\n scan_id: Optional[str] = None,\n neo4j_conn: Optional[Neo4jConnection] = None,", + "detail": "spectragraph-transforms.src.spectragraph_transforms.domain.to_history", + "documentation": {} + }, + { + "label": "InputType", + "kind": 5, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.domain.to_history", + "description": "spectragraph-transforms.src.spectragraph_transforms.domain.to_history", + "peekOfCode": "InputType = DomainToHistoryTransform.InputType\nOutputType = DomainToHistoryTransform.OutputType", + "detail": "spectragraph-transforms.src.spectragraph_transforms.domain.to_history", + "documentation": {} + }, + { + "label": "OutputType", + "kind": 5, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.domain.to_history", + "description": "spectragraph-transforms.src.spectragraph_transforms.domain.to_history", + "peekOfCode": "OutputType = DomainToHistoryTransform.OutputType", + "detail": "spectragraph-transforms.src.spectragraph_transforms.domain.to_history", + "documentation": {} + }, + { + "label": "ResolveTransform", + "kind": 6, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.domain.to_ip", + "description": "spectragraph-transforms.src.spectragraph_transforms.domain.to_ip", + "peekOfCode": "class ResolveTransform(Transform):\n \"\"\"Resolve domain names to IP addresses.\"\"\"\n # Define the input and output types as class attributes\n InputType = List[Domain]\n OutputType = List[Ip]\n @classmethod\n def name(cls) -> str:\n return \"domain_to_ip\"\n @classmethod\n def category(cls) -> str:", + "detail": "spectragraph-transforms.src.spectragraph_transforms.domain.to_ip", + "documentation": {} + }, + { + "label": "InputType", + "kind": 5, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.domain.to_ip", + "description": "spectragraph-transforms.src.spectragraph_transforms.domain.to_ip", + "peekOfCode": "InputType = ResolveTransform.InputType\nOutputType = ResolveTransform.OutputType", + "detail": "spectragraph-transforms.src.spectragraph_transforms.domain.to_ip", + "documentation": {} + }, + { + "label": "OutputType", + "kind": 5, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.domain.to_ip", + "description": "spectragraph-transforms.src.spectragraph_transforms.domain.to_ip", + "peekOfCode": "OutputType = ResolveTransform.OutputType", + "detail": "spectragraph-transforms.src.spectragraph_transforms.domain.to_ip", + "documentation": {} + }, + { + "label": "DomainToRootDomain", + "kind": 6, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.domain.to_root_domain", + "description": "spectragraph-transforms.src.spectragraph_transforms.domain.to_root_domain", + "peekOfCode": "class DomainToRootDomain(Transform):\n \"\"\"Subdomain to root domain.\"\"\"\n InputType = List[Domain]\n OutputType = List[Domain]\n def __init__(self, *args, **kwargs):\n super().__init__(*args, **kwargs)\n # Store mapping between original domains and their root domains\n self.domain_root_mapping: List[tuple[Domain, Domain]] = []\n @classmethod\n def name(cls) -> str:", + "detail": "spectragraph-transforms.src.spectragraph_transforms.domain.to_root_domain", + "documentation": {} + }, + { + "label": "InputType", + "kind": 5, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.domain.to_root_domain", + "description": "spectragraph-transforms.src.spectragraph_transforms.domain.to_root_domain", + "peekOfCode": "InputType = DomainToRootDomain.InputType\nOutputType = DomainToRootDomain.OutputType", + "detail": "spectragraph-transforms.src.spectragraph_transforms.domain.to_root_domain", + "documentation": {} + }, + { + "label": "OutputType", + "kind": 5, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.domain.to_root_domain", + "description": "spectragraph-transforms.src.spectragraph_transforms.domain.to_root_domain", + "peekOfCode": "OutputType = DomainToRootDomain.OutputType", + "detail": "spectragraph-transforms.src.spectragraph_transforms.domain.to_root_domain", + "documentation": {} + }, + { + "label": "SubdomainTransform", + "kind": 6, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.domain.to_subdomains", + "description": "spectragraph-transforms.src.spectragraph_transforms.domain.to_subdomains", + "peekOfCode": "class SubdomainTransform(Transform):\n \"\"\"Transform to find subdomains associated with a domain.\"\"\"\n # Define types as class attributes - base class handles schema generation automatically\n InputType = List[Domain | str]\n OutputType = List[Domain]\n @classmethod\n def name(cls) -> str:\n return \"domain_to_subdomains\"\n @classmethod\n def category(cls) -> str:", + "detail": "spectragraph-transforms.src.spectragraph_transforms.domain.to_subdomains", + "documentation": {} + }, + { + "label": "InputType", + "kind": 5, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.domain.to_subdomains", + "description": "spectragraph-transforms.src.spectragraph_transforms.domain.to_subdomains", + "peekOfCode": "InputType = SubdomainTransform.InputType\nOutputType = SubdomainTransform.OutputType", + "detail": "spectragraph-transforms.src.spectragraph_transforms.domain.to_subdomains", + "documentation": {} + }, + { + "label": "OutputType", + "kind": 5, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.domain.to_subdomains", + "description": "spectragraph-transforms.src.spectragraph_transforms.domain.to_subdomains", + "peekOfCode": "OutputType = SubdomainTransform.OutputType", + "detail": "spectragraph-transforms.src.spectragraph_transforms.domain.to_subdomains", + "documentation": {} + }, + { + "label": "DomainToWebsiteTransform", + "kind": 6, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.domain.to_website", + "description": "spectragraph-transforms.src.spectragraph_transforms.domain.to_website", + "peekOfCode": "class DomainToWebsiteTransform(Transform):\n \"\"\"From domain to website.\"\"\"\n # Define types as class attributes - base class handles schema generation automatically\n InputType = List[Domain]\n OutputType = List[Website]\n @classmethod\n def name(cls) -> str:\n return \"domain_to_website\"\n @classmethod\n def category(cls) -> str:", + "detail": "spectragraph-transforms.src.spectragraph_transforms.domain.to_website", + "documentation": {} + }, + { + "label": "InputType", + "kind": 5, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.domain.to_website", + "description": "spectragraph-transforms.src.spectragraph_transforms.domain.to_website", + "peekOfCode": "InputType = DomainToWebsiteTransform.InputType\nOutputType = DomainToWebsiteTransform.OutputType", + "detail": "spectragraph-transforms.src.spectragraph_transforms.domain.to_website", + "documentation": {} + }, + { + "label": "OutputType", + "kind": 5, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.domain.to_website", + "description": "spectragraph-transforms.src.spectragraph_transforms.domain.to_website", + "peekOfCode": "OutputType = DomainToWebsiteTransform.OutputType", + "detail": "spectragraph-transforms.src.spectragraph_transforms.domain.to_website", + "documentation": {} + }, + { + "label": "WhoisTransform", + "kind": 6, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.domain.to_whois", + "description": "spectragraph-transforms.src.spectragraph_transforms.domain.to_whois", + "peekOfCode": "class WhoisTransform(Transform):\n \"\"\"Scan for WHOIS information of a domain.\"\"\"\n # Define types as class attributes - base class handles schema generation automatically\n InputType = List[Domain]\n OutputType = List[Whois]\n @classmethod\n def name(cls) -> str:\n return \"domain_to_whois\"\n @classmethod\n def category(cls) -> str:", + "detail": "spectragraph-transforms.src.spectragraph_transforms.domain.to_whois", + "documentation": {} + }, + { + "label": "InputType", + "kind": 5, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.domain.to_whois", + "description": "spectragraph-transforms.src.spectragraph_transforms.domain.to_whois", + "peekOfCode": "InputType = WhoisTransform.InputType\nOutputType = WhoisTransform.OutputType", + "detail": "spectragraph-transforms.src.spectragraph_transforms.domain.to_whois", + "documentation": {} + }, + { + "label": "OutputType", + "kind": 5, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.domain.to_whois", + "description": "spectragraph-transforms.src.spectragraph_transforms.domain.to_whois", + "peekOfCode": "OutputType = WhoisTransform.OutputType", + "detail": "spectragraph-transforms.src.spectragraph_transforms.domain.to_whois", + "documentation": {} + }, + { + "label": "EmailToDomainsTransform", + "kind": 6, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.email.to_domains", + "description": "spectragraph-transforms.src.spectragraph_transforms.email.to_domains", + "peekOfCode": "class EmailToDomainsTransform(Transform):\n \"\"\"[WHOXY] Takes an email and returns the domains it registered.\"\"\"\n # Define types as class attributes - base class handles schema generation automatically\n InputType = List[Email]\n OutputType = List[Domain]\n def __init__(\n self,\n sketch_id: Optional[str] = None,\n scan_id: Optional[str] = None,\n neo4j_conn: Optional[Neo4jConnection] = None,", + "detail": "spectragraph-transforms.src.spectragraph_transforms.email.to_domains", + "documentation": {} + }, + { + "label": "WHOXY_API_KEY", + "kind": 5, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.email.to_domains", + "description": "spectragraph-transforms.src.spectragraph_transforms.email.to_domains", + "peekOfCode": "WHOXY_API_KEY = os.getenv(\"WHOXY_API_KEY\")\nclass EmailToDomainsTransform(Transform):\n \"\"\"[WHOXY] Takes an email and returns the domains it registered.\"\"\"\n # Define types as class attributes - base class handles schema generation automatically\n InputType = List[Email]\n OutputType = List[Domain]\n def __init__(\n self,\n sketch_id: Optional[str] = None,\n scan_id: Optional[str] = None,", + "detail": "spectragraph-transforms.src.spectragraph_transforms.email.to_domains", + "documentation": {} + }, + { + "label": "InputType", + "kind": 5, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.email.to_domains", + "description": "spectragraph-transforms.src.spectragraph_transforms.email.to_domains", + "peekOfCode": "InputType = EmailToDomainsTransform.InputType\nOutputType = EmailToDomainsTransform.OutputType", + "detail": "spectragraph-transforms.src.spectragraph_transforms.email.to_domains", + "documentation": {} + }, + { + "label": "OutputType", + "kind": 5, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.email.to_domains", + "description": "spectragraph-transforms.src.spectragraph_transforms.email.to_domains", + "peekOfCode": "OutputType = EmailToDomainsTransform.OutputType", + "detail": "spectragraph-transforms.src.spectragraph_transforms.email.to_domains", + "documentation": {} + }, + { + "label": "EmailToGravatarTransform", + "kind": 6, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.email.to_gravatar", + "description": "spectragraph-transforms.src.spectragraph_transforms.email.to_gravatar", + "peekOfCode": "class EmailToGravatarTransform(Transform):\n \"\"\"From md5 hash of email to gravatar.\"\"\"\n InputType = List[Email]\n OutputType = List[Gravatar]\n @classmethod\n def name(cls) -> str:\n return \"email_to_gravatar\"\n @classmethod\n def category(cls) -> str:\n return \"Email\"", + "detail": "spectragraph-transforms.src.spectragraph_transforms.email.to_gravatar", + "documentation": {} + }, + { + "label": "InputType", + "kind": 5, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.email.to_gravatar", + "description": "spectragraph-transforms.src.spectragraph_transforms.email.to_gravatar", + "peekOfCode": "InputType = EmailToGravatarTransform.InputType\nOutputType = EmailToGravatarTransform.OutputType", + "detail": "spectragraph-transforms.src.spectragraph_transforms.email.to_gravatar", + "documentation": {} + }, + { + "label": "OutputType", + "kind": 5, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.email.to_gravatar", + "description": "spectragraph-transforms.src.spectragraph_transforms.email.to_gravatar", + "peekOfCode": "OutputType = EmailToGravatarTransform.OutputType", + "detail": "spectragraph-transforms.src.spectragraph_transforms.email.to_gravatar", + "documentation": {} + }, + { + "label": "EmailToBreachesTransform", + "kind": 6, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.email.to_leaks", + "description": "spectragraph-transforms.src.spectragraph_transforms.email.to_leaks", + "peekOfCode": "class EmailToBreachesTransform(Transform):\n \"\"\"[HIBPWNED] Get the breaches the email might be invovled in.\"\"\"\n InputType = List[Email]\n OutputType = List[tuple] # List of (email, breach) tuples\n def __init__(\n self,\n sketch_id: Optional[str] = None,\n scan_id: Optional[str] = None,\n neo4j_conn: Optional[Neo4jConnection] = None,\n vault=None,", + "detail": "spectragraph-transforms.src.spectragraph_transforms.email.to_leaks", + "documentation": {} + }, + { + "label": "HIBP_API_KEY", + "kind": 5, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.email.to_leaks", + "description": "spectragraph-transforms.src.spectragraph_transforms.email.to_leaks", + "peekOfCode": "HIBP_API_KEY = os.getenv(\"HIBP_API_KEY\")\nclass EmailToBreachesTransform(Transform):\n \"\"\"[HIBPWNED] Get the breaches the email might be invovled in.\"\"\"\n InputType = List[Email]\n OutputType = List[tuple] # List of (email, breach) tuples\n def __init__(\n self,\n sketch_id: Optional[str] = None,\n scan_id: Optional[str] = None,\n neo4j_conn: Optional[Neo4jConnection] = None,", + "detail": "spectragraph-transforms.src.spectragraph_transforms.email.to_leaks", + "documentation": {} + }, + { + "label": "InputType", + "kind": 5, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.email.to_leaks", + "description": "spectragraph-transforms.src.spectragraph_transforms.email.to_leaks", + "peekOfCode": "InputType = EmailToBreachesTransform.InputType\nOutputType = EmailToBreachesTransform.OutputType", + "detail": "spectragraph-transforms.src.spectragraph_transforms.email.to_leaks", + "documentation": {} + }, + { + "label": "OutputType", + "kind": 5, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.email.to_leaks", + "description": "spectragraph-transforms.src.spectragraph_transforms.email.to_leaks", + "peekOfCode": "OutputType = EmailToBreachesTransform.OutputType", + "detail": "spectragraph-transforms.src.spectragraph_transforms.email.to_leaks", + "documentation": {} + }, + { + "label": "IndividualToDomainsTransform", + "kind": 6, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.individual.to_domains", + "description": "spectragraph-transforms.src.spectragraph_transforms.individual.to_domains", + "peekOfCode": "class IndividualToDomainsTransform(Transform):\n \"\"\"[WHOXY] Takes an individual and returns the domains it registered.\"\"\"\n # Define types as class attributes - base class handles schema generation automatically\n InputType = List[Individual]\n OutputType = List[Domain]\n def __init__(\n self,\n sketch_id: Optional[str] = None,\n scan_id: Optional[str] = None,\n neo4j_conn: Optional[Neo4jConnection] = None,", + "detail": "spectragraph-transforms.src.spectragraph_transforms.individual.to_domains", + "documentation": {} + }, + { + "label": "WHOXY_API_KEY", + "kind": 5, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.individual.to_domains", + "description": "spectragraph-transforms.src.spectragraph_transforms.individual.to_domains", + "peekOfCode": "WHOXY_API_KEY = os.getenv(\"WHOXY_API_KEY\")\nclass IndividualToDomainsTransform(Transform):\n \"\"\"[WHOXY] Takes an individual and returns the domains it registered.\"\"\"\n # Define types as class attributes - base class handles schema generation automatically\n InputType = List[Individual]\n OutputType = List[Domain]\n def __init__(\n self,\n sketch_id: Optional[str] = None,\n scan_id: Optional[str] = None,", + "detail": "spectragraph-transforms.src.spectragraph_transforms.individual.to_domains", + "documentation": {} + }, + { + "label": "InputType", + "kind": 5, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.individual.to_domains", + "description": "spectragraph-transforms.src.spectragraph_transforms.individual.to_domains", + "peekOfCode": "InputType = IndividualToDomainsTransform.InputType\nOutputType = IndividualToDomainsTransform.OutputType", + "detail": "spectragraph-transforms.src.spectragraph_transforms.individual.to_domains", + "documentation": {} + }, + { + "label": "OutputType", + "kind": 5, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.individual.to_domains", + "description": "spectragraph-transforms.src.spectragraph_transforms.individual.to_domains", + "peekOfCode": "OutputType = IndividualToDomainsTransform.OutputType", + "detail": "spectragraph-transforms.src.spectragraph_transforms.individual.to_domains", + "documentation": {} + }, + { + "label": "IndividualToOrgTransform", + "kind": 6, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.individual.to_org", + "description": "spectragraph-transforms.src.spectragraph_transforms.individual.to_org", + "peekOfCode": "class IndividualToOrgTransform(Transform):\n \"\"\"[SIRENE] Find organization from a person with data from SIRENE (France only).\"\"\"\n # Define types as class attributes - base class handles schema generation automatically\n InputType = List[Individual]\n OutputType = List[Organization]\n @classmethod\n def name(cls) -> str:\n return \"individual_to_organization\"\n @classmethod\n def category(cls) -> str:", + "detail": "spectragraph-transforms.src.spectragraph_transforms.individual.to_org", + "documentation": {} + }, + { + "label": "InputType", + "kind": 5, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.individual.to_org", + "description": "spectragraph-transforms.src.spectragraph_transforms.individual.to_org", + "peekOfCode": "InputType = IndividualToOrgTransform.InputType\nOutputType = IndividualToOrgTransform.OutputType", + "detail": "spectragraph-transforms.src.spectragraph_transforms.individual.to_org", + "documentation": {} + }, + { + "label": "OutputType", + "kind": 5, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.individual.to_org", + "description": "spectragraph-transforms.src.spectragraph_transforms.individual.to_org", + "peekOfCode": "OutputType = IndividualToOrgTransform.OutputType", + "detail": "spectragraph-transforms.src.spectragraph_transforms.individual.to_org", + "documentation": {} + }, + { + "label": "IpToAsnTransform", + "kind": 6, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.ip.to_asn", + "description": "spectragraph-transforms.src.spectragraph_transforms.ip.to_asn", + "peekOfCode": "class IpToAsnTransform(Transform):\n \"\"\"[ASNMAP] Takes an IP address and returns its corresponding ASN.\"\"\"\n # Define types as class attributes - base class handles schema generation automatically\n InputType = List[Ip]\n OutputType = List[ASN]\n def __init__(\n self,\n sketch_id: Optional[str] = None,\n scan_id: Optional[str] = None,\n neo4j_conn: Optional[Neo4jConnection] = None,", + "detail": "spectragraph-transforms.src.spectragraph_transforms.ip.to_asn", + "documentation": {} + }, + { + "label": "InputType", + "kind": 5, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.ip.to_asn", + "description": "spectragraph-transforms.src.spectragraph_transforms.ip.to_asn", + "peekOfCode": "InputType = IpToAsnTransform.InputType\nOutputType = IpToAsnTransform.OutputType", + "detail": "spectragraph-transforms.src.spectragraph_transforms.ip.to_asn", + "documentation": {} + }, + { + "label": "OutputType", + "kind": 5, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.ip.to_asn", + "description": "spectragraph-transforms.src.spectragraph_transforms.ip.to_asn", + "peekOfCode": "OutputType = IpToAsnTransform.OutputType", + "detail": "spectragraph-transforms.src.spectragraph_transforms.ip.to_asn", + "documentation": {} + }, + { + "label": "ReverseResolveTransform", + "kind": 6, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.ip.to_domain", + "description": "spectragraph-transforms.src.spectragraph_transforms.ip.to_domain", + "peekOfCode": "class ReverseResolveTransform(Transform):\n \"\"\"Resolve IP addresses to domain names using PTR, Certificate Transparency and optional API calls.\"\"\"\n # Define types as class attributes - base class handles schema generation automatically\n InputType = List[Ip]\n OutputType = List[Domain]\n @classmethod\n def name(cls) -> str:\n return \"ip_to_domain\"\n @classmethod\n def category(cls) -> str:", + "detail": "spectragraph-transforms.src.spectragraph_transforms.ip.to_domain", + "documentation": {} + }, + { + "label": "PTR_BLACKLIST", + "kind": 5, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.ip.to_domain", + "description": "spectragraph-transforms.src.spectragraph_transforms.ip.to_domain", + "peekOfCode": "PTR_BLACKLIST = re.compile(r\"^ip\\d+\\.ip-\\d+-\\d+-\\d+-\\d+\\.\")\nclass ReverseResolveTransform(Transform):\n \"\"\"Resolve IP addresses to domain names using PTR, Certificate Transparency and optional API calls.\"\"\"\n # Define types as class attributes - base class handles schema generation automatically\n InputType = List[Ip]\n OutputType = List[Domain]\n @classmethod\n def name(cls) -> str:\n return \"ip_to_domain\"\n @classmethod", + "detail": "spectragraph-transforms.src.spectragraph_transforms.ip.to_domain", + "documentation": {} + }, + { + "label": "InputType", + "kind": 5, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.ip.to_domain", + "description": "spectragraph-transforms.src.spectragraph_transforms.ip.to_domain", + "peekOfCode": "InputType = ReverseResolveTransform.InputType\nOutputType = ReverseResolveTransform.OutputType", + "detail": "spectragraph-transforms.src.spectragraph_transforms.ip.to_domain", + "documentation": {} + }, + { + "label": "OutputType", + "kind": 5, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.ip.to_domain", + "description": "spectragraph-transforms.src.spectragraph_transforms.ip.to_domain", + "peekOfCode": "OutputType = ReverseResolveTransform.OutputType", + "detail": "spectragraph-transforms.src.spectragraph_transforms.ip.to_domain", + "documentation": {} + }, + { + "label": "IpToInfosTransform", + "kind": 6, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.ip.to_infos", + "description": "spectragraph-transforms.src.spectragraph_transforms.ip.to_infos", + "peekOfCode": "class IpToInfosTransform(Transform):\n \"\"\"[ip-api.com] Get information data for IP addresses.\"\"\"\n # Define types as class attributes - base class handles schema generation automatically\n InputType = List[Ip]\n OutputType = List[Ip]\n @classmethod\n def name(cls) -> str:\n return \"ip_to_infos\"\n @classmethod\n def category(cls) -> str:", + "detail": "spectragraph-transforms.src.spectragraph_transforms.ip.to_infos", + "documentation": {} + }, + { + "label": "InputType", + "kind": 5, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.ip.to_infos", + "description": "spectragraph-transforms.src.spectragraph_transforms.ip.to_infos", + "peekOfCode": "InputType = IpToInfosTransform.InputType\nOutputType = IpToInfosTransform.OutputType", + "detail": "spectragraph-transforms.src.spectragraph_transforms.ip.to_infos", + "documentation": {} + }, + { + "label": "OutputType", + "kind": 5, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.ip.to_infos", + "description": "spectragraph-transforms.src.spectragraph_transforms.ip.to_infos", + "peekOfCode": "OutputType = IpToInfosTransform.OutputType", + "detail": "spectragraph-transforms.src.spectragraph_transforms.ip.to_infos", + "documentation": {} + }, + { + "label": "HibpTransform", + "kind": 6, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.leak.to_leaks", + "description": "spectragraph-transforms.src.spectragraph_transforms.leak.to_leaks", + "peekOfCode": "class HibpTransform(Transform):\n \"\"\"Queries HaveIBeenPwned for potential leaks.\"\"\"\n # Define types as class attributes - base class handles schema generation automatically\n InputType = List[str] # Email addresses as strings\n OutputType = List[Dict[str, Any]] # Breach results as dictionaries\n def __init__(\n self,\n sketch_id: Optional[str] = None,\n scan_id: Optional[str] = None,\n neo4j_conn: Optional[Neo4jConnection] = None,", + "detail": "spectragraph-transforms.src.spectragraph_transforms.leak.to_leaks", + "documentation": {} + }, + { + "label": "HIBP_API_KEY", + "kind": 5, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.leak.to_leaks", + "description": "spectragraph-transforms.src.spectragraph_transforms.leak.to_leaks", + "peekOfCode": "HIBP_API_KEY = os.getenv(\"HIBP_API_KEY\")\nclass HibpTransform(Transform):\n \"\"\"Queries HaveIBeenPwned for potential leaks.\"\"\"\n # Define types as class attributes - base class handles schema generation automatically\n InputType = List[str] # Email addresses as strings\n OutputType = List[Dict[str, Any]] # Breach results as dictionaries\n def __init__(\n self,\n sketch_id: Optional[str] = None,\n scan_id: Optional[str] = None,", + "detail": "spectragraph-transforms.src.spectragraph_transforms.leak.to_leaks", + "documentation": {} + }, + { + "label": "InputType", + "kind": 5, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.leak.to_leaks", + "description": "spectragraph-transforms.src.spectragraph_transforms.leak.to_leaks", + "peekOfCode": "InputType = HibpTransform.InputType\nOutputType = HibpTransform.OutputType", + "detail": "spectragraph-transforms.src.spectragraph_transforms.leak.to_leaks", + "documentation": {} + }, + { + "label": "OutputType", + "kind": 5, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.leak.to_leaks", + "description": "spectragraph-transforms.src.spectragraph_transforms.leak.to_leaks", + "peekOfCode": "OutputType = HibpTransform.OutputType", + "detail": "spectragraph-transforms.src.spectragraph_transforms.leak.to_leaks", + "documentation": {} + }, + { + "label": "N8nConnector", + "kind": 6, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.n8n.connector", + "description": "spectragraph-transforms.src.spectragraph_transforms.n8n.connector", + "peekOfCode": "class N8nConnector(Transform):\n \"\"\"\n Connect to your custom n8n workflows to process data through webhooks.\n \"\"\"\n # Define types as class attributes - base class handles schema generation automatically\n InputType = List[Any]\n OutputType = List[Any]\n def __init__(\n self,\n sketch_id: Optional[str] = None,", + "detail": "spectragraph-transforms.src.spectragraph_transforms.n8n.connector", + "documentation": {} + }, + { + "label": "InputType", + "kind": 5, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.n8n.connector", + "description": "spectragraph-transforms.src.spectragraph_transforms.n8n.connector", + "peekOfCode": "InputType = N8nConnector.InputType\nOutputType = N8nConnector.OutputType", + "detail": "spectragraph-transforms.src.spectragraph_transforms.n8n.connector", + "documentation": {} + }, + { + "label": "OutputType", + "kind": 5, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.n8n.connector", + "description": "spectragraph-transforms.src.spectragraph_transforms.n8n.connector", + "peekOfCode": "OutputType = N8nConnector.OutputType", + "detail": "spectragraph-transforms.src.spectragraph_transforms.n8n.connector", + "documentation": {} + }, + { + "label": "OrgToAsnTransform", + "kind": 6, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.organization.to_asn", + "description": "spectragraph-transforms.src.spectragraph_transforms.organization.to_asn", + "peekOfCode": "class OrgToAsnTransform(Transform):\n \"\"\"Takes an organization and returns its corresponding ASN.\"\"\"\n # Define types as class attributes - base class handles schema generation automatically\n InputType = List[Organization]\n OutputType = List[ASN]\n @classmethod\n def name(cls) -> str:\n return \"org_to_asn\"\n @classmethod\n def category(cls) -> str:", + "detail": "spectragraph-transforms.src.spectragraph_transforms.organization.to_asn", + "documentation": {} + }, + { + "label": "InputType", + "kind": 5, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.organization.to_asn", + "description": "spectragraph-transforms.src.spectragraph_transforms.organization.to_asn", + "peekOfCode": "InputType = OrgToAsnTransform.InputType\nOutputType = OrgToAsnTransform.OutputType", + "detail": "spectragraph-transforms.src.spectragraph_transforms.organization.to_asn", + "documentation": {} + }, + { + "label": "OutputType", + "kind": 5, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.organization.to_asn", + "description": "spectragraph-transforms.src.spectragraph_transforms.organization.to_asn", + "peekOfCode": "OutputType = OrgToAsnTransform.OutputType", + "detail": "spectragraph-transforms.src.spectragraph_transforms.organization.to_asn", + "documentation": {} + }, + { + "label": "OrgToDomainsTransform", + "kind": 6, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.organization.to_domains", + "description": "spectragraph-transforms.src.spectragraph_transforms.organization.to_domains", + "peekOfCode": "class OrgToDomainsTransform(Transform):\n \"\"\"[WHOXY] Takes an organization and returns the domains it registered.\"\"\"\n # Define types as class attributes - base class handles schema generation automatically\n InputType = List[Organization]\n OutputType = List[Domain]\n def __init__(\n self,\n sketch_id: Optional[str] = None,\n scan_id: Optional[str] = None,\n neo4j_conn: Optional[Neo4jConnection] = None,", + "detail": "spectragraph-transforms.src.spectragraph_transforms.organization.to_domains", + "documentation": {} + }, + { + "label": "InputType", + "kind": 5, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.organization.to_domains", + "description": "spectragraph-transforms.src.spectragraph_transforms.organization.to_domains", + "peekOfCode": "InputType = OrgToDomainsTransform.InputType\nOutputType = OrgToDomainsTransform.OutputType", + "detail": "spectragraph-transforms.src.spectragraph_transforms.organization.to_domains", + "documentation": {} + }, + { + "label": "OutputType", + "kind": 5, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.organization.to_domains", + "description": "spectragraph-transforms.src.spectragraph_transforms.organization.to_domains", + "peekOfCode": "OutputType = OrgToDomainsTransform.OutputType", + "detail": "spectragraph-transforms.src.spectragraph_transforms.organization.to_domains", + "documentation": {} + }, + { + "label": "OrgToInfosTransform", + "kind": 6, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.organization.to_infos", + "description": "spectragraph-transforms.src.spectragraph_transforms.organization.to_infos", + "peekOfCode": "class OrgToInfosTransform(Transform):\n \"\"\"Enrich Organization with data from SIRENE (France only).\"\"\"\n # Define types as class attributes - base class handles schema generation automatically\n InputType = List[Organization]\n OutputType = List[Organization]\n @classmethod\n def name(cls) -> str:\n return \"org_to_infos\"\n @classmethod\n def category(cls) -> str:", + "detail": "spectragraph-transforms.src.spectragraph_transforms.organization.to_infos", + "documentation": {} + }, + { + "label": "InputType", + "kind": 5, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.organization.to_infos", + "description": "spectragraph-transforms.src.spectragraph_transforms.organization.to_infos", + "peekOfCode": "InputType = OrgToInfosTransform.InputType\nOutputType = OrgToInfosTransform.OutputType", + "detail": "spectragraph-transforms.src.spectragraph_transforms.organization.to_infos", + "documentation": {} + }, + { + "label": "OutputType", + "kind": 5, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.organization.to_infos", + "description": "spectragraph-transforms.src.spectragraph_transforms.organization.to_infos", + "peekOfCode": "OutputType = OrgToInfosTransform.OutputType", + "detail": "spectragraph-transforms.src.spectragraph_transforms.organization.to_infos", + "documentation": {} + }, + { + "label": "IgnorantTransform", + "kind": 6, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.phone.to_infos", + "description": "spectragraph-transforms.src.spectragraph_transforms.phone.to_infos", + "peekOfCode": "class IgnorantTransform(Transform):\n # Define types as class attributes - base class handles schema generation automatically\n InputType = List[str] # Phone numbers as strings\n OutputType = List[Dict[str, Any]] # Results as dictionaries\n @classmethod\n def name(cls) -> str:\n return \"phone_to_infos\"\n @classmethod\n def category(cls) -> str:\n return \"phones\"", + "detail": "spectragraph-transforms.src.spectragraph_transforms.phone.to_infos", + "documentation": {} + }, + { + "label": "InputType", + "kind": 5, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.phone.to_infos", + "description": "spectragraph-transforms.src.spectragraph_transforms.phone.to_infos", + "peekOfCode": "InputType = IgnorantTransform.InputType\nOutputType = IgnorantTransform.OutputType", + "detail": "spectragraph-transforms.src.spectragraph_transforms.phone.to_infos", + "documentation": {} + }, + { + "label": "OutputType", + "kind": 5, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.phone.to_infos", + "description": "spectragraph-transforms.src.spectragraph_transforms.phone.to_infos", + "peekOfCode": "OutputType = IgnorantTransform.OutputType", + "detail": "spectragraph-transforms.src.spectragraph_transforms.phone.to_infos", + "documentation": {} + }, + { + "label": "PhoneToBreachesTransform", + "kind": 6, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.phone.to_leaks", + "description": "spectragraph-transforms.src.spectragraph_transforms.phone.to_leaks", + "peekOfCode": "class PhoneToBreachesTransform(Transform):\n \"\"\"[HIBPWNED] Get the breaches the phone number might be invovled in.\"\"\"\n InputType = List[Phone]\n OutputType = List[tuple] # List of (phone, breach) tuples\n def __init__(\n self,\n sketch_id: Optional[str] = None,\n scan_id: Optional[str] = None,\n neo4j_conn: Optional[Neo4jConnection] = None,\n vault=None,", + "detail": "spectragraph-transforms.src.spectragraph_transforms.phone.to_leaks", + "documentation": {} + }, + { + "label": "HIBP_API_KEY", + "kind": 5, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.phone.to_leaks", + "description": "spectragraph-transforms.src.spectragraph_transforms.phone.to_leaks", + "peekOfCode": "HIBP_API_KEY = os.getenv(\"HIBP_API_KEY\")\nclass PhoneToBreachesTransform(Transform):\n \"\"\"[HIBPWNED] Get the breaches the phone number might be invovled in.\"\"\"\n InputType = List[Phone]\n OutputType = List[tuple] # List of (phone, breach) tuples\n def __init__(\n self,\n sketch_id: Optional[str] = None,\n scan_id: Optional[str] = None,\n neo4j_conn: Optional[Neo4jConnection] = None,", + "detail": "spectragraph-transforms.src.spectragraph_transforms.phone.to_leaks", + "documentation": {} + }, + { + "label": "InputType", + "kind": 5, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.phone.to_leaks", + "description": "spectragraph-transforms.src.spectragraph_transforms.phone.to_leaks", + "peekOfCode": "InputType = PhoneToBreachesTransform.InputType\nOutputType = PhoneToBreachesTransform.OutputType", + "detail": "spectragraph-transforms.src.spectragraph_transforms.phone.to_leaks", + "documentation": {} + }, + { + "label": "OutputType", + "kind": 5, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.phone.to_leaks", + "description": "spectragraph-transforms.src.spectragraph_transforms.phone.to_leaks", + "peekOfCode": "OutputType = PhoneToBreachesTransform.OutputType", + "detail": "spectragraph-transforms.src.spectragraph_transforms.phone.to_leaks", + "documentation": {} + }, + { + "label": "GitHubRepoParams", + "kind": 6, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.social.github_repo", + "description": "spectragraph-transforms.src.spectragraph_transforms.social.github_repo", + "peekOfCode": "class GitHubRepoParams(BaseModel):\n \"\"\"Parameters for GitHub repository transform.\"\"\"\n domain: str = Field(..., description=\"Target domain to investigate\")\n include_forks: bool = Field(default=False, description=\"Include forked repositories\")\n max_repos: int = Field(default=50, ge=1, le=100, description=\"Maximum repos to return\")\n min_stars: int = Field(default=0, ge=0, description=\"Minimum stars filter\")\n language_filter: Optional[str] = Field(default=None, description=\"Filter by programming language\")\nclass GitHubRepoTransform(Transform):\n \"\"\"\n Transform that enriches domains with GitHub organization information.", + "detail": "spectragraph-transforms.src.spectragraph_transforms.social.github_repo", + "documentation": {} + }, + { + "label": "GitHubRepoTransform", + "kind": 6, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.social.github_repo", + "description": "spectragraph-transforms.src.spectragraph_transforms.social.github_repo", + "peekOfCode": "class GitHubRepoTransform(Transform):\n \"\"\"\n Transform that enriches domains with GitHub organization information.\n Capabilities:\n - Search for GitHub organizations matching domain\n - Retrieve organization details and metrics\n - List public repositories with detailed metadata\n - Identify top contributors per repository\n - Track repository activity and health\n - Detect security indicators (Dependabot, policies, etc.)", + "detail": "spectragraph-transforms.src.spectragraph_transforms.social.github_repo", + "documentation": {} + }, + { + "label": "MaigretTransform", + "kind": 6, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.social.to_maigret", + "description": "spectragraph-transforms.src.spectragraph_transforms.social.to_maigret", + "peekOfCode": "class MaigretTransform(Transform):\n \"\"\"[MAIGRET] Scans usernames for associated social accounts using Maigret.\"\"\"\n # Define types as class attributes - base class handles schema generation automatically\n InputType = List[SocialProfile]\n OutputType = List[SocialProfile]\n @classmethod\n def name(cls) -> str:\n return \"username_to_socials_maigret\"\n @classmethod\n def category(cls) -> str:", + "detail": "spectragraph-transforms.src.spectragraph_transforms.social.to_maigret", + "documentation": {} + }, + { + "label": "false_positives", + "kind": 5, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.social.to_maigret", + "description": "spectragraph-transforms.src.spectragraph_transforms.social.to_maigret", + "peekOfCode": "false_positives = [\"LeagueOfLegends\"]\nclass MaigretTransform(Transform):\n \"\"\"[MAIGRET] Scans usernames for associated social accounts using Maigret.\"\"\"\n # Define types as class attributes - base class handles schema generation automatically\n InputType = List[SocialProfile]\n OutputType = List[SocialProfile]\n @classmethod\n def name(cls) -> str:\n return \"username_to_socials_maigret\"\n @classmethod", + "detail": "spectragraph-transforms.src.spectragraph_transforms.social.to_maigret", + "documentation": {} + }, + { + "label": "InputType", + "kind": 5, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.social.to_maigret", + "description": "spectragraph-transforms.src.spectragraph_transforms.social.to_maigret", + "peekOfCode": "InputType = MaigretTransform.InputType\nOutputType = MaigretTransform.OutputType", + "detail": "spectragraph-transforms.src.spectragraph_transforms.social.to_maigret", + "documentation": {} + }, + { + "label": "OutputType", + "kind": 5, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.social.to_maigret", + "description": "spectragraph-transforms.src.spectragraph_transforms.social.to_maigret", + "peekOfCode": "OutputType = MaigretTransform.OutputType", + "detail": "spectragraph-transforms.src.spectragraph_transforms.social.to_maigret", + "documentation": {} + }, + { + "label": "SherlockTransform", + "kind": 6, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.social.to_sherlock", + "description": "spectragraph-transforms.src.spectragraph_transforms.social.to_sherlock", + "peekOfCode": "class SherlockTransform(Transform):\n \"\"\"[SHERLOCK] Scans the usernames for associated social accounts using Sherlock.\"\"\"\n # Define types as class attributes - base class handles schema generation automatically\n InputType = List[SocialProfile]\n OutputType = List[SocialProfile]\n @classmethod\n def name(cls) -> str:\n return \"username_to_socials_sherlock\"\n @classmethod\n def category(cls) -> str:", + "detail": "spectragraph-transforms.src.spectragraph_transforms.social.to_sherlock", + "documentation": {} + }, + { + "label": "InputType", + "kind": 5, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.social.to_sherlock", + "description": "spectragraph-transforms.src.spectragraph_transforms.social.to_sherlock", + "peekOfCode": "InputType = SherlockTransform.InputType\nOutputType = SherlockTransform.OutputType", + "detail": "spectragraph-transforms.src.spectragraph_transforms.social.to_sherlock", + "documentation": {} + }, + { + "label": "OutputType", + "kind": 5, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.social.to_sherlock", + "description": "spectragraph-transforms.src.spectragraph_transforms.social.to_sherlock", + "peekOfCode": "OutputType = SherlockTransform.OutputType", + "detail": "spectragraph-transforms.src.spectragraph_transforms.social.to_sherlock", + "documentation": {} + }, + { + "label": "ReturnType", + "kind": 6, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.website.to_crawler", + "description": "spectragraph-transforms.src.spectragraph_transforms.website.to_crawler", + "peekOfCode": "class ReturnType(BaseModel):\n website: Website\n emails: Optional[Email]\n phones: Optional[Phone]\nclass WebsiteToCrawler(Transform):\n \"\"\"From website to crawler.\"\"\"\n # Define types as class attributes - base class handles schema generation automatically\n InputType = List[Website]\n OutputType = List[ReturnType] # Simplified output type\n @classmethod", + "detail": "spectragraph-transforms.src.spectragraph_transforms.website.to_crawler", + "documentation": {} + }, + { + "label": "WebsiteToCrawler", + "kind": 6, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.website.to_crawler", + "description": "spectragraph-transforms.src.spectragraph_transforms.website.to_crawler", + "peekOfCode": "class WebsiteToCrawler(Transform):\n \"\"\"From website to crawler.\"\"\"\n # Define types as class attributes - base class handles schema generation automatically\n InputType = List[Website]\n OutputType = List[ReturnType] # Simplified output type\n @classmethod\n def name(cls) -> str:\n return \"website_to_crawler\"\n @classmethod\n def category(cls) -> str:", + "detail": "spectragraph-transforms.src.spectragraph_transforms.website.to_crawler", + "documentation": {} + }, + { + "label": "InputType", + "kind": 5, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.website.to_crawler", + "description": "spectragraph-transforms.src.spectragraph_transforms.website.to_crawler", + "peekOfCode": "InputType = WebsiteToCrawler.InputType\nOutputType = WebsiteToCrawler.OutputType", + "detail": "spectragraph-transforms.src.spectragraph_transforms.website.to_crawler", + "documentation": {} + }, + { + "label": "OutputType", + "kind": 5, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.website.to_crawler", + "description": "spectragraph-transforms.src.spectragraph_transforms.website.to_crawler", + "peekOfCode": "OutputType = WebsiteToCrawler.OutputType", + "detail": "spectragraph-transforms.src.spectragraph_transforms.website.to_crawler", + "documentation": {} + }, + { + "label": "WebsiteToDomainTransform", + "kind": 6, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.website.to_domain", + "description": "spectragraph-transforms.src.spectragraph_transforms.website.to_domain", + "peekOfCode": "class WebsiteToDomainTransform(Transform):\n \"\"\"From website to domain.\"\"\"\n # Define types as class attributes - base class handles schema generation automatically\n InputType = List[Website]\n OutputType = List[Domain]\n @classmethod\n def name(cls) -> str:\n return \"website_to_domain\"\n @classmethod\n def category(cls) -> str:", + "detail": "spectragraph-transforms.src.spectragraph_transforms.website.to_domain", + "documentation": {} + }, + { + "label": "InputType", + "kind": 5, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.website.to_domain", + "description": "spectragraph-transforms.src.spectragraph_transforms.website.to_domain", + "peekOfCode": "InputType = WebsiteToDomainTransform.InputType\nOutputType = WebsiteToDomainTransform.OutputType", + "detail": "spectragraph-transforms.src.spectragraph_transforms.website.to_domain", + "documentation": {} + }, + { + "label": "OutputType", + "kind": 5, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.website.to_domain", + "description": "spectragraph-transforms.src.spectragraph_transforms.website.to_domain", + "peekOfCode": "OutputType = WebsiteToDomainTransform.OutputType", + "detail": "spectragraph-transforms.src.spectragraph_transforms.website.to_domain", + "documentation": {} + }, + { + "label": "WebsiteToLinks", + "kind": 6, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.website.to_links", + "description": "spectragraph-transforms.src.spectragraph_transforms.website.to_links", + "peekOfCode": "class WebsiteToLinks(Transform):\n \"\"\"From website to spread crawler that extracts domains and internal/external links.\"\"\"\n # Define types as class attributes - base class handles schema generation automatically\n InputType = List[Website]\n OutputType = List[Website]\n @classmethod\n def name(cls) -> str:\n return \"website_to_links\"\n @classmethod\n def category(cls) -> str:", + "detail": "spectragraph-transforms.src.spectragraph_transforms.website.to_links", + "documentation": {} + }, + { + "label": "InputType", + "kind": 5, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.website.to_links", + "description": "spectragraph-transforms.src.spectragraph_transforms.website.to_links", + "peekOfCode": "InputType = WebsiteToLinks.InputType\nOutputType = WebsiteToLinks.OutputType", + "detail": "spectragraph-transforms.src.spectragraph_transforms.website.to_links", + "documentation": {} + }, + { + "label": "OutputType", + "kind": 5, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.website.to_links", + "description": "spectragraph-transforms.src.spectragraph_transforms.website.to_links", + "peekOfCode": "OutputType = WebsiteToLinks.OutputType", + "detail": "spectragraph-transforms.src.spectragraph_transforms.website.to_links", + "documentation": {} + }, + { + "label": "WebsiteToText", + "kind": 6, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.website.to_text", + "description": "spectragraph-transforms.src.spectragraph_transforms.website.to_text", + "peekOfCode": "class WebsiteToText(Transform):\n \"\"\"Extracts the texts in a webpage.\"\"\"\n InputType = List[Website]\n OutputType = List[Phrase]\n @classmethod\n def name(cls) -> str:\n return \"website_to_text\"\n @classmethod\n def category(cls) -> str:\n return \"Website\"", + "detail": "spectragraph-transforms.src.spectragraph_transforms.website.to_text", + "documentation": {} + }, + { + "label": "InputType", + "kind": 5, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.website.to_text", + "description": "spectragraph-transforms.src.spectragraph_transforms.website.to_text", + "peekOfCode": "InputType = WebsiteToText.InputType\nOutputType = WebsiteToText.OutputType", + "detail": "spectragraph-transforms.src.spectragraph_transforms.website.to_text", + "documentation": {} + }, + { + "label": "OutputType", + "kind": 5, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.website.to_text", + "description": "spectragraph-transforms.src.spectragraph_transforms.website.to_text", + "peekOfCode": "OutputType = WebsiteToText.OutputType", + "detail": "spectragraph-transforms.src.spectragraph_transforms.website.to_text", + "documentation": {} + }, + { + "label": "WebsiteToWebtrackersTransform", + "kind": 6, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.website.to_webtrackers", + "description": "spectragraph-transforms.src.spectragraph_transforms.website.to_webtrackers", + "peekOfCode": "class WebsiteToWebtrackersTransform(Transform):\n \"\"\"From website to webtrackers.\"\"\"\n # Define types as class attributes - base class handles schema generation automatically\n InputType = List[Website]\n OutputType = List[WebTracker]\n def __init__(\n self,\n sketch_id: str,\n scan_id: str,\n neo4j_conn: Optional[Neo4jConnection] = None,", + "detail": "spectragraph-transforms.src.spectragraph_transforms.website.to_webtrackers", + "documentation": {} + }, + { + "label": "InputType", + "kind": 5, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.website.to_webtrackers", + "description": "spectragraph-transforms.src.spectragraph_transforms.website.to_webtrackers", + "peekOfCode": "InputType = WebsiteToWebtrackersTransform.InputType\nOutputType = WebsiteToWebtrackersTransform.OutputType", + "detail": "spectragraph-transforms.src.spectragraph_transforms.website.to_webtrackers", + "documentation": {} + }, + { + "label": "OutputType", + "kind": 5, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.website.to_webtrackers", + "description": "spectragraph-transforms.src.spectragraph_transforms.website.to_webtrackers", + "peekOfCode": "OutputType = WebsiteToWebtrackersTransform.OutputType", + "detail": "spectragraph-transforms.src.spectragraph_transforms.website.to_webtrackers", + "documentation": {} + }, + { + "label": "is_valid_ip", + "kind": 2, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.utils", + "description": "spectragraph-transforms.src.spectragraph_transforms.utils", + "peekOfCode": "def is_valid_ip(address: str) -> bool:\n try:\n ipaddress.ip_address(address)\n return True\n except ValueError:\n return False\ndef is_valid_username(username: str) -> bool:\n if not re.match(r\"^[a-zA-Z0-9_-]{3,30}$\", username):\n return False\n return True", + "detail": "spectragraph-transforms.src.spectragraph_transforms.utils", + "documentation": {} + }, + { + "label": "is_valid_username", + "kind": 2, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.utils", + "description": "spectragraph-transforms.src.spectragraph_transforms.utils", + "peekOfCode": "def is_valid_username(username: str) -> bool:\n if not re.match(r\"^[a-zA-Z0-9_-]{3,30}$\", username):\n return False\n return True\ndef is_valid_email(email: str) -> bool:\n if not re.match(r\"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$\", email):\n return False\n return True\ndef is_valid_domain(url_or_domain: str) -> str:\n try:", + "detail": "spectragraph-transforms.src.spectragraph_transforms.utils", + "documentation": {} + }, + { + "label": "is_valid_email", + "kind": 2, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.utils", + "description": "spectragraph-transforms.src.spectragraph_transforms.utils", + "peekOfCode": "def is_valid_email(email: str) -> bool:\n if not re.match(r\"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$\", email):\n return False\n return True\ndef is_valid_domain(url_or_domain: str) -> str:\n try:\n parsed = urlparse(\n url_or_domain if \"://\" in url_or_domain else \"http://\" + url_or_domain\n )\n hostname = parsed.hostname or url_or_domain", + "detail": "spectragraph-transforms.src.spectragraph_transforms.utils", + "documentation": {} + }, + { + "label": "is_valid_domain", + "kind": 2, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.utils", + "description": "spectragraph-transforms.src.spectragraph_transforms.utils", + "peekOfCode": "def is_valid_domain(url_or_domain: str) -> str:\n try:\n parsed = urlparse(\n url_or_domain if \"://\" in url_or_domain else \"http://\" + url_or_domain\n )\n hostname = parsed.hostname or url_or_domain\n if not hostname or \".\" not in hostname:\n return False\n if not re.match(r\"^[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$\", hostname):\n return False", + "detail": "spectragraph-transforms.src.spectragraph_transforms.utils", + "documentation": {} + }, + { + "label": "is_root_domain", + "kind": 2, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.utils", + "description": "spectragraph-transforms.src.spectragraph_transforms.utils", + "peekOfCode": "def is_root_domain(domain: str) -> bool:\n \"\"\"\n Determine if a domain is a root domain or subdomain.\n Args:\n domain: The domain string to check\n Returns:\n True if it's a root domain (e.g., example.com), False if it's a subdomain (e.g., sub.example.com)\n \"\"\"\n try:\n # Remove protocol if present", + "detail": "spectragraph-transforms.src.spectragraph_transforms.utils", + "documentation": {} + }, + { + "label": "get_root_domain", + "kind": 2, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.utils", + "description": "spectragraph-transforms.src.spectragraph_transforms.utils", + "peekOfCode": "def get_root_domain(domain: str) -> str:\n \"\"\"\n Extract the root domain from a given domain string.\n Args:\n domain: The domain string (can be a subdomain or root domain)\n Returns:\n The root domain (e.g., \"example.com\" from \"sub.example.com\" or \"www.sub.example.com\")\n \"\"\"\n try:\n # Remove protocol if present", + "detail": "spectragraph-transforms.src.spectragraph_transforms.utils", + "documentation": {} + }, + { + "label": "is_valid_number", + "kind": 2, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.utils", + "description": "spectragraph-transforms.src.spectragraph_transforms.utils", + "peekOfCode": "def is_valid_number(phone: str, region: str = \"FR\") -> None:\n \"\"\"\n Validates a phone number. Raises InvalidPhoneNumberError if invalid.\n - `region` should be ISO 3166-1 alpha-2 country code (e.g., 'FR' for France)\n \"\"\"\n try:\n parsed = phonenumbers.parse(phone, region)\n if not phonenumbers.is_valid_number(parsed):\n return False\n except NumberParseException:", + "detail": "spectragraph-transforms.src.spectragraph_transforms.utils", + "documentation": {} + }, + { + "label": "parse_asn", + "kind": 2, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.utils", + "description": "spectragraph-transforms.src.spectragraph_transforms.utils", + "peekOfCode": "def parse_asn(asn: str) -> int:\n if not is_valid_asn(asn):\n raise ValueError(f\"Invalid ASN format: {asn}\")\n return int(re.sub(r\"(?i)^AS\", \"\", asn))\ndef is_valid_asn(asn: str) -> bool:\n if not re.fullmatch(r\"(AS)?\\d+\", asn, re.IGNORECASE):\n return False\n asn_num = int(re.sub(r\"(?i)^AS\", \"\", asn))\n return 0 <= asn_num <= 4294967295\ndef resolve_type(details: dict, schema_context: dict = None) -> str:", + "detail": "spectragraph-transforms.src.spectragraph_transforms.utils", + "documentation": {} + }, + { + "label": "is_valid_asn", + "kind": 2, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.utils", + "description": "spectragraph-transforms.src.spectragraph_transforms.utils", + "peekOfCode": "def is_valid_asn(asn: str) -> bool:\n if not re.fullmatch(r\"(AS)?\\d+\", asn, re.IGNORECASE):\n return False\n asn_num = int(re.sub(r\"(?i)^AS\", \"\", asn))\n return 0 <= asn_num <= 4294967295\ndef resolve_type(details: dict, schema_context: dict = None) -> str:\n if \"anyOf\" in details:\n types = []\n for option in details[\"anyOf\"]:\n if \"$ref\" in option:", + "detail": "spectragraph-transforms.src.spectragraph_transforms.utils", + "documentation": {} + }, + { + "label": "resolve_type", + "kind": 2, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.utils", + "description": "spectragraph-transforms.src.spectragraph_transforms.utils", + "peekOfCode": "def resolve_type(details: dict, schema_context: dict = None) -> str:\n if \"anyOf\" in details:\n types = []\n for option in details[\"anyOf\"]:\n if \"$ref\" in option:\n ref = option[\"$ref\"].split(\"/\")[-1]\n types.append(ref)\n elif option.get(\"type\") == \"array\":\n # Handle array types within anyOf\n item_type = resolve_type(option.get(\"items\", {}), schema_context)", + "detail": "spectragraph-transforms.src.spectragraph_transforms.utils", + "documentation": {} + }, + { + "label": "extract_input_schema_flow", + "kind": 2, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.utils", + "description": "spectragraph-transforms.src.spectragraph_transforms.utils", + "peekOfCode": "def extract_input_schema_flow(model: Type[BaseModel]) -> Dict[str, Any]:\n adapter = TypeAdapter(model)\n schema = adapter.json_schema()\n # Use the main schema properties, not the $defs\n type_name = model.__name__\n details = schema\n return {\n \"class_name\": model.__name__,\n \"name\": model.__name__,\n \"module\": model.__module__,", + "detail": "spectragraph-transforms.src.spectragraph_transforms.utils", + "documentation": {} + }, + { + "label": "get_domain_from_ssl", + "kind": 2, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.utils", + "description": "spectragraph-transforms.src.spectragraph_transforms.utils", + "peekOfCode": "def get_domain_from_ssl(ip: str, port: int = 443) -> str | None:\n try:\n context = ssl.create_default_context()\n with socket.create_connection((ip, port), timeout=3) as sock:\n with context.wrap_socket(sock, server_hostname=ip) as ssock:\n cert = ssock.getpeercert()\n subject = cert.get(\"subject\", [])\n for entry in subject:\n if entry[0][0] == \"commonName\":\n return entry[0][1]", + "detail": "spectragraph-transforms.src.spectragraph_transforms.utils", + "documentation": {} + }, + { + "label": "extract_transform", + "kind": 2, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.utils", + "description": "spectragraph-transforms.src.spectragraph_transforms.utils", + "peekOfCode": "def extract_transform(transform: Dict[str, Any]) -> Dict[str, Any]:\n nodes = transform[\"nodes\"]\n edges = transform[\"edges\"]\n input_node = next((node for node in nodes if node[\"data\"][\"type\"] == \"type\"), None)\n if not input_node:\n raise ValueError(\"No input node found.\")\n input_output = input_node[\"data\"][\"outputs\"]\n node_lookup = {node[\"id\"]: node for node in nodes}\n transforms = []\n for edge in edges:", + "detail": "spectragraph-transforms.src.spectragraph_transforms.utils", + "documentation": {} + }, + { + "label": "get_label_color", + "kind": 2, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.utils", + "description": "spectragraph-transforms.src.spectragraph_transforms.utils", + "peekOfCode": "def get_label_color(label: str) -> str:\n color_map = {\"subdomain\": \"#A5ABB6\", \"domain\": \"#68BDF6\", \"default\": \"#A5ABB6\"}\n return color_map.get(label, color_map[\"default\"])\ndef flatten(data_dict, prefix=\"\"):\n \"\"\"\n Flattens a dictionary to contain only Neo4j-compatible property values.\n Neo4j supports primitive types (string, number, boolean) and arrays of those types.\n Args:\n data_dict (dict): Dictionary to flatten\n Returns:", + "detail": "spectragraph-transforms.src.spectragraph_transforms.utils", + "documentation": {} + }, + { + "label": "flatten", + "kind": 2, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.utils", + "description": "spectragraph-transforms.src.spectragraph_transforms.utils", + "peekOfCode": "def flatten(data_dict, prefix=\"\"):\n \"\"\"\n Flattens a dictionary to contain only Neo4j-compatible property values.\n Neo4j supports primitive types (string, number, boolean) and arrays of those types.\n Args:\n data_dict (dict): Dictionary to flatten\n Returns:\n dict: Flattened dictionary with only Neo4j-compatible values\n \"\"\"\n flattened = {}", + "detail": "spectragraph-transforms.src.spectragraph_transforms.utils", + "documentation": {} + }, + { + "label": "get_inline_relationships", + "kind": 2, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.utils", + "description": "spectragraph-transforms.src.spectragraph_transforms.utils", + "peekOfCode": "def get_inline_relationships(nodes: List[Any], edges: List[Any]) -> List[str]:\n \"\"\"\n Get the inline relationships for a list of nodes and edges.\n \"\"\"\n relationships = []\n for edge in edges:\n source = next((node for node in nodes if node[\"id\"] == edge[\"source\"]), None)\n target = next((node for node in nodes if node[\"id\"] == edge[\"target\"]), None)\n if source and target:\n relationships.append({\"source\": source, \"edge\": edge, \"target\": target})", + "detail": "spectragraph-transforms.src.spectragraph_transforms.utils", + "documentation": {} + }, + { + "label": "to_json_serializable", + "kind": 2, + "importPath": "spectragraph-transforms.src.spectragraph_transforms.utils", + "description": "spectragraph-transforms.src.spectragraph_transforms.utils", + "peekOfCode": "def to_json_serializable(obj):\n \"\"\"Convert any object to a JSON-serializable format.\"\"\"\n import json\n from pydantic import BaseModel\n try:\n # Test if already JSON serializable\n json.dumps(obj)\n return obj\n except (TypeError, ValueError):\n # Handle common cases", + "detail": "spectragraph-transforms.src.spectragraph_transforms.utils", + "documentation": {} + }, + { + "label": "AsnmapTool", + "kind": 6, + "importPath": "spectragraph-transforms.src.tools.network.asnmap", + "description": "spectragraph-transforms.src.tools.network.asnmap", + "peekOfCode": "class AsnmapTool(DockerTool):\n image = \"projectdiscovery/asnmap\"\n default_tag = \"latest\"\n def __init__(self):\n super().__init__(self.image, self.default_tag)\n @classmethod\n def name(cls) -> str:\n return \"asnmap\"\n @classmethod\n def description(cls) -> str:", + "detail": "spectragraph-transforms.src.tools.network.asnmap", + "documentation": {} + }, + { + "label": "DnsxTool", + "kind": 6, + "importPath": "spectragraph-transforms.src.tools.network.dnsx", + "description": "spectragraph-transforms.src.tools.network.dnsx", + "peekOfCode": "class DnsxTool(DockerTool):\n image = \"projectdiscovery/dnsx\"\n default_tag = \"latest\"\n def __init__(self):\n super().__init__(self.image, self.default_tag)\n @classmethod\n def name(cls) -> str:\n return \"dnsx\"\n @classmethod\n def description(cls) -> str:", + "detail": "spectragraph-transforms.src.tools.network.dnsx", + "documentation": {} + }, + { + "label": "HttpxTool", + "kind": 6, + "importPath": "spectragraph-transforms.src.tools.network.httpx", + "description": "spectragraph-transforms.src.tools.network.httpx", + "peekOfCode": "class HttpxTool(DockerTool):\n image = \"projectdiscovery/httpx\"\n default_tag = \"latest\"\n def __init__(self):\n super().__init__(self.image, self.default_tag)\n @classmethod\n def name(cls) -> str:\n return \"httpx\"\n @classmethod\n def description(cls) -> str:", + "detail": "spectragraph-transforms.src.tools.network.httpx", + "documentation": {} + }, + { + "label": "MapcidrTool", + "kind": 6, + "importPath": "spectragraph-transforms.src.tools.network.mapcidr", + "description": "spectragraph-transforms.src.tools.network.mapcidr", + "peekOfCode": "class MapcidrTool(DockerTool):\n image = \"projectdiscovery/mapcidr\"\n default_tag = \"latest\"\n def __init__(self):\n super().__init__(self.image, self.default_tag)\n @classmethod\n def name(cls) -> str:\n return \"mapcidr\"\n @classmethod\n def description(cls) -> str:", + "detail": "spectragraph-transforms.src.tools.network.mapcidr", + "documentation": {} + }, + { + "label": "ReconCrawlTool", + "kind": 6, + "importPath": "spectragraph-transforms.src.tools.network.reconcrawl", + "description": "spectragraph-transforms.src.tools.network.reconcrawl", + "peekOfCode": "class ReconCrawlTool(Tool):\n def __init__(self):\n super().__init__()\n @classmethod\n def name(cls) -> str:\n return \"reconcrawl\"\n @classmethod\n def description(cls) -> str:\n return \"Emails and phone numbers crawler from websites by analyzing their HTML and embedded scripts.\"\n @classmethod", + "detail": "spectragraph-transforms.src.tools.network.reconcrawl", + "documentation": {} + }, + { + "label": "SubfinderTool", + "kind": 6, + "importPath": "spectragraph-transforms.src.tools.network.subfinder", + "description": "spectragraph-transforms.src.tools.network.subfinder", + "peekOfCode": "class SubfinderTool(DockerTool):\n image = \"projectdiscovery/subfinder\"\n default_tag = \"latest\"\n def __init__(self):\n super().__init__(self.image, self.default_tag)\n @classmethod\n def name(cls) -> str:\n return \"subfinder\"\n @classmethod\n def description(cls) -> str:", + "detail": "spectragraph-transforms.src.tools.network.subfinder", + "documentation": {} + }, + { + "label": "WhoxyTool", + "kind": 6, + "importPath": "spectragraph-transforms.src.tools.network.whoxy", + "description": "spectragraph-transforms.src.tools.network.whoxy", + "peekOfCode": "class WhoxyTool(Tool):\n whoxy_api_endoint = \"https://api.whoxy.com/\"\n @classmethod\n def name(cls) -> str:\n return \"whoxy\"\n @classmethod\n def version(cls) -> str:\n return \"1.0.0\"\n @classmethod\n def description(cls) -> str:", + "detail": "spectragraph-transforms.src.tools.network.whoxy", + "documentation": {} + }, + { + "label": "SireneTool", + "kind": 6, + "importPath": "spectragraph-transforms.src.tools.organizations.sirene", + "description": "spectragraph-transforms.src.tools.organizations.sirene", + "peekOfCode": "class SireneTool(Tool):\n @classmethod\n def name(cls) -> str:\n return \"sirene\"\n @classmethod\n def version(cls) -> str:\n return \"1.0.0\"\n @classmethod\n def description(cls) -> str:\n return \"The Sirene API allows you to query the Sirene directory of businesses and establishments, managed by Insee.\"", + "detail": "spectragraph-transforms.src.tools.organizations.sirene", + "documentation": {} + }, + { + "label": "Tool", + "kind": 6, + "importPath": "spectragraph-transforms.src.tools.base", + "description": "spectragraph-transforms.src.tools.base", + "peekOfCode": "class Tool(ABC):\n @classmethod\n @abstractmethod\n def name(cls) -> str:\n pass\n @classmethod\n @abstractmethod\n def category(cls) -> str:\n pass\n @classmethod", + "detail": "spectragraph-transforms.src.tools.base", + "documentation": {} + }, + { + "label": "DockerTool", + "kind": 6, + "importPath": "spectragraph-transforms.src.tools.dockertool", + "description": "spectragraph-transforms.src.tools.dockertool", + "peekOfCode": "class DockerTool(Tool):\n def __init__(self, image: str, default_tag: str = \"latest\"):\n self.image = f\"{image}:{default_tag}\"\n try:\n self.client = from_env()\n except Exception as e:\n raise RuntimeError(\n f\"Failed to connect to Docker daemon. Is Docker running? Error: {e}\"\n )\n @classmethod", + "detail": "spectragraph-transforms.src.tools.dockertool", + "documentation": {} + }, + { + "label": "test_name", + "kind": 2, + "importPath": "spectragraph-transforms.tests.tools.network.asnmap", + "description": "spectragraph-transforms.tests.tools.network.asnmap", + "peekOfCode": "def test_name():\n assert tool.name() == \"asnmap\"\ndef test_description():\n assert tool.description() == \"ASN mapping and network reconnaissance tool.\"\ndef test_category():\n assert tool.category() == \"ASN discovery\"\ndef test_image():\n assert tool.get_image() == \"projectdiscovery/asnmap\"\ndef test_install():\n tool.install()", + "detail": "spectragraph-transforms.tests.tools.network.asnmap", + "documentation": {} + }, + { + "label": "test_description", + "kind": 2, + "importPath": "spectragraph-transforms.tests.tools.network.asnmap", + "description": "spectragraph-transforms.tests.tools.network.asnmap", + "peekOfCode": "def test_description():\n assert tool.description() == \"ASN mapping and network reconnaissance tool.\"\ndef test_category():\n assert tool.category() == \"ASN discovery\"\ndef test_image():\n assert tool.get_image() == \"projectdiscovery/asnmap\"\ndef test_install():\n tool.install()\n assert tool.is_installed() == True\ndef test_version():", + "detail": "spectragraph-transforms.tests.tools.network.asnmap", + "documentation": {} + }, + { + "label": "test_category", + "kind": 2, + "importPath": "spectragraph-transforms.tests.tools.network.asnmap", + "description": "spectragraph-transforms.tests.tools.network.asnmap", + "peekOfCode": "def test_category():\n assert tool.category() == \"ASN discovery\"\ndef test_image():\n assert tool.get_image() == \"projectdiscovery/asnmap\"\ndef test_install():\n tool.install()\n assert tool.is_installed() == True\ndef test_version():\n tool.install()\n version = tool.version()", + "detail": "spectragraph-transforms.tests.tools.network.asnmap", + "documentation": {} + }, + { + "label": "test_image", + "kind": 2, + "importPath": "spectragraph-transforms.tests.tools.network.asnmap", + "description": "spectragraph-transforms.tests.tools.network.asnmap", + "peekOfCode": "def test_image():\n assert tool.get_image() == \"projectdiscovery/asnmap\"\ndef test_install():\n tool.install()\n assert tool.is_installed() == True\ndef test_version():\n tool.install()\n version = tool.version()\n # Check that version follows the expected format: v followed by digits and dots\n assert re.match(r\"^v[\\d\\.]+$\", version)", + "detail": "spectragraph-transforms.tests.tools.network.asnmap", + "documentation": {} + }, + { + "label": "test_install", + "kind": 2, + "importPath": "spectragraph-transforms.tests.tools.network.asnmap", + "description": "spectragraph-transforms.tests.tools.network.asnmap", + "peekOfCode": "def test_install():\n tool.install()\n assert tool.is_installed() == True\ndef test_version():\n tool.install()\n version = tool.version()\n # Check that version follows the expected format: v followed by digits and dots\n assert re.match(r\"^v[\\d\\.]+$\", version)\ndef test_launch_no_api_key():\n import pytest", + "detail": "spectragraph-transforms.tests.tools.network.asnmap", + "documentation": {} + }, + { + "label": "test_version", + "kind": 2, + "importPath": "spectragraph-transforms.tests.tools.network.asnmap", + "description": "spectragraph-transforms.tests.tools.network.asnmap", + "peekOfCode": "def test_version():\n tool.install()\n version = tool.version()\n # Check that version follows the expected format: v followed by digits and dots\n assert re.match(r\"^v[\\d\\.]+$\", version)\ndef test_launch_no_api_key():\n import pytest\n with pytest.raises(KeyError, match=\"Missing key\"):\n tool.launch(\"alliage.io\", \"domain\")\ndef test_launch_wrong_type():", + "detail": "spectragraph-transforms.tests.tools.network.asnmap", + "documentation": {} + }, + { + "label": "test_launch_no_api_key", + "kind": 2, + "importPath": "spectragraph-transforms.tests.tools.network.asnmap", + "description": "spectragraph-transforms.tests.tools.network.asnmap", + "peekOfCode": "def test_launch_no_api_key():\n import pytest\n with pytest.raises(KeyError, match=\"Missing key\"):\n tool.launch(\"alliage.io\", \"domain\")\ndef test_launch_wrong_type():\n import pytest\n with pytest.raises(ValueError, match=\"Invalid type: 'domains'\"):\n tool.launch(\"alliage.io\", \"domains\")\ndef test_launch():\n results = tool.launch(\"alliage.io\", \"domain\")", + "detail": "spectragraph-transforms.tests.tools.network.asnmap", + "documentation": {} + }, + { + "label": "test_launch_wrong_type", + "kind": 2, + "importPath": "spectragraph-transforms.tests.tools.network.asnmap", + "description": "spectragraph-transforms.tests.tools.network.asnmap", + "peekOfCode": "def test_launch_wrong_type():\n import pytest\n with pytest.raises(ValueError, match=\"Invalid type: 'domains'\"):\n tool.launch(\"alliage.io\", \"domains\")\ndef test_launch():\n results = tool.launch(\"alliage.io\", \"domain\")\n assert isinstance(results, Dict)", + "detail": "spectragraph-transforms.tests.tools.network.asnmap", + "documentation": {} + }, + { + "label": "test_launch", + "kind": 2, + "importPath": "spectragraph-transforms.tests.tools.network.asnmap", + "description": "spectragraph-transforms.tests.tools.network.asnmap", + "peekOfCode": "def test_launch():\n results = tool.launch(\"alliage.io\", \"domain\")\n assert isinstance(results, Dict)", + "detail": "spectragraph-transforms.tests.tools.network.asnmap", + "documentation": {} + }, + { + "label": "tool", + "kind": 5, + "importPath": "spectragraph-transforms.tests.tools.network.asnmap", + "description": "spectragraph-transforms.tests.tools.network.asnmap", + "peekOfCode": "tool = AsnmapTool()\ndef test_name():\n assert tool.name() == \"asnmap\"\ndef test_description():\n assert tool.description() == \"ASN mapping and network reconnaissance tool.\"\ndef test_category():\n assert tool.category() == \"ASN discovery\"\ndef test_image():\n assert tool.get_image() == \"projectdiscovery/asnmap\"\ndef test_install():", + "detail": "spectragraph-transforms.tests.tools.network.asnmap", + "documentation": {} + }, + { + "label": "test_name", + "kind": 2, + "importPath": "spectragraph-transforms.tests.tools.network.httpx", + "description": "spectragraph-transforms.tests.tools.network.httpx", + "peekOfCode": "def test_name():\n assert tool.name() == \"httpx\"\ndef test_description():\n assert (\n tool.description()\n == \"An HTTP toolkit that probes services, web servers, and other valuable metadata.\"\n )\ndef test_category():\n assert tool.category() == \"Web technologies enumeration\"\ndef test_image():", + "detail": "spectragraph-transforms.tests.tools.network.httpx", + "documentation": {} + }, + { + "label": "test_description", + "kind": 2, + "importPath": "spectragraph-transforms.tests.tools.network.httpx", + "description": "spectragraph-transforms.tests.tools.network.httpx", + "peekOfCode": "def test_description():\n assert (\n tool.description()\n == \"An HTTP toolkit that probes services, web servers, and other valuable metadata.\"\n )\ndef test_category():\n assert tool.category() == \"Web technologies enumeration\"\ndef test_image():\n assert tool.get_image() == \"projectdiscovery/httpx\"\ndef test_install():", + "detail": "spectragraph-transforms.tests.tools.network.httpx", + "documentation": {} + }, + { + "label": "test_category", + "kind": 2, + "importPath": "spectragraph-transforms.tests.tools.network.httpx", + "description": "spectragraph-transforms.tests.tools.network.httpx", + "peekOfCode": "def test_category():\n assert tool.category() == \"Web technologies enumeration\"\ndef test_image():\n assert tool.get_image() == \"projectdiscovery/httpx\"\ndef test_install():\n tool.install()\n assert tool.is_installed() == True\ndef test_version():\n tool.install()\n version = tool.version()", + "detail": "spectragraph-transforms.tests.tools.network.httpx", + "documentation": {} + }, + { + "label": "test_image", + "kind": 2, + "importPath": "spectragraph-transforms.tests.tools.network.httpx", + "description": "spectragraph-transforms.tests.tools.network.httpx", + "peekOfCode": "def test_image():\n assert tool.get_image() == \"projectdiscovery/httpx\"\ndef test_install():\n tool.install()\n assert tool.is_installed() == True\ndef test_version():\n tool.install()\n version = tool.version()\n # Check that version follows the expected format: v followed by digits and dots\n assert re.match(r\"^v[\\d\\.]+$\", version)", + "detail": "spectragraph-transforms.tests.tools.network.httpx", + "documentation": {} + }, + { + "label": "test_install", + "kind": 2, + "importPath": "spectragraph-transforms.tests.tools.network.httpx", + "description": "spectragraph-transforms.tests.tools.network.httpx", + "peekOfCode": "def test_install():\n tool.install()\n assert tool.is_installed() == True\ndef test_version():\n tool.install()\n version = tool.version()\n # Check that version follows the expected format: v followed by digits and dots\n assert re.match(r\"^v[\\d\\.]+$\", version)\ndef test_launch():\n assert True", + "detail": "spectragraph-transforms.tests.tools.network.httpx", + "documentation": {} + }, + { + "label": "test_version", + "kind": 2, + "importPath": "spectragraph-transforms.tests.tools.network.httpx", + "description": "spectragraph-transforms.tests.tools.network.httpx", + "peekOfCode": "def test_version():\n tool.install()\n version = tool.version()\n # Check that version follows the expected format: v followed by digits and dots\n assert re.match(r\"^v[\\d\\.]+$\", version)\ndef test_launch():\n assert True\n results = tool.launch(\"https://alliage.io\")\n print(results)\n assert isinstance(results, List)", + "detail": "spectragraph-transforms.tests.tools.network.httpx", + "documentation": {} + }, + { + "label": "test_launch", + "kind": 2, + "importPath": "spectragraph-transforms.tests.tools.network.httpx", + "description": "spectragraph-transforms.tests.tools.network.httpx", + "peekOfCode": "def test_launch():\n assert True\n results = tool.launch(\"https://alliage.io\")\n print(results)\n assert isinstance(results, List)\ndef test_launch_unreached_host():\n assert True\n results = tool.launch(\"https://this-is-not-a-valid-domain.local\")\n assert isinstance(results, List)\n assert len(results) == 0", + "detail": "spectragraph-transforms.tests.tools.network.httpx", + "documentation": {} + }, + { + "label": "test_launch_unreached_host", + "kind": 2, + "importPath": "spectragraph-transforms.tests.tools.network.httpx", + "description": "spectragraph-transforms.tests.tools.network.httpx", + "peekOfCode": "def test_launch_unreached_host():\n assert True\n results = tool.launch(\"https://this-is-not-a-valid-domain.local\")\n assert isinstance(results, List)\n assert len(results) == 0", + "detail": "spectragraph-transforms.tests.tools.network.httpx", + "documentation": {} + }, + { + "label": "tool", + "kind": 5, + "importPath": "spectragraph-transforms.tests.tools.network.httpx", + "description": "spectragraph-transforms.tests.tools.network.httpx", + "peekOfCode": "tool = HttpxTool()\ndef test_name():\n assert tool.name() == \"httpx\"\ndef test_description():\n assert (\n tool.description()\n == \"An HTTP toolkit that probes services, web servers, and other valuable metadata.\"\n )\ndef test_category():\n assert tool.category() == \"Web technologies enumeration\"", + "detail": "spectragraph-transforms.tests.tools.network.httpx", + "documentation": {} + }, + { + "label": "test_name", + "kind": 2, + "importPath": "spectragraph-transforms.tests.tools.network.reconcrawl", + "description": "spectragraph-transforms.tests.tools.network.reconcrawl", + "peekOfCode": "def test_name():\n assert tool.name() == \"reconcrawl\"\ndef test_description():\n assert (\n tool.description()\n == \"Emails and phone numbers crawler from websites by analyzing their HTML and embedded scripts.\"\n )\ndef test_category():\n assert tool.category() == \"Crawler\"\ndef test_install():", + "detail": "spectragraph-transforms.tests.tools.network.reconcrawl", + "documentation": {} + }, + { + "label": "test_description", + "kind": 2, + "importPath": "spectragraph-transforms.tests.tools.network.reconcrawl", + "description": "spectragraph-transforms.tests.tools.network.reconcrawl", + "peekOfCode": "def test_description():\n assert (\n tool.description()\n == \"Emails and phone numbers crawler from websites by analyzing their HTML and embedded scripts.\"\n )\ndef test_category():\n assert tool.category() == \"Crawler\"\ndef test_install():\n tool.install()\n assert tool.is_installed() == True", + "detail": "spectragraph-transforms.tests.tools.network.reconcrawl", + "documentation": {} + }, + { + "label": "test_category", + "kind": 2, + "importPath": "spectragraph-transforms.tests.tools.network.reconcrawl", + "description": "spectragraph-transforms.tests.tools.network.reconcrawl", + "peekOfCode": "def test_category():\n assert tool.category() == \"Crawler\"\ndef test_install():\n tool.install()\n assert tool.is_installed() == True", + "detail": "spectragraph-transforms.tests.tools.network.reconcrawl", + "documentation": {} + }, + { + "label": "test_install", + "kind": 2, + "importPath": "spectragraph-transforms.tests.tools.network.reconcrawl", + "description": "spectragraph-transforms.tests.tools.network.reconcrawl", + "peekOfCode": "def test_install():\n tool.install()\n assert tool.is_installed() == True", + "detail": "spectragraph-transforms.tests.tools.network.reconcrawl", + "documentation": {} + }, + { + "label": "tool", + "kind": 5, + "importPath": "spectragraph-transforms.tests.tools.network.reconcrawl", + "description": "spectragraph-transforms.tests.tools.network.reconcrawl", + "peekOfCode": "tool = ReconCrawlTool()\ndef test_name():\n assert tool.name() == \"reconcrawl\"\ndef test_description():\n assert (\n tool.description()\n == \"Emails and phone numbers crawler from websites by analyzing their HTML and embedded scripts.\"\n )\ndef test_category():\n assert tool.category() == \"Crawler\"", + "detail": "spectragraph-transforms.tests.tools.network.reconcrawl", + "documentation": {} + }, + { + "label": "test_name", + "kind": 2, + "importPath": "spectragraph-transforms.tests.tools.network.subfinder", + "description": "spectragraph-transforms.tests.tools.network.subfinder", + "peekOfCode": "def test_name():\n assert tool.name() == \"subfinder\"\ndef test_description():\n assert tool.description() == \"Fast passive subdomain enumeration tool.\"\ndef test_category():\n assert tool.category() == \"Subdomain enumeration\"\ndef test_image():\n assert tool.get_image() == \"projectdiscovery/subfinder\"\ndef test_install():\n tool.install()", + "detail": "spectragraph-transforms.tests.tools.network.subfinder", + "documentation": {} + }, + { + "label": "test_description", + "kind": 2, + "importPath": "spectragraph-transforms.tests.tools.network.subfinder", + "description": "spectragraph-transforms.tests.tools.network.subfinder", + "peekOfCode": "def test_description():\n assert tool.description() == \"Fast passive subdomain enumeration tool.\"\ndef test_category():\n assert tool.category() == \"Subdomain enumeration\"\ndef test_image():\n assert tool.get_image() == \"projectdiscovery/subfinder\"\ndef test_install():\n tool.install()\n assert tool.is_installed() == True\ndef test_version():", + "detail": "spectragraph-transforms.tests.tools.network.subfinder", + "documentation": {} + }, + { + "label": "test_category", + "kind": 2, + "importPath": "spectragraph-transforms.tests.tools.network.subfinder", + "description": "spectragraph-transforms.tests.tools.network.subfinder", + "peekOfCode": "def test_category():\n assert tool.category() == \"Subdomain enumeration\"\ndef test_image():\n assert tool.get_image() == \"projectdiscovery/subfinder\"\ndef test_install():\n tool.install()\n assert tool.is_installed() == True\ndef test_version():\n tool.install()\n version = tool.version()", + "detail": "spectragraph-transforms.tests.tools.network.subfinder", + "documentation": {} + }, + { + "label": "test_image", + "kind": 2, + "importPath": "spectragraph-transforms.tests.tools.network.subfinder", + "description": "spectragraph-transforms.tests.tools.network.subfinder", + "peekOfCode": "def test_image():\n assert tool.get_image() == \"projectdiscovery/subfinder\"\ndef test_install():\n tool.install()\n assert tool.is_installed() == True\ndef test_version():\n tool.install()\n version = tool.version()\n # Check that version follows the expected format: v followed by digits and dots\n assert re.match(r\"^v[\\d\\.]+$\", version)", + "detail": "spectragraph-transforms.tests.tools.network.subfinder", + "documentation": {} + }, + { + "label": "test_install", + "kind": 2, + "importPath": "spectragraph-transforms.tests.tools.network.subfinder", + "description": "spectragraph-transforms.tests.tools.network.subfinder", + "peekOfCode": "def test_install():\n tool.install()\n assert tool.is_installed() == True\ndef test_version():\n tool.install()\n version = tool.version()\n # Check that version follows the expected format: v followed by digits and dots\n assert re.match(r\"^v[\\d\\.]+$\", version)\ndef test_launch():\n results = tool.launch(\"alliage.io\")", + "detail": "spectragraph-transforms.tests.tools.network.subfinder", + "documentation": {} + }, + { + "label": "test_version", + "kind": 2, + "importPath": "spectragraph-transforms.tests.tools.network.subfinder", + "description": "spectragraph-transforms.tests.tools.network.subfinder", + "peekOfCode": "def test_version():\n tool.install()\n version = tool.version()\n # Check that version follows the expected format: v followed by digits and dots\n assert re.match(r\"^v[\\d\\.]+$\", version)\ndef test_launch():\n results = tool.launch(\"alliage.io\")\n assert isinstance(results, list)\n assert all(isinstance(item, str) for item in results)", + "detail": "spectragraph-transforms.tests.tools.network.subfinder", + "documentation": {} + }, + { + "label": "test_launch", + "kind": 2, + "importPath": "spectragraph-transforms.tests.tools.network.subfinder", + "description": "spectragraph-transforms.tests.tools.network.subfinder", + "peekOfCode": "def test_launch():\n results = tool.launch(\"alliage.io\")\n assert isinstance(results, list)\n assert all(isinstance(item, str) for item in results)", + "detail": "spectragraph-transforms.tests.tools.network.subfinder", + "documentation": {} + }, + { + "label": "tool", + "kind": 5, + "importPath": "spectragraph-transforms.tests.tools.network.subfinder", + "description": "spectragraph-transforms.tests.tools.network.subfinder", + "peekOfCode": "tool = SubfinderTool()\ndef test_name():\n assert tool.name() == \"subfinder\"\ndef test_description():\n assert tool.description() == \"Fast passive subdomain enumeration tool.\"\ndef test_category():\n assert tool.category() == \"Subdomain enumeration\"\ndef test_image():\n assert tool.get_image() == \"projectdiscovery/subfinder\"\ndef test_install():", + "detail": "spectragraph-transforms.tests.tools.network.subfinder", + "documentation": {} + }, + { + "label": "test_name", + "kind": 2, + "importPath": "spectragraph-transforms.tests.tools.network.whoxy", + "description": "spectragraph-transforms.tests.tools.network.whoxy", + "peekOfCode": "def test_name():\n assert tool.name() == \"whoxy\"\ndef test_description():\n assert (\n tool.description()\n == \"The WHOIS API returns consistent and well-structured WHOIS data in XML & JSON format. Returned data contain parsed WHOIS fields that can be easily understood. Along with WHOIS API, Whoxy also offer WHOIS History API and Reverse WHOIS API.\"\n )\ndef test_category():\n assert tool.category() == \"Network intelligence\"", + "detail": "spectragraph-transforms.tests.tools.network.whoxy", + "documentation": {} + }, + { + "label": "test_description", + "kind": 2, + "importPath": "spectragraph-transforms.tests.tools.network.whoxy", + "description": "spectragraph-transforms.tests.tools.network.whoxy", + "peekOfCode": "def test_description():\n assert (\n tool.description()\n == \"The WHOIS API returns consistent and well-structured WHOIS data in XML & JSON format. Returned data contain parsed WHOIS fields that can be easily understood. Along with WHOIS API, Whoxy also offer WHOIS History API and Reverse WHOIS API.\"\n )\ndef test_category():\n assert tool.category() == \"Network intelligence\"", + "detail": "spectragraph-transforms.tests.tools.network.whoxy", + "documentation": {} + }, + { + "label": "test_category", + "kind": 2, + "importPath": "spectragraph-transforms.tests.tools.network.whoxy", + "description": "spectragraph-transforms.tests.tools.network.whoxy", + "peekOfCode": "def test_category():\n assert tool.category() == \"Network intelligence\"", + "detail": "spectragraph-transforms.tests.tools.network.whoxy", + "documentation": {} + }, + { + "label": "tool", + "kind": 5, + "importPath": "spectragraph-transforms.tests.tools.network.whoxy", + "description": "spectragraph-transforms.tests.tools.network.whoxy", + "peekOfCode": "tool = WhoxyTool()\ndef test_name():\n assert tool.name() == \"whoxy\"\ndef test_description():\n assert (\n tool.description()\n == \"The WHOIS API returns consistent and well-structured WHOIS data in XML & JSON format. Returned data contain parsed WHOIS fields that can be easily understood. Along with WHOIS API, Whoxy also offer WHOIS History API and Reverse WHOIS API.\"\n )\ndef test_category():\n assert tool.category() == \"Network intelligence\"", + "detail": "spectragraph-transforms.tests.tools.network.whoxy", + "documentation": {} + }, + { + "label": "test_name", + "kind": 2, + "importPath": "spectragraph-transforms.tests.tools.organizations.sirene", + "description": "spectragraph-transforms.tests.tools.organizations.sirene", + "peekOfCode": "def test_name():\n assert tool.name() == \"sirene\"\ndef test_description():\n assert (\n tool.description()\n == \"The Sirene API allows you to query the Sirene directory of businesses and establishments, managed by Insee.\"\n )\ndef test_category():\n assert tool.category() == \"Business intelligence\"\ndef test_launch_org():", + "detail": "spectragraph-transforms.tests.tools.organizations.sirene", + "documentation": {} + }, + { + "label": "test_description", + "kind": 2, + "importPath": "spectragraph-transforms.tests.tools.organizations.sirene", + "description": "spectragraph-transforms.tests.tools.organizations.sirene", + "peekOfCode": "def test_description():\n assert (\n tool.description()\n == \"The Sirene API allows you to query the Sirene directory of businesses and establishments, managed by Insee.\"\n )\ndef test_category():\n assert tool.category() == \"Business intelligence\"\ndef test_launch_org():\n results = tool.launch(\"blablacar\", 1)\n assert isinstance(results, list)", + "detail": "spectragraph-transforms.tests.tools.organizations.sirene", + "documentation": {} + }, + { + "label": "test_category", + "kind": 2, + "importPath": "spectragraph-transforms.tests.tools.organizations.sirene", + "description": "spectragraph-transforms.tests.tools.organizations.sirene", + "peekOfCode": "def test_category():\n assert tool.category() == \"Business intelligence\"\ndef test_launch_org():\n results = tool.launch(\"blablacar\", 1)\n assert isinstance(results, list)\n assert all(isinstance(item, Dict) for item in results)\ndef test_launch_person():\n results = tool.launch(\"Karim+Terrache\", 1)\n assert isinstance(results, list)\n assert all(isinstance(item, Dict) for item in results)", + "detail": "spectragraph-transforms.tests.tools.organizations.sirene", + "documentation": {} + }, + { + "label": "test_launch_org", + "kind": 2, + "importPath": "spectragraph-transforms.tests.tools.organizations.sirene", + "description": "spectragraph-transforms.tests.tools.organizations.sirene", + "peekOfCode": "def test_launch_org():\n results = tool.launch(\"blablacar\", 1)\n assert isinstance(results, list)\n assert all(isinstance(item, Dict) for item in results)\ndef test_launch_person():\n results = tool.launch(\"Karim+Terrache\", 1)\n assert isinstance(results, list)\n assert all(isinstance(item, Dict) for item in results)\ndef test_launch_person_space_format():\n results = tool.launch(\"Karim Terrache\", 1)", + "detail": "spectragraph-transforms.tests.tools.organizations.sirene", + "documentation": {} + }, + { + "label": "test_launch_person", + "kind": 2, + "importPath": "spectragraph-transforms.tests.tools.organizations.sirene", + "description": "spectragraph-transforms.tests.tools.organizations.sirene", + "peekOfCode": "def test_launch_person():\n results = tool.launch(\"Karim+Terrache\", 1)\n assert isinstance(results, list)\n assert all(isinstance(item, Dict) for item in results)\ndef test_launch_person_space_format():\n results = tool.launch(\"Karim Terrache\", 1)\n assert isinstance(results, list)\n assert all(isinstance(item, Dict) for item in results)", + "detail": "spectragraph-transforms.tests.tools.organizations.sirene", + "documentation": {} + }, + { + "label": "test_launch_person_space_format", + "kind": 2, + "importPath": "spectragraph-transforms.tests.tools.organizations.sirene", + "description": "spectragraph-transforms.tests.tools.organizations.sirene", + "peekOfCode": "def test_launch_person_space_format():\n results = tool.launch(\"Karim Terrache\", 1)\n assert isinstance(results, list)\n assert all(isinstance(item, Dict) for item in results)", + "detail": "spectragraph-transforms.tests.tools.organizations.sirene", + "documentation": {} + }, + { + "label": "tool", + "kind": 5, + "importPath": "spectragraph-transforms.tests.tools.organizations.sirene", + "description": "spectragraph-transforms.tests.tools.organizations.sirene", + "peekOfCode": "tool = SireneTool()\ndef test_name():\n assert tool.name() == \"sirene\"\ndef test_description():\n assert (\n tool.description()\n == \"The Sirene API allows you to query the Sirene directory of businesses and establishments, managed by Insee.\"\n )\ndef test_category():\n assert tool.category() == \"Business intelligence\"", + "detail": "spectragraph-transforms.tests.tools.organizations.sirene", + "documentation": {} + }, + { + "label": "test_wallet_address_to_transactions_name", + "kind": 2, + "importPath": "spectragraph-transforms.tests.transforms.crypto.wallet_to_nfts", + "description": "spectragraph-transforms.tests.transforms.crypto.wallet_to_nfts", + "peekOfCode": "def test_wallet_address_to_transactions_name():\n assert transform.name() == \"wallet_to_nfts\"\ndef test_wallet_address_to_transactions_category():\n assert transform.category() == \"crypto\"\ndef test_wallet_address_to_transactions_key():\n assert transform.key() == \"address\"\ndef test_preprocess_with_string():\n input_data = [\"0x742d35Cc6634C0532925a3b844Bc454e4438f44e\"]\n result = transform.preprocess(input_data)\n assert len(result) == 1", + "detail": "spectragraph-transforms.tests.transforms.crypto.wallet_to_nfts", + "documentation": {} + }, + { + "label": "test_wallet_address_to_transactions_category", + "kind": 2, + "importPath": "spectragraph-transforms.tests.transforms.crypto.wallet_to_nfts", + "description": "spectragraph-transforms.tests.transforms.crypto.wallet_to_nfts", + "peekOfCode": "def test_wallet_address_to_transactions_category():\n assert transform.category() == \"crypto\"\ndef test_wallet_address_to_transactions_key():\n assert transform.key() == \"address\"\ndef test_preprocess_with_string():\n input_data = [\"0x742d35Cc6634C0532925a3b844Bc454e4438f44e\"]\n result = transform.preprocess(input_data)\n assert len(result) == 1\n assert isinstance(result[0], CryptoWallet)\n assert result[0].address == \"0x742d35Cc6634C0532925a3b844Bc454e4438f44e\"", + "detail": "spectragraph-transforms.tests.transforms.crypto.wallet_to_nfts", + "documentation": {} + }, + { + "label": "test_wallet_address_to_transactions_key", + "kind": 2, + "importPath": "spectragraph-transforms.tests.transforms.crypto.wallet_to_nfts", + "description": "spectragraph-transforms.tests.transforms.crypto.wallet_to_nfts", + "peekOfCode": "def test_wallet_address_to_transactions_key():\n assert transform.key() == \"address\"\ndef test_preprocess_with_string():\n input_data = [\"0x742d35Cc6634C0532925a3b844Bc454e4438f44e\"]\n result = transform.preprocess(input_data)\n assert len(result) == 1\n assert isinstance(result[0], CryptoWallet)\n assert result[0].address == \"0x742d35Cc6634C0532925a3b844Bc454e4438f44e\"\ndef test_preprocess_with_dict():\n input_data = [{\"address\": \"0x742d35Cc6634C0532925a3b844Bc454e4438f44e\"}]", + "detail": "spectragraph-transforms.tests.transforms.crypto.wallet_to_nfts", + "documentation": {} + }, + { + "label": "test_preprocess_with_string", + "kind": 2, + "importPath": "spectragraph-transforms.tests.transforms.crypto.wallet_to_nfts", + "description": "spectragraph-transforms.tests.transforms.crypto.wallet_to_nfts", + "peekOfCode": "def test_preprocess_with_string():\n input_data = [\"0x742d35Cc6634C0532925a3b844Bc454e4438f44e\"]\n result = transform.preprocess(input_data)\n assert len(result) == 1\n assert isinstance(result[0], CryptoWallet)\n assert result[0].address == \"0x742d35Cc6634C0532925a3b844Bc454e4438f44e\"\ndef test_preprocess_with_dict():\n input_data = [{\"address\": \"0x742d35Cc6634C0532925a3b844Bc454e4438f44e\"}]\n result = transform.preprocess(input_data)\n assert len(result) == 1", + "detail": "spectragraph-transforms.tests.transforms.crypto.wallet_to_nfts", + "documentation": {} + }, + { + "label": "test_preprocess_with_dict", + "kind": 2, + "importPath": "spectragraph-transforms.tests.transforms.crypto.wallet_to_nfts", + "description": "spectragraph-transforms.tests.transforms.crypto.wallet_to_nfts", + "peekOfCode": "def test_preprocess_with_dict():\n input_data = [{\"address\": \"0x742d35Cc6634C0532925a3b844Bc454e4438f44e\"}]\n result = transform.preprocess(input_data)\n assert len(result) == 1\n assert isinstance(result[0], CryptoWallet)\n assert result[0].address == \"0x742d35Cc6634C0532925a3b844Bc454e4438f44e\"\ndef test_preprocess_with_wallet_object():\n wallet = CryptoWallet(address=\"0x742d35Cc6634C0532925a3b844Bc454e4438f44e\")\n input_data = [wallet]\n result = transform.preprocess(input_data)", + "detail": "spectragraph-transforms.tests.transforms.crypto.wallet_to_nfts", + "documentation": {} + }, + { + "label": "test_preprocess_with_wallet_object", + "kind": 2, + "importPath": "spectragraph-transforms.tests.transforms.crypto.wallet_to_nfts", + "description": "spectragraph-transforms.tests.transforms.crypto.wallet_to_nfts", + "peekOfCode": "def test_preprocess_with_wallet_object():\n wallet = CryptoWallet(address=\"0x742d35Cc6634C0532925a3b844Bc454e4438f44e\")\n input_data = [wallet]\n result = transform.preprocess(input_data)\n assert len(result) == 1\n assert isinstance(result[0], CryptoWallet)\n assert result[0].address == \"0x742d35Cc6634C0532925a3b844Bc454e4438f44e\"\ndef test_scan_mocked_transactions(monkeypatch):\n # Mock the _get_transactions method\n def mock_get_nfts(address):", + "detail": "spectragraph-transforms.tests.transforms.crypto.wallet_to_nfts", + "documentation": {} + }, + { + "label": "test_scan_mocked_transactions", + "kind": 2, + "importPath": "spectragraph-transforms.tests.transforms.crypto.wallet_to_nfts", + "description": "spectragraph-transforms.tests.transforms.crypto.wallet_to_nfts", + "peekOfCode": "def test_scan_mocked_transactions(monkeypatch):\n # Mock the _get_transactions method\n def mock_get_nfts(address):\n return [\n CryptoNFT(\n wallet=CryptoWallet(\n address=\"0x742d35Cc6634C0532925a3b844Bc454e4438f44e\"\n ),\n contract_address=\"0x123\",\n token_id=\"1\",", + "detail": "spectragraph-transforms.tests.transforms.crypto.wallet_to_nfts", + "documentation": {} + }, + { + "label": "transform", + "kind": 5, + "importPath": "spectragraph-transforms.tests.transforms.crypto.wallet_to_nfts", + "description": "spectragraph-transforms.tests.transforms.crypto.wallet_to_nfts", + "peekOfCode": "transform = CryptoWalletAddressToNFTs(\"sketch_123\", \"scan_123\")\ndef test_wallet_address_to_transactions_name():\n assert transform.name() == \"wallet_to_nfts\"\ndef test_wallet_address_to_transactions_category():\n assert transform.category() == \"crypto\"\ndef test_wallet_address_to_transactions_key():\n assert transform.key() == \"address\"\ndef test_preprocess_with_string():\n input_data = [\"0x742d35Cc6634C0532925a3b844Bc454e4438f44e\"]\n result = transform.preprocess(input_data)", + "detail": "spectragraph-transforms.tests.transforms.crypto.wallet_to_nfts", + "documentation": {} + }, + { + "label": "test_wallet_address_to_transactions_name", + "kind": 2, + "importPath": "spectragraph-transforms.tests.transforms.crypto.wallet_to_transactions", + "description": "spectragraph-transforms.tests.transforms.crypto.wallet_to_transactions", + "peekOfCode": "def test_wallet_address_to_transactions_name():\n assert transform.name() == \"wallet_to_transactions\"\ndef test_wallet_address_to_transactions_category():\n assert transform.category() == \"CryptoCryptoWallet\"\ndef test_wallet_address_to_transactions_key():\n assert transform.key() == \"address\"\ndef test_preprocess_with_string():\n input_data = [\"0x742d35Cc6634C0532925a3b844Bc454e4438f44e\"]\n result = transform.preprocess(input_data)\n assert len(result) == 1", + "detail": "spectragraph-transforms.tests.transforms.crypto.wallet_to_transactions", + "documentation": {} + }, + { + "label": "test_wallet_address_to_transactions_category", + "kind": 2, + "importPath": "spectragraph-transforms.tests.transforms.crypto.wallet_to_transactions", + "description": "spectragraph-transforms.tests.transforms.crypto.wallet_to_transactions", + "peekOfCode": "def test_wallet_address_to_transactions_category():\n assert transform.category() == \"CryptoCryptoWallet\"\ndef test_wallet_address_to_transactions_key():\n assert transform.key() == \"address\"\ndef test_preprocess_with_string():\n input_data = [\"0x742d35Cc6634C0532925a3b844Bc454e4438f44e\"]\n result = transform.preprocess(input_data)\n assert len(result) == 1\n assert isinstance(result[0], CryptoWallet)\n assert result[0].address == \"0x742d35Cc6634C0532925a3b844Bc454e4438f44e\"", + "detail": "spectragraph-transforms.tests.transforms.crypto.wallet_to_transactions", + "documentation": {} + }, + { + "label": "test_wallet_address_to_transactions_key", + "kind": 2, + "importPath": "spectragraph-transforms.tests.transforms.crypto.wallet_to_transactions", + "description": "spectragraph-transforms.tests.transforms.crypto.wallet_to_transactions", + "peekOfCode": "def test_wallet_address_to_transactions_key():\n assert transform.key() == \"address\"\ndef test_preprocess_with_string():\n input_data = [\"0x742d35Cc6634C0532925a3b844Bc454e4438f44e\"]\n result = transform.preprocess(input_data)\n assert len(result) == 1\n assert isinstance(result[0], CryptoWallet)\n assert result[0].address == \"0x742d35Cc6634C0532925a3b844Bc454e4438f44e\"\ndef test_preprocess_with_dict():\n input_data = [{\"address\": \"0x742d35Cc6634C0532925a3b844Bc454e4438f44e\"}]", + "detail": "spectragraph-transforms.tests.transforms.crypto.wallet_to_transactions", + "documentation": {} + }, + { + "label": "test_preprocess_with_string", + "kind": 2, + "importPath": "spectragraph-transforms.tests.transforms.crypto.wallet_to_transactions", + "description": "spectragraph-transforms.tests.transforms.crypto.wallet_to_transactions", + "peekOfCode": "def test_preprocess_with_string():\n input_data = [\"0x742d35Cc6634C0532925a3b844Bc454e4438f44e\"]\n result = transform.preprocess(input_data)\n assert len(result) == 1\n assert isinstance(result[0], CryptoWallet)\n assert result[0].address == \"0x742d35Cc6634C0532925a3b844Bc454e4438f44e\"\ndef test_preprocess_with_dict():\n input_data = [{\"address\": \"0x742d35Cc6634C0532925a3b844Bc454e4438f44e\"}]\n result = transform.preprocess(input_data)\n assert len(result) == 1", + "detail": "spectragraph-transforms.tests.transforms.crypto.wallet_to_transactions", + "documentation": {} + }, + { + "label": "test_preprocess_with_dict", + "kind": 2, + "importPath": "spectragraph-transforms.tests.transforms.crypto.wallet_to_transactions", + "description": "spectragraph-transforms.tests.transforms.crypto.wallet_to_transactions", + "peekOfCode": "def test_preprocess_with_dict():\n input_data = [{\"address\": \"0x742d35Cc6634C0532925a3b844Bc454e4438f44e\"}]\n result = transform.preprocess(input_data)\n assert len(result) == 1\n assert isinstance(result[0], CryptoWallet)\n assert result[0].address == \"0x742d35Cc6634C0532925a3b844Bc454e4438f44e\"\ndef test_preprocess_with_wallet_object():\n wallet = CryptoWallet(address=\"0x742d35Cc6634C0532925a3b844Bc454e4438f44e\")\n input_data = [wallet]\n result = transform.preprocess(input_data)", + "detail": "spectragraph-transforms.tests.transforms.crypto.wallet_to_transactions", + "documentation": {} + }, + { + "label": "test_preprocess_with_wallet_object", + "kind": 2, + "importPath": "spectragraph-transforms.tests.transforms.crypto.wallet_to_transactions", + "description": "spectragraph-transforms.tests.transforms.crypto.wallet_to_transactions", + "peekOfCode": "def test_preprocess_with_wallet_object():\n wallet = CryptoWallet(address=\"0x742d35Cc6634C0532925a3b844Bc454e4438f44e\")\n input_data = [wallet]\n result = transform.preprocess(input_data)\n assert len(result) == 1\n assert isinstance(result[0], CryptoWallet)\n assert result[0].address == \"0x742d35Cc6634C0532925a3b844Bc454e4438f44e\"\n@pytest.mark.asyncio\nasync def test_scan_mocked_transactions(monkeypatch):\n # Mock the _get_transactions method - note it takes address and api_key parameters", + "detail": "spectragraph-transforms.tests.transforms.crypto.wallet_to_transactions", + "documentation": {} + }, + { + "label": "test_transform_requires_api_key", + "kind": 2, + "importPath": "spectragraph-transforms.tests.transforms.crypto.wallet_to_transactions", + "description": "spectragraph-transforms.tests.transforms.crypto.wallet_to_transactions", + "peekOfCode": "def test_transform_requires_api_key():\n \"\"\"Test that the transform validates required ETHERSCAN_API_KEY parameter at construction\"\"\"\n with pytest.raises(\n ValueError, match=\"Transform wallet_to_transactions received invalid params\"\n ):\n CryptoWalletAddressToTransactions(\"sketch_123\", \"scan_123\", params={})\ndef test_transform_with_invalid_api_key_type():\n \"\"\"Test that the transform validates parameter types\"\"\"\n with pytest.raises(\n ValueError, match=\"Transform wallet_to_transactions received invalid params\"", + "detail": "spectragraph-transforms.tests.transforms.crypto.wallet_to_transactions", + "documentation": {} + }, + { + "label": "test_transform_with_invalid_api_key_type", + "kind": 2, + "importPath": "spectragraph-transforms.tests.transforms.crypto.wallet_to_transactions", + "description": "spectragraph-transforms.tests.transforms.crypto.wallet_to_transactions", + "peekOfCode": "def test_transform_with_invalid_api_key_type():\n \"\"\"Test that the transform validates parameter types\"\"\"\n with pytest.raises(\n ValueError, match=\"Transform wallet_to_transactions received invalid params\"\n ):\n CryptoWalletAddressToTransactions(\n \"sketch_123\", \"scan_123\", params={\"ETHERSCAN_API_KEY\": 123}\n )", + "detail": "spectragraph-transforms.tests.transforms.crypto.wallet_to_transactions", + "documentation": {} + }, + { + "label": "transform", + "kind": 5, + "importPath": "spectragraph-transforms.tests.transforms.crypto.wallet_to_transactions", + "description": "spectragraph-transforms.tests.transforms.crypto.wallet_to_transactions", + "peekOfCode": "transform = CryptoWalletAddressToTransactions(\n \"sketch_123\",\n \"scan_123\",\n params={\"ETHERSCAN_API_KEY\": \"ta-clef-api\"},\n)\ndef test_wallet_address_to_transactions_name():\n assert transform.name() == \"wallet_to_transactions\"\ndef test_wallet_address_to_transactions_category():\n assert transform.category() == \"CryptoCryptoWallet\"\ndef test_wallet_address_to_transactions_key():", + "detail": "spectragraph-transforms.tests.transforms.crypto.wallet_to_transactions", + "documentation": {} + }, + { + "label": "TestResolveInputOutputTypes", + "kind": 6, + "importPath": "spectragraph-transforms.tests.transforms.domain.resolve", + "description": "spectragraph-transforms.tests.transforms.domain.resolve", + "peekOfCode": "class TestResolveInputOutputTypes:\n \"\"\"Test the InputType/OutputType functionality for ResolveTransform\"\"\"\n def test_input_output_types_are_defined(self):\n \"\"\"Test that InputType and OutputType are properly defined\"\"\"\n assert hasattr(ResolveTransform, \"InputType\")\n assert hasattr(ResolveTransform, \"OutputType\")\n assert ResolveTransform.InputType == List[Domain]\n assert ResolveTransform.OutputType == List[Ip]\n def test_schemas_use_generate_methods(self):\n \"\"\"Test that schema methods use the new generate methods\"\"\"", + "detail": "spectragraph-transforms.tests.transforms.domain.resolve", + "documentation": {} + }, + { + "label": "test_preprocess_valid_domains", + "kind": 2, + "importPath": "spectragraph-transforms.tests.transforms.domain.resolve", + "description": "spectragraph-transforms.tests.transforms.domain.resolve", + "peekOfCode": "def test_preprocess_valid_domains():\n domains = [\n Domain(domain=\"example.com\"),\n Domain(domain=\"example2.com\"),\n ]\n result = transform.preprocess(domains)\n result_domains = [d.domain for d in result]\n expected_domains = [d.domain for d in domains]\n assert result_domains == expected_domains\ndef test_unprocessed_valid_domains():", + "detail": "spectragraph-transforms.tests.transforms.domain.resolve", + "documentation": {} + }, + { + "label": "test_unprocessed_valid_domains", + "kind": 2, + "importPath": "spectragraph-transforms.tests.transforms.domain.resolve", + "description": "spectragraph-transforms.tests.transforms.domain.resolve", + "peekOfCode": "def test_unprocessed_valid_domains():\n domains = [\n \"example.com\",\n \"example2.com\",\n ]\n result = transform.preprocess(domains)\n result_domains = [d for d in result]\n expected_domains = [Domain(domain=d) for d in domains]\n assert result_domains == expected_domains\ndef test_preprocess_invalid_domains():", + "detail": "spectragraph-transforms.tests.transforms.domain.resolve", + "documentation": {} + }, + { + "label": "test_preprocess_invalid_domains", + "kind": 2, + "importPath": "spectragraph-transforms.tests.transforms.domain.resolve", + "description": "spectragraph-transforms.tests.transforms.domain.resolve", + "peekOfCode": "def test_preprocess_invalid_domains():\n domains = [\n Domain(domain=\"example.com\"),\n Domain(domain=\"invalid_domain\"),\n Domain(domain=\"example.org\"),\n ]\n result = transform.preprocess(domains)\n result_domains = [d.domain for d in result]\n assert \"example.com\" in result_domains\n assert \"example.org\" in result_domains", + "detail": "spectragraph-transforms.tests.transforms.domain.resolve", + "documentation": {} + }, + { + "label": "test_preprocess_multiple_formats", + "kind": 2, + "importPath": "spectragraph-transforms.tests.transforms.domain.resolve", + "description": "spectragraph-transforms.tests.transforms.domain.resolve", + "peekOfCode": "def test_preprocess_multiple_formats():\n domains = [\n {\"domain\": \"example.com\"},\n {\"invalid_key\": \"example.io\"},\n Domain(domain=\"example.org\"),\n \"example.org\",\n ]\n result = transform.preprocess(domains)\n result_domains = [d.domain for d in result]\n assert \"example.com\" in result_domains", + "detail": "spectragraph-transforms.tests.transforms.domain.resolve", + "documentation": {} + }, + { + "label": "test_schemas", + "kind": 2, + "importPath": "spectragraph-transforms.tests.transforms.domain.resolve", + "description": "spectragraph-transforms.tests.transforms.domain.resolve", + "peekOfCode": "def test_schemas():\n input_schema = transform.input_schema()\n output_schema = transform.output_schema()\n # Test the structure and key properties rather than exact match\n assert input_schema[\"type\"] == \"Domain\"\n assert isinstance(input_schema[\"properties\"], list)\n input_property_names = [prop[\"name\"] for prop in input_schema[\"properties\"]]\n assert \"domain\" in input_property_names\n assert output_schema[\"type\"] == \"Ip\"\n assert isinstance(output_schema[\"properties\"], list)", + "detail": "spectragraph-transforms.tests.transforms.domain.resolve", + "documentation": {} + }, + { + "label": "transform", + "kind": 5, + "importPath": "spectragraph-transforms.tests.transforms.domain.resolve", + "description": "spectragraph-transforms.tests.transforms.domain.resolve", + "peekOfCode": "transform = ResolveTransform(\"sketch_123\", \"scan_123\")\ndef test_preprocess_valid_domains():\n domains = [\n Domain(domain=\"example.com\"),\n Domain(domain=\"example2.com\"),\n ]\n result = transform.preprocess(domains)\n result_domains = [d.domain for d in result]\n expected_domains = [d.domain for d in domains]\n assert result_domains == expected_domains", + "detail": "spectragraph-transforms.tests.transforms.domain.resolve", + "documentation": {} + }, + { + "label": "test_preprocess_valid_domains", + "kind": 2, + "importPath": "spectragraph-transforms.tests.transforms.domain.subdomains", + "description": "spectragraph-transforms.tests.transforms.domain.subdomains", + "peekOfCode": "def test_preprocess_valid_domains():\n domains = [\n Domain(domain=\"example.com\"),\n Domain(domain=\"example2.com\"),\n ]\n result = transform.preprocess(domains)\n result_domains = [d.domain for d in result]\n expected_domains = [d.domain for d in domains]\n assert result_domains == expected_domains\ndef test_unprocessed_valid_domains():", + "detail": "spectragraph-transforms.tests.transforms.domain.subdomains", + "documentation": {} + }, + { + "label": "test_unprocessed_valid_domains", + "kind": 2, + "importPath": "spectragraph-transforms.tests.transforms.domain.subdomains", + "description": "spectragraph-transforms.tests.transforms.domain.subdomains", + "peekOfCode": "def test_unprocessed_valid_domains():\n domains = [\n \"example.com\",\n \"example2.com\",\n ]\n result = transform.preprocess(domains)\n result_domains = [d for d in result]\n expected_domains = [Domain(domain=d) for d in domains]\n assert result_domains == expected_domains\ndef test_preprocess_invalid_domains():", + "detail": "spectragraph-transforms.tests.transforms.domain.subdomains", + "documentation": {} + }, + { + "label": "test_preprocess_invalid_domains", + "kind": 2, + "importPath": "spectragraph-transforms.tests.transforms.domain.subdomains", + "description": "spectragraph-transforms.tests.transforms.domain.subdomains", + "peekOfCode": "def test_preprocess_invalid_domains():\n domains = [\n Domain(domain=\"example.com\"),\n Domain(domain=\"invalid_domain\"),\n Domain(domain=\"example.org\"),\n ]\n result = transform.preprocess(domains)\n result_domains = [d.domain for d in result]\n assert \"example.com\" in result_domains\n assert \"example.org\" in result_domains", + "detail": "spectragraph-transforms.tests.transforms.domain.subdomains", + "documentation": {} + }, + { + "label": "test_preprocess_multiple_formats", + "kind": 2, + "importPath": "spectragraph-transforms.tests.transforms.domain.subdomains", + "description": "spectragraph-transforms.tests.transforms.domain.subdomains", + "peekOfCode": "def test_preprocess_multiple_formats():\n domains = [\n {\"domain\": \"example.com\"},\n {\"invalid_key\": \"example.io\"},\n Domain(domain=\"example.org\"),\n \"example.org\",\n ]\n result = transform.preprocess(domains)\n result_domains = [d.domain for d in result]\n assert \"example.com\" in result_domains", + "detail": "spectragraph-transforms.tests.transforms.domain.subdomains", + "documentation": {} + }, + { + "label": "test_scan_extracts_subdomains", + "kind": 2, + "importPath": "spectragraph-transforms.tests.transforms.domain.subdomains", + "description": "spectragraph-transforms.tests.transforms.domain.subdomains", + "peekOfCode": "def test_scan_extracts_subdomains(monkeypatch):\n mock_response = [\n {\"name_value\": \"mail.example.com\\nwww.example.com\"},\n {\"name_value\": \"api.example.com\"},\n {\"name_value\": \"invalid_domain\"}, # devrait être ignoré\n ]\n class MockRequestsResponse:\n def __init__(self, json_data):\n self._json_data = json_data\n self.status_code = 200", + "detail": "spectragraph-transforms.tests.transforms.domain.subdomains", + "documentation": {} + }, + { + "label": "transform", + "kind": 5, + "importPath": "spectragraph-transforms.tests.transforms.domain.subdomains", + "description": "spectragraph-transforms.tests.transforms.domain.subdomains", + "peekOfCode": "transform = SubdomainTransform(\"sketch_123\", \"scan_123\")\ndef test_preprocess_valid_domains():\n domains = [\n Domain(domain=\"example.com\"),\n Domain(domain=\"example2.com\"),\n ]\n result = transform.preprocess(domains)\n result_domains = [d.domain for d in result]\n expected_domains = [d.domain for d in domains]\n assert result_domains == expected_domains", + "detail": "spectragraph-transforms.tests.transforms.domain.subdomains", + "documentation": {} + }, + { + "label": "MockNeo4jConn", + "kind": 6, + "importPath": "spectragraph-transforms.tests.transforms.domain.to_history", + "description": "spectragraph-transforms.tests.transforms.domain.to_history", + "peekOfCode": "class MockNeo4jConn:\n def __init__(self):\n self.nodes_created = []\n self.relationships_created = []\n def create_node(self, label, key, value, **kwargs):\n node_info = {\"label\": label, \"key\": key, \"value\": value, **kwargs}\n self.nodes_created.append(node_info)\n def create_relationship(\n self,\n from_label,", + "detail": "spectragraph-transforms.tests.transforms.domain.to_history", + "documentation": {} + }, + { + "label": "MockTransform", + "kind": 6, + "importPath": "spectragraph-transforms.tests.transforms.domain.to_history", + "description": "spectragraph-transforms.tests.transforms.domain.to_history", + "peekOfCode": "class MockTransform(DomainToHistoryTransform):\n def __init__(self):\n self.sketch_id = \"test_sketch_123\"\n self.neo4j_conn = MockNeo4jConn()\n self._extracted_data = []\n self._extracted_individuals = []\n def log_graph_message(self, message):\n \"\"\"Mock log_graph_message method.\"\"\"\n pass\n@pytest.fixture", + "detail": "spectragraph-transforms.tests.transforms.domain.to_history", + "documentation": {} + }, + { + "label": "transform", + "kind": 2, + "importPath": "spectragraph-transforms.tests.transforms.domain.to_history", + "description": "spectragraph-transforms.tests.transforms.domain.to_history", + "peekOfCode": "def transform():\n \"\"\"Create a transform instance for testing.\"\"\"\n transform = MockTransform()\n return transform\n@pytest.fixture\ndef test_data():\n \"\"\"Load test data from data.json.\"\"\"\n current_dir = os.path.dirname(os.path.abspath(__file__))\n data_file = os.path.join(current_dir, \"..\", \"..\", \"test_data\", \"data.json\")\n with open(data_file, \"r\") as f:", + "detail": "spectragraph-transforms.tests.transforms.domain.to_history", + "documentation": {} + }, + { + "label": "test_data", + "kind": 2, + "importPath": "spectragraph-transforms.tests.transforms.domain.to_history", + "description": "spectragraph-transforms.tests.transforms.domain.to_history", + "peekOfCode": "def test_data():\n \"\"\"Load test data from data.json.\"\"\"\n current_dir = os.path.dirname(os.path.abspath(__file__))\n data_file = os.path.join(current_dir, \"..\", \"..\", \"test_data\", \"data.json\")\n with open(data_file, \"r\") as f:\n return json.load(f)\ndef test_preprocess_valid_domains(transform):\n \"\"\"Test preprocessing with valid domains.\"\"\"\n domains = [\n Domain(domain=\"example.com\"),", + "detail": "spectragraph-transforms.tests.transforms.domain.to_history", + "documentation": {} + }, + { + "label": "test_preprocess_valid_domains", + "kind": 2, + "importPath": "spectragraph-transforms.tests.transforms.domain.to_history", + "description": "spectragraph-transforms.tests.transforms.domain.to_history", + "peekOfCode": "def test_preprocess_valid_domains(transform):\n \"\"\"Test preprocessing with valid domains.\"\"\"\n domains = [\n Domain(domain=\"example.com\"),\n Domain(domain=\"example2.com\"),\n ]\n result = transform.preprocess(domains)\n result_domains = [d.domain for d in result]\n expected_domains = [d.domain for d in domains]\n assert result_domains == expected_domains", + "detail": "spectragraph-transforms.tests.transforms.domain.to_history", + "documentation": {} + }, + { + "label": "test_preprocess_string_domains", + "kind": 2, + "importPath": "spectragraph-transforms.tests.transforms.domain.to_history", + "description": "spectragraph-transforms.tests.transforms.domain.to_history", + "peekOfCode": "def test_preprocess_string_domains(transform):\n \"\"\"Test preprocessing with string domains.\"\"\"\n domains = [\"example.com\", \"example2.com\"]\n result = transform.preprocess(domains)\n assert len(result) == 2\n assert all(isinstance(d, Domain) for d in result)\n assert result[0].domain == \"example.com\"\n assert result[1].domain == \"example2.com\"\ndef test_preprocess_dict_domains(transform):\n \"\"\"Test preprocessing with dict domains.\"\"\"", + "detail": "spectragraph-transforms.tests.transforms.domain.to_history", + "documentation": {} + }, + { + "label": "test_preprocess_dict_domains", + "kind": 2, + "importPath": "spectragraph-transforms.tests.transforms.domain.to_history", + "description": "spectragraph-transforms.tests.transforms.domain.to_history", + "peekOfCode": "def test_preprocess_dict_domains(transform):\n \"\"\"Test preprocessing with dict domains.\"\"\"\n domains = [{\"domain\": \"example.com\"}, {\"domain\": \"example2.com\"}]\n result = transform.preprocess(domains)\n assert len(result) == 2\n assert all(isinstance(d, Domain) for d in result)\n assert result[0].domain == \"example.com\"\n assert result[1].domain == \"example2.com\"\ndef test_preprocess_invalid_domains(transform):\n \"\"\"Test preprocessing with invalid domains.\"\"\"", + "detail": "spectragraph-transforms.tests.transforms.domain.to_history", + "documentation": {} + }, + { + "label": "test_preprocess_invalid_domains", + "kind": 2, + "importPath": "spectragraph-transforms.tests.transforms.domain.to_history", + "description": "spectragraph-transforms.tests.transforms.domain.to_history", + "peekOfCode": "def test_preprocess_invalid_domains(transform):\n \"\"\"Test preprocessing with invalid domains.\"\"\"\n domains = [\n Domain(domain=\"example.com\"),\n Domain(domain=\"invalid_domain\"),\n Domain(domain=\"example.org\"),\n ]\n result = transform.preprocess(domains)\n result_domains = [d.domain for d in result]\n assert \"example.com\" in result_domains", + "detail": "spectragraph-transforms.tests.transforms.domain.to_history", + "documentation": {} + }, + { + "label": "test_is_redacted", + "kind": 2, + "importPath": "spectragraph-transforms.tests.transforms.domain.to_history", + "description": "spectragraph-transforms.tests.transforms.domain.to_history", + "peekOfCode": "def test_is_redacted(transform):\n \"\"\"Test the __is_redacted method.\"\"\"\n # Should be redacted\n assert transform._DomainToHistoryTransform__is_redacted(\"REDACTED FOR PRIVACY\")\n assert transform._DomainToHistoryTransform__is_redacted(\"redacted for privacy\")\n assert transform._DomainToHistoryTransform__is_redacted(\"Some text with PRIVACY in it\")\n # Should NOT be redacted\n assert not transform._DomainToHistoryTransform__is_redacted(\"JOHN DOE\")\n assert not transform._DomainToHistoryTransform__is_redacted(\"john@doe.com\")\n assert not transform._DomainToHistoryTransform__is_redacted(\"123 JOHN STREET\")", + "detail": "spectragraph-transforms.tests.transforms.domain.to_history", + "documentation": {} + }, + { + "label": "test_has_non_redacted_info", + "kind": 2, + "importPath": "spectragraph-transforms.tests.transforms.domain.to_history", + "description": "spectragraph-transforms.tests.transforms.domain.to_history", + "peekOfCode": "def test_has_non_redacted_info(transform):\n \"\"\"Test the __has_non_redacted_info method.\"\"\"\n # Contact with valid information\n valid_contact = {\n \"full_name\": \"JOHN DOE\",\n \"email_address\": \"john@doe.com, martinemah@yahoo.com\",\n \"phone_number\": \"+123456789\",\n \"mailing_address\": \"123 JOHN STREET\",\n \"city_name\": \"DOE CITY\",\n \"zip_code\": \"12345\",", + "detail": "spectragraph-transforms.tests.transforms.domain.to_history", + "documentation": {} + }, + { + "label": "test_extract_individual_from_contact", + "kind": 2, + "importPath": "spectragraph-transforms.tests.transforms.domain.to_history", + "description": "spectragraph-transforms.tests.transforms.domain.to_history", + "peekOfCode": "def test_extract_individual_from_contact(transform):\n \"\"\"Test the __extract_individual_from_contact method.\"\"\"\n # Valid contact\n valid_contact = {\n \"full_name\": \"JOHN DOE\",\n \"email_address\": \"john@doe.com, martinemah@yahoo.com\",\n \"phone_number\": \"+123456789\",\n \"mailing_address\": \"123 JOHN STREET\",\n \"city_name\": \"DOE CITY\",\n \"zip_code\": \"12345\",", + "detail": "spectragraph-transforms.tests.transforms.domain.to_history", + "documentation": {} + }, + { + "label": "test_extract_individual_redacted_name", + "kind": 2, + "importPath": "spectragraph-transforms.tests.transforms.domain.to_history", + "description": "spectragraph-transforms.tests.transforms.domain.to_history", + "peekOfCode": "def test_extract_individual_redacted_name(transform):\n \"\"\"Test that individuals with redacted names are skipped.\"\"\"\n redacted_contact = {\n \"full_name\": \"REDACTED FOR PRIVACY\",\n \"email_address\": \"test@example.com\",\n \"phone_number\": \"+1234567890\",\n }\n individual = transform._DomainToHistoryTransform__extract_individual_from_contact(\n redacted_contact, \"REGISTRANT\"\n )", + "detail": "spectragraph-transforms.tests.transforms.domain.to_history", + "documentation": {} + }, + { + "label": "test_is_valid_email", + "kind": 2, + "importPath": "spectragraph-transforms.tests.transforms.domain.to_history", + "description": "spectragraph-transforms.tests.transforms.domain.to_history", + "peekOfCode": "def test_is_valid_email(transform):\n \"\"\"Test the __is_valid_email method.\"\"\"\n # Valid emails\n assert transform._DomainToHistoryTransform__is_valid_email(\"test@example.com\")\n assert transform._DomainToHistoryTransform__is_valid_email(\"user.name@domain.org\")\n assert transform._DomainToHistoryTransform__is_valid_email(\"user+tag@example.co.uk\")\n # Invalid emails\n assert not transform._DomainToHistoryTransform__is_valid_email(\"invalid-email\")\n assert not transform._DomainToHistoryTransform__is_valid_email(\"@example.com\")\n assert not transform._DomainToHistoryTransform__is_valid_email(\"test@\")", + "detail": "spectragraph-transforms.tests.transforms.domain.to_history", + "documentation": {} + }, + { + "label": "test_extract_physical_address", + "kind": 2, + "importPath": "spectragraph-transforms.tests.transforms.domain.to_history", + "description": "spectragraph-transforms.tests.transforms.domain.to_history", + "peekOfCode": "def test_extract_physical_address(transform):\n \"\"\"Test the __extract_physical_address method.\"\"\"\n # Valid address\n valid_contact = {\n \"mailing_address\": \"123 JOHN STREET\",\n \"city_name\": \"DOE CITY\",\n \"zip_code\": \"12345\",\n \"country_name\": \"United States\",\n }\n address = transform._DomainToHistoryTransform__extract_physical_address(valid_contact)", + "detail": "spectragraph-transforms.tests.transforms.domain.to_history", + "documentation": {} + }, + { + "label": "test_postprocess_creates_nodes_and_relationships", + "kind": 2, + "importPath": "spectragraph-transforms.tests.transforms.domain.to_history", + "description": "spectragraph-transforms.tests.transforms.domain.to_history", + "peekOfCode": "def test_postprocess_creates_nodes_and_relationships(transform, test_data, monkeypatch):\n \"\"\"Test that postprocess creates the expected nodes and relationships.\"\"\"\n # Mock the __get_infos_from_whoxy method\n def mock_get_infos(domain):\n if domain == \"epios.com\":\n return test_data\n return {}\n monkeypatch.setattr(\n transform, \"_DomainToHistoryTransform__get_infos_from_whoxy\", mock_get_infos\n )", + "detail": "spectragraph-transforms.tests.transforms.domain.to_history", + "documentation": {} + }, + { + "label": "test_schemas", + "kind": 2, + "importPath": "spectragraph-transforms.tests.transforms.domain.to_history", + "description": "spectragraph-transforms.tests.transforms.domain.to_history", + "peekOfCode": "def test_schemas(transform):\n \"\"\"Test that the transform has the expected schemas.\"\"\"\n input_schema = transform.input_schema()\n output_schema = transform.output_schema()\n assert input_schema is not None\n assert output_schema is not None", + "detail": "spectragraph-transforms.tests.transforms.domain.to_history", + "documentation": {} + }, + { + "label": "test_preprocess_valid_domains", + "kind": 2, + "importPath": "spectragraph-transforms.tests.transforms.domain.whois", + "description": "spectragraph-transforms.tests.transforms.domain.whois", + "peekOfCode": "def test_preprocess_valid_domains():\n domains = [\n Domain(domain=\"example.com\"),\n Domain(domain=\"example2.com\"),\n ]\n result = transform.preprocess(domains)\n result_domains = [d.domain for d in result]\n expected_domains = [d.domain for d in domains]\n assert result_domains == expected_domains\ndef test_unprocessed_valid_domains():", + "detail": "spectragraph-transforms.tests.transforms.domain.whois", + "documentation": {} + }, + { + "label": "test_unprocessed_valid_domains", + "kind": 2, + "importPath": "spectragraph-transforms.tests.transforms.domain.whois", + "description": "spectragraph-transforms.tests.transforms.domain.whois", + "peekOfCode": "def test_unprocessed_valid_domains():\n domains = [\n \"example.com\",\n \"example2.com\",\n ]\n result = transform.preprocess(domains)\n result_domains = [d for d in result]\n expected_domains = [Domain(domain=d) for d in domains]\n assert result_domains == expected_domains\ndef test_preprocess_invalid_domains():", + "detail": "spectragraph-transforms.tests.transforms.domain.whois", + "documentation": {} + }, + { + "label": "test_preprocess_invalid_domains", + "kind": 2, + "importPath": "spectragraph-transforms.tests.transforms.domain.whois", + "description": "spectragraph-transforms.tests.transforms.domain.whois", + "peekOfCode": "def test_preprocess_invalid_domains():\n domains = [\n Domain(domain=\"example.com\"),\n Domain(domain=\"invalid_domain\"),\n Domain(domain=\"example.org\"),\n ]\n result = transform.preprocess(domains)\n result_domains = [d.domain for d in result]\n assert \"example.com\" in result_domains\n assert \"example.org\" in result_domains", + "detail": "spectragraph-transforms.tests.transforms.domain.whois", + "documentation": {} + }, + { + "label": "test_preprocess_multiple_formats", + "kind": 2, + "importPath": "spectragraph-transforms.tests.transforms.domain.whois", + "description": "spectragraph-transforms.tests.transforms.domain.whois", + "peekOfCode": "def test_preprocess_multiple_formats():\n domains = [\n {\"domain\": \"example.com\"},\n {\"invalid_key\": \"example.io\"},\n Domain(domain=\"example.org\"),\n \"example.org\",\n ]\n result = transform.preprocess(domains)\n result_domains = [d.domain for d in result]\n assert \"example.com\" in result_domains", + "detail": "spectragraph-transforms.tests.transforms.domain.whois", + "documentation": {} + }, + { + "label": "test_scan_returns_whois_objects", + "kind": 2, + "importPath": "spectragraph-transforms.tests.transforms.domain.whois", + "description": "spectragraph-transforms.tests.transforms.domain.whois", + "peekOfCode": "def test_scan_returns_whois_objects(monkeypatch):\n # Patch `whois.whois` to avoid real network call\n mock_whois = lambda domain: {\n \"registrar\": \"MockRegistrar\",\n \"org\": \"MockOrg\",\n \"city\": \"MockCity\",\n \"country\": \"MockCountry\",\n \"emails\": [\"admin@example.com\"],\n \"creation_date\": \"2020-01-01\",\n \"expiration_date\": \"2030-01-01\",", + "detail": "spectragraph-transforms.tests.transforms.domain.whois", + "documentation": {} + }, + { + "label": "test_schemas", + "kind": 2, + "importPath": "spectragraph-transforms.tests.transforms.domain.whois", + "description": "spectragraph-transforms.tests.transforms.domain.whois", + "peekOfCode": "def test_schemas():\n input_schema = transform.input_schema()\n output_schema = transform.output_schema()\n assert input_schema == {\n \"type\": \"Domain\",\n \"properties\": [\n {\"name\": \"domain\", \"type\": \"string\"},\n {\"name\": \"subdomains\", \"type\": \"array | null\"},\n {\"name\": \"ips\", \"type\": \"array | null\"},\n {\"name\": \"whois\", \"type\": \"Whois | null\"},", + "detail": "spectragraph-transforms.tests.transforms.domain.whois", + "documentation": {} + }, + { + "label": "transform", + "kind": 5, + "importPath": "spectragraph-transforms.tests.transforms.domain.whois", + "description": "spectragraph-transforms.tests.transforms.domain.whois", + "peekOfCode": "transform = WhoisTransform(\"sketch_123\", \"scan_123\")\ndef test_preprocess_valid_domains():\n domains = [\n Domain(domain=\"example.com\"),\n Domain(domain=\"example2.com\"),\n ]\n result = transform.preprocess(domains)\n result_domains = [d.domain for d in result]\n expected_domains = [d.domain for d in domains]\n assert result_domains == expected_domains", + "detail": "spectragraph-transforms.tests.transforms.domain.whois", + "documentation": {} + }, + { + "label": "TestEmailToGravatarTransform", + "kind": 6, + "importPath": "spectragraph-transforms.tests.transforms.email.to_gravatar", + "description": "spectragraph-transforms.tests.transforms.email.to_gravatar", + "peekOfCode": "class TestEmailToGravatarTransform:\n \"\"\"Test suite for EmailToGravatarTransform\"\"\"\n def test_name(self):\n \"\"\"Test the transform name\"\"\"\n assert EmailToGravatarTransform.name() == \"to_gravatar\"\n def test_category(self):\n \"\"\"Test the transform category\"\"\"\n assert EmailToGravatarTransform.category() == \"Email\"\n def test_key(self):\n \"\"\"Test the transform key\"\"\"", + "detail": "spectragraph-transforms.tests.transforms.email.to_gravatar", + "documentation": {} + }, + { + "label": "transform", + "kind": 5, + "importPath": "spectragraph-transforms.tests.transforms.email.to_gravatar", + "description": "spectragraph-transforms.tests.transforms.email.to_gravatar", + "peekOfCode": "transform = EmailToGravatarTransform(\"sketch_123\", \"scan_123\")\nclass TestEmailToGravatarTransform:\n \"\"\"Test suite for EmailToGravatarTransform\"\"\"\n def test_name(self):\n \"\"\"Test the transform name\"\"\"\n assert EmailToGravatarTransform.name() == \"to_gravatar\"\n def test_category(self):\n \"\"\"Test the transform category\"\"\"\n assert EmailToGravatarTransform.category() == \"Email\"\n def test_key(self):", + "detail": "spectragraph-transforms.tests.transforms.email.to_gravatar", + "documentation": {} + }, + { + "label": "test_transform_name", + "kind": 2, + "importPath": "spectragraph-transforms.tests.transforms.email.to_leaks", + "description": "spectragraph-transforms.tests.transforms.email.to_leaks", + "peekOfCode": "def test_transform_name():\n assert EmailToBreachesTransform.name() == \"to_leaks\"\ndef test_transform_category():\n assert EmailToBreachesTransform.category() == \"Email\"\ndef test_transform_key():\n assert EmailToBreachesTransform.key() == \"email\"\ndef test_preprocess_string_emails():\n emails = [\n \"test@example.com\",\n \"user@domain.org\",", + "detail": "spectragraph-transforms.tests.transforms.email.to_leaks", + "documentation": {} + }, + { + "label": "test_transform_category", + "kind": 2, + "importPath": "spectragraph-transforms.tests.transforms.email.to_leaks", + "description": "spectragraph-transforms.tests.transforms.email.to_leaks", + "peekOfCode": "def test_transform_category():\n assert EmailToBreachesTransform.category() == \"Email\"\ndef test_transform_key():\n assert EmailToBreachesTransform.key() == \"email\"\ndef test_preprocess_string_emails():\n emails = [\n \"test@example.com\",\n \"user@domain.org\",\n ]\n result = transform.preprocess(emails)", + "detail": "spectragraph-transforms.tests.transforms.email.to_leaks", + "documentation": {} + }, + { + "label": "test_transform_key", + "kind": 2, + "importPath": "spectragraph-transforms.tests.transforms.email.to_leaks", + "description": "spectragraph-transforms.tests.transforms.email.to_leaks", + "peekOfCode": "def test_transform_key():\n assert EmailToBreachesTransform.key() == \"email\"\ndef test_preprocess_string_emails():\n emails = [\n \"test@example.com\",\n \"user@domain.org\",\n ]\n result = transform.preprocess(emails)\n expected_emails = [Email(email=email) for email in emails]\n assert result == expected_emails", + "detail": "spectragraph-transforms.tests.transforms.email.to_leaks", + "documentation": {} + }, + { + "label": "test_preprocess_string_emails", + "kind": 2, + "importPath": "spectragraph-transforms.tests.transforms.email.to_leaks", + "description": "spectragraph-transforms.tests.transforms.email.to_leaks", + "peekOfCode": "def test_preprocess_string_emails():\n emails = [\n \"test@example.com\",\n \"user@domain.org\",\n ]\n result = transform.preprocess(emails)\n expected_emails = [Email(email=email) for email in emails]\n assert result == expected_emails\ndef test_preprocess_dict_emails():\n emails = [", + "detail": "spectragraph-transforms.tests.transforms.email.to_leaks", + "documentation": {} + }, + { + "label": "test_preprocess_dict_emails", + "kind": 2, + "importPath": "spectragraph-transforms.tests.transforms.email.to_leaks", + "description": "spectragraph-transforms.tests.transforms.email.to_leaks", + "peekOfCode": "def test_preprocess_dict_emails():\n emails = [\n {\"email\": \"test@example.com\"},\n {\"email\": \"user@domain.org\"},\n ]\n result = transform.preprocess(emails)\n expected_emails = [Email(email=email[\"email\"]) for email in emails]\n assert result == expected_emails\ndef test_preprocess_email_objects():\n emails = [", + "detail": "spectragraph-transforms.tests.transforms.email.to_leaks", + "documentation": {} + }, + { + "label": "test_preprocess_email_objects", + "kind": 2, + "importPath": "spectragraph-transforms.tests.transforms.email.to_leaks", + "description": "spectragraph-transforms.tests.transforms.email.to_leaks", + "peekOfCode": "def test_preprocess_email_objects():\n emails = [\n Email(email=\"test@example.com\"),\n Email(email=\"user@domain.org\"),\n ]\n result = transform.preprocess(emails)\n assert result == emails\ndef test_preprocess_mixed_formats():\n emails = [\n \"test@example.com\",", + "detail": "spectragraph-transforms.tests.transforms.email.to_leaks", + "documentation": {} + }, + { + "label": "test_preprocess_mixed_formats", + "kind": 2, + "importPath": "spectragraph-transforms.tests.transforms.email.to_leaks", + "description": "spectragraph-transforms.tests.transforms.email.to_leaks", + "peekOfCode": "def test_preprocess_mixed_formats():\n emails = [\n \"test@example.com\",\n {\"email\": \"user@domain.org\"},\n Email(email=\"admin@company.com\"),\n {\"invalid_key\": \"should_be_ignored@test.com\"},\n ]\n result = transform.preprocess(emails)\n result_emails = [email.email for email in result]\n assert \"test@example.com\" in result_emails", + "detail": "spectragraph-transforms.tests.transforms.email.to_leaks", + "documentation": {} + }, + { + "label": "test_scan_successful_response", + "kind": 2, + "importPath": "spectragraph-transforms.tests.transforms.email.to_leaks", + "description": "spectragraph-transforms.tests.transforms.email.to_leaks", + "peekOfCode": "def test_scan_successful_response(mock_get):\n # Mock successful API response\n mock_response = MagicMock()\n mock_response.status_code = 200\n mock_response.json.return_value = [\n {\"Name\": \"TestBreach\", \"Title\": \"Test Breach\", \"Domain\": \"test.com\"},\n {\"Name\": \"AnotherBreach\", \"Title\": \"Another Breach\", \"Domain\": \"another.com\"},\n ]\n mock_get.return_value = mock_response\n emails = [Email(email=\"test@example.com\")]", + "detail": "spectragraph-transforms.tests.transforms.email.to_leaks", + "documentation": {} + }, + { + "label": "test_scan_no_breaches_found", + "kind": 2, + "importPath": "spectragraph-transforms.tests.transforms.email.to_leaks", + "description": "spectragraph-transforms.tests.transforms.email.to_leaks", + "peekOfCode": "def test_scan_no_breaches_found(mock_get):\n # Mock 404 response (no breaches found)\n mock_response = MagicMock()\n mock_response.status_code = 404\n mock_get.return_value = mock_response\n emails = [Email(email=\"test@example.com\")]\n result = transform.scan(emails)\n assert len(result) == 0\n@patch(\"src.transforms.emails.to_leaks.requests.get\")\ndef test_scan_api_error(mock_get):", + "detail": "spectragraph-transforms.tests.transforms.email.to_leaks", + "documentation": {} + }, + { + "label": "test_scan_api_error", + "kind": 2, + "importPath": "spectragraph-transforms.tests.transforms.email.to_leaks", + "description": "spectragraph-transforms.tests.transforms.email.to_leaks", + "peekOfCode": "def test_scan_api_error(mock_get):\n # Mock API error\n mock_get.side_effect = Exception(\"API Error\")\n emails = [Email(email=\"test@example.com\")]\n result = transform.scan(emails)\n assert len(result) == 0\n@patch(\"src.transforms.emails.to_leaks.requests.get\")\ndef test_scan_missing_name_field(mock_get):\n # Mock API response with missing \"Name\" field\n mock_response = MagicMock()", + "detail": "spectragraph-transforms.tests.transforms.email.to_leaks", + "documentation": {} + }, + { + "label": "test_scan_missing_name_field", + "kind": 2, + "importPath": "spectragraph-transforms.tests.transforms.email.to_leaks", + "description": "spectragraph-transforms.tests.transforms.email.to_leaks", + "peekOfCode": "def test_scan_missing_name_field(mock_get):\n # Mock API response with missing \"Name\" field\n mock_response = MagicMock()\n mock_response.status_code = 200\n mock_response.json.return_value = [\n {\"Title\": \"Test Breach\", \"Domain\": \"test.com\"}, # Missing \"Name\" field\n {\"Name\": \"ValidBreach\", \"Title\": \"Valid Breach\", \"Domain\": \"valid.com\"},\n ]\n mock_get.return_value = mock_response\n emails = [Email(email=\"test@example.com\")]", + "detail": "spectragraph-transforms.tests.transforms.email.to_leaks", + "documentation": {} + }, + { + "label": "test_scan_no_api_key", + "kind": 2, + "importPath": "spectragraph-transforms.tests.transforms.email.to_leaks", + "description": "spectragraph-transforms.tests.transforms.email.to_leaks", + "peekOfCode": "def test_scan_no_api_key():\n \"\"\"Test that transform raises ValueError when HIBP_API_KEY is not set.\"\"\"\n emails = [Email(email=\"test@example.com\")]\n with pytest.raises(ValueError, match=\"HIBP_API_KEY not set\"):\n transform.scan(emails)\ndef test_postprocess():\n # Test postprocess method with mocked neo4j connection\n transform.neo4j_conn = MagicMock()\n # Create breach objects with the new structure\n breach1 = Breach(", + "detail": "spectragraph-transforms.tests.transforms.email.to_leaks", + "documentation": {} + }, + { + "label": "test_postprocess", + "kind": 2, + "importPath": "spectragraph-transforms.tests.transforms.email.to_leaks", + "description": "spectragraph-transforms.tests.transforms.email.to_leaks", + "peekOfCode": "def test_postprocess():\n # Test postprocess method with mocked neo4j connection\n transform.neo4j_conn = MagicMock()\n # Create breach objects with the new structure\n breach1 = Breach(\n name=\"testbreach\",\n title=\"Test Breach\",\n domain=\"test.com\",\n pwncount=1000,\n breach={\"name\": \"testbreach\", \"title\": \"Test Breach\"},", + "detail": "spectragraph-transforms.tests.transforms.email.to_leaks", + "documentation": {} + }, + { + "label": "transform", + "kind": 5, + "importPath": "spectragraph-transforms.tests.transforms.email.to_leaks", + "description": "spectragraph-transforms.tests.transforms.email.to_leaks", + "peekOfCode": "transform = EmailToBreachesTransform(\"sketch_123\", \"scan_123\")\ndef test_transform_name():\n assert EmailToBreachesTransform.name() == \"to_leaks\"\ndef test_transform_category():\n assert EmailToBreachesTransform.category() == \"Email\"\ndef test_transform_key():\n assert EmailToBreachesTransform.key() == \"email\"\ndef test_preprocess_string_emails():\n emails = [\n \"test@example.com\",", + "detail": "spectragraph-transforms.tests.transforms.email.to_leaks", + "documentation": {} + }, + { + "label": "test_preprocess_valid_asns", + "kind": 2, + "importPath": "spectragraph-transforms.tests.transforms.ip.asn_to_cidrs", + "description": "spectragraph-transforms.tests.transforms.ip.asn_to_cidrs", + "peekOfCode": "def test_preprocess_valid_asns():\n asns = [\n ASN(number=15169),\n ASN(number=13335),\n ]\n result = transform.preprocess(asns)\n result_numbers = [asn.number for asn in result]\n expected_numbers = [asn.number for asn in asns]\n assert result_numbers == expected_numbers\ndef test_unprocessed_valid_asns():", + "detail": "spectragraph-transforms.tests.transforms.ip.asn_to_cidrs", + "documentation": {} + }, + { + "label": "test_unprocessed_valid_asns", + "kind": 2, + "importPath": "spectragraph-transforms.tests.transforms.ip.asn_to_cidrs", + "description": "spectragraph-transforms.tests.transforms.ip.asn_to_cidrs", + "peekOfCode": "def test_unprocessed_valid_asns():\n asns = [\n \"15169\",\n \"13335\",\n ]\n result = transform.preprocess(asns)\n result_asns = [asn for asn in result]\n expected_asns = [ASN(number=int(asn)) for asn in asns]\n assert result_asns == expected_asns\ndef test_preprocess_invalid_asns():", + "detail": "spectragraph-transforms.tests.transforms.ip.asn_to_cidrs", + "documentation": {} + }, + { + "label": "test_preprocess_invalid_asns", + "kind": 2, + "importPath": "spectragraph-transforms.tests.transforms.ip.asn_to_cidrs", + "description": "spectragraph-transforms.tests.transforms.ip.asn_to_cidrs", + "peekOfCode": "def test_preprocess_invalid_asns():\n asns = [\n ASN(number=15169),\n ASN(number=999999999999), # Invalid ASN number\n ASN(number=13335),\n ]\n result = transform.preprocess(asns)\n result_numbers = [asn.number for asn in result]\n assert 15169 in result_numbers\n assert 13335 in result_numbers", + "detail": "spectragraph-transforms.tests.transforms.ip.asn_to_cidrs", + "documentation": {} + }, + { + "label": "test_preprocess_multiple_formats", + "kind": 2, + "importPath": "spectragraph-transforms.tests.transforms.ip.asn_to_cidrs", + "description": "spectragraph-transforms.tests.transforms.ip.asn_to_cidrs", + "peekOfCode": "def test_preprocess_multiple_formats():\n asns = [\n {\"number\": 15169},\n {\"invalid_key\": 13335},\n ASN(number=13335),\n \"15169\",\n ]\n result = transform.preprocess(asns)\n result_numbers = [asn.number for asn in result]\n assert 15169 in result_numbers", + "detail": "spectragraph-transforms.tests.transforms.ip.asn_to_cidrs", + "documentation": {} + }, + { + "label": "test_schemas", + "kind": 2, + "importPath": "spectragraph-transforms.tests.transforms.ip.asn_to_cidrs", + "description": "spectragraph-transforms.tests.transforms.ip.asn_to_cidrs", + "peekOfCode": "def test_schemas():\n input_schema = transform.input_schema()\n output_schema = transform.output_schema()\n # Input schema should have number field\n assert \"properties\" in input_schema\n number_prop = next(\n (prop for prop in input_schema[\"properties\"] if prop[\"name\"] == \"number\"), None\n )\n assert number_prop is not None\n assert number_prop[\"type\"] == \"integer\"", + "detail": "spectragraph-transforms.tests.transforms.ip.asn_to_cidrs", + "documentation": {} + }, + { + "label": "transform", + "kind": 5, + "importPath": "spectragraph-transforms.tests.transforms.ip.asn_to_cidrs", + "description": "spectragraph-transforms.tests.transforms.ip.asn_to_cidrs", + "peekOfCode": "transform = AsnToCidrsTransform(\"sketch_123\", \"scan_123\")\ndef test_preprocess_valid_asns():\n asns = [\n ASN(number=15169),\n ASN(number=13335),\n ]\n result = transform.preprocess(asns)\n result_numbers = [asn.number for asn in result]\n expected_numbers = [asn.number for asn in asns]\n assert result_numbers == expected_numbers", + "detail": "spectragraph-transforms.tests.transforms.ip.asn_to_cidrs", + "documentation": {} + }, + { + "label": "test_preprocess_valid_cidrs", + "kind": 2, + "importPath": "spectragraph-transforms.tests.transforms.ip.cidr_to_ips", + "description": "spectragraph-transforms.tests.transforms.ip.cidr_to_ips", + "peekOfCode": "def test_preprocess_valid_cidrs():\n cidrs = [\n CIDR(network=\"8.8.8.0/24\"),\n CIDR(network=\"1.1.1.0/24\"),\n ]\n result = transform.preprocess(cidrs)\n result_networks = [cidr.network for cidr in result]\n expected_networks = [cidr.network for cidr in cidrs]\n assert result_networks == expected_networks\ndef test_preprocess_unprocessed_valid_cidrs():", + "detail": "spectragraph-transforms.tests.transforms.ip.cidr_to_ips", + "documentation": {} + }, + { + "label": "test_preprocess_unprocessed_valid_cidrs", + "kind": 2, + "importPath": "spectragraph-transforms.tests.transforms.ip.cidr_to_ips", + "description": "spectragraph-transforms.tests.transforms.ip.cidr_to_ips", + "peekOfCode": "def test_preprocess_unprocessed_valid_cidrs():\n cidrs = [\n \"8.8.8.0/24\",\n \"1.1.1.0/24\",\n ]\n result = transform.preprocess(cidrs)\n result_cidrs = [c for c in result]\n expected_cidrs = [CIDR(network=c) for c in cidrs]\n assert result_cidrs == expected_cidrs\ndef test_preprocess_invalid_cidrs():", + "detail": "spectragraph-transforms.tests.transforms.ip.cidr_to_ips", + "documentation": {} + }, + { + "label": "test_preprocess_invalid_cidrs", + "kind": 2, + "importPath": "spectragraph-transforms.tests.transforms.ip.cidr_to_ips", + "description": "spectragraph-transforms.tests.transforms.ip.cidr_to_ips", + "peekOfCode": "def test_preprocess_invalid_cidrs():\n cidrs = [\n CIDR(network=\"8.8.8.0/24\"),\n \"invalid-cidr\",\n \"not-a-cidr\",\n ]\n result = transform.preprocess(cidrs)\n result_networks = [str(cidr.network) for cidr in result]\n assert \"8.8.8.0/24\" in result_networks\n assert \"invalid-cidr\" not in result_networks", + "detail": "spectragraph-transforms.tests.transforms.ip.cidr_to_ips", + "documentation": {} + }, + { + "label": "test_preprocess_multiple_formats", + "kind": 2, + "importPath": "spectragraph-transforms.tests.transforms.ip.cidr_to_ips", + "description": "spectragraph-transforms.tests.transforms.ip.cidr_to_ips", + "peekOfCode": "def test_preprocess_multiple_formats():\n cidrs = [\n {\"network\": \"8.8.8.0/24\"},\n {\"invalid_key\": \"1.1.1.0/24\"},\n CIDR(network=\"9.9.9.0/24\"),\n \"InvalidCIDR\",\n ]\n result = transform.preprocess(cidrs)\n result_networks = [str(cidr.network) for cidr in result]\n assert \"8.8.8.0/24\" in result_networks", + "detail": "spectragraph-transforms.tests.transforms.ip.cidr_to_ips", + "documentation": {} + }, + { + "label": "test_scan_extracts_ips", + "kind": 2, + "importPath": "spectragraph-transforms.tests.transforms.ip.cidr_to_ips", + "description": "spectragraph-transforms.tests.transforms.ip.cidr_to_ips", + "peekOfCode": "def test_scan_extracts_ips(monkeypatch):\n mock_dnsx_output = \"\"\"8.35.200.12\n8.35.200.112\n8.35.200.16\n8.35.200.170\"\"\"\n class MockSubprocessResult:\n def __init__(self, stdout):\n self.stdout = stdout\n self.returncode = 0\n def mock_subprocess_run(cmd, shell, capture_output, text, timeout):", + "detail": "spectragraph-transforms.tests.transforms.ip.cidr_to_ips", + "documentation": {} + }, + { + "label": "test_scan_handles_empty_output", + "kind": 2, + "importPath": "spectragraph-transforms.tests.transforms.ip.cidr_to_ips", + "description": "spectragraph-transforms.tests.transforms.ip.cidr_to_ips", + "peekOfCode": "def test_scan_handles_empty_output(monkeypatch):\n class MockSubprocessResult:\n def __init__(self):\n self.stdout = \"\"\n self.returncode = 0\n def mock_subprocess_run(cmd, shell, capture_output, text, timeout):\n return MockSubprocessResult()\n monkeypatch.setattr(\"subprocess.run\", mock_subprocess_run)\n input_data = [CIDR(network=\"8.8.8.0/24\")]\n ips = transform.scan(input_data)", + "detail": "spectragraph-transforms.tests.transforms.ip.cidr_to_ips", + "documentation": {} + }, + { + "label": "test_scan_handles_subprocess_exception", + "kind": 2, + "importPath": "spectragraph-transforms.tests.transforms.ip.cidr_to_ips", + "description": "spectragraph-transforms.tests.transforms.ip.cidr_to_ips", + "peekOfCode": "def test_scan_handles_subprocess_exception(monkeypatch):\n def mock_subprocess_run(cmd, shell, capture_output, text, timeout):\n raise Exception(\"Subprocess failed\")\n monkeypatch.setattr(\"subprocess.run\", mock_subprocess_run)\n input_data = [CIDR(network=\"8.8.8.0/24\")]\n ips = transform.scan(input_data)\n assert isinstance(ips, list)\n assert len(ips) == 0", + "detail": "spectragraph-transforms.tests.transforms.ip.cidr_to_ips", + "documentation": {} + }, + { + "label": "logger", + "kind": 5, + "importPath": "spectragraph-transforms.tests.transforms.ip.cidr_to_ips", + "description": "spectragraph-transforms.tests.transforms.ip.cidr_to_ips", + "peekOfCode": "logger = TestLogger()\ntransform = CidrToIpsTransform(\"sketch_123\", \"scan_123\", logger)\ndef test_preprocess_valid_cidrs():\n cidrs = [\n CIDR(network=\"8.8.8.0/24\"),\n CIDR(network=\"1.1.1.0/24\"),\n ]\n result = transform.preprocess(cidrs)\n result_networks = [cidr.network for cidr in result]\n expected_networks = [cidr.network for cidr in cidrs]", + "detail": "spectragraph-transforms.tests.transforms.ip.cidr_to_ips", + "documentation": {} + }, + { + "label": "transform", + "kind": 5, + "importPath": "spectragraph-transforms.tests.transforms.ip.cidr_to_ips", + "description": "spectragraph-transforms.tests.transforms.ip.cidr_to_ips", + "peekOfCode": "transform = CidrToIpsTransform(\"sketch_123\", \"scan_123\", logger)\ndef test_preprocess_valid_cidrs():\n cidrs = [\n CIDR(network=\"8.8.8.0/24\"),\n CIDR(network=\"1.1.1.0/24\"),\n ]\n result = transform.preprocess(cidrs)\n result_networks = [cidr.network for cidr in result]\n expected_networks = [cidr.network for cidr in cidrs]\n assert result_networks == expected_networks", + "detail": "spectragraph-transforms.tests.transforms.ip.cidr_to_ips", + "documentation": {} + }, + { + "label": "test_preprocess_valid_ips", + "kind": 2, + "importPath": "spectragraph-transforms.tests.transforms.ip.ip_to_asn", + "description": "spectragraph-transforms.tests.transforms.ip.ip_to_asn", + "peekOfCode": "def test_preprocess_valid_ips():\n ips = [\n Ip(address=\"8.8.8.8\"),\n Ip(address=\"1.1.1.1\"),\n ]\n result = transform.preprocess(ips)\n result_addresses = [ip.address for ip in result]\n expected_addresses = [ip.address for ip in ips]\n assert result_addresses == expected_addresses\ndef test_unprocessed_valid_ips():", + "detail": "spectragraph-transforms.tests.transforms.ip.ip_to_asn", + "documentation": {} + }, + { + "label": "test_unprocessed_valid_ips", + "kind": 2, + "importPath": "spectragraph-transforms.tests.transforms.ip.ip_to_asn", + "description": "spectragraph-transforms.tests.transforms.ip.ip_to_asn", + "peekOfCode": "def test_unprocessed_valid_ips():\n ips = [\n \"8.8.8.8\",\n \"1.1.1.1\",\n ]\n result = transform.preprocess(ips)\n result_ips = [ip for ip in result]\n expected_ips = [Ip(address=ip) for ip in ips]\n assert result_ips == expected_ips\ndef test_preprocess_invalid_ips():", + "detail": "spectragraph-transforms.tests.transforms.ip.ip_to_asn", + "documentation": {} + }, + { + "label": "test_preprocess_invalid_ips", + "kind": 2, + "importPath": "spectragraph-transforms.tests.transforms.ip.ip_to_asn", + "description": "spectragraph-transforms.tests.transforms.ip.ip_to_asn", + "peekOfCode": "def test_preprocess_invalid_ips():\n ips = [\n Ip(address=\"8.8.8.8\"),\n Ip(address=\"invalid_ip\"),\n Ip(address=\"192.168.1.1\"),\n ]\n result = transform.preprocess(ips)\n result_addresses = [ip.address for ip in result]\n assert \"8.8.8.8\" in result_addresses\n assert \"192.168.1.1\" in result_addresses", + "detail": "spectragraph-transforms.tests.transforms.ip.ip_to_asn", + "documentation": {} + }, + { + "label": "test_preprocess_multiple_formats", + "kind": 2, + "importPath": "spectragraph-transforms.tests.transforms.ip.ip_to_asn", + "description": "spectragraph-transforms.tests.transforms.ip.ip_to_asn", + "peekOfCode": "def test_preprocess_multiple_formats():\n ips = [\n {\"address\": \"8.8.8.8\"},\n {\"invalid_key\": \"1.1.1.1\"},\n Ip(address=\"192.168.1.1\"),\n \"10.0.0.1\",\n ]\n result = transform.preprocess(ips)\n result_addresses = [ip.address for ip in result]\n assert \"8.8.8.8\" in result_addresses", + "detail": "spectragraph-transforms.tests.transforms.ip.ip_to_asn", + "documentation": {} + }, + { + "label": "test_scan_extracts_asn_info", + "kind": 2, + "importPath": "spectragraph-transforms.tests.transforms.ip.ip_to_asn", + "description": "spectragraph-transforms.tests.transforms.ip.ip_to_asn", + "peekOfCode": "def test_scan_extracts_asn_info(monkeypatch):\n mock_asnmap_output = {\n \"input\": \"8.8.8.8\",\n \"as_number\": \"AS15169\",\n \"as_name\": \"GOOGLE\",\n \"as_country\": \"US\",\n \"as_range\": [\"8.8.8.0/24\", \"8.8.4.0/24\"],\n }\n class MockSubprocessResult:\n def __init__(self, stdout):", + "detail": "spectragraph-transforms.tests.transforms.ip.ip_to_asn", + "documentation": {} + }, + { + "label": "test_scan_handles_no_asn_found", + "kind": 2, + "importPath": "spectragraph-transforms.tests.transforms.ip.ip_to_asn", + "description": "spectragraph-transforms.tests.transforms.ip.ip_to_asn", + "peekOfCode": "def test_scan_handles_no_asn_found(monkeypatch):\n class MockSubprocessResult:\n def __init__(self, stdout):\n self.stdout = stdout\n self.returncode = 0\n def mock_subprocess_run(cmd, input, capture_output, text, timeout):\n # Return empty output to simulate no ASN found\n return MockSubprocessResult(\"\")\n monkeypatch.setattr(\"subprocess.run\", mock_subprocess_run)\n input_data = [Ip(address=\"192.168.1.1\")]", + "detail": "spectragraph-transforms.tests.transforms.ip.ip_to_asn", + "documentation": {} + }, + { + "label": "test_scan_handles_subprocess_exception", + "kind": 2, + "importPath": "spectragraph-transforms.tests.transforms.ip.ip_to_asn", + "description": "spectragraph-transforms.tests.transforms.ip.ip_to_asn", + "peekOfCode": "def test_scan_handles_subprocess_exception(monkeypatch):\n def mock_subprocess_run(cmd, input, capture_output, text, timeout):\n raise Exception(\"Subprocess failed\")\n monkeypatch.setattr(\"subprocess.run\", mock_subprocess_run)\n input_data = [Ip(address=\"8.8.8.8\")]\n asns = transform.scan(input_data)\n assert isinstance(asns, list)\n assert len(asns) == 1\n asn = asns[0]\n assert isinstance(asn, ASN)", + "detail": "spectragraph-transforms.tests.transforms.ip.ip_to_asn", + "documentation": {} + }, + { + "label": "test_scan_multiple_ips", + "kind": 2, + "importPath": "spectragraph-transforms.tests.transforms.ip.ip_to_asn", + "description": "spectragraph-transforms.tests.transforms.ip.ip_to_asn", + "peekOfCode": "def test_scan_multiple_ips(monkeypatch):\n mock_responses = {\n \"8.8.8.8\": {\n \"input\": \"8.8.8.8\",\n \"as_number\": \"AS15169\",\n \"as_name\": \"GOOGLE\",\n \"as_country\": \"US\",\n \"as_range\": [\"8.8.8.0/24\"],\n },\n \"1.1.1.1\": {", + "detail": "spectragraph-transforms.tests.transforms.ip.ip_to_asn", + "documentation": {} + }, + { + "label": "test_schemas", + "kind": 2, + "importPath": "spectragraph-transforms.tests.transforms.ip.ip_to_asn", + "description": "spectragraph-transforms.tests.transforms.ip.ip_to_asn", + "peekOfCode": "def test_schemas():\n input_schema = transform.input_schema()\n output_schema = transform.output_schema()\n # Input schema should have address field\n assert \"properties\" in input_schema\n address_prop = next(\n (prop for prop in input_schema[\"properties\"] if prop[\"name\"] == \"address\"), None\n )\n assert address_prop is not None\n assert address_prop[\"type\"] == \"string\"", + "detail": "spectragraph-transforms.tests.transforms.ip.ip_to_asn", + "documentation": {} + }, + { + "label": "test_postprocess_creates_neo4j_relationships", + "kind": 2, + "importPath": "spectragraph-transforms.tests.transforms.ip.ip_to_asn", + "description": "spectragraph-transforms.tests.transforms.ip.ip_to_asn", + "peekOfCode": "def test_postprocess_creates_neo4j_relationships(monkeypatch):\n # Mock Neo4j connection\n mock_neo4j = Mock()\n transform.neo4j_conn = mock_neo4j\n input_data = [Ip(address=\"8.8.8.8\")]\n asn_results = [\n ASN(\n number=15169,\n name=\"GOOGLE\",\n country=\"US\",", + "detail": "spectragraph-transforms.tests.transforms.ip.ip_to_asn", + "documentation": {} + }, + { + "label": "test_postprocess_skips_unknown_asns", + "kind": 2, + "importPath": "spectragraph-transforms.tests.transforms.ip.ip_to_asn", + "description": "spectragraph-transforms.tests.transforms.ip.ip_to_asn", + "peekOfCode": "def test_postprocess_skips_unknown_asns(monkeypatch):\n # Mock Neo4j connection\n mock_neo4j = Mock()\n transform.neo4j_conn = mock_neo4j\n input_data = [Ip(address=\"192.168.1.1\")]\n asn_results = [\n ASN(number=0, name=\"Unknown\", country=\"Unknown\", cidrs=[]) # Unknown ASN\n ]\n result = transform.postprocess(asn_results, input_data)\n # Verify Neo4j query was NOT called for unknown ASN", + "detail": "spectragraph-transforms.tests.transforms.ip.ip_to_asn", + "documentation": {} + }, + { + "label": "logger", + "kind": 5, + "importPath": "spectragraph-transforms.tests.transforms.ip.ip_to_asn", + "description": "spectragraph-transforms.tests.transforms.ip.ip_to_asn", + "peekOfCode": "logger = TestLogger()\n# The transform will get a mock logger from conftest.py automatically\ntransform = IpToAsnTransform(\"sketch_123\", \"scan_123\", logger)\ndef test_preprocess_valid_ips():\n ips = [\n Ip(address=\"8.8.8.8\"),\n Ip(address=\"1.1.1.1\"),\n ]\n result = transform.preprocess(ips)\n result_addresses = [ip.address for ip in result]", + "detail": "spectragraph-transforms.tests.transforms.ip.ip_to_asn", + "documentation": {} + }, + { + "label": "transform", + "kind": 5, + "importPath": "spectragraph-transforms.tests.transforms.ip.ip_to_asn", + "description": "spectragraph-transforms.tests.transforms.ip.ip_to_asn", + "peekOfCode": "transform = IpToAsnTransform(\"sketch_123\", \"scan_123\", logger)\ndef test_preprocess_valid_ips():\n ips = [\n Ip(address=\"8.8.8.8\"),\n Ip(address=\"1.1.1.1\"),\n ]\n result = transform.preprocess(ips)\n result_addresses = [ip.address for ip in result]\n expected_addresses = [ip.address for ip in ips]\n assert result_addresses == expected_addresses", + "detail": "spectragraph-transforms.tests.transforms.ip.ip_to_asn", + "documentation": {} + }, + { + "label": "test_preprocess_valid_ips", + "kind": 2, + "importPath": "spectragraph-transforms.tests.transforms.ip.ip_to_infos", + "description": "spectragraph-transforms.tests.transforms.ip.ip_to_infos", + "peekOfCode": "def test_preprocess_valid_ips():\n ips = [\n Ip(address=\"8.8.8.8\"),\n Ip(address=\"1.1.1.1\"),\n ]\n result = transform.preprocess(ips)\n result_ips = [d.address for d in result]\n expected_ips = [d.address for d in ips]\n assert result_ips == expected_ips\ndef test_preprocess_string_ips():", + "detail": "spectragraph-transforms.tests.transforms.ip.ip_to_infos", + "documentation": {} + }, + { + "label": "test_preprocess_string_ips", + "kind": 2, + "importPath": "spectragraph-transforms.tests.transforms.ip.ip_to_infos", + "description": "spectragraph-transforms.tests.transforms.ip.ip_to_infos", + "peekOfCode": "def test_preprocess_string_ips():\n ips = [\n \"8.8.8.8\",\n \"1.1.1.1\",\n ]\n result = transform.preprocess(ips)\n result_ips = [d.address for d in result]\n expected_ips = [d for d in ips]\n assert [ip.address for ip in result] == expected_ips\ndef test_preprocess_invalid_ips():", + "detail": "spectragraph-transforms.tests.transforms.ip.ip_to_infos", + "documentation": {} + }, + { + "label": "test_preprocess_invalid_ips", + "kind": 2, + "importPath": "spectragraph-transforms.tests.transforms.ip.ip_to_infos", + "description": "spectragraph-transforms.tests.transforms.ip.ip_to_infos", + "peekOfCode": "def test_preprocess_invalid_ips():\n ips = [\n Ip(address=\"8.8.8.8\"),\n Ip(address=\"invalid_ip\"),\n Ip(address=\"1.1.1.1\"),\n ]\n result = transform.preprocess(ips)\n result_ips = [d.address for d in result]\n assert \"8.8.8.8\" in result_ips\n assert \"1.1.1.1\" in result_ips", + "detail": "spectragraph-transforms.tests.transforms.ip.ip_to_infos", + "documentation": {} + }, + { + "label": "test_preprocess_multiple_formats", + "kind": 2, + "importPath": "spectragraph-transforms.tests.transforms.ip.ip_to_infos", + "description": "spectragraph-transforms.tests.transforms.ip.ip_to_infos", + "peekOfCode": "def test_preprocess_multiple_formats():\n ips = [\n {\"address\": \"8.8.8.8\"},\n {\"invalid_key\": \"1.2.3.4\"},\n Ip(address=\"1.1.1.1\"),\n \"1.1.1.1\",\n ]\n result = transform.preprocess(ips)\n result_ips = [d.address for d in result]\n assert \"8.8.8.8\" in result_ips", + "detail": "spectragraph-transforms.tests.transforms.ip.ip_to_infos", + "documentation": {} + }, + { + "label": "test_scan_returns_ip", + "kind": 2, + "importPath": "spectragraph-transforms.tests.transforms.ip.ip_to_infos", + "description": "spectragraph-transforms.tests.transforms.ip.ip_to_infos", + "peekOfCode": "def test_scan_returns_ip(monkeypatch):\n # Mock of get_location_data\n def mock_get_location_data(address):\n return {\n \"latitude\": 37.386,\n \"longitude\": -122.0838,\n \"country\": \"US\",\n \"city\": \"Mountain View\",\n \"isp\": \"Google LLC\",\n }", + "detail": "spectragraph-transforms.tests.transforms.ip.ip_to_infos", + "documentation": {} + }, + { + "label": "test_schemas", + "kind": 2, + "importPath": "spectragraph-transforms.tests.transforms.ip.ip_to_infos", + "description": "spectragraph-transforms.tests.transforms.ip.ip_to_infos", + "peekOfCode": "def test_schemas():\n input_schema = transform.input_schema()\n output_schema = transform.output_schema()\n assert input_schema == {\n \"type\": \"Ip\",\n \"properties\": [\n {\"name\": \"address\", \"type\": \"string\"},\n {\"name\": \"latitude\", \"type\": \"number | null\"},\n {\"name\": \"longitude\", \"type\": \"number | null\"},\n {\"name\": \"country\", \"type\": \"string | null\"},", + "detail": "spectragraph-transforms.tests.transforms.ip.ip_to_infos", + "documentation": {} + }, + { + "label": "transform", + "kind": 5, + "importPath": "spectragraph-transforms.tests.transforms.ip.ip_to_infos", + "description": "spectragraph-transforms.tests.transforms.ip.ip_to_infos", + "peekOfCode": "transform = IpToInfosTransform(\"sketch_123\", \"scan_123\")\ndef test_preprocess_valid_ips():\n ips = [\n Ip(address=\"8.8.8.8\"),\n Ip(address=\"1.1.1.1\"),\n ]\n result = transform.preprocess(ips)\n result_ips = [d.address for d in result]\n expected_ips = [d.address for d in ips]\n assert result_ips == expected_ips", + "detail": "spectragraph-transforms.tests.transforms.ip.ip_to_infos", + "documentation": {} + }, + { + "label": "test_preprocess_valid_names", + "kind": 2, + "importPath": "spectragraph-transforms.tests.transforms.organization.to_infos", + "description": "spectragraph-transforms.tests.transforms.organization.to_infos", + "peekOfCode": "def test_preprocess_valid_names():\n data = [Organization(name=\"OpenAI\"), {\"name\": \"Inria\"}, \"OVH\"]\n result = transform.preprocess(data)\n result_names = [org.name for org in result]\n assert result_names == [\"OpenAI\", \"Inria\", \"OVH\"]\n# def test_preprocess_invalid_entries():\n# data = [\n# {\"wrong_key\": \"value\"},\n# 123,\n# None,", + "detail": "spectragraph-transforms.tests.transforms.organization.to_infos", + "documentation": {} + }, + { + "label": "test_execute", + "kind": 2, + "importPath": "spectragraph-transforms.tests.transforms.organization.to_infos", + "description": "spectragraph-transforms.tests.transforms.organization.to_infos", + "peekOfCode": "def test_execute():\n transform.execute([\"Karim Terrache\"])\n assert True", + "detail": "spectragraph-transforms.tests.transforms.organization.to_infos", + "documentation": {} + }, + { + "label": "transform", + "kind": 5, + "importPath": "spectragraph-transforms.tests.transforms.organization.to_infos", + "description": "spectragraph-transforms.tests.transforms.organization.to_infos", + "peekOfCode": "transform = OrgToInfosTransform(\"sketch_123\", \"scan_123\")\ndef test_preprocess_valid_names():\n data = [Organization(name=\"OpenAI\"), {\"name\": \"Inria\"}, \"OVH\"]\n result = transform.preprocess(data)\n result_names = [org.name for org in result]\n assert result_names == [\"OpenAI\", \"Inria\", \"OVH\"]\n# def test_preprocess_invalid_entries():\n# data = [\n# {\"wrong_key\": \"value\"},\n# 123,", + "detail": "spectragraph-transforms.tests.transforms.organization.to_infos", + "documentation": {} + }, + { + "label": "test_unprocessed_valid_usernames", + "kind": 2, + "importPath": "spectragraph-transforms.tests.transforms.social.maigret", + "description": "spectragraph-transforms.tests.transforms.social.maigret", + "peekOfCode": "def test_unprocessed_valid_usernames():\n usernames = [\n \"toto123\",\n \"DorianXd78\",\n ]\n result = transform.preprocess(usernames)\n result_usernames = [d for d in result]\n expected_usernames = [SocialProfile(username=d) for d in usernames]\n assert result_usernames == expected_usernames\ndef test_preprocess_invalid_usernames():", + "detail": "spectragraph-transforms.tests.transforms.social.maigret", + "documentation": {} + }, + { + "label": "test_preprocess_invalid_usernames", + "kind": 2, + "importPath": "spectragraph-transforms.tests.transforms.social.maigret", + "description": "spectragraph-transforms.tests.transforms.social.maigret", + "peekOfCode": "def test_preprocess_invalid_usernames():\n usernames = [\n SocialProfile(username=\"toto123\"),\n SocialProfile(username=\"DorianXd78_Official\"),\n SocialProfile(username=\"This is not a username\"),\n ]\n result = transform.preprocess(usernames)\n result_usernames = [d.username for d in result]\n assert \"toto123\" in result_usernames\n assert \"DorianXd78_Official\" in result_usernames", + "detail": "spectragraph-transforms.tests.transforms.social.maigret", + "documentation": {} + }, + { + "label": "test_preprocess_multiple_formats", + "kind": 2, + "importPath": "spectragraph-transforms.tests.transforms.social.maigret", + "description": "spectragraph-transforms.tests.transforms.social.maigret", + "peekOfCode": "def test_preprocess_multiple_formats():\n usernames = [\n {\"username\": \"toto123\"},\n {\"invalid_key\": \"ValId_UseRnAme\"},\n SocialProfile(username=\"DorianXd78_Official\"),\n \"MySimpleUsername\",\n ]\n result = transform.preprocess(usernames)\n result_usernames = [d.username for d in result]\n assert \"toto123\" in result_usernames", + "detail": "spectragraph-transforms.tests.transforms.social.maigret", + "documentation": {} + }, + { + "label": "test_parsing_invalid_output_file", + "kind": 2, + "importPath": "spectragraph-transforms.tests.transforms.social.maigret", + "description": "spectragraph-transforms.tests.transforms.social.maigret", + "peekOfCode": "def test_parsing_invalid_output_file():\n results = transform.parse_maigret_output(\"toto123\", Path(\"/this/path/does/not/exist\"))\n assert results == []\ndef test_parsing():\n results = transform.parse_maigret_output(\"toto123\", Path(\"/tmp/maigret_test.json\"))\n print(results)\n assert len(results) == 2", + "detail": "spectragraph-transforms.tests.transforms.social.maigret", + "documentation": {} + }, + { + "label": "test_parsing", + "kind": 2, + "importPath": "spectragraph-transforms.tests.transforms.social.maigret", + "description": "spectragraph-transforms.tests.transforms.social.maigret", + "peekOfCode": "def test_parsing():\n results = transform.parse_maigret_output(\"toto123\", Path(\"/tmp/maigret_test.json\"))\n print(results)\n assert len(results) == 2", + "detail": "spectragraph-transforms.tests.transforms.social.maigret", + "documentation": {} + }, + { + "label": "transform", + "kind": 5, + "importPath": "spectragraph-transforms.tests.transforms.social.maigret", + "description": "spectragraph-transforms.tests.transforms.social.maigret", + "peekOfCode": "transform = MaigretTransform(\"sketch_123\", \"scan_123\")\ndef test_unprocessed_valid_usernames():\n usernames = [\n \"toto123\",\n \"DorianXd78\",\n ]\n result = transform.preprocess(usernames)\n result_usernames = [d for d in result]\n expected_usernames = [SocialProfile(username=d) for d in usernames]\n assert result_usernames == expected_usernames", + "detail": "spectragraph-transforms.tests.transforms.social.maigret", + "documentation": {} + }, + { + "label": "MockCrawlResults", + "kind": 6, + "importPath": "spectragraph-transforms.tests.transforms.website.to_links", + "description": "spectragraph-transforms.tests.transforms.website.to_links", + "peekOfCode": "class MockCrawlResults:\n def __init__(self, internal=None, external=None):\n self.internal = internal or []\n self.external = external or []\nclass MockCrawler:\n def __init__(self, url, recursive=True, verbose=False, _on_result_callback=None):\n self.url = url\n self.callback = _on_result_callback\n def fetch(self):\n pass", + "detail": "spectragraph-transforms.tests.transforms.website.to_links", + "documentation": {} + }, + { + "label": "MockCrawler", + "kind": 6, + "importPath": "spectragraph-transforms.tests.transforms.website.to_links", + "description": "spectragraph-transforms.tests.transforms.website.to_links", + "peekOfCode": "class MockCrawler:\n def __init__(self, url, recursive=True, verbose=False, _on_result_callback=None):\n self.url = url\n self.callback = _on_result_callback\n def fetch(self):\n pass\n def extract_urls(self):\n # Simulate callback calls\n if self.callback:\n self.callback(\"https://example.com/page1\", is_external=False)", + "detail": "spectragraph-transforms.tests.transforms.website.to_links", + "documentation": {} + }, + { + "label": "test_postprocess_simplified", + "kind": 2, + "importPath": "spectragraph-transforms.tests.transforms.website.to_links", + "description": "spectragraph-transforms.tests.transforms.website.to_links", + "peekOfCode": "def test_postprocess_simplified():\n \"\"\"Test that postprocess now just returns results as-is.\"\"\"\n transform = WebsiteToLinks(sketch_id=\"test\", scan_id=\"test\")\n original_input = [Website(url=\"https://example.com\")]\n results = [\n {\n \"website\": \"https://example.com\",\n \"main_domain\": \"example.com\",\n \"internal_urls\": [\"https://example.com/page1\"],\n \"external_urls\": [\"https://external.com/page\"],", + "detail": "spectragraph-transforms.tests.transforms.website.to_links", + "documentation": {} + }, + { + "label": "mock_logger", + "kind": 2, + "importPath": "spectragraph-transforms.tests.conftest", + "description": "spectragraph-transforms.tests.conftest", + "peekOfCode": "def mock_logger(monkeypatch):\n \"\"\"Automatically replace the production Logger with TestLogger for all tests.\"\"\"\n monkeypatch.setattr(\"spectragraph_core.core.logger.Logger\", TestLogger)\n # Mock the emit_event_task to do nothing\n monkeypatch.setattr(\n \"spectragraph_core.core.logger.emit_event_task.delay\", lambda *args, **kwargs: None\n )", + "detail": "spectragraph-transforms.tests.conftest", + "documentation": {} + }, + { + "label": "TestLogger", + "kind": 6, + "importPath": "spectragraph-transforms.tests.logger", + "description": "spectragraph-transforms.tests.logger", + "peekOfCode": "class TestLogger:\n @staticmethod\n def _format_message(type: str, message: str) -> str:\n \"\"\"Format the log message with type prefix\"\"\"\n return f\"[{type.upper()}] {message}\"\n @staticmethod\n def _create_log(sketch_id: Union[str, UUID], log_type: str, content: str) -> Any:\n \"\"\"Create a dummy log object for testing\"\"\"\n class DummyLog:\n def __init__(self):", + "detail": "spectragraph-transforms.tests.logger", + "documentation": {} + }, + { + "label": "EventLevel", + "kind": 5, + "importPath": "spectragraph-transforms.tests.logger", + "description": "spectragraph-transforms.tests.logger", + "peekOfCode": "EventLevel = Literal[\"info\", \"warn\", \"error\", \"success\", \"debug\"]\nLEVEL_MAP = {\n \"info\": \"INFO\",\n \"warn\": \"WARN\",\n \"error\": \"FAILED\",\n \"success\": \"SUCCESS\",\n \"debug\": \"DEBUG\",\n}\nclass TestLogger:\n @staticmethod", + "detail": "spectragraph-transforms.tests.logger", + "documentation": {} + }, + { + "label": "LEVEL_MAP", + "kind": 5, + "importPath": "spectragraph-transforms.tests.logger", + "description": "spectragraph-transforms.tests.logger", + "peekOfCode": "LEVEL_MAP = {\n \"info\": \"INFO\",\n \"warn\": \"WARN\",\n \"error\": \"FAILED\",\n \"success\": \"SUCCESS\",\n \"debug\": \"DEBUG\",\n}\nclass TestLogger:\n @staticmethod\n def _format_message(type: str, message: str) -> str:", + "detail": "spectragraph-transforms.tests.logger", + "documentation": {} + }, + { + "label": "TestParams", + "kind": 6, + "importPath": "spectragraph-transforms.tests.test_github_repo", + "description": "spectragraph-transforms.tests.test_github_repo", + "peekOfCode": "class TestParams:\n \"\"\"Test parameter validation.\"\"\"\n def test_valid_params(self):\n \"\"\"Test valid parameter combinations.\"\"\"\n # Note: We are testing the Pydantic model directly here\n params = GitHubRepoParams(\n domain=\"example.com\",\n max_repos=25,\n min_stars=10,\n include_forks=True", + "detail": "spectragraph-transforms.tests.test_github_repo", + "documentation": {} + }, + { + "label": "TestPreprocess", + "kind": 6, + "importPath": "spectragraph-transforms.tests.test_github_repo", + "description": "spectragraph-transforms.tests.test_github_repo", + "peekOfCode": "class TestPreprocess:\n \"\"\"Test preprocessing logic.\"\"\"\n @pytest.mark.asyncio\n async def test_success(self, transform):\n \"\"\"Test successful preprocessing.\"\"\"\n # Preprocess converts input list to cleaned list of domains\n input_data = [\"anthropic.com\", {\"domain\": \"example.com\"}]\n result = await transform.preprocess(input_data)\n assert len(result) == 2\n assert \"anthropic.com\" in result", + "detail": "spectragraph-transforms.tests.test_github_repo", + "documentation": {} + }, + { + "label": "TestSearch", + "kind": 6, + "importPath": "spectragraph-transforms.tests.test_github_repo", + "description": "spectragraph-transforms.tests.test_github_repo", + "peekOfCode": "class TestSearch:\n \"\"\"Test organization search.\"\"\"\n @pytest.mark.asyncio\n async def test_search_organizations(self, transform, mock_org_response):\n \"\"\"Test successful organization search.\"\"\"\n mock_response = MagicMock()\n mock_response.json.return_value = {\n \"items\": [{\"login\": \"anthropics\", \"type\": \"Organization\"}]\n }\n mock_response.raise_for_status = MagicMock()", + "detail": "spectragraph-transforms.tests.test_github_repo", + "documentation": {} + }, + { + "label": "TestRepositories", + "kind": 6, + "importPath": "spectragraph-transforms.tests.test_github_repo", + "description": "spectragraph-transforms.tests.test_github_repo", + "peekOfCode": "class TestRepositories:\n \"\"\"Test repository retrieval.\"\"\"\n @pytest.mark.asyncio\n async def test_get_repositories(self, transform, mock_repo_response):\n \"\"\"Test successful repository retrieval.\"\"\"\n mock_response = MagicMock()\n mock_response.json.return_value = [mock_repo_response]\n mock_response.raise_for_status = MagicMock()\n mock_client = AsyncMock()\n mock_client.get.return_value = mock_response", + "detail": "spectragraph-transforms.tests.test_github_repo", + "documentation": {} + }, + { + "label": "TestFullScan", + "kind": 6, + "importPath": "spectragraph-transforms.tests.test_github_repo", + "description": "spectragraph-transforms.tests.test_github_repo", + "peekOfCode": "class TestFullScan:\n \"\"\"Test complete scan workflow.\"\"\"\n @pytest.mark.asyncio\n async def test_successful_scan(self, transform, mock_org_response, mock_repo_response):\n \"\"\"Test complete scan execution.\"\"\"\n with patch('httpx.AsyncClient') as mock_client_class:\n mock_client = AsyncMock()\n mock_client_class.return_value.__aenter__.return_value = mock_client\n with patch.object(transform, '_search_organizations', return_value=[mock_org_response]), \\\n patch.object(transform, '_get_org_repositories', return_value=[mock_repo_response]), \\", + "detail": "spectragraph-transforms.tests.test_github_repo", + "documentation": {} + }, + { + "label": "transform", + "kind": 2, + "importPath": "spectragraph-transforms.tests.test_github_repo", + "description": "spectragraph-transforms.tests.test_github_repo", + "peekOfCode": "def transform():\n \"\"\"Create transform instance.\"\"\"\n t = GitHubRepoTransform()\n # Mock params to simulate async_init resolution\n t.params = {\"github_token\": \"ghp_fake_token\"} \n return t\n@pytest.fixture\ndef sample_params():\n \"\"\"Sample valid parameters.\"\"\"\n return {", + "detail": "spectragraph-transforms.tests.test_github_repo", + "documentation": {} + }, + { + "label": "sample_params", + "kind": 2, + "importPath": "spectragraph-transforms.tests.test_github_repo", + "description": "spectragraph-transforms.tests.test_github_repo", + "peekOfCode": "def sample_params():\n \"\"\"Sample valid parameters.\"\"\"\n return {\n \"domain\": \"anthropic.com\",\n \"include_forks\": False,\n \"max_repos\": 10,\n \"min_stars\": 0,\n \"language_filter\": None\n }\n@pytest.fixture", + "detail": "spectragraph-transforms.tests.test_github_repo", + "documentation": {} + }, + { + "label": "mock_org_response", + "kind": 2, + "importPath": "spectragraph-transforms.tests.test_github_repo", + "description": "spectragraph-transforms.tests.test_github_repo", + "peekOfCode": "def mock_org_response():\n \"\"\"Mock GitHub organization API response.\"\"\"\n return {\n \"login\": \"anthropics\",\n \"name\": \"Anthropic\",\n \"description\": \"AI safety company\",\n \"blog\": \"anthropic.com\",\n \"location\": \"San Francisco\",\n \"email\": \"hello@anthropic.com\",\n \"twitter_username\": \"AnthropicAI\",", + "detail": "spectragraph-transforms.tests.test_github_repo", + "documentation": {} + }, + { + "label": "mock_repo_response", + "kind": 2, + "importPath": "spectragraph-transforms.tests.test_github_repo", + "description": "spectragraph-transforms.tests.test_github_repo", + "peekOfCode": "def mock_repo_response():\n \"\"\"Mock GitHub repository API response.\"\"\"\n return {\n \"name\": \"claude-api\",\n \"full_name\": \"anthropics/claude-api\",\n \"description\": \"Python client for Claude API\",\n \"html_url\": \"https://github.com/anthropics/claude-api\",\n \"homepage\": \"https://anthropic.com\",\n \"language\": \"Python\",\n \"stargazers_count\": 3400,", + "detail": "spectragraph-transforms.tests.test_github_repo", + "documentation": {} + }, + { + "label": "TestWhoxyTransformsVaultIntegration", + "kind": 6, + "importPath": "spectragraph-transforms.tests.test_vault_integration", + "description": "spectragraph-transforms.tests.test_vault_integration", + "peekOfCode": "class TestWhoxyTransformsVaultIntegration:\n \"\"\"Tests for WHOXY transforms vault integration.\"\"\"\n @pytest.mark.asyncio\n async def test_domain_to_history_gets_api_key_from_vault(\n self, mock_vault, sketch_id\n ):\n \"\"\"Test that domain_to_history retrieves WHOXY_API_KEY from vault.\"\"\"\n api_key = \"whoxy-api-key-12345\"\n mock_vault.get_secret.return_value = api_key\n transform = DomainToHistoryTransform(", + "detail": "spectragraph-transforms.tests.test_vault_integration", + "documentation": {} + }, + { + "label": "TestEtherscanTransformsVaultIntegration", + "kind": 6, + "importPath": "spectragraph-transforms.tests.test_vault_integration", + "description": "spectragraph-transforms.tests.test_vault_integration", + "peekOfCode": "class TestEtherscanTransformsVaultIntegration:\n \"\"\"Tests for Etherscan transforms vault integration.\"\"\"\n @pytest.mark.asyncio\n async def test_wallet_to_nfts_gets_api_key_from_vault(self, mock_vault, sketch_id):\n \"\"\"Test that wallet_to_nfts retrieves ETHERSCAN_API_KEY from vault.\"\"\"\n api_key = \"etherscan-api-key-12345\"\n mock_vault.get_secret.return_value = api_key\n transform = CryptoWalletAddressToNFTs(\n sketch_id=sketch_id, scan_id=\"scan_123\", vault=mock_vault, params={}\n )", + "detail": "spectragraph-transforms.tests.test_vault_integration", + "documentation": {} + }, + { + "label": "TestHIBPTransformsVaultIntegration", + "kind": 6, + "importPath": "spectragraph-transforms.tests.test_vault_integration", + "description": "spectragraph-transforms.tests.test_vault_integration", + "peekOfCode": "class TestHIBPTransformsVaultIntegration:\n \"\"\"Tests for HIBP transforms vault integration.\"\"\"\n @pytest.mark.asyncio\n async def test_email_to_breaches_gets_api_key_from_vault(\n self, mock_vault, sketch_id\n ):\n \"\"\"Test that email_to_breaches retrieves HIBP_API_KEY from vault.\"\"\"\n api_key = \"hibp-api-key-12345\"\n mock_vault.get_secret.return_value = api_key\n transform = EmailToBreachesTransform(", + "detail": "spectragraph-transforms.tests.test_vault_integration", + "documentation": {} + }, + { + "label": "TestVaultSecretWithUserProvidedID", + "kind": 6, + "importPath": "spectragraph-transforms.tests.test_vault_integration", + "description": "spectragraph-transforms.tests.test_vault_integration", + "peekOfCode": "class TestVaultSecretWithUserProvidedID:\n \"\"\"Tests for vault secrets when user provides a specific vault ID.\"\"\"\n @pytest.mark.asyncio\n async def test_transform_uses_user_provided_vault_id(self, mock_vault, sketch_id):\n \"\"\"Test that transform uses user-provided vault ID if specified.\"\"\"\n vault_id = str(uuid.uuid4())\n api_key = \"whoxy-api-key-12345\"\n # First call (by ID) returns the secret\n mock_vault.get_secret.return_value = api_key\n transform = DomainToHistoryTransform(", + "detail": "spectragraph-transforms.tests.test_vault_integration", + "documentation": {} + }, + { + "label": "TestMissingRequiredVaultSecret", + "kind": 6, + "importPath": "spectragraph-transforms.tests.test_vault_integration", + "description": "spectragraph-transforms.tests.test_vault_integration", + "peekOfCode": "class TestMissingRequiredVaultSecret:\n \"\"\"Tests for error handling when required vault secrets are missing.\"\"\"\n @pytest.mark.asyncio\n async def test_missing_required_secret_logs_error(self, mock_vault, sketch_id):\n \"\"\"Test that missing required secret logs an error message.\"\"\"\n # Vault returns None (secret not found)\n mock_vault.get_secret.return_value = None\n from unittest.mock import patch\n with patch(\"spectragraph_core.core.transform_base.Logger\") as mock_logger:\n transform = DomainToHistoryTransform(", + "detail": "spectragraph-transforms.tests.test_vault_integration", + "documentation": {} + }, + { + "label": "mock_vault", + "kind": 2, + "importPath": "spectragraph-transforms.tests.test_vault_integration", + "description": "spectragraph-transforms.tests.test_vault_integration", + "peekOfCode": "def mock_vault():\n \"\"\"Create a mock vault instance.\"\"\"\n vault = Mock()\n vault.get_secret = Mock()\n return vault\n@pytest.fixture\ndef sketch_id():\n \"\"\"Create a test sketch ID.\"\"\"\n return str(uuid.uuid4())\nclass TestWhoxyTransformsVaultIntegration:", + "detail": "spectragraph-transforms.tests.test_vault_integration", + "documentation": {} + }, + { + "label": "sketch_id", + "kind": 2, + "importPath": "spectragraph-transforms.tests.test_vault_integration", + "description": "spectragraph-transforms.tests.test_vault_integration", + "peekOfCode": "def sketch_id():\n \"\"\"Create a test sketch ID.\"\"\"\n return str(uuid.uuid4())\nclass TestWhoxyTransformsVaultIntegration:\n \"\"\"Tests for WHOXY transforms vault integration.\"\"\"\n @pytest.mark.asyncio\n async def test_domain_to_history_gets_api_key_from_vault(\n self, mock_vault, sketch_id\n ):\n \"\"\"Test that domain_to_history retrieves WHOXY_API_KEY from vault.\"\"\"", + "detail": "spectragraph-transforms.tests.test_vault_integration", + "documentation": {} + }, + { + "label": "Location", + "kind": 6, + "importPath": "spectragraph-types.src.spectragraph_types.address", + "description": "spectragraph-types.src.spectragraph_types.address", + "peekOfCode": "class Location(BaseModel):\n \"\"\"Represents a physical address with geographical coordinates.\"\"\"\n address: str = Field(..., description=\"Street address\", title=\"Street Address\")\n city: str = Field(..., description=\"City name\", title=\"City\")\n country: str = Field(..., description=\"Country name\", title=\"Country\")\n zip: str = Field(..., description=\"ZIP or postal code\", title=\"ZIP/Postal Code\")\n latitude: Optional[float] = Field(\n None, description=\"Latitude coordinate of the address\", title=\"Latitude\"\n )\n longitude: Optional[float] = Field(", + "detail": "spectragraph-types.src.spectragraph_types.address", + "documentation": {} + }, + { + "label": "Affiliation", + "kind": 6, + "importPath": "spectragraph-types.src.spectragraph_types.affiliation", + "description": "spectragraph-types.src.spectragraph_types.affiliation", + "peekOfCode": "class Affiliation(BaseModel):\n \"\"\"Represents an organizational affiliation or employment relationship.\"\"\"\n organization: str = Field(\n ..., description=\"Organization or group name\", title=\"Organization\"\n )\n role: Optional[str] = Field(\n None, description=\"Role or position within organization\", title=\"Role\"\n )\n start_date: Optional[str] = Field(\n None, description=\"Start date of affiliation\", title=\"Start Date\"", + "detail": "spectragraph-types.src.spectragraph_types.affiliation", + "documentation": {} + }, + { + "label": "Alias", + "kind": 6, + "importPath": "spectragraph-types.src.spectragraph_types.alias", + "description": "spectragraph-types.src.spectragraph_types.alias", + "peekOfCode": "class Alias(BaseModel):\n \"\"\"Represents an alias or alternative name used by an entity.\"\"\"\n alias: str = Field(..., description=\"Alias or alternative name\", title=\"Alias\")\n type: Optional[str] = Field(\n None,\n description=\"Type of alias (nickname, code name, etc.)\",\n title=\"Alias Type\",\n )\n context: Optional[str] = Field(\n None, description=\"Context where alias is used\", title=\"Context\"", + "detail": "spectragraph-types.src.spectragraph_types.alias", + "documentation": {} + }, + { + "label": "ASN", + "kind": 6, + "importPath": "spectragraph-types.src.spectragraph_types.asn", + "description": "spectragraph-types.src.spectragraph_types.asn", + "peekOfCode": "class ASN(BaseModel):\n \"\"\"Represents an Autonomous System Number with associated network information.\"\"\"\n number: int = Field(\n ..., description=\"Autonomous System Number (e.g., 15169)\", title=\"ASN Number\"\n )\n name: Optional[str] = Field(\n None,\n description=\"Name of the organization owning the ASN\",\n title=\"Organization Name\",\n )", + "detail": "spectragraph-types.src.spectragraph_types.asn", + "documentation": {} + }, + { + "label": "BankAccount", + "kind": 6, + "importPath": "spectragraph-types.src.spectragraph_types.bank_account", + "description": "spectragraph-types.src.spectragraph_types.bank_account", + "peekOfCode": "class BankAccount(BaseModel):\n \"\"\"Represents a bank account with financial and security information.\"\"\"\n account_number: str = Field(\n ..., description=\"Bank account number\", title=\"Account Number\"\n )\n bank_name: Optional[str] = Field(None, description=\"Bank name\", title=\"Bank Name\")\n account_type: Optional[str] = Field(\n None,\n description=\"Type of account (checking, savings, etc.)\",\n title=\"Account Type\",", + "detail": "spectragraph-types.src.spectragraph_types.bank_account", + "documentation": {} + }, + { + "label": "FingerprintBase", + "kind": 6, + "importPath": "spectragraph-types.src.spectragraph_types.base", + "description": "spectragraph-types.src.spectragraph_types.base", + "peekOfCode": "class FingerprintBase(BaseModel):\n \"\"\"\n Base class for entities that require deterministic fingerprinting.\n \"\"\"\n def _fingerprint_payload(self) -> dict:\n \"\"\"\n Override in child classes to control fingerprint inputs.\n \"\"\"\n return self.model_dump(exclude_none=True)\n def fingerprint(self) -> str:", + "detail": "spectragraph-types.src.spectragraph_types.base", + "documentation": {} + }, + { + "label": "Breach", + "kind": 6, + "importPath": "spectragraph-types.src.spectragraph_types.breach", + "description": "spectragraph-types.src.spectragraph_types.breach", + "peekOfCode": "class Breach(BaseModel):\n \"\"\"Represents a data breach incident with affected accounts and details.\"\"\"\n name: str = Field(\n ..., description=\"The name of the breach or service\", title=\"Breach Name\"\n )\n title: Optional[str] = Field(\n None, description=\"Title of the breach\", title=\"Breach Title\"\n )\n domain: Optional[str] = Field(\n None, description=\"Domain of the breached service\", title=\"Domain\"", + "detail": "spectragraph-types.src.spectragraph_types.breach", + "documentation": {} + }, + { + "label": "CIDR", + "kind": 6, + "importPath": "spectragraph-types.src.spectragraph_types.cidr", + "description": "spectragraph-types.src.spectragraph_types.cidr", + "peekOfCode": "class CIDR(BaseModel):\n \"\"\"Represents a CIDR (Classless Inter-Domain Routing) network block.\"\"\"\n network: IPvAnyNetwork = Field(\n ..., description=\"CIDR block (e.g., 8.8.8.0/24)\", title=\"Network Block\"\n )", + "detail": "spectragraph-types.src.spectragraph_types.cidr", + "documentation": {} + }, + { + "label": "Credential", + "kind": 6, + "importPath": "spectragraph-types.src.spectragraph_types.credential", + "description": "spectragraph-types.src.spectragraph_types.credential", + "peekOfCode": "class Credential(BaseModel):\n \"\"\"Represents user credentials with compromise and usage information.\"\"\"\n username: str = Field(..., description=\"Username or identifier\", title=\"Username\")\n service: Optional[str] = Field(\n None,\n description=\"Service or platform where credential is used\",\n title=\"Service\",\n )\n type: Optional[str] = Field(\n None,", + "detail": "spectragraph-types.src.spectragraph_types.credential", + "documentation": {} + }, + { + "label": "CreditCard", + "kind": 6, + "importPath": "spectragraph-types.src.spectragraph_types.credit_card", + "description": "spectragraph-types.src.spectragraph_types.credit_card", + "peekOfCode": "class CreditCard(BaseModel):\n \"\"\"Represents a credit card with financial details and security status.\"\"\"\n card_number: str = Field(..., description=\"Credit card number\", title=\"Card Number\")\n card_type: Optional[str] = Field(\n None, description=\"Type of card (Visa, Mastercard, etc.)\", title=\"Card Type\"\n )\n issuer: Optional[str] = Field(None, description=\"Card issuer bank\", title=\"Issuer\")\n expiry_date: Optional[str] = Field(\n None, description=\"Card expiry date\", title=\"Expiry Date\"\n )", + "detail": "spectragraph-types.src.spectragraph_types.credit_card", + "documentation": {} + }, + { + "label": "Device", + "kind": 6, + "importPath": "spectragraph-types.src.spectragraph_types.device", + "description": "spectragraph-types.src.spectragraph_types.device", + "peekOfCode": "class Device(BaseModel):\n \"\"\"Represents a device with hardware, software, and network information.\"\"\"\n device_id: str = Field(\n ..., description=\"Unique device identifier\", title=\"Device ID\"\n )\n type: Optional[str] = Field(\n None,\n description=\"Type of device (mobile, desktop, server, etc.)\",\n title=\"Device Type\",\n )", + "detail": "spectragraph-types.src.spectragraph_types.device", + "documentation": {} + }, + { + "label": "DNSRecord", + "kind": 6, + "importPath": "spectragraph-types.src.spectragraph_types.dns_record", + "description": "spectragraph-types.src.spectragraph_types.dns_record", + "peekOfCode": "class DNSRecord(BaseModel):\n \"\"\"Represents a DNS record with type, value, and security information.\"\"\"\n record_type: str = Field(\n ...,\n description=\"Type of DNS record (A, AAAA, CNAME, MX, etc.)\",\n title=\"Record Type\",\n )\n name: str = Field(..., description=\"Domain name\", title=\"Domain Name\")\n value: str = Field(..., description=\"Record value\", title=\"Record Value\")\n ttl: Optional[int] = Field(None, description=\"Time to live in seconds\", title=\"TTL\")", + "detail": "spectragraph-types.src.spectragraph_types.dns_record", + "documentation": {} + }, + { + "label": "Document", + "kind": 6, + "importPath": "spectragraph-types.src.spectragraph_types.document", + "description": "spectragraph-types.src.spectragraph_types.document", + "peekOfCode": "class Document(BaseModel):\n \"\"\"Represents a document with metadata, security, and content information.\"\"\"\n title: str = Field(..., description=\"Document title\", title=\"Title\")\n doc_type: Optional[str] = Field(\n None, description=\"Type of document (PDF, DOC, etc.)\", title=\"Document Type\"\n )\n file_size: Optional[int] = Field(\n None, description=\"File size in bytes\", title=\"File Size\"\n )\n created_date: Optional[str] = Field(", + "detail": "spectragraph-types.src.spectragraph_types.document", + "documentation": {} + }, + { + "label": "Domain", + "kind": 6, + "importPath": "spectragraph-types.src.spectragraph_types.domain", + "description": "spectragraph-types.src.spectragraph_types.domain", + "peekOfCode": "class Domain(FingerprintBase):\n \"\"\"Represents a domain name and its properties.\"\"\"\n domain: str = Field(..., description=\"Domain name\", title=\"Domain Name\")\n root: Optional[bool] = Field(\n True, description=\"Is root or not\", title=\"Is Root Domain\"\n )\n def _fingerprint_payload(self) -> dict:\n return{ \n \"domain\":\n self.domain.strip().lower()", + "detail": "spectragraph-types.src.spectragraph_types.domain", + "documentation": {} + }, + { + "label": "Email", + "kind": 6, + "importPath": "spectragraph-types.src.spectragraph_types.email", + "description": "spectragraph-types.src.spectragraph_types.email", + "peekOfCode": "class Email(BaseModel):\n \"\"\"Represents an email address.\"\"\"\n email: str = Field(..., description=\"Email address\", title=\"Email Address\")", + "detail": "spectragraph-types.src.spectragraph_types.email", + "documentation": {} + }, + { + "label": "File", + "kind": 6, + "importPath": "spectragraph-types.src.spectragraph_types.file", + "description": "spectragraph-types.src.spectragraph_types.file", + "peekOfCode": "class File(BaseModel):\n \"\"\"Represents a file with metadata, type information, and security assessment.\"\"\"\n filename: str = Field(..., description=\"File name\", title=\"Filename\")\n file_type: Optional[str] = Field(\n None, description=\"File type or extension\", title=\"File Type\"\n )\n file_size: Optional[int] = Field(\n None, description=\"File size in bytes\", title=\"File Size\"\n )\n created_date: Optional[str] = Field(", + "detail": "spectragraph-types.src.spectragraph_types.file", + "documentation": {} + }, + { + "label": "Gravatar", + "kind": 6, + "importPath": "spectragraph-types.src.spectragraph_types.gravatar", + "description": "spectragraph-types.src.spectragraph_types.gravatar", + "peekOfCode": "class Gravatar(BaseModel):\n \"\"\"Represents a Gravatar profile with image and user information.\"\"\"\n src: HttpUrl = Field(..., description=\"Gravatar image URL\", title=\"Image URL\")\n hash: str = Field(..., description=\"Gravatar hash\", title=\"Hash\")\n size: Optional[int] = Field(\n None, description=\"Image size in pixels\", title=\"Image Size\"\n )\n rating: Optional[str] = Field(\n None, description=\"Content rating (g, pg, r, x)\", title=\"Content Rating\"\n )", + "detail": "spectragraph-types.src.spectragraph_types.gravatar", + "documentation": {} + }, + { + "label": "Individual", + "kind": 6, + "importPath": "spectragraph-types.src.spectragraph_types.individual", + "description": "spectragraph-types.src.spectragraph_types.individual", + "peekOfCode": "class Individual(BaseModel):\n \"\"\"Represents an individual person with comprehensive personal information.\"\"\"\n # Basic Information\n first_name: str = Field(\n ..., description=\"First name of the individual\", title=\"First Name\"\n )\n last_name: str = Field(\n ..., description=\"Last name of the individual\", title=\"Last Name\"\n )\n full_name: str = Field(", + "detail": "spectragraph-types.src.spectragraph_types.individual", + "documentation": {} + }, + { + "label": "Ip", + "kind": 6, + "importPath": "spectragraph-types.src.spectragraph_types.ip", + "description": "spectragraph-types.src.spectragraph_types.ip", + "peekOfCode": "class Ip(BaseModel):\n \"\"\"Represents an IP address with geolocation and ISP information.\"\"\"\n address: str = Field(..., description=\"IP address\", title=\"IP Address\")\n latitude: Optional[float] = Field(\n None, description=\"Latitude coordinate of the IP location\", title=\"Latitude\"\n )\n longitude: Optional[float] = Field(\n None, description=\"Longitude coordinate of the IP location\", title=\"Longitude\"\n )\n country: Optional[str] = Field(", + "detail": "spectragraph-types.src.spectragraph_types.ip", + "documentation": {} + }, + { + "label": "Leak", + "kind": 6, + "importPath": "spectragraph-types.src.spectragraph_types.leak", + "description": "spectragraph-types.src.spectragraph_types.leak", + "peekOfCode": "class Leak(BaseModel):\n \"\"\"Represents a data leak or breach with associated data.\"\"\"\n name: str = Field(\n ..., description=\"The name of the leak or service brea\", title=\"Leak Name\"\n )\n leak: Optional[List[Dict]] = Field(\n None, description=\"List of data leaks found\", title=\"Leak Data\"\n )", + "detail": "spectragraph-types.src.spectragraph_types.leak", + "documentation": {} + }, + { + "label": "Malware", + "kind": 6, + "importPath": "spectragraph-types.src.spectragraph_types.malware", + "description": "spectragraph-types.src.spectragraph_types.malware", + "peekOfCode": "class Malware(BaseModel):\n \"\"\"Represents malware with family, capabilities, and threat intelligence.\"\"\"\n name: str = Field(..., description=\"Malware name or identifier\", title=\"Name\")\n family: Optional[str] = Field(None, description=\"Malware family\", title=\"Family\")\n type: Optional[str] = Field(\n None, description=\"Type of malware (trojan, ransomware, etc.)\", title=\"Type\"\n )\n description: Optional[str] = Field(\n None, description=\"Malware description\", title=\"Description\"\n )", + "detail": "spectragraph-types.src.spectragraph_types.malware", + "documentation": {} + }, + { + "label": "Message", + "kind": 6, + "importPath": "spectragraph-types.src.spectragraph_types.message", + "description": "spectragraph-types.src.spectragraph_types.message", + "peekOfCode": "class Message(BaseModel):\n \"\"\"Represents a message with content, metadata, and security analysis.\"\"\"\n message_id: str = Field(\n ..., description=\"Unique message identifier\", title=\"Message ID\"\n )\n content: str = Field(..., description=\"Message content\", title=\"Content\")\n sender: Optional[str] = Field(None, description=\"Message sender\", title=\"Sender\")\n recipient: Optional[str] = Field(\n None, description=\"Message recipient\", title=\"Recipient\"\n )", + "detail": "spectragraph-types.src.spectragraph_types.message", + "documentation": {} + }, + { + "label": "Organization", + "kind": 6, + "importPath": "spectragraph-types.src.spectragraph_types.organization", + "description": "spectragraph-types.src.spectragraph_types.organization", + "peekOfCode": "class Organization(BaseModel):\n \"\"\"Represents an organization with detailed business and administrative information.\"\"\"\n # Basic information\n name: Any = Field(..., description=\"Organization name\", title=\"Organization Name\")\n siren: Optional[Any] = Field(None, description=\"SIREN number\", title=\"SIREN Number\")\n nom_complet: Optional[Any] = Field(\n None, description=\"Complete name\", title=\"Complete Name\"\n )\n nom_raison_sociale: Optional[Any] = Field(\n None, description=\"Company name\", title=\"Company Name\"", + "detail": "spectragraph-types.src.spectragraph_types.organization", + "documentation": {} + }, + { + "label": "Phone", + "kind": 6, + "importPath": "spectragraph-types.src.spectragraph_types.phone", + "description": "spectragraph-types.src.spectragraph_types.phone", + "peekOfCode": "class Phone(BaseModel):\n \"\"\"Represents a phone number with country and carrier information.\"\"\"\n number: str = Field(..., description=\"Phone number\", title=\"Phone Number\")\n country: Optional[str] = Field(\n None, description=\"Country code (ISO 3166-1 alpha-2)\", title=\"Country Code\"\n )\n carrier: Optional[str] = Field(\n None, description=\"Mobile carrier or service provider\", title=\"Carrier\"\n )", + "detail": "spectragraph-types.src.spectragraph_types.phone", + "documentation": {} + }, + { + "label": "Phrase", + "kind": 6, + "importPath": "spectragraph-types.src.spectragraph_types.phrase", + "description": "spectragraph-types.src.spectragraph_types.phrase", + "peekOfCode": "class Phrase(BaseModel):\n \"\"\"Represents a phrase or text content.\"\"\"\n text: Any = Field(\n ..., description=\"The content of the phrase.\", title=\"Phrase text value.\"\n )", + "detail": "spectragraph-types.src.spectragraph_types.phrase", + "documentation": {} + }, + { + "label": "ReputationScore", + "kind": 6, + "importPath": "spectragraph-types.src.spectragraph_types.reputation_score", + "description": "spectragraph-types.src.spectragraph_types.reputation_score", + "peekOfCode": "class ReputationScore(BaseModel):\n \"\"\"Represents a reputation score for an entity with historical data and trends.\"\"\"\n entity_id: str = Field(..., description=\"Entity identifier\", title=\"Entity ID\")\n entity_type: Optional[str] = Field(\n None,\n description=\"Type of entity (domain, IP, email, etc.)\",\n title=\"Entity Type\",\n )\n score: Optional[float] = Field(\n None, description=\"Reputation score (0-100)\", title=\"Score\"", + "detail": "spectragraph-types.src.spectragraph_types.reputation_score", + "documentation": {} + }, + { + "label": "RiskProfile", + "kind": 6, + "importPath": "spectragraph-types.src.spectragraph_types.risk_profile", + "description": "spectragraph-types.src.spectragraph_types.risk_profile", + "peekOfCode": "class RiskProfile(BaseModel):\n \"\"\"Represents a comprehensive risk assessment profile for an entity.\"\"\"\n entity_id: str = Field(..., description=\"Entity identifier\", title=\"Entity ID\")\n entity_type: Optional[str] = Field(\n None, description=\"Type of entity\", title=\"Entity Type\"\n )\n overall_risk_score: Optional[float] = Field(\n None, description=\"Overall risk score (0-100)\", title=\"Overall Risk Score\"\n )\n risk_level: Optional[str] = Field(", + "detail": "spectragraph-types.src.spectragraph_types.risk_profile", + "documentation": {} + }, + { + "label": "Script", + "kind": 6, + "importPath": "spectragraph-types.src.spectragraph_types.script", + "description": "spectragraph-types.src.spectragraph_types.script", + "peekOfCode": "class Script(BaseModel):\n \"\"\"Represents a script or code file with analysis and security information.\"\"\"\n script_id: str = Field(\n ..., description=\"Unique script identifier\", title=\"Script ID\"\n )\n name: Optional[str] = Field(None, description=\"Script name\", title=\"Name\")\n language: Optional[str] = Field(\n None, description=\"Programming language\", title=\"Language\"\n )\n type: Optional[str] = Field(", + "detail": "spectragraph-types.src.spectragraph_types.script", + "documentation": {} + }, + { + "label": "Session", + "kind": 6, + "importPath": "spectragraph-types.src.spectragraph_types.session", + "description": "spectragraph-types.src.spectragraph_types.session", + "peekOfCode": "class Session(BaseModel):\n \"\"\"Represents a user session with device and activity information.\"\"\"\n session_id: str = Field(\n ..., description=\"Unique session identifier\", title=\"Session ID\"\n )\n user_id: Optional[str] = Field(None, description=\"User identifier\", title=\"User ID\")\n service: Optional[str] = Field(\n None, description=\"Service or platform\", title=\"Service\"\n )\n start_time: Optional[str] = Field(", + "detail": "spectragraph-types.src.spectragraph_types.session", + "documentation": {} + }, + { + "label": "SocialProfile", + "kind": 6, + "importPath": "spectragraph-types.src.spectragraph_types.social", + "description": "spectragraph-types.src.spectragraph_types.social", + "peekOfCode": "class SocialProfile(BaseModel):\n \"\"\"Represents a social media profile with engagement metrics.\"\"\"\n username: str = Field(\n ..., description=\"Username on the social platform\", title=\"Username\"\n )\n profile_url: Optional[str] = Field(\n None, description=\"URL to the user's profile page\", title=\"Profile URL\"\n )\n platform: Optional[str] = Field(\n None, description=\"Name of the social media platform\", title=\"Platform\"", + "detail": "spectragraph-types.src.spectragraph_types.social", + "documentation": {} + }, + { + "label": "SSLCertificate", + "kind": 6, + "importPath": "spectragraph-types.src.spectragraph_types.ssl_certificate", + "description": "spectragraph-types.src.spectragraph_types.ssl_certificate", + "peekOfCode": "class SSLCertificate(BaseModel):\n \"\"\"Represents an SSL/TLS certificate with validation and security details.\"\"\"\n subject: str = Field(\n ..., description=\"Certificate subject (domain name)\", title=\"Subject\"\n )\n issuer: Optional[str] = Field(\n None,\n description=\"Certificate authority that issued the certificate\",\n title=\"Issuer\",\n )", + "detail": "spectragraph-types.src.spectragraph_types.ssl_certificate", + "documentation": {} + }, + { + "label": "Username", + "kind": 6, + "importPath": "spectragraph-types.src.spectragraph_types.username", + "description": "spectragraph-types.src.spectragraph_types.username", + "peekOfCode": "class Username(BaseModel):\n \"\"\"Represents a username or handle on a platform with associated profile information.\"\"\"\n username: str = Field(..., description=\"Username or handle\", title=\"Username\")\n platform: Optional[str] = Field(\n None, description=\"Platform or service where username is used\", title=\"Platform\"\n )\n display_name: Optional[str] = Field(\n None, description=\"Display name associated with username\", title=\"Display Name\"\n )\n created_at: Optional[str] = Field(", + "detail": "spectragraph-types.src.spectragraph_types.username", + "documentation": {} + }, + { + "label": "CryptoWallet", + "kind": 6, + "importPath": "spectragraph-types.src.spectragraph_types.wallet", + "description": "spectragraph-types.src.spectragraph_types.wallet", + "peekOfCode": "class CryptoWallet(BaseModel):\n \"\"\"Represents a cryptocurrency wallet.\"\"\"\n address: str = Field(..., description=\"Wallet address\", title=\"Wallet Address\")\n node_id: Optional[str] = Field(\n None, description=\"Wallet Explorer node ID\", title=\"Node ID\"\n )\nclass CryptoWalletTransaction(BaseModel):\n \"\"\"Represents a cryptocurrency transaction.\"\"\"\n source: CryptoWallet = Field(\n ..., description=\"Source wallet\", title=\"Source Wallet\"", + "detail": "spectragraph-types.src.spectragraph_types.wallet", + "documentation": {} + }, + { + "label": "CryptoWalletTransaction", + "kind": 6, + "importPath": "spectragraph-types.src.spectragraph_types.wallet", + "description": "spectragraph-types.src.spectragraph_types.wallet", + "peekOfCode": "class CryptoWalletTransaction(BaseModel):\n \"\"\"Represents a cryptocurrency transaction.\"\"\"\n source: CryptoWallet = Field(\n ..., description=\"Source wallet\", title=\"Source Wallet\"\n )\n target: Optional[CryptoWallet] = Field(\n None, description=\"Target wallet\", title=\"Target Wallet\"\n )\n hash: Optional[str] = Field(\n None, description=\"Transaction hash\", title=\"Transaction Hash\"", + "detail": "spectragraph-types.src.spectragraph_types.wallet", + "documentation": {} + }, + { + "label": "CryptoNFT", + "kind": 6, + "importPath": "spectragraph-types.src.spectragraph_types.wallet", + "description": "spectragraph-types.src.spectragraph_types.wallet", + "peekOfCode": "class CryptoNFT(BaseModel):\n \"\"\"Represents a Non-Fungible Token (NFT) held or minted by a wallet.\"\"\"\n wallet: CryptoWallet = Field(..., description=\"Source wallet\", title=\"Wallet\")\n contract_address: str = Field(\n ...,\n description=\"Address of the NFT smart contract (ERC-721/1155)\",\n title=\"Contract Address\",\n )\n token_id: str = Field(\n ...,", + "detail": "spectragraph-types.src.spectragraph_types.wallet", + "documentation": {} + }, + { + "label": "Weapon", + "kind": 6, + "importPath": "spectragraph-types.src.spectragraph_types.weapon", + "description": "spectragraph-types.src.spectragraph_types.weapon", + "peekOfCode": "class Weapon(BaseModel):\n \"\"\"Represents a weapon with detailed specifications and forensic information.\"\"\"\n name: str = Field(..., description=\"Weapon name or identifier\", title=\"Name\")\n type: Optional[\n Literal[\n \"firearm\",\n \"melee\",\n \"explosive\",\n \"bladed\",\n \"blunt\",", + "detail": "spectragraph-types.src.spectragraph_types.weapon", + "documentation": {} + }, + { + "label": "WebTracker", + "kind": 6, + "importPath": "spectragraph-types.src.spectragraph_types.web_tracker", + "description": "spectragraph-types.src.spectragraph_types.web_tracker", + "peekOfCode": "class WebTracker(BaseModel):\n \"\"\"Represents a web tracking technology with privacy and compliance information.\"\"\"\n tracker_id: str = Field(\n ..., description=\"Unique tracker identifier\", title=\"Tracker ID\"\n )\n name: Optional[str] = Field(None, description=\"Tracker name\", title=\"Name\")\n type: Optional[str] = Field(\n None, description=\"Type of tracker (analytics, advertising, etc.)\", title=\"Type\"\n )\n domain: Optional[str] = Field(", + "detail": "spectragraph-types.src.spectragraph_types.web_tracker", + "documentation": {} + }, + { + "label": "Website", + "kind": 6, + "importPath": "spectragraph-types.src.spectragraph_types.website", + "description": "spectragraph-types.src.spectragraph_types.website", + "peekOfCode": "class Website(BaseModel):\n \"\"\"Represents a website with its URL, domain, and redirect information.\"\"\"\n url: HttpUrl = Field(\n ..., description=\"Full URL of the website\", title=\"Website URL\"\n )\n redirects: Optional[List[HttpUrl]] = Field(\n [], description=\"List of redirects from the website\", title=\"Redirects\"\n )\n domain: Optional[Domain] = Field(\n None, description=\"Domain information for the website\", title=\"Domain\"", + "detail": "spectragraph-types.src.spectragraph_types.website", + "documentation": {} + }, + { + "label": "Whois", + "kind": 6, + "importPath": "spectragraph-types.src.spectragraph_types.whois", + "description": "spectragraph-types.src.spectragraph_types.whois", + "peekOfCode": "class Whois(BaseModel):\n \"\"\"Represents WHOIS domain registration information.\"\"\"\n domain: str = Field(..., description=\"Domain name\", title=\"Domain\")\n registrar: Optional[str] = Field(\n None, description=\"Domain registrar name\", title=\"Registrar\"\n )\n org: Optional[str] = Field(\n None,\n description=\"Organization name associated with the domain\",\n title=\"Organization\",", + "detail": "spectragraph-types.src.spectragraph_types.whois", + "documentation": {} + } +] \ No newline at end of file diff --git a/README.md b/README.md index 875f718..b4d61df 100644 --- a/README.md +++ b/README.md @@ -1,129 +1,302 @@ -# 🌌 SpectraGraph +
+
+ SpectraGraph
+
+
+
+
+
+
+
+
+
+
+
+
+---
+
+
+
+
+
+
+
+
+
+---
+
+
+
+
+
+
+
+
+
---
+
+
+
+
+
+
+
+
+
+
+
+
+---
+
+
+
## 🗺 SWoC 2026 Roadmap
+
+
- [ ] **Websocket Streams:** Real-time investigation status updates.
+
- [ ] **Transform Marketplace:** Plugin-style architecture for easy community PRs.
+
- [ ] **Visual Overhaul:** Dark-mode "Command Center" UI aesthetics.
+
+
**Contributing:** Please read [CONTRIBUTING.md](./CONTRIBUTING.md) and look for the `SWoC` label on issues!
+
+
---
+
+
+### 🌟 Hall of Fame
+
+
+
+
+
+