def create_plugin(
    plugin_name,
    from_files=None,
    outdir=None,
    description=None,
    version=None,
    overwrite=False,
    **kwargs,
):
    """Creates a plugin with the given name.

    If no ``from_files`` are provided, a directory containing only the plugin's
    metadata file will be created.

    If no ``outdir`` is specified, the plugin is created within your local
    plugins directory (``fo.config.plugins_dir``).

    Args:
        plugin_name: the name of the plugin
        from_files (None): a directory or list of explicit filepaths to include
            in the plugin
        outdir (None): the path at which to create the plugin directory. If
            not provided, the plugin is created within your
            ``fo_config.plugins_dir``
        description (None): a description for the plugin
        version (None): an optional FiftyOne version requirement string
        overwrite (False): whether to overwrite a local plugin with the same
            name if one exists
        **kwargs: additional keyword arguments to include in the plugin
            definition

    Returns:
        the directory containing the created plugin
    """
    if outdir is None:
        existing_plugins = {
            p.name: p for p in list_plugins(enabled="all", builtin="all")
        }
        existing_plugin = existing_plugins.get(plugin_name, None)
        if existing_plugin is not None:
            if not overwrite:
                raise ValueError(f"Plugin '{plugin_name}' already exists")

            if existing_plugin.builtin:
                raise ValueError(
                    f"Cannot overwrite builtin plugin '{plugin_name}'"
                )

            plugin_dir = existing_plugin.directory
            logger.info(f"Overwriting existing plugin '{plugin_name}'")
        else:
            plugin_dir = os.path.join(fo.config.plugins_dir, plugin_name)
    elif os.path.isdir(outdir):
        if not overwrite:
            raise ValueError(f"Directory '{outdir}' already exists")

        plugin_dir = outdir
        logger.info(f"Overwriting existing plugin at '{plugin_dir}'")
    else:
        plugin_dir = _recommend_plugin_dir(plugin_name)
        logger.info(f"Creating plugin at '{plugin_dir}'")

    etau.ensure_empty_dir(plugin_dir, cleanup=True)

    if from_files is not None:
        if etau.is_str(from_files):
            from_files = [from_files]

        for from_path in from_files:
            if os.path.isfile(from_path):
                shutil.copy(from_path, plugin_dir)
            elif os.path.isdir(from_path):
                shutil.copytree(from_path, plugin_dir)
            else:
                logger.warning(
                    f"Skipping nonexistent file or directory '{from_path}'"
                )

    yaml_path = _find_plugin_metadata_file(plugin_dir)
    if yaml_path is None:
        yaml_path = os.path.join(plugin_dir, PLUGIN_METADATA_FILENAMES[0])

    pd = {"name": plugin_name}
    if description:
        pd[description] = description

    pd.update(kwargs)

    if version is not None:
        if "fiftyone" not in pd:
            pd["fiftyone"] = {}

        pd["fiftyone"]["version"] = version

    # Merge with existing YAML file, if necessary
    if os.path.isfile(yaml_path):
        with open(yaml_path, "r") as f:
            pd = yaml.safe_load(f) | pd

    with open(yaml_path, "w") as f:
        yaml.dump(pd, f)

    return plugin_dir
Creates a plugin with the given name.

    If no ``from_files`` are provided, a directory containing only the plugin's
    metadata file will be created.

    If no ``outdir`` is specified, the plugin is created within your local
    plugins directory (``fo.config.plugins_dir``).

    Args:
        plugin_name: the name of the plugin
        from_files (None): a directory or list of explicit filepaths to include
            in the plugin
        outdir (None): the path at which to create the plugin directory. If
            not provided, the plugin is created within your
            ``fo_config.plugins_dir``
        description (None): a description for the plugin
        version (None): an optional FiftyOne version requirement string
        overwrite (False): whether to overwrite a local plugin with the same
            name if one exists
        **kwargs: additional keyword arguments to include in the plugin
            definition

    Returns:
        the directory containing the created plugin
    
fiftyone/plugins/core.py