Source code for flexget.api.core.schema

from __future__ import annotations

from typing import TYPE_CHECKING

from flask import jsonify, request
from referencing.exceptions import Unresolvable

from flexget.api import APIResource, api
from flexget.api.app import NotFoundError
from flexget.config_schema import resolve_ref, schema_paths

if TYPE_CHECKING:
    from flask import Response
    from sqlalchemy.orm import Session

schema_api = api.namespace('schema', description='Config and plugin schemas')

schema_api_list = api.schema_model(
    'schema.list',
    {'type': 'object', 'properties': {'schemas': {'type': 'array', 'items': {'type': 'object'}}}},
)


[docs] def rewrite_ref(identifier: str, base_url: str) -> str: """Rewrite all arbitrary refs in the schemas to be real urls servable by this endpoint. The refs in the schemas are arbitrary identifiers, and cannot be used as-is as real network locations. """ if not base_url.endswith('/'): base_url += '/' if identifier.startswith('/schema/'): return base_url + identifier[1:] return identifier
[docs] def rewrite_refs(schema, base_url: str): """Make sure any $refs in the schema point properly back to this endpoint.""" if isinstance(schema, dict): if '$ref' in schema: return {**schema, '$ref': rewrite_ref(schema['$ref'], base_url)} return {k: rewrite_refs(v, base_url) for k, v in schema.items()} if isinstance(schema, list): return [rewrite_refs(v, base_url) for v in schema] return schema
[docs] @schema_api.route('/') class SchemaAllAPI(APIResource):
[docs] @api.response(200, model=schema_api_list) def get(self, session: Session = None) -> Response: """List all schema definitions.""" schemas = [] for path in schema_paths: schema = rewrite_refs(resolve_ref(path), request.url_root) schema['id'] = rewrite_ref(path, request.url_root) schemas.append(schema) return jsonify({'schemas': schemas})
[docs] @schema_api.route('/<path:path>/') @api.doc(params={'path': 'Path of schema'}) @api.response(NotFoundError) class SchemaAPI(APIResource):
[docs] @api.response(200, model=schema_api_list) def get(self, path: str, session: Session = None) -> Response: """Get schema definition.""" try: schema = resolve_ref(request.full_path) except Unresolvable: raise NotFoundError('invalid schema path') schema['id'] = request.url return jsonify(rewrite_refs(schema, request.url_root))