akipy
A Python wrapper library for the Akinator game API. Akinator is the popular web-based game that guesses characters you're thinking of by asking a series of questions. This library allows you to integrate Akinator's functionality into your Python applications with both synchronous and asynchronous support.
Table of Contents
- Features
- Quick Links
- Installation
- Usage
- Game state and images
- Async usage
- Cloudflare / challenge solvers
- Contributing
Features
- Both synchronous and asynchronous API support
- Context manager support for automatic resource cleanup
- Type hints for better IDE support
- Comprehensive error handling with custom exceptions
- Multiple language support
- Child mode support
- Optional Cloudflare bypass via FlareSolverr, TRAWL, or any FlareSolverr v2-compatible solver
Quick Links
Installation
pip install akipy
Usage
This example covers questions, guesses, Back, and a finished game. A context manager closes the HTTP client when you leave it.
import akipy
with akipy.Akinator() as aki:
aki.start_game(language="en", game_mode="c", child_mode=False)
while not aki.finished:
if aki.win:
print(f"My guess: {aki.name_proposition} ({aki.description_proposition})")
print(f"Character photo: {aki.photo}")
if input("Is that right? [y/n] ").strip().lower() == "y":
aki.choose()
else:
aki.exclude()
continue
print(f"Question {aki.step}: {aki.question}")
print(f"Akinator image: {aki.akinator_image_url}")
reply = input("yes/no/idk/probably/probably not/back: ").strip().lower()
if reply == "back":
try:
aki.back()
except akipy.CantGoBackAnyFurther:
print("Already at the first question.")
else:
try:
aki.answer(reply)
except akipy.InvalidChoiceError:
print("Please enter one of the listed answers.")
if aki.child_mode_blocked:
print("Akinator's guess was hidden by child mode.")
elif aki.soundlike:
print("Akinator ran out of questions and guesses.")
elif aki.win:
print(f"Akinator guessed {aki.name_proposition}.")
else:
print("Game ended without a correct guess.")
The five answer choices are yes, no, idk, probably, and probably not.
You can also pass their numeric IDs, 0 through 4. back is handled by the
example; it is not an answer you pass to aki.answer().
Use game_mode="c" for characters, "a" for animals, or "o" for objects.
Availability depends on the language.
Game state and images
After start_game() and after each action, read these fields from the same
Akinator instance:
| Field | What it tells you |
|---|---|
question |
Current question text. |
step |
Current server step. |
progression / confidence |
Progress as a server value / a float from 0 to 1. |
akinator_image_url |
URL of the current PNG fallback image. akitude_url is an alias. |
win |
Akinator has proposed a character, or you accepted its guess. |
name_proposition, description_proposition, photo |
Details of the proposed character. Read these when win is true. |
no_question |
There are no more questions after the current guess. Rejecting it ends the game. |
child_mode_blocked |
A proposed character was hidden by child mode. |
soundlike |
The game reached its sounds-like ending. |
finished |
The game is over. Check win, child_mode_blocked, and soundlike for the outcome. |
completion |
Last server result, usually "OK". Rejected requests raise an exception. |
The image URL changes as you answer and returns to the previous image when
you call back(). It points to the site's PNG fallback, not a frame from its
animated Lottie artwork. If an API response omits the scores used to select
the next image, the last known PNG stays available.
A guess does not finish the game on its own. Call choose() to accept it or
exclude() to reject it. If no_question is true, exclude() ends the game.
The yes() and no() helpers also work: on a question they answer yes or no;
on a guess they accept or reject it.
Async usage
The async client exposes the same state fields and uses await for game
actions:
import asyncio
from akipy.async_akinator import Akinator
async def play():
async with Akinator() as aki:
await aki.start_game(language="en")
while not aki.finished:
if aki.win:
print(f"Akinator guesses {aki.name_proposition}: {aki.photo}")
if input("Correct? [y/n] ").strip().lower() == "y":
await aki.choose()
else:
await aki.exclude()
else:
print(aki.question, aki.akinator_image_url)
await aki.answer(input("Your answer: ").strip().lower())
asyncio.run(play())
An expired or out-of-sync session raises AkinatorServerError when Akinator
returns completion="KO". A session timeout raises TimeoutError. Start a
new game in either case. See Errors for Cloudflare and solver errors.
Cloudflare / challenge solvers (optional)
Most games work without a solver. akipy sends a browser-style User-Agent on
normal HTTP requests. If Cloudflare challenges those requests, you can pass a
solver that speaks the FlareSolverr v2 POST /v1 API:
| Solver | Notes |
|---|---|
| FlareSolverr | Cloudflare proxy |
| TRAWL | FlareSolverr-compatible API |
| Other v2-compatible proxies | Same request format |
Direct requests run first. On a Cloudflare challenge, akipy calls the solver once, applies cookies and User-Agent to the client, then continues over normal HTTP.
Run a solver locally
FlareSolverr:
docker run -d --name=flaresolverr -p 8191:8191 ghcr.io/flaresolverr/flaresolverr:latest
TRAWL:
docker run -d --name=trawl -p 8191:8191 --shm-size=1gb ghcr.io/germondai/trawl:latest
Use with akipy
import akipy
# FlareSolverr, TRAWL, or any compatible host
aki = akipy.Akinator(solver_url="http://localhost:8191")
# aki = akipy.Akinator(solver_url="https://trawl.example.com")
# aki = akipy.Akinator(solver_url="localhost:8191") # defaults to http
# aki = akipy.Akinator(solver_url="https://fs.example.com/v1")
aki.start_game()
Or set the env var:
export AKIPY_SOLVER_URL="http://localhost:8191"
AKIPY_FLARESOLVERR_URL and flaresolverr_url= still work as aliases.
CI integration tests start FlareSolverr as a service on the runner (http://127.0.0.1:8191). Remote public solvers are often unreachable from GitHub Actions (403 from edge WAF).
Errors
| Exception | When |
|---|---|
CloudflareBlockedError |
Challenge detected and no solver_url configured |
SolverError |
Solver unreachable or returned a non-ok status (FlareSolverrError is an alias) |
AkinatorServerError |
Akinator rejected the game request, often because the session expired or the game state is out of sync |
Contributing
For contributing to this library, please check CONTRIBUTING.md
Metadata
Release files for akipy 1.7.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 | Provenance | Actions |
|---|---|---|---|---|
| akipy-1.7.1.tar.gz | 37.8 kB | Without provenance | Details for akipy-1.7.1.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| akipy-1.7.1-py3-none-any.whl | Python 3 | none | any | Details for akipy-1.7.1-py3-none-any.whl |
Total release size: 62.8 kB
Release files / akipy-1.7.1.tar.gz
| Download URL | akipy-1.7.1.tar.gz |
|---|---|
| Size | 37.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
1b3abfe3119dbaf7a25412d8906ed78ef86be8ea3d9af2000fcac4e1790f6f73
|
|
BLAKE2b-256 checksum How to use checksums |
564f23fdb654a63f984289a124afaf7eb4ece557e5d46f57aa8ebf92a367bf98
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.13.4 {"installer":{"name":"uv","version":"0.13.4","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / akipy-1.7.1-py3-none-any.whl
| Download URL | akipy-1.7.1-py3-none-any.whl |
|---|---|
| Size | 25.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
6195a1392bb0cfd78d0a115c5f890af8d6ab69dd01cb4133d5d2a96f400c66b5
|
|
BLAKE2b-256 checksum How to use checksums |
4461de9413d1f83a60d67bada0865e9d6bc5dac81fe2472958e1f6a9276df6e9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.13.4 {"installer":{"name":"uv","version":"0.13.4","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Security for akipy 1.7.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.