def upload_to_pypi( path: str = "dist", skip_existing: bool = False, ): """Upload wheels to PyPI with Twine. Wheels must already be created and stored at the given path. Credentials are taken from either the environment variable ``PYPI_TOKEN``, or from ``PYPI_USERNAME`` and ``PYPI_PASSWORD``. :param path: Path to dist folder containing the files to upload. :param skip_existing: Continue uploading files if one already exists. (Only valid when uploading to PyPI. Other implementations may not support this.) """ # Attempt to get an API token from environment token = os.environ.get("PYPI_TOKEN") if not token: # Look for a username and password instead username = os.environ.get("PYPI_USERNAME") password = os.environ.get("PYPI_PASSWORD") if not (username or password): raise ImproperConfigurationError( "Missing credentials for uploading to PyPI") elif not token.startswith("pypi-"): raise ImproperConfigurationError( 'PyPI token should begin with "pypi-"') else: username = "******" password = token run("twine upload -u '{}' -p '{}' {} \"{}/*\"".format( username, password, "--skip-existing" if skip_existing else "", path))
def upload_to_pypi( path: str = "dist", skip_existing: bool = False, glob_patterns: List[str] = None ): """Upload wheels to PyPI with Twine. Wheels must already be created and stored at the given path. Credentials are taken from either the environment variable ``PYPI_TOKEN``, or from ``PYPI_USERNAME`` and ``PYPI_PASSWORD``. :param path: Path to dist folder containing the files to upload. :param skip_existing: Continue uploading files if one already exists. (Only valid when uploading to PyPI. Other implementations may not support this.) :param glob_patterns: List of glob patterns to include in the upload (["*"] by default). """ if not glob_patterns: glob_patterns = ["*"] # Attempt to get an API token from environment token = os.environ.get("PYPI_TOKEN") username = None password = None if not token: # Look for a username and password instead username = os.environ.get("PYPI_USERNAME") password = os.environ.get("PYPI_PASSWORD") home_dir = os.environ.get("HOME", "") if not (username or password) and ( not home_dir or not os.path.isfile(os.path.join(home_dir, ".pypirc")) ): raise ImproperConfigurationError( "Missing credentials for uploading to PyPI" ) elif not token.startswith("pypi-"): raise ImproperConfigurationError('PyPI token should begin with "pypi-"') else: username = "******" password = token repository = config.get("repository", None) repository_arg = f" -r '{repository}'" if repository else "" username_password = ( f"-u '{username}' -p '{password}'" if username and password else "" ) dist = " ".join( ['"{}/{}"'.format(path, glob_pattern.strip()) for glob_pattern in glob_patterns] ) skip_existing_param = " --skip-existing" if skip_existing else "" run(f"twine upload {username_password}{repository_arg}{skip_existing_param} {dist}")
def _handle_credentials_init(self) -> None: """ Initialize credentials from environment variables. For the transitional period until the *pypi* variables can be safely removed, additional complexity is needed. :raises ImproperConfigurationError: Error while setting up credentials configuration. """ username = get_env_var("repository_user_var") or get_env_var( "pypi_user_var") password = (get_env_var("repository_pass_var") or get_env_var("pypi_pass_var") or get_env_var("pypi_token_var")) if username and password: self.username = username self.password = password elif password and not username: self.username = username or "__token__" self.password = password logger.warning( "Providing only password or token without username is deprecated" ) # neither username nor password provided, check for ~/.pypirc file elif not Path("~/.pypirc").expanduser().exists(): raise ImproperConfigurationError( "Missing credentials for uploading to artifact repository")
def upload_to_pypi( dists: str = 'sdist bdist_wheel', path: str = 'dist', username: str = None, password: str = None, skip_existing: bool = False, remove_dist: bool = True ): """Creates the wheel and uploads to pypi with twine. :param dists: The dists string passed to setup.py. Default: 'bdist_wheel' :param username: PyPI account username string :param password: PyPI account password string :param skip_existing: Continue uploading files if one already exists. (Only valid when uploading to PyPI. Other implementations may not support this.) """ if username is None or password is None or username == "" or password == "": raise ImproperConfigurationError('Missing credentials for uploading') if remove_dist: run(f'rm -rf {path}') run('python setup.py {}'.format(dists)) run( "twine upload -u '{}' -p '{}' {} \"{}/*\"".format( username, password, '--skip-existing' if skip_existing else '', path ) ) if remove_dist: run(f'rm -rf {path}')
def upload_to_pypi( dists: str = 'sdist bdist_wheel', username: str = None, password: str = None, skip_existing: bool = False ): """Creates the wheel and uploads to pypi with twine. :param dists: The dists string passed to setup.py. Default: 'bdist_wheel' :param username: PyPI account username string :param password: PyPI account password string :param skip_existing: Continue uploading files if one already exists. (Only valid when uploading to PyPI. Other implementations may not support this.) """ if username is None or password is None: raise ImproperConfigurationError('Missing credentials for uploading') run('python setup.py {}'.format(dists)) run( 'twine upload -u {} -p {} {} {}'.format( username, password, '--skip-existing' if skip_existing else '', 'dist/*' ) ) run('rm -rf build dist')
def upload_to_pypi(path: str = 'dist', username: str = None, password: str = None, skip_existing: bool = False): """Upload wheels to PyPI with Twine. Wheels must already be created and stored at the given path. :param path: Path to dist folder containing the files to upload. :param username: PyPI account username. :param password: PyPI account password. :param skip_existing: Continue uploading files if one already exists. (Only valid when uploading to PyPI. Other implementations may not support this.) """ if username is None or password is None or username == "" or password == "": raise ImproperConfigurationError('Missing credentials for uploading') run("twine upload -u '{}' -p '{}' {} \"{}/*\"".format( username, password, '--skip-existing' if skip_existing else '', path))
def upload_to_pypi(dists: str = 'sdist bdist_wheel', username: str = None, password: str = None, skip_existing: bool = False): """Creates the wheel and uploads to pypi with twine. :param dists: The dists string passed to setup.py. Default: 'bdist_wheel' :param username: PyPI account username string :param password: PyPI account password string :param skip_existing: Continue uploading files if one already exists. (Only valid when uploading to PyPI. Other implementations may not support this.) """ if username is None or password is None or username == "" or password == "": raise ImproperConfigurationError('Missing credentials for uploading') run(['rm', '-rf', 'build', 'dist']) run(['python', 'setup.py', *dists.split(' ')]) run([ 'twine', 'upload', '-u', username, '-p', password, *(['--skip-existing'] if skip_existing else []), 'dist/*' ]) run(['rm', '-rf', 'build', 'dist'])
def upload(self, noop: bool, verbose: bool, skip_existing: bool, **additional_kwargs) -> bool: """ Upload artifact to repository using Twine. For known repositories (like PyPI), the web URLs of successfully uploaded packages will be displayed. :param noop: Do not apply any changes.. :param verbose: Show verbose output for Twine. :param skip_existing: Continue uploading files if one already exists. (May not work, check your repository for support.) :raises ImproperConfigurationError: The upload failed due to a configuration error. :returns True if successfull, False otherwise. """ addon_kwargs = { "non_interactive": True, "verbose": verbose, "skip_existing": skip_existing, **additional_kwargs, } try: twine_settings = self._create_twine_settings(addon_kwargs) if not noop: twine_upload(upload_settings=twine_settings, dists=self.dists) except TwineException as e: raise ImproperConfigurationError( "Upload to artifact repository has failed") from e except requests.HTTPError as e: logger.warning(f"Upload to artifact repository has failed: {e}") return False else: return True