'type': 'array', 'items': { 'type': 'string' } }, 'phase_handlers': { 'type': 'array', 'items': phase_object } } } plugin_list_reply = {'type': 'array', 'items': plugin_object} plugin_schema = api.schema('plugin_object', ObjectsContainer.plugin_object) plugin_list_reply_schema = api.schema('plugin_list_reply', ObjectsContainer.plugin_list_reply) plugin_parser = api.parser() plugin_parser.add_argument( 'include_schema', type=inputs.boolean, default=False, help='Include plugin schema. This will increase response size') plugins_parser = api.pagination_parser(plugin_parser) plugins_parser.add_argument('interface', case_sensitive=False, help='Show plugins which implement this interface')
'type': 'object', 'properties': { 'code': { 'type': 'integer' }, 'error': { 'type': 'array', 'items': config_error }, 'message': { 'type': 'string' }, } } yaml_error_schema = api.schema('yaml_error_schema', yaml_error_response) config_validation_schema = api.schema('config_validation_schema', config_validation_error) @server_api.route('/reload/') class ServerReloadAPI(APIResource): @api.response(501, model=yaml_error_schema, description='YAML syntax error') @api.response(502, model=config_validation_schema, description='Config validation error') @api.response(200, description='Newly reloaded config') def get(self, session=None): """ Reload Flexget config """
def get(self, session=None): """ Reload Flexget config """ log.info('Reloading config from disk.') try: self.manager.load_config() except ValueError as e: raise ApiError('Error loading config: %s' % e.args[0]) log.info('Config successfully reloaded from disk.') return {} pid_schema = api.schema('server.pid', { 'type': 'object', 'properties': { 'pid': { 'type': 'integer' } } }) @server_api.route('/pid/') class ServerPIDAPI(APIResource): @api.response(200, description='Reloaded config', model=pid_schema) def get(self, session=None): """ Get server PID """ return {'pid': os.getpid()} shutdown_parser = api.parser() shutdown_parser.add_argument('force',
request.path.startswith('/logout') or request.path.startswith('/swagger'): return if not current_user.is_authenticated: return current_app.login_manager.unauthorized() # API Authentication and Authorization login_api = api.namespace('login', description='API Authentication') login_api_schema = api.schema( 'login', { 'type': 'object', 'properties': { 'username': { 'type': 'string' }, 'password': { 'type': 'string' } } }) login_parser = api.parser() login_parser.add_argument('remember', type=bool, required=False, default=False, help='Remember for next time') @login_api.route('/')
movie_queue_api = api.namespace('movie_queue', description='Movie Queue operations') default_error_schema = { 'type': 'object', 'properties': { 'status': { 'type': 'string' }, 'message': { 'type': 'string' } } } default_error_schema = api.schema('default_error_schema', default_error_schema) empty_response = api.schema('empty', {'type': 'object'}) movie_object = { 'type': 'object', 'properties': { 'added_date': { 'type': 'string' }, 'is_downloaded': { 'type': 'boolean' }, 'download_date': { 'type': 'string' },
'last_update': { 'type': 'string', 'format': 'date-time' } }, 'required': [ 'tvmaze_id', 'series_id', 'number', 'season_number', 'title', 'airdate', 'url', 'original_image', 'medium_image', 'airstamp', 'runtime', 'summary', 'last_update' ], 'additionalProperties': False } tvmaze_series_schema = api.schema('tvmaze_series_schema', ObjectsContainer.tvmaze_series_object) tvmaze_episode_schema = api.schema('tvmaze_episode_schema', ObjectsContainer.tvmaze_episode_object) @tvmaze_api.route('/series/<string:title>/') @api.doc(params={'title': 'TV Show name or TVMaze ID'}) class TVDBSeriesSearchApi(APIResource): @etag @api.response(200, 'Successfully found show', model=tvmaze_series_schema) @api.response(NotFoundError) def get(self, title, session=None): """TVMaze series lookup""" try: tvmaze_id = int(title) except ValueError:
raise ValueError('Value expected to be in' + ' ,'.join(enum)) return value def movie_queue_sort_order_enum(value): enum = ['desc', 'asc'] if isinstance(value, bool): return value if value not in enum: raise ValueError('Value expected to be in' + ' ,'.join(enum)) if value == 'desc': return True return False movie_queue_schema = api.schema('list_movie_queue', movie_queue_schema) movie_queue_parser = api.parser() movie_queue_parser.add_argument('page', type=int, default=1, help='Page number') movie_queue_parser.add_argument('max', type=int, default=100, help='Movies per page') movie_queue_parser.add_argument('status', type=movie_queue_status_value_enum, default=False, help='Filter list by status. Filter by {0}. Default is "pending"'.format( ' ,'.join(movie_queue_status_value_enum_list))) movie_queue_parser.add_argument('sort_by', type=movie_queue_sort_value_enum, default='added', help="Sort response by 'added', 'downloaded', 'id', 'title'") movie_queue_parser.add_argument('order', type=movie_queue_sort_order_enum, default='desc', help="Sorting order, can be 'asc' or 'desc'") movie_add_results_schema = { 'type': 'object', 'properties': {
from flask import jsonify from flexget.db_schema import reset_schema, plugin_schemas from flexget.api import api, APIResource from flexget.api.app import base_message_schema, success_response, BadRequest, etag log = logging.getLogger('database') db_api = api.namespace('database', description='Manage Flexget DB') class ObjectsContainer(object): plugin_list = {'type': 'array', 'items': {'type': 'string'}} plugins_schema = api.schema('plugins_list', ObjectsContainer.plugin_list) @db_api.route('/cleanup/') class DBCleanup(APIResource): @etag @api.response(200, model=base_message_schema) def get(self, session=None): """ Make all plugins clean un-needed data from the database """ self.manager.db_cleanup(force=True) return success_response('DB Cleanup triggered') @db_api.route('/vacuum/') class DBVacuum(APIResource): @etag
'error': {'type': 'string'}, 'config_path': {'type': 'string'} } } config_validation_error = { 'type': 'object', 'properties': { 'code': {'type': 'integer'}, 'error': {'type': 'array', 'items': config_error}, 'message': {'type': 'string'}, } } yaml_error_schema = api.schema('yaml_error_schema', yaml_error_response) config_validation_schema = api.schema('config_validation_schema', config_validation_error) @server_api.route('/reload/') class ServerReloadAPI(APIResource): @api.response(501, model=yaml_error_schema, description='YAML syntax error') @api.response(502, model=config_validation_schema, description='Config validation error') @api.response(200, description='Newly reloaded config') def get(self, session=None): """ Reload Flexget config """ log.info('Reloading config from disk.') try: self.manager.load_config(output_to_console=False) except YAMLError as e: if hasattr(e, 'problem') and hasattr(e, 'context_mark') and hasattr(e, 'problem_mark'):
'type': 'string' } } } connection = { 'type': 'object', 'patternProperties': { '\w': connection_object } } return_response = {'type': 'array', 'items': connection} return_schema = api.schema('irc.connections', ObjectsContainer.return_response) @irc_api.route('/connections/') @api.doc(parser=irc_parser) class IRCStatus(APIResource): @api.response(200, model=return_schema) @api.response(NotFoundError) @api.response(BadRequest) def get(self, session=None): """Returns status of IRC connections""" from flexget.plugins.daemon.irc import irc_manager if irc_manager is None: raise BadRequest('IRC daemon does not appear to be running') args = irc_parser.parse_args()
from builtins import * from flask import jsonify, request from jsonschema import RefResolutionError from flexget.api import api, APIResource from flexget.config_schema import schema_paths, resolve_ref schema_api = api.namespace('schema', description='Config and plugin schemas') _plugins_cache = None schema_api_list = api.schema('schema.list', { 'type': 'object', 'properties': { 'schemas': { 'type': 'array', 'items': {'type': 'object'} } } }) @schema_api.route('/') class SchemaAllAPI(APIResource): @api.response(200, model=schema_api_list) def get(self, session=None): """ List all schema definitions """ schemas = {} for path in schema_paths: schemas[path] = resolve_ref(path)
PLUGIN_TASK_NAME = 'seen_plugin_API' # Name of task to use when adding entries via API default_error_schema = { 'type': 'object', 'properties': { 'status': { 'type': 'string' }, 'message': { 'type': 'string' } } } empty_response = api.schema('empty', {'type': 'object'}) default_error_schema = api.schema('default_error_schema', default_error_schema) seen_field_object = { 'type': 'object', 'properties': { 'id': { 'type': 'integer' }, 'field': { 'type': 'string' }, 'value': { 'type': 'string' },
'type': 'integer' } } } search_results_object = { 'type': 'object', 'properties': { 'search_results': { 'type': 'array', 'items': search_result_object } } } default_error_schema = api.schema('default_error_schema', objects_container.default_error_schema) tvdb_series_schema = api.schema('tvdb_series_schema', objects_container.tvdb_series_object) tvdb_episode_schema = api.schema('tvdb_episode_schema', objects_container.episode_object) search_results_schema = api.schema('tvdb_search_results_schema', objects_container.search_results_object) series_parser = api.parser() series_parser.add_argument('include_actors', type=inputs.boolean, help='Include actors in response') @tvdb_api.route('/series/<string:title>/') @api.doc(params={'title': 'TV Show name or TVDB ID'}, parser=series_parser)
'format': 'file' }, 'path': { 'type': 'string', 'format': 'path' }, 'url': { 'type': 'string', 'format': 'url' }, 'episode_identifier': { 'type': 'string', 'format': 'episode_identifier' } } } format_checker_schema = api.schema('format_checker', ObjectContainer.format_checker_input) @schema_api.route('/', doc=False) class SchemaTest(APIResource): @api.validate(format_checker_schema) @api.response(200, model=base_message_schema) def post(self, session=None): """ Validate flexget custom schema""" # If validation passed, all is well return success_response('payload is valid')
@event("manager.shutdown") def stop_scheduler(manager): if scheduler and scheduler.running: scheduler.shutdown(wait=False) @event("config.register") def register_config(): register_config_key("schedules", main_schema) register_schema("/schema/config/schedule", schedule_schema) schedule_api = api.namespace("schedules", description="Task Scheduler") api_schedule_schema = api.schema("schedule", schedule_schema) api_schedules_list_schema = api.schema("schedule", main_schema) def _schedule_by_id(schedule_id): for schedule in manager.config.get("schedules", []): if id(schedule) == schedule_id: schedule = schedule.copy() schedule["id"] = schedule_id return schedule @schedule_api.route("/") class SchedulesAPI(APIResource): @api.response(200, "List of schedules", api_schedules_list_schema) def get(self, session=None):
'network': {'type': 'string'}, 'series_name': {'type': 'string'}, 'status': {'type': 'string'}, 'overview': {'type': 'string'}, 'tvdb_id': {'type': 'integer'} } } search_results_object = { 'type': 'object', 'properties': { 'search_results': {'type': 'array', 'items': search_result_object} } } default_error_schema = api.schema('default_error_schema', objects_container.default_error_schema) tvdb_series_schema = api.schema('tvdb_series_schema', objects_container.tvdb_series_object) tvdb_episode_schema = api.schema('tvdb_episode_schema', objects_container.episode_object) search_results_schema = api.schema('tvdb_search_results_schema', objects_container.search_results_object) series_parser = api.parser() series_parser.add_argument('include_actors', type=inputs.boolean, help='Include actors in response') @tvdb_api.route('/series/<string:title>/') @api.doc(params={'title': 'TV Show name or TVDB ID'}, parser=series_parser) class TVDBSeriesSearchApi(APIResource): @api.response(200, 'Successfully found show', tvdb_series_schema) @api.response(404, 'No show found', default_error_schema) def get(self, title, session=None):
from flexget.api import api, APIResource from flexget.api.app import NotFoundError, APIError, base_message_schema, success_response, etag, Conflict schedule_api = api.namespace('schedules', description='Task Scheduler') class ObjectsContainer(object): # SwaggerUI does not yet support anyOf or oneOf schedule_object = copy.deepcopy(schedule_schema) schedule_object['properties']['id'] = {'type': 'integer'} schedule_object['maxProperties'] += 1 schedules_list = {'type': 'array', 'items': schedule_object} base_schedule_schema = api.schema('schedules.base', schedule_schema) api_schedule_schema = api.schema('schedules.schedule', ObjectsContainer.schedule_object) api_schedules_list_schema = api.schema('schedules.list', ObjectsContainer.schedules_list) def _schedule_by_id(schedule_id, schedules): for idx, schedule in enumerate(schedules): if schedule and id(schedule) == schedule_id: schedule = schedule.copy() schedule['id'] = schedule_id return schedule, idx return None, None schedule_desc = "Schedule ID changes upon daemon restart. The schedules object supports either interval or schedule" \ " (cron) objects, see the model definition for details. Tasks also support string or list " \
'category': {'type': 'string'}, 'contexts': {'type': 'array', 'items': {'type': 'string'}}, 'debug': {'type': 'boolean'}, 'groups': {'type': 'array', 'items': {'type': 'string'}}, 'phase_handlers': {'type': 'array', 'items': phase_object} } } plugin_list_reply = { 'type': 'object', 'properties': { 'plugin_list': {'type': 'array', 'items': plugin_object}, 'number_of_plugins': {'type': 'integer'} } } plugin_schema = api.schema('plugin_object', plugin_object) plugin_list_reply_schema = api.schema('plugin_list_reply', plugin_list_reply) plugin_parser = api.parser() plugin_parser.add_argument('include_schema', type=inputs.boolean, default=False, help='Include plugin schema. This will increase response size') plugins_parser = plugin_parser.copy() plugins_parser.add_argument('group', help='Show plugins belonging to this group') plugins_parser.add_argument('phase', help='Show plugins that act on this phase') def plugin_to_dict(plugin): """ Returns a dict for API usage from a PluginInfo object :param plugin: PluginInfo instance
}, 'additionalProperties': False } tasks_api_schema = { "type": "object", "properties": { "tasks": { "type": "array", "items": task_api_schema } }, 'additionalProperties': False } tasks_api_schema = api.schema('tasks', tasks_api_schema) task_api_schema = api.schema('task', task_api_schema) @tasks_api.route('/') class TasksAPI(APIResource): @api.response(200, 'list of tasks', tasks_api_schema) def get(self, session=None): """ Show all tasks """ tasks = [] for name, config in self.manager.user_config.get('tasks', {}).iteritems(): tasks.append({'name': name, 'config': config}) return {'tasks': tasks}
def get(self, session=None): """ Reload Flexget config """ log.info('Reloading config from disk.') try: self.manager.load_config() except ValueError as e: raise ApiError('Error loading config: %s' % e.args[0]) log.info('Config successfully reloaded from disk.') return {} pid_schema = api.schema('server_pid', { 'type': 'object', 'properties': { 'pid': { 'type': 'integer' } } }) @server_api.route('/pid/') class ServerPIDAPI(APIResource): @api.response(200, 'Reloaded config', pid_schema) def get(self, session=None): """ Get server PID """ return{'pid': os.getpid()} shutdown_parser = api.parser() shutdown_parser.add_argument('force', type=bool, required=False, default=False, help='Ignore tasks in the queue')
from flask.ext.login import current_user from flexget.api import api, APIResource from flexget.webserver import change_password, generate_token, WeakPassword user_api = api.namespace('user', description='Manage user login credentials') user_password_input = { 'type': 'object', 'properties': { 'password': { 'type': 'string' } } } user_password_input_schema = api.schema('user_password_input', user_password_input) default_error_schema = { 'type': 'object', 'properties': { 'status': { 'type': 'string' }, 'message': { 'type': 'string' } } } default_error_schema = api.schema('default_error_schema', default_error_schema)
from flexget.options import get_parser from flexget.task import task_phases from flexget.utils import json from flexget.utils import requests from flexget.utils.lazy_dict import LazyLookup # Tasks API tasks_api = api.namespace('tasks', description='Manage Tasks') tasks_list_api_schema = api.schema( 'tasks.list', { "type": "object", "properties": { "tasks": { "type": "array", "items": { '$ref': '#/definitions/tasks.task' } } }, 'additionalProperties': False }) task_schema_validate = { 'type': 'object', 'properties': { 'name': { 'type': 'string' }, 'config': { '$ref': '/schema/plugins'
import flexget.plugins.list.entry_list as el from flexget.api import api, APIResource log = logging.getLogger('entry_list') entry_list_api = api.namespace('entry_list', description='Entry List operations') default_error_schema = { 'type': 'object', 'properties': { 'status': {'type': 'string'}, 'message': {'type': 'string'} } } empty_response = api.schema('empty', {'type': 'object'}) default_error_schema = api.schema('default_error_schema', default_error_schema) entry_list_base_object = { 'type': 'object', 'properties': { 'id': {'type': 'integer'}, 'name': {'type': 'string'}, 'added_on': {'type': 'string'} } } entry_list_input_object = copy.deepcopy(entry_list_base_object) del entry_list_input_object['properties']['id'] del entry_list_input_object['properties']['added_on'] entry_list_return_lists = {'type': 'array', 'items': entry_list_base_object}
'release_downloaded': {'type': 'string'}, 'release_quality': {'type': 'string'}, 'release_proper_count': {'type': 'integer'}, 'release_first_seen': {'type': 'string'}, 'release_episode_id': {'type': 'integer'} } } release_schema = { 'type': 'object', 'properties': { 'episode_id': {'type': 'integer'}, 'release': release_object } } release_schema = api.schema('release_schema', release_schema) release_list_schema = { 'type': 'object', 'properties': { 'releases': { 'type': 'array', 'items': release_object }, 'number_of_releases': {'type': 'integer'}, 'episode_id': {'type': 'integer'}, 'show_id': {'type': 'integer'} } } release_list_schema = api.schema('release_list_schema', release_list_schema)
movie_object = { 'type': 'object', 'properties': { 'imdb_id': {'type': 'string'}, 'match': {'type': 'number'}, 'name': {'type': 'string'}, 'url': {'type': 'string'}, 'year': {'type': 'string'}, 'thumbnail': {'type': 'string'} } } return_object = {'type': 'array', 'items': movie_object} return_schema = api.schema('imdb_search_schema', ObjectsContainer.return_object) @imdb_api.route('/search/<string:title>/') @api.doc(params={'title': 'Movie name or IMDB ID'}) class IMDBMovieSearch(APIResource): @api.response(200, model=return_schema) def get(self, title, session=None): """ Get a list of IMDB search result by name or ID""" raw_movies = ImdbSearch().smart_match(title, single_match=False) if not raw_movies: return [] # Convert single movie to list to preserve consistent reply if not isinstance(raw_movies, list): raw_movies = [raw_movies] return jsonify(raw_movies)
from flask import jsonify, Response from flexget.task import task_phases from flexget.utils import json from json import JSONEncoder from flexget.event import event from flexget.utils.lazy_dict import LazyLookup import flask_restplus # Tasks API tasks_api = api.namespace('tasks', description='Manage Tasks') tasks_list_api_schema = api.schema('tasks.list', { "type": "object", "properties": { "tasks": { "type": "array", "items": {'$ref': '#/definitions/tasks.task'} } }, 'additionalProperties': False }) task_schema_validate = { 'type': 'object', 'properties': { 'name': {'type': 'string'}, 'config': {'$ref': '/schema/plugins'} }, 'additionalProperties': False }
from flask import jsonify from flexget.api import api, APIResource from flexget.config_schema import schema_paths, resolve_ref schema_api = api.namespace('schema', description='Config and plugin schemas') _plugins_cache = None schema_api_list = api.schema( 'schema.list', { 'type': 'object', 'properties': { 'schemas': { 'type': 'array', 'items': { 'type': 'object' } } } }) @schema_api.route('/') class SchemaAllAPI(APIResource): @api.response(200, model=schema_api_list) def get(self, session=None): """ List all schema definitions """ schemas = {} for path in schema_paths: schemas[path] = resolve_ref(path) return jsonify({'schemas': schemas})
from flask_restplus import inputs from flexget.api import api, APIResource from flexget.plugins.api_tvdb import lookup_series, lookup_episode tvdb_api = api.namespace('tvdb', description='TheTVDB Shows') default_error_schema = { 'type': 'object', 'properties': { 'status': {'type': 'string'}, 'message': {'type': 'string'} } } default_error_schema = api.schema('default_error_schema', default_error_schema) tvdb_series_object = { 'type': 'object', 'properties': { 'tvdb_id': {'type': 'integer'}, 'last_updated': {'type': 'string', 'format': 'date-time'}, 'expired': {'type': 'boolean'}, 'name': {'type': 'string'}, 'rating': {'type': 'number'}, 'status': {'type': 'string'}, 'runtime': {'type': 'integer'}, 'airs_time': {'type': 'string'}, 'airs_dayofweek': {'type': 'string'}, 'content_rating': {'type': 'string'}, 'network': {'type': 'string'},
"type": "object", "properties": {"id": {"type": "integer"}, "added_on": {"type": "string"}, "name": {"type": "string"}}, } list_input = copy.deepcopy(list_object) del list_input["properties"]["id"] del list_input["properties"]["added_on"] return_movies = {"type": "array", "items": movie_list_object} return_lists = {"type": "array", "items": list_object} return_identifiers = {"type": "array", "items": {"type": "string"}} input_movie_entry_schema = api.schema("input_movie_entry", ObjectsContainer.input_movie_entry) input_movie_list_id_schema = api.schema("input_movie_list_id_object", ObjectsContainer.input_movie_list_id_object) movie_list_id_object_schema = api.schema("movie_list_id_object", ObjectsContainer.return_movie_list_id_object) movie_list_object_schema = api.schema("movie_list_object", ObjectsContainer.movie_list_object) list_object_schema = api.schema("list_object", ObjectsContainer.list_object) return_lists_schema = api.schema("return_lists", ObjectsContainer.return_lists) return_movies_schema = api.schema("return_movies", ObjectsContainer.return_movies) new_list_schema = api.schema("new_list", ObjectsContainer.list_input) identifiers_schema = api.schema("movie_list.identifiers", ObjectsContainer.return_identifiers) movie_list_parser = api.parser() movie_list_parser.add_argument("name", help="Filter results by list name")
from __future__ import unicode_literals, division, absolute_import from builtins import * # pylint: disable=unused-import, redefined-builtin import logging from flask import jsonify from sqlalchemy.orm.exc import NoResultFound from flexget.api import api, APIResource from flexget.plugins.filter.retry_failed import FailedEntry log = logging.getLogger('retry_failed_api') retry_failed_api = api.namespace('retry_failed', description='View and manage failed entries') empty_response = api.schema('empty', {'type': 'object'}) retry_failed_entry_object = { 'type': 'object', 'properties': { 'id': {'type': 'integer'}, 'title': {'type': 'string'}, 'url': {'type': 'string'}, 'added_at': {'type': 'string', 'format': 'date-time'}, 'reason': {'type': 'string'}, 'count': {'type': 'integer'}, 'retry_time': {'type': 'string', 'format': 'date-time'} } } retry_entries_list_object = { 'type': 'object',
from builtins import * # pylint: disable=unused-import, redefined-builtin import logging from flask import jsonify from sqlalchemy.orm.exc import NoResultFound from flexget.api import api, APIResource from flexget.plugins.filter.retry_failed import FailedEntry log = logging.getLogger('failed_api') retry_failed_api = api.namespace('failed', description='View and manage failed entries') empty_response = api.schema('empty', {'type': 'object'}) retry_failed_entry_object = { 'type': 'object', 'properties': { 'id': { 'type': 'integer' }, 'title': { 'type': 'string' }, 'url': { 'type': 'string' }, 'added_at': { 'type': 'string',
pending_entry_list = {'type': 'array', 'items': pending_entry_object} operation_object = { 'type': 'object', 'properties': { 'operation': { 'type': 'string', 'enum': ['approve', 'reject'] } }, 'required': ['operation'], 'additionalProperties': False } pending_entry_schema = api.schema('pending.entry', ObjectsContainer.pending_entry_object) pending_entry_list_schema = api.schema('pending.entry_list', ObjectsContainer.pending_entry_list) operation_schema = api.schema('pending.operation', ObjectsContainer.operation_object) filter_parser = api.parser() filter_parser.add_argument('task_name', help='Filter by task name') filter_parser.add_argument('approved', type=inputs.boolean, help='Filter by approval status') sort_choices = ('added', 'task_name', 'title', 'url', 'approved') pending_parser = api.pagination_parser(parser=filter_parser, sort_choices=sort_choices)
} } } list_input = copy.deepcopy(list_object) del list_input['properties']['id'] del list_input['properties']['added_on'] return_movies = {'type': 'array', 'items': movie_list_object} return_lists = {'type': 'array', 'items': list_object} return_identifiers = {'type': 'array', 'items': {'type': 'string'}} input_movie_entry_schema = api.schema('input_movie_entry', ObjectsContainer.input_movie_entry) input_movie_list_id_schema = api.schema( 'input_movie_list_id_object', ObjectsContainer.input_movie_list_id_object) movie_list_id_object_schema = api.schema( 'movie_list_id_object', ObjectsContainer.return_movie_list_id_object) movie_list_object_schema = api.schema('movie_list_object', ObjectsContainer.movie_list_object) list_object_schema = api.schema('list_object', ObjectsContainer.list_object) return_lists_schema = api.schema('return_lists', ObjectsContainer.return_lists) return_movies_schema = api.schema('return_movies', ObjectsContainer.return_movies) new_list_schema = api.schema('new_list', ObjectsContainer.list_input) identifiers_schema = api.schema('movie_list.identifiers', ObjectsContainer.return_identifiers)
def get(self, session=None): """ Reload Flexget config """ log.info('Reloading config from disk.') try: self.manager.load_config() except ValueError as e: raise ApiError('Error loading config: %s' % e.args[0]) log.info('Config successfully reloaded from disk.') return {} pid_schema = api.schema('server.pid', { 'type': 'object', 'properties': { 'pid': { 'type': 'integer' } } }) @server_api.route('/pid/') class ServerPIDAPI(APIResource): @api.response(200, description='Reloaded config', model=pid_schema) def get(self, session=None): """ Get server PID """ return {'pid': os.getpid()} shutdown_parser = api.parser() shutdown_parser.add_argument('force', type=inputs.boolean, required=False, default=False,
from flexget.api import api, APIResource, ApiClient from flexget.event import fire_event from flexget.plugin import PluginError from flexget.plugins.filter import series series_api = api.namespace('series', description='Flexget Series operations') default_error_schema = { 'type': 'object', 'properties': { 'status': {'type': 'string'}, 'message': {'type': 'string'} } } default_error_schema = api.schema('default_error_schema', default_error_schema) empty_response = api.schema('empty', {'type': 'object'}) begin_object = { 'type': 'object', 'properties': { 'episode_id': {'type': 'integer'}, 'episode_identifier': {'type': 'string'} } } release_object = { 'type': 'object', 'properties': { 'release_id': {'type': 'integer'},
'rejected_by': { 'type': 'string' } }, 'required': ['id', 'title', 'url', 'added', 'reason', 'expires', 'rejected_by'], 'additionalProperties': False } rejected_entries_list_object = { 'type': 'array', 'items': rejected_entry_object } rejected_entry_schema = api.schema('rejected_failed_entry_schema', ObjectsContainer.rejected_entry_object) rejected_entries_list_schema = api.schema( 'rejected_entries_list_schema', ObjectsContainer.rejected_entries_list_object) sort_choices = ('added', 'id', 'title', 'url', 'expires', 'rejected_by', 'reason') rejected_parser = api.pagination_parser(sort_choices=sort_choices) @rejected_api.route('/') class Rejected(APIResource): @etag @api.response(NotFoundError) @api.response(200, model=rejected_entries_list_schema) @api.doc(parser=rejected_parser)
series_api = api.namespace('series', description='Flexget Series operations') default_error_schema = { 'type': 'object', 'properties': { 'status': { 'type': 'string' }, 'message': { 'type': 'string' } } } default_error_schema = api.schema('default_error_schema', default_error_schema) empty_response = api.schema('empty', {'type': 'object'}) begin_object = { 'type': 'object', 'properties': { 'episode_id': { 'type': 'integer' }, 'episode_identifier': { 'type': 'string' } } }
from flask import request from flask_login import current_user from flexget.api import api, APIResource from flexget.webserver import change_password, generate_token, WeakPassword user_api = api.namespace('user', description='Manage user login credentials') user_password_input = { 'type': 'object', 'properties': { 'password': {'type': 'string'} } } user_password_input_schema = api.schema('user_password_input', user_password_input) default_error_schema = { 'type': 'object', 'properties': { 'status': {'type': 'string'}, 'message': {'type': 'string'} } } default_error_schema = api.schema('default_error_schema', default_error_schema) empty_response = api.schema('empty', {'type': 'object'}) @user_api.route('/')
from flexget.api import api, APIResource from flexget.plugins.filter import seen seen_api = api.namespace('seen', description='Managed Flexget seen entries and fields') PLUGIN_TASK_NAME = 'seen_plugin_API' # Name of task to use when adding entries via API default_error_schema = { 'type': 'object', 'properties': { 'status': {'type': 'string'}, 'message': {'type': 'string'} } } empty_response = api.schema('empty', {'type': 'object'}) default_error_schema = api.schema('default_error_schema', default_error_schema) seen_field_object = { 'type': 'object', 'properties': { 'id': {'type': 'integer'}, 'field': {'type': 'string'}, 'value': {'type': 'string'}, 'added': {'type': 'string', 'format': 'date-time'}, 'seen_entry_id': {'type': 'integer'} } } seen_object = {
from builtins import * # pylint: disable=unused-import, redefined-builtin import copy from flask import request, jsonify from flexget.manager import manager from flexget.plugins.daemon.scheduler import schedule_schema, scheduler, scheduler_job_map from flexget.api import api, APIResource schedule_api = api.namespace('schedules', description='Task Scheduler') # SwaggerUI does not yet support anyOf or oneOf schedule_schema = copy.deepcopy(schedule_schema) schedule_schema['properties']['id'] = {'type': 'integer'} api_schedule_schema = api.schema('schedules.schedule', schedule_schema) api_schedules_list_schema = api.schema('schedules.list', { 'type': 'object', 'properties': { 'schedules': { 'type': 'array', 'items': schedule_schema } } }) def _schedule_by_id(schedule_id): for schedule in manager.config.get('schedules', []): if id(schedule) == schedule_id: schedule = schedule.copy()
from __future__ import unicode_literals, division, absolute_import from builtins import * # pylint: disable=unused-import, redefined-builtin import logging from flask import request from flexget.api import api, APIResource, NotFoundError from flexget.plugins.modify.config_secrets import secrets_from_db, secrets_to_db log = logging.getLogger('secrets') secrets_api = api.namespace('secrets', description='View and edit secrets') empty_object = api.schema('empty_object', {'type': 'object'}) @secrets_api.route('/') class SecretsAPI(APIResource): @api.response(200) @api.response(NotFoundError) def get(self, session=None): return secrets_from_db() @api.response(201, 'Successfully updated secrets file') @api.response(NotFoundError) @api.validate(empty_object) @api.doc(description='Note that editing secrets may not be persistent, depending on user config') def put(self, session=None): data = request.json secrets_to_db(data)
'properties': { 'name': {'type': 'string'}, 'api_ver': {'type': 'integer'}, 'builtin': {'type': 'boolean'}, 'category': {'type': ['string', 'null']}, 'contexts': {'type': 'array', 'items': {'type': 'string'}}, 'debug': {'type': 'boolean'}, 'interfaces': {'type': 'array', 'items': {'type': 'string'}}, 'phase_handlers': {'type': 'array', 'items': phase_object} } } plugin_list_reply = {'type': 'array', 'items': plugin_object} plugin_schema = api.schema('plugin_object', ObjectsContainer.plugin_object) plugin_list_reply_schema = api.schema('plugin_list_reply', ObjectsContainer.plugin_list_reply) plugin_parser = api.parser() plugin_parser.add_argument('include_schema', type=inputs.boolean, default=False, help='Include plugin schema. This will increase response size') plugins_parser = api.pagination_parser(plugin_parser) plugins_parser.add_argument('interface', case_sensitive=False, help='Show plugins which implement this interface') plugins_parser.add_argument('phase', case_sensitive=False, help='Show plugins that act on this phase') def plugin_to_dict(plugin): return { 'name': plugin.name,
'type': 'object', 'properties': { 'id': {'type': 'integer'}, 'name': {'type': 'string'}, 'added_on': {'type': 'string'}, 'title': {'type': 'string'}, 'original_url': {'type': 'string'}, 'entry': base_entry_object, } } entry_lists_entries_return_object = {'type': 'array', 'items': entry_list_entry_base_object} entry_list_object_schema = api.schema('entry_list_object_schema', ObjectsContainer.entry_list_base_object) entry_list_input_object_schema = api.schema('entry_list_input_object_schema', ObjectsContainer.entry_list_input_object) entry_list_return_lists_schema = api.schema('entry_list_return_lists_schema', ObjectsContainer.entry_list_return_lists) entry_list_parser = api.parser() entry_list_parser.add_argument('name', help='Filter results by list name') @entry_list_api.route('/') class EntryListListsAPI(APIResource): @etag @api.doc(parser=entry_list_parser) @api.response(200, 'Successfully retrieved entry lists', entry_list_return_lists_schema) def get(self, session=None): """ Get entry lists """ args = entry_list_parser.parse_args()
@event('manager.shutdown') def stop_scheduler(manager): if scheduler and scheduler.running: scheduler.shutdown(wait=False) @event('config.register') def register_config(): register_config_key('schedules', main_schema) register_schema('/schema/config/schedule', schedule_schema) schedule_api = api.namespace('schedules', description='Task Scheduler') api_schedule_schema = api.schema('schedule', schedule_schema) api_schedules_list_schema = api.schema('schedule', main_schema) def _schedule_by_id(schedule_id): for schedule in manager.config.get('schedules', []): if id(schedule) == schedule_id: schedule = schedule.copy() schedule['id'] = schedule_id return schedule @schedule_api.route('/') class SchedulesAPI(APIResource): @api.response(200, 'List of schedules', api_schedules_list_schema) def get(self, session=None):
'properties': { 'password': {'type': 'string'} }, 'required': ['password'], 'additionalProperties': False } user_token_response = { 'type': 'object', 'properties': { 'token': {'type': 'string'} } } user_password_input_schema = api.schema('user_password_input', ObjectsContainer.user_password_input) user_token_response_schema = api.schema('user_token_response', ObjectsContainer.user_token_response) @user_api.route('/') @api.doc('Change user password') class UserManagementAPI(APIResource): @api.validate(model=user_password_input_schema, description='Password change schema') @api.response(BadRequest) @api.response(200, 'Success', model=base_message_schema) @api.doc(description='Change user password. A score of at least 3 is needed.' 'See https://github.com/dropbox/zxcvbn for details') def put(self, session=None): """ Change user password """ user = current_user data = request.json
'anyOf': [{ 'required': ['begin_episode'] }, { 'required': ['alternate_names'] }], 'additionalProperties:': False } series_input_object = copy.deepcopy(series_edit_object) series_input_object['properties']['name'] = {'type': 'string'} del series_input_object['anyOf'] series_input_object['required'] = ['name'] series_list_schema = api.schema('list_series', ObjectsContainer.series_list_schema) series_edit_schema = api.schema('series_edit_schema', ObjectsContainer.series_edit_object) series_input_schema = api.schema('series_input_schema', ObjectsContainer.series_input_object) show_details_schema = api.schema('show_details', ObjectsContainer.single_series_object) episode_list_schema = api.schema('episode_list', ObjectsContainer.episode_list_schema) episode_schema = api.schema('episode_item', ObjectsContainer.episode_object) release_schema = api.schema('release_schema', ObjectsContainer.release_object) release_list_schema = api.schema('release_list_schema', ObjectsContainer.release_list_schema)
from flask_restplus import inputs from flexget.api import api, APIResource from flexget.plugins.internal.api_tvmaze import APITVMaze as tvm tvmaze_api = api.namespace('tvmaze', description='TVMaze Shows') default_error_schema = { 'type': 'object', 'properties': { 'status': {'type': 'string'}, 'message': {'type': 'string'} } } default_error_schema = api.schema('default_error_schema', default_error_schema) actor_object = { 'type': 'object', 'properties': { "last_update": {'type': 'string', 'format': 'date-time'}, "medium_image": {'type': 'string'}, "name": {'type': 'string'}, "original_image": {'type': 'string'}, "tvmaze_id": {'type': 'integer'}, "url": {'type': 'string'}, } } schedule_object = { 'type': 'object',
'properties': { 'details': {'type': 'string'}, 'filename': {'type': 'string'}, 'id': {'type': 'integer'}, 'task': {'type': 'string'}, 'time': {'type': 'string'}, 'title': {'type': 'string'}, 'url': {'type': 'string'} } } }, 'pages': {'type': 'integer'} } } history_api_schema = api.schema('history.list', history_api_schema) default_error_schema = { 'type': 'object', 'properties': { 'status': {'type': 'string'}, 'message': {'type': 'string'} } } default_error_schema = api.schema('default_error_schema', default_error_schema) history_parser = api.parser() history_parser.add_argument('page', type=int, required=False, default=1, help='Page number') history_parser.add_argument('max', type=int, required=False, default=50, help='Results per page') history_parser.add_argument('task', type=str, required=False, default=None, help='Filter by task name')
'aliases': {'type': 'array', 'items': {'type': 'string'}}, 'first_aired': {'type': 'string', 'format': 'date-time'}, 'banner': {'type': ['string', 'null']}, 'network': {'type': 'string'}, 'series_name': {'type': 'string'}, 'status': {'type': 'string'}, 'overview': {'type': ['string', 'null']}, 'tvdb_id': {'type': 'integer'} }, 'required': ['aliases', 'first_aired', 'banner', 'network', 'series_name', 'status', 'overview', 'tvdb_id'], 'additionalProperties': False } search_results_object = {'type': 'array', 'items': search_result_object} tvdb_series_schema = api.schema('tvdb_series_schema', ObjectsContainer.tvdb_series_object) tvdb_episode_schema = api.schema('tvdb_episode_schema', ObjectsContainer.episode_object) search_results_schema = api.schema('tvdb_search_results_schema', ObjectsContainer.search_results_object) base_parser = api.parser() base_parser.add_argument('language', default='en', help='Language abbreviation string for different language support') series_parser = base_parser.copy() series_parser.add_argument('include_actors', type=inputs.boolean, help='Include actors in response') @tvdb_api.route('/series/<string:title>/') @api.doc(params={'title': 'TV Show name or TVDB ID'}, parser=series_parser) class TVDBSeriesLookupAPI(APIResource): @etag @api.response(200, 'Successfully found show', tvdb_series_schema)
from flexget.api import api, APIResource from flexget.plugins.list import movie_list as ml from flexget.utils.tools import split_title_year log = logging.getLogger('movie_list') movie_list_api = api.namespace('movie_list', description='Movie List operations') default_error_schema = { 'type': 'object', 'properties': { 'status': {'type': 'string'}, 'message': {'type': 'string'} } } empty_response = api.schema('empty', {'type': 'object'}) default_error_schema = api.schema('default_error_schema', default_error_schema) empty_response = api.schema('empty_response', empty_response) allowed_ids = ml.SUPPORTED_IDS input_movie_list_id_object = { 'type': 'array', 'items': { 'type': 'object', 'minProperties': 1, 'additionalProperties': True } }
def check_valid_login(): # Allow access to root, login and swagger documentation without authentication if request.path == '/' or request.path.startswith('/login') or \ request.path.startswith('/logout') or request.path.startswith('/swagger'): return if not current_user.is_authenticated: return current_app.login_manager.unauthorized() # API Authentication and Authorization login_api = api.namespace('login', description='API Authentication') login_api_schema = api.schema('login', { 'type': 'object', 'properties': { 'username': {'type': 'string'}, 'password': {'type': 'string'} } }) login_parser = api.parser() login_parser.add_argument('remember', type=bool, required=False, default=False, help='Remember for next time') @login_api.route('/') @api.doc(description='Login to API with username and password') class LoginAPI(APIResource): @api.expect(login_api_schema) @api.response(400, 'Invalid username or password') @api.response(200, 'Login successful')
from __future__ import unicode_literals, division, absolute_import from builtins import * # pylint: disable=unused-import, redefined-builtin import logging from flask import request from flexget.api import api, APIResource, NotFoundError from flexget.plugins.modify.config_secrets import secrets_from_db, secrets_to_db log = logging.getLogger('secrets') secrets_api = api.namespace('secrets', description='View and edit secrets') empty_object = api.schema('empty_object', {'type': 'object'}) @secrets_api.route('/') class SecretsAPI(APIResource): @api.response(200) @api.response(NotFoundError) def get(self, session=None): return secrets_from_db() @api.response(201, 'Successfully updated secrets file') @api.response(NotFoundError) @api.validate(empty_object) @api.doc( description= 'Note that editing secrets may not be persistent, depending on user config' ) def put(self, session=None):
entry_list_api = api.namespace('entry_list', description='Entry List operations') default_error_schema = { 'type': 'object', 'properties': { 'status': { 'type': 'string' }, 'message': { 'type': 'string' } } } empty_response = api.schema('empty', {'type': 'object'}) default_error_schema = api.schema('default_error_schema', default_error_schema) entry_list_base_object = { 'type': 'object', 'properties': { 'id': { 'type': 'integer' }, 'name': { 'type': 'string' }, 'added_on': { 'type': 'string' } }
'name': {'type': 'string'} } } list_input = copy.deepcopy(list_object) del list_input['properties']['id'] del list_input['properties']['added_on'] return_movies = {'type': 'array', 'items': movie_list_object} return_lists = {'type': 'array', 'items': list_object} return_identifiers = {'type': 'array', 'items': {'type': 'string'}} input_movie_entry_schema = api.schema('input_movie_entry', ObjectsContainer.input_movie_entry) input_movie_list_id_schema = api.schema('input_movie_list_id_object', ObjectsContainer.input_movie_list_id_object) movie_list_id_object_schema = api.schema('movie_list_id_object', ObjectsContainer.return_movie_list_id_object) movie_list_object_schema = api.schema('movie_list_object', ObjectsContainer.movie_list_object) list_object_schema = api.schema('list_object', ObjectsContainer.list_object) return_lists_schema = api.schema('return_lists', ObjectsContainer.return_lists) return_movies_schema = api.schema('return_movies', ObjectsContainer.return_movies) new_list_schema = api.schema('new_list', ObjectsContainer.list_input) identifiers_schema = api.schema('movie_list.identifiers', ObjectsContainer.return_identifiers) movie_list_parser = api.parser() movie_list_parser.add_argument('name', help='Filter results by list name')
movie_return_object = copy.deepcopy(base_return_object) movie_return_object['properties']['tagline'] = {'type': 'string'} movie_return_object['properties']['released'] = {'type': 'string'} movie_return_object['properties']['trailer'] = {'type': 'string'} default_error_object = { 'type': 'object', 'properties': { 'status': {'type': 'string'}, 'message': {'type': 'string'} } } default_error_schema = api.schema('default_error_schema', objects_container.default_error_object) series_return_schema = api.schema('series_return_schema', objects_container.series_return_object) movie_return_schema = api.schema('movie_return_schema', objects_container.movie_return_object) lookup_parser = api.parser() lookup_parser.add_argument('year', type=int, help='Lookup year') lookup_parser.add_argument('trakt_id', type=int, help='Trakt ID') lookup_parser.add_argument('trakt_slug', help='Trakt slug') lookup_parser.add_argument('tmdb_id', type=int, help='TMDB ID') lookup_parser.add_argument('imdb_id', help='IMDB ID') lookup_parser.add_argument('tvdb_id', type=int, help='TVDB ID') lookup_parser.add_argument('tvrage_id', type=int, help='TVRage ID') lookup_parser.add_argument('include_actors', type=inputs.boolean, help='Include actors in response') lookup_parser.add_argument('include_translations', type=inputs.boolean, help='Include translations in response')