Substitutions and Templates¶
Common Data Context¶
pytest-httpchain maintains a key-value context throughout scenario execution. This context is populated by:
- Variables from
substitutions - pytest fixtures
- Values saved from responses
Substitutions Structure¶
Substitutions can be defined at scenario or stage level:
{
"substitutions": [
{
"vars": {
"base_url": "https://api.example.com",
"timeout": 30
}
},
{
"functions": {
"timestamp": "mymodule:get_timestamp"
}
}
]
}
List vs Dictionary Format¶
List format:
Dictionary format (keys are organizational only):
{
"substitutions": {
"config": {
"vars": {
"base_url": "https://api.example.com",
"api_version": "v2"
}
},
"auth": {
"functions": {
"token": "auth_module:get_token"
}
}
}
}
Mixed format:
{
"substitutions": {
"batch1": [
{"vars": {"key1": "value1"}},
{"vars": {"key2": "value2"}}
],
"batch2": {"vars": {"key3": "value3"}}
}
}
Variable Substitutions¶
Define static values:
{
"substitutions": [
{
"vars": {
"string_var": "hello",
"number_var": 42,
"bool_var": true,
"list_var": [1, 2, 3],
"object_var": {"nested": "value"}
}
}
]
}
Function Substitutions¶
Call Python functions to compute values:
{
"substitutions": [
{
"functions": {
"uuid": "uuid:uuid4",
"timestamp": "mymodule:get_timestamp",
"config": "mymodule:load_config"
}
}
]
}
# mymodule.py
from datetime import datetime
def get_timestamp() -> str:
return datetime.now().isoformat()
def load_config() -> dict:
return {"environment": "test", "debug": True}
Template Expressions¶
Use {{ expression }} syntax anywhere in requests. Expressions support Python syntax via simpleeval.
Basic Variable Access¶
String Operations¶
{
"headers": {
"Authorization": "{{ 'Bearer ' + token }}",
"X-Request-ID": "{{ prefix + '_' + str(counter) }}"
}
}
Arithmetic¶
Conditionals¶
Built-in Functions¶
Available functions in expressions:
str(),int(),float(),bool()len(),range()list(),dict(),set(),tuple()min(),max(),sum()abs(),round()sorted(),reversed()any(),all()enumerate(),zip()
List/Dict Comprehensions¶
{
"body": {
"json": {
"ids": "{{ [item['id'] for item in items] }}",
"names": "{{ {item['id']: item['name'] for item in items} }}"
}
}
}
Note: Comprehension length is limited by max_comprehension_length config.
Stage-Level Substitutions¶
Override or add variables for specific stages:
{
"substitutions": [
{"vars": {"base_url": "https://api.example.com"}}
],
"stages": [
{
"name": "production_test",
"substitutions": [
{"vars": {"base_url": "https://prod.example.com"}}
],
"request": {
"url": "{{ base_url }}/health"
}
}
]
}
Using Saved Values¶
Values saved from responses are available in subsequent stages:
{
"stages": [
{
"name": "login",
"request": {
"url": "https://api.example.com/login",
"method": "POST",
"body": {"json": {"user": "test", "pass": "secret"}}
},
"response": [
{
"save": {
"jmespath": {
"auth_token": "token",
"user_id": "user.id"
}
}
}
]
},
{
"name": "get_profile",
"request": {
"url": "https://api.example.com/users/{{ user_id }}",
"headers": {
"Authorization": "Bearer {{ auth_token }}"
}
}
}
]
}
Fixtures in Context¶
Pytest fixtures are added to context when listed: