Name | ssdp JSON |
Version |
1.3.0
JSON |
| download |
home_page | |
Summary | Python asyncio library for Simple Service Discovery Protocol (SSDP). |
upload_time | 2023-07-04 16:16:35 |
maintainer | |
docs_url | None |
author | |
requires_python | >=3.8 |
license | |
keywords |
ssdp
python
asyncio
upnp
iot
|
VCS |
|
bugtrack_url |
|
requirements |
No requirements were recorded.
|
Travis-CI |
No Travis.
|
coveralls test coverage |
No coveralls.
|
# Python SSDP
Python asyncio library for Simple Service Discovery Protocol (SSDP).
SSDP is a UPnP substandard. For more information see:
https://en.wikipedia.org/wiki/Simple_Service_Discovery_Protocol
## Setup
```bash
python3 -m pip install ssdp # lightweight, without any dependencies
# or
python3 -m pip install ssdp[cli] # with cli support for testing and debugging
```
## Usage
### CLI
```console-interactive
$ ssdp --help
Usage: ssdp [OPTIONS] COMMAND [ARGS]...
SSDP command line interface.
Options:
-v, --verbose Increase verbosity.
--help Show this message and exit.
Commands:
discover Send out an M-SEARCH request and listening for responses.
```
#### Discover
Discover devices on the network and print the responses.
```console
ssdp discover --help
Usage: ssdp discover [OPTIONS]
Send out an M-SEARCH request and listening for responses.
Options:
-b, --bind TEXT Specify alternate bind address [default: all
interfaces]
--search-target, --st TEXT Search target [default: ssdp:all]
--max-wait, --mx INTEGER Maximum wait time in seconds [default: 5]
--help Show this message and exit.
```
Example:
```console
$ ssdp discover
[::]:1900 - - [Sun Jun 11 12:07:09 2023] M-SEARCH * HTTP/1.1
HOST: 239.255.255.250:1900
MAN: "ssdp:discover"
MX: 5
ST: ssdp:all
[::ffff:192.168.178.1]:1900 - - [Sun Jun 11 12:07:09 2023] HTTP/1.1 200 OK
Cache-Control: max-age=1800
Location: http://192.168.178.1:49000/MediaServerDevDesc.xml
Server: FRITZ!Box 7590 UPnP/1.0 AVM FRITZ!Box 7590 154.07.50
Ext:
ST: upnp:rootdevice
USN: uuid:fa095ecc-e13e-40e7-8e6c-3ca62f98471f::upnp:rootdevice
```
### Python API
#### Messages
The SSDP library provides two classes for SSDP messages: `SSDPRequest` and
`SSDPResponse`. Both classes are subclasses of `SSDPMessage` and provide
the following methods:
- `parse`: Parse a SSDP message from a string.
- `__bytes__`: Convert the SSDP message to a bytes object.
- `__str__`: Convert the SSDP message to a string.
You can parse a SSDP message from a string with the `parse` method.
It will return a `SSDPRequest` or `SSDPResponse` object depending
on the message type.
```pycon
>>> import ssdp.messages
>>> ssdp.messages.SSDPRequest.parse('NOTIFY * HTTP/1.1\r\n\r\n')
<ssdp.messages.SSDPRequest object at 0x7f8b1c0b6a90>
>>> ssdp.messages.SSDPResponse.parse('HTTP/1.1 200 OK\r\n\r\n')
<ssdp.messages.SSDPResponse object at 0x7f8b1c0b6a90>
```
##### SSDPRequest
```pycon
>>> from ssdp.messages import SSDPRequest
>>> SSDPRequest('NOTIFY', headers={
... 'HOST': '10.0.0.42',
... 'NT': 'upnp:rootdevice',
... 'NTS': 'ssdp:alive',
... })
<ssdp.messages.SSDPRequest object at 0x7f8b1c0b6a90>
```
The `SSDPRequest` class provides the a `sendto` method to send the request
over a open transport.
```pycon
>>> from ssdp import network, messages
>>> notify = messages.SSDPRequest('NOTIFY')
>>> notify.sendto(transport, (network.MULTICAST_ADDRESS_IPV4, network.PORT))
```
##### SSDPResponse
```pycon
>>> from ssdp.messages import SSDPResponse
>>> SSDPResponse(200, 'OK', headers={
... 'CACHE-CONTROL': 'max-age=1800',
... 'LOCATION': 'http://10.0.0.1:80/description.xml',
... 'SERVER': 'Linux/2.6.18 UPnP/1.0 quick_ssdp/1.0',
... 'ST': 'upnp:rootdevice',
... })
<ssdp.messages.SSDPResponse object at 0x7f8b1c0b6a90>
```
#### Asyncio SSD Protocol datagram endpoint
The `aio.SimpleServiceDiscoveryProtocol` class is a subclass of
`asyncio.DatagramProtocol` and provides the following additional methods:
- `response_received`: Called when a SSDP response was received.
- `request_received`: Called when a SSDP request was received.
The protocol can be used to react to SSDP messages in an asyncio event loop.
This example sends a SSDP NOTIFY message and prints all received SSDP messages:
```python
#!/usr/bin/env python3
import asyncio
import socket
from ssdp import aio, messages, network
class MyProtocol(aio.SimpleServiceDiscoveryProtocol):
def response_received(self, response, addr):
print(response, addr)
def request_received(self, request, addr):
print(request, addr)
loop = asyncio.get_event_loop()
connect = loop.create_datagram_endpoint(MyProtocol, family=socket.AF_INET)
transport, protocol = loop.run_until_complete(connect)
notify = messages.SSDPRequest('NOTIFY')
notify.sendto(transport, (network.MULTICAST_ADDRESS_IPV4, network.PORT))
try:
loop.run_forever()
except KeyboardInterrupt:
pass
transport.close()
loop.close()
```
## SSDP lexer plugin for [Pygments][pygments]
The SSDP library comes with a lexer plugin for [Pygments][pygments]
to highlight SSDP messages. It's based on a HTTP lexer and adds SSDP
specific keywords.
You can install the plugin with the following command:
```bash
pip install ssdp[pymgments] # included in ssdp[cli]
```
You can either get the lexer by name:
```pycon
>>> from pygments.lexers import get_lexer_by_name
>>> get_lexer_by_name('ssdp')
<pygments.lexers.SSDPLexer>
```
Highlighting a SSDP message, could look like this:
```python
#/usr/bin/env python3
from pygments import highlight
from pygments.lexers import get_lexer_by_name
from pygments.formatters import TerminalFormatter
if __name__ == '__main__':
lexer = get_lexer_by_name('ssdp')
formatter = TerminalFormatter()
code = 'NOTIFY * HTTP/1.1\r\nHOST: localhost:1900'
msg = highlight(code, lexer, formatter)
print(msg)
```
[pygments]: https://pygments.org/
Raw data
{
"_id": null,
"home_page": "",
"name": "ssdp",
"maintainer": "",
"docs_url": null,
"requires_python": ">=3.8",
"maintainer_email": "",
"keywords": "ssdp,python,asyncio,upnp,iot",
"author": "",
"author_email": "Johannes Maron <johannes@maron.family>",
"download_url": "https://files.pythonhosted.org/packages/c5/8a/fb7c36813462ad73933c7c0012f4698e8c7137bc2678e4085d4696754818/ssdp-1.3.0.tar.gz",
"platform": null,
"description": "# Python SSDP\n\nPython asyncio library for Simple Service Discovery Protocol (SSDP).\n\nSSDP is a UPnP substandard. For more information see:\nhttps://en.wikipedia.org/wiki/Simple_Service_Discovery_Protocol\n\n## Setup\n\n```bash\npython3 -m pip install ssdp # lightweight, without any dependencies\n# or\npython3 -m pip install ssdp[cli] # with cli support for testing and debugging\n```\n\n## Usage\n\n### CLI\n\n```console-interactive\n$ ssdp --help\nUsage: ssdp [OPTIONS] COMMAND [ARGS]...\n\n SSDP command line interface.\n\nOptions:\n -v, --verbose Increase verbosity.\n --help Show this message and exit.\n\nCommands:\n discover Send out an M-SEARCH request and listening for responses.\n```\n\n#### Discover\n\nDiscover devices on the network and print the responses.\n\n```console\nssdp discover --help\nUsage: ssdp discover [OPTIONS]\n\n Send out an M-SEARCH request and listening for responses.\n\nOptions:\n -b, --bind TEXT Specify alternate bind address [default: all\n interfaces]\n --search-target, --st TEXT Search target [default: ssdp:all]\n --max-wait, --mx INTEGER Maximum wait time in seconds [default: 5]\n --help Show this message and exit.\n```\n\nExample:\n\n```console\n$ ssdp discover\n[::]:1900 - - [Sun Jun 11 12:07:09 2023] M-SEARCH * HTTP/1.1\nHOST: 239.255.255.250:1900\nMAN: \"ssdp:discover\"\nMX: 5\nST: ssdp:all\n\n[::ffff:192.168.178.1]:1900 - - [Sun Jun 11 12:07:09 2023] HTTP/1.1 200 OK\nCache-Control: max-age=1800\nLocation: http://192.168.178.1:49000/MediaServerDevDesc.xml\nServer: FRITZ!Box 7590 UPnP/1.0 AVM FRITZ!Box 7590 154.07.50\nExt:\nST: upnp:rootdevice\nUSN: uuid:fa095ecc-e13e-40e7-8e6c-3ca62f98471f::upnp:rootdevice\n```\n\n### Python API\n\n#### Messages\n\nThe SSDP library provides two classes for SSDP messages: `SSDPRequest` and\n`SSDPResponse`. Both classes are subclasses of `SSDPMessage` and provide\nthe following methods:\n\n- `parse`: Parse a SSDP message from a string.\n- `__bytes__`: Convert the SSDP message to a bytes object.\n- `__str__`: Convert the SSDP message to a string.\n\nYou can parse a SSDP message from a string with the `parse` method.\nIt will return a `SSDPRequest` or `SSDPResponse` object depending\non the message type.\n\n```pycon\n>>> import ssdp.messages\n>>> ssdp.messages.SSDPRequest.parse('NOTIFY * HTTP/1.1\\r\\n\\r\\n')\n<ssdp.messages.SSDPRequest object at 0x7f8b1c0b6a90>\n>>> ssdp.messages.SSDPResponse.parse('HTTP/1.1 200 OK\\r\\n\\r\\n')\n<ssdp.messages.SSDPResponse object at 0x7f8b1c0b6a90>\n```\n\n##### SSDPRequest\n\n```pycon\n>>> from ssdp.messages import SSDPRequest\n>>> SSDPRequest('NOTIFY', headers={\n... 'HOST': '10.0.0.42',\n... 'NT': 'upnp:rootdevice',\n... 'NTS': 'ssdp:alive',\n... })\n<ssdp.messages.SSDPRequest object at 0x7f8b1c0b6a90>\n```\n\nThe `SSDPRequest` class provides the a `sendto` method to send the request\nover a open transport.\n\n```pycon\n>>> from ssdp import network, messages\n>>> notify = messages.SSDPRequest('NOTIFY')\n>>> notify.sendto(transport, (network.MULTICAST_ADDRESS_IPV4, network.PORT))\n```\n\n##### SSDPResponse\n\n```pycon\n>>> from ssdp.messages import SSDPResponse\n>>> SSDPResponse(200, 'OK', headers={\n... 'CACHE-CONTROL': 'max-age=1800',\n... 'LOCATION': 'http://10.0.0.1:80/description.xml',\n... 'SERVER': 'Linux/2.6.18 UPnP/1.0 quick_ssdp/1.0',\n... 'ST': 'upnp:rootdevice',\n... })\n<ssdp.messages.SSDPResponse object at 0x7f8b1c0b6a90>\n```\n\n#### Asyncio SSD Protocol datagram endpoint\n\nThe `aio.SimpleServiceDiscoveryProtocol` class is a subclass of\n`asyncio.DatagramProtocol` and provides the following additional methods:\n\n- `response_received`: Called when a SSDP response was received.\n- `request_received`: Called when a SSDP request was received.\n\nThe protocol can be used to react to SSDP messages in an asyncio event loop.\n\nThis example sends a SSDP NOTIFY message and prints all received SSDP messages:\n\n```python\n#!/usr/bin/env python3\nimport asyncio\nimport socket\n\nfrom ssdp import aio, messages, network\n\n\nclass MyProtocol(aio.SimpleServiceDiscoveryProtocol):\n\n def response_received(self, response, addr):\n print(response, addr)\n\n def request_received(self, request, addr):\n print(request, addr)\n\n\nloop = asyncio.get_event_loop()\nconnect = loop.create_datagram_endpoint(MyProtocol, family=socket.AF_INET)\ntransport, protocol = loop.run_until_complete(connect)\n\nnotify = messages.SSDPRequest('NOTIFY')\nnotify.sendto(transport, (network.MULTICAST_ADDRESS_IPV4, network.PORT))\n\ntry:\n loop.run_forever()\nexcept KeyboardInterrupt:\n pass\n\ntransport.close()\nloop.close()\n```\n\n## SSDP lexer plugin for [Pygments][pygments]\n\nThe SSDP library comes with a lexer plugin for [Pygments][pygments]\nto highlight SSDP messages. It's based on a HTTP lexer and adds SSDP\nspecific keywords.\n\nYou can install the plugin with the following command:\n\n```bash\npip install ssdp[pymgments] # included in ssdp[cli]\n```\n\nYou can either get the lexer by name:\n\n```pycon\n>>> from pygments.lexers import get_lexer_by_name\n>>> get_lexer_by_name('ssdp')\n<pygments.lexers.SSDPLexer>\n```\n\nHighlighting a SSDP message, could look like this:\n\n```python\n#/usr/bin/env python3\nfrom pygments import highlight\nfrom pygments.lexers import get_lexer_by_name\nfrom pygments.formatters import TerminalFormatter\n\n\nif __name__ == '__main__':\n lexer = get_lexer_by_name('ssdp')\n formatter = TerminalFormatter()\n code = 'NOTIFY * HTTP/1.1\\r\\nHOST: localhost:1900'\n msg = highlight(code, lexer, formatter)\n print(msg)\n```\n\n[pygments]: https://pygments.org/\n\n",
"bugtrack_url": null,
"license": "",
"summary": "Python asyncio library for Simple Service Discovery Protocol (SSDP).",
"version": "1.3.0",
"project_urls": {
"Changelog": "https://github.com/codingjoe/ssdp/releases",
"Project-URL": "https://github.com/codingjoe/ssdp"
},
"split_keywords": [
"ssdp",
"python",
"asyncio",
"upnp",
"iot"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "1557e4546471bd05d356920ad525bb1bdaa23128d760a292b8c9caa49050f0e4",
"md5": "bf52a4c394f05d54ca8dbb0cd3e0b72a",
"sha256": "749c28cb6934f44017672676083b80f305f3c27f4c512dcaa1264be862f5d30f"
},
"downloads": -1,
"filename": "ssdp-1.3.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "bf52a4c394f05d54ca8dbb0cd3e0b72a",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.8",
"size": 9992,
"upload_time": "2023-07-04T16:16:33",
"upload_time_iso_8601": "2023-07-04T16:16:33.834145Z",
"url": "https://files.pythonhosted.org/packages/15/57/e4546471bd05d356920ad525bb1bdaa23128d760a292b8c9caa49050f0e4/ssdp-1.3.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "c58afb7c36813462ad73933c7c0012f4698e8c7137bc2678e4085d4696754818",
"md5": "beb4d2888081c71589d6f4f14dbade78",
"sha256": "438f1449d0d8f7bd82228cdf8d92c3327edef83b411f28cf23d055d012651491"
},
"downloads": -1,
"filename": "ssdp-1.3.0.tar.gz",
"has_sig": false,
"md5_digest": "beb4d2888081c71589d6f4f14dbade78",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.8",
"size": 9315,
"upload_time": "2023-07-04T16:16:35",
"upload_time_iso_8601": "2023-07-04T16:16:35.201897Z",
"url": "https://files.pythonhosted.org/packages/c5/8a/fb7c36813462ad73933c7c0012f4698e8c7137bc2678e4085d4696754818/ssdp-1.3.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2023-07-04 16:16:35",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "codingjoe",
"github_project": "ssdp",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "ssdp"
}