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 therequestandresponsesections.
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 thehttptype. The source defines authentication parameters and source-level variables that can be access from all sections of thehttp_requestoperation. For more information on thehttpsource, 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 thebodyparameter value and the format to which to convert thebodyvalue. Values are:json- thebodyparameter must be dictionary that will be converted to JSON formatform_urlencoded- thebodyparameter must be a dictionary that will be encoded in URL-encoded format. Note: you must set theContent-Type: application/x-www-form-urlencodedheader yourself.
response section
The response section defines how to process the HTTP response:
parser_expression(type: str, required) - a Python functionevaluatethat takes two parameters:context- provides access to variables and other runtime informationresponse- contains response information. For information method of thecontextobject, see the Python functions subsection in Dynamic parametrization. Theresponseobject 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.