def test_pyproject():
    with TemporaryDirectory() as output_dir:
        output_dir = Path(output_dir)
        with chdir(output_dir):
            output_file: Path = output_dir / 'output.py'
            pyproject_toml_path = Path(
                DATA_PATH) / "project" / "pyproject.toml"
            pyproject_toml = (pyproject_toml_path.read_text().replace(
                'INPUT_PATH', str(OPEN_API_DATA_PATH / 'api.yaml')).replace(
                    'OUTPUT_PATH', str(output_file)).replace(
                        'ALIASES_PATH',
                        str(OPEN_API_DATA_PATH /
                            'empty_aliases.json')).replace(
                                'EXTRA_TEMPLATE_DATA_PATH',
                                str(OPEN_API_DATA_PATH / 'empty_data.json'),
                            ).replace('CUSTOM_TEMPLATE_DIR_PATH',
                                      str(output_dir)))
            (output_dir / 'pyproject.toml').write_text(pyproject_toml)

            return_code: Exit = main([])
            assert return_code == Exit.OK
            assert (output_file.read_text() == (EXPECTED_MAIN_PATH /
                                                'pyproject' /
                                                'output.py').read_text())
    with pytest.raises(SystemExit):
        main()
Esempio n. 2
0
def generate_models(output, input_text) -> None:
    """based on datamodel_code_generator.generate"""
    py37 = datamodel_code_generator.format.PythonVersion.PY_37
    target_python_version = py37

    validation = True
    base_class = "pydantic.BaseModel"
    custom_template_dir = BASE / pathlib.Path("template/pydantic")
    extra_template_data = None

    parser_class = K8SParser

    parser = parser_class(
        BaseModel,
        CustomRootType,
        DataModelField,
        base_class=base_class,
        custom_template_dir=custom_template_dir,
        extra_template_data=extra_template_data,
        target_python_version=target_python_version,
        text=input_text,
        dump_resolve_reference_action=dump_resolve_reference_action,
        validation=validation,
    )

    with datamodel_code_generator.chdir(output):
        result = parser.parse()

    if isinstance(result, str):
        modules = {output: result}
    else:
        if output is None:
            raise Error("Modular references require an output directory")
        if output.suffix:
            raise Error(
                "Modular references require an output directory, not a file")
        modules = {
            output.joinpath(*name): body
            for name, body in sorted(result.items())
        }

    header = "# automatically generated file. DO NOT CHANGE MANUALLY"

    file: Optional[IO[Any]]
    for path, body in modules.items():
        if path is not None:
            if not path.parent.exists():
                path.parent.mkdir(parents=True)
            file = path.open("wt")
        else:
            file = None

        print(header, file=file)
        if body:
            print("", file=file)
            print(body.rstrip(), file=file)

        if file is not None:
            file.close()
def test_pyproject_not_found():
    with TemporaryDirectory() as output_dir:
        output_dir = Path(output_dir)
        with chdir(output_dir):
            output_file: Path = output_dir / 'output.py'
            return_code: Exit = main([
                '--input',
                str(OPEN_API_DATA_PATH / 'api.yaml'),
                '--output',
                str(output_file),
            ])
            assert return_code == Exit.OK
            assert (output_file.read_text() == (EXPECTED_MAIN_PATH /
                                                'pyproject_not_found' /
                                                'output.py').read_text())
Esempio n. 4
0
def generate_code(
    input_name: str,
    input_text: str,
    output_dir: Path,
    template_dir: Optional[Path],
    model_path: Optional[Path] = None,
    enum_field_as_literal: Optional[str] = None,
) -> None:
    if not model_path:
        model_path = MODEL_PATH
    if not output_dir.exists():
        output_dir.mkdir(parents=True)
    if not template_dir:
        template_dir = BUILTIN_TEMPLATE_DIR
    if enum_field_as_literal:
        parser = OpenAPIParser(input_text, enum_field_as_literal=enum_field_as_literal)
    else:
        parser = OpenAPIParser(input_text)
    with chdir(output_dir):
        models = parser.parse()
    if not models:
        return
    elif isinstance(models, str):
        output = output_dir / model_path
        modules = {output: (models, input_name)}
    else:
        raise Exception('Modular references are not supported in this version')

    environment: Environment = Environment(
        loader=FileSystemLoader(
            template_dir if template_dir else f"{Path(__file__).parent}/template",
            encoding="utf8",
        ),
    )
    imports = Imports()
    imports.update(parser.imports)
    for data_type in parser.data_types:
        reference = _get_most_of_reference(data_type)
        if reference:
            imports.append(data_type.all_imports)
            imports.append(
                Import.from_full_path(f'.{model_path.stem}.{reference.name}')
            )
    for from_, imports_ in parser.imports_for_fastapi.items():
        imports[from_].update(imports_)
    results: Dict[Path, str] = {}
    code_formatter = CodeFormatter(PythonVersion.PY_38, Path().resolve())
    sorted_operations: List[Operation] = sorted(
        parser.operations.values(), key=lambda m: m.path
    )
    for target in template_dir.rglob("*"):
        relative_path = target.relative_to(template_dir)
        result = environment.get_template(str(relative_path)).render(
            operations=sorted_operations, imports=imports, info=parser.parse_info(),
        )
        results[relative_path] = code_formatter.format_code(result)

    timestamp = datetime.now(timezone.utc).replace(microsecond=0).isoformat()
    header = f"""\
# generated by fastapi-codegen:
#   filename:  {Path(input_name).name}
#   timestamp: {timestamp}"""

    for path, code in results.items():
        with output_dir.joinpath(path.with_suffix(".py")).open("wt") as file:
            print(header, file=file)
            print("", file=file)
            print(code.rstrip(), file=file)

    header = f'''\
# generated by fastapi-codegen:
#   filename:  {{filename}}'''
    #     if not disable_timestamp:
    header += f'\n#   timestamp: {timestamp}'

    for path, body_and_filename in modules.items():
        body, filename = body_and_filename
        if path is None:
            file = None
        else:
            if not path.parent.exists():
                path.parent.mkdir(parents=True)
            file = path.open('wt', encoding='utf8')

        print(header.format(filename=filename), file=file)
        if body:
            print('', file=file)
            print(body.rstrip(), file=file)

        if file is not None:
            file.close()
Esempio n. 5
0
def generate_code(input_name: str, input_text: str, output_dir: Path,
                  template_dir: Optional[Path]) -> None:
    if not output_dir.exists():
        output_dir.mkdir(parents=True)
    if not template_dir:
        template_dir = BUILTIN_TEMPLATE_DIR

    model_parser = OpenAPIModelParser(source=input_text, )

    parser = OpenAPIParser(input_name,
                           input_text,
                           openapi_model_parser=model_parser)
    parsed_object: ParsedObject = parser.parse()

    environment: Environment = Environment(loader=FileSystemLoader(
        template_dir if template_dir else f"{Path(__file__).parent}/template",
        encoding="utf8",
    ), )
    results: Dict[Path, str] = {}
    code_formatter = CodeFormatter(PythonVersion.PY_38, Path().resolve())
    for target in template_dir.rglob("*"):
        relative_path = target.relative_to(template_dir)
        result = environment.get_template(str(relative_path)).render(
            operations=parsed_object.operations,
            imports=parsed_object.imports,
            info=parsed_object.info,
        )
        results[relative_path] = code_formatter.format_code(result)

    timestamp = datetime.now(timezone.utc).replace(microsecond=0).isoformat()
    header = f"""\
# generated by fastapi-codegen:
#   filename:  {Path(input_name).name}
#   timestamp: {timestamp}"""

    for path, code in results.items():
        with output_dir.joinpath(path.with_suffix(".py")).open("wt") as file:
            print(header, file=file)
            print("", file=file)
            print(code.rstrip(), file=file)

    with chdir(output_dir):
        results = model_parser.parse()
    if not results:
        return
    elif isinstance(results, str):
        output = output_dir / MODEL_PATH
        modules = {output: (results, input_name)}
    else:
        raise Exception('Modular references are not supported in this version')

    header = f'''\
# generated by fastapi-codegen:
#   filename:  {{filename}}'''
    #     if not disable_timestamp:
    header += f'\n#   timestamp: {timestamp}'

    for path, body_and_filename in modules.items():
        body, filename = body_and_filename
        if path is None:
            file = None
        else:
            if not path.parent.exists():
                path.parent.mkdir(parents=True)
            file = path.open('wt', encoding='utf8')

        print(header.format(filename=filename), file=file)
        if body:
            print('', file=file)
            print(body.rstrip(), file=file)

        if file is not None:
            file.close()