Skip to content

Scripting

Scripting involves writing code to automate, test, and customize API requests and responses. These scripts can be used to set variables to Stores, authentication, extract data from responses, perform conditional logic, testing API and more.

request_script

How to use?

Here is a complete example:

# 'ctx' (context) is imported automatically
# or import them directly:
# from zapy.ctx import hooks, store

# import any library on your venv or local modules
from decimal import Decimal
import unittest
import my_local_module


# print logs to Response Console
print("Hello world")

# use 'ctx.store' to store and retrieve variables among requests
ctx.store.my_var = Decimal('0.1')
ctx.store['my_var_2'] = Decimal('0.2')


# Use the lifecycle hooks to modify, debug or test
@ctx.hooks.pre_request
async def on_pre_request(httpx_args):
    print("pre_request")

@ctx.hooks.post_request
async def on_response(httpx_response):
    print("post_request")
    # example, persist the id to use on other request
    ctx.store['my_saved_id'] = httpx_response.data.id

@ctx.hooks.test
class TestResponse(unittest.TestCase):
    def test_status_code(self):
        self.assertEqual(self.response.status_code, 200)

Request Context module

This module is automatically imported on each request as ctx. It contains the following variables:

  • hooks
    • pre_request: decorator for async or sync function
    • post_request: decorator for async or sync function
    • test: decorator for testing. Cannot be async
  • store
  • auto: special function used for inferring the header Content-Type
  • load_file: special function used for loading files on body with Content-Type as multipart/form-data

Hooks

All request script hooks are optional and should register only once. These hooks are applied only to the current request. Hooks are triggered at a specific time in a request lifecycle:

  1. evaluate script
  2. declare variables
  3. pre_request hook @ctx.hooks.pre_request
  4. send request
  5. post_request hook @ctx.hooks.post_request
  6. test hook @ctx.hooks.test

pre_request

@ctx.hooks.pre_request
async def on_pre_request(httpx_args):
    print("pre_request")

post_request

@ctx.hooks.post_request
async def on_response(httpx_response):
    print("post_request")
    # example, persist the id to use on other request
    ctx.store['my_saved_id'] = httpx_response.data.id

test

Register a unittest.TestCase class. It contains special attributes such as:

  • self.response: the httpx response
  • self.request: the httpx request
  • self.httpx_args: the httpx request arguments for httpx.Request and client.send

See more info on testing.

# test hook expects a unittest.TestCase class, cannot be async
import unittest

@ctx.hooks.test
class TestResponse(unittest.TestCase):
    def test_status_code(self):
        self.assertEqual(self.response.status_code, 200)

Stores

Store is the mechanism to persist and share variables among requests. Use ctx.store to store and retrieve variables among requests. Read more here.

ctx.store.my_var = Decimal('0.1')
ctx.store['my_var_2'] = Decimal('0.2')

And then access use the variable on the next requests

my_var: {{ ctx.store.my_var }}

Printing

To show information on the Console tab use the print function.

print('hello world')

response_console

Importing modules

Note

Importing local modules requires the use of a main file.

Printing (stdout) on imported modules won't be on the Console tab, they will appear on the terminal.

Import local modules by using a path relative to the main file.

For example, if we have the following files:

my_main.py           # Main file for starting the server
my_module.py         # Local module at same level
test_dir/
    __init__.py
    test_dir_1.py    # Local module inside directory (aka package)

Then, we can import as:

# installed library
import httpx

# local module
import my_module

# local package
import test_dir.test_dir_1
# or
from test_dir import test_dir_1