Metadata-Version: 2.4
Name: jupyter_functions_exec
Version: 0.8.0
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
License-File: LICENSE
Summary: Clase rápida para trabajar con notebooks
Author-email: Oscar <oscarortegarios@gmail.com>
License: MIT
Requires-Python: >=3.11
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM

# Jupyter Functions Exec

[![PyPI version](https://badge.fury.io/py/jupyter-functions-exec.svg)](https://badge.fury.io/py/jupyter-functions-exec)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![Rust](https://img.shields.io/badge/Built%20with-Rust-orange.svg)](https://www.rust-lang.org/)
[![Python](https://img.shields.io/badge/Python-3.11+-blue.svg)](https://www.python.org/)

High-performance Python package built in **Rust** to extract and execute functions directly from Jupyter Notebooks (`.ipynb`) -> no copy-paste.

Ignores broken cells, keeps only valid functions and imports.

## Installation

Requires Python 3.11+

```bash
pip install jupyter-functions-exec
```

## Quickstart

If your `notebook.ipynb` contains:

```python
import math

def add(a, b):
    return a + b

def circle_area(r):
    return math.pi * r ** 2
```

Use it from Python:

```python
from jupyter_functions_exec import JupyterFunctions

jf = JupyterFunctions("notebook.ipynb")

print(jf.functions_names())
# ['add', 'circle_area']

print(jf.necessary_imports())
# ['import math']
```

## Examples

### 1. Execute a function

```python
result = jf.exec_function("add", 2, 3)
print(result) # 5
```

With kwargs:

```python
result = jf.exec_function("circle_area", r=10)
print(result) # 314.159...
```

### 2. Get a callable

```python
add = jf.return_function("add")
print(add(10, 20)) # 30
```

### 3. Check and inspect

```python
if jf.exists_function("add"):
    print("found!")

print(jf.functions_names())
print(jf.necessary_imports())
```

## API Reference

| Method | Description |
| :--- | :--- |
| `JupyterFunctions(path: str)` | Parse a `.ipynb` file. Filters broken code automatically. |
| `exec_function(name, *args, **kwargs)` | Execute function by name and return result. |
| `return_function(name) -> Callable` | Return function as callable for later use. |
| `exists_function(name) -> bool` | Check if function exists. O(1) lookup. |
| `functions_names() -> list[str]` | Get sorted list of all valid functions. |
| `necessary_imports() -> list[str]` | Get list of imports needed. |

## How it works

1. Parses `.ipynb` as JSON in Rust
2. Extracts `import` / `def` per code chunk
3. Validates each function with Python `compile()` -> broken cells are skipped
4. Pre-compiles everything once in `__init__` for fast `exec`

## License

MIT - see [LICENSE](LICENSE)

