Async distributed load-testing framework contracts and runtime
Project description
vikhry
vikhry is an async distributed load-testing framework built for high concurrency, horizontal scaling, and workloads that need globally unique resources.
It combines:
- a Python runtime for writing virtual-user scenarios;
- an orchestrator that manages test lifecycle and aggregates metrics;
- worker processes that execute VUs;
- Redis as the shared coordination layer;
- a built-in web UI served by the orchestrator.
Architecture
At a high level, vikhry has four runtime parts:
orchestratorHandles the test state machine, exposes HTTP/WebSocket APIs, serves the UI, and coordinates workers.workerRuns VU tasks, processes orchestrator commands, publishes metrics, and manages acquired resources.redisStores shared state, worker presence, user assignments, resources, and metric streams.uiA React frontend bundled into the Python package and served by the orchestrator.
Lifecycle flow:
IDLE -> PREPARING -> RUNNING -> STOPPING -> IDLE
Install and run
Install from PyPI:
pip install vikhry
Start local infrastructure:
vikhry infra up --worker-count 3 --scenario my_scenario:DemoVU
This command:
- checks that Docker is available;
- starts Redis in a Docker container;
- starts the orchestrator;
- starts the requested number of workers.
Open:
- UI:
http://127.0.0.1:8080/ - API:
http://127.0.0.1:8080
Stop everything:
vikhry infra down
Example test file
Create my_scenario.py:
from __future__ import annotations
from typing import Any
from vikhry import ReqwestClient, VU, between, resource, step
@resource(name="users")
async def create_user(resource_id: int | str, _ctx: object) -> dict[str, Any]:
rid = str(resource_id)
return {
"resource_id": rid,
"username": f"user_{rid}",
"password": "password",
}
class DemoVU(VU):
http = ReqwestClient(timeout=5.0)
async def on_init(self, base_url: str) -> None:
self.http = self.http(base_url=base_url)
async def on_start(self) -> None:
self.user = await self.resources.acquire("users")
async def on_stop(self) -> None:
await self.resources.release("users", str(self.user["resource_id"]))
@step(name="login", weight=1.0, every_s=between(10.0, 15.0), timeout=5.0)
async def login(self) -> None:
response = await self.http.post(
"/auth",
json={
"username": self.user["username"],
"password": self.user["password"],
},
)
if response.status >= 400:
raise RuntimeError(f"login returned HTTP {response.status}")
@step(name="catalog", weight=3.0, requires=("login",), every_s=between(0.2, 1.0))
async def catalog(self) -> None:
response = await self.http.get("/catalog")
if response.status >= 400:
raise RuntimeError(f"catalog returned HTTP {response.status}")
Run it:
vikhry infra up --worker-count 3 --scenario my_scenario:DemoVU
Test authoring capabilities
vikhry scenarios are plain Python classes built on top of the VU DSL.
What you can define:
VU.on_init(...)Accept runtime parameters for each VU instance.VU.on_start()/VU.on_stop()Allocate and release state or resources around the VU lifecycle.@step(...)Define executable load steps.@resource(name="...")Define global resource factories managed through Redis-backed pools.ReqwestClientUse an async HTTP client for relative or absolute requests.emit_metric(...)and@metric(...)Publish custom metrics in addition to automatic HTTP and step metrics.
Step controls:
weightWeighted random scheduling between eligible steps.requiresDeclare prerequisites by step name.every_sThrottle step execution to a fixed or randomized interval.timeoutFail a step if it exceeds its maximum runtime.
Resource model:
- resource factories create globally tracked objects;
- workers acquire resources with
self.resources.acquire(name); - workers release them with
self.resources.release(name, resource_id).
Packaging and release
The Python package includes the built UI assets.
Build locally:
./scripts/build_frontend.sh
uv build
Release automation:
.github/workflows/release-artifacts.ymlBuilds the frontend, createswheelandsdist, and publishes the package to PyPI usingPYPI_TOKEN..github/workflows/docker-image.ymlBuilds and publishes the runtime Docker image toghcr.io/<owner>/<repo>on every branch push.
The package version is taken from project.version in pyproject.toml.
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 vikhry-0.1.1.tar.gz.
File metadata
- Download URL: vikhry-0.1.1.tar.gz
- Upload date:
- Size: 361.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e56bd92ecd64a8d7dac12e2a314bf03ac82dbb7c9c113c39cb94c98896ac6f37
|
|
| MD5 |
5e28955320189c306017bdfcdc94a7e7
|
|
| BLAKE2b-256 |
6cc119d4dd34a8793dd27a7fea3a24eb162426635ff351b4146f40029dc3d7d4
|
Provenance
The following attestation bundles were made for vikhry-0.1.1.tar.gz:
Publisher:
release-artifacts.yml on gigimon/vikhry
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
vikhry-0.1.1.tar.gz -
Subject digest:
e56bd92ecd64a8d7dac12e2a314bf03ac82dbb7c9c113c39cb94c98896ac6f37 - Sigstore transparency entry: 1076858069
- Sigstore integration time:
-
Permalink:
gigimon/vikhry@a0fe0a9dc6a8e76278a70cc8bafc32a832eef937 -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/gigimon
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release-artifacts.yml@a0fe0a9dc6a8e76278a70cc8bafc32a832eef937 -
Trigger Event:
push
-
Statement type:
File details
Details for the file vikhry-0.1.1-py3-none-any.whl.
File metadata
- Download URL: vikhry-0.1.1-py3-none-any.whl
- Upload date:
- Size: 250.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
35f27f5d45728709b4f29842a910d564909a17e16535fcd57c07c25525f941e4
|
|
| MD5 |
23b2e0c152c3d21c27bd68cfa531c562
|
|
| BLAKE2b-256 |
46c08e1ec61b26573d8f97f92e1732a19cffffb379634de8fbad519b26dfae84
|
Provenance
The following attestation bundles were made for vikhry-0.1.1-py3-none-any.whl:
Publisher:
release-artifacts.yml on gigimon/vikhry
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
vikhry-0.1.1-py3-none-any.whl -
Subject digest:
35f27f5d45728709b4f29842a910d564909a17e16535fcd57c07c25525f941e4 - Sigstore transparency entry: 1076858079
- Sigstore integration time:
-
Permalink:
gigimon/vikhry@a0fe0a9dc6a8e76278a70cc8bafc32a832eef937 -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/gigimon
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release-artifacts.yml@a0fe0a9dc6a8e76278a70cc8bafc32a832eef937 -
Trigger Event:
push
-
Statement type: