{"id":16243560,"url":"https://github.com/flyte/upnpclient","last_synced_at":"2025-04-05T07:05:28.858Z","repository":{"id":42654096,"uuid":"99926119","full_name":"flyte/upnpclient","owner":"flyte","description":"uPnP client library for Python 3.","archived":false,"fork":false,"pushed_at":"2022-12-08T10:33:31.000Z","size":1256,"stargazers_count":202,"open_issues_count":17,"forks_count":37,"subscribers_count":15,"default_branch":"develop","last_synced_at":"2024-10-11T14:15:09.628Z","etag":null,"topics":["python3","upnp"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/flyte.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-08-10T13:28:43.000Z","updated_at":"2024-09-11T16:52:46.000Z","dependencies_parsed_at":"2023-01-25T01:00:13.746Z","dependency_job_id":null,"html_url":"https://github.com/flyte/upnpclient","commit_stats":null,"previous_names":[],"tags_count":13,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flyte%2Fupnpclient","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flyte%2Fupnpclient/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flyte%2Fupnpclient/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flyte%2Fupnpclient/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/flyte","download_url":"https://codeload.github.com/flyte/upnpclient/tar.gz/refs/heads/develop","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247299832,"owners_count":20916190,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["python3","upnp"],"created_at":"2024-10-10T14:15:23.298Z","updated_at":"2025-04-05T07:05:28.824Z","avatar_url":"https://github.com/flyte.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Build Status](https://travis-ci.org/flyte/upnpclient.svg?branch=develop)](https://travis-ci.org/flyte/upnpclient)\n\nuPnPclient\n============\n\n_uPnP client library for Python 3._\n\nThis library can be used to discover and consume uPnP devices and their services.\n\nIt's originally based on [Ferry Boender's work](https://github.com/fboender/pyupnpclient) and his blog post entitled [Exploring UPnP with Python](https://www.electricmonk.nl/log/2016/07/05/exploring-upnp-with-python/).\n\n### Installation\n\n```bash\npip install upnpclient\n```\n\n### Usage\n\nTypical usage:\n\n```python\nIn [1]: import upnpclient\n\nIn [2]: devices = upnpclient.discover()\n\nIn [3]: devices\nOut[3]: \n[\u003cDevice 'OpenWRT router'\u003e,\n \u003cDevice 'Harmony Hub'\u003e,\n \u003cDevice 'walternate: root'\u003e]\n\nIn [4]: d = devices[0]\n\nIn [5]: d.WANIPConn1.GetStatusInfo()\nOut[5]: \n{'NewConnectionStatus': 'Connected',\n 'NewLastConnectionError': 'ERROR_NONE',\n 'NewUptime': 14851479}\n\nIn [6]: d.WANIPConn1.GetNATRSIPStatus()\nOut[6]: {'NewNATEnabled': True, 'NewRSIPAvailable': False}\n\nIn [7]: d.WANIPConn1.GetExternalIPAddress()\nOut[7]: {'NewExternalIPAddress': '123.123.123.123'}\n```\n\nIf you know the URL for the device description XML, you can access it directly.\n\n```python\nIn [1]: import upnpclient\n\nIn [2]: d = upnpclient.Device(\"http://192.168.1.1:5000/rootDesc.xml\")\n\nIn [3]: d.services\nOut[3]: \n[\u003cService service_id='urn:upnp-org:serviceId:Layer3Forwarding1'\u003e,\n \u003cService service_id='urn:upnp-org:serviceId:WANCommonIFC1'\u003e,\n \u003cService service_id='urn:upnp-org:serviceId:WANIPConn1'\u003e]\n\nIn [4]: d.Layer3Forwarding1.actions\nOut[4]: \n[\u003cAction 'SetDefaultConnectionService'\u003e,\n \u003cAction 'GetDefaultConnectionService'\u003e]\n\nIn [5]: d.Layer3Forwarding1.GetDefaultConnectionService()\nOut[5]: {'NewDefaultConnectionService': 'uuid:46cb370a-d7f2-490f-ac01-fb0db6c8b22b:WANConnectionDevice:1,urn:upnp-org:serviceId:WANIPConn1'}\n```\n\nSometimes the service or action name isn't a valid property name. In which case, service and actions can be accessed other ways:\n\n```python\nIn [1]: d[\"Layer3Forwarding1\"][\"GetDefaultConnectionService\"]()\nOut[1]: {'NewDefaultConnectionService': 'uuid:46cb370a-d7f2-490f-ac01-fb0db6c8b22b:WANConnectionDevice:1,urn:upnp-org:serviceId:WANIPConn1'}\n```\n\nTo view the arguments required to call a given action:\n\n```python\nIn [1]: d.WANIPConn1.AddPortMapping.argsdef_in\nOut[1]: \n[('NewRemoteHost',\n  {'allowed_values': set(), 'datatype': 'string', 'name': 'RemoteHost'}),\n ('NewExternalPort',\n  {'allowed_values': set(), 'datatype': 'ui2', 'name': 'ExternalPort'}),\n ('NewProtocol',\n  {'allowed_values': {'TCP', 'UDP'},\n   'datatype': 'string',\n   'name': 'PortMappingProtocol'}),\n ('NewInternalPort',\n  {'allowed_values': set(), 'datatype': 'ui2', 'name': 'InternalPort'}),\n ('NewInternalClient',\n  {'allowed_values': set(), 'datatype': 'string', 'name': 'InternalClient'}),\n ('NewEnabled',\n  {'allowed_values': set(),\n   'datatype': 'boolean',\n   'name': 'PortMappingEnabled'}),\n ('NewPortMappingDescription',\n  {'allowed_values': set(),\n   'datatype': 'string',\n   'name': 'PortMappingDescription'}),\n ('NewLeaseDuration',\n  {'allowed_values': set(),\n   'datatype': 'ui4',\n   'name': 'PortMappingLeaseDuration'})]\n```\n\nand then to call the action using those arguments:\n\n```python\nIn [1]: d.WANIPConn1.AddPortMapping(\n   ...:     NewRemoteHost='0.0.0.0',\n   ...:     NewExternalPort=12345,\n   ...:     NewProtocol='TCP',\n   ...:     NewInternalPort=12345,\n   ...:     NewInternalClient='192.168.1.10',\n   ...:     NewEnabled='1',\n   ...:     NewPortMappingDescription='Testing',\n   ...:     NewLeaseDuration=10000)\nOut[1]: {}\n```\n\nSimilarly, the arguments you can expect to receive in response are listed:\n\n```python\nIn [1]: d.WANIPConn1.GetGenericPortMappingEntry.argsdef_out\nOut[1]: \n[('NewRemoteHost',\n  {'allowed_values': set(), 'datatype': 'string', 'name': 'RemoteHost'}),\n ('NewExternalPort',\n  {'allowed_values': set(), 'datatype': 'ui2', 'name': 'ExternalPort'}),\n ('NewProtocol',\n  {'allowed_values': {'TCP', 'UDP'},\n   'datatype': 'string',\n   'name': 'PortMappingProtocol'}),\n ('NewInternalPort',\n  {'allowed_values': set(), 'datatype': 'ui2', 'name': 'InternalPort'}),\n ('NewInternalClient',\n  {'allowed_values': set(), 'datatype': 'string', 'name': 'InternalClient'}),\n ('NewEnabled',\n  {'allowed_values': set(),\n   'datatype': 'boolean',\n   'name': 'PortMappingEnabled'}),\n ('NewPortMappingDescription',\n  {'allowed_values': set(),\n   'datatype': 'string',\n   'name': 'PortMappingDescription'}),\n ('NewLeaseDuration',\n  {'allowed_values': set(),\n   'datatype': 'ui4',\n   'name': 'PortMappingLeaseDuration'})]\n```\n\n#### HTTP Auth/Headers\n\nYou may pass a\n[requests compatible](http://docs.python-requests.org/en/master/user/authentication/)\nauthentication object and/or a dictionary containing headers to use on the HTTP\ncalls to your uPnP device.\n\nThese may be set on the `Device` itself on creation for use with every HTTP\ncall:\n\n```python\ndevice = upnpclient.Device(\n    \"http://192.168.1.1:5000/rootDesc.xml\"\n    http_auth=('myusername', 'mypassword'),\n    http_headers={'Some-Required-Header': 'somevalue'}\n)\n```\n\nOr on a per-call basis:\n\n```python\ndevice.Layer3Forwarding1.GetDefaultConnectionService(\n    http_auth=('myusername', 'mypassword'),\n    http_headers={'Some-Required-Header': 'somevalue'}\n)\n```\n\nIf you've set either at `Device` level, they can be overridden per-call by\nsetting them to `None`.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fflyte%2Fupnpclient","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fflyte%2Fupnpclient","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fflyte%2Fupnpclient/lists"}