Usage#
Writing Notebook Functions#
To turn any existing notebook into a notebook function, all you need to include a .config.json
file next to the notebook. For example a notebook named hello_world.ipynb
should have a hello_world.config.json
file next to it in order for Jupyrest to consider the hello_world.ipynb
notebook to be a notebook function.
If you do not intend to expose a Jupyter notebook a REST API, do not include the .config.json
file.
The .config.json
file#
The .config.json
file is used to set input and output schemas for the associated notebook.
A .config.json
file that looks like the one below describes a notebook function called my-notebook
that takes an input of arbitrary schema and returns an output of arbitrary schema.
{
"id": "my-notebook",
"input": {},
"output": {}
}
The id
property should be a URL-safe string because this value will be used in API called like:
POST /api/notebooks/<notebook_id>/execute
The input
and output
properties are JSON-schema objects.
Setting Notebook Inputs#
When writing a Jupyter notebook, you might find yourself having a code cell with a set of variables that you change frequently in order to test how your notebook functions with different inputs.
In order to tell Jupyrest and Papermill (the underlying library used by Jupyrest) about our notebook inputs, we need to designate this cell as the parameter cell. To do that we should set the code cell as parameters
.
How do I do that?
See these docs from the Papermill library on how to do that in JupyterLab and Jupyter Notebook.
In VSCode, download the Jupyter Cell Tags extension to do this.
Setting Notebook Outputs#
From within a notebook, we can set the notebook’s output using the save_output
function in Jupyrest.
from jupyrest import save_output
my_output_data = {
"title": "my output information",
"some_random_number": 42
}
save_output(my_output_data)
The input to save_output
should be any object that can be converted into JSON.
Configuring a Jupyrest Application#
A Jupyrest application is defined by its dependencies. All parts of a Jupyrest application are configurable using a set of well defined interfaces.
These dependencies are packaged into a DependencyBag
object:
import inspect
from IPython.display import Markdown
from jupyrest.contracts import DependencyBag
Markdown(f"""
```python
{inspect.getsource(DependencyBag)}
```
""")
@dataclass
class DependencyBag:
notebook_execution_repository: NotebookExecutionRepository
notebook_repository: NotebookRepository
file_obj_client: FileObjectClient
notebook_converter: NotebookConverter
notebook_parameterizier: NotebookParameterizier
notebook_executor: NotebookExeuctor
notebook_output_reader: NotebookOutputReader
notebook_input_output_validator: NotebookInputOutputValidator
notebook_execution_task_handler: NotebookExecutionTaskHandler
notebook_execution_file_namer: NotebookExecutionFileNamer
But for practical purposes, we can’t expect every developer to have to construct a DependencyBag on their own. That’s why we have builders.
We have the InMemoryApplicationBuilder
and the AzureApplicationBuilder
provided in the Jupyrest library. For this guide, we will use the InMemoryApplicationBuilder
.
We can create an InMemoryApplicationBuilder
by providing the path to our notebooks as notebooks_dir
:
from jupyrest.infra.in_memory.builder import InMemoryApplicationBuilder
from pathlib import Path
notebooks_dir = Path(__file__).parent / 'notebooks'
deps = InMemoryApplicationBuilder(
notebooks_dir=notebooks_dir
).build()
The deps
variable here is an instance of DependencyBag
and we can use this to deploy our Jupyrest Application where we so choose.
Starting the HTTP Server#
To start the HTTP Server, jupyrest
has a create_asgi_app
function. This functions takes a DependencyBag
as input, and returns a FastAPI application instance. FastAPI is a popular web server framework for Python and supports many forms of deployment.
If we wanted to run our FastAPI app locally, we could use uvicorn
:
import uvicorn
from jupyrest.http.asgi import create_asgi_app
app = create_asgi_app(deps=deps)
uvicorn.run(app, port=5051)