{"id":13498179,"url":"https://github.com/pusher/pusher-http-python","last_synced_at":"2026-04-01T18:39:47.408Z","repository":{"id":885691,"uuid":"633141","full_name":"pusher/pusher-http-python","owner":"pusher","description":"Pusher Channels HTTP API library for Python","archived":false,"fork":false,"pushed_at":"2026-03-18T19:10:46.000Z","size":686,"stargazers_count":391,"open_issues_count":7,"forks_count":115,"subscribers_count":21,"default_branch":"master","last_synced_at":"2026-03-19T08:37:39.334Z","etag":null,"topics":["http","pusher","python"],"latest_commit_sha":null,"homepage":"https://pusher.com/docs/server_api_guide","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/pusher.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2010-04-28T11:07:18.000Z","updated_at":"2026-03-05T18:24:46.000Z","dependencies_parsed_at":"2023-02-13T23:55:13.732Z","dependency_job_id":"f48a0ef0-8d56-46bb-bc26-d2ae8113db06","html_url":"https://github.com/pusher/pusher-http-python","commit_stats":{"total_commits":334,"total_committers":58,"mean_commits":5.758620689655173,"dds":0.8353293413173652,"last_synced_commit":"239d67b7a047a18ee181922c0a1461ceaf7c565f"},"previous_names":["pusher/pusher_client_python"],"tags_count":39,"template":false,"template_full_name":null,"purl":"pkg:github/pusher/pusher-http-python","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pusher%2Fpusher-http-python","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pusher%2Fpusher-http-python/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pusher%2Fpusher-http-python/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pusher%2Fpusher-http-python/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pusher","download_url":"https://codeload.github.com/pusher/pusher-http-python/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pusher%2Fpusher-http-python/sbom","scorecard":{"id":750298,"data":{"date":"2025-08-11","repo":{"name":"github.com/pusher/pusher-http-python","commit":"10372d07123318775dbf250ea25b79c9b9bb0bbe"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":4.2,"checks":[{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Code-Review","score":10,"reason":"all changesets reviewed","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/release.yml:1","Warn: no topLevel permission defined: .github/workflows/release_pr.yml:1","Warn: no topLevel permission defined: .github/workflows/test.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:10: update your workflow using https://app.stepsecurity.io/secureworkflow/pusher/pusher-http-python/release.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:38: update your workflow using https://app.stepsecurity.io/secureworkflow/pusher/pusher-http-python/release.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:52: update your workflow using https://app.stepsecurity.io/secureworkflow/pusher/pusher-http-python/release.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:66: update your workflow using https://app.stepsecurity.io/secureworkflow/pusher/pusher-http-python/release.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:67: update your workflow using https://app.stepsecurity.io/secureworkflow/pusher/pusher-http-python/release.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/release.yml:77: update your workflow using https://app.stepsecurity.io/secureworkflow/pusher/pusher-http-python/release.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release_pr.yml:14: update your workflow using https://app.stepsecurity.io/secureworkflow/pusher/pusher-http-python/release_pr.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release_pr.yml:20: update your workflow using https://app.stepsecurity.io/secureworkflow/pusher/pusher-http-python/release_pr.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/test.yml:20: update your workflow using https://app.stepsecurity.io/secureworkflow/pusher/pusher-http-python/test.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/test.yml:23: update your workflow using https://app.stepsecurity.io/secureworkflow/pusher/pusher-http-python/test.yml/master?enable=pin","Warn: pipCommand not pinned by hash: .github/workflows/release.yml:72","Warn: pipCommand not pinned by hash: .github/workflows/test.yml:29","Info:   0 out of   9 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   1 third-party GitHubAction dependencies pinned","Info:   0 out of   2 pipCommand dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Packaging","score":10,"reason":"packaging workflow detected","details":["Info: Project packages its releases by way of GitHub Actions.: .github/workflows/release.yml:62"],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Branch-Protection","score":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 30 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":0,"reason":"35 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-3ww4-gg4f-jr7f","Warn: Project is vulnerable to: GHSA-9v9h-cgj8-h64p","Warn: Project is vulnerable to: PYSEC-2021-62 / GHSA-hggm-jpg3-v476","Warn: Project is vulnerable to: PYSEC-2017-8 / GHSA-q3cj-2r34-2cwc","Warn: Project is vulnerable to: PYSEC-2024-225","Warn: Project is vulnerable to: GHSA-jjg7-2v4v-x38h","Warn: Project is vulnerable to: PYSEC-2018-24 / GHSA-2rcm-phc9-3945","Warn: Project is vulnerable to: PYSEC-2013-31 / GHSA-6748-36qp-fx6r","Warn: Project is vulnerable to: PYSEC-2018-23 / GHSA-p28m-34f6-967q","Warn: Project is vulnerable to: PYSEC-2014-14 / GHSA-652x-xj99-gmcc","Warn: Project is vulnerable to: GHSA-9hjg-9r4m-mvj7","Warn: Project is vulnerable to: GHSA-9wx4-h78v-vm56","Warn: Project is vulnerable to: PYSEC-2014-13 / GHSA-cfj3-7x9c-4p3h","Warn: Project is vulnerable to: PYSEC-2018-28 / GHSA-x84v-xcm2-53pg","Warn: Project is vulnerable to: PYSEC-2015-17","Warn: Project is vulnerable to: PYSEC-2023-74","Warn: Project is vulnerable to: GHSA-753j-mpmx-qq6g","Warn: Project is vulnerable to: GHSA-7cx3-6m66-7c5m","Warn: Project is vulnerable to: PYSEC-2020-213 / GHSA-8vpw-mgpf-mpvv","Warn: Project is vulnerable to: GHSA-8w49-h785-mj3c","Warn: Project is vulnerable to: PYSEC-2012-5 / GHSA-f7fv-v9rh-prvc","Warn: Project is vulnerable to: PYSEC-2023-75 / GHSA-hj3f-6gcp-jg8j","Warn: Project is vulnerable to: GHSA-qppv-j76h-2rpx","Warn: Project is vulnerable to: GHSA-w235-7p84-xx57","Warn: Project is vulnerable to: GHSA-34jh-p97f-mpxf","Warn: Project is vulnerable to: PYSEC-2023-212 / GHSA-g4mx-q9vg-27p4","Warn: Project is vulnerable to: PYSEC-2023-207 / GHSA-gwvm-45gx-3cf8","Warn: Project is vulnerable to: PYSEC-2019-133 / GHSA-mh33-7rrq-662w","Warn: Project is vulnerable to: GHSA-pq67-6m6q-mj2v","Warn: Project is vulnerable to: PYSEC-2019-132 / GHSA-r64q-w8jr-g9qp","Warn: Project is vulnerable to: PYSEC-2023-192 / GHSA-v845-jxx5-vc9f","Warn: Project is vulnerable to: PYSEC-2020-148 / GHSA-wqvq-5m8c-6g24","Warn: Project is vulnerable to: PYSEC-2018-32 / GHSA-www2-v7xj-xrc6","Warn: Project is vulnerable to: PYSEC-2021-108","Warn: Project is vulnerable to: PYSEC-2021-59"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-22T20:07:55.824Z","repository_id":885691,"created_at":"2025-08-22T20:07:55.824Z","updated_at":"2025-08-22T20:07:55.824Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31290937,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-01T13:12:26.723Z","status":"ssl_error","status_checked_at":"2026-04-01T13:12:25.102Z","response_time":53,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["http","pusher","python"],"created_at":"2024-07-31T20:00:53.106Z","updated_at":"2026-04-01T18:39:47.383Z","avatar_url":"https://github.com/pusher.png","language":"Python","readme":"# Pusher Channels HTTP Python Library\n\n[![Build Status](https://github.com/pusher/pusher-http-python/workflows/Tests/badge.svg)](https://github.com/pusher/pusher-http-python/actions?query=workflow%3ATests+branch%3Amaster)\n[![PyPI version](https://badge.fury.io/py/pusher.svg)](https://badge.fury.io/py/pusher)\n\nThis package lets you trigger events to your client and query the state of your channels. When used with a server, you can validate webhooks and authenticate `private-` or `presence-` channels.\n\nIn order to use this library, you need to have a free account on \u003chttp://pusher.com\u003e. After registering, you will need the application credentials for your app.\n\n## Supported Platforms\n\n* Python - supports Python version 3.6 and above\n\n## Features\n\n* Adapters for various http libraries like requests, urlfetch, aiohttp (requires Python \u003e= 3.5.3) and tornado.\n* WebHook validation\n* Signature generation for socket subscriptions\n\n### Table of Contents\n\n- [Installation](#installation)\n- [Getting started](#getting-started)\n- [Configuration](#configuration)\n- [Triggering Events](#triggering-events)\n  - [Send a message to a specific user](#send-a-message-to-a-specific-user)\n- [Querying Application State](#querying-application-state)\n  - [Getting Information For All Channels](#getting-information-for-all-channels)\n  - [Getting Information For A Specific Channel](#getting-information-for-a-specific-channel)\n  - [Getting User Information For A Presence Channel](#getting-user-information-for-a-presence-channel)\n- [Authenticating Channel Subscription](#authenticating-channel-subscription)\n- [Authenticating User](#authenticating-user)\n- [Terminating User Connections](#terminating-user-connections)\n- [End-to-end Encryption](#end-to-end-encryption)\n- [Receiving Webhooks](#receiving-webhooks)\n- [Request Library Configuration](#request-library-configuration)\n  - [Google App Engine](#google-app-engine)\n- [Feature Support](#feature-support)\n- [Running the tests](#running-the-tests)\n- [License](#license)\n\n## Installation\n\nYou can install this module using your package management method or choice,\nnormally `easy_install` or `pip`. For example:\n\n```bash\npip install pusher\n```\n\nUsers on Python 2.x and older versions of pip may get a warning, due to pip compiling the optional `pusher.aiohttp` module, which uses Python 3 syntax. However, as `pusher.aiohttp` is not used by default, this does not affect the library's functionality. See [our Github issue](https://github.com/pusher/pusher-http-python/issues/52), as well as [this issue from Gunicorn](https://github.com/benoitc/gunicorn/issues/788) for more details.\n\nOn Linux, you must ensure that OpenSSL is installed, e.g. on Debian/Ubuntu:\n\n```sh\n$ sudo apt-get install build-essential libssl-dev libffi-dev\n```\n\n## Getting started\n\n The minimum configuration required to use the `Pusher` object are the three\nconstructor arguments which identify your Pusher Channels app. You can find them by\ngoing to \"API Keys\" on your app at \u003chttps://app.pusher.com\u003e.\n\n```python\nimport pusher\npusher_client = pusher.Pusher(app_id=u'4', key=u'key', secret=u'secret', cluster=u'cluster')\n```\n\nYou can then trigger events to channels. Channel and event names may only\ncontain alphanumeric characters, `-` and `_`:\n\n```python\npusher_client.trigger(u'a_channel', u'an_event', {u'some': u'data'})\n```\n\n## Configuration\n\n```python\nimport pusher\npusher_client = pusher.Pusher(app_id, key, secret, cluster=u'cluster')\n```\n\n|Argument   |Description   |\n|:-:|:-:|\n|app_id `String`  |**Required** \u003cbr\u003e The Pusher Channels application ID |\n|key `String`     |**Required** \u003cbr\u003e The Pusher Channels application key |\n|secret `String`  |**Required** \u003cbr\u003e The Pusher Channels application secret token |\n|cluster `String` | **Default:`mt1`** \u003cbr\u003e The pusher application cluster. Will be overwritten if `host` is set |\n|host `String`    | **Default:`None`** \u003cbr\u003e The host to connect to |\n|port `int`       | **Default:`None`** \u003cbr\u003eWhich port to connect to |\n|ssl `bool`       | **Default:`True`** \u003cbr\u003e Use HTTPS |\n|~~encryption_master_key~~ `String` | **Default:`None`** \u003cbr\u003e *Deprecated*, see `encryption_master_key_base64` |\n|encryption_master_key_base64 `String` | **Default:`None`** \u003cbr\u003e The encryption master key for End-to-end Encryption |\n|backend `Object` | an object that responds to the `send_request(request)` method. If none is provided, a `pusher.requests.RequestsBackend` instance is created. |\n|json_encoder `Object` | **Default: `None`**\u003cbr\u003e Custom JSON encoder. |\n|json_decoder `Object` | **Default: `None`**\u003cbr\u003e Custom JSON decoder.\n\nThe constructor will throw a `TypeError` if it is called with parameters that don’t match the types listed above.\n\n##### Example\n\n```py\nimport pusher\npusher_client = pusher.Pusher(app_id=u'4', key=u'key', secret=u'secret', ssl=True, cluster=u'cluster')\n```\n\n## Triggering Events\n\nTo trigger an event on one or more channels, use the `trigger` method on the `Pusher` object.\n\n#### `Pusher::trigger`\n\n|Argument   |Description   |\n|:-:|:-:|\n|channels `String` or `Collection`   |**Required** \u003cbr\u003e The name or list of names of the channel you wish to trigger events on   |\n|event `String`| **Required** \u003cbr\u003e The name of the event you wish to trigger. |\n|data `JSONable data` | **Required** \u003cbr\u003e The event's payload |\n|socket_id `String` | **Default:`None`** \u003cbr\u003e The socket_id of the connection you wish to exclude from receiving the event. You can read more [here](https://pusher.com/docs/channels/server_api/excluding-event-recipients/). |\n\n|Return Values   |Description   |\n|:-:|:-:|\n|buffered_events `Dict`   | A parsed response that includes the event_id for each event published to a channel. See example.   |\n\n`Pusher::trigger` will throw a `TypeError` if called with parameters of the wrong type; or a `ValueError` if called on more than 100 channels, with an event name longer than 200 characters, or with more than 10240 characters of data (post JSON serialisation).\n\n##### Example\n\nThis call will trigger to `'a_channel'` and `'another_channel'`, and exclude the recipient with socket_id `\"1234.12\"`.\n\n```python\npusher_client.trigger([u'a_channel', u'another_channel'], u'an_event', {u'some': u'data'}, \"1234.12\")\n```\n\n#### `Pusher::trigger_batch`\n\nIt's also possible to send distinct messages in batches to limit the overhead\nof HTTP headers. There is a current limit of 10 events per batch on\nour multi-tenant clusters.\n\n|Argument   |Description   |\n|:-:|:-:|\n|batch `Array` of `Dict`  |**Required** \u003cbr\u003e A list of events to trigger   |\n\nEvents are a `Dict` with keys:\n\n|Argument   |Description   |\n|:-:|:-:|\n|channel `String`| **Required** \u003cbr\u003e The name of the channel to publish to. |\n|name `String`| **Required** \u003cbr\u003e The name of the event you wish to trigger. |\n|data `JSONable data` | **Required** \u003cbr\u003e The event's payload |\n|socket_id `String` | **Default:`None`** \u003cbr\u003e The socket_id of the connection you wish to exclude from receiving the event. You can read more [here](http://pusher.com/docs/duplicates). |\n\n|Return Values   |Description   |\n|:-:|:-:|\n|`Dict`| An empty dict on success |\n\n`Pusher::trigger_batch` will throw a `TypeError` if the data parameter is not JSONable.\n\n##### Example\n\n```python\npusher_client.trigger_batch([\n  { u'channel': u'a_channel', u'name': u'an_event', u'data': {u'some': u'data'}, u'socket_id': '1234.12'},\n  { u'channel': u'a_channel', u'name': u'an_event', u'data': {u'some': u'other data'}}\n])\n```\n\n### Send a message to a specific user\n\n#### `Pusher::send_to_user`\n\n|Argument   |Description   |\n|:-:|:-:|\n|user_id `String` |**Required** \u003cbr\u003e The user id |\n|event `String`| **Required** \u003cbr\u003e The name of the event you wish to trigger. |\n|data `JSONable data` | **Required** \u003cbr\u003e The event's payload |\n\n|Return Values   |Description   |\n|:-:|:-:|\n|buffered_events `Dict`   | A parsed response that includes the event_id for each event published to a channel. See example.   |\n\n`Pusher::trigger` will throw a `TypeError` if called with parameters of the wrong type; or a `ValueError` if called on more than 100 channels, with an event name longer than 200 characters, or with more than 10240 characters of data (post JSON serialisation).\n\n##### Example\n\nThis call will send a message to the user with id `'123'`.\n\n```python\npusher_client.send_to_user( u'123', u'some_event', {u'message': u'hello worlds'})\n```\n\n## Querying Application State\n\n### Getting Information For All Channels\n\n\n#### `Pusher::channels_info`\n\n|Argument   |Description |\n|:-:|:-:|\n|prefix_filter `String`  |**Default: `None`** \u003cbr\u003e Filter the channels returned by their prefix   |\n|attributes `Collection` | **Default: `[]`** \u003cbr\u003e A collection of attributes which should be returned for each channel. If empty, an empty dictionary of attributes will be returned for each channel. \u003cbr\u003e Available attributes: `\"user_count\"`.\n\n|Return Values   |Description   |\n|:-:|:-:|\n|channels `Dict`   | A parsed response from the HTTP API. See example.   |\n\n`Pusher::channels_info` will throw a `TypeError` if `prefix_filter` is not a `String`.\n\n##### Example\n\n```python\nchannels = pusher_client.channels_info(u\"presence-\", [u'user_count'])\n\n#=\u003e {u'channels': {u'presence-chatroom': {u'user_count': 2}, u'presence-notifications': {u'user_count': 1}}}\n```\n\n### Getting Information For A Specific Channel\n\n#### `Pusher::channel_info`\n\n|Argument   |Description   |\n|:-:|:-:|\n|channel `String`  |**Required** \u003cbr\u003e The name of the channel you wish to query|\n|attributes `Collection` | **Default: `[]`** \u003cbr\u003e A collection of attributes to be returned for the channel. \u003cbr\u003e\u003cbr\u003e Available attributes: \u003cbr\u003e `\"user_count\"` : Number of *distinct* users currently subscribed. **Applicable only to presence channels**. \u003cbr\u003e `\"subscription_count\"`:  Number of *connections* currently subscribed to the channel. Enable this feature in your Pusher dashboard's App Settings.\n\n|Return Values   |Description   |\n|:-:|:-:|\n|channel `Dict`   |  A parsed response from the HTTP API. See example.  |\n\n`Pusher::channel_info` will throw a `ValueError` if `channel` is not a valid channel.\n\n##### Example\n\n```python\nchannel = pusher_client.channel_info(u'presence-chatroom', [u\"user_count\"])\n#=\u003e {u'user_count': 42, u'occupied': True}\n```\n\n### Getting User Information For A Presence Channel\n\n#### `Pusher::users_info`\n\n|Argument   |Description   |\n|:-:|:-:|\n|channel `String`   |**Required** \u003cbr\u003e The name of the *presence* channel you wish to query   |\n\n|Return Values   |Description   |\n|:-:|:-:|\n|users `Dict`   | A parsed response from the HTTP API. See example.   |\n\n`Pusher::users_info` will throw a `ValueError` if `channel` is not a valid channel.\n\n##### Example\n\n```python\npusher_client.users_info(u'presence-chatroom')\n#=\u003e {u'users': [{u'id': u'1035'}, {u'id': u'4821'}]}\n```\n\n## Authenticating Channel Subscription\n\n#### `Pusher::authenticate`\n\nIn order for users to subscribe to a private- or presence-channel, they must be authenticated by your server.\n\nThe client will make a POST request to an endpoint (either \"/pusher/auth\" or any which you specify) with a body consisting of the channel's name and socket_id.\n\nUsing your `Pusher` instance, with which you initialized `Pusher`, you can generate an authentication signature. Having responded to the request with this signature, the subscription will be authenticated.\n\n|Argument   |Description   |\n|:-:|:-:|\n|channel `String`   |**Required**\u003cbr\u003e The name of the channel, sent to you in the POST request    |\n|socket_id `String` | **Required**\u003cbr\u003e The channel's socket_id, also sent to you in the POST request |\n|custom_data `Dict` |**Required for presence channels** \u003cbr\u003e This will be a dictionary containing the data you want associated with a member of a presence channel. A `\"user_id\"` key is *required*, and you can optionally pass in a `\"user_info\"` key. See the example below.  |\n\n|Return Values   |Description   |\n|:-:|:-:|\n|response `Dict`   | A dictionary to send as a response to the authentication request.|\n\n`Pusher::authenticate` will throw a `ValueError` if the `channel` or `socket_id` that it’s called with are invalid.\n\n##### Example\n\n###### Private Channels\n\n```python\nauth = pusher_client.authenticate(\n\n  channel=u\"private-channel\",\n\n  socket_id=u\"1234.12\"\n)\n# return `auth` as a response\n```\n\n###### Presence Channels\n\n```python\nauth = pusher_client.authenticate(\n\n  channel=u\"presence-channel\",\n\n  socket_id=u\"1234.12\",\n\n  custom_data={\n    u'user_id': u'1',\n    u'user_info': {\n      u'twitter': '@pusher'\n    }\n  }\n)\n# return `auth` as a response\n```\n\n## Authenticating User\n\n#### `Pusher::authenticate_user`\n\nTo authenticate users on Pusher Channels on your application, you can use the authenticate_user function:\n\n|Argument   |Description   |\n|:-:|:-:|\n|socket_id `String` | **Required**\u003cbr\u003e The channel's socket_id, also sent to you in the POST request |\n|user_data `Dict` |**Required for presence channels** \u003cbr\u003e This will be a dictionary containing the data you want associated with a user. An `\"id\"` key is *required*  |\n\n|Return Values   |Description   |\n|:-:|:-:|\n|response `Dict`   | A dictionary to send as a response to the authentication request.|\n\nFor  more information see:\n* [authenticating users](https://pusher.com/docs/channels/server_api/authenticating-users/)\n* [auth-signatures](https://pusher.com/docs/channels/library_auth_reference/auth-signatures/)\n\n##### Example\n\n###### User Authentication\n\n```python\nauth = pusher_client.authenticate_user(\n  socket_id=u\"1234.12\",\n  user_data = {\n    u'id': u'123',\n    u'name': u'John Smith'\n  }\n)\n# return `auth` as a response\n```\n\n## Terminating user connections\n\nTIn order to terminate a user's connections, the user must have been authenticated. Check the [Server user authentication docs](http://pusher.com/docs/authenticating_users) for the information on how to create a user authentication endpoint.\n\nTo terminate all connections established by a given user, you can use the `terminate_user_connections` function:\n\n```python\npusher_client.terminate_user_connections(userId)\n```\n\nPlease note, that it only terminates the user's active connections. This means, if nothing else is done, the user will be able to reconnect. For more information see: [Terminating user connections docs](https://pusher.com/docs/channels/server_api/terminating-user-connections/).\n\n## End to End Encryption\n\nThis library supports end to end encryption of your private channels. This\nmeans that only you and your connected clients will be able to read your\nmessages. Pusher cannot decrypt them. You can enable this feature by following\nthese steps:\n\n1. You should first set up Private channels. This involves [creating an\n   authentication endpoint on your\n   server](https://pusher.com/docs/authenticating_users).\n\n2. Next, generate a 32 byte master encryption key, base64 encode it and store\n   it securely.\n\n   This is secret and you should never share this with anyone. Not even Pusher.\n\n   To generate a suitable key from a secure random source, you could use:\n\n   ```bash\n   openssl rand -base64 32\n   ```\n\n3. Pass your master key to the SDK constructor\n\n   ```python\n   import pusher\n\n   pusher_client = pusher.Pusher(\n     app_id='yourappid',\n     key='yourkey',\n     secret='yoursecret',\n     encryption_master_key_base64='\u003coutput from command above\u003e',\n     cluster='yourclustername',\n     ssl=True\n   )\n\n   pusher_client.trigger('private-encrypted-my-channel', 'my-event', {\n     'message': 'hello world'\n   })\n   ```\n\n4. Channels where you wish to use end to end encryption must be prefixed with\n   `private-encrypted-`.\n\n5. Subscribe to these channels in your client, and you're done! You can verify\n   it is working by checking out the debug console on the\n   https://dashboard.pusher.com/ and seeing the scrambled ciphertext.\n\n**Important note: This will not encrypt messages on channels that are not prefixed by private-encrypted-.**\n\nMore info on End-to-end Encrypted Channels [here](https://pusher.com/docs/client_api_guide/client_encrypted_channels).\n\n## Receiving Webhooks\n\nIf you have webhooks set up to POST a payload to a specified endpoint, you may wish to validate that these are actually from Pusher. The `Pusher` object achieves this by checking the authentication signature in the request body using your application credentials.\n\n#### `Pusher::validate_webhook`\n\n|Argument   |Description   |\n|:-:|:-:|\n|key `String`   | **Required**\u003cbr\u003ePass in the value sent in the request headers under the key \"X-PUSHER-KEY\". The method will check this matches your app key.   |\n|signature `String` | **Required**\u003cbr\u003eThis is the value in the request headers under the key \"X-PUSHER-SIGNATURE\". The method will verify that this is the result of signing the request body against your app secret.  |\n|body `String` | **Required**\u003cbr\u003eThe JSON string of the request body received. |\n\n|Return Values   |Description   |\n|:-:|:-:|\n|body_data `Dict`   | If validation was successful, the return value will be the parsed payload. Otherwise, it will be `None`.   |\n\n`Pusher::validate_webhook` will raise a `TypeError` if it is called with any parameters of the wrong type.\n\n##### Example\n\n```python\nwebhook = pusher_client.validate_webhook(\n\n  key=\"key_sent_in_header\",\n\n  signature=\"signature_sent_in_header\",\n\n  body=\"{ \\\"time_ms\\\": 1327078148132  \\\"events\\\": [ { \\\"name\\\": \\\"event_name\\\", \\\"some\\\": \\\"data\\\" }  ]}\"\n)\n\nprint webhook[\"events\"]\n```\n\n## Request Library Configuration\n\nUsers can configure the library to use different backends to send calls to our API. The HTTP libraries we support are:\n\n* [Requests](https://requests.readthedocs.io/en/master/) (`pusher.requests.RequestsBackend`). This is used by default.\n* [Tornado](http://www.tornadoweb.org/en/stable/) (`pusher.tornado.TornadoBackend`).\n* [AsyncIO](https://docs.python.org/3/library/asyncio.html) (`pusher.aiohttp.AsyncIOBackend`).\n* [Google App Engine](https://cloud.google.com/appengine/docs/python/urlfetch/) (`pusher.gae.GAEBackend`).\n\nUpon initializing a `Pusher` instance, pass in any of these options to the `backend` keyword argument.\n\n### Google App Engine\n\nGAE users are advised to use the `pusher.gae.GAEBackend` backend to ensure compatability.\n\n## Feature Support\n\nFeature                                    | Supported\n-------------------------------------------| :-------:\nTrigger event on single channel            | *\u0026#10004;*\nTrigger event on multiple channels         | *\u0026#10004;*\nTrigger event to a specifc user            | *\u0026#10004;*\nExcluding recipients from events           | *\u0026#10004;*\nAuthenticating private channels            | *\u0026#10004;*\nAuthenticating presence channels           | *\u0026#10004;*\nAuthenticating users                       | *\u0026#10004;*\nGet the list of channels in an application | *\u0026#10004;*\nGet the state of a single channel          | *\u0026#10004;*\nGet a list of users in a presence channel  | *\u0026#10004;*\nWebHook validation                         | *\u0026#10004;*\nTerminate user connections                 | *\u0026#10004;*\nHeroku add-on support                      | *\u0026#10004;*\nDebugging \u0026 Logging                        | *\u0026#10004;*\nCluster configuration                      | *\u0026#10004;*\nTimeouts                                   | *\u0026#10004;*\nHTTPS                                      | *\u0026#10004;*\nEnd-to-end Encryption                      | *\u0026#10004;*\nHTTP Proxy configuration                   | *\u0026#10008;*\nHTTP KeepAlive                             | *\u0026#10008;*\n\n#### Helper Functionality\n\nThese are helpers that have been implemented to to ensure interactions with the HTTP API only occur if they will not be rejected e.g. [channel naming conventions](https://pusher.com/docs/channels/using_channels/channels#channel-naming-conventions).\n\nHelper Functionality                     | Supported\n-----------------------------------------| :-------:\nChannel name validation                  | \u0026#10004;\nLimit to 100 channels per trigger        | \u0026#10004;\nLimit event name length to 200 chars     | \u0026#10004;\n\n\n## Running the tests\n\nTo run the tests run `python setup.py test`\n\n## License\n\nCopyright (c) 2015 Pusher Ltd. See [LICENSE](LICENSE) for details.\n\n","funding_links":[],"categories":["Python"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpusher%2Fpusher-http-python","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpusher%2Fpusher-http-python","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpusher%2Fpusher-http-python/lists"}