code: def package(
      input_dir: Path,
      output_dir: Path,
      meta_path: Optional[Path] = None,
      code_paths: List[Path] = [],
      name: Optional[str] = None,
      version: Optional[str] = None,
      create_meta: bool = False,
      create_sdist: bool = True,
      create_wheel: bool = False,
      force: bool = False,
      silent: bool = True,
  ) -> None:
      msg = Printer(no_print=silent, pretty=not silent)
      input_path = util.ensure_path(input_dir)
      output_path = util.ensure_path(output_dir)
      meta_path = util.ensure_path(meta_path)
      if create_wheel and not has_wheel() and not has_build():
          err = "Generating wheels requires 'build' or 'wheel' (deprecated) to be installed"
          msg.fail(err, "pip install build", exits=1)
      if not has_build():
          msg.warn(
              "Generating packages without the 'build' package is deprecated and "
              "will not be supported in the future. To install 'build': pip "
              "install build"
          )
      if not input_path or not input_path.exists():
          msg.fail("Can't locate pipeline data", input_path, exits=1)
      if not output_path or not output_path.exists():
          msg.fail("Output directory not found", output_path, exits=1)
      if create_sdist or create_wheel:
          opts = [
              "sdist" if create_sdist else "",
              "wheel" if create_wheel else "",
          ]
          msg.info(
              f"Building package artifacts: {', '.join(opt for opt in opts if opt)}"
          )
      for code_path in code_paths:
          if not code_path.exists():
              msg.fail("Can't find code file", code_path, exits=1)
          # Import the code here so it's available when model is loaded (via
          # get_meta helper). Also verifies that everything works
          util.import_file(code_path.stem, code_path)
      if code_paths:
          msg.good(
              f"Including {len(code_paths)} Python module(s) with custom code"
          )
      if meta_path and not meta_path.exists():
          msg.fail("Can't find pipeline meta.json", meta_path, exits=1)
      meta_path = meta_path or input_dir / "meta.json"
      if not meta_path.exists() or not meta_path.is_file():
          msg.fail("Can't load pipeline meta.json", meta_path, exits=1)
      meta = srsly.read_json(meta_path)
      meta = get_meta(input_dir, meta)
      if meta["requirements"]:
          msg.good(
              f"Including {len(meta['requirements'])} package requirement(s) from "
              f"meta and config",
              ", ".join(meta["requirements"]),
          )
      if name is not None:
          if not name.isidentifier():
              msg.fail(
                  f"Model name ('{name}') is not a valid module name. "
                  "This is required so it can be imported as a module.",
                  "We recommend names that use ASCII A-Z, a-z, _ (underscore), "
                  "and 0-9. "
                  "For specific details see: https://docs.python.org/3/reference/lexical_analysis.html#identifiers",
                  exits=1,
              )
          if not _is_permitted_package_name(name):
              msg.fail(
                  f"Model name ('{name}') is not a permitted package name. "
                  "This is required to correctly load the model with spacy.load.",
                  "We recommend names that use ASCII A-Z, a-z, _ (underscore), "
                  "and 0-9. "
                  "For specific details see: https://www.python.org/dev/peps/pep-0426/#name",
                  exits=1,
              )
          meta["name"] = name
      if version is not None:
          meta["version"] = version
      if (
          not create_meta
      ):  # only print if user doesn't want to overwrite
          msg.good("Loaded meta.json from file", meta_path)
      else:
          meta = generate_meta(meta, msg)
      errors = validate(ModelMetaSchema, meta)
      if errors:
          msg.fail("Invalid pipeline meta.json")
          print("\n".join(errors))
          sys.exit(1)
      model_name = meta["name"]
      if not model_name.startswith(meta["lang"] + "_"):
          model_name = f"{meta['lang']}_{model_name}"
      model_name_v = model_name + "-" + meta["version"]
      main_path = output_dir / model_name_v
      package_path = main_path / model_name
      if package_path.exists():
          if force:
              shutil.rmtree(str(package_path))
          else:
              msg.fail(
                  "Package directory already exists",
                  "Please delete the directory and try again, or use the "
                  "`--force` flag to overwrite existing directories.",
                  exits=1,
              )
      Path.mkdir(package_path, parents=True)
      shutil.copytree(str(input_dir), str(package_path / model_name_v))
      for file_name in FILENAMES_DOCS:
          file_path = package_path / model_name_v / file_name
          if file_path.exists():
              shutil.copy(str(file_path), str(main_path))
      readme_path = main_path / "README.md"
      if not readme_path.exists():
          readme = generate_readme(meta)
          create_file(readme_path, readme)
          create_file(package_path / model_name_v / "README.md", readme)
          msg.good("Generated README.md from meta.json")
      else:
          msg.info("Using existing README.md from pipeline directory")
      imports = []
      for code_path in code_paths:
          imports.append(code_path.stem)
          shutil.copy(str(code_path), str(package_path))
      create_file(
          main_path / "meta.json", srsly.json_dumps(meta, indent=2)
      )
      create_file(main_path / "setup.py", TEMPLATE_SETUP)
      create_file(main_path / "MANIFEST.in", TEMPLATE_MANIFEST)
      init_py = TEMPLATE_INIT.format(
          imports="\n".join(f"from . import {m}" for m in imports)
      )
      create_file(package_path / "__init__.py", init_py)
      msg.good(
          f"Successfully created package directory '{model_name_v}'",
          main_path,
      )
      if create_sdist:
          with util.working_dir(main_path):
              # run directly, since util.run_command is not designed to continue
              # after a command fails
              ret = subprocess.run(
                  [sys.executable, "-m", "build", ".", "--sdist"],
                  env=os.environ.copy(),
              )
              if ret.returncode != 0:
                  msg.warn(
                      "Creating sdist with 'python -m build' failed. Falling "
                      "back to deprecated use of 'python setup.py sdist'"
                  )
                  util.run_command(
                      [sys.executable, "setup.py", "sdist"],
                      capture=False,
                  )
          zip_file = (
              main_path / "dist" / f"{model_name_v}{SDIST_SUFFIX}"
          )
          msg.good(
              f"Successfully created zipped Python package", zip_file
          )
      if create_wheel:
          with util.working_dir(main_path):
              # run directly, since util.run_command is not designed to continue
              # after a command fails
              ret = subprocess.run(
                  [sys.executable, "-m", "build", ".", "--wheel"],
                  env=os.environ.copy(),
              )
              if ret.returncode != 0:
                  msg.warn(
                      "Creating wheel with 'python -m build' failed. Falling "
                      "back to deprecated use of 'wheel' with "
                      "'python setup.py bdist_wheel'"
                  )
                  util.run_command(
                      [sys.executable, "setup.py", "bdist_wheel"],
                      capture=False,
                  )
          wheel_name_squashed = re.sub("_+", "_", model_name_v)
          wheel = (
              main_path
              / "dist"
              / f"{wheel_name_squashed}{WHEEL_SUFFIX}"
          )
          msg.good(f"Successfully created binary wheel", wheel)
      if "__" in model_name:
          msg.warn(
              f"Model name ('{model_name}') contains a run of underscores. "
              "Runs of underscores are not significant in installed package names.",
          )
  
imports: import os
  import re
  import shutil
  import subprocess
  import sys
  from collections import defaultdict
  from pathlib import Path
  from typing import Any, Dict, List, Optional, Tuple, Union, cast
  import srsly
  from catalogue import RegistryError
  from thinc.api import Config
  from wasabi import MarkdownRenderer, Printer, get_raw_input
  from ..None import about, util
  from ..compat import importlib_metadata
  from ..schemas import ModelMetaSchema, validate
  from ._util import SDIST_SUFFIX, WHEEL_SUFFIX, Arg, Opt, app, string_to_list
label_desc: Use image node_id 2 for calling a global function with example usage: package(input_dir, output_dir, meta_path, code_paths, name, version, create_meta, create_sdist, create_wheel, force, silent) without return types