def extract_schemas_from_source(source, filename='<STR_LIT>'):
<EOL>acceptable_services = set()<EOL>acceptable_views = {}<EOL>schemas_found = []<EOL>ast_tree = ast.parse(source, filename)<EOL>simple_names = _get_simple_assignments(ast_tree)<EOL>assigns = [n for n in ast_tree.body if isinstance(n, ast.Assign)]<EOL>call_assigns = [n for n in assigns if isinstance(n.value, ast.Call)]<EOL>for assign in call_assigns:<EOL><INDENT>if isinstance(assign.value.func, ast.Attribute):<EOL><INDENT>continue<EOL><DEDENT>if assign.value.func.id == '<STR_LIT>':<EOL><INDENT>for target in assign.targets:<EOL><INDENT>acceptable_services.add(target.id)<EOL><DEDENT><DEDENT><DEDENT>for assign in call_assigns:<EOL><INDENT>if isinstance(assign.value.func, ast.Attribute) andassign.value.func.value.id in acceptable_services andassign.value.func.attr == '<STR_LIT>':<EOL><INDENT>url = None<EOL>name = None<EOL>methods = ['<STR_LIT:GET>']<EOL>args = assign.value.args<EOL>if len(args) >= <NUM_LIT:1>:<EOL><INDENT>url = ast.literal_eval(args[<NUM_LIT:0>])<EOL><DEDENT>if len(args) >= <NUM_LIT:2>:<EOL><INDENT>name = ast.literal_eval(args[<NUM_LIT:1>])<EOL><DEDENT>kwargs = assign.value.keywords<EOL>for kwarg in kwargs:<EOL><INDENT>if kwarg.arg == '<STR_LIT:url>':<EOL><INDENT>url = ast.literal_eval(kwarg.value)<EOL><DEDENT>if kwarg.arg == '<STR_LIT>':<EOL><INDENT>methods = ast.literal_eval(kwarg.value)<EOL><DEDENT>if kwarg.arg == '<STR_LIT>':<EOL><INDENT>name = ast.literal_eval(kwarg.value)<EOL><DEDENT><DEDENT>if url and name:<EOL><INDENT>for target in assign.targets:<EOL><INDENT>acceptable_views[target.id] = {<EOL>'<STR_LIT:url>': url,<EOL>'<STR_LIT:name>': name,<EOL>'<STR_LIT>': methods,<EOL>}<EOL><DEDENT><DEDENT><DEDENT><DEDENT>functions = [n for n in ast_tree.body if isinstance(n, ast.FunctionDef)]<EOL>for function in functions:<EOL><INDENT>input_schema = None<EOL>output_schema = None<EOL>doc = ast.get_docstring(function)<EOL>api_options_list = []<EOL>for decorator in function.decorator_list:<EOL><INDENT>if not isinstance(decorator, ast.Call):<EOL><INDENT>continue<EOL><DEDENT>if isinstance(decorator.func, ast.Attribute):<EOL><INDENT>decorator_name = decorator.func.value.id<EOL>version = None<EOL>for kwarg in decorator.keywords:<EOL><INDENT>if kwarg.arg == '<STR_LIT>':<EOL><INDENT>version = ast.literal_eval(kwarg.value)<EOL>break<EOL><DEDENT><DEDENT>if len(decorator.args) == <NUM_LIT:1>:<EOL><INDENT>version = ast.literal_eval(decorator.args[<NUM_LIT:0>])<EOL><DEDENT>if decorator_name in acceptable_views:<EOL><INDENT>api_options = acceptable_views[decorator_name]<EOL>api_options['<STR_LIT:version>'] = version<EOL>api_options_list.append(api_options)<EOL><DEDENT><DEDENT>else:<EOL><INDENT>decorator_name = decorator.func.id<EOL>if decorator_name == '<STR_LIT>':<EOL><INDENT>_SimpleNamesResolver(simple_names).visit(decorator.args[<NUM_LIT:0>])<EOL>input_schema = ast.literal_eval(decorator.args[<NUM_LIT:0>])<EOL><DEDENT>if decorator_name == '<STR_LIT>':<EOL><INDENT>_SimpleNamesResolver(simple_names).visit(decorator.args[<NUM_LIT:0>])<EOL>output_schema = ast.literal_eval(decorator.args[<NUM_LIT:0>])<EOL><DEDENT><DEDENT><DEDENT>for api_options in api_options_list:<EOL><INDENT>schema = ViewSchema(<EOL>view_name=api_options['<STR_LIT:name>'],<EOL>version=api_options['<STR_LIT:version>'],<EOL>input_schema=input_schema,<EOL>output_schema=output_schema,<EOL>methods=api_options['<STR_LIT>'],<EOL>url=api_options['<STR_LIT:url>'],<EOL>doc=doc,<EOL>)<EOL>schemas_found.append(schema)<EOL><DEDENT><DEDENT>return schemas_found<EOL>
Extract schemas from 'source'.

    The 'source' parameter must be a string, and should be valid python
    source.

    If 'source' is not valid python source, a SyntaxError will be raised.

    :returns: a list of ViewSchema objects.