Tiny CLI to post simultaneously to Mastodon and Bluesky
Project description
Not my ex

Tiny app to post simultaneously to Mastodon and Bluesky.
Obviously, based on cuducos/from-my-ex.
It supports:
- Post status updates to both networks with a simple CLI command
- Posting with images
- Including alt text for images
- Setting post language
It does not support:
- Tagging other users (they would have different IDs and servers in each platform)
It used to have:
- A simple GUI (version 0.1.1), but dropped support to focus on CLI — there are other great GUI out there by now
Getting started
Requirements
- Python 3.9 or newer
Optionally, you can set some environment variables, but you don't have to.
Environment variables
General settings
| Name | Description | Example | Default value |
|---|---|---|---|
NOT_MY_EX_DEFAULT_LANG |
2-letter ISO 639-1 code | "pt" |
None |
To post to Bluesky
| Name | Description | Example | Default value |
|---|---|---|---|
NOT_MY_EX_BSKY_AGENT |
Bluesky instance | "https://bsky.social" |
"https://bsky.social" |
NOT_MY_EX_BSKY_EMAIL |
Email used in Bluesky | "cuducos@mailinator.com" |
None |
NOT_MY_EX_BSKY_PASSWORD |
Password used in Bluesky | As created in App Passwords. | None |
Not setting NOT_MY_EX_BSKY_EMAIL or NOT_MY_EX_BSKY_PASSWORD disables posting to Bluesky.
To post to Mastodon
| Name | Description | Example | Default value |
|---|---|---|---|
NOT_MY_EX_MASTODON_INSTANCE |
Mastodon instance | "https://tech.lgbt" |
"https://mastodon.social" |
NOT_MY_EX_MASTODON_TOKEN |
Mastodon access token | Go to your Settings, Development and then create an app to get the access token. Select the write:statuses and write:media scopes. |
None |
Not setting NOT_MY_EX_MASTODON_TOKEN disables posting to Mastodon.
Install
$ pip install not-my-ex
Usage
CLI
$ not-my-ex post "Magic, madness, heaven, sin" --images /tmp/1989.gif
You can skip the post text; in that case, it will open $EDITOR so you can write your post.
You can skip --images or pass multiple images (e.g. --images taylor.jpg --images swift.gif).
Check --help for more details on commands and subcommand.
API
from asyncio import gather
from httpx import AsyncClient
from not_my_ex.auth import EnvAuth
from not_my_ex.bluesky import Bluesky
from not_my_ex.mastodon import Mastodon
from not_my_ex.media import Media
from not_my_ex.post import Post
async def main():
auth = EnvAuth()
media_tasks = tuple(
Media.from_img(path, alt, auth.image_size_limit)
for path, alt in (("taylor.jpg", "Taylor"), ("swift.jpg", "Swift"))
)
media = await gather(*media_tasks)
post = Post("Magic, madness, heaven, sin", auth.limit, media, "en")
async with AsyncClient() as http:
post_tasks = tuple(cls(http).post(post) for cls in (Bluesky, Mastodon))
await gather(*post_tasks)
In Post, limit, media and lang are optional. In Media, both alt and image_size_limit are optional.
The usage of auth.limit and auth.image_size_limit makes sure the limits are set according to the authenticated clients.
Contributing
Requires uv Python package manager. The tests include Ruff and Mypy:
$ uv run pytest
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file not_my_ex-1.2.2.tar.gz.
File metadata
- Download URL: not_my_ex-1.2.2.tar.gz
- Upload date:
- Size: 161.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.8.17
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4bfa1a373e3bce67be934627688a4cc4e2892deb3d13b3f312a46ab5408d8032
|
|
| MD5 |
62a809c7641694fbcbac2a5b6662d6ce
|
|
| BLAKE2b-256 |
51b33c9dc51a4c5ae28b8353be7e4976b7eb9d1ed33202eaf1bea63b9e5f2ede
|
File details
Details for the file not_my_ex-1.2.2-py3-none-any.whl.
File metadata
- Download URL: not_my_ex-1.2.2-py3-none-any.whl
- Upload date:
- Size: 41.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.8.17
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
14a6e334ac0dff0c7b096870e1151bd5d3effe04d3e64bb6b7d69c7f6c551902
|
|
| MD5 |
d0fe2eea3f365053927e6c261b2c647b
|
|
| BLAKE2b-256 |
0d346a8b7aec028513f3aa88c03a3ddedf68c46e54cc54d05afa89b4ee0cdb39
|