Skip to main content
Version: 2.14.1

Addons API

API documentation for the Reqable scripting.

tip

Variable names in italics are read-only, and in bold they can be overwritten.

CaptureContext

VariableTypeDescription
urlstrRequest url, read-only.
schemestrURL scheme, http or https, read-only.
hoststrHost, read-only.
portintPort number, read-only.
cidintConnection ID, read-only.
ctimeintTCP connection establishment timestamp, in milliseconds, read-only.
sidintHTTP session ID, read-only.
stimeintHTTP session start timestamp, in milliseconds, read-only.
uidstrThe unique identifier of an HTTP session, consisting of ctime + cid + sid.
appCaptureAppApp/Process information.
envdictA collection of variables for the global environment and currently actived custom environment.
shared-A special variable used to share data between onRequest and onResponse, which can be auto-serializable variables such as str, int, list and dict.

Code example:

def onRequest(context, request):
# Print url, for example: https://reqable.com/
print(context.url)
# Print scheme, for example: https
print(context.scheme)
# Print host, for example: reqable.com
print(context.host)
# Print port number, for example: 443
print(context.port)
# Print connection ID, for example: 1
print(context.cid)
# Print TCP connection timestamp, for example: 1686711219444
print(context.ctime)
# Print HTTP session ID, for example: 1
print(context.sid)
# Print HTTP session start timestamp, for example: 1686711224132
print(context.stime)

# Get an environment variable
print(context.env['foo'])
print(context.env['$timestamp'])

# Write an environment variable
# The currently activated custom environment is written first, and if there is no activated environment, the global environment is written.
context.env['foo'] = 'bar'

# Set shared value
context.shared = 'Hello'

# Done
return request

def onResponse(context, response):
# Print shared value, output: Hello
print(context.shared)
return response

CaptureHttpRequest

VariableTypeDescription
methodstrHTTP request method.
pathstrHTTP request path. Note that the query part is not included.
protocolstrHTTP protocol version of the request, read-only.
queriesCaptureHttpQueriesList of request query parameters.
headersCaptureHttpHeadersList of request headers.
bodyCaptureHttpBodyRequest body.
trailersCaptureHttpHeadersList of request trailers, see chunked trailers of HTTP1 or trailers of HTTP2.
contentTypestr or NoneRequest type (that is, the value of Content-Type in headers), read-only.
mimestr or NoneRequest MIME type, such as application/json, read-only.

Code example:

def onRequest(context, request):
# Print method, for example: POST
print(request.method)
# Print path, for example: /foo
print(request.path)
# Print query parameters, for example: [('foo', 'bar'), ('hello', 'world')]
print(request.queries)
# Print headers, for example: ['host: reqable.com', 'content-length: 6', 'content-type: text/plain']
print(request.headers)
# Print body payload, for example: {"foo":"bar"}
print(request.body)

# Update request method
request.method = 'GET'
# Update request path
request.path = '/bar'

# Update request parameters, more APIs please refer to `CaptureHttpQueries` below.
request.queries['foo'] = 'bar'
# Assign request parameters
request.queries = 'foo=bar&hello=world&abc=123'
request.queries = {
'foo': 'bar',
'hello': 'world',
'abc': '123'
}
# Delete specified request parameters
request.queries.remove('foo')

# Update request headers, more APIs please refer to `CaptureHttpHeaders` below.
request.headers['content-type'] = 'application/json'
# Assign request headers
request.headers = [
'content-type: application/json',
'foo: bar'
]
# Delete specified request headers
request.headers.remove('foo')

# Set a text to body
request.body = 'Hello World'
# Set a dictionary to body, it will be automatically converted to JSON
request.body = {
'foo': 'bar',
'abc': 123
}
# Set a binary data to body
request.body = b'\x01\x02\x03\x04'
# Set a file path to body
request.body.file('/User/Reqable/Desktop/test.png')

# JSON body is converted into a dictionary
request.body.jsonify()
# Then manipulate the dictionary to modify the Body
request.body['foo'] = 'bar'
request.body['error'] = {
'code': 1000,
'message': 'Runtime Error'
}

# Done
return request

CaptureHttpResponse

VariableTypeDescription
requestCaptureHttpRequestThe request of response, read-only.
codeintResponse status code.
messagestrResponse status message, read-only. Note: In the HTTP2 protocol, the value is empty; this value will be automatically updated after the status code is changed.
protocolstrThe HTTP protocol version of the response, read-only.
headersCaptureHttpHeadersList of response headers.
bodyCaptureHttpBodyResponse body.
trailersCaptureHttpHeadersList of response trailers, see chunked trailers for HTTP1 or trailers for HTTP2.
contentTypestr or NoneResponse type (that is, the value of Content-Type in headers), read-only.
mimestr or NoneResponse MIME type, such as application/json, read-only.

Code example:

def onResponse(context, response):
# Print request information, for more APIs, please refer to `CaptureHttpRequest` above
print(response.request)
# Print response status code, for example: 200
print(response.code)
# Print response status message, for example: OK
print(response.message)
# Print response headers, for example: ['server: Netlify', 'content-length: 6', 'content-type: text/plain']
print(response.headers)
# Print response body payload, for example: {"foo":"bar"}
print(response.body)

# Update status code
response.code = 400

# More examples refer to `onRequest` above, exactly the same.

# Done
return request

CaptureHttpQueries

FunctionParametersReturnDescription
lenintReturns the count of query parameters.
iterIterate the query parameters.
addstr, strAdd a new query, the parameters are name and value.
removestrDelete the query with the specified name. Note: If there are more than one with the same name, all will be removed.
clearDelete all queries.
concatboolstrReturns the concatenated complete query string.
indexstrintQuery the index of the query parameter of the specified name in the list, and only return the first index that matches the name.
indexesstrlistQuery the index of the query parameter of the specified name in the list, and return a list of all indexes matching the name.
getitemstrstrGet the query value of the specified name. Note: If there are more than one with the same name, it will return the first one; if it does not exist, it will return None.
getiteminttupleGet query by index.
setitemstr, strUpdate or add a query. If there is a query with the specified name, update its value, otherwise add a new query parameter.

Code example:

def onRequest(context, request):
# Print the count of query parameters
print(len(request.queries))
# Iterate the query parameters
for query in request.queries:
print(query)

# Add a new query
request.queries.add('foo', 'bar')
# Remove the query named `foo`
request.queries.remove('foo')
# Remove all query parameters
request.queries.clear()
# Update the query parameter, if it does not exist, it will be added automatically.
request.queries['foo'] = 'bar'

# Print the query value, for example: bar
print(request.queries['foo'])
# Print the query name and value at the specified index position, for example: (foo, bar)
print(request.queries[0])
# Print the concatenated query string, such as: foo=bar&hello=world
print(request.concat())
# Print the concatenated query string(URL encoded).
print(request.concat(encode=True))

# Done
return request

CaptureHttpHeaders

FunctionParametersReturnDescription
lenintReturns the count of headers.
iterIterate the headers.
addstr, strAdd a new header, the parameters are name and value.
removestrDelete the header with the specified name. Note: If there are more than one with the same name, all will be removed.
clearDelete all headers.
indexstrintQuery the index of the header of the specified name in the list, and only return the first index that matches the name.
indexesstrlistQuery the index of the header of the specified name in the list, and return a list of all indexes matching the name.
getitemstrstrGet the header value of the specified name. Note: If there are more than one with the same name, it will return the first one; if it does not exist, it will return None.
getitemintstrGet header by index.
setitemstr, strUpdate or add a header. If there is a header with the specified name, update its value, otherwise add a new header.

Code example:

def onRequest(context, request):
# Print the count of headers
print(len(request.headers))
# Iterate the header list
for header in request.headers:
print(header)
# Add a new header
request.headers.add('foo', 'bar')
# Remove the header named `foo`
request.headers.remove('foo')
# Remove all headers
request.headers.clear()
# Update the header, if it does not exist, it will be added automatically.
request.headers['foo'] = 'bar'
# Print the header value, for example: bar
print(request.headers['foo'])
# Print the header at the specified index position, for example: `foo: bar`
print(request.headers[0])
# Done
return request

CaptureHttpBody

VariableTypeDescription
isNoneboolDetermine whether it is an empty Body. For this type, payload is None.
isTextboolDetermine whether it is a string Body. For this type, the payload is str.
isBinaryboolDetermine whether it is a binary Body. For this type, the payload is bytes.
isMultipartboolDetermine whether it is a form Body. For this type, the payload is a list of CaptureHttpMultipartBody.
typeintReturns the type of Body. 0 means none, 1 means text, 2 means binary, 3 means form.
payloadPolymorphic types, refer to the description above.Body payload.
def onRequest(context, request):
# Judging body type
print(request.body.type)
if request.body.isNone:
print('Http body is none')
elif request.body.isText:
print('Http body is text')
elif request.body.isBinary:
print('Http body is binary')
elif request.body.isMultipart:
print('Http body is multipart')

# Print body type value
print(request.body.type)
# Print body payload
print(request.body.payload)
FunctionParametersReturnDescription
noneSet None to body.
textstrSet a text value to body.
textFromFilestrSet a file content(text) to body.
binarystr or bytesSet binary data to body.
filestrSet the file content(binary) to body.
multipartslistSet to forms, the parameter is a list of CaptureHttpMultipartBody.
writeFilestrWrite body payload to a file. Note: form body is not supported.

Code example:

def onRequest(context, request):
# Set `None` to body.
request.body.none()
# Set `foobar`` to body.
request.body.text('foobar')
# Set the file content to body, body type is text.
request.body.textFromFile('/User/Reqable/Desktop/body.json')
# Set bytes to body
request.body.binary(b'\x01\x02\x03\x04')
# Set the file content to body, body type is binary.
request.body.binary('~/Desktop/body.json')
# Set the forms to body.
request.body.multiparts([
CaptureHttpMultipartBody.text('Hi World'),
CaptureHttpMultipartBody.file('data/body_binary.bin')
])

# Write body payload to the file.
request.body.writeFile('/User/Reqable/Desktop/body.json')

# Done
return request

CaptureHttpMultipartBody

CaptureHttpMultipartBody inherits from CaptureHttpBody, with an additional headers field.

VariableTypeDescription
headersCaptureHttpHeadersList of headers in the part.
namestrPart name.
filenamestrPart file name.

Code example:

def onRequest(context, request):
# Iterate parts
for part in request.body:
print(f'name {part.name}')
print(f'filename {part.filename}')
print(f'value {part}')

# Update parts
request.body[0] = CaptureHttpMultipartBody.text('Hi World')
request.body[0] = CaptureHttpMultipartBody.text('Hi World', name='reqable')
request.body[0] = CaptureHttpMultipartBody.file('data/body_binary.bin')
request.body[0] = CaptureHttpMultipartBody.file('data/body_binary.bin', name='reqable', filename='test.png')

# Done
return request
caution

If you change the non-form type to form type, you must modify the headers and set boundary at the same time!

CaptureApp

VariableTypeDescription
namestrName of the app/process.
idstrApp unique id, such as bundleId for mac app, packageName for android app. Return None if not detected.
pathstrThe app installed path.

Code example:

def onRequest(context, response):
# Print app information
print(context.app.name)
print(context.app.id)
print(context.app.path)
# Done
return request

Example 1

Below is an example of modifying JSON response data.

Suppose the response data is in the following format:

{
"code": 10000,
"message": "ok",
"content": {
"version": "1.0.0",
"platform": "windows"
}
}

We need to change the value of version to 2.0.0.

from reqable import *

def onRequest(context, request):
# Done
return request

def onResponse(context, response):
# Jsonify the response body
response.body.jsonify()
# Modify the version value in the dictionary
response.body['content']['version'] = '2.0.0'
# Done
return response

Example 2

The following is an example of automatically signing request parameters with MD5.

from reqable import *
import hashlib

def onRequest(context, request):
# Sort the query list
queries = sorted(request.queries)
# Concat the query parameters
text = queries.concat()
# Sign using the md5 algorithm
algorithm = hashlib.md5()
algorithm.update(text.encode(encoding='UTF-8'))
signature = algorithm.hexdigest()
# The signature is added to the request header
request.headers['signature'] = signature
# Done
return request

def onResponse(context, response):
# Done
return response

Example 3

Below is an example script that automatically saves images.

from reqable import *
from mimetypes import guess_extension
import datetime
import os

def onRequest(context, request):
return request

def onResponse(context, response):
# Check the Mime type, if it is not an image type, it will be skipped and not processed
mime = response.mime
if mime == None:
return response

maintype, subtype = mime.split('/')
if not maintype == 'image':
return response

# Save the image to the directory, the file name is timestamp, and the suffix is derived according to the mime type
dir = '/Users/megatronking/Downloads/reqable/'
os.makedirs(dir, exist_ok=True)
name = datetime.datetime.now().strftime("%H%M%S%f")
ext = guess_extension(mime)
image = os.path.join(dir, name + ext)

# Write body payload to file
print(f'Saving image {image}')
response.body.writeFile(image)

# Done
return response