hammerAPI 0.1.0__tar.gz → 0.1.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- hammerapi-0.1.1/PKG-INFO +450 -0
- hammerapi-0.1.1/README.md +434 -0
- {hammerapi-0.1.0 → hammerapi-0.1.1}/pyproject.toml +1 -1
- hammerapi-0.1.0/PKG-INFO +0 -450
- hammerapi-0.1.0/README.md +0 -434
- {hammerapi-0.1.0 → hammerapi-0.1.1}/.gitignore +0 -0
- {hammerapi-0.1.0 → hammerapi-0.1.1}/LICENSE +0 -0
- {hammerapi-0.1.0 → hammerapi-0.1.1}/examples/hammer_report.html +0 -0
- {hammerapi-0.1.0 → hammerapi-0.1.1}/examples/sample-code.py +0 -0
- {hammerapi-0.1.0 → hammerapi-0.1.1}/examples/sample-report.jpeg +0 -0
- {hammerapi-0.1.0 → hammerapi-0.1.1}/logo.png +0 -0
- {hammerapi-0.1.0 → hammerapi-0.1.1}/logo_readme.png +0 -0
- {hammerapi-0.1.0 → hammerapi-0.1.1}/src/hammerapi/__init__.py +0 -0
- {hammerapi-0.1.0 → hammerapi-0.1.1}/src/hammerapi/monitor.py +0 -0
- {hammerapi-0.1.0 → hammerapi-0.1.1}/src/hammerapi/reporter.py +0 -0
- {hammerapi-0.1.0 → hammerapi-0.1.1}/src/hammerapi/runner.py +0 -0
hammerapi-0.1.1/PKG-INFO
ADDED
|
@@ -0,0 +1,450 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: hammerAPI
|
|
3
|
+
Version: 0.1.1
|
|
4
|
+
Summary: A lightweight, blazing-fast, multi-threaded API performance and load testing library for Python. HammerAPI allows you to orchestrate parallel API requests smoothly while automatically collecting cross-platform hardware telemetry (CPU/RAM usage) from your local machine, compiling everything into a self-contained, interactive HTML dashboard.
|
|
5
|
+
Project-URL: Homepage, https://github.com/shayansaha85/hammerAPI
|
|
6
|
+
Author-email: Shayan <shayan851997@gmail.com>
|
|
7
|
+
License: MIT
|
|
8
|
+
License-File: LICENSE
|
|
9
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
10
|
+
Classifier: Operating System :: OS Independent
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Requires-Python: >=3.8
|
|
13
|
+
Requires-Dist: httpx>=0.24.0
|
|
14
|
+
Requires-Dist: psutil>=5.9.0
|
|
15
|
+
Description-Content-Type: text/markdown
|
|
16
|
+
|
|
17
|
+
<p align="center">
|
|
18
|
+
<img src="data:image;base64,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/GMzLdsAADoXaVRYdFhNTDpjb20uYWRvYmUueG1wAAAAAAA8P3hwYWNrZXQgYmVnaW49Iu+7vyIgaWQ9Ilc1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI/Pgo8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJBZG9iZSBYTVAgQ29yZSA1LjUtYzAyMSA3OS4xNTQ5MTEsIDIwMTMvMTAvMjktMTE6NDc6MTYgICAgICAgICI+CiAgIDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+CiAgICAgIDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiCiAgICAgICAgICAgIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIKICAgICAgICAgICAgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iCiAgICAgICAgICAgIHhtbG5zOnN0RXZ0PSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VFdmVudCMiCiAgICAgICAgICAgIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIKICAgICAgICAgICAgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIgogICAgICAgICAgICB4bWxuczp0aWZmPSJodHRwOi8vbnMuYWRvYmUuY29tL3RpZmYvMS4wLyIKICAgICAgICAgICAgeG1sbnM6ZXhpZj0iaHR0cDovL25zLmFkb2JlLmNvbS9leGlmLzEuMC8iPgogICAgICAgICA8eG1wOkNyZWF0b3JUb29sPkFkb2JlIFBob3Rvc2hvcCBDQyAoV2luZG93cyk8L3htcDpDcmVhdG9yVG9vbD4KICAgICAgICAgPHhtcDpDcmVhdGVEYXRlPjIwMjYtMDYtMjBUMDE6MDI6MDIrMDU6MzA8L3htcDpDcmVhdGVEYXRlPgogICAgICAgICA8eG1wOk1ldGFkYXRhRGF0ZT4yMDI2LTA2LTIwVDAxOjAyOjAyKzA1OjMwPC94bXA6TWV0YWRhdGFEYXRlPgogICAgICAgICA8eG1wOk1vZGlmeURhdGU+MjAyNi0wNi0yMFQwMTowMjowMiswNTozMDwveG1wOk1vZGlmeURhdGU+CiAgICAgICAgIDx4bXBNTTpJbnN0YW5jZUlEPnhtcC5paWQ6MTgxOWI0MTMtYTAxZi1iNDQ3LTgyOTgtYWQyYWJmNDU4NmQzPC94bXBNTTpJbnN0YW5jZUlEPgogICAgICAgICA8eG1wTU06RG9jdW1lbnRJRD54bXAuZGlkOjkwYjgwNDRhLTg4YjItYjA0MC05NDM3LWUwNDUxNmFmYTA5NDwveG1wTU06RG9jdW1lbnRJRD4KICAgICAgICAgPHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD54bXAuZGlkOjkwYjgwNDRhLTg4YjItYjA0MC05NDM3LWUwNDUxNmFmYTA5NDwveG1wTU06T3JpZ2luYWxEb2N1bWVudElEPgogICAgICAgICA8eG1wTU06SGlzdG9yeT4KICAgICAgICAgICAgPHJkZjpTZXE+CiAgICAgICAgICAgICAgIDxyZGY6bGkgcmRmOnBhcnNlVHlwZT0iUmVzb3VyY2UiPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6YWN0aW9uPmNyZWF0ZWQ8L3N0RXZ0OmFjdGlvbj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0Omluc3RhbmNlSUQ+eG1wLmlpZDo5MGI4MDQ0YS04OGIyLWIwNDAtOTQzNy1lMDQ1MTZhZmEwOTQ8L3N0RXZ0Omluc3RhbmNlSUQ+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDp3aGVuPjIwMjYtMDYtMjBUMDE6MDI6MDIrMDU6MzA8L3N0RXZ0OndoZW4+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDpzb2Z0d2FyZUFnZW50PkFkb2JlIFBob3Rvc2hvcCBDQyAoV2luZG93cyk8L3N0RXZ0OnNvZnR3YXJlQWdlbnQ+CiAgICAgICAgICAgICAgIDwvcmRmOmxpPgogICAgICAgICAgICAgICA8cmRmOmxpIHJkZjpwYXJzZVR5cGU9IlJlc291cmNlIj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OmFjdGlvbj5zYXZlZDwvc3RFdnQ6YWN0aW9uPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6aW5zdGFuY2VJRD54bXAuaWlkOjE4MTliNDEzLWEwMWYtYjQ0Ny04Mjk4LWFkMmFiZjQ1ODZkMzwvc3RFdnQ6aW5zdGFuY2VJRD4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OndoZW4+MjAyNi0wNi0yMFQwMTowMjowMiswNTozMDwvc3RFdnQ6d2hlbj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OnNvZnR3YXJlQWdlbnQ+QWRvYmUgUGhvdG9zaG9wIENDIChXaW5kb3dzKTwvc3RFdnQ6c29mdHdhcmVBZ2VudD4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OmNoYW5nZWQ+Lzwvc3RFdnQ6Y2hhbmdlZD4KICAgICAgICAgICAgICAgPC9yZGY6bGk+CiAgICAgICAgICAgIDwvcmRmOlNlcT4KICAgICAgICAgPC94bXBNTTpIaXN0b3J5PgogICAgICAgICA8ZGM6Zm9ybWF0PmltYWdlL3BuZzwvZGM6Zm9ybWF0PgogICAgICAgICA8cGhvdG9zaG9wOkNvbG9yTW9kZT4zPC9waG90b3Nob3A6Q29sb3JNb2RlPgogICAgICAgICA8cGhvdG9zaG9wOklDQ1Byb2ZpbGU+c1JHQiBJRUM2MTk2Ni0yLjE8L3Bob3Rvc2hvcDpJQ0NQcm9maWxlPgogICAgICAgICA8dGlmZjpPcmllbnRhdGlvbj4xPC90aWZmOk9yaWVudGF0aW9uPgogICAgICAgICA8dGlmZjpYUmVzb2x1dGlvbj4zMDAwMDAwLzEwMDAwPC90aWZmOlhSZXNvbHV0aW9uPgogICAgICAgICA8dGlmZjpZUmVzb2x1dGlvbj4zMDAwMDAwLzEwMDAwPC90aWZmOllSZXNvbHV0aW9uPgogICAgICAgICA8dGlmZjpSZXNvbHV0aW9uVW5pdD4yPC90aWZmOlJlc29sdXRpb25Vbml0PgogICAgICAgICA8ZXhpZjpDb2xvclNwYWNlPjE8L2V4aWY6Q29sb3JTcGFjZT4KICAgICAgICAgPGV4aWY6UGl4ZWxYRGltZW5zaW9uPjIwMDwvZXhpZjpQaXhlbFhEaW1lbnNpb24+CiAgICAgICAgIDxleGlmOlBpeGVsWURpbWVuc2lvbj4xMTc8L2V4aWY6UGl4ZWxZRGltZW5zaW9uPgogICAgICA8L3JkZjpEZXNjcmlwdGlvbj4KICAgPC9yZGY6UkRGPgo8L3g6eG1wbWV0YT4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAKPD94cGFja2V0IGVuZD0idyI/PgOHOmcAAAAgY0hSTQAAeiUAAICDAAD5/wAAgOkAAHUwAADqYAAAOpgAABdvkl/FRgAAJf9JREFUeNrsnXmcHFXV97/nVi+zzyQhCZAAIWEJEVBECESM7CgPLiyur7K4i8sLj/pREV4VN0QFF/RBZRcR2QQVkH0nbMoOD6uJSUgIScgymZme7q77/nFPdd+u6e7pIZNkMlO/z6c/M91dXd1V9/7uWe85Yq0lQYIE1WGSW5AgQUKQBAkSgiRIMNxI+U9m7v/H9T6hVdalGP22Tb1rFUCwiB4jWAxgvNcMNjCwq8HuFMD2AbbLQCbAFgLs2gAWBtgXDPbpFHZNCkug3xdgSfkPsaT1/1p/448ASGMxpefVxywE2ghpIqSIjOoxffMdp9cmSIKNQyqBo4D3A3MFu52pIJMt/S9YcP+vBOZZuB64Elie3MlExRptaAK+AbwocLVgP25AyVFN4uBLmvEG/svAbwReAH4JzEhuaUKQ0YJjgecFfmRgRpwEZfXLJ4aNHVM6tkuwXxJ4HvhBcms3og2SYNjRAVwA9mhfjfLU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">
|
|
19
|
+
</p>
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
[](https://pypi.org/project/hammerapi/)
|
|
23
|
+
[](https://opensource.org/licenses/MIT)
|
|
24
|
+
|
|
25
|
+
A lightweight, blazing-fast, multi-threaded API performance and load testing library for Python.
|
|
26
|
+
|
|
27
|
+
**HammerAPI** helps developers, QA engineers, SREs, and performance testers stress-test REST APIs with minimal code while automatically collecting local machine telemetry (CPU/RAM) and generating beautiful interactive HTML reports.
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## 🚀 Installation
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
pip install hammerapi
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## ✨ Features
|
|
40
|
+
|
|
41
|
+
### 🧵 Concurrent API Execution
|
|
42
|
+
|
|
43
|
+
Run hundreds or thousands of requests using a configurable thread pool.
|
|
44
|
+
|
|
45
|
+
### ⏱️ Multiple Execution Modes
|
|
46
|
+
|
|
47
|
+
* Run each test case exactly once
|
|
48
|
+
* Run continuously for a fixed duration
|
|
49
|
+
* Mix multiple endpoints in the same workload
|
|
50
|
+
|
|
51
|
+
### 🌐 Full HTTP Support
|
|
52
|
+
|
|
53
|
+
Supports:
|
|
54
|
+
|
|
55
|
+
* GET
|
|
56
|
+
* POST
|
|
57
|
+
* PUT
|
|
58
|
+
* PATCH
|
|
59
|
+
* DELETE
|
|
60
|
+
|
|
61
|
+
### 🔐 Authentication Support
|
|
62
|
+
|
|
63
|
+
Works with:
|
|
64
|
+
|
|
65
|
+
* Bearer Tokens
|
|
66
|
+
* API Keys
|
|
67
|
+
* Custom Headers
|
|
68
|
+
* Session Cookies
|
|
69
|
+
|
|
70
|
+
### 📊 Performance Metrics
|
|
71
|
+
|
|
72
|
+
Automatically captures:
|
|
73
|
+
|
|
74
|
+
* Response Time
|
|
75
|
+
* Success / Failure Counts
|
|
76
|
+
* Request Throughput
|
|
77
|
+
* Average Latency
|
|
78
|
+
* P90 Latency
|
|
79
|
+
* P95 Latency
|
|
80
|
+
* P99 Latency
|
|
81
|
+
|
|
82
|
+
### 🖥️ System Resource Monitoring
|
|
83
|
+
|
|
84
|
+
Captures local machine:
|
|
85
|
+
|
|
86
|
+
* CPU Utilization
|
|
87
|
+
* RAM Utilization
|
|
88
|
+
* Operating System Information
|
|
89
|
+
|
|
90
|
+
### 📈 Interactive HTML Dashboard
|
|
91
|
+
|
|
92
|
+
Generate beautiful standalone reports with:
|
|
93
|
+
|
|
94
|
+
* Charts
|
|
95
|
+
* Percentiles
|
|
96
|
+
* Error Analysis
|
|
97
|
+
* Resource Consumption Trends
|
|
98
|
+
* Request Distribution
|
|
99
|
+
|
|
100
|
+
### 🌍 Cross Platform
|
|
101
|
+
|
|
102
|
+
Works on:
|
|
103
|
+
|
|
104
|
+
* Windows
|
|
105
|
+
* Linux
|
|
106
|
+
* macOS
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
# 📁 Project Structure
|
|
111
|
+
|
|
112
|
+
```text
|
|
113
|
+
hammerAPI/
|
|
114
|
+
├── LICENSE
|
|
115
|
+
├── README.md
|
|
116
|
+
├── pyproject.toml
|
|
117
|
+
├── logo.png
|
|
118
|
+
├── logo_readme.png
|
|
119
|
+
├── src/
|
|
120
|
+
│ └── hammerapi/
|
|
121
|
+
│ ├── __init__.py
|
|
122
|
+
│ ├── monitor.py
|
|
123
|
+
│ ├── reporter.py
|
|
124
|
+
│ └── runner.py
|
|
125
|
+
└── examples/
|
|
126
|
+
├── sample-code.py
|
|
127
|
+
├── sample-report.html
|
|
128
|
+
└── sample-report.jpeg
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
---
|
|
132
|
+
|
|
133
|
+
# Quick Start
|
|
134
|
+
|
|
135
|
+
## Simple GET Request
|
|
136
|
+
|
|
137
|
+
```python
|
|
138
|
+
from hammerapi import HammerAPI
|
|
139
|
+
|
|
140
|
+
hammer = HammerAPI(max_workers=5)
|
|
141
|
+
|
|
142
|
+
hammer.add_test(
|
|
143
|
+
method="GET",
|
|
144
|
+
url="https://jsonplaceholder.typicode.com/posts/1"
|
|
145
|
+
)
|
|
146
|
+
|
|
147
|
+
hammer.run()
|
|
148
|
+
|
|
149
|
+
hammer.generate_report()
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
---
|
|
153
|
+
|
|
154
|
+
## Multiple Endpoints
|
|
155
|
+
|
|
156
|
+
```python
|
|
157
|
+
from hammerapi import HammerAPI
|
|
158
|
+
|
|
159
|
+
hammer = HammerAPI(max_workers=10)
|
|
160
|
+
|
|
161
|
+
hammer.add_test(
|
|
162
|
+
"GET",
|
|
163
|
+
"https://jsonplaceholder.typicode.com/posts/1"
|
|
164
|
+
)
|
|
165
|
+
|
|
166
|
+
hammer.add_test(
|
|
167
|
+
"GET",
|
|
168
|
+
"https://jsonplaceholder.typicode.com/users/1"
|
|
169
|
+
)
|
|
170
|
+
|
|
171
|
+
hammer.add_test(
|
|
172
|
+
"GET",
|
|
173
|
+
"https://jsonplaceholder.typicode.com/comments/1"
|
|
174
|
+
)
|
|
175
|
+
|
|
176
|
+
hammer.run()
|
|
177
|
+
|
|
178
|
+
hammer.generate_report()
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
---
|
|
182
|
+
|
|
183
|
+
## POST Request with JSON Payload
|
|
184
|
+
|
|
185
|
+
```python
|
|
186
|
+
from hammerapi import HammerAPI
|
|
187
|
+
|
|
188
|
+
hammer = HammerAPI()
|
|
189
|
+
|
|
190
|
+
hammer.add_test(
|
|
191
|
+
method="POST",
|
|
192
|
+
url="https://jsonplaceholder.typicode.com/posts",
|
|
193
|
+
json={
|
|
194
|
+
"title": "HammerAPI",
|
|
195
|
+
"body": "Load Testing",
|
|
196
|
+
"userId": 1
|
|
197
|
+
}
|
|
198
|
+
)
|
|
199
|
+
|
|
200
|
+
hammer.run()
|
|
201
|
+
hammer.generate_report()
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
---
|
|
205
|
+
|
|
206
|
+
## Authenticated API Testing
|
|
207
|
+
|
|
208
|
+
```python
|
|
209
|
+
from hammerapi import HammerAPI
|
|
210
|
+
|
|
211
|
+
hammer = HammerAPI()
|
|
212
|
+
|
|
213
|
+
hammer.add_test(
|
|
214
|
+
method="GET",
|
|
215
|
+
url="https://api.example.com/users",
|
|
216
|
+
headers={
|
|
217
|
+
"Authorization": "Bearer YOUR_TOKEN"
|
|
218
|
+
}
|
|
219
|
+
)
|
|
220
|
+
|
|
221
|
+
hammer.run()
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
---
|
|
225
|
+
|
|
226
|
+
## API Key Authentication
|
|
227
|
+
|
|
228
|
+
```python
|
|
229
|
+
from hammerapi import HammerAPI
|
|
230
|
+
|
|
231
|
+
hammer = HammerAPI()
|
|
232
|
+
|
|
233
|
+
hammer.add_test(
|
|
234
|
+
method="GET",
|
|
235
|
+
url="https://api.example.com/data",
|
|
236
|
+
headers={
|
|
237
|
+
"x-api-key": "YOUR_API_KEY"
|
|
238
|
+
}
|
|
239
|
+
)
|
|
240
|
+
|
|
241
|
+
hammer.run()
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
---
|
|
245
|
+
|
|
246
|
+
## Query Parameters
|
|
247
|
+
|
|
248
|
+
```python
|
|
249
|
+
from hammerapi import HammerAPI
|
|
250
|
+
|
|
251
|
+
hammer = HammerAPI()
|
|
252
|
+
|
|
253
|
+
hammer.add_test(
|
|
254
|
+
method="GET",
|
|
255
|
+
url="https://api.example.com/search",
|
|
256
|
+
params={
|
|
257
|
+
"page": 1,
|
|
258
|
+
"limit": 100
|
|
259
|
+
}
|
|
260
|
+
)
|
|
261
|
+
|
|
262
|
+
hammer.run()
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
---
|
|
266
|
+
|
|
267
|
+
## Custom Headers
|
|
268
|
+
|
|
269
|
+
```python
|
|
270
|
+
from hammerapi import HammerAPI
|
|
271
|
+
|
|
272
|
+
hammer = HammerAPI()
|
|
273
|
+
|
|
274
|
+
hammer.add_test(
|
|
275
|
+
method="GET",
|
|
276
|
+
url="https://api.example.com/data",
|
|
277
|
+
headers={
|
|
278
|
+
"Environment": "QA",
|
|
279
|
+
"Client": "HammerAPI"
|
|
280
|
+
}
|
|
281
|
+
)
|
|
282
|
+
|
|
283
|
+
hammer.run()
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
---
|
|
287
|
+
|
|
288
|
+
## PUT Request
|
|
289
|
+
|
|
290
|
+
```python
|
|
291
|
+
hammer.add_test(
|
|
292
|
+
method="PUT",
|
|
293
|
+
url="https://api.example.com/user/1",
|
|
294
|
+
json={
|
|
295
|
+
"name": "John Doe"
|
|
296
|
+
}
|
|
297
|
+
)
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
---
|
|
301
|
+
|
|
302
|
+
## PATCH Request
|
|
303
|
+
|
|
304
|
+
```python
|
|
305
|
+
hammer.add_test(
|
|
306
|
+
method="PATCH",
|
|
307
|
+
url="https://api.example.com/user/1",
|
|
308
|
+
json={
|
|
309
|
+
"status": "active"
|
|
310
|
+
}
|
|
311
|
+
)
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
---
|
|
315
|
+
|
|
316
|
+
## DELETE Request
|
|
317
|
+
|
|
318
|
+
```python
|
|
319
|
+
hammer.add_test(
|
|
320
|
+
method="DELETE",
|
|
321
|
+
url="https://api.example.com/user/1"
|
|
322
|
+
)
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
---
|
|
326
|
+
|
|
327
|
+
# 🔥 Load Testing For Fixed Duration
|
|
328
|
+
|
|
329
|
+
Continuously hit endpoints for a specific duration.
|
|
330
|
+
|
|
331
|
+
```python
|
|
332
|
+
from hammerapi import HammerAPI
|
|
333
|
+
|
|
334
|
+
hammer = HammerAPI(max_workers=25)
|
|
335
|
+
|
|
336
|
+
hammer.add_test(
|
|
337
|
+
"GET",
|
|
338
|
+
"https://api.example.com/health"
|
|
339
|
+
)
|
|
340
|
+
|
|
341
|
+
hammer.run(duration_seconds=60)
|
|
342
|
+
|
|
343
|
+
hammer.generate_report("load_test_report.html")
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
This will continuously execute requests across 25 worker threads for 60 seconds.
|
|
347
|
+
|
|
348
|
+
---
|
|
349
|
+
|
|
350
|
+
# ⚡ High Concurrency Example
|
|
351
|
+
|
|
352
|
+
```python
|
|
353
|
+
from hammerapi import HammerAPI
|
|
354
|
+
|
|
355
|
+
hammer = HammerAPI(max_workers=100)
|
|
356
|
+
|
|
357
|
+
hammer.add_test(
|
|
358
|
+
"GET",
|
|
359
|
+
"https://api.example.com/health"
|
|
360
|
+
)
|
|
361
|
+
|
|
362
|
+
hammer.run(duration_seconds=120)
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
Perfect for:
|
|
366
|
+
|
|
367
|
+
* Load Testing
|
|
368
|
+
* Stress Testing
|
|
369
|
+
* Smoke Testing
|
|
370
|
+
* Capacity Planning
|
|
371
|
+
|
|
372
|
+
---
|
|
373
|
+
|
|
374
|
+
# 📄 Generate Report
|
|
375
|
+
|
|
376
|
+
```python
|
|
377
|
+
hammer.generate_report(
|
|
378
|
+
output_path="hammer_report.html"
|
|
379
|
+
)
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
Generated report includes:
|
|
383
|
+
|
|
384
|
+
* Total Requests
|
|
385
|
+
* Success Rate
|
|
386
|
+
* Failure Rate
|
|
387
|
+
* Average Response Time
|
|
388
|
+
* P90 Latency
|
|
389
|
+
* P95 Latency
|
|
390
|
+
* P99 Latency
|
|
391
|
+
* CPU Utilization
|
|
392
|
+
* RAM Utilization
|
|
393
|
+
* Throughput Analysis
|
|
394
|
+
|
|
395
|
+
---
|
|
396
|
+
|
|
397
|
+
# Report Snapshot
|
|
398
|
+
|
|
399
|
+

|
|
400
|
+
|
|
401
|
+
---
|
|
402
|
+
|
|
403
|
+
# Example Files
|
|
404
|
+
|
|
405
|
+
See the `examples/` directory:
|
|
406
|
+
|
|
407
|
+
```text
|
|
408
|
+
examples/
|
|
409
|
+
├── sample-code.py
|
|
410
|
+
├── sample-report.html
|
|
411
|
+
└── sample-report.jpeg
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
---
|
|
415
|
+
|
|
416
|
+
# Use Cases
|
|
417
|
+
|
|
418
|
+
### QA Engineers
|
|
419
|
+
|
|
420
|
+
* Regression Testing
|
|
421
|
+
* Smoke Testing
|
|
422
|
+
* API Validation
|
|
423
|
+
|
|
424
|
+
### SRE Teams
|
|
425
|
+
|
|
426
|
+
* Capacity Testing
|
|
427
|
+
* Reliability Benchmarking
|
|
428
|
+
* SLA Validation
|
|
429
|
+
|
|
430
|
+
### Developers
|
|
431
|
+
|
|
432
|
+
* Endpoint Benchmarking
|
|
433
|
+
* Performance Optimization
|
|
434
|
+
|
|
435
|
+
### DevOps Engineers
|
|
436
|
+
|
|
437
|
+
* Pre-Deployment Validation
|
|
438
|
+
* Infrastructure Load Testing
|
|
439
|
+
|
|
440
|
+
---
|
|
441
|
+
|
|
442
|
+
# License
|
|
443
|
+
|
|
444
|
+
MIT License
|
|
445
|
+
|
|
446
|
+
---
|
|
447
|
+
|
|
448
|
+
### Attribution
|
|
449
|
+
|
|
450
|
+
<a href="https://www.flaticon.com/free-icons/hammer" title="hammer icons">Hammer icons created by nawicon - Flaticon</a>
|