Pychive
Unofficial Python wrapper for the Pawchive API. This project is not affiliated with, endorsed by, or associated with Pawchive.
Pychive provides a clean, typed, object-oriented interface to Pawchive's REST API — covering creators, posts, comments, announcements, fancards, post flagging, favorites, file-hash search, and app version info.
- Base URL:
https://pawchive.pw/api/v1 - Auth: cookie-based (
sessioncookie), passed to the client constructor - Python: 3.9+
- Dependencies:
requests
Documentation
Full documentation — installation, quick start, authentication, configuration,
API reference, models, exceptions, error handling, pagination, cookbook, and
changelog — lives in docs/index.md.
Installation (local, into a virtualenv)
Pychive uses a standard src/-layout package described by pyproject.toml,
so it installs cleanly with pip (which will pull in requests automatically).
1. Clone the repository
git clone https://github.com/NoobToolzz/Pychive.git
cd Pychive
2. Create and activate a virtualenv
python3 -m venv .venv
# activate it
source .venv/bin/activate # Linux / macOS
# .venv\Scripts\activate # Windows
3. Install the package
From the project root (where pyproject.toml lives):
# editable install (recommended while developing — picks up edits live)
pip install -e .
# OR a regular install (copies the package into the venv)
pip install .
pip install -e .installs in "editable" mode so changes to files undersrc/pychive/are reflected immediately without reinstalling.pip install .builds and installs a copy instead.Both commands automatically pull in the runtime dependency
requests.
4. (Optional) Install dev tooling
pip install -e ".[dev]"
This adds pytest, responses, ruff, and mypy for testing/linting.
5. Verify the install
python -c "import pychive; print(pychive.__version__)"
Expected output: 1.0.0
Updating / reinstalling
pip install -e . --upgrade
Uninstall
pip uninstall pychive
Quick start
from pychive import Pawchive, AuthenticationError, NotFoundError
# Pass the session cookie value. The "session=" prefix is optional,
# and surrounding quotes/spaces are stripped automatically.
with Pawchive("your_session_value_here") as client:
# Public endpoints (no auth needed)
creators = client.creators.list_all()
for c in creators:
print(c.name, c.service, c.url)
# Recent posts across all creators (paginated)
posts = client.posts.list_recent(limit=50, offset=0)
for p in posts:
print(p.title, p.published_at)
# Posts from a specific creator
fanbox_posts = client.posts.list_from_creator("fanbox", "12345", limit=20)
# A specific post + its revisions and comments
post = client.posts.get("fanbox", "12345", "67890")
revisions = client.posts.list_revisions("fanbox", "12345", "67890")
comments = client.comments.list("fanbox", "12345", "67890")
# Creator profile / links / tags / announcements / fancards
profile = client.creators.get_profile("fanbox", "12345")
links = client.creators.get_links("fanbox", "12345")
tags = client.creators.get_tags("fanbox", "12345")
announcements = client.creators.get_announcements("fanbox", "12345")
fancards = client.creators.get_fancards("fanbox", "12345") # fanbox only
# Authorized endpoints (require a valid session)
try:
favs = client.favorites.list()
client.favorites.add_post("fanbox", "12345", "67890")
client.favorites.add_creator("fanbox", "12345")
client.flags.flag("fanbox", "12345", "67890")
flag_status = client.flags.get_status("fanbox", "12345", "67890")
except AuthenticationError:
print("Session is invalid or expired.")
# File search by hash + app version
result = client.search.lookup_hash("abcdef1234567890")
version = client.misc.app_version()
Getting your session cookie
- Log in to https://pawchive.pw in your browser.
- Open DevTools → Application (Chrome) / Storage (Firefox) → Cookies.
- Copy the value of the
sessioncookie. - Pass it to
Pawchive(...)— either as the bare value or assession=<value>.
You can also load it from an environment variable:
import os
from pychive import Pawchive
session = os.environ["PAWCHIVE_SESSION"]
with Pawchive(session) as client:
...
export PAWCHIVE_SESSION="your_session_value_here"
API surface
The Pawchive client exposes endpoint groups as properties:
| Property | Class | Single-id methods | Multi-id (*_many) methods |
Auth? |
|---|---|---|---|---|
client.creators |
CreatorsEndpoint |
list_all(), get_profile(s,cid), get_links(s,cid), get_tags(s,cid), get_announcements(s,cid), get_fancards(s,cid) |
get_profile_many(s,cids), get_links_many(s,cids), get_tags_many(s,cids), get_announcements_many(s,cids), get_fancards_many(cids) |
No (fancards: fanbox only) |
client.posts |
PostsEndpoint |
list_recent(l,o), list_from_creator(s,cid,l,o), get(s,cid,pid), list_revisions(s,cid,pid) |
list_from_creator_many(s,cids,l,o), get_many(s,cid,pids), list_revisions_many(s,cid,pids) |
No |
client.comments |
CommentsEndpoint |
list(s,cid,pid) |
list_many(s,cid,pids) |
No |
client.flags |
FlagsEndpoint |
flag(s,cid,pid), get_status(s,cid,pid) |
flag_many(s,cid,pids), get_status_many(s,cid,pids) |
Yes |
client.favorites |
FavoritesEndpoint |
list(), add_post(s,cid,pid), remove_post(s,cid,pid), add_creator(s,cid), remove_creator(s,cid) |
add_post_many(s,cid,pids), remove_post_many(s,cid,pids), add_creator_many(s,cids), remove_creator_many(s,cids) |
Yes |
client.search |
SearchEndpoint |
lookup_hash(hash) |
— | No |
client.misc |
MiscEndpoint |
app_version() |
— | No |
Multi-id methods accept a string or iterable of ids, return a
dictkeyed by id, and accept an optionaldelaykeyword to throttle between requests. A bare string is treated as a single id (not character-split).
Constructor options
Pawchive(
session, # str: session cookie value (with or without "session=")
base_url="https://pawchive.pw/api/v1",
timeout=30, # per-request timeout (seconds)
max_retries=3, # retries on 429 / 5xx
backoff_base=0.5, # exponential backoff base (seconds)
)
Error handling
All errors inherit from pychive.PawchiveError. Catch the base class or a
specific subclass:
| Exception | When raised |
|---|---|
PawchiveError |
Base class for all wrapper errors |
AuthenticationError |
HTTP 401 (invalid/missing session) |
NotFoundError |
HTTP 404 |
RateLimitError |
HTTP 429 after retries exhausted |
ClientError |
Other HTTP 4xx |
ServerError |
HTTP 5xx after retries exhausted |
ValidationError |
Invalid arguments passed to a method |
ConnectionError |
Network/timeout failures |
Each HTTP exception carries .status_code and .response (the original
requests.Response). RateLimitError also exposes .retry_after.
from pychive import Pawchive, RateLimitError, AuthenticationError, NotFoundError
with Pawchive(session) as client:
try:
post = client.posts.get("fanbox", "12345", "67890")
except NotFoundError:
print("Post not found.")
except AuthenticationError:
print("Session expired.")
except RateLimitError as e:
print(f"Rate limited; server suggested waiting {e.retry_after}s")
Retry behavior: the client automatically retries 429, 502, 503, and
504 responses up to max_retries times with exponential backoff. It honors
the Retry-After header when present (capped at 60s).
Project layout
Pychive/
├── pyproject.toml # packaging + tool config
├── README.md
├── AGENTS.md # compact guide for AI coding sessions
├── docs/ # full documentation (Markdown)
│ ├── index.md # entry point + table of contents
│ ├── installation.md
│ ├── quickstart.md
│ ├── authentication.md
│ ├── configuration.md
│ ├── api-reference.md # every endpoint, method, return type
│ ├── models.md # every dataclass and its fields
│ ├── exceptions.md
│ ├── error-handling.md
│ ├── pagination.md
│ ├── cookbook.md # complete examples
│ └── changelog.md
├── tests/ # pytest test suite (responses for HTTP mocking)
│ ├── conftest.py # shared fixtures (client with max_retries=0)
│ ├── test_session_parsing.py
│ ├── test_models.py
│ ├── test_validation.py
│ ├── test_endpoints.py
│ ├── test_error_handling.py
│ └── test_client.py
└── src/
└── pychive/
├── __init__.py # public exports (Pawchive, models, exceptions)
├── client.py # Pawchive — main client class
├── http.py # HttpClient — transport, auth, retry/backoff
├── exceptions.py # exception hierarchy
├── models.py # frozen dataclasses for API responses
├── py.typed # PEP 561 marker (typed package)
└── endpoints/
├── __init__.py
├── base.py # BaseEndpoint
├── creators.py # list_all, profile, links, tags, announcements, fancards
├── posts.py # recent, creator posts, specific post, revisions
├── comments.py # post comments
├── flags.py # flag / flag status
├── favorites.py # list / add / remove posts & creators
├── search.py # hash lookup
└── misc.py # app version
Development
source .venv/bin/activate
pip install -e ".[dev]"
# lint
ruff check src
# type-check
mypy src
# tests
pytest
License
MIT
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 pychive-1.0.0.tar.gz.
File metadata
- Download URL: pychive-1.0.0.tar.gz
- Upload date:
- Size: 28.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
90cd34021259ac0471029f9802e3abbb52943b13c2adcc206a23ec77c2bdb9ed
|
|
| MD5 |
c079d0c7129f709f577b8706f4ed518d
|
|
| BLAKE2b-256 |
964b7b757420586fe1b20b1d6c36765d7af38d2e92da9da8090820ab4b6d97e9
|
Provenance
The following attestation bundles were made for pychive-1.0.0.tar.gz:
Publisher:
release.yml on NoobToolzz/Pychive
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pychive-1.0.0.tar.gz -
Subject digest:
90cd34021259ac0471029f9802e3abbb52943b13c2adcc206a23ec77c2bdb9ed - Sigstore transparency entry: 2617628682
- Sigstore integration time:
-
Permalink:
NoobToolzz/Pychive@5854163b727d399195ad2c8680c7d5465a2f2dc7 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/NoobToolzz
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@5854163b727d399195ad2c8680c7d5465a2f2dc7 -
Trigger Event:
push
-
Statement type:
File details
Details for the file pychive-1.0.0-py3-none-any.whl.
File metadata
- Download URL: pychive-1.0.0-py3-none-any.whl
- Upload date:
- Size: 23.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b81e826603ff1c8cd9f972683059b8b390af8ff1683f295ac29c97b7607a6a13
|
|
| MD5 |
2ba501d32058896a4dde43858db5087a
|
|
| BLAKE2b-256 |
8a5a8f97ba2eaeab25ebb5e6200bf6cad6d1196dbe548b1ea034d794046a66a7
|
Provenance
The following attestation bundles were made for pychive-1.0.0-py3-none-any.whl:
Publisher:
release.yml on NoobToolzz/Pychive
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pychive-1.0.0-py3-none-any.whl -
Subject digest:
b81e826603ff1c8cd9f972683059b8b390af8ff1683f295ac29c97b7607a6a13 - Sigstore transparency entry: 2617628686
- Sigstore integration time:
-
Permalink:
NoobToolzz/Pychive@5854163b727d399195ad2c8680c7d5465a2f2dc7 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/NoobToolzz
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@5854163b727d399195ad2c8680c7d5465a2f2dc7 -
Trigger Event:
push
-
Statement type: