Provider Guide¶
This guide is going to explain how to add a Provider
to subliminal. You are encouraged
to take a look at the existing providers, it can be a nice base to start your own provider.
Requirements¶
When starting a provider you should be able to answer to the following questions:
- What languages does my provider support?
- What are the language codes for the supported languages?
- Does my provider deliver subtitles for episodes? for movies?
- Does my provider require a video hash?
Each response of these questions will help you set the correct attributes for your
Provider
.
Video Validation¶
Not all providers deliver subtitles for Episode
. Some may require a hash.
The check()
method does validation against a Video
object and will return False if the given Video
isn’t suitable. If you’re not happy
with the default implementation, you can override it.
Configuration¶
API keys must not be configurable by the user and must remain linked to subliminal. Hence they must be written in the provider module.
Per-user authentication is allowed and must be configured at instantiation as keyword arguments. Configuration
will be done by the user through the provider_configs argument of the list_subtitles()
and
download_best_subtitles()
functions. No network operation must be done during instantiation,
only configuration. Any error in the configuration must raise a
ConfigurationError
.
Beyond this point, if an error occurs, a generic ProviderError
exception
must be raised. You can also use more explicit exception classes AuthenticationError
and DownloadLimitExceeded
.
Initialization / Termination¶
Actual authentication operations must take place in the initialize()
method.
If you need anything to be executed when the provider isn’t used anymore like logout,
use terminate()
.
Caching policy¶
To save bandwidth and improve querying time, intermediate data should be cached when possible. Typical use case is
when a query to retrieve show ids is required prior to the query to actually search for subtitles. In that case
the function that gets the show id from the show name must be cached.
Expiration time should be SHOW_EXPIRATION_TIME
for shows and
EPISODE_EXPIRATION_TIME
for episodes.
Language¶
To be able to handle various language codes, subliminal makes use of babelfish
Language and converters. You must set the attribute languages
with a set of
supported Language
.
If you cannot find a suitable converter for your provider, you can make one of your own.
Querying¶
The query()
method parameters must include all aspects of provider’s querying with
primary types.
Subtitle¶
A custom Subtitle
subclass must be created to represent a subtitle from the provider.
It must have relevant attributes that can be used to compute the matches of the subtitle against a
Video
object.
Score computation¶
To be able to compare subtitles coming from different providers between them, the
get_matches()
method must be implemented.
If guessit is used to extract data from the
Subtitle
subclass, you can use guess_matches()
as a helper to compute matches between the Video
and the Guess
.
Refer to the scores attribute of Episode
and Movie
for a list of possible matches.
Unittesting¶
All possible uses of query()
,
list_subtitles()
and download_subtitle()
methods must have integration tests. Use vcrpy for recording and playback
of network activity.
Other functions must be unittested. If necessary, you can use unittest.mock
to mock some functions.