diff --git a/app/runtime/extensions/module/contracts.py b/app/runtime/extensions/module/contracts.py index d97f7b556..b10e7ad73 100644 --- a/app/runtime/extensions/module/contracts.py +++ b/app/runtime/extensions/module/contracts.py @@ -161,6 +161,21 @@ _METHOD_CONTRACTS = { "anilist_popular_this_season": ModuleMethodContract(family="anilist", input_contract="AniListPageRequest", result_contract="list[MediaInfo]", result_shape=ModuleResultShape.LIST, aggregation=ModuleResultAggregation.ORDERED_LIST_MERGE, required_parameters=("page", "count")), "anilist_recommendations": ModuleMethodContract(family="anilist", input_contract="AniListMediaPageRequest", result_contract="list[MediaInfo]", result_shape=ModuleResultShape.LIST, aggregation=ModuleResultAggregation.ORDERED_LIST_MERGE, required_parameters=("anilist_id", "page", "count")), "anilist_trending": ModuleMethodContract(family="anilist", input_contract="AniListPageRequest", result_contract="list[MediaInfo]", result_shape=ModuleResultShape.LIST, aggregation=ModuleResultAggregation.ORDERED_LIST_MERGE, required_parameters=("page", "count")), + "tmdb_collection": ModuleMethodContract(family="tmdb", input_contract="TmdbCollectionRequest", result_contract="list[MediaInfo]", result_shape=ModuleResultShape.LIST, aggregation=ModuleResultAggregation.ORDERED_LIST_MERGE, required_parameters=("collection_id",)), + "tmdb_discover": ModuleMethodContract(family="tmdb", input_contract="TmdbDiscoverRequest", result_contract="list[MediaInfo]", result_shape=ModuleResultShape.LIST, aggregation=ModuleResultAggregation.ORDERED_LIST_MERGE, required_parameters=("mtype", "sort_by", "with_genres", "with_original_language", "with_keywords", "with_watch_providers", "vote_average", "vote_count", "release_date", "page")), + "tmdb_episodes": ModuleMethodContract(family="tmdb", input_contract="TmdbEpisodesRequest", result_contract="list[TmdbEpisode]", result_shape=ModuleResultShape.LIST, aggregation=ModuleResultAggregation.ORDERED_LIST_MERGE, required_parameters=("tmdbid", "season", "episode_group")), + "tmdb_group_seasons": ModuleMethodContract(family="tmdb", input_contract="TmdbGroupRequest", result_contract="list[TmdbSeason]", result_shape=ModuleResultShape.LIST, aggregation=ModuleResultAggregation.ORDERED_LIST_MERGE, required_parameters=("group_id",)), + "tmdb_info": ModuleMethodContract(family="tmdb", input_contract="TmdbInfoRequest", result_contract="dict | None", result_shape=ModuleResultShape.MAPPING, aggregation=ModuleResultAggregation.FIRST_NON_EMPTY, required_parameters=("tmdbid", "mtype", "season")), + "tmdb_movie_credits": ModuleMethodContract(family="tmdb", input_contract="TmdbMediaPageRequest", result_contract="list[MediaPerson]", result_shape=ModuleResultShape.LIST, aggregation=ModuleResultAggregation.ORDERED_LIST_MERGE, required_parameters=("tmdbid", "page")), + "tmdb_movie_recommend": ModuleMethodContract(family="tmdb", input_contract="TmdbMediaRequest", result_contract="list[MediaInfo]", result_shape=ModuleResultShape.LIST, aggregation=ModuleResultAggregation.ORDERED_LIST_MERGE, required_parameters=("tmdbid",)), + "tmdb_movie_similar": ModuleMethodContract(family="tmdb", input_contract="TmdbMediaRequest", result_contract="list[MediaInfo]", result_shape=ModuleResultShape.LIST, aggregation=ModuleResultAggregation.ORDERED_LIST_MERGE, required_parameters=("tmdbid",)), + "tmdb_person_credits": ModuleMethodContract(family="tmdb", input_contract="TmdbPersonPageRequest", result_contract="list[MediaInfo]", result_shape=ModuleResultShape.LIST, aggregation=ModuleResultAggregation.ORDERED_LIST_MERGE, required_parameters=("person_id", "page")), + "tmdb_person_detail": ModuleMethodContract(family="tmdb", input_contract="TmdbPersonRequest", result_contract="MediaPerson | None", aggregation=ModuleResultAggregation.FIRST_NON_EMPTY, required_parameters=("person_id",)), + "tmdb_seasons": ModuleMethodContract(family="tmdb", input_contract="TmdbMediaRequest", result_contract="list[TmdbSeason]", result_shape=ModuleResultShape.LIST, aggregation=ModuleResultAggregation.ORDERED_LIST_MERGE, required_parameters=("tmdbid",)), + "tmdb_trending": ModuleMethodContract(family="tmdb", input_contract="TmdbTrendingRequest", result_contract="list[MediaInfo]", result_shape=ModuleResultShape.LIST, aggregation=ModuleResultAggregation.ORDERED_LIST_MERGE, required_parameters=("page",)), + "tmdb_tv_credits": ModuleMethodContract(family="tmdb", input_contract="TmdbMediaPageRequest", result_contract="list[MediaPerson]", result_shape=ModuleResultShape.LIST, aggregation=ModuleResultAggregation.ORDERED_LIST_MERGE, required_parameters=("tmdbid", "page")), + "tmdb_tv_recommend": ModuleMethodContract(family="tmdb", input_contract="TmdbMediaRequest", result_contract="list[MediaInfo]", result_shape=ModuleResultShape.LIST, aggregation=ModuleResultAggregation.ORDERED_LIST_MERGE, required_parameters=("tmdbid",)), + "tmdb_tv_similar": ModuleMethodContract(family="tmdb", input_contract="TmdbMediaRequest", result_contract="list[MediaInfo]", result_shape=ModuleResultShape.LIST, aggregation=ModuleResultAggregation.ORDERED_LIST_MERGE, required_parameters=("tmdbid",)), "send_message": ModuleMethodContract(family="messaging", input_contract="MessageSendRequest", result_contract="Message | None", aggregation=ModuleResultAggregation.FIRST_NON_EMPTY), "finalize_message": ModuleMethodContract(family="messaging", input_contract="MessageFinalizeRequest", result_contract="Message | None", aggregation=ModuleResultAggregation.FIRST_NON_EMPTY, required_parameters=("response",)), "register_commands": ModuleMethodContract(family="messaging", input_contract="CommandRegistrationRequest", result_contract="None", required_parameters=("commands",)), @@ -230,6 +245,21 @@ _METHOD_CONTRACTS.update({ "async_anilist_popular_this_season": _METHOD_CONTRACTS["anilist_popular_this_season"], "async_anilist_recommendations": _METHOD_CONTRACTS["anilist_recommendations"], "async_anilist_trending": _METHOD_CONTRACTS["anilist_trending"], + "async_tmdb_collection": _METHOD_CONTRACTS["tmdb_collection"], + "async_tmdb_discover": _METHOD_CONTRACTS["tmdb_discover"], + "async_tmdb_episodes": _METHOD_CONTRACTS["tmdb_episodes"], + "async_tmdb_group_seasons": _METHOD_CONTRACTS["tmdb_group_seasons"], + "async_tmdb_info": _METHOD_CONTRACTS["tmdb_info"], + "async_tmdb_movie_credits": _METHOD_CONTRACTS["tmdb_movie_credits"], + "async_tmdb_movie_recommend": _METHOD_CONTRACTS["tmdb_movie_recommend"], + "async_tmdb_movie_similar": _METHOD_CONTRACTS["tmdb_movie_similar"], + "async_tmdb_person_credits": _METHOD_CONTRACTS["tmdb_person_credits"], + "async_tmdb_person_detail": _METHOD_CONTRACTS["tmdb_person_detail"], + "async_tmdb_seasons": _METHOD_CONTRACTS["tmdb_seasons"], + "async_tmdb_trending": _METHOD_CONTRACTS["tmdb_trending"], + "async_tmdb_tv_credits": _METHOD_CONTRACTS["tmdb_tv_credits"], + "async_tmdb_tv_recommend": _METHOD_CONTRACTS["tmdb_tv_recommend"], + "async_tmdb_tv_similar": _METHOD_CONTRACTS["tmdb_tv_similar"], }) _PREFIX_CONTRACTS = ( diff --git a/tests/fixtures/architecture/runtime-contract-baseline.json b/tests/fixtures/architecture/runtime-contract-baseline.json index 4483fe053..eaea11ef8 100644 --- a/tests/fixtures/architecture/runtime-contract-baseline.json +++ b/tests/fixtures/architecture/runtime-contract-baseline.json @@ -3216,159 +3216,194 @@ "version": 1 }, "async_tmdb_collection": { - "aggregation": "legacy", + "aggregation": "ordered_list_merge", "error_policy": "isolate_provider", "execution": "sync_or_async", "family": "tmdb", - "input_contract": "TmdbKeywordArguments", + "input_contract": "TmdbCollectionRequest", "plugin_short_circuit": true, "public_to_plugins": true, - "required_parameters": [], - "result_contract": "TmdbProviderResult", - "result_shape": "any", + "required_parameters": [ + "collection_id" + ], + "result_contract": "list[MediaInfo]", + "result_shape": "list", "supports_async": true, "supports_sync": true, "timeout_policy": "caller_budget", "version": 1 }, "async_tmdb_discover": { - "aggregation": "legacy", + "aggregation": "ordered_list_merge", "error_policy": "isolate_provider", "execution": "sync_or_async", "family": "tmdb", - "input_contract": "TmdbKeywordArguments", + "input_contract": "TmdbDiscoverRequest", "plugin_short_circuit": true, "public_to_plugins": true, - "required_parameters": [], - "result_contract": "TmdbProviderResult", - "result_shape": "any", + "required_parameters": [ + "mtype", + "page", + "release_date", + "sort_by", + "vote_average", + "vote_count", + "with_genres", + "with_keywords", + "with_original_language", + "with_watch_providers" + ], + "result_contract": "list[MediaInfo]", + "result_shape": "list", "supports_async": true, "supports_sync": true, "timeout_policy": "caller_budget", "version": 1 }, "async_tmdb_episodes": { - "aggregation": "legacy", + "aggregation": "ordered_list_merge", "error_policy": "isolate_provider", "execution": "sync_or_async", "family": "tmdb", - "input_contract": "TmdbKeywordArguments", + "input_contract": "TmdbEpisodesRequest", "plugin_short_circuit": true, "public_to_plugins": true, - "required_parameters": [], - "result_contract": "TmdbProviderResult", - "result_shape": "any", + "required_parameters": [ + "episode_group", + "season", + "tmdbid" + ], + "result_contract": "list[TmdbEpisode]", + "result_shape": "list", "supports_async": true, "supports_sync": true, "timeout_policy": "caller_budget", "version": 1 }, "async_tmdb_group_seasons": { - "aggregation": "legacy", + "aggregation": "ordered_list_merge", "error_policy": "isolate_provider", "execution": "sync_or_async", "family": "tmdb", - "input_contract": "TmdbKeywordArguments", + "input_contract": "TmdbGroupRequest", "plugin_short_circuit": true, "public_to_plugins": true, - "required_parameters": [], - "result_contract": "TmdbProviderResult", - "result_shape": "any", + "required_parameters": [ + "group_id" + ], + "result_contract": "list[TmdbSeason]", + "result_shape": "list", "supports_async": true, "supports_sync": true, "timeout_policy": "caller_budget", "version": 1 }, "async_tmdb_info": { - "aggregation": "legacy", + "aggregation": "first_non_empty", "error_policy": "isolate_provider", "execution": "sync_or_async", "family": "tmdb", - "input_contract": "TmdbKeywordArguments", + "input_contract": "TmdbInfoRequest", "plugin_short_circuit": true, "public_to_plugins": true, - "required_parameters": [], - "result_contract": "TmdbProviderResult", - "result_shape": "any", + "required_parameters": [ + "mtype", + "season", + "tmdbid" + ], + "result_contract": "dict | None", + "result_shape": "mapping", "supports_async": true, "supports_sync": true, "timeout_policy": "caller_budget", "version": 1 }, "async_tmdb_movie_credits": { - "aggregation": "legacy", + "aggregation": "ordered_list_merge", "error_policy": "isolate_provider", "execution": "sync_or_async", "family": "tmdb", - "input_contract": "TmdbKeywordArguments", + "input_contract": "TmdbMediaPageRequest", "plugin_short_circuit": true, "public_to_plugins": true, - "required_parameters": [], - "result_contract": "TmdbProviderResult", - "result_shape": "any", + "required_parameters": [ + "page", + "tmdbid" + ], + "result_contract": "list[MediaPerson]", + "result_shape": "list", "supports_async": true, "supports_sync": true, "timeout_policy": "caller_budget", "version": 1 }, "async_tmdb_movie_recommend": { - "aggregation": "legacy", + "aggregation": "ordered_list_merge", "error_policy": "isolate_provider", "execution": "sync_or_async", "family": "tmdb", - "input_contract": "TmdbKeywordArguments", + "input_contract": "TmdbMediaRequest", "plugin_short_circuit": true, "public_to_plugins": true, - "required_parameters": [], - "result_contract": "TmdbProviderResult", - "result_shape": "any", + "required_parameters": [ + "tmdbid" + ], + "result_contract": "list[MediaInfo]", + "result_shape": "list", "supports_async": true, "supports_sync": true, "timeout_policy": "caller_budget", "version": 1 }, "async_tmdb_movie_similar": { - "aggregation": "legacy", + "aggregation": "ordered_list_merge", "error_policy": "isolate_provider", "execution": "sync_or_async", "family": "tmdb", - "input_contract": "TmdbKeywordArguments", + "input_contract": "TmdbMediaRequest", "plugin_short_circuit": true, "public_to_plugins": true, - "required_parameters": [], - "result_contract": "TmdbProviderResult", - "result_shape": "any", + "required_parameters": [ + "tmdbid" + ], + "result_contract": "list[MediaInfo]", + "result_shape": "list", "supports_async": true, "supports_sync": true, "timeout_policy": "caller_budget", "version": 1 }, "async_tmdb_person_credits": { - "aggregation": "legacy", + "aggregation": "ordered_list_merge", "error_policy": "isolate_provider", "execution": "sync_or_async", "family": "tmdb", - "input_contract": "TmdbKeywordArguments", + "input_contract": "TmdbPersonPageRequest", "plugin_short_circuit": true, "public_to_plugins": true, - "required_parameters": [], - "result_contract": "TmdbProviderResult", - "result_shape": "any", + "required_parameters": [ + "page", + "person_id" + ], + "result_contract": "list[MediaInfo]", + "result_shape": "list", "supports_async": true, "supports_sync": true, "timeout_policy": "caller_budget", "version": 1 }, "async_tmdb_person_detail": { - "aggregation": "legacy", + "aggregation": "first_non_empty", "error_policy": "isolate_provider", "execution": "sync_or_async", "family": "tmdb", - "input_contract": "TmdbKeywordArguments", + "input_contract": "TmdbPersonRequest", "plugin_short_circuit": true, "public_to_plugins": true, - "required_parameters": [], - "result_contract": "TmdbProviderResult", + "required_parameters": [ + "person_id" + ], + "result_contract": "MediaPerson | None", "result_shape": "any", "supports_async": true, "supports_sync": true, @@ -3376,80 +3411,91 @@ "version": 1 }, "async_tmdb_seasons": { - "aggregation": "legacy", + "aggregation": "ordered_list_merge", "error_policy": "isolate_provider", "execution": "sync_or_async", "family": "tmdb", - "input_contract": "TmdbKeywordArguments", + "input_contract": "TmdbMediaRequest", "plugin_short_circuit": true, "public_to_plugins": true, - "required_parameters": [], - "result_contract": "TmdbProviderResult", - "result_shape": "any", + "required_parameters": [ + "tmdbid" + ], + "result_contract": "list[TmdbSeason]", + "result_shape": "list", "supports_async": true, "supports_sync": true, "timeout_policy": "caller_budget", "version": 1 }, "async_tmdb_trending": { - "aggregation": "legacy", + "aggregation": "ordered_list_merge", "error_policy": "isolate_provider", "execution": "sync_or_async", "family": "tmdb", - "input_contract": "TmdbKeywordArguments", + "input_contract": "TmdbTrendingRequest", "plugin_short_circuit": true, "public_to_plugins": true, - "required_parameters": [], - "result_contract": "TmdbProviderResult", - "result_shape": "any", + "required_parameters": [ + "page" + ], + "result_contract": "list[MediaInfo]", + "result_shape": "list", "supports_async": true, "supports_sync": true, "timeout_policy": "caller_budget", "version": 1 }, "async_tmdb_tv_credits": { - "aggregation": "legacy", + "aggregation": "ordered_list_merge", "error_policy": "isolate_provider", "execution": "sync_or_async", "family": "tmdb", - "input_contract": "TmdbKeywordArguments", + "input_contract": "TmdbMediaPageRequest", "plugin_short_circuit": true, "public_to_plugins": true, - "required_parameters": [], - "result_contract": "TmdbProviderResult", - "result_shape": "any", + "required_parameters": [ + "page", + "tmdbid" + ], + "result_contract": "list[MediaPerson]", + "result_shape": "list", "supports_async": true, "supports_sync": true, "timeout_policy": "caller_budget", "version": 1 }, "async_tmdb_tv_recommend": { - "aggregation": "legacy", + "aggregation": "ordered_list_merge", "error_policy": "isolate_provider", "execution": "sync_or_async", "family": "tmdb", - "input_contract": "TmdbKeywordArguments", + "input_contract": "TmdbMediaRequest", "plugin_short_circuit": true, "public_to_plugins": true, - "required_parameters": [], - "result_contract": "TmdbProviderResult", - "result_shape": "any", + "required_parameters": [ + "tmdbid" + ], + "result_contract": "list[MediaInfo]", + "result_shape": "list", "supports_async": true, "supports_sync": true, "timeout_policy": "caller_budget", "version": 1 }, "async_tmdb_tv_similar": { - "aggregation": "legacy", + "aggregation": "ordered_list_merge", "error_policy": "isolate_provider", "execution": "sync_or_async", "family": "tmdb", - "input_contract": "TmdbKeywordArguments", + "input_contract": "TmdbMediaRequest", "plugin_short_circuit": true, "public_to_plugins": true, - "required_parameters": [], - "result_contract": "TmdbProviderResult", - "result_shape": "any", + "required_parameters": [ + "tmdbid" + ], + "result_contract": "list[MediaInfo]", + "result_shape": "list", "supports_async": true, "supports_sync": true, "timeout_policy": "caller_budget", @@ -5659,159 +5705,194 @@ "version": 1 }, "tmdb_collection": { - "aggregation": "legacy", + "aggregation": "ordered_list_merge", "error_policy": "isolate_provider", "execution": "sync_or_async", "family": "tmdb", - "input_contract": "TmdbKeywordArguments", + "input_contract": "TmdbCollectionRequest", "plugin_short_circuit": true, "public_to_plugins": true, - "required_parameters": [], - "result_contract": "TmdbProviderResult", - "result_shape": "any", + "required_parameters": [ + "collection_id" + ], + "result_contract": "list[MediaInfo]", + "result_shape": "list", "supports_async": true, "supports_sync": true, "timeout_policy": "caller_budget", "version": 1 }, "tmdb_discover": { - "aggregation": "legacy", + "aggregation": "ordered_list_merge", "error_policy": "isolate_provider", "execution": "sync_or_async", "family": "tmdb", - "input_contract": "TmdbKeywordArguments", + "input_contract": "TmdbDiscoverRequest", "plugin_short_circuit": true, "public_to_plugins": true, - "required_parameters": [], - "result_contract": "TmdbProviderResult", - "result_shape": "any", + "required_parameters": [ + "mtype", + "page", + "release_date", + "sort_by", + "vote_average", + "vote_count", + "with_genres", + "with_keywords", + "with_original_language", + "with_watch_providers" + ], + "result_contract": "list[MediaInfo]", + "result_shape": "list", "supports_async": true, "supports_sync": true, "timeout_policy": "caller_budget", "version": 1 }, "tmdb_episodes": { - "aggregation": "legacy", + "aggregation": "ordered_list_merge", "error_policy": "isolate_provider", "execution": "sync_or_async", "family": "tmdb", - "input_contract": "TmdbKeywordArguments", + "input_contract": "TmdbEpisodesRequest", "plugin_short_circuit": true, "public_to_plugins": true, - "required_parameters": [], - "result_contract": "TmdbProviderResult", - "result_shape": "any", + "required_parameters": [ + "episode_group", + "season", + "tmdbid" + ], + "result_contract": "list[TmdbEpisode]", + "result_shape": "list", "supports_async": true, "supports_sync": true, "timeout_policy": "caller_budget", "version": 1 }, "tmdb_group_seasons": { - "aggregation": "legacy", + "aggregation": "ordered_list_merge", "error_policy": "isolate_provider", "execution": "sync_or_async", "family": "tmdb", - "input_contract": "TmdbKeywordArguments", + "input_contract": "TmdbGroupRequest", "plugin_short_circuit": true, "public_to_plugins": true, - "required_parameters": [], - "result_contract": "TmdbProviderResult", - "result_shape": "any", + "required_parameters": [ + "group_id" + ], + "result_contract": "list[TmdbSeason]", + "result_shape": "list", "supports_async": true, "supports_sync": true, "timeout_policy": "caller_budget", "version": 1 }, "tmdb_info": { - "aggregation": "legacy", + "aggregation": "first_non_empty", "error_policy": "isolate_provider", "execution": "sync_or_async", "family": "tmdb", - "input_contract": "TmdbKeywordArguments", + "input_contract": "TmdbInfoRequest", "plugin_short_circuit": true, "public_to_plugins": true, - "required_parameters": [], - "result_contract": "TmdbProviderResult", - "result_shape": "any", + "required_parameters": [ + "mtype", + "season", + "tmdbid" + ], + "result_contract": "dict | None", + "result_shape": "mapping", "supports_async": true, "supports_sync": true, "timeout_policy": "caller_budget", "version": 1 }, "tmdb_movie_credits": { - "aggregation": "legacy", + "aggregation": "ordered_list_merge", "error_policy": "isolate_provider", "execution": "sync_or_async", "family": "tmdb", - "input_contract": "TmdbKeywordArguments", + "input_contract": "TmdbMediaPageRequest", "plugin_short_circuit": true, "public_to_plugins": true, - "required_parameters": [], - "result_contract": "TmdbProviderResult", - "result_shape": "any", + "required_parameters": [ + "page", + "tmdbid" + ], + "result_contract": "list[MediaPerson]", + "result_shape": "list", "supports_async": true, "supports_sync": true, "timeout_policy": "caller_budget", "version": 1 }, "tmdb_movie_recommend": { - "aggregation": "legacy", + "aggregation": "ordered_list_merge", "error_policy": "isolate_provider", "execution": "sync_or_async", "family": "tmdb", - "input_contract": "TmdbKeywordArguments", + "input_contract": "TmdbMediaRequest", "plugin_short_circuit": true, "public_to_plugins": true, - "required_parameters": [], - "result_contract": "TmdbProviderResult", - "result_shape": "any", + "required_parameters": [ + "tmdbid" + ], + "result_contract": "list[MediaInfo]", + "result_shape": "list", "supports_async": true, "supports_sync": true, "timeout_policy": "caller_budget", "version": 1 }, "tmdb_movie_similar": { - "aggregation": "legacy", + "aggregation": "ordered_list_merge", "error_policy": "isolate_provider", "execution": "sync_or_async", "family": "tmdb", - "input_contract": "TmdbKeywordArguments", + "input_contract": "TmdbMediaRequest", "plugin_short_circuit": true, "public_to_plugins": true, - "required_parameters": [], - "result_contract": "TmdbProviderResult", - "result_shape": "any", + "required_parameters": [ + "tmdbid" + ], + "result_contract": "list[MediaInfo]", + "result_shape": "list", "supports_async": true, "supports_sync": true, "timeout_policy": "caller_budget", "version": 1 }, "tmdb_person_credits": { - "aggregation": "legacy", + "aggregation": "ordered_list_merge", "error_policy": "isolate_provider", "execution": "sync_or_async", "family": "tmdb", - "input_contract": "TmdbKeywordArguments", + "input_contract": "TmdbPersonPageRequest", "plugin_short_circuit": true, "public_to_plugins": true, - "required_parameters": [], - "result_contract": "TmdbProviderResult", - "result_shape": "any", + "required_parameters": [ + "page", + "person_id" + ], + "result_contract": "list[MediaInfo]", + "result_shape": "list", "supports_async": true, "supports_sync": true, "timeout_policy": "caller_budget", "version": 1 }, "tmdb_person_detail": { - "aggregation": "legacy", + "aggregation": "first_non_empty", "error_policy": "isolate_provider", "execution": "sync_or_async", "family": "tmdb", - "input_contract": "TmdbKeywordArguments", + "input_contract": "TmdbPersonRequest", "plugin_short_circuit": true, "public_to_plugins": true, - "required_parameters": [], - "result_contract": "TmdbProviderResult", + "required_parameters": [ + "person_id" + ], + "result_contract": "MediaPerson | None", "result_shape": "any", "supports_async": true, "supports_sync": true, @@ -5819,80 +5900,91 @@ "version": 1 }, "tmdb_seasons": { - "aggregation": "legacy", + "aggregation": "ordered_list_merge", "error_policy": "isolate_provider", "execution": "sync_or_async", "family": "tmdb", - "input_contract": "TmdbKeywordArguments", + "input_contract": "TmdbMediaRequest", "plugin_short_circuit": true, "public_to_plugins": true, - "required_parameters": [], - "result_contract": "TmdbProviderResult", - "result_shape": "any", + "required_parameters": [ + "tmdbid" + ], + "result_contract": "list[TmdbSeason]", + "result_shape": "list", "supports_async": true, "supports_sync": true, "timeout_policy": "caller_budget", "version": 1 }, "tmdb_trending": { - "aggregation": "legacy", + "aggregation": "ordered_list_merge", "error_policy": "isolate_provider", "execution": "sync_or_async", "family": "tmdb", - "input_contract": "TmdbKeywordArguments", + "input_contract": "TmdbTrendingRequest", "plugin_short_circuit": true, "public_to_plugins": true, - "required_parameters": [], - "result_contract": "TmdbProviderResult", - "result_shape": "any", + "required_parameters": [ + "page" + ], + "result_contract": "list[MediaInfo]", + "result_shape": "list", "supports_async": true, "supports_sync": true, "timeout_policy": "caller_budget", "version": 1 }, "tmdb_tv_credits": { - "aggregation": "legacy", + "aggregation": "ordered_list_merge", "error_policy": "isolate_provider", "execution": "sync_or_async", "family": "tmdb", - "input_contract": "TmdbKeywordArguments", + "input_contract": "TmdbMediaPageRequest", "plugin_short_circuit": true, "public_to_plugins": true, - "required_parameters": [], - "result_contract": "TmdbProviderResult", - "result_shape": "any", + "required_parameters": [ + "page", + "tmdbid" + ], + "result_contract": "list[MediaPerson]", + "result_shape": "list", "supports_async": true, "supports_sync": true, "timeout_policy": "caller_budget", "version": 1 }, "tmdb_tv_recommend": { - "aggregation": "legacy", + "aggregation": "ordered_list_merge", "error_policy": "isolate_provider", "execution": "sync_or_async", "family": "tmdb", - "input_contract": "TmdbKeywordArguments", + "input_contract": "TmdbMediaRequest", "plugin_short_circuit": true, "public_to_plugins": true, - "required_parameters": [], - "result_contract": "TmdbProviderResult", - "result_shape": "any", + "required_parameters": [ + "tmdbid" + ], + "result_contract": "list[MediaInfo]", + "result_shape": "list", "supports_async": true, "supports_sync": true, "timeout_policy": "caller_budget", "version": 1 }, "tmdb_tv_similar": { - "aggregation": "legacy", + "aggregation": "ordered_list_merge", "error_policy": "isolate_provider", "execution": "sync_or_async", "family": "tmdb", - "input_contract": "TmdbKeywordArguments", + "input_contract": "TmdbMediaRequest", "plugin_short_circuit": true, "public_to_plugins": true, - "required_parameters": [], - "result_contract": "TmdbProviderResult", - "result_shape": "any", + "required_parameters": [ + "tmdbid" + ], + "result_contract": "list[MediaInfo]", + "result_shape": "list", "supports_async": true, "supports_sync": true, "timeout_policy": "caller_budget", diff --git a/tests/test_module_method_contracts.py b/tests/test_module_method_contracts.py index bd2000abd..2dd64e1cf 100644 --- a/tests/test_module_method_contracts.py +++ b/tests/test_module_method_contracts.py @@ -397,6 +397,37 @@ def test_sync_and_async_anilist_capabilities_share_contracts() -> None: assert contract.aggregation is expected +def test_sync_and_async_tmdb_capabilities_share_contracts() -> None: + """TMDB 同步与异步查询应共享列表或首值契约。""" + list_methods = { + "tmdb_collection", + "tmdb_discover", + "tmdb_episodes", + "tmdb_group_seasons", + "tmdb_movie_credits", + "tmdb_movie_recommend", + "tmdb_movie_similar", + "tmdb_person_credits", + "tmdb_seasons", + "tmdb_trending", + "tmdb_tv_credits", + "tmdb_tv_recommend", + "tmdb_tv_similar", + } + value_methods = {"tmdb_info", "tmdb_person_detail"} + + for sync_method in list_methods | value_methods: + contract = get_module_method_contract(sync_method) + assert contract is get_module_method_contract(f"async_{sync_method}") + expected = ( + ModuleResultAggregation.ORDERED_LIST_MERGE + if sync_method in list_methods + else ModuleResultAggregation.FIRST_NON_EMPTY + ) + assert contract.aggregation is expected + assert contract.required_parameters + + def test_attachment_result_diagnostics_distinguish_bytes_and_strings() -> None: """附件契约应区分二进制内容和可展示字符串,偏差仍仅供诊断。""" assert diagnose_module_result("download_qq_file_bytes", b"content") == ()