A lightweight, developer-friendly Python library for API test automation
Project description
APItestGenie
APItestGenie is a lightweight, developer-friendly Python library designed to simplify API testing for automation engineers.
Overview
APItestGenie provides:
- Two ways to perform API requests: Client mode and Simple mode
- Built-in JSON assertions and JSON path assertions for nested responses
- Header assertions
- Response time assertions
- JSON schema validation (optional)
- Retry logic with fixed or exponential backoff delay
- Optional request logging
- GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS support
- Timeout and headers support
- A complete pytest suite
- A modern Python packaging layout using the src structure
Installation
Clone the repository:
git clone https://github.com/Akash402/apitestgenie.git
cd apitestgenie
Create and activate a virtual environment:
python3 -m venv venv
source venv/bin/activate
Install dependencies:
pip install httpx pytest
(Optional) Install the library locally in editable mode:
pip install -e .
For JSON schema validation support:
pip install apitestgenie[schema]
Usage Examples
Client Mode
from apitestgenie.client import ApiClient
api = ApiClient("https://jsonplaceholder.typicode.com", timeout=10)
response = api.get("/posts/1", retries=2)
response.assert_status(200)
response.assert_json_value("id", 1)
POST example:
resp = api.post("/posts", json={"title": "foo"})
resp.assert_status(201)
PUT example:
resp = api.put("/posts/1", json={"id": 1, "title": "updated"})
resp.assert_status(200)
DELETE example:
resp = api.delete("/posts/1")
resp.assert_status(200)
HEAD and OPTIONS example:
resp = api.head("/posts/1")
resp.assert_status(200)
resp = api.options("/posts/1")
assert resp.status_code in (200, 204)
Simple Mode
from apitestgenie.simple import get
response = get("https://jsonplaceholder.typicode.com/posts/1")
response.assert_status(200)
print(response.json())
POST example:
from apitestgenie.simple import post
resp = post("https://jsonplaceholder.typicode.com/posts", json={"hello": "world"})
resp.assert_status(201)
HEAD and OPTIONS example:
from apitestgenie.simple import head, options
resp = head("https://jsonplaceholder.typicode.com/posts/1")
resp.assert_status(200)
resp = options("https://jsonplaceholder.typicode.com/posts/1")
assert resp.status_code in (200, 204)
Retry and timeout example:
resp = get(
"https://jsonplaceholder.typicode.com/posts/1",
retries=3,
retry_delay=1,
retry_on_status=[500],
timeout=5
)
JSON Assertions
resp.assert_status(200)
resp.assert_json_key("id")
resp.assert_json_value("id", 1)
resp.assert_json_path_exists("user.address.city")
resp.assert_json_path_value("user.address.city", "London")
Header Assertions
resp.assert_header("content-type")
resp.assert_header_value("content-type", "application/json")
Header name matching is case-insensitive.
Response Time Assertion
resp.assert_response_time(2.0) # fails if response took more than 2 seconds
JSON Schema Validation
Requires jsonschema (pip install apitestgenie[schema]):
schema = {
"type": "object",
"properties": {
"id": {"type": "integer"},
"title": {"type": "string"}
},
"required": ["id"]
}
resp.assert_json_schema(schema)
Retry with Exponential Backoff
resp = api.get(
"/posts/1",
retries=3,
retry_delay=1,
retry_on_status=[503],
retry_backoff=True # sleeps 2s, 4s, 8s between retries
)
Without retry_backoff=True (default), the delay is fixed at retry_delay seconds.
Logging
Pass logging=True to emit INFO-level log lines for each request (method, URL, status, elapsed):
import logging
logging.basicConfig(level=logging.INFO)
api = ApiClient("https://jsonplaceholder.typicode.com", logging=True)
api.get("/posts/1")
# INFO apitestgenie: GET https://jsonplaceholder.typicode.com/posts/1 -> 200 (0.123s)
In simple mode:
get("https://jsonplaceholder.typicode.com/posts/1", logging=True)
Logging is off by default.
Chaining Assertions
All assertion methods return self, so they can be chained:
api.get("/posts/1") \
.assert_status(200) \
.assert_response_time(2.0) \
.assert_header("content-type") \
.assert_json_key("id") \
.assert_json_value("id", 1)
Running Tests
pytest
Project Structure
apitestgenie/
│
├── src/
│ └── apitestgenie/
│ ├── client.py
│ ├── simple.py
│ ├── response_wrapper.py
│ └── __init__.py
│
├── tests/
├── playground.py
├── pytest.ini
├── README.md
└── SCOPE.md
Changelog
v1.1.0
- Added
assert_header(name)andassert_header_value(name, expected)toResponseWrapper - Added
assert_response_time(max_seconds)toResponseWrapper - Added
assert_json_schema(schema)toResponseWrapper(requiresjsonschema) - Added
retry_backoff=Trueoption for exponential backoff on retries - Added optional
logging=Trueparameter onApiClientand all simple mode functions - Added
head()andoptions()to bothApiClientand simple mode
v1.0.0
- Initial release with GET, POST, PUT, PATCH, DELETE
- JSON and JSON path assertions
- Basic retry logic
- ResponseWrapper abstraction
- Client and simple modes
License
MIT License. See LICENSE for details.
Project details
Release history Release notifications | RSS feed
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 apitestgenie-1.1.0.tar.gz.
File metadata
- Download URL: apitestgenie-1.1.0.tar.gz
- Upload date:
- Size: 12.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
dd9793f7a0f424b35656e67c966608616c369efdde6e17ca0dc3958663407a8d
|
|
| MD5 |
47ba7a3fd6ff9d29716a345139c23d16
|
|
| BLAKE2b-256 |
d000f85203d8bdb16bf38f516205a4611906096b17248632d1907f82ad681e69
|
File details
Details for the file apitestgenie-1.1.0-py3-none-any.whl.
File metadata
- Download URL: apitestgenie-1.1.0-py3-none-any.whl
- Upload date:
- Size: 8.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
dc4a4b47250df5bce5f6dba41d6f8e3fdcba41cf6005d1d183980593d67796a2
|
|
| MD5 |
1efd8b96b524c392c143815c1ecdb9ee
|
|
| BLAKE2b-256 |
38b716568d5efa120602730bd6d493ff64c20f6859b16db54a359b9689db490d
|