Skip to main content

A lightweight, type-safe Python library for emoji search, transformation, and detection.

Project description

pymojis

PyPI version Python versions License: MIT CI

A tiny Python library for working with emojis. Look them up by name or codepoint, pick a random one, check if a string contains any, pull all the emojis out of a chat message, convert to HTML or to a Twemoji URL โ€” that kind of thing.

I wrote it because every time I needed "just a list of emojis with their names" I ended up vendoring a JSON file from somewhere. This is that JSON file with a few helpers on top, no runtime dependencies, and types that actually work in mypy strict.

Install

pip install pymojis              # ~1900 emojis, ~230 KB of data
pip install 'pymojis[full]'      # full Unicode set, ~3790 emojis (~1 MB)

Python 3.12+.

The default dataset covers the everyday stuff. The [full] extra pulls in pymojis-fulldata, which ships every emoji including the skin-tone variants, ZWJ sequences, CLDR keywords, and GitHub-style shortcodes โ€” useful if you care about completeness, overkill if you don't.

Using it

from pymojis import PymojisManager

m = PymojisManager()

m.get_random(length=3)                                  # 3 random Emoji objects
m.get_by_name("grinning face with smiling eyes")        # โ†’ '๐Ÿ˜„'
m.get_by_code("1F604")                                  # โ†’ '๐Ÿ˜„'
m.get_by_emoji("๐Ÿ˜Š")                                    # โ†’ Emoji(...)

m.contains_emojis("hello ๐Ÿ‘‹")                            # โ†’ True
m.is_emoji("๐Ÿ˜„")                                         # โ†’ True

m.extract("hi ๐Ÿ˜€ and ๐Ÿ˜ช")                                # โ†’ [Emoji('grinning face'), Emoji('sleepy face')]
m.strip("hi ๐Ÿ˜€ there")                                   # โ†’ "hi  there"
m.replace("hi ๐Ÿ˜€", lambda e: f"[{e.name}]")              # โ†’ "hi [grinning face]"

m.flag_for("FR")                                         # โ†’ '๐Ÿ‡ซ๐Ÿ‡ท'
m.country_of("๐Ÿ‡ซ๐Ÿ‡ท")                                       # โ†’ 'FR'

m.to_html("๐Ÿ˜ตโ€๐Ÿ’ซ")                                        # โ†’ "😵‍💫"
m.to_unicode_escape("๐Ÿ˜€")                                # โ†’ "\\U0001F600"
m.to_image_url("๐Ÿ˜€")                                     # โ†’ twemoji CDN URL

Switching to the full set:

m = PymojisManager(use_full_dataset=True)
# Raises DatasetNotFoundError (with the pip command) if [full] isn't installed.

What's on the manager

Lookup and random

  • get_random(categories=None, length=1, exclude=None) โ€” random pick. categories wins over exclude.
  • get_all_emojis(exclude=None) โ€” every emoji. exclude accepts "complex" (drop multi-codepoint) or a list of categories.
  • get_by_code(code), get_by_name(name) โ€” single-codepoint / full-name lookup, case-insensitive.
  • get_by_category(category), get_by_subcategory(name), get_by_emoji(emoji).
  • categories(), sub_categories(category=None) โ€” list what the dataset actually contains.

Detection and scanning โ€” all share one longest-match-first regex, so ๐Ÿ‘๐Ÿฝ matches as one unit, not "thumbs up + skin tone modifier".

  • contains_emojis(text) / is_emoji(text).
  • extract(text) โ†’ list[Emoji] in order of appearance.
  • find(text) โ†’ iterator of (emoji, start, end).
  • count(text), count_by(text).
  • strip(text), replace(text, repl) โ€” repl is a literal string or Callable[[Emoji], str].
  • demojifie(text) โ€” rewrites each emoji as :slugified_name:.

Format and convert

  • to_html(emoji) โ€” &#xHEX; references.
  • to_codepoint_string(emoji, sep=" ", prefix="U+") โ€” "U+1F635 U+200D U+1F4AB".
  • to_unicode_escape(emoji) โ€” \U0001F600 form, safe to paste into Python source.
  • to_image_url(emoji, provider="twemoji" | "openmoji", extension="svg" | "png") โ€” public CDN URLs.

Flags โ€” these don't need any dataset, they're computed from codepoints.

  • is_flag(emoji) โ€” Flags category or a bare Regional Indicator Symbol pair.
  • flag_for(country_code) โ€” "FR" โ†’ "๐Ÿ‡ซ๐Ÿ‡ท". Raises on invalid input.
  • country_of(emoji) โ€” "๐Ÿ‡ซ๐Ÿ‡ท" โ†’ "FR". None for non-flags (including tag-sequence subdivision flags).

Family and shortcodes โ€” only meaningful with the [full] dataset. On the light bundle these return None / [] because the data isn't there (size budget), not because the logic is missing.

  • base_of(emoji) โ€” "๐Ÿ‘๐Ÿฝ" โ†’ "๐Ÿ‘".
  • skin_tones(emoji) โ€” all five Fitzpatrick siblings; works whether you pass the base or a variant.
  • to_shortcode(emoji, set_name="github"), from_shortcode(code, set_name=None).

Search

  • search(query, limit=10) โ€” ranked: exact name, then name substring, then name token, then keyword. Falls back to name-only on the light dataset (no keywords).
  • suggest(emoji, limit=5) โ€” same subcategory first, then keyword overlap, then same category.

Text replacement based on names

  • emojifie(text) โ€” replaces whole words with an emoji whose name contains that word (see below).

Anything that takes a string and gets something else raises TypeError on the spot. No silent None, no warnings to ignore.

Categories

from pymojis import Categories
# Literal type of: "Smileys & Emotion", "People & Body", "Animals & Nature",
# "Food & Drink", "Activities", "Travel & Places", "Objects", "Symbols",
# "Flags", "Component"

The Emoji record

Emoji(
    id=...,                          # UUID, generated on construction
    emoji="๐Ÿ‘๐Ÿฝ",
    name="thumbs up: medium skin tone",
    code=["1F44D", "1F3FD"],         # list because ZWJ sequences have multiple codepoints
    category="People & Body",
    sub_category="hand-fingers-closed",
    unicode_version="1.0",
    qualification="fully-qualified", # or "minimally-qualified", "unqualified", "component"
    base_code=["1F44D"],             # None for base emojis; set for skin-tone variants
    keywords=["hand", "thumb", "up"],          # full dataset only; [] on light
    shortcodes={"github": ":thumbs_up_..."},   # full dataset only; {} on light
)

unicode_version, qualification, and base_code come from emoji-test.txt; keywords and shortcodes are added from the CLDR annotations during the dataset build (see scripts/build_dataset.py).

CLI

There's a small command-line tool โ€” call it as pymojis once installed, or python -m pymojis without installing the script.

pymojis search grin              # find emojis by name / keyword
pymojis search face --limit 5
pymojis random --length 3        # 3 random emoji glyphs
pymojis random --length 1 -v     # verbose: emoji + name + category
pymojis info ๐Ÿ˜€                  # everything we know about an emoji
pymojis --full search "thumbs"   # use the full dataset for richer search

Exit codes: 0 on success, 1 when nothing matched (or the emoji's unknown), 2 when argparse didn't like your invocation.

A note on emojifie

It's whole-word matching against a token index built from emoji names. Tokens shorter than 3 characters are skipped โ€” otherwise "I" and "m" would get eaten by โ„น and โ“‚, which is funny exactly once. If a word matches several emojis, the first one in dataset order wins.

m.emojifie("I'm sleepy")     # โ†’ "I'm ๐Ÿ˜ช"
m.emojifie("zzzz xyzzy")     # โ†’ "zzzz xyzzy"

It still only looks at words that appear in the emoji name, so "happy" doesn't match ๐Ÿ˜„ โ€” for keyword-aware search use m.search instead (with the [full] dataset, which ships the CLDR keywords).

Development

There's a Makefile for the usual chores:

make install       # uv sync --extra dev --frozen
make lint
make format-check
make typecheck
make test
make build         # builds both wheels
make ci            # everything above

pre-commit is set up โ€” uv run pre-commit install once and the same checks run on commit.

Contributing

Issues and PRs welcome. Run make ci before opening one.

License

MIT โ€” see LICENSE.

The bundled emoji metadata is generated directly from the Unicode CLDR sources โ€” emoji-test.txt (UTS #51) for the canonical emoji list and annotations/en.xml for keywords. Both are vendored under third_party/cldr/ and licensed under the Unicode License V3 (see third_party/cldr/LICENSE and third_party/NOTICE.txt).

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pymojis-1.1.0.tar.gz (57.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pymojis-1.1.0-py3-none-any.whl (57.3 kB view details)

Uploaded Python 3

File details

Details for the file pymojis-1.1.0.tar.gz.

File metadata

  • Download URL: pymojis-1.1.0.tar.gz
  • Upload date:
  • Size: 57.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for pymojis-1.1.0.tar.gz
Algorithm Hash digest
SHA256 b8e5edeed8cb13ab54bf8cd2db6693151c44fea76c3410d7492100198b669c48
MD5 f517b0ba07e21e3054b4245c5fd759af
BLAKE2b-256 72903fcdca050b6f79a6f4c3ab6ce09146f9f35f58a9a7ae6451caff145c131a

See more details on using hashes here.

Provenance

The following attestation bundles were made for pymojis-1.1.0.tar.gz:

Publisher: github_ci.yaml on pallandir/pymojis

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pymojis-1.1.0-py3-none-any.whl.

File metadata

  • Download URL: pymojis-1.1.0-py3-none-any.whl
  • Upload date:
  • Size: 57.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for pymojis-1.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 0bba36ecdd68bc1005cdcb5072f2ea62910b183b7ac23abd22ee3efaeddd6ff3
MD5 d14958dbe2e700cbd458a059a6b17f10
BLAKE2b-256 589b7911f640a3ca38f03e9b7277bddf770fd7e6bc9050cbe3ca23e31b5bf97c

See more details on using hashes here.

Provenance

The following attestation bundles were made for pymojis-1.1.0-py3-none-any.whl:

Publisher: github_ci.yaml on pallandir/pymojis

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page