ONVIF Zeep Async

raw JSON →
4.0.4 verified Mon Apr 27 auth: no python

Async Python client for ONVIF cameras using zeep and aiohttp. Provides SOAP-based device discovery, media streaming, PTZ control, and event handling. Current version 4.0.4, requires Python >=3.10. Active development with frequent releases.

pip install onvif-zeep-async
error ModuleNotFoundError: No module named 'onvif'
cause Installing wrong package or using wrong import name.
fix
Install onvif-zeep-async and import as from onvif import ONVIFCamera.
error zeep.exceptions.SignatureVerificationFailed: Failed to verify signature
cause Camera requires WS-UsernameToken authentication with strict timestamp checking.
fix
Ensure system clock is synchronized (NTP) and retry. The library adds a timestamp automatically.
error aiohttp.client_exceptions.ClientConnectorError: Cannot connect to host 192.168.1.100:80
cause Camera not reachable or wrong IP/port.
fix
Verify camera IP and port, and ensure network connectivity.
error TypeError: object NoneType can't be used in 'await' expression
cause Calling `camera.create_media_service()` without `await`.
fix
Prepend await to the call: media_service = await camera.create_media_service().
breaking v4.0.0 migrated from httplib2 to aiohttp for HTTP transport. Old code using custom httplib2 transport will break.
fix Use aiohttp-based transport or upgrade to v4+ and adopt async/await pattern.
breaking v4.0.0 requires Python >=3.10. Python 3.9 and older are not supported.
fix Upgrade Python to 3.10+ or pin to onvif-zeep-async==3.2.5 (last Python 3.9 compatible version).
deprecated The `update_xaddrs` parameter in ONVIFCamera constructor may be deprecated in future releases. Use `await camera.update_xaddrs()` explicitly.
fix Prefer calling `await camera.update_xaddrs()` after initialization.
gotcha ONVIFCamera constructor does not connect immediately; you must await service creation methods. Attempting to use the camera before awaiting will cause runtime errors.
fix Always use `await` with methods like `create_media_service()` and `update_xaddrs()`.
gotcha Snapshot URIs returned by some cameras may be broken or missing authentication. The library tries to fetch snapshot URI without user/pass as fallback (since v3.2.4), but this may still fail.
fix Manually construct snapshot URL with credentials if automatic fallback fails.

Discover ONVIF device and list media profiles.

import asyncio
from onvif import ONVIFCamera

async def main():
    # create ONVIFCamera instance
    ip = os.environ.get('CAMERA_IP', '192.168.1.100')
    username = os.environ.get('CAMERA_USER', 'admin')
    password = os.environ.get('CAMERA_PASS', 'admin')
    camera = ONVIFCamera(ip, 80, username, password)
    # get services
    media_service = await camera.create_media_service()
    # get profiles
    profiles = await media_service.GetProfiles()
    print(profiles)

asyncio.run(main())