diff --git a/README.md b/README.md
index 8f98d25..acd260c 100644
--- a/README.md
+++ b/README.md
@@ -28,7 +28,7 @@
* [About](#about)
* [Installation](#installation)
-* [API Reference](#api-reference)
+* [Docs](#docs)
* [License](#license)
## About
@@ -47,73 +47,95 @@ pip install pyanilist
## Usage
-PyAnilist offers two main classes:
-
1. `Anilist()` - Synchronous class
- `search()` - Search a media
```py
- >>> from pyanilist import Anilist, MediaType
- >>> media = Anilist().search("Attack on Titan", type=MediaType.ANIME)
- >>> media.title
- MediaTitle(romaji='Shingeki no Kyojin', english='Attack on Titan', native='進撃の巨人')
- >>> media.title.romaji
- 'Shingeki no Kyojin'
- >>> media.site_url
- Url('https://anilist.co/anime/16498')
- >>> media.episodes
+ from pyanilist import Anilist, MediaType
+
+ media = Anilist().search("Attack on Titan", type=MediaType.ANIME)
+
+ print(media.title.romaji)
+ """
+ Shingeki no Kyojin
+ """
+ print(media.site_url)
+ """
+ https://anilist.co/anime/16498
+ """
+ print(media.episodes)
+ """
25
+ """
```
- `get()` - Get a media by it's Anilist ID
```py
- >>> from pyanilist import Anilist
- >>> media = Anilist().get(21459)
- >>> media.title
- MediaTitle(romaji='Boku no Hero Academia', english='My Hero Academia', native='僕のヒーローアカデミア')
- >>> media.title.english
- 'My Hero Academia'
- >>> media.site_url
- Url('https://anilist.co/anime/21459')
- >>> media.episodes
+ from pyanilist import Anilist
+
+ media = Anilist().get(21459)
+
+ print(media.title.english)
+ """
+ My Hero Academia
+ """
+ print(media.site_url)
+ """
+ https://anilist.co/anime/21459
+ """
+ print(media.episodes)
+ """
13
+ """
```
2. `AsyncAnilist()` - Asynchronous class
- `search()` - Search a media
```py
- >>> import asyncio
- >>> from pyanilist import AsyncAnilist, MediaType
- >>> media = asyncio.run(AsyncAnilist().search("Attack on Titan", type=MediaType.ANIME))
- >>> media.title
- MediaTitle(romaji='Shingeki no Kyojin', english='Attack on Titan', native='進撃の巨人')
- >>> media.title.romaji
- 'Shingeki no Kyojin'
- >>> media.site_url
- Url('https://anilist.co/anime/16498')
- >>> media.episodes
+ import asyncio
+ from pyanilist import AsyncAnilist, MediaType
+
+ media = asyncio.run(AsyncAnilist().search("Attack on Titan", type=MediaType.ANIME))
+
+ print(media.title.romaji)
+ """
+ Shingeki no Kyojin
+ """
+ print(media.site_url)
+ """
+ https://anilist.co/anime/16498
+ """
+ print(media.episodes)
+ """
25
+ """
```
- `get()` - Get a media by it's Anilist ID
```py
- >>> import asyncio
- >>> from pyanilist import AsyncAnilist
- >>> media = asyncio.run(AsyncAnilist().get(21459))
- >>> media.title
- MediaTitle(romaji='Boku no Hero Academia', english='My Hero Academia', native='僕のヒーローアカデミア')
- >>> media.title.english
- 'My Hero Academia'
- >>> media.site_url
- Url('https://anilist.co/anime/21459')
- >>> media.episodes
+ import asyncio
+ from pyanilist import AsyncAnilist
+
+ media = asyncio.run(AsyncAnilist().get(21459))
+
+ print(media.title.english)
+ """
+ My Hero Academia
+ """
+ print(media.site_url)
+ """
+ https://anilist.co/anime/21459
+ """
+ print(media.episodes)
+ """
13
+ """
```
-## API Reference
+## Docs
-Checkout the complete API reference [here](https://ravencentric.github.io/pyanilist/).
+Checkout the complete documentation [here](https://pyanilist.zip).
## License
diff --git a/docs/examples.md b/docs/examples.md
new file mode 100644
index 0000000..234dcdf
--- /dev/null
+++ b/docs/examples.md
@@ -0,0 +1,125 @@
+# Examples
+
+!!! note
+ These examples use `pyanilist.Anilist` but you can do the same thing with `pyanilist.AsyncAnilist` since they share the same methods
+
+## Anilist ID
+
+```py
+from pyanilist import Anilist
+
+media = Anilist().get(16498)
+
+print(media.title.english)
+"""
+Attack on Titan
+"""
+```
+
+## Search
+
+```py
+from pyanilist import Anilist
+
+media = Anilist().search("Attack on titan")
+
+print(media.format)
+"""
+ANIME
+"""
+print(media.title.romaji)
+"""
+Shingeki no Kyojin
+"""
+print(media.episodes)
+"""
+25
+"""
+```
+
+## Search with constraints
+
+```py
+from pyanilist import Anilist, MediaSeason, MediaType, MediaStatus, MediaFormat
+media = Anilist().search(
+ "My Hero Academia",
+ season=MediaSeason.SPRING,
+ season_year=2016,
+ type=MediaType.ANIME,
+ format=MediaFormat.TV,
+ status=MediaStatus.FINISHED,
+
+)
+print(media.title.romaji)
+"""
+Boku no Hero Academia
+"""
+print(media.start_date.iso_format())
+"""
+2016-04-03
+"""
+print(media.site_url)
+"""
+https://anilist.co/anime/21459
+"""
+```
+
+## Related media
+
+```py
+from pyanilist import Anilist
+
+media = Anilist().search("violet evergarden")
+
+print(media.format)
+"""
+TV
+"""
+
+for relation in media.relations:
+ print(f"{relation.title.romaji} ({relation.format}) - {relation.site_url}")
+"""
+Violet Evergarden: Kitto "Ai" wo Shiru Hi ga Kuru no Darou (OVA) - https://anilist.co/anime/101432
+Violet Evergarden (NOVEL) - https://anilist.co/manga/97298
+Violet Evergarden Gaiden: Eien to Jidou Shuki Ningyou (MOVIE) - https://anilist.co/anime/109190
+Violet Evergarden CM (ONA) - https://anilist.co/anime/154164
+"""
+```
+
+## Retries
+
+Anilist API is flaky, sometimes it might return an error for a perfectly valid request. `pyanilist` handles this by simply retrying failed requests a specified number of times (default is 5) before raising an error. Every subsequent retry also adds an additional one-second delay between requests.
+
+```py
+from pyanilist import Anilist
+
+# Configure the number of retries. Setting it to 1 basically disables retrying.
+anilist = Anilist(retries=1)
+
+media = anilist.search("violet evergarden")
+
+print(f"{media.title.english} - {media.site_url}")
+"""
+Violet Evergarden - https://anilist.co/anime/21827
+"""
+```
+
+## Client
+
+`pyanilist` gives you direct access to the internal [`httpx.Client()`](https://www.python-httpx.org/api/#client) used to send the POST request.
+
+```py
+from pyanilist import Anilist
+
+headers = {'user-agent': 'my-app/0.0.1'}
+
+# You can pass any httpx.Client() keyword argument to Anilist()
+anilist = Anilist(headers=headers)
+
+media = anilist.get(105333)
+
+print(media.title.english)
+"""
+Dr. STONE
+"""
+```
\ No newline at end of file
diff --git a/docs/index.md b/docs/index.md
index 7285e68..6df01d2 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -10,17 +10,15 @@
-
-
-[](https://pypi.org/project/pyanilist/)
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
## About
@@ -45,68 +43,88 @@ PyAnilist offers two main classes:
- `search()` - Search a media
```py
- >>> from pyanilist import Anilist, MediaType
- >>> media = Anilist().search("Attack on Titan", type=MediaType.ANIME)
- >>> media.title
- MediaTitle(romaji='Shingeki no Kyojin', english='Attack on Titan', native='進撃の巨人')
- >>> media.title.romaji
- 'Shingeki no Kyojin'
- >>> media.site_url
- Url('https://anilist.co/anime/16498')
- >>> media.episodes
+ from pyanilist import Anilist, MediaType
+
+ media = Anilist().search("Attack on Titan", type=MediaType.ANIME)
+
+ print(media.title.romaji)
+ """
+ Shingeki no Kyojin
+ """
+ print(media.site_url)
+ """
+ https://anilist.co/anime/16498
+ """
+ print(media.episodes)
+ """
25
+ """
```
- `get()` - Get a media by it's Anilist ID
```py
- >>> from pyanilist import Anilist
- >>> media = Anilist().get(21459)
- >>> media.title
- MediaTitle(romaji='Boku no Hero Academia', english='My Hero Academia', native='僕のヒーローアカデミア')
- >>> media.title.english
- 'My Hero Academia'
- >>> media.site_url
- Url('https://anilist.co/anime/21459')
- >>> media.episodes
+ from pyanilist import Anilist
+
+ media = Anilist().get(21459)
+
+ print(media.title.english)
+ """
+ My Hero Academia
+ """
+ print(media.site_url)
+ """
+ https://anilist.co/anime/21459
+ """
+ print(media.episodes)
+ """
13
+ """
```
2. `AsyncAnilist()` - Asynchronous class
- `search()` - Search a media
```py
- >>> import asyncio
- >>> from pyanilist import AsyncAnilist, MediaType
- >>> media = asyncio.run(AsyncAnilist().search("Attack on Titan", type=MediaType.ANIME))
- >>> media.title
- MediaTitle(romaji='Shingeki no Kyojin', english='Attack on Titan', native='進撃の巨人')
- >>> media.title.romaji
- 'Shingeki no Kyojin'
- >>> media.site_url
- Url('https://anilist.co/anime/16498')
- >>> media.episodes
+ import asyncio
+ from pyanilist import AsyncAnilist, MediaType
+
+ media = asyncio.run(AsyncAnilist().search("Attack on Titan", type=MediaType.ANIME))
+
+ print(media.title.romaji)
+ """
+ Shingeki no Kyojin
+ """
+ print(media.site_url)
+ """
+ https://anilist.co/anime/16498
+ """
+ print(media.episodes)
+ """
25
+ """
```
- `get()` - Get a media by it's Anilist ID
```py
- >>> import asyncio
- >>> from pyanilist import AsyncAnilist
- >>> media = asyncio.run(AsyncAnilist().get(21459))
- >>> media.title
- MediaTitle(romaji='Boku no Hero Academia', english='My Hero Academia', native='僕のヒーローアカデミア')
- >>> media.title.english
- 'My Hero Academia'
- >>> media.site_url
- Url('https://anilist.co/anime/21459')
- >>> media.episodes
+ import asyncio
+ from pyanilist import AsyncAnilist
+
+ media = asyncio.run(AsyncAnilist().get(21459))
+
+ print(media.title.english)
+ """
+ My Hero Academia
+ """
+ print(media.site_url)
+ """
+ https://anilist.co/anime/21459
+ """
+ print(media.episodes)
+ """
13
+ """
```
-## API Reference
-
-Checkout the complete API reference [here](https://ravencentric.github.io/pyanilist/).
-
## License
Distributed under the [Unlicense](https://choosealicense.com/licenses/unlicense/) License. See [UNLICENSE](https://github.com/Ravencentric/pyanilist/blob/main/UNLICENSE) for more information.
\ No newline at end of file
diff --git a/mkdocs.yml b/mkdocs.yml
index 04b25ea..b38604a 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -78,6 +78,7 @@ markdown_extensions:
nav:
- Home: index.md
+ - Examples: examples.md
- API Reference:
- Clients: api-reference/clients.md
- Models: api-reference/models.md
diff --git a/src/pyanilist/_clients/_async.py b/src/pyanilist/_clients/_async.py
index 83f726d..595aa06 100644
--- a/src/pyanilist/_clients/_async.py
+++ b/src/pyanilist/_clients/_async.py
@@ -178,7 +178,7 @@ async def search(
Parameters
----------
title : AnilistTitle | None, optional
- The string used for searching on Anilist. Default is None.
+ The string used for searching on Anilist.
season : MediaSeason | None, optional
The season the media was initially released in. Default is None.
season_year : AnilistYear | None, optional
@@ -194,8 +194,8 @@ async def search(
------
ValidationError
Invalid input
- pyanilist.exceptions.*
- Any exception from the pyanilist.exceptions module may be raised
+ pyanilist._exceptions.*
+ Any exception from the pyanilist._exceptions module may be raised
in case of errors encountered during the POST request.
Returns
@@ -231,8 +231,8 @@ async def get(self, id: AnilistID) -> Media:
------
ValidationError
Invalid input
- pyanilist.exceptions.*
- Any exception from the pyanilist.exceptions module may be raised
+ pyanilist._exceptions.*
+ Any exception from the pyanilist._exceptions module may be raised
in case of errors encountered during the POST request.
Returns
diff --git a/src/pyanilist/_clients/_sync.py b/src/pyanilist/_clients/_sync.py
index b07afeb..34d5f8c 100644
--- a/src/pyanilist/_clients/_sync.py
+++ b/src/pyanilist/_clients/_sync.py
@@ -193,8 +193,8 @@ def search(
------
ValidationError
Invalid input
- pyanilist.exceptions.*
- Any exception from the pyanilist.exceptions module may be raised
+ pyanilist._exceptions.*
+ Any exception from the pyanilist._exceptions module may be raised
in case of errors encountered during the POST request.
Returns
@@ -230,8 +230,8 @@ def get(self, id: AnilistID) -> Media:
------
ValidationError
Invalid input
- pyanilist.exceptions.*
- Any exception from the pyanilist.exceptions module may be raised
+ pyanilist._exceptions.*
+ Any exception from the pyanilist._exceptions module may be raised
in case of errors encountered during the POST request.
Returns