Movies
Overview¶
Core movie operations include the following, in order:
- Searching for a particular movie
- Fetching more details about it
- Identifying URLs pointing to different files with respect to video quality and subtitle language
- Downloading the selected movie file and subtitle file
Movie Search¶
We can locate movies this way:
from moviebox_api.v1.core import Search, Session, SubjectType
async def search_movie():
client_session = Session()
search = Search(
session=client_session, query="avatar", subject_type=SubjectType.MOVIES
)
search_results = await search.get_content()
print(type(search_results)) # (1)
modelled_search_results = await search.get_content_model() # (2)
print(type(modelled_search_results)) # (3)
if __name__ == "__main__":
import asyncio
asyncio.run(search_movie())
- Output:
<class 'dict'>. Access list of movies matching the query fromsearch_results['items'] - This is simply whatever
.get_content()returns, passed into a Pydantic model - Output:
<class 'moviebox_api.v1.models.SearchResultsModel'>. Access search result items fromsearch_results.items
from moviebox_api.v1.core import Search, Session, SubjectType
def search_movie():
client_session = Session()
search = Search(
session=client_session, query="avatar", subject_type=SubjectType.MOVIES
)
search_results = search.get_content_sync()
print(type(search_results)) # (1)
modelled_search_results = search.get_content_model_sync() # (2)
print(type(modelled_search_results)) # (3)
if __name__ == "__main__":
search_movie()
- Output:
<class 'dict'>. Access list of movies matching the query fromsearch_results['items'] - This is simply whatever
.get_content()returns, passed into a Pydantic model - Output:
<class 'moviebox_api.v1.models.SearchResultsModel'>. Access search result items fromsearch_results.items
Developer experience
As shown in the example above, each of the core classes — Search, MovieDetails, DownloadableMovieFilesDetail — has two methods, i.e., get_content() and get_content_model(). In the following examples, we will use the get_content_model() method due to the benefits of working with structured data such as type hints.
Navigating Search Results Page¶
Next Page¶
async def search_movie():
...
contents: SearchResultsModel = await search.get_content_model() # (3)
next_search: Search = search.next_page(contents) # (1)
next_contents: SearchResultsModel = await next_search.get_content_model() # (2)
- Page 2 search instance
- Page 2 search results
- Page 1 search results
Previous Page¶
async def search_movie():
search = Search(Session(), query="avatar" page=3, per_page=5)
contents: SearchResultsModel = await search.get_content_model() # (1)
previous_search: Search = search.previous_page(contents) # (2)
previous_contents: SearchResultsModel = await previous_search.get_content_model() # (3)
- Page 3 search results
- Page 2 search instance
- Page 2 search results
Navigation Check
Before navigating to next page, it's better to consider search_results.pager.hasMore flag.
Movie Details¶
There are two ways to approach this:
- Using a search results item
- Using a specific item page URL
1. Using Search Results Item¶
movie_details_using_search_results_item.py
from moviebox_api.v1 import MovieDetails, Search, Session, SubjectType
async def movie_details_using_search_results_item():
client_session = Session()
search = Search(
client_session, query="avatar", subject_type=SubjectType.MOVIES
)
search_results = await search.get_content_model()
target_item = search_results.first_item # (1)
md = MovieDetails(
target_item,
session=client_session,
)
details = await md.get_content_model()
print(type(details)) # (2)
if __name__ == "__main__":
import asyncio
asyncio.run(movie_details_using_search_results_item())
- Shortcut for
search_results.items[0] - Output:
<class 'moviebox_api.v1.extractor.models.json.ItemJsonDetailsModel'>
movie_details_using_search_results_item_sync.py
# Extra imports for type hints since *_sync() methods lacks such
from moviebox_api.v1 import MovieDetails, Search, Session, SubjectType
from moviebox_api.v1.extractor.models.json import ItemJsonDetailsModel
from moviebox_api.v1.models import SearchResultsModel
def movie_details_using_search_results_item():
client_session = Session()
search = Search(
client_session, query="avatar", subject_type=SubjectType.MOVIES
)
search_results: SearchResultsModel = search.get_content_model_sync()
target_item = search_results.first_item # (1)
md = MovieDetails(
target_item,
session=client_session,
)
details: ItemJsonDetailsModel = md.get_content_model_sync()
print(type(details)) # (2)
if __name__ == "__main__":
movie_details_using_search_results_item()
- Shortcut for
search_results.items[0] - Output:
<class 'moviebox_api.v1.extractor.models.json.ItemJsonDetailsModel'>
2. Using Specific Item Page URL¶
from moviebox_api.v1 import MovieDetails, Session
async def movie_details_using_page_url():
page_url = "/detail/avatar-WLDIi21IUBa?id=8906247916759695608" # (1)
client_session = Session()
md = MovieDetails(
page_url,
session=client_session,
)
details = await md.get_content_model()
print(type(details)) # (2)
if __name__ == "__main__":
import asyncio
asyncio.run(movie_details_using_page_url())
- Obtained from
target_item.page_url <class 'moviebox_api.v1.extractor.models.json.ItemJsonDetailsModel'>
from moviebox_api.v1 import MovieDetails, Session
def movie_details_using_page_url():
page_url = "/detail/avatar-WLDIi21IUBa?id=8906247916759695608" # (1)
client_session = Session()
md = MovieDetails(
page_url,
session=client_session,
)
details = md.get_content_model_sync()
print(type(details)) # (2)
if __name__ == "__main__":
movie_details_using_page_url()
- Obtained from
target_item.page_url <class 'moviebox_api.v1.extractor.models.json.ItemJsonDetailsModel'>
Downloadable Files Detail¶
For better understanding, consider this as file metadata — where the files are the movie file and subtitle file.
These metadata include file URLs, file sizes, video quality, and subtitle language.
from moviebox_api.v1 import (
DownloadableMovieFilesDetail,
MovieDetails,
Search,
Session,
SubjectType,
)
async def downloadable_movie_file_details():
client_session = Session()
search = Search(client_session, "avatar", subject_type=SubjectType.MOVIES)
search_results = await search.get_content_model()
target_movie = search_results.first_item
target_movie_details_instance = MovieDetails(
target_movie, client_session
) # (1)
target_movie_details_model = (
await target_movie_details_instance.get_content_model()
)
downloadable_files = DownloadableMovieFilesDetail(
client_session, target_movie_details_model
)
downloadable_files_detail = await downloadable_files.get_content_model()
print(type(downloadable_files_detail)) # (2)
subtitles = downloadable_files_detail.captions
videos = downloadable_files_detail.downloads
if __name__ == "__main__":
import asyncio
asyncio.run(downloadable_movie_file_details())
-
Alternative
target_movie_details_instance = search.get_item_details(target_movie) - Output :
<class 'moviebox_api.v1.models.DownloadableFilesMetadata'>
from moviebox_api.v1 import (
DownloadableMovieFilesDetail,
MovieDetails,
Search,
Session,
SubjectType,
)
def downloadable_movie_file_details():
client_session = Session()
search = Search(client_session, "avatar", subject_type=SubjectType.MOVIES)
search_results = search.get_content_model_sync()
target_movie = search_results.first_item
target_movie_details_instance = MovieDetails(
target_movie, client_session
) # (1)
target_movie_details_model = (
target_movie_details_instance.get_content_model_sync()
)
downloadable_files = DownloadableMovieFilesDetail(
client_session, target_movie_details_model
)
downloadable_files_detail = downloadable_files.get_content_model_sync()
print(type(downloadable_files_detail)) # (2)
subtitles = downloadable_files_detail.captions
videos = downloadable_files_detail.downloads
if __name__ == "__main__":
downloadable_movie_file_details()
Downloading Movie File¶
from moviebox_api.v1 import (
DownloadableMovieFilesDetail,
MovieDetails,
Search,
Session,
SubjectType,
)
from moviebox_api.v1.download import MediaFileDownloader
async def download_movie_file():
client_session = Session()
search = Search(client_session, "avatar", subject_type=SubjectType.MOVIES)
search_results = await search.get_content_model()
target_movie = search_results.first_item
target_movie_details_instance = MovieDetails(target_movie, client_session)
target_movie_details_model = (
await target_movie_details_instance.get_content_model()
)
downloadable_files = DownloadableMovieFilesDetail(
client_session, target_movie_details_model
)
downloadable_files_detail = await downloadable_files.get_content_model()
target_media_file = downloadable_files_detail.best_media_file
media_file_downloader = MediaFileDownloader()
downloaded_file = await media_file_downloader.run(
target_media_file,
filename=target_movie,
)
print(downloaded_file.saved_to)
if __name__ == "__main__":
import asyncio
asyncio.run(download_movie_file())
from moviebox_api.v1 import (
DownloadableMovieFilesDetail,
MovieDetails,
Search,
Session,
SubjectType,
)
from moviebox_api.v1.download import MediaFileDownloader
def download_movie_file():
client_session = Session()
search = Search(client_session, "avatar", subject_type=SubjectType.MOVIES)
search_results = search.get_content_model_sync()
target_movie = search_results.first_item
target_movie_details_instance = MovieDetails(target_movie, client_session)
target_movie_details_model = (
target_movie_details_instance.get_content_model_sync()
)
downloadable_files = DownloadableMovieFilesDetail(
client_session, target_movie_details_model
)
downloadable_files_detail = downloadable_files.get_content_model_sync()
target_media_file = downloadable_files_detail.best_media_file
media_file_downloader = MediaFileDownloader()
downloaded_file = media_file_downloader.run_sync(
target_media_file,
filename=target_movie,
)
print(downloaded_file.saved_to)
if __name__ == "__main__":
download_movie_file()
Download Subtitle File¶
from moviebox_api.v1 import (
DownloadableMovieFilesDetail,
MovieDetails,
Search,
Session,
SubjectType,
)
from moviebox_api.v1.download import CaptionFileDownloader
async def download_subtitle_file():
session = Session()
search = Search(session, "avatar", subject_type=SubjectType.MOVIES)
search_results = await search.get_content_model()
target_movie = search_results.first_item
target_movie_details_instance = MovieDetails(target_movie, session)
target_movie_details_model = (
await target_movie_details_instance.get_content_model()
)
downloadable_files = DownloadableMovieFilesDetail(
session, target_movie_details_model
)
downloadable_files_detail = await downloadable_files.get_content_model()
target_caption_file = downloadable_files_detail.english_subtitle_file
caption_file_downloader = CaptionFileDownloader()
downloaded_file = await caption_file_downloader.run(
target_caption_file, filename=target_movie
)
print(downloaded_file.saved_to)
if __name__ == "__main__":
import asyncio
asyncio.run(download_subtitle_file())
from moviebox_api.v1 import (
DownloadableMovieFilesDetail,
MovieDetails,
Search,
Session,
SubjectType,
)
from moviebox_api.v1.download import CaptionFileDownloader
def download_subtitle_file():
session = Session()
search = Search(session, "avatar", subject_type=SubjectType.MOVIES)
search_results = search.get_content_model_sync()
target_movie = search_results.first_item
target_movie_details_instance = MovieDetails(target_movie, session)
target_movie_details_model = (
target_movie_details_instance.get_content_model_sync()
)
downloadable_files = DownloadableMovieFilesDetail(
session, target_movie_details_model
)
downloadable_files_detail = downloadable_files.get_content_model_sync()
target_caption_file = downloadable_files_detail.english_subtitle_file
caption_file_downloader = CaptionFileDownloader()
downloaded_file = caption_file_downloader.run_sync(
target_caption_file, filename=target_movie
)
print(downloaded_file.saved_to)
if __name__ == "__main__":
download_subtitle_file()