REST API driver for OKW4Robot - keyword-driven REST API test automation.
Project description
robotframework-okw-api-rest
Deutsche Version: README_de.md
Keyword-driven REST API testing for OKW4Robot.
One set of keywords covers the complete REST API test lifecycle: Start -> Scope -> Input -> Action -> Verify -> Memorize -> Stop.
Installation
pip install robotframework-okw-api-rest
Or editable (for development):
pip install -e path/to/robotframework-okw-api-rest
Dependencies
- Python >= 3.10
- robotframework >= 6.0
- requests >= 2.28
- PyYAML >= 6.0
- okw-contract-utils >= 0.2.0
Quick Start
1. YAML Configuration
Create a file locators/NotesAPI.yaml:
NotesAPI:
__self__:
class: okw_api_rest.library.OkwApiRestLibrary
base_url: https://practice.expandtesting.com/notes/api
content_type: application/x-www-form-urlencoded
2. Test File
*** Settings ***
Library okw_api_rest.library.OkwApiRestLibrary WITH NAME RESTAPI
*** Test Cases ***
Health Check
RESTStart NotesAPI
RESTSelectEndpoint /health-check
RESTSendRequest GET
RESTVerifyStatus 200
RESTStop
3. Run
robot tests/REST_NotesAPI.robot
Keywords
| Keyword | Description |
|---|---|
RESTStart |
Start REST service (load YAML, base URL) |
RESTStop |
Stop REST service |
RESTSelectEndpoint |
Select endpoint path |
RESTSetValue |
Set request body field or query parameter (auto type detection) |
RESTSetValueAsString |
Set request body field (always string, no conversion) |
RESTSetValueAsList |
Set request body field as JSON array |
RESTSetFile |
Set file field for multipart form-data upload |
RESTSetContext |
Navigate into nested JSON object |
RESTSetHeader |
Set request header |
RESTSendRequest |
Send HTTP request (GET, POST, PUT, PATCH, DELETE) |
RESTVerifyValue |
Verify response field value (exact match) |
RESTVerifyValueWCM |
Verify response field value (wildcard: *, ?) |
RESTVerifyValueREGX |
Verify response field value (regular expression) |
RESTVerifyStatus |
Verify HTTP status code |
RESTVerifyResponseTime |
Verify response time is below threshold (ms) |
RESTVerifyListCount |
Verify number of elements in a JSON array |
RESTVerifyHeader |
Verify response header |
RESTMemorizeValue |
Store response field value for $MEM{name} |
RESTMemorizeBody |
Store entire response body |
RESTSaveResponseToFile |
Save response body to a local file (binary-safe) |
Phase Model
| Phase | REST Keyword | GUI Equivalent |
|---|---|---|
| Start | RESTStart |
StartApp |
| Scope | RESTSelectEndpoint |
SelectWindow |
| Input | RESTSetValue |
SetValue |
| Context | RESTSetContext |
SetContext |
| Header | RESTSetHeader |
-- |
| File | RESTSetFile |
-- |
| Action | RESTSendRequest |
ClickOn |
| Verify | RESTVerifyValue |
VerifyValue |
| Status | RESTVerifyStatus |
-- |
| Timing | RESTVerifyResponseTime |
-- |
| Memorize | RESTMemorizeValue |
MemorizeValue |
| Save | RESTSaveResponseToFile |
-- |
| Stop | RESTStop |
StopApp |
OKW Tokens
| Token | Behavior |
|---|---|
$IGNORE |
Keyword becomes a no-op (field is not sent) |
$EMPTY |
Set field explicitly to empty string |
$NULL |
Set field explicitly to JSON null |
Auto Type Detection
RESTSetValue automatically converts values to their native JSON type:
RESTSetValue name Zoltan # → string "Zoltan"
RESTSetValue count 42 # → integer 42
RESTSetValue price 3.14 # → float 3.14
RESTSetValue active true # → boolean true
RESTSetValue comment $NULL # → null
Use RESTSetValueAsString when a value must remain a string:
RESTSetValueAsString zipcode 01234 # → string "01234" (not integer)
RESTSetValueAsString flag true # → string "true" (not boolean)
Query parameters (? prefix) are always strings — no type conversion.
JSON Arrays
Two ways to set array fields:
# Short array — one line
RESTSetValueAsList tags important urgent work
# Array index — one value per line (auto-typed)
RESTSetValue scores[0] 42
RESTSetValue scores[1] 87
RESTSetValue scores[2] 15
# Empty array
RESTSetValueAsList items
Verify array length with RESTVerifyListCount:
RESTVerifyListCount todos 3 # todos has 3 elements
RESTVerifyListCount items 0 # items is empty
File Upload
Upload files via multipart form-data:
RESTSelectEndpoint /api/documents
RESTSetValue title Annual Report
RESTSetFile file ${CURDIR}/testdata/report.pdf
RESTSendRequest POST
RESTVerifyStatus 200
When files are present, RESTSendRequest automatically switches to
multipart encoding. Text fields are sent as form fields alongside.
# Multiple files, same field name
RESTSetFile attachments photo1.jpg
RESTSetFile attachments photo2.jpg
# Explicit MIME type
RESTSetFile data export.bin application/octet-stream
MIME type is auto-detected from file extension. Paths support ~ and $ENV_VAR.
File content is previewed in the Robot log (text readable, binary as hex).
Query Parameters
Fields prefixed with ? are sent as URL query parameters:
RESTSetValue ?page 1 # query param: ?page=1
RESTSetValue name Zoltan # body field
Query parameters work with all HTTP methods and are not affected by RESTSetContext.
Value Memorization
Store response values and reuse them in subsequent requests:
# Store token from login response
RESTMemorizeValue data.token TOKEN
# Use in next request
RESTSetHeader x-auth-token $MEM{TOKEN}
RESTSelectEndpoint /notes/$MEM{NOTE_ID}
Nested Request Bodies
Use RESTSetContext to build nested JSON structures:
RESTSelectEndpoint /orders
RESTSetContext customer
RESTSetValue name Zoltan
RESTSetValue email z@test.com
RESTSetContext customer.address
RESTSetValue street Hauptstr. 1
RESTSetValue city Berlin
RESTSendRequest POST
Produces: {"customer": {"name": "Zoltan", "email": "z@test.com", "address": {"street": "Hauptstr. 1", "city": "Berlin"}}}.
Endpoint Keywords Pattern
Wrap endpoints as reusable keywords with default values:
*** Keywords ***
Register User
[Arguments] ${name}=DefaultUser ${email}=default@test.com ${password}=Test1234!
RESTSelectEndpoint /users/register
RESTSetValue name ${name}
RESTSetValue email ${email}
RESTSetValue password ${password}
RESTSendRequest POST
*** Test Cases ***
Default Registration
Register User
RESTVerifyStatus 201
Custom Name Only
Register User name=Zoltan
RESTVerifyStatus 201
Missing Email
Register User email=$IGNORE
RESTVerifyStatus 400
Three levels: no argument = default sent, custom value = override, $IGNORE = field not sent.
Environment Configuration
Separate credentials and URLs from the service YAML using environment
files — like ~/.ssh/ keeps keys out of your projects.
Service YAML (safe for repo)
NotesAPI:
__self__:
class: okw_api_rest.library.OkwApiRestLibrary
base_url: ${BASE_URL}
content_type: ${CONTENT_TYPE}
Environment file (in user profile, NOT in repo)
# ~/.okw/env/env-test.yaml
BASE_URL: https://practice.expandtesting.com/notes/api
CONTENT_TYPE: application/x-www-form-urlencoded
Test file
RESTStart NotesAPI env-test
Search order for env files
| Priority | Path | Purpose |
|---|---|---|
| 1 | ~/.okw/env/ |
User profile (secure) |
| 2 | $OKW_ENV_DIR |
CI/CD override |
| 3 | locators/ next to test |
Development |
| 4 | OS environment variables | Fallback |
Authentication
Configured in YAML __self__ — no credentials in test code.
# Basic Auth
auth_type: basic
auth_user: ${API_USER}
auth_password: ${API_PASSWORD}
# API Key
auth_type: api_key
auth_header: X-API-Key
auth_key: ${API_KEY}
# Bearer Token (static)
auth_type: bearer
auth_token: ${AUTH_TOKEN}
OAuth 2.0 Client Credentials (machine-to-machine):
auth_type: oauth2_client_credentials
token_url: https://auth.example.com/oauth/token
client_id: ${CLIENT_ID}
client_secret: ${CLIENT_SECRET}
scope: read write
RESTStart fetches the token automatically — the test code is unaware of OAuth.
For dynamic tokens (login flow), use RESTMemorizeValue + RESTSetHeader.
SSL / Certificates
verify_ssl: false # self-signed certs
client_cert: ~/.okw/certs/client.pem # mTLS
client_key: ~/.okw/certs/client.key
ca_bundle: ~/.okw/certs/ca-bundle.pem # custom CA
Paths support ~ and $ENV_VAR expansion.
User profile structure
~/.okw/
env/
env-test.yaml # credentials + URLs
env-prod.yaml
certs/
client.pem # client certificate
client.key # private key
ca-bundle.pem # custom CA
Response Time Verification
Verify that the API responds within acceptable time limits:
RESTSendRequest GET
RESTVerifyResponseTime 500 # must respond under 500ms
RESTVerifyResponseTime $IGNORE # skip check
Request/Response Logging
RESTSendRequest automatically logs request and response with full
headers and formatted body in the Robot log. Sensitive fields
(password, token, secret) are masked with *** in the request body.
Headers are logged in cleartext for maximum observability.
>>> POST https://dummyjson.com/auth/login
Headers:
Content-Type: application/json
User-Agent: python-requests/2.31.0
Request Body:
{
"username": "emilys",
"password": "***"
}
<<< 200 OK
Headers:
Content-Type: application/json; charset=utf-8
Set-Cookie: accessToken=eyJ...; Path=/; HttpOnly
Response Body:
{
"accessToken": "eyJ...",
"username": "emilys"
}
Retry on Error
Automatic retry for transient HTTP errors (429, 502, 503, etc.). Configured in YAML — the test code stays unchanged.
MyAPI:
__self__:
base_url: https://api.example.com
content_type: application/json
retry_count: 3
retry_delay: 1000
retry_on: 429,502,503
| Setting | Default | Description |
|---|---|---|
retry_count |
0 (off) | Maximum number of retries |
retry_delay |
1000 | Delay between retries in milliseconds |
retry_on |
(none) | Status codes that trigger a retry |
Complete Example: Login + CRUD
*** Settings ***
Library okw_api_rest.library.OkwApiRestLibrary WITH NAME RESTAPI
*** Test Cases ***
Login And Create Note
RESTStart NotesAPI
# Login
RESTSelectEndpoint /users/login
RESTSetValue email user@example.com
RESTSetValue password Secret123!
RESTSendRequest POST
RESTVerifyStatus 200
RESTMemorizeValue data.token TOKEN
# Create note
RESTSelectEndpoint /notes
RESTSetHeader x-auth-token $MEM{TOKEN}
RESTSetValue title My Note
RESTSetValue description Created by OKW
RESTSetValue category Work
RESTSendRequest POST
RESTVerifyStatus 200
RESTMemorizeValue data.id NOTE_ID
# Delete note
RESTSelectEndpoint /notes/$MEM{NOTE_ID}
RESTSetHeader x-auth-token $MEM{TOKEN}
RESTSendRequest DELETE
RESTVerifyStatus 200
RESTStop
AI Test Generation
Test cases can be generated with any LLM (Claude, ChatGPT, Copilot, ...).
The system prompts for test generation are maintained centrally in
robotframework-okw4robot/prompts/.
Documentation
- Keyword Specification -- full keyword reference
- Keyword API (libdoc) -- auto-generated from docstrings
License
See LICENSE.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file robotframework_okw_api_rest-0.1.0.tar.gz.
File metadata
- Download URL: robotframework_okw_api_rest-0.1.0.tar.gz
- Upload date:
- Size: 54.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
edae08d640282cca1fddc221eb49f419f296b703055d0296f9496e430fb86010
|
|
| MD5 |
9a5d4e51a79c5e26d8606ebe76205520
|
|
| BLAKE2b-256 |
b510d4a212e9f438245b4807d6b82fbe583853141669da486d05edf241cf557f
|
Provenance
The following attestation bundles were made for robotframework_okw_api_rest-0.1.0.tar.gz:
Publisher:
publish-pypi.yml on Hrabovszki1023/robotframework-okw-api-rest
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
robotframework_okw_api_rest-0.1.0.tar.gz -
Subject digest:
edae08d640282cca1fddc221eb49f419f296b703055d0296f9496e430fb86010 - Sigstore transparency entry: 1903570463
- Sigstore integration time:
-
Permalink:
Hrabovszki1023/robotframework-okw-api-rest@b9920e195093e4711a2f13a2e118ee4dcdfc251b -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/Hrabovszki1023
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@b9920e195093e4711a2f13a2e118ee4dcdfc251b -
Trigger Event:
push
-
Statement type:
File details
Details for the file robotframework_okw_api_rest-0.1.0-py3-none-any.whl.
File metadata
- Download URL: robotframework_okw_api_rest-0.1.0-py3-none-any.whl
- Upload date:
- Size: 40.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0f626ea6e5b5259ee4b6aad7eae8513e5142fc98eb0aa6d068bd56d995ed9284
|
|
| MD5 |
1f8e9ee432f687f922efe8041399fe82
|
|
| BLAKE2b-256 |
0ea6b7f90b89127401b76e73f07ae32dbc1d1899aafd7e5b14f47dd18209fedd
|
Provenance
The following attestation bundles were made for robotframework_okw_api_rest-0.1.0-py3-none-any.whl:
Publisher:
publish-pypi.yml on Hrabovszki1023/robotframework-okw-api-rest
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
robotframework_okw_api_rest-0.1.0-py3-none-any.whl -
Subject digest:
0f626ea6e5b5259ee4b6aad7eae8513e5142fc98eb0aa6d068bd56d995ed9284 - Sigstore transparency entry: 1903570548
- Sigstore integration time:
-
Permalink:
Hrabovszki1023/robotframework-okw-api-rest@b9920e195093e4711a2f13a2e118ee4dcdfc251b -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/Hrabovszki1023
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@b9920e195093e4711a2f13a2e118ee4dcdfc251b -
Trigger Event:
push
-
Statement type: