<jupyter_start><jupyter_text>pypi> Automate pypi package building and publishing<jupyter_code>#hide
from nbdev.showdoc import *
#export
import os
import shutil
import subprocess
from easyrelease.utils import check_project_root, get_pypi_credentials, run_tests
#export
@check_project_root
def clean_dist():
    "Clean dist/ folder"
    shutil.rmtree("dist", ignore_errors=True)
#export
@check_project_root
def build_pypi_package():
    "Build pypi package"
    subprocess.run(["python", "setup.py", "sdist", "bdist_wheel"])
#export
@check_project_root
def publish_pypi_package():
    "Publish package to pypi via twine"
    username, password = get_pypi_credentials()
    subprocess.run(
        ["twine", "upload", "--repository", "pypi", "dist/*", 
         "--username", username, "--password", password]
    )
#export
@run_tests
def build_and_publish_pypi():
    "Build and publish pypi package"
    clean_dist()
    build_pypi_package()
    publish_pypi_package()
#hide
from nbdev.export import notebook2script
notebook2script()<jupyter_output>Converted 00_gh.ipynb.
Converted 02_conda.ipynb.
Converted 03_cli.ipynb.
Converted 04_utils.ipynb.
Converted index.ipynb.
{'fraction_non_alphanumeric': 0.10949529512403763, 'fraction_numerical': 0.00855431993156544, 'mean_word_length': 5.25668449197861, 'pattern_counts': {'":': 0, '<': 4, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '1', 'dir': 'jupyter-structured-clean-dedup', 'id': '64715', 'license': 'Apache-2.0', 'n_tokens_mistral': 421, 'n_tokens_neox': 398, 'n_words': 93, 'path': 'nbs/01_pypi.ipynb', 'repo_name': 'PabloRMira/easyrelease', 'size': '1169'}