pypush: a Python client for Apple's private APNs and iMessage APIs
Python APNs and iMessage client
At a glance
- What is it?
- pypush activates as an Apple device and receives push notifications through Apple's internal APNs API. The README warns the current rewrite is not stable, and the iMessage API has been temporarily removed.
- Who is it for?
- pypush is for engineers who need to experiment with Apple's private APNs activation flow from Python and can tolerate an alpha that the README itself calls unstable. It is not for anyone shipping a production messaging integration, because the iMessage API has been temporarily removed in the rewrite and versioning will not settle until 3.0.0.
- Can I use it commercially?
- Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
- Is it still maintained?
- Activity is slowing. The repository last received commits 6 months ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 2, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What pypush actually does today
pypush began as a proof of concept for iMessage reverse engineering and is now described in its README as a community library aiming to cover all of Apple's internal API surface. That ambition is larger than the current code. According to the README, the rewritten version supports the client side of Apple's internal APNs API, which means it can activate as an Apple device and receive push notifications. The iMessage API is not available right now; the README says many features have been temporarily removed and asks readers to stay tuned for future updates that bring the iMessage API back.
The audience is narrow and technical. This is for people who want to script against Apple's private endpoints from Python, or who want to read and extend a reverse-engineering implementation. The repository topics are imessage, proof-of-concept and reverse-engineering, which matches the scope. If you need a supported, documented Apple messaging integration, this project is not that, and its own README does not pretend otherwise. The warning at the top states the current version is not stable and may not work as expected.
How the APNs activation path is put together
The mechanism visible from the repository is a Python client that speaks Apple's internal APNs protocol, with HTTP/2 as the transport. The dependency list in pyproject.toml includes httpx[http2], anyio for async I/O, and cryptography for the certificate and key work that device activation requires. That combination tells you the shape of the data flow: an async HTTP/2 client talks to Apple, cryptography handles the identity material, and anyio keeps the event loop portable across backends.
Activation as an Apple device is the part that matters. Apple's push service expects a device identity, so the library has to construct and present the certificates and keys that a real device would use. The README notes that pypush is completely platform-independent, though it may require device identifiers to use some APIs. That sentence is doing real work: the code does not depend on macOS or iOS, but some endpoints will not answer without identifiers that only a real device would have. The optional cli extra pulls in frida, rich and typer, which suggests the command line tool is where device-identifier extraction is intended to happen rather than in the library core.
The versioning is unusual and worth understanding before you pin anything. The README explains that versioning starts at 2.0.0 because of a name conflict with an earlier package called pypush, and it says not to expect stability until 3.0.0. The PyPI release history reflects that: v2.0.0 is labelled as the initial PyPI release, followed by v2.0.1 and v2.0.2. None of those numbers indicate a stable interface.
Installing pypush and running the CLI
The README gives two installation routes. The simple one installs the package with the cli extra, which is what you want if you intend to use the command line entry point rather than import the library directly. The pyproject.toml declares that entry point as pypush = pypush.cli:main, so the pypush executable comes from the cli extra, not from the base install.
pip install pypush[cli]After that command finishes, the pypush command should be on your PATH. The base package requires Python 3.9 or newer, per the requires-python field in pyproject.toml.
If you plan to modify the code, the README gives an editable install instead. This clones the repository, changes into it, and installs it in place so your edits take effect without reinstalling.
git clone https://github.com/JJTech0130/pypush
cd pypush
pip install -e .Note that the editable command does not include the cli extra. If you want the pypush command while developing, you would need to add the extra yourself; the README does not spell that out. The repository also ships a tests directory and declares pytest with pytest-asyncio as a test extra, so a development install plus that extra is the path to running the test suite.
What you should see after either install is a working Python package and, with the cli extra, a pypush executable. What you should not expect is a working iMessage client. The README is explicit that the iMessage API is not part of the current rewrite, so a first real use today is APNs activation and push reception, not sending messages.
The stability warning is the main limitation
The most important thing about pypush is written at the top of its own README. The project is undergoing a major rewrite, the current version is not stable, and it may not work as expected. Features have been temporarily removed. The README says not to expect stability until 3.0.0. Anyone evaluating this for anything beyond experimentation should treat that as the governing constraint, not as boilerplate.
The second limitation is the missing iMessage API. The project's name and topics point at iMessage, and the search interest around it is mostly about iMessage, but the current release does not expose that API. If your goal is to send or receive iMessage content, the rewrite has taken that away for now and the README does not give a date for its return.
The third is the device-identifier dependency. Platform independence does not mean you can run every API on any machine with no Apple hardware involved. The README says some APIs may require device identifiers, which means parts of the surface are gated behind material you have to obtain elsewhere. The optional frida dependency in the cli extra hints at how that extraction is meant to work, but the README does not document the procedure, and it does not document rollback or migration between versions either. That silence is itself a signal about how much operational guidance exists.
How pypush differs from rustpush
The natural comparison is rustpush, which appears in the search terms around this project and is the same reverse-engineering effort written in Rust rather than Python. The difference is not just language preference. A Python implementation fits into scripts, notebooks and existing Python services with no build step beyond pip, and the dependency set here (httpx with HTTP/2, anyio, cryptography) is ordinary Python ecosystem material. A Rust implementation gives you a compiled artifact and a different set of guarantees around memory and concurrency, at the cost of a toolchain and a build.
For someone already working in Python, pypush is the lower-friction way to read and modify the protocol logic, because the code you are studying is the code you are running. For someone who wants a binary they can drop into a non-Python service, or who prefers Rust's type system for protocol work, rustpush is the more natural fit. Both are reverse-engineering projects against the same private Apple surface, so neither comes with a support contract, and the choice is mostly about which language you want to maintain.
A second reference point is the original pypush package that forced the version numbering to start at 2.0.0. That name collision is why the README explains the version jump at all; if you find older documentation or examples referring to pypush 1.x behaviour, they describe a different package, not this one.
Licence, maintenance and upgrade cost
The licensing situation needs care because the two sources do not agree. The README says the project is licensed under the terms of the SSPL and links to MongoDB's server-side public licence page. The pyproject.toml sets license = {text = "Server Side Public License (SSPL)"} but also carries the classifier License :: Other/Proprietary License, and the licence reported alongside the repository is NOASSERTION. On top of that, the README states the project has been purchased by Beeper and directs licensing questions to them. If you intend to use pypush in anything commercial, the classifier and the NOASSERTION status are the reason to read the LICENSE file in the repository root yourself rather than relying on the README summary. This is not legal advice, and the README's own instruction is to contact Beeper.
On maintenance, the last push was on 2026-03-15, which is also the date of the v2.0.2 release. The repository is not archived. The release cadence visible in the repository is sparse: v2.0.0 in May 2024, v2.0.1 in July 2025, v2.0.2 in March 2026. That spacing matters for upgrade planning, because a project that moves this slowly will not ship quick fixes for a broken private API, and Apple can change those APIs without notice. Pin an exact version and read the diff between releases before moving, since the README gives no deprecation policy and no migration notes.
Editorial conclusion
pypush is for engineers who need to experiment with Apple's private APNs activation flow from Python and can tolerate an alpha that the README itself calls unstable. It is not for anyone shipping a production messaging integration, because the iMessage API has been temporarily removed in the rewrite and versioning will not settle until 3.0.0. Before adopting it, check the LICENSE file, since the package metadata labels the project Other/Proprietary while the README points to the SSPL, and both the README and the metadata direct licensing questions to Beeper.
Frequently asked questions
Can pypush send iMessage messages?
Not in the current rewrite. The README states that many features have been temporarily removed and that the iMessage API will come back in a future update; the rewritten version supports the client side of Apple's internal APNs API, meaning activation as an Apple device and receiving push notifications.
How do I install pypush?
The README gives pip install pypush[cli] for a simple installation, or a git clone followed by pip install -e . for an editable development install. The cli extra is what provides the pypush command, and the package requires Python 3.9 or newer.
What licence is pypush under?
The README says the project is licensed under the terms of the SSPL and points licensing questions to Beeper, which purchased the project. The package metadata labels it Other/Proprietary while setting the licence text to Server Side Public License (SSPL), and the licence is reported as NOASSERTION, so check the LICENSE file in the repository.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/jjtech0130-pypush)