Metadata-Version: 2.4
Name: recard
Version: 0.3.0
Summary: Async Genshin Impact character card generator (Enka.Network showcase -> image), styled after zenka for ZZZ.
Author: HATheekshana
License: MIT
Project-URL: Homepage, https://github.com/HATheekshana/recard
Keywords: genshin,genshin-impact,enka,card,zenka
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: aiohttp<4,>=3.12
Requires-Dist: Pillow>=10.0
Requires-Dist: enka<3,>=2.5.20
Provides-Extra: hoyolab
Requires-Dist: genshin<2,>=1.7.27; extra == "hoyolab"
Provides-Extra: fast-dns
Requires-Dist: aiodns>=3.2.0; extra == "fast-dns"
Requires-Dist: pycares<4.4.0; extra == "fast-dns"
Dynamic: license-file

# recard

Async Genshin Impact character card generator, built the same way you'd use
[`zenka`](https://pypi.org/project/zenka/) for Zenless Zone Zero: give it a
UID, get back rendered card images.

```bash
pip install ./recard   # local build, see "Installing" below
```

```python
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](https://github.com/seriaati/enka-py), installed automatically
  as the `enka` dependency. Public `Client.get_api()` and `Client.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/assets`
  under the process working directory, which must be writable. First use
  needs an internet connection. Refresh assets after game patches:

  ```python
  async with recard.Client() as client:
      await client.update_assets()
  ```

  The command `python -m recard.data.update_data` also 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.

## Optional HoYoLAB cards (0.3.0)

Install the optional dependency from this extracted project folder:

```bash
python -m pip install ".[hoyolab]"
```

After publishing this version to PyPI, users can install it with:

```bash
python -m pip install --upgrade "recard[hoyolab]"
```

Pass each user's own cookie dictionary when creating their client:

```python
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 mode uses the artwork returned by HoYoLAB and a neutral background
because that endpoint does not supply a character namecard. Custom splash files
still override artwork. Level caps are omitted if the response lacks ascension
information. Stats, weapon main/sub stats, artifact levels, talents and
constellations come from the authenticated response without bundled JSON files.

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:

```bash
pip install ./recard
# or, for local editing:
pip install -e ./recard
```

Once published:

```bash
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.
