{"id":20958,"library":"async-upnp-client","title":"async-upnp-client","description":"Async UPnP Client library for Python, implementing UPnP (Universal Plug and Play) protocol asynchronously using asyncio. Current version 0.47.0, release cadence is irregular, roughly monthly. Requires Python >=3.10.","status":"active","version":"0.47.0","language":"python","source_language":"en","source_url":"https://github.com/StevenLooman/async_upnp_client","tags":["UPnP","async","asyncio","home-automation","SSDP","network"],"install":[{"cmd":"pip install async-upnp-client","lang":"bash","label":"Install from PyPI"}],"dependencies":[{"reason":"HTTP client used for UPnP requests","package":"aiohttp","optional":false},{"reason":"Timeout handling for async operations","package":"async-timeout","optional":false},{"reason":"Safe XML parsing for UPnP responses","package":"defusedxml","optional":false},{"reason":"Schema validation for device descriptions","package":"voluptuous","optional":true}],"imports":[{"note":"UPnPDevice is exposed at package level, not in a submodule.","wrong":"from async_upnp_client.device import UPnPDevice","symbol":"UPnPDevice","correct":"from async_upnp_client import UPnPDevice"},{"note":"UPnPService is also at package level.","wrong":"from async_upnp_client.service import UPnPService","symbol":"UPnPService","correct":"from async_upnp_client import UPnPService"},{"note":"UPnPFactory is at package level.","wrong":"from async_upnp_client.factory import UPnPFactory","symbol":"UPnPFactory","correct":"from async_upnp_client import UPnPFactory"},{"note":"UPnPRequester is at package level.","wrong":"from async_upnp_client.requester import UPnPRequester","symbol":"UPnPRequester","correct":"from async_upnp_client import UPnPRequester"}],"quickstart":{"code":"import asyncio\nfrom async_upnp_client import UPnPFactory, UPnPRequester\n\nasync def main():\n    requester = UPnPRequester()\n    factory = UPnPFactory(requester)\n    # Discover devices, for example:\n    # device = await factory.create_device(\"http://192.168.1.1:49152/description.xml\")\n    print(\"UPnP client ready\")\n\nasyncio.run(main())","lang":"python","description":"Basic setup to instantiate a UPnP factory and requester."},"warnings":[{"fix":"Use UPnPFactory.create_device() and UPnPService.from_device() instead of classmethods.","message":"Version 0.47.0 removed deprecated classmethods from UPnPDevice and UPnPService. Use factory pattern instead.","severity":"breaking","affected_versions":">=0.47.0"},{"fix":"Ensure all calls to async methods are awaited within an async context.","message":"The library uses async/await exclusively. Mixing synchronous code will cause RuntimeError or deadlocks.","severity":"gotcha","affected_versions":"all"},{"fix":"Use aiohttp.ClientSession directly and pass to factory.","message":"UPnPRequester is deprecated in favor of aiohttp session-based approach. Future versions may remove it.","severity":"deprecated","affected_versions":">=0.47.0"},{"fix":"Run the script as root or use `sudo` for discovery. Alternatively, hardcode device URL.","message":"UPnP device discovery using SSDP may require root privileges on some systems (e.g., Linux) due to port binding.","severity":"gotcha","affected_versions":"all"}],"env_vars":null,"last_verified":"2026-04-27T00:00:00.000Z","next_check":"2026-07-26T00:00:00.000Z","problems":[{"fix":"Run `pip install async-upnp-client`.","cause":"Library not installed.","error":"ModuleNotFoundError: No module named 'async_upnp_client'"},{"fix":"Use `from async_upnp_client import UPnPDevice` directly.","cause":"Incorrect import path in older versions?","error":"ImportError: cannot import name 'UPnPDevice' from 'async_upnp_client'"},{"fix":"Ensure single event loop usage; avoid nesting asyncio.run().","cause":"Mixing asyncio event loops, often due to using asyncio.run() inside an already running loop.","error":"RuntimeError: Task <Task pending> got Future <Future pending> attached to a different loop"}],"ecosystem":"pypi","meta_description":null,"install_score":null,"install_tag":null,"quickstart_score":null,"quickstart_tag":null}