Skip to content

# cli

## `xsdata.cli`

### `cli(ctx, **kwargs)`

Xsdata command line interface.

Source code in `xsdata/cli.py`

    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63

    @click.group()
    @click.pass_context
    @click.version_option(__version__)
    def cli(ctx: click.Context, **kwargs: Any) -> None:
        """Xsdata command line interface."""
        logger.setLevel(logging.INFO)
        formatwarning_orig = warnings.formatwarning

        logger.info(
            "========= xsdata v%s / Python %s / Platform %s =========\n",
            __version__,
            platform.python_version(),
            sys.platform,
        )

        def format_warning(message: Any, category: Any, *args: Any) -> str:
            return (
                f"{category.__name__}: {message}" if category else message
            )  # pragma: no cover

        def format_warning_restore() -> None:
            warnings.formatwarning = formatwarning_orig

        warnings.formatwarning = format_warning  # type: ignore

        ctx.call_on_close(format_warning_restore)

### `init_config(**kwargs)`

Create or update a configuration file.

Source code in `xsdata/cli.py`

    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81

    @cli.command("init-config")
    @click.argument("output", type=click.Path(), default=".xsdata.xml")
    def init_config(**kwargs: Any) -> None:
        """Create or update a configuration file."""
        file_path = Path(kwargs["output"])
        if file_path.exists():
            config = GeneratorConfig.read(file_path)
            logger.info("Updating configuration file %s", kwargs["output"])
        else:
            logger.info("Initializing configuration file %s", kwargs["output"])
            config = GeneratorConfig.create()

        with file_path.open("w") as fp:
            config.write(fp, config)

        handler.emit_warnings()

### `download(source, output)`

Download a schema or a definition locally with all its dependencies.

Source code in `xsdata/cli.py`

    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98

    @cli.command("download")
    @click.argument("source", type=URL(), required=True)
    @click.option(
        "-o",
        "--output",
        type=click.Path(),
        default="./",
        help="Output directory, default cwd",
    )
    def download(source: str, output: str) -> None:
        """Download a schema or a definition locally with all its dependencies."""
        downloader = Downloader(output=Path(output).resolve())
        downloader.wget(source)

        handler.emit_warnings()

### `generate(**kwargs)`

Generate code from xsd, dtd, wsdl, xml and json files.

The input source can be either a filepath, uri or a directory containing xml, json, xsd and wsdl files.

Source code in `xsdata/cli.py`

    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149

    @cli.command("generate")
    @click.argument("source", required=True)
    @click.option(
        "-r",
        "--recursive",
        is_flag=True,
        default=False,
        help="Search files recursively in the source directory",
    )
    @click.option("-c", "--config", default=".xsdata.xml", help="Project configuration")
    @click.option("--cache", is_flag=True, default=False, help="Cache sources loading")
    @click.option("--debug", is_flag=True, default=False, help="Show debug messages")
    @click.option(
        "--extensions",
        default=",".join(_SUPPORTED_EXTENSIONS),
        help="Comma-separated list of extensions to filter",
    )
    @model_options(GeneratorOutput)
    def generate(**kwargs: Any) -> None:
        """Generate code from xsd, dtd, wsdl, xml and json files.

        The input source can be either a filepath, uri or a directory
        containing xml, json, xsd and wsdl files.
        """
        debug = kwargs.pop("debug")
        if debug:
            logger.setLevel(logging.DEBUG)

        source = kwargs.pop("source")
        cache = kwargs.pop("cache")
        recursive = kwargs.pop("recursive")
        config_file = Path(kwargs.pop("config")).resolve()

        # Parse the comma-separated extensions string into a tuple
        extensions_str = kwargs.pop("extensions")
        extensions = tuple(ext.strip() for ext in extensions_str.split(",") if ext.strip())

        params = {k.replace("__", "."): v for k, v in kwargs.items() if v is not None}
        config = GeneratorConfig.read(config_file)
        config.output.update(**params)

        transformer = ResourceTransformer(config=config)
        uris = sorted(resolve_source(source, recursive=recursive, extensions=extensions))
        transformer.process(uris, cache=cache)

        handler.emit_warnings()

### `resolve_source(source, recursive, extensions=_SUPPORTED_EXTENSIONS)`

Yields all supported resource URIs.

Source code in `xsdata/cli.py`

    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165

    def resolve_source(
        source: str, recursive: bool, extensions: tuple[str, ...] = _SUPPORTED_EXTENSIONS
    ) -> Iterator[str]:
        """Yields all supported resource URIs."""
        if source.find("://") > -1 and not source.startswith("file://"):
            yield source
        else:
            path = Path(source).resolve()
            match = "**/*" if recursive else "*"
            if path.is_dir():
                for ext in extensions:
                    yield from (x.as_uri() for x in path.glob(f"{match}.{ext}"))
            else:  # is a file
                yield path.as_uri()