def register(package, repository, username, password, comment, config_file, cert, client_cert): config = utils.get_repository_from_config(config_file, repository) config["repository"] = utils.normalize_repository_url(config["repository"]) print("Registering package to {0}".format(config["repository"])) username = utils.get_username(username, config) password = utils.get_password(password, config) ca_cert = utils.get_cacert(cert, config) client_cert = utils.get_clientcert(client_cert, config) repository = Repository(config["repository"], username, password) repository.set_certificate_authority(ca_cert) repository.set_client_certificate(client_cert) if not os.path.exists(package): raise exc.PackageNotFound( '"{0}" does not exist on the file system.'.format(package)) resp = repository.register(PackageFile.from_filename(package, comment)) repository.close() if resp.is_redirect: raise exc.RedirectDetected( ('"{0}" attempted to redirect to "{1}" during registration.' ' Aborting...').format(config["repository"], resp.headers["location"])) resp.raise_for_status()
def upload(dists, repository, sign, identity, username, password, comment, sign_with, config_file, skip_existing, cert, client_cert): # Check that a nonsensical option wasn't given if not sign and identity: raise ValueError("sign must be given along with identity") dists = find_dists(dists) # Determine if the user has passed in pre-signed distributions signatures = dict( (os.path.basename(d), d) for d in dists if d.endswith(".asc")) uploads = [i for i in dists if not i.endswith(".asc")] config = utils.get_repository_from_config(config_file, repository) config["repository"] = utils.normalize_repository_url(config["repository"]) print("Uploading distributions to {0}".format(config["repository"])) username = utils.get_username(username, config) password = utils.get_password(password, config) ca_cert = utils.get_cacert(cert, config) client_cert = utils.get_clientcert(client_cert, config) repository = Repository(config["repository"], username, password) repository.set_certificate_authority(ca_cert) repository.set_client_certificate(client_cert) for filename in uploads: package = PackageFile.from_filename(filename, comment) signed_name = package.signed_basefilename if signed_name in signatures: package.add_gpg_signature(signatures[signed_name], signed_name) elif sign: package.sign(sign_with, identity) resp = repository.upload(package) # Bug 92. If we get a redirect we should abort because something seems # funky. The behaviour is not well defined and redirects being issued # by PyPI should never happen in reality. This should catch malicious # redirects as well. if resp.is_redirect: raise exc.RedirectDetected( ('"{0}" attempted to redirect to "{1}" during upload.' ' Aborting...').format(config["repository"], resp.headers["location"])) # Otherwise, raise an HTTPError based on the status code. if skip_upload(resp, skip_existing, package): print(" Skipping {0} because it appears to already exist".format( package.basefilename)) continue resp.raise_for_status() # Bug 28. Try to silence a ResourceWarning by clearing the connection # pool. repository.close()
def upload(upload_settings, dists): dists = _find_dists(dists) # Determine if the user has passed in pre-signed distributions signatures = dict( (os.path.basename(d), d) for d in dists if d.endswith(".asc") ) uploads = [i for i in dists if not i.endswith(".asc")] upload_settings.check_repository_url() repository_url = upload_settings.repository_config['repository'] print("Uploading distributions to {0}".format(repository_url)) repository = upload_settings.create_repository() for filename in uploads: package = PackageFile.from_filename(filename, upload_settings.comment) skip_message = ( " Skipping {0} because it appears to already exist".format( package.basefilename) ) # Note: The skip_existing check *needs* to be first, because otherwise # we're going to generate extra HTTP requests against a hardcoded # URL for no reason. if (upload_settings.skip_existing and repository.package_is_uploaded(package)): print(skip_message) continue signed_name = package.signed_basefilename if signed_name in signatures: package.add_gpg_signature(signatures[signed_name], signed_name) elif upload_settings.sign: package.sign(upload_settings.sign_with, upload_settings.identity) resp = repository.upload(package) # Bug 92. If we get a redirect we should abort because something seems # funky. The behaviour is not well defined and redirects being issued # by PyPI should never happen in reality. This should catch malicious # redirects as well. if resp.is_redirect: raise exc.RedirectDetected( ('"{0}" attempted to redirect to "{1}" during upload.' ' Aborting...').format(repository_url, resp.headers["location"])) if skip_upload(resp, upload_settings.skip_existing, package): print(skip_message) continue utils.check_status_code(resp, upload_settings.verbose) # Bug 28. Try to silence a ResourceWarning by clearing the connection # pool. repository.close() return True
def register(register_settings, package): repository_url = register_settings.repository_config['repository'] print("Registering package to {0}".format(repository_url)) repository = register_settings.create_repository() if not os.path.exists(package): raise exc.PackageNotFound( '"{0}" does not exist on the file system.'.format(package)) resp = repository.register( PackageFile.from_filename(package, register_settings.comment)) repository.close() if resp.is_redirect: raise exc.RedirectDetected( ('"{0}" attempted to redirect to "{1}" during registration.' ' Aborting...').format(repository_url, resp.headers["location"])) resp.raise_for_status()
def upload(dists, repository, sign, identity, username, password, comment, sign_with, config_file, skip_existing, cert, client_cert, repository_url): # Check that a nonsensical option wasn't given if not sign and identity: raise ValueError("sign must be given along with identity") dists = find_dists(dists) # Determine if the user has passed in pre-signed distributions signatures = dict( (os.path.basename(d), d) for d in dists if d.endswith(".asc") ) uploads = [i for i in dists if not i.endswith(".asc")] config = utils.get_repository_from_config( config_file, repository, repository_url, ) config["repository"] = utils.normalize_repository_url( config["repository"] ) print("Uploading distributions to {0}".format(config["repository"])) if config["repository"].startswith((LEGACY_PYPI, LEGACY_TEST_PYPI)): raise exc.UploadToDeprecatedPyPIDetected( "You're trying to upload to the legacy PyPI site '{0}'. " "Uploading to those sites is deprecated. \n " "The new sites are pypi.org and test.pypi.org. Try using " "{1} (or {2}) to upload your packages instead. " "These are the default URLs for Twine now. \n More at " "https://packaging.python.org/guides/migrating-to-pypi-org/ " ".".format( config["repository"], utils.DEFAULT_REPOSITORY, utils.TEST_REPOSITORY ) ) username = utils.get_username(username, config) password = utils.get_password( config["repository"], username, password, config, ) ca_cert = utils.get_cacert(cert, config) client_cert = utils.get_clientcert(client_cert, config) repository = Repository(config["repository"], username, password) repository.set_certificate_authority(ca_cert) repository.set_client_certificate(client_cert) for filename in uploads: package = PackageFile.from_filename(filename, comment) skip_message = ( " Skipping {0} because it appears to already exist".format( package.basefilename) ) # Note: The skip_existing check *needs* to be first, because otherwise # we're going to generate extra HTTP requests against a hardcoded # URL for no reason. if skip_existing and repository.package_is_uploaded(package): print(skip_message) continue signed_name = package.signed_basefilename if signed_name in signatures: package.add_gpg_signature(signatures[signed_name], signed_name) elif sign: package.sign(sign_with, identity) resp = repository.upload(package) # Bug 92. If we get a redirect we should abort because something seems # funky. The behaviour is not well defined and redirects being issued # by PyPI should never happen in reality. This should catch malicious # redirects as well. if resp.is_redirect: raise exc.RedirectDetected( ('"{0}" attempted to redirect to "{1}" during upload.' ' Aborting...').format(config["repository"], resp.headers["location"])) if skip_upload(resp, skip_existing, package): print(skip_message) continue utils.check_status_code(resp) # Bug 28. Try to silence a ResourceWarning by clearing the connection # pool. repository.close()
def upload(dists, repository, sign, identity, username, password, comment, sign_with, config_file): # Check that a nonsensical option wasn't given if not sign and identity: raise ValueError("sign must be given along with identity") # Determine if the user has passed in pre-signed distributions signatures = dict( (os.path.basename(d), d) for d in dists if d.endswith(".asc")) dists = [i for i in dists if not i.endswith(".asc")] # Get our config from the .pypirc file try: config = get_config(config_file)[repository] except KeyError: raise KeyError( "Missing '{0}' section from the configuration file".format( repository, ), ) parsed = urlparse(config["repository"]) if parsed.netloc in ["pypi.python.org", "testpypi.python.org"]: config["repository"] = urlunparse(("https", ) + parsed[1:]) print("Uploading distributions to {0}".format(config["repository"])) username = get_username(username, config) password = get_password(password, config) session = requests.session() uploads = find_dists(dists) for filename in uploads: # Sign the dist if requested if sign: sign_file(sign_with, filename, identity) # Extract the metadata from the package for ext, dtype in DIST_EXTENSIONS.items(): if filename.endswith(ext): meta = DIST_TYPES[dtype](filename) break else: raise ValueError("Unknown distribution format: '%s'" % os.path.basename(filename)) if dtype == "bdist_egg": pkgd = pkg_resources.Distribution.from_filename(filename) py_version = pkgd.py_version elif dtype == "bdist_wheel": py_version = meta.py_version elif dtype == "bdist_wininst": py_version = meta.py_version else: py_version = None # Fill in the data - send all the meta-data in case we need to # register a new release data = { # action ":action": "file_upload", "protcol_version": "1", # identify release "name": pkg_resources.safe_name(meta.name), "version": meta.version, # file content "filetype": dtype, "pyversion": py_version, # additional meta-data "metadata_version": meta.metadata_version, "summary": meta.summary, "home_page": meta.home_page, "author": meta.author, "author_email": meta.author_email, "maintainer": meta.maintainer, "maintainer_email": meta.maintainer_email, "license": meta.license, "description": meta.description, "keywords": meta.keywords, "platform": meta.platforms, "classifiers": meta.classifiers, "download_url": meta.download_url, "supported_platform": meta.supported_platforms, "comment": comment, # PEP 314 "provides": meta.provides, "requires": meta.requires, "obsoletes": meta.obsoletes, # Metadata 1.2 "project_urls": meta.project_urls, "provides_dist": meta.provides_dist, "obsoletes_dist": meta.obsoletes_dist, "requires_dist": meta.requires_dist, "requires_external": meta.requires_external, "requires_python": meta.requires_python, } md5_hash = hashlib.md5() with open(filename, "rb") as fp: content = fp.read(4096) while content: md5_hash.update(content) content = fp.read(4096) data["md5_digest"] = md5_hash.hexdigest() signed_name = os.path.basename(filename) + ".asc" if signed_name in signatures: with open(signatures[signed_name], "rb") as gpg: data["gpg_signature"] = (signed_name, gpg.read()) elif sign: with open(filename + ".asc", "rb") as gpg: data["gpg_signature"] = (signed_name, gpg.read()) print("Uploading {0}".format(os.path.basename(filename))) data_to_send = [] for key, value in data.items(): if isinstance(value, (list, tuple)): for item in value: data_to_send.append((key, item)) else: data_to_send.append((key, value)) with open(filename, "rb") as fp: data_to_send.append(( "content", (os.path.basename(filename), fp, "application/octet-stream"), )) encoder = MultipartEncoder(data_to_send) resp = session.post( config["repository"], data=encoder, auth=(username, password), allow_redirects=False, headers={'Content-Type': encoder.content_type}, ) # Bug 28. Try to silence a ResourceWarning by releasing the socket and # clearing the connection pool. resp.close() session.close() # Bug 92. If we get a redirect we should abort because something seems # funky. The behaviour is not well defined and redirects being issued # by PyPI should never happen in reality. This should catch malicious # redirects as well. if resp.is_redirect: raise exc.RedirectDetected( ('"{0}" attempted to redirect to "{1}" during upload.' ' Aborting...').format(config["respository"], resp.headers["location"])) # Otherwise, raise an HTTPError based on the status code. resp.raise_for_status()