Pillow-based emoji rendering with HTTP and local sources
Project description
Parmoji
Description
Parmoji is a Pillow-based emoji rendering library (unicode + Discord custom emoji) with pluggable image sources (HTTP CDN and local font), LRU in-memory caching, and optional on-disk caching using XDG locations. It’s extracted from the par-term-emu project and packaged as a standalone library for reuse.
Technology
- Python 3.11+
- Pillow
- httpx / requests (optional fallback)
Prerequisites
- Python 3.11 or higher
- uv package manager (recommended)
Features
- Unicode and Discord emoji
- Multi-line rendering with alignment and anchors
- Fine control over emoji size/position per draw call
- Multiple built-in emoji sources (Twemoji, Apple, Google, etc.)
- LRU in-memory cache and optional disk cache (XDG)
Installation
uv add parmoji
Update
uv add parmoji -U
Quickstart
from parmoji import Parmoji
from parmoji.source import TwitterEmojiSource
from PIL import Image, ImageFont
text = "Hello 👋 from Parmoji 😎"
img = Image.new("RGBA", (480, 120), (255, 255, 255, 255))
font = ImageFont.load_default()
with Parmoji(img, source=TwitterEmojiSource, cache=True) as p:
p.text((10, 20), text, fill=(0, 0, 0), font=font)
img.save("parmoji_example.png")
Emoji Sources and Caching
- Default source is
Twemoji(Twitter-style). Swap viaParmoji(image, source=AppleEmojiSource). - Disk cache: construct sources with
disk_cache=Trueto persist assets. - Cache location:
$XDG_CACHE_HOME/par-term/parmoji/<SourceClass>/(or~/.cache/par-term/parmoji/<SourceClass>/). - Clear failed CDN retries:
source.clear_failed_cache().
Architecture
For a high-level system design, components, rendering flow, and caching details, see the Architecture overview:
Development
make setup # uv lock + uv sync
make checkall # format + lint + typecheck + test
make test # run tests
make package-all # build wheel + sdist
- Pre-commit:
pre-commit install(thenpre-commit run --all-files) - Type checking:
uv run pyright - Lint/format:
uv run ruff check --fix src/ testsanduv run ruff format src/ tests
CI / Releases
- Build & test on push:
.github/workflows/build.yml - Publish to TestPyPI (manual):
.github/workflows/publish-dev.yml - Publish to PyPI (manual):
.github/workflows/publish.yml(trusted publishing) - GitHub Release (manual):
.github/workflows/release.yml
License
MIT — see LICENSE.
Acknowledgements
Originally based on the Pilmoji project by jay3332; heavily refactored and extended for standalone packaging.
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 parmoji-2.0.6.tar.gz.
File metadata
- Download URL: parmoji-2.0.6.tar.gz
- Upload date:
- Size: 21.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
eb736bdf762d9f947a6cdf78b60f17a7ccd41a7d1c2046533876471b4a14de04
|
|
| MD5 |
28963965518267e53e074ac69bec7a45
|
|
| BLAKE2b-256 |
20a825d0e708d5ca54e03dac0402a5658156124b424fec035a476f31054a6ec8
|
Provenance
The following attestation bundles were made for parmoji-2.0.6.tar.gz:
Publisher:
publish.yml on paulrobello/parmoji
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
parmoji-2.0.6.tar.gz -
Subject digest:
eb736bdf762d9f947a6cdf78b60f17a7ccd41a7d1c2046533876471b4a14de04 - Sigstore transparency entry: 489803993
- Sigstore integration time:
-
Permalink:
paulrobello/parmoji@f21db967091111942cc1ef641e36f97c301b8f4b -
Branch / Tag:
refs/heads/main - Owner: https://github.com/paulrobello
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@f21db967091111942cc1ef641e36f97c301b8f4b -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file parmoji-2.0.6-py3-none-any.whl.
File metadata
- Download URL: parmoji-2.0.6-py3-none-any.whl
- Upload date:
- Size: 23.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a9ea632657b6832967ee87d4aaeefaf33ef845e249a5906b4356bf7795b67a37
|
|
| MD5 |
31749fcf04688b4a6d12f9443479e5c6
|
|
| BLAKE2b-256 |
e5e3f8006cc7acbfc0efd012bc3e00c64d471bd6f2c1e6fa5276ba55c1404de2
|
Provenance
The following attestation bundles were made for parmoji-2.0.6-py3-none-any.whl:
Publisher:
publish.yml on paulrobello/parmoji
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
parmoji-2.0.6-py3-none-any.whl -
Subject digest:
a9ea632657b6832967ee87d4aaeefaf33ef845e249a5906b4356bf7795b67a37 - Sigstore transparency entry: 489804011
- Sigstore integration time:
-
Permalink:
paulrobello/parmoji@f21db967091111942cc1ef641e36f97c301b8f4b -
Branch / Tag:
refs/heads/main - Owner: https://github.com/paulrobello
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@f21db967091111942cc1ef641e36f97c301b8f4b -
Trigger Event:
workflow_dispatch
-
Statement type: