Spaces:
Sleeping
Sleeping
| """ | |
| notebook_parser.py | |
| ------------------- | |
| Extracts code cells from a .ipynb file and feeds the combined source | |
| through the same safe AST analyzer used for .py files. No cell is ever | |
| executed — we only read the "source" field of each code cell. | |
| """ | |
| import json | |
| from .code_parser import analyze_python_source | |
| def _strip_magics_and_shell(src): | |
| """Comment out Jupyter magics (%..., %%...) and shell escapes (!...) | |
| so the combined source is valid, parseable Python.""" | |
| out = [] | |
| for line in src.split("\n"): | |
| stripped = line.lstrip() | |
| if stripped.startswith("%") or stripped.startswith("!"): | |
| out.append("# " + line) | |
| else: | |
| out.append(line) | |
| return "\n".join(out) | |
| def analyze_notebook_source(nb_text, filename="uploaded.ipynb"): | |
| try: | |
| nb = json.loads(nb_text) | |
| except Exception as e: | |
| return {"error": f"Invalid notebook JSON: {e}", "filename": filename} | |
| cells = nb.get("cells", []) | |
| chunks = [] | |
| for cell in cells: | |
| if cell.get("cell_type") != "code": | |
| continue | |
| src = cell.get("source", "") | |
| if isinstance(src, list): | |
| src = "".join(src) | |
| chunks.append(_strip_magics_and_shell(src)) | |
| combined = "\n\n".join(chunks) | |
| if not combined.strip(): | |
| return {"error": "Notebook has no code cells", "filename": filename} | |
| return analyze_python_source(combined, filename=filename) | |