A Python wrapper for the VAPIX API by Axis Communications, providing a clean, typed interface for controlling Axis network cameras.
- PTZ control — absolute, relative, and continuous pan/tilt/zoom moves, focus, iris, brightness, presets, and home position via
com/ptz.cgi. - Geolocation — read and set the camera's configured position and heading.
- Device parameters — list device parameters via
param.cgi. - Solid HTTP layer — one authenticated session (digest or basic auth), HTTP or HTTPS, real per-request timeouts, and typed exceptions (
VapixAuthenticationError,VapixRequestError,VapixResponseError). - Typed and tested — full type hints and a mocked test suite that runs without camera hardware.
Not yet published to PyPI. Install from source:
pip install git+https://github.com/derens99/vapix-python.gitOr for local development (using uv):
git clone https://github.com/derens99/vapix-python.git
cd vapix-python
uv syncfrom vapix_python import VapixAPI
with VapixAPI("192.168.0.90", "root", "your-password") as api:
# Current pan/tilt/zoom
pan, tilt, zoom = api.ptz.get_current_position()
# Move the camera
api.ptz.absolute_move(pan=90, tilt=0, zoom=500, speed=50)
api.ptz.go_home(speed=100)
# Geolocation
position = api.geolocation.get_position()
print(position["lat"], position["lon"])
# Device parameters
brand = api.get_parameters(group="Brand")api = VapixAPI(
"cam.example.com",
"root",
"your-password",
timeout=10, # per-request timeout in seconds
secure=True, # use HTTPS
verify_ssl=False, # or a path to a CA bundle
auth_method="digest" # or "basic"
)from vapix_python import VapixAPI, VapixAuthenticationError, VapixRequestError
try:
with VapixAPI("192.168.0.90", "root", "wrong") as api:
api.ptz.get_current_position()
except VapixAuthenticationError:
print("Bad credentials")
except VapixRequestError as exc:
print(f"Camera unreachable or returned an error: {exc}")The project uses uv for dependency management:
uv sync # create .venv and install the package + dev dependencies
uv run ruff check . # lint
uv run pytest # run the test suite (no camera required)
uv build # build sdist and wheelpip install -e ".[dev]" also works if you prefer plain pip.
Import from the package root — the old CamelCase module paths were removed (keeping them silently corrupted the package namespace when both import styles were used in one process):
from vapix_python.VapixAPI import VapixAPI # 0.1.x — no longer works
from vapix_python import VapixAPI # 0.2.0Notable fixes in 0.2.0:
- Request timeouts are now actually applied (previously the
timeoutargument was silently ignored, so calls could hang forever). PTZControl.rename_preset_number(number, name)now sends the number and name in the correct fields (they were swapped).PTZControl.ptz_enabled(channel)now actually queries the given channel (info=1&camera=<channel>; previously the channel was sent as theinfovalue).- PTZ commands the camera rejects with an
Error: ...body now raiseVapixResponseErrorinstead of silently returning success. - Geolocation responses are parsed robustly (namespaced XML supported, no stray
print()output) and camera-reported errors raiseVapixResponseError. - Errors are raised as
vapix_pythonexception types;VapixRequestErrorstill subclassesrequests.RequestException, so existingexcept requests.RequestException:handlers keep working. - HTTP 401 and 403 raise
VapixAuthenticationError(bad credentials vs. insufficient privileges).