async-xenapi (Python)
An async library for XenAPI.
Install
pip install async-xenapi
Or with uv:
uv add async-xenapi
Requires Python 3.12+.
Usage
import asyncio
from async_xenapi import AsyncXenAPISession
async def main():
session = AsyncXenAPISession("https://xen-host")
await session.login_with_password("root", "password")
try:
vms = await session.xenapi.VM.get_all()
for vm in vms:
record = await session.xenapi.VM.get_record(vm)
print(record["name_label"])
finally:
await session.logout()
asyncio.run(main())
Any dotted method path under session.xenapi maps directly to the corresponding JSON-RPC call.
See the XenAPI Reference for all available classes and fields.
Best Practices
1. Use get_all_records() instead of N+1 queries
The single biggest performance win. Instead of fetching a list of refs then querying each one individually, fetch everything in one call:
# SLOW — N+1 round-trips (1 for get_all + N for each get_name_label)
vms = await session.xenapi.VM.get_all()
for vm in vms:
name = await session.xenapi.VM.get_name_label(vm)
print(name)
# FAST — 1 round-trip, returns {ref: {field: value, ...}, ...}
records = await session.xenapi.VM.get_all_records()
for ref, rec in records.items():
if not rec["is_a_template"] and not rec["is_a_snapshot"]:
print(f"{rec['name_label']} ({rec['power_state']})")
This applies to every XenAPI class: host, SR, network, VM, pool, etc.
2. Use asyncio.gather() for independent calls
When you need results from multiple independent API calls, run them concurrently:
# SLOW — sequential, each awaits the previous
major = await session.xenapi.host.get_API_version_major(host)
minor = await session.xenapi.host.get_API_version_minor(host)
# FAST — concurrent, both requests in flight at the same time
major, minor = await asyncio.gather(
session.xenapi.host.get_API_version_major(host),
session.xenapi.host.get_API_version_minor(host),
)
You can also gather across different classes:
hosts, vms, networks = await asyncio.gather(
session.xenapi.host.get_all_records(),
session.xenapi.VM.get_all_records(),
session.xenapi.network.get_all_records(),
)
3. Always clean up the session
Use try/finally to ensure logout() is called, which closes both the server-side session and the underlying HTTP connection:
session = AsyncXenAPISession("https://xen-host")
await session.login_with_password("root", "password")
try:
# ... your code ...
finally:
await session.logout()
Key Takeaways
| Pattern | Calls | Approach |
|---|---|---|
| List objects with fields | 1 | get_all_records() |
| Multiple independent values | N concurrent | asyncio.gather() |
| Lookup one field for one ref | 1 | get_<field>(ref) |
Run Tests
git clone git@github.com:acefei/async-xenapi.git
cd async-xenapi
cp .env.example .env # then edit .env with your credentials
cd python
uv sync
uv run pytest tests/test_get_xapi_version.py -v
License
LGPL-2.1-only
Metadata
Release files for async-xenapi 1.0.5
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| async_xenapi-1.0.5.tar.gz | 3.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| async_xenapi-1.0.5-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 8.2 kB
Release files / async_xenapi-1.0.5.tar.gz
| Download URL | async_xenapi-1.0.5.tar.gz |
|---|---|
| Size | 3.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
d4bff7675567f88c640ddaec72173c10c5a90b3aa34548a361780247bbd5e16d
|
|
BLAKE2b-256 checksum How to use checksums |
de05d558782e1bda1c6a23da7e0fa226904f803d5fa1480bb3ce70463e3dcfa3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.10.7 {"installer":{"name":"uv","version":"0.10.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / async_xenapi-1.0.5-py3-none-any.whl
| Download URL | async_xenapi-1.0.5-py3-none-any.whl |
|---|---|
| Size | 4.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
eebcb8b5d068ab79c55da26369edbcdb26bb017b4709e2dee16937afa893027d
|
|
BLAKE2b-256 checksum How to use checksums |
69aea7b4e4a050c6fd283388d91b569e2e3bc64dfbd9f1f6b79c8228ae4c3dcd
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.10.7 {"installer":{"name":"uv","version":"0.10.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|