Skip to main content
Version: v2.x

Jupyter Python Notebook & API Server

Introduction

To enable quick prototyping and experimentation with AI apps, we've built a tool where you can write Python code and expose it as an API, which can be used with Hasura Event Triggers and Actions.

This tool includes a Jupyter Notebook where Python code can be written and executed. It also comes with a Jupyter Kernel Gateway, which can be then used to start an API out of the functions defined in the notebook.

You can use this framework to prototype your AI applications while simultaneously using Hasura Connectors to bring together data from any data source easily and securely.

Jupyter Notebook

Prerequisites

  • Install the Hasura CLI: instructions can be found here.
  • Install the cloud and notebook plugins using the following command:
hasura plugins install cloud
hasura plugins install notebook

To proceed, you'll need to ensure you're logged into Hasura Cloud via the CLI:

hasura cloud login

Getting started

Step 1: Create a notebook

Once you login to Hasura Cloud, you can create a Jupyter notebook to use the tool. Run the following command by supplying any random password which you will later use to access the notebook and the API:

hasura notebook create -p <password>

This takes a few minutes, you can check the status using the following command:

hasura notebook status

When the notebook is deployed, the CLI will display the access URL. Visit the URL in a browser to see the homepage. You will be prompted to enter a username and password. The username is hasura and password is the one you set while creating the notebook:

Jupyter Notebook homepage

Step 2: Launch the notebook

Click the "Launch Notebook" button to launch the Jupyter Notebook. You should see a screen like this:

Contents of the notebook

In the notebook, you'll find several project folders. For each, you'll find the handler code in server.py. This handler is responsible for processing requests and serving responses from the API.

Once you have a block of code in your notebook, you can expose that as an API through the Jupyter Kernel Gateway by adding a comment of the format # METHOD /url. For example:

# GET /hello_world

import json
print(json.dumps({
'hello': 'world'
}))

Step 3: Start the API

From the homepage, you can select the server to start from the dropdown. Clicking the "Start API" button will start the selected server from the dropdown option above the button.

This block of code will return {"hello": "world"} when you visit /invoke/hello_world. More details on how to handle headers and response data can be found at Jupyter Kernel Gateway notebook-http mode documentation.

The endpoints for any API are served from the server.ipynb notebook. You can add new endpoints by adding a new block of code in this file with the comment format # METHOD /url.

You can then monitor the logs of the API by running the following command:

hasura notebook logs
Restart the API after making changes

Each time changes are made to the notebook, click the "Restart API" button to deploy the latest version.

Templates

You can find templates for events and action handlers in this notebook:

Template for Event Trigger to Extract, Transform, Load (ETL) data

# POST /handle_event

GRAPHQL_ENDPOINT = ""
ADMIN_SECRET = ""

import json
from gql import gql, Client
from gql.transport.requests import RequestsHTTPTransport

def handle_insert(row, client):
id = int(row['id'])
name = str(row['name'])
description = str(row['description'])
# In reality you would follow the URL from row['url']
content = "dummy content"
gql_query = gql("""
mutation insertItem($id: int!, $name: text!, $description: text!) {
insert_Product_one(object: { product_id: $id, name: $name, description: $description }) {
id
}
}
""")
print(client.execute(gql_query, variable_values={
'id': id, 'name': name, 'description': description}))

Template to respond to user's questions by querying Weaviate + OpenAI

# POST /handle_query

GRAPHQL_ENDPOINT = ""
ADMIN_SECRET = ""
OPENAI_API_KEY = ""

import json
from gql import gql, Client
from gql.transport.requests import RequestsHTTPTransport

from langchain.llms import OpenAI
from langchain.chains import LLMChain
from langchain.prompts import PromptTemplate

def handle_query(request):
user_query = request['body']['input']['user_query']

gql_headers = dict()
gql_headers['x-hasura-admin-secret'] = ADMIN_SECRET

# Create a GraphQL client with the request transport
transport = RequestsHTTPTransport(
url=GRAPHQL_ENDPOINT, headers=gql_headers)
client = Client(transport=transport)

Authentication

The APIs exposed by the notebook require Basic HTTP authentication. When added as an Event Trigger or Action to Hasura, you'll need to add the Authorization header in basic auth format with user name as hasura and password as the password you set for the notebook.

The header format is:

Authorization: Basic <token>

The token can be created by base64-encoding a string in username:password format in your terminal:

echo -ne "<username>:<password>" | base64

You can then use the encoded string returned by this command as your token in the authorization header.

Exposed APIs

The container exposes the following APIs:

APIDescription
/jupyterJupyter notebook entrypoint.
/invoke/<path>Invoke APIs exposed via the notebook's server.ipynb.
/process/startStart the notebook API server.
/process/stopStop the notebook API server.
/process/restartRestart the notebook API server.

The source code for the container can be found here.

Production environments

It is not recommended to use this notebook in production. It is intended to be a playground for experimenting and fast iterations to validate your ideas.

In production, we recommend that you migrate your code from a notebook and into a Flask application or equivalent, which you can then deploy in a production-ready environment.

Deleting the notebook

Once you are done, you can keep the notebook around for your next project or delete it using the command:

hasura notebook delete