http_request
operation
The http_request
operation executes HTTP requests integrated with data sources. While sources are typically databases, they
can be any source for which we have a built-in connector, such as file-based sources (e.g. Amazon S3).
The http_request
operation consists of three main section:
for_each
- to iterate over an input tablerequest
- HTTP call configurationresponse
- to process the HTTP response
As with any operation, any YAML parameters described below can be dynamically parameterized using Jinja templates
or by adding an _expression
suffix to its name and defining it as a Python function.
For more information on dynamic parametrization, see the Dynamic parametrization section.
for_each
section
The for_each
section is optional. It allows you to specify an input table. http_request
will iterate over the table
executing the request
and response
sections for each input row.
The for_each
section has the following parameters:
source
(type: string, required) - source namedatabase
(type: string, optional) - database namenamespace
(type: string, optional) - namespace nametable
(type: string, required) - table nameas
(type: string, required) - variable name for a local variable that will be set to the current row. You can access this variable from Jinja templates and Python functions in therequest
andresponse
sections.
The value of the variable specified in the as
parameter is a Row object that provides dictionary-style access to column values. The following methods are available:
Method | Description | Example |
---|---|---|
row['column_name'] | Access a column value by name | Jinja: var('customer')['id'] Python: context.var('customer')['id'] |
row[0] | Access a column value by index | Jinja: var('customer')[0] Python: context.var('customer')[0] |
row.get('column_name', default) | Get column value with optional default if column value is NULL | Jinja: var('customer').get('email', 'unknown') Python: context.var('customer').get('email', 'unknown') |
'column_name' in row | Check if column exists | if 'email' in context.var('customer'): |
len(row) | Get number of columns | len(context.var('customer')) |
for column_name in row | Iterate through column names | for column in context.var('customer'): |
row.keys() | Get all column names | for name in context.var('customer').keys(): |
row.values() | Get all column values | for value in context.var('customer').values(): |
row.items() | Get all (name, value) pairs | for name, value in context.var('customer').items(): |
row.to_dict() | Convert row to Python dictionary | customer_dict = context.var('customer').to_dict() |
request
section
The request
section contains HTTP call configuration with the following parameters:
source
(type: str, optional) - name of a source of thehttp
type. The source defines authentication parameters and source-level variables that can be access from all sections of thehttp_request
operation. For more information on thehttp
source, see the http source section.url
(type: str, required) - URL to call.method
(type: str, required) - HTTP method. Values are:GET
,POST
,DELETE
, orPATCH
.parameters
(type: Dict[str, str], optional) - URL parameters.header
(type: Dict[str, str], optional) - HTTP headerbody_format
(type: str, required if body is present) - defines the expected type of thebody
parameter value and the format to which to convert thebody
value. Values are:json
- thebody
parameter must be dictionary that will be converted to JSON formatform_urlencoded
- thebody
parameter must be a dictionary that will be encoded in URL-encoded format. Note: you must set theContent-Type: application/x-www-form-urlencoded
header yourself.
response
section
The response
section defines how to process the HTTP response:
parser_expression
(type: str, required) - a Python functionevaluate
that takes two parameters:context
- provides access to variables and other runtime informationresponse
- contains response information. For information method of thecontext
object, see the Python functions subsection in Dynamic parametrization. Theresponse
object has the following methods and properties:status_code
(type: int) - HTTP status of the response (e.g. 200 or 404)headers
(type: Dict[str, str]) - case-insensitive dictionary of the response headers. For example, headers[‘content-encoding’] will return the value of a ‘Content-Encoding’ response header.text
(type: str) - content of the response, in unicode.json()
- parses the response body as JSON and returns the corresponding Python data structure (dict, list, etc).
Examples
This example demonstrates most parameters described of the http_request
operations. It creates customers in a Bigcommerce e-commerce system
from an input table by executing a POST API call for each customer and parses the response of each call to store the newly generated customer IDs.
In the response parsing, it stores the ID from the input row to preserve lineage information.
- op: http_request
id: create_customers
for_each:
source: "stage"
table: "bc_customers_to_insert"
as: customer
request:
source: "bigcommerce_rest"
url: "https://api.bigcommerce.com/stores/{{ var('store_hash') }}/{{ var('api_version') }}/customers"
method: POST
headers:
"Content-Type": "application/json"
body_format: json
body:
- "first_name": "{{ var('customer').get('first_name', '__NULL__') }}"
"last_name": "{{ var('customer').get('last_name', '__NULL__') }}"
"email": "{{ var('customer').get('email', '__NULL__') }}"
# Equivalent version using body_expression
# body_expression: |
# def evaluate(context):
# return [{
# "first_name": context.var("customer").get("first_name"),
# "last_name": context.var("customer").get("last_name"),
# "email": context.var("customer").get("email")
# }]
response:
parser_expression: |
def evaluate(context, response):
if response.status_code != 200:
raise Exception(f"Error status code: {response.status_code}, body: {response.text}")
customers_created = response.json()['data']
customers_created['source_id'] = context.var("customer").get("id")
return {
"tables": [{
"source": "stage",
"table": "bc_customers_inserted",
"data": customers_created,
"model": {
"columns": [
{"name": "id", "type": "text"},
{"name": "source_id", "type": "text"},
{"name": "first_name", "type": "text"},
{"name": "last_name", "type": "text"},
{"name": "email", "type": "text"}
]
}
}]
}
You can find more examples of HTTP request operations for various systems and use cases in the Sequor integrations GitHub repository.