Skip to content

Chaining Requests

Chaining requests refers to the practice of sending multiple HTTP requests in a sequence, where the response of one request serves as the input or context for the next request. This allows you to build complex workflows and test different scenarios by combining multiple API calls into a single workflow.

This can be achieved by storing data from responses on Stores and using the stored value as the input on the next request.

Manual chaining

Manual chaining is the manual execution of a series of requests, requiring individual actions for each request and waiting for results. You can forget about manual chaining using Jupyter Notebooks.

Jupyter Notebooks

Jupyter Notebooks are interactive documents that combine code, visualizations, and text. They are a sequence of cells which have ability to execute code interactively using a GUI.

Importing local modules

If a Jupyter Notebook is executed as __main__, it operates on a different process. It means that it creates it's own default Store and configurations. Also the relative paths to files are different.

To improve code reusability, create a dedicated module for authentication and environment variables. It's also recommended to extract the paths into variables to allow parameterization when using the SDK. When importing the modules or declaring variables to substitute, include if __name__ == '__main__' for convenient invocation during testing. This enhances code maintainability and testing efficiency.

For example:

Cell 1

from pathlib import Path
from zapy import requests
from zapy.utils import module

if __name__ == '__main__':
    setup_store = module.load_module('./my_store.py')
    setup_auth = module.load_module('./my_auth.py')
    rel_path = Path().resolve()

Cell 2

request = requests.from_path(rel_path / 'request1.zapy')
response = await request.send()
response.json()

Execute a chain with a single click

By using the Run All button is possible to execute the whole sequence on a single click. This executes the Jupyter Notebook as __main__,

jupyter_menu

Resume from last error

On a particular cell, click Execute Cell and Below.

jupyter_run_below

Debug data from requests

Print variables and debug.

jupyter_store

Invoking Jupyter Notebooks

To invoke Jupyter Notebooks from Python, utilize the module.load_ipynb function. Its first argument should be the notebook's path, and the optional variables argument can be used to pass parameters to the notebook.

jupyter_output

In this example, the Jupyter Notebook will take a global variable rel_path as a parameter, and we can access its variable named out_response after execution.

from zapy.utils import module
rel_path = Path('tests/assets')
# invoke jupyter notebook
chain = await module.load_ipynb(rel_path / 'chain_import.ipynb', variables={
    'rel_path': rel_path
})
# access a variable
print(chain.out_response)

Notice that as invoking the Jupyter Notebook uses a different __main__ and __file__.