Metadata-Version: 2.4
Name: comixto
Version: 0.3.1
Summary: Pure-Python comix.to client: request signing, x-enc decrypt, WAF solver
Author-email: fratboys <fratboys@users.noreply.github.com>
License: MIT
Project-URL: Homepage, https://github.com/lmaohi7181828/comix
Project-URL: Repository, https://github.com/lmaohi7181828/comix
Project-URL: Issues, https://github.com/lmaohi7181828/comix/issues
Project-URL: Documentation, https://github.com/lmaohi7181828/comix/tree/main/docs
Keywords: comix,comix.to,manga,api,crypto,waf
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Internet :: WWW/HTTP
Classifier: Topic :: Security :: Cryptography
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: requests>=2.31
Requires-Dist: orjson>=3.9
Requires-Dist: numpy>=1.26
Requires-Dist: Pillow>=10.0
Provides-Extra: dev
Requires-Dist: pytest>=8.0; extra == "dev"
Requires-Dist: pytest-timeout>=2.0; extra == "dev"
Dynamic: license-file

# comixto

Pure-Python toolkit for [comix.to](https://comix.to) by [@fratboys](https://github.com/fratboys).

- **Request signing** — `1k4.*` tokens, no browser required  
- **Response decrypt** — `x-enc: 1|2` chapter lists and protected payloads  
- **WAF helpers** — Cloudflare Turnstile + legacy rotation captcha  

**Docs:** [Reverse engineering](docs/REVERSE_ENGINEERING.md) · [Crypto](docs/crypto.md) · [WAF](docs/waf.md)

## Install

```bash
pip install comixto
```

## Quick start

```python
from comixto import Client

# Public endpoints (no signature)
with Client(crypto=False) as c:
    print(c.comments(limit=3))

# Signed + encrypted endpoints
with Client() as c:
    chapters = c.chapters("zgk6j", limit=5)
    print(chapters["items"][0]["number"])
    print(c.manga("zgk6j")["title"])
```

When `crypto=True` and you hit a public route, the client warns once and still
sends the request unsigned.

## Manual crypto

```python
from comixto.crypto import Crypto

c = Crypto()
params = c.sign("/manga/zgk6j/chapters", {
    "page": 1, "limit": 2, "order[number]": "desc", "v": 0, "w": 0,
})
# params["_"] == "1k4...."
```

## WAF

Current site uses **Cloudflare Turnstile** (not the old rotation image).
Most API calls work without solving it.

```python
from comixto import solve_waf

# Detect / explain (success=False until you pass a token or captcha API key)
r = solve_waf(source="/", verbose=True)
print(r["kind"], r.get("error") or r.get("sitekey"))

# Or verify a token from a browser / 2captcha / Capsolver
# r = solve_waf(token="...")
# r = solve_waf(provider="2captcha", api_key="...")
```

## License

MIT
