Skip to main content

touhou-world

A Python package for querying Touhou Project character data, powered by thwiki.cc.

pip install touhou-world

Quick Start

Async (recommended)

import asyncio
from TouhouWorld import TouhouWorld

async def main():
    async with TouhouWorld() as tw:
        char = await tw.get_character("博丽灵梦")
        print(char.name, char.species, char.ability)

        names = await tw.all_characters()
        print(f"Total characters: {len(names)}")

asyncio.run(main())

Sync

from TouhouWorld import CharacterFetcher

with CharacterFetcher() as f:
    char = f.get("雾雨魔理沙")
    print(char)

    results = f.search("咲夜")
    print(results)

Character Model

class Character(msgspec.Struct, frozen=True):
    name: str                        # 中文名
    name_jp: str | None              # 日文名
    name_en: str | None              # 英文名
    species: str | None              # 种族
    ability: str | None              # 能力
    occupation: str | None           # 职业/身份
    location: str | None             # 居所
    first_appearance: str | None     # 初登场作品
    appearances: tuple[str, ...]     # 所有登场作品
    theme: str | None                # 主题曲
    source_url: str | None           # 数据来源页面

TouhouWorld API

async with TouhouWorld() as tw:
    # 查询单个角色
    char = await tw.get_character("十六夜咲夜")

    # 并发查询多个
    chars = await tw.get_characters(["博丽灵梦", "雾雨魔理沙"])

    # 搜索
    results = await tw.search_characters("红魔馆", limit=5)

    # 确认是否存在
    exists = await tw.character_exists("帕秋莉·诺蕾姬")

    # 所有官方角色名
    names = await tw.all_characters()

Custom DataSource

Implement IDataSource (async) or ISyncDataSource (sync) to plug in your own backend.

from TouhouWorld import TouhouWorld, IDataSource, AsyncCharacterFetcher

class MyDataSource(IDataSource):
    async def get_character(self, name): ...
    async def get_characters(self, names): ...
    async def search_characters(self, query, limit): ...
    async def all_characters(self): ...
    async def close(self): ...

async with TouhouWorld(datasource=MyDataSource()) as tw:
    char = await tw.get_character("博丽灵梦")

# Or use the fetcher layer directly
async with AsyncCharacterFetcher(datasource=MyDataSource()) as f:
    char = await f.get("博丽灵梦")

Plugin System

from TouhouWorld import Plugin, PluginBase, PluginConfig, TouhouWorld

class MyConfig(PluginConfig):
    prefix: str = "[LOG]"

@Plugin("logger", version="1.0.0", description="Log every ready event", config_class=MyConfig)
class LoggerPlugin(PluginBase):
    async def on_load(self, world):
        print(f"{self.config.prefix} loaded")

    async def on_ready(self, world):
        print(f"{self.config.prefix} world is ready")

    async def on_stop(self, world):
        print(f"{self.config.prefix} stopping")

async with TouhouWorld() as tw:
    await tw.plugins.load_all(configs={"logger": {"prefix": "[TOUHOU]"}})

Plugin lifecycle

on_load → on_ready → [running] → on_stop → on_unload

Any hook that raises will call on_error and be isolated — other plugins continue normally.

Load from module or directory

# By module path (importlib)
await tw.plugins.load_module("myapp.plugins.logger")

# Scan a directory for all plugin files
await tw.plugins.load_directory("plugins/")

Dependencies

Package Purpose
aiohttp Async HTTP
requests Sync HTTP
beautifulsoup4 HTML parsing
msgspec Fast data models
loguru Logging

License

MIT

Metadata

Release files for touhou-world 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for touhou-world 0.1.0
File Size Uploaded Provenance Actions
touhou_world-0.1.0.tar.gz 16.1 kB Without provenance Details for touhou_world-0.1.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for touhou-world 0.1.0
File Interpreter ABI Platform Actions
touhou_world-0.1.0-py3-none-any.whl Python 3 none any Details for touhou_world-0.1.0-py3-none-any.whl

Total release size: 39.7 kB

Release files / touhou_world-0.1.0.tar.gz

Download URL touhou_world-0.1.0.tar.gz
Size 16.1 kB
Tags Source
SHA-256 checksum
How to use checksums
44b5459fab2fb20ca87048ade83f727096f2571b5e1907d74256591e539c9810
BLAKE2b-256 checksum
How to use checksums
b74cbe301aa2f1f7e66f93e4930623b7f78bf3ba46e5dbc013ea6ea92ec34443
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.3

Release files / touhou_world-0.1.0-py3-none-any.whl

Download URL touhou_world-0.1.0-py3-none-any.whl
Size 23.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
911643998bac75e219c43828d37d40a55a32becac52570abb36719332189ea05
BLAKE2b-256 checksum
How to use checksums
0be444f4ac8229e7e66fffb0571af0f0252d81b4b15d63a0fc5225457d18b5ec
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.3

Security for touhou-world 0.1.0

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.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page