Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
318d5a2
Initial implementation of improved error handling
Electronic-Mango Apr 2, 2026
7431421
Add raised exceptions to docstrings
Electronic-Mango Apr 2, 2026
1edea7b
Update messages and fields in exceptions
Electronic-Mango Apr 2, 2026
399183e
Whole bunch of prep for full release
Electronic-Mango Apr 3, 2026
3cf4852
Move internal modules in docs to separate section
Electronic-Mango Apr 3, 2026
1278832
Tweaks to docstrings, minor refactor
Electronic-Mango Apr 3, 2026
f104046
Tweak docstrings, add icons to docs, order elements in docs
Electronic-Mango Apr 3, 2026
b331419
Add TODO to readme
Electronic-Mango Apr 3, 2026
e7db252
Improve docstrings in "exceptions.py"
Electronic-Mango Apr 3, 2026
2e6821d
Add new exception for invalid language code, minor refactor to "query…
Electronic-Mango Apr 3, 2026
be23e99
Update docstrings for tuples
Electronic-Mango Apr 3, 2026
dd2f424
Remove order of functions/classes from docs
Electronic-Mango Apr 3, 2026
a374dce
Restore explicit list of functions in docs
Electronic-Mango Apr 3, 2026
52c45db
Remove init args description from exception docstrings
Electronic-Mango Apr 3, 2026
9b0876e
Change "Exceptions" icon in docs
Electronic-Mango Apr 3, 2026
4b43a52
Improve type-hinting JSONs in query.py
Electronic-Mango Apr 3, 2026
7ea7bcc
Tweak parsing OfferPackage icon URL
Electronic-Mango Apr 3, 2026
f49df99
Remove locale-specific exceptions and verification
Electronic-Mango Apr 4, 2026
093d5ef
Tweak docstrings
Electronic-Mango Apr 4, 2026
a1f5dee
Add more pages to docs, mostly in "initial" state
Electronic-Mango Apr 4, 2026
10c5dc8
Update docstrings in justwatch.py
Electronic-Mango Apr 8, 2026
a653ef4
Tweaks to README.md
Electronic-Mango Apr 8, 2026
376bec8
Add new "caveats" page to docs
Electronic-Mango Apr 8, 2026
03237e6
Expand docs start page
Electronic-Mango Apr 8, 2026
32f4b5e
Remove httpx from installation page
Electronic-Mango Apr 8, 2026
92f0a56
Update "usage" docs page
Electronic-Mango Apr 8, 2026
f5e958e
More updates to docstrings in "justwatch.py"
Electronic-Mango Apr 8, 2026
3dd1bc5
Fix too long lines in examples
Electronic-Mango Apr 8, 2026
f7f0c65
Add examples (and docs) back to ruff linter
Electronic-Mango Apr 8, 2026
d02a1f1
Update packages
Electronic-Mango Apr 8, 2026
80749f6
Rename "request/response complexity" with "operation complexity" in R…
Electronic-Mango Apr 8, 2026
12deedd
Tweak docs
Electronic-Mango Apr 8, 2026
560fc05
Update ToC labels in API References in docs
Electronic-Mango Apr 8, 2026
21bf552
Describe pagination in "Caveats" docs page
Electronic-Mango Apr 9, 2026
dd36d85
Tweak docs
Electronic-Mango Apr 9, 2026
6ddc97b
Tweak docstrings in "justwatch.py"
Electronic-Mango Apr 9, 2026
db8888a
Rework "Usage" docs page
Electronic-Mango Apr 9, 2026
d1f5a9c
Add more details to basic examples in "usage.md" docs page
Electronic-Mango Apr 9, 2026
91005ec
Add more advanced examples to "usage.md" docs page
Electronic-Mango Apr 9, 2026
d234977
Remove internal API Reference from docs
Electronic-Mango Apr 9, 2026
04c4e3d
Use "spacy" docstring section style
Electronic-Mango Apr 9, 2026
a1828d3
Update "caveats.md" docs page
Electronic-Mango Apr 9, 2026
8d15575
Tweaks to docs, add pagination example to "usage.md"
Electronic-Mango Apr 9, 2026
126f547
Tweak docstrings in "justwatch.py"
Electronic-Mango Apr 9, 2026
379bf45
Tweaks to "usage.md" docs page
Electronic-Mango Apr 9, 2026
069eded
Update dependencies
Electronic-Mango Apr 9, 2026
f908cc8
Tweak docstrings
Electronic-Mango Apr 10, 2026
669f6d0
Tweak "usage" page to match new docstrings
Electronic-Mango Apr 10, 2026
1da9320
Add instant preview to selected links
Electronic-Mango Apr 10, 2026
9ad56a3
Tweaks to "usage" docs page
Electronic-Mango Apr 11, 2026
91662d6
Final docs pages tweaks
Electronic-Mango Apr 11, 2026
11562ef
Remove old Sphinx workflow
Electronic-Mango Apr 11, 2026
da960ba
Streamline README.md since most of the information is in docs
Electronic-Mango Apr 11, 2026
9bdf75f
Remove initial Zensical pages from zensical.toml
Electronic-Mango Apr 11, 2026
a36a9e5
Remove "under construction" admonition
Electronic-Mango Apr 11, 2026
dc06685
Add CHANGELOG.md
Electronic-Mango Apr 11, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Add raised exceptions to docstrings
  • Loading branch information
Electronic-Mango committed Apr 4, 2026
commit 74314213e926b40272ec51d9ec563a670a5dae32
29 changes: 23 additions & 6 deletions src/simplejustwatchapi/justwatch.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,9 @@ def search(
list[MediaEntry]: List of ``MediaEntry`` NamedTuples parsed from JustWatch response.

Raises:
httpx.HTTPStatusError: If JustWatch API doesn't respond with success code.
JustWatchHttpError: If JustWatch API doesn't respond with 2xx success code.
JustWatchCountryCodeError: Provided ``country`` is not a 2-letter code.
JustWatchApiError: Response from API has internal errors.

"""
request = prepare_search_request(title, country, language, count, best_only, offset, providers)
Expand Down Expand Up @@ -134,7 +136,9 @@ def popular(
list[MediaEntry]: List of ``MediaEntry`` NamedTuples parsed from JustWatch response.

Raises:
httpx.HTTPStatusError: If JustWatch API doesn't respond with success code.
JustWatchHttpError: If JustWatch API doesn't respond with 2xx success code.
JustWatchCountryCodeError: Provided ``country`` is not a 2-letter code.
JustWatchApiError: Response from API has internal errors.

"""
request = prepare_popular_request(country, language, count, best_only, offset, providers)
Expand Down Expand Up @@ -166,7 +170,9 @@ def details(
MediaEntry: ``MediaEntry`` NamedTuple with data about requested entry.

Raises:
httpx.HTTPStatusError: If JustWatch API doesn't respond with success code.
JustWatchHttpError: If JustWatch API doesn't respond with 2xx success code.
JustWatchCountryCodeError: Provided ``country`` is not a 2-letter code.
JustWatchApiError: Response from API has internal errors.

"""
request = prepare_details_request(node_id, country, language, best_only)
Expand Down Expand Up @@ -195,7 +201,9 @@ def seasons(
list[MediaEntry]: List of ``MediaEntry`` NamedTuples with data about requested entry.

Raises:
httpx.HTTPStatusError: If JustWatch API doesn't respond with success code.
JustWatchHttpError: If JustWatch API doesn't respond with 2xx success code.
JustWatchCountryCodeError: Provided ``country`` is not a 2-letter code.
JustWatchApiError: Response from API has internal errors.

"""
request = prepare_seasons_request(show_id, country, language, best_only)
Expand Down Expand Up @@ -224,7 +232,9 @@ def episodes(
list[Episode]: List of ``Episode`` NamedTuples with data about requested entry.

Raises:
httpx.HTTPStatusError: If JustWatch API doesn't respond with success code.
JustWatchHttpError: If JustWatch API doesn't respond with 2xx success code.
JustWatchCountryCodeError: Provided ``country`` is not a 2-letter code.
JustWatchApiError: Response from API has internal errors.

"""
request = prepare_episodes_request(season_id, country, language, best_only)
Expand Down Expand Up @@ -281,7 +291,9 @@ def offers_for_countries(
and keys are all found offers for their respective countries.

Raises:
httpx.HTTPStatusError: If JustWatch API doesn't respond with success code.
JustWatchHttpError: If JustWatch API doesn't respond with 2xx success code.
JustWatchCountryCodeError: Provided ``countries`` contain invalid county code.
JustWatchApiError: Response from API has internal errors.

"""
if not countries:
Expand All @@ -304,6 +316,11 @@ def providers(country: str = "US") -> list[OfferPackage]:
values in ``Offer`` (and thus in ``MediaEntry``), but the data structure is the same,
so the same tuple is reused.

Raises:
JustWatchHttpError: If JustWatch API doesn't respond with 2xx success code.
JustWatchCountryCodeError: Provided ``country`` is not a 2-letter code.
JustWatchApiError: Response from API has internal errors.

"""
request = prepare_providers_request(country)
response = post(_GRAPHQL_API_URL, json=request)
Expand Down
53 changes: 43 additions & 10 deletions src/simplejustwatchapi/query.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@ def prepare_search_request(
Returns:
dict: JSON/dict with GraphQL POST body.

Raises:
JustWatchCountryCodeError: Provided ``country`` is not a 2-letter code.

"""
_raise_for_invalid_country_code(country)
return {
Expand Down Expand Up @@ -102,6 +105,9 @@ def parse_search_response(json: dict) -> list[MediaEntry]:
Returns:
list[MediaEntry]: Parsed received JSON as a list of ``MediaEntry`` NamedTuples.

Raises:
JustWatchApiError: Response from API has internal errors.

"""
_raise_for_errors_in_response(json)
return [_parse_entry(edge["node"]) for edge in json["data"]["popularTitles"]["edges"]]
Expand Down Expand Up @@ -136,6 +142,9 @@ def prepare_popular_request(
Returns:
dict: JSON/dict with GraphQL POST body.

Raises:
JustWatchCountryCodeError: Provided ``country`` is not a 2-letter code.

"""
_raise_for_invalid_country_code(country)
return {
Expand Down Expand Up @@ -172,6 +181,9 @@ def parse_popular_response(json: dict) -> list[MediaEntry]:
Returns:
list[MediaEntry]: Parsed received JSON as a list of ``MediaEntry`` NamedTuples.

Raises:
JustWatchApiError: Response from API has internal errors.

"""
_raise_for_errors_in_response(json)
return [_parse_entry(edge["node"]) for edge in json["data"]["popularTitles"]["edges"]]
Expand All @@ -196,6 +208,9 @@ def prepare_details_request(node_id: str, country: str, language: str, best_only
Returns:
dict: JSON/dict with GraphQL POST body.

Raises:
JustWatchCountryCodeError: Provided ``country`` is not a 2-letter code.

"""
_raise_for_invalid_country_code(country)
return {
Expand All @@ -220,16 +235,16 @@ def parse_details_response(json: dict) -> MediaEntry:

Parses response for ``GetTitleNode`` query.

If API responded with an internal error (mostly due to not found node ID),
then ``None`` will be returned instead.

Meant to be used together with :func:`prepare_details_request`.

Args:
json (dict): JSON returned by JustWatch GraphQL API.

Returns:
MediaEntry | None: Parsed received JSON as a ``MediaEntry`` NamedTuple.
MediaEntry: Parsed received JSON as a ``MediaEntry`` NamedTuple.

Raises:
JustWatchApiError: Response from API has internal errors.

"""
_raise_for_errors_in_response(json)
Expand All @@ -255,6 +270,9 @@ def prepare_seasons_request(show_id: str, country: str, language: str, best_only
Returns:
dict: JSON/dict with GraphQL POST body.

Raises:
JustWatchCountryCodeError: Provided ``country`` is not a 2-letter code.

"""
_raise_for_invalid_country_code(country)
return {
Expand All @@ -279,9 +297,6 @@ def parse_seasons_response(json: dict) -> list[MediaEntry]:

Parses response for ``GetTitleNode`` query.

If API responded with an internal error (mostly due to not found node ID),
then ``None`` will be returned instead.

Meant to be used together with :func:`prepare_seasons_request`.

Args:
Expand All @@ -290,6 +305,9 @@ def parse_seasons_response(json: dict) -> list[MediaEntry]:
Returns:
list[MediaEntry]: Parsed received JSON as a ``MediaEntry`` NamedTuple list.

Raises:
JustWatchApiError: Response from API has internal errors.

"""
_raise_for_errors_in_response(json)
return [_parse_entry(season) for season in json["data"]["node"].get("seasons", [])]
Expand All @@ -314,6 +332,9 @@ def prepare_episodes_request(episode_id: str, country: str, language: str, best_
Returns:
dict: JSON/dict with GraphQL POST body.

Raises:
JustWatchCountryCodeError: Provided ``country`` is not a 2-letter code.

"""
_raise_for_invalid_country_code(country)
return {
Expand All @@ -338,9 +359,6 @@ def parse_episodes_response(json: dict) -> list[Episode]:

Parses response for ``GetTitleNode`` query.

If API responded with an internal error (mostly due to not found node ID),
then ``None`` will be returned instead.

Meant to be used together with :func:`prepare_episodes_request`.

Args:
Expand All @@ -349,6 +367,9 @@ def parse_episodes_response(json: dict) -> list[Episode]:
Returns:
list[Episode]: Parsed received JSON as a ``Episode`` NamedTuple list.

Raises:
JustWatchApiError: Response from API has internal errors.

"""
_raise_for_errors_in_response(json)
return [_parse_episode(episode) for episode in json["data"]["node"].get("episodes", [])]
Expand Down Expand Up @@ -379,6 +400,9 @@ def prepare_offers_for_countries_request(
Returns:
dict: JSON/dict with GraphQL POST body.

Raises:
JustWatchCountryCodeError: Provided ``countries`` contain invalid country code.

"""
if not countries:
# This should never happen, justwatch.py should take care of this.
Expand Down Expand Up @@ -423,6 +447,9 @@ def parse_offers_for_countries_response(json: dict, countries: set[str]) -> dict
dict[str, list[Offer]]: A dict, where keys are matching ``countries`` argument and values
are offers for a given country parsed from JSON response.

Raises:
JustWatchApiError: Response from API has internal errors.

"""
_raise_for_errors_in_response(json)
return {
Expand All @@ -447,6 +474,9 @@ def prepare_providers_request(country: str) -> dict:
Returns:
dict: JSON/dict with GraphQL POST body.

Raises:
JustWatchCountryCodeError: Provided ``country`` is not a 2-letter code.

"""
_raise_for_invalid_country_code(country)
return {
Expand Down Expand Up @@ -475,6 +505,9 @@ def parse_providers_response(json: dict) -> list[OfferPackage]:
Returns:
list[MediaEntry]: Parsed received JSON as a list of ``OfferPackage`` NamedTuples.

Raises:
JustWatchApiError: Response from API has internal errors.

"""
_raise_for_errors_in_response(json)
return [_parse_package(package) for package in json["data"]["packages"]]
Expand Down