Skip to content

Movies

Overview

Core movie operations include the following, in order:

  1. Searching for a particular movie
  2. Fetching more details about it
  3. Identifying URLs pointing to different files with respect to video quality and subtitle language
  4. Downloading the selected movie file and subtitle file

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())
  1. Output: <class 'dict'>. Access list of movies matching the query from search_results['items']
  2. This is simply whatever .get_content() returns, passed into a Pydantic model
  3. Output: <class 'moviebox_api.v1.models.SearchResultsModel'>. Access search result items from search_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()
  1. Output: <class 'dict'>. Access list of movies matching the query from search_results['items']
  2. This is simply whatever .get_content() returns, passed into a Pydantic model
  3. Output: <class 'moviebox_api.v1.models.SearchResultsModel'>. Access search result items from search_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.

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)
  1. Page 2 search instance
  2. Page 2 search results
  3. 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)
  1. Page 3 search results
  2. Page 2 search instance
  3. 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:

  1. Using a search results item
  2. 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())
  1. Shortcut for search_results.items[0]
  2. 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()
  1. Shortcut for search_results.items[0]
  2. 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())
  1. Obtained from target_item.page_url
  2. <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()
  1. Obtained from target_item.page_url
  2. <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())
  1. Alternative

    target_movie_details_instance = search.get_item_details(target_movie)
  2. 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()