recard
Async Genshin Impact character card generator, built the same way you'd use
zenka for Zenless Zone Zero: give it a
UID, get back rendered card images.
pip install ./recard # local build, see "Installing" below
import asyncio
import recard
async def main():
async with recard.Client() as client:
# list everything currently in the player's public showcase
showcase = await client.get_api(700000000)
for char in showcase:
print(char.id, char.name, char.element)
# render one character by name
result = await client.card(700000000, "Hu Tao")
for card in result.cards:
card.card.save(f"{card.name}.png") # card.card is a PIL.Image
# ...or by exact avatar ID, same call shape
result = await client.card(700000000, 10000046)
# or render the whole showcase at once
result = await client.card(700000000)
for card in result.cards:
card.card.save(f"{card.name}.png")
asyncio.run(main())
How it works / limitations
-
Uses enka-py, installed automatically as the
enkadependency. PublicClient.get_api()andClient.card()calls keep the same interface and return types. -
Public Enka showcase access remains the default. Optional HoYoLAB access can render owned characters outside the showcase; see below.
-
Character names, artwork, namecards, talents, constellations, weapons, and artifacts come from enka-py's enriched models. The four bundled metadata JSON files are no longer needed or shipped.
-
enka-py downloads its metadata on first use into
.enka_py/assetsunder the process working directory, which must be writable. First use needs an internet connection. Refresh assets after game patches:async with recard.Client() as client: await client.update_assets()
The command
python -m recard.data.update_dataalso performs this refresh. Updates depend on the upstream asset sources supporting the new characters. -
Network and parsing errors now propagate instead of appearing as an empty showcase. An empty public showcase still returns an empty list; requesting a missing character raises
recard.CharacterNotFound. -
Custom splash art is read from
~/.recard/custom_splash/<char_id>.(png|jpg|jpeg|webp). -
Internal JSON-path constructor options and old placeholder HoYoLAB hooks were removed. Integrations using those internals should use the public Client.
Sketch layout (0.4.0)
Use style="chevron" for the 2000 × 1200 layout based on the supplied sketch:
large character artwork on the left, three talents and six constellations on
the angled divider, weapon/player panels, right-hand stats, a character-name
strip, and five artifacts in a 3-by-2 grid with the logo in the sixth cell.
async with recard.Client(cookies=cookies) as client:
result = await client.card(uid, "Hu Tao", source="hoyolab", style="chevron")
for card in result.cards:
card.card.save(f"{card.id}.png")
For public showcase cards, omit cookies and use source="enka" (the default).
style="classic" remains the default for existing callers. The new layout uses
the same custom images, namecard backgrounds, and Traveler/Mondstadt fallback.
Pass custom_image="portrait.png" for a one-time override. Artifact stats and
talent levels are rendered dynamically; missing equipment is shown as not equipped.
Validation: 25 tests pass, including both model sources, custom art, long labels, and layout selection. The preview uses a saved public Enka response and downloaded game artwork. Live cookie-authenticated access has not been tested.
Optional HoYoLAB cards (0.3.0)
Install the optional dependency from this extracted project folder:
python -m pip install ".[hoyolab]"
After publishing this version to PyPI, users can install it with:
python -m pip install --upgrade "recard[hoyolab]"
Pass each user's own cookie dictionary when creating their client:
import os
import recard
cookies = {
"ltuid_v2": os.environ["LTUID_V2"],
"ltoken_v2": os.environ["LTOKEN_V2"],
}
async with recard.Client(cookies=cookies) as client:
roster = await client.get_api(uid, source="hoyolab")
result = await client.card(uid, "Hu Tao", source="hoyolab")
# IDs also work: client.card(uid, 10000046, source="hoyolab")
for card in result.cards:
card.card.save(f"{card.id}.png")
source="enka" remains the default, even if cookies are supplied. HoYoLAB
mode is explicit and independent of the public showcase. Omitting a character
in HoYoLAB mode renders the returned owned roster; this may take time for large
accounts. Selecting a character downloads only that character's detailed build.
The library verifies that the requested Genshin UID belongs to a linked account
before requesting its roster or details. Use region="cn" for Miyoushe cookies;
the default is region="os" for HoYoLAB. Each Client keeps a private copy of its
cookie mapping in memory, with no global cookie account or cookie files.
In a multi-user bot, create a Client using the requesting user's cookies.
Missing cookies, unlinked UIDs, failed authenticated requests, and incomplete
details raise recard.HoYoLABError. HoYoLAB can require fresh cookies or account
verification. The library does not change privacy settings or bypass verification.
Missing characters raise recard.CharacterNotFound.
HoYoLAB cards now use enka-py's cached character metadata for namecard
backgrounds, without requiring a public showcase. Banner artwork is tried first,
then the full namecard. Aether and Lumine use Mondstadt: Whistling Wind in every element and source.
Other characters with missing metadata or unavailable artwork use a neutral background. Run
await client.update_assets() to refresh metadata after game patches.
Custom images (0.3.1)
Works with both source="enka" and source="hoyolab":
async with recard.Client(cookies=cookies, splash_directory="data/custom_splash") as client:
# Save by character ID, like the bot's !add_splash command.
client.set_custom_image(10000046, "my-hu-tao.png")
result = await client.card(uid, "Hu Tao", source="hoyolab")
for card in result.cards:
card.card.save(f"{card.id}.png")
# Override only this call; leave the saved image unchanged.
result = await client.card(uid, "Hu Tao", source="hoyolab",
custom_image="another-image.jpg")
# Remove the saved image to restore official artwork.
client.remove_custom_image(10000046)
Image arguments accept a local path, encoded image bytes, or a Pillow image.
Saved images are normalized to PNG. Existing ID-named PNG/JPG/JPEG/WebP files
in the configured folder are also recognized. The default folder remains
~/.recard/custom_splash. A one-time override takes priority over the saved image;
saved images take priority over official artwork. Custom images keep the bot's
left-aligned crop and fade, while the namecard remains the background.
If rendering multiple cards at once, a one-time override is applied to every card.
For a multi-user bot, use a separate splash directory per user.
See examples/hoyolab_card.py for a runnable example using environment variables.
The Telegram bot's cookie-entry and storage interface is outside this library.
Verification
Install the HoYoLAB extra, then run python -m unittest discover -s tests -v.
Tests cover public and authenticated selection, account ownership checks, cookie
isolation, error redaction, stat units, artifact levels, talents and rendering.
Authenticated requests are mocked; a live cookie-authenticated request has not
been verified for this release. Public Enka rendering was verified in 0.2.0.
Installing
This isn't published to PyPI yet. Until then:
pip install ./recard
# or, for local editing:
pip install -e ./recard
Once published:
pip install recard
License
The code in this repository is MIT-licensed - see LICENSE.
Note on bundled assets: recard/assets/ ships
fonts, icons, and character art from Genshin Impact,
© COGNOSPHERE PTE. LTD. / HoYoverse. These are included for card
rendering purposes only, are not covered by this project's MIT license,
and all rights to them remain with their original owner. This project
is an unofficial fan tool and is not affiliated with or endorsed by
HoYoverse.
The enka-py dependency has its own GPL-3.0 license; see its repository for details.
Chevron style in 0.4.1 uses a charcoal halftone background with element accents, no namecard background, and staggered talents. Custom character images remain supported.
In 0.4.2 the namecard is clipped behind character art only (opaque custom images can cover it). Character level is larger; all three talents align in a straight diagonal row inside the strip.
Version 0.4.4 restores the character namecard across chevron with 70%-opaque charcoal panels. Missing namecards fall back to the element texture.
Third style: textured
Use await client.card(uid, character_id, style="textured") for the dark halftone background and solid charcoal info panels. Element accents, custom artwork, namecard behind character art, and artifact CV remain supported. Existing classic and chevron styles are unchanged.
Team cards
image = await client.team(uid, ["Nahida", "Yelan"]) returns one PIL image. Save using image.save("team.jpg"). Choose 1–4 unique names or IDs. Height is exactly 600 pixels per character, width 2400. Pass source="hoyolab" for linked cookie accounts, and custom_images={character_id: image_path} for individual overrides (keys must match your character inputs). Saved custom images work as usual.
Metadata
Release files for recard 0.6.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| recard-0.6.1.tar.gz | 13.9 MB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| recard-0.6.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 27.9 MB
Release files / recard-0.6.1.tar.gz
| Download URL | recard-0.6.1.tar.gz |
|---|---|
| Size | 13.9 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
853d80b8c1178ed9c009cdafed2600095eea480981ba69aa0804a56e1df1a18b
|
|
BLAKE2b-256 checksum How to use checksums |
bfd6e499c54768cae8482344cfe8f20ee19f6c88eb84ce5aea50a64bdff412bc
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.2
|
Release files / recard-0.6.1-py3-none-any.whl
| Download URL | recard-0.6.1-py3-none-any.whl |
|---|---|
| Size | 14.0 MB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
75d7a2dbac6b54d31eb80d40e703242a53c374237c46757293f2ee018da0ae6c
|
|
BLAKE2b-256 checksum How to use checksums |
ef98e4a69920af0445b5815342d5f83efeff481c2be5c055dbb9049b996c43b7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.2
|