This release is a pre-release and may not be stable for production use.
Nadeshiko SDK
Python SDK for the Nadeshiko API. Full API reference at nadeshiko.co/docs/api.
Install
pip install nadeshiko-sdk
Quick start
from nadeshiko import Nadeshiko
from nadeshiko.models import SearchQuery
client = Nadeshiko(
api_key=os.environ["NADESHIKO_API_KEY"],
)
data = client.search(query=SearchQuery(search="彼女"))
print(data.segments)
# [
# Segment(
# segment_public_id="xK9mP2nQwR4t",
# media_public_id="steins-gate",
# episode=1,
# start_time_ms=62340,
# end_time_ms=65180,
# text_ja=SegmentTextJa(content="彼女に会いたい", ...),
# text_en=SegmentTextEn(content="I want to see her", ...),
# urls=SegmentUrls(
# image_url="https://...",
# audio_url="https://...",
# video_url="https://...",
# ),
# ),
# # ...
# ]
Methods return data directly and accept model objects — pass SearchQuery, SearchFilters, and other model instances directly.
Authentication
Pass your API key to Nadeshiko. It is sent as Authorization: Bearer <api_key> on every request.
client = Nadeshiko(
api_key=os.environ["NADESHIKO_API_KEY"],
base_url="PRODUCTION", # "LOCAL" | "DEVELOPMENT" | "PRODUCTION" | custom URL
headers={"User-Agent": "MyApp/1.0"},
)
Model objects
All methods accept model objects — body fields are passed as SearchQuery, SearchFilters, and other model instances:
from nadeshiko.models import SearchQuery, SearchFilters, ContentRating
# POST endpoints — body models
result = client.search(
query=SearchQuery(search="猫"),
filters=SearchFilters(content_rating=[ContentRating.SAFE]),
)
# GET with query params — as keyword arguments
media_list = client.list_media(query="naruto", category="ANIME")
# GET with path params — as keyword arguments or positional
collection = client.get_collection("collection-public-id")
episode = client.get_episode(media_public_id="abc", episode_number=5)
Single-path-param endpoints also accept the ID as a plain string:
media = client.get_media("some-public-id")
segment = client.get_segment("some-uuid")
context = client.get_segment_context("some-uuid")
Available endpoints
Search
| Method | Description |
|---|---|
search(params?) |
Search segments by query, with filters and sorting |
get_search_stats(params?) |
Category counts and media list for filter UI |
search_words(params) |
Look up multiple words and get match counts per media |
search_media(params) |
Find media by name (autocomplete) |
Stats
| Method | Description |
|---|---|
get_stats_overview() |
Corpus-wide stats: segment count, media count, coverage tiers |
Media
| Method | Description |
|---|---|
list_media(params?) |
Browse the media catalog |
get_media(id) |
Get a single media entry by public ID |
list_episodes(params) |
List episodes for a media entry |
get_episode(params) |
Get a single episode |
get_segment(id) |
Get a single segment by UUID |
get_segment_context(id) |
Get segments surrounding a given segment |
User
| Method | Description |
|---|---|
get_me() |
Current user profile and API quota |
list_user_activity(params?) |
Activity history (searches, plays, exports) |
get_user_activity_heatmap(params?) |
Daily activity counts for a heatmap |
get_user_activity_stats(params?) |
Aggregate stats over a date range |
list_excluded_media() |
Media hidden from search results |
add_excluded_media(params) |
Hide a media entry from search results |
remove_excluded_media(id) |
Un-hide a media entry |
Collections
| Method | Description |
|---|---|
list_collections(params?) |
List your saved collections |
create_collection(params) |
Create a new collection |
get_collection(id) |
Get a collection and its segments |
delete_collection(id) |
Delete a collection |
add_segment_to_collection(params) |
Add a segment to a collection |
search_collection_segments(params) |
Search within a collection |
remove_segment_from_collection(params) |
Remove a segment from a collection |
Error handling
Errors throw a NadeshikoError. A proper Exception subclass with all RFC 7807 Problem Details fields.
from nadeshiko import NadeshikoError
from nadeshiko.models import SearchQuery
try:
data = client.search(query=SearchQuery(search="食べる"))
print(data.segments)
except NadeshikoError as err:
match err.code:
case "VALIDATION_FAILED":
print("Validation failed:", err.detail)
for field, msg in (err.errors or {}).items():
print(f" {field}: {msg}")
case "AUTH_CREDENTIALS_REQUIRED" | "AUTH_CREDENTIALS_INVALID":
print("Authentication failed:", err.detail)
case "RATE_LIMIT_EXCEEDED":
print("Rate limited - slow down")
case "QUOTA_EXCEEDED":
print("Monthly quota exhausted")
case "INTERNAL_SERVER_EXCEPTION":
print("Server error, trace ID:", err.trace_id)
NadeshikoError fields:
| Field | Type | Description |
|---|---|---|
code |
str |
Machine-readable error code |
title |
str |
Short summary |
detail |
str |
Human-readable explanation |
status |
int |
HTTP status code |
trace_id |
str | None |
Trace ID - include when reporting issues |
errors |
dict[str, object] | None |
Per-field messages (VALIDATION_FAILED only) |
Opt out of throwing per-call
Pass throw_on_error=False to get a response object instead of throwing:
from nadeshiko.models import SearchQuery
result = client.search(
throw_on_error=False,
query=SearchQuery(search="猫"),
)
if result.error is not None:
print(result.error)
else:
print(result.data.segments)
Retry and timeout
The client retries automatically on network errors and 408 / 429 / 500 / 502 / 503 / 504 responses. 429 responses with a Retry-After header are respected.
from nadeshiko import Nadeshiko, RetryOptions
client = Nadeshiko(
api_key=os.environ["NADESHIKO_API_KEY"],
retry_options=RetryOptions(
max_retries=3, # default: 2
initial_delay=1, # default: 0.5 - doubles with each attempt
max_delay=30, # default: 30
timeout=10, # per-attempt timeout in seconds (default: none)
),
)
Pagination
Paginated endpoints have an iter_* method that returns an iterator over individual items:
from nadeshiko.models import SearchQuery
for segment in client.iter_search(
query=SearchQuery(search="猫"),
):
print(segment.text_ja.content)
for media in client.iter_list_media():
print(media.name_en)
For manual page-by-page control, use the cursor field:
from nadeshiko.models import SearchQuery
cursor: str | None = None
while True:
data = client.search(
query=SearchQuery(search="犬"),
take=10,
cursor=cursor,
)
for segment in data.segments:
print(segment.text_ja.content)
if not data.pagination.has_more or data.pagination.cursor is None:
break
cursor = data.pagination.cursor
See examples/examples.py for more usage patterns.
Metadata
Release files for nadeshiko-internal-sdk 2.2.0.dev1781577462
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| nadeshiko_internal_sdk-2.2.0.dev1781577462.tar.gz | 103.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| nadeshiko_internal_sdk-2.2.0.dev1781577462-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 416.8 kB
Release files / nadeshiko_internal_sdk-2.2.0.dev1781577462.tar.gz
| Download URL | nadeshiko_internal_sdk-2.2.0.dev1781577462.tar.gz |
|---|---|
| Size | 103.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
14d5e9cabc235938e54db9123bb6440ca3e9abfe88066a27b4d618097d91d400
|
|
BLAKE2b-256 checksum How to use checksums |
d1116485820643b5de1ae8be083dbba0b301244cb470bbcc2e1234657443ad3e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jun 16, 2026.
Transparency logRelease files / nadeshiko_internal_sdk-2.2.0.dev1781577462-py3-none-any.whl
| Download URL | nadeshiko_internal_sdk-2.2.0.dev1781577462-py3-none-any.whl |
|---|---|
| Size | 313.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
4397169f5bc6890c7a555382cbb9af7a7bac15d6c084f8ab46fad76c4bb8a978
|
|
BLAKE2b-256 checksum How to use checksums |
aec7c42012c7f26edf7aab9bbb4ca01cf66f600c0d0c42c75a731f4ddafee369
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jun 16, 2026.
Transparency log