A lightweight, type-safe Python library for emoji search, transformation, and detection.
Project description
pymojis
A small, type-safe Python library for working with emojis: search them by name / code / character, transform text, detect emojis in strings, and convert to HTML.
- Zero runtime dependencies.
- Two install sizes: a tiny default (~230 KB of data) or the full
Unicode dataset (~1 MB) via the
[full]extra. - Strict typing —
py.typed, full mypy strict compliance. - Fail-fast API — bad input raises immediately, no silent
Nonereturns or warnings.
Install
pip install pymojis # lightweight: ~1900 emojis
pip install 'pymojis[full]' # full Unicode coverage: ~3790 emojis
Requires Python 3.12+.
Quick start
from pymojis import PymojisManager
manager = PymojisManager()
# Pick random emojis
print([e.emoji for e in manager.get_random(length=3)])
# → ['😊', '🎉', '🌟']
# Look up by name / code / character
manager.get_by_name("grinning face with smiling eyes") # → '😄'
manager.get_by_code("1F604") # → '😄'
manager.get_by_emoji("😊") # → Emoji(...)
# Replace whole-word matches in text
manager.emojifie("I'm sleepy")
# → "I'm 😪"
# Detection
manager.contains_emojis("hello 👋") # → True
manager.is_emoji("😄") # → True
manager.is_emoji("😄😊") # → False
# HTML hex references
manager.to_html("😵💫")
# → "😵‍💫"
To use the full Unicode dataset:
manager = PymojisManager(use_full_dataset=True)
# Requires `pip install 'pymojis[full]'`. Raises DatasetNotFoundError
# with installation instructions otherwise.
API
| Method | Returns | Notes |
|---|---|---|
get_random(categories=None, length=1, exclude=None) |
list[Emoji] |
categories takes precedence over exclude. |
get_all_emojis(exclude=None) |
list[Emoji] |
exclude accepts "complex" or a list of categories. |
get_by_code(code) |
str | None |
Single-codepoint lookup. Case-insensitive. |
get_by_name(name) |
str | None |
Full-name lookup. Case-insensitive. |
get_by_category(category) |
list[str] |
All emojis in a category. |
get_by_emoji(emoji) |
Emoji | None |
Reverse lookup from character to record. |
contains_emojis(text) |
bool |
True if text contains at least one known emoji. |
is_emoji(text) |
bool |
True if text.strip() is a single known emoji. |
emojifie(text) |
str |
Replace whole words with emojis (whose name contains that word). |
to_html(emoji) |
str |
Encode each codepoint as &#xHEX;. |
All methods raise TypeError on non-str arguments — no silent None.
Categories
from pymojis import Categories
Categories # type alias of all valid categories:
# "Smileys & Emotion", "People & Body", "Animals & Nature",
# "Food & Drink", "Activities", "Travel & Places", "Objects",
# "Symbols", "Flags", "Component"
Emoji data model
from pymojis import Emoji
@dataclass-like
class Emoji:
id: str # auto-generated UUID
emoji: str # the character itself, e.g. "😄"
name: str # e.g. "grinning face with smiling eyes"
code: list[str] # one or more Unicode codepoints, e.g. ["1F604"]
# (multi-codepoint emojis like ZWJ sequences have len > 1)
category: str # e.g. "Smileys & Emotion"
sub_category: str # e.g. "face-smiling"
Notes on emojifie
emojifie does whole-word matching. Each word in the input is looked up in
an index of emoji-name tokens. Tokens shorter than 3 characters are skipped
(otherwise pronouns like "I" and "m" would be replaced by ℹ and Ⓜ). When a
word matches multiple emojis, the first one (in dataset order) wins.
manager.emojifie("I'm sleepy") # → "I'm 😪" (sleepy → "sleepy face")
manager.emojifie("zzzz xyzzy") # → "zzzz xyzzy" (no match, unchanged)
Releases (maintainer notes)
This repo publishes two packages on every git tag: pymojis and
pymojis-fulldata. Both must share the same version.
To cut a release:
# 1. Bump version in BOTH pyproject files
$EDITOR pyproject.toml # version = "X.Y.Z"
$EDITOR packages/pymojis-fulldata/pyproject.toml # version = "X.Y.Z"
# Also bump the [full] extra dependency pin in pyproject.toml.
# 2. Commit, tag, push
git commit -am "Release vX.Y.Z"
git tag vX.Y.Z
git push origin main --tags
CI runs the full make ci pipeline (lint, format, typecheck, tests,
build both wheels, twine check) and publishes via PyPI Trusted Publishing
(OIDC — no API tokens). One-time setup: register both projects as
Trusted Publishers on https://pypi.org pointing at this repo and the
workflow .github/workflows/github_ci.yaml.
Development
A Makefile wraps the common workflows:
make install # uv sync --extra dev --frozen
make lint # ruff check
make format-check # ruff format --check
make typecheck # mypy src
make test # pytest
make build # build both wheels into dist/
make twine-check # twine check dist/*
make ci # lint + format-check + typecheck + test + build + twine-check
make clean # remove dist/, build/, *.egg-info
pre-commit is configured: uv run pre-commit install once, and the same
checks run on every commit.
Contributing
Issues and PRs welcome. Please run the full check suite above before opening a PR.
License
MIT — see LICENSE.
The bundled emoji metadata derives from the work of
Chalda Pnuzig (ISC License,
see third_party/).
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 pymojis-1.0.1.tar.gz.
File metadata
- Download URL: pymojis-1.0.1.tar.gz
- Upload date:
- Size: 42.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6f7d4860a08e5423b7608d25322218145c23a5417d42b262150eeb4d9d4d9e8a
|
|
| MD5 |
fd5e296efba8ddc9c1fa65fa70e0f04c
|
|
| BLAKE2b-256 |
175457a09dafce398908df43c4333d2a3c4f41888210a2ce81385373f5a14085
|
Provenance
The following attestation bundles were made for pymojis-1.0.1.tar.gz:
Publisher:
github_ci.yaml on pallandir/pymojis
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pymojis-1.0.1.tar.gz -
Subject digest:
6f7d4860a08e5423b7608d25322218145c23a5417d42b262150eeb4d9d4d9e8a - Sigstore transparency entry: 1503711790
- Sigstore integration time:
-
Permalink:
pallandir/pymojis@27a1ef12d6e90177eb584a6f5f4f1cd1523df15f -
Branch / Tag:
refs/tags/v1.0.1 - Owner: https://github.com/pallandir
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
github_ci.yaml@27a1ef12d6e90177eb584a6f5f4f1cd1523df15f -
Trigger Event:
push
-
Statement type:
File details
Details for the file pymojis-1.0.1-py3-none-any.whl.
File metadata
- Download URL: pymojis-1.0.1-py3-none-any.whl
- Upload date:
- Size: 41.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
67772a6ae4f99f24cbe5447c48db36f8dea977a991bb533fa4a0217af2f13701
|
|
| MD5 |
9e88acf7ad32c6c093245fd7ea9efb83
|
|
| BLAKE2b-256 |
2e3133f55ca0b381baf930ecebf367baef94bf48df58821c063d219890ab888b
|
Provenance
The following attestation bundles were made for pymojis-1.0.1-py3-none-any.whl:
Publisher:
github_ci.yaml on pallandir/pymojis
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pymojis-1.0.1-py3-none-any.whl -
Subject digest:
67772a6ae4f99f24cbe5447c48db36f8dea977a991bb533fa4a0217af2f13701 - Sigstore transparency entry: 1503712089
- Sigstore integration time:
-
Permalink:
pallandir/pymojis@27a1ef12d6e90177eb584a6f5f4f1cd1523df15f -
Branch / Tag:
refs/tags/v1.0.1 - Owner: https://github.com/pallandir
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
github_ci.yaml@27a1ef12d6e90177eb584a6f5f4f1cd1523df15f -
Trigger Event:
push
-
Statement type: