Usage & Examples

Quickstart

A single command is all you need to quickly start coding like a Python rockstar, skipping all the difficult and tedious bits:

putup my_project

This will create a new folder called my_project containing a perfect project template with everything you need for getting things done. Checkout out this demo project, which was set up using Pyscaffold.

Tip

New in version 4.0: We are trying out a brand new interactive mode that makes it even easier to use PyScaffold in its full potential. If you want to give it a shot, use the --interactive, or simply -i option.

The interactive command equivalent to the previous example is: putup -i my_project.

You can cd into your new project and interact with it from the command line after creating (or activating) an isolated development environment (with virtualenv, conda or your preferred tool), and performing the usual editable install:

pip install -e .

… all set and ready to go! Try the following in a Python shell:

>>> from my_project.skeleton import fib
>>> fib(10)
55

Or if you are concerned about performing package maintainer tasks, make sure to have tox installed and see what we have prepared for you out of the box:

tox -e docs  # to build your documentation
tox -e build  # to build your package distribution
tox -e publish  # to test your project uploads correctly in test.pypi.org
tox -e publish -- --repository pypi  # to release your package to PyPI
tox -av  # to list all the tasks available

The following figure demonstrates the usage of putup with the new experimental interactive mode for setting up a simple project. It uses the –cirrus flag to add CI support (via Cirrus CI), and tox to run automated project tasks like building a package file for distribution (or publishing).

Creating a simple package with PyScaffold

Type putup -h to learn about other things PyScaffold can do for your project, and if you are not convinced yet, have a look on these reasons to use PyScaffold.

There is also a video tutorial on how to develop a command-line application with the help of PyScaffold.

Notes

  1. PyScaffold’s project template makes use of a dedicated src folder to store all the package files meant for distribution (additional files like tests and documentation are kept in their own separated folders). You can find some comments and useful links about this design decision in our FAQ.

  2. The pip install -e . command installs your project in editable mode, making it available in import statements as any other Python module. It might fail if your have an old version of Python’s package manager and tooling in your current environment. Please make sure you are using the intended environment (either a virtual environment [recommended] or the default installation of Python in the operating system) and try to update them with python -m pip install -U pip setuptools.

  3. If you are using a virtual environment, please remember to re-activate it everytime you close your shell, otherwise you will not be able to import your project in the REPL. To check if you have already activated it you can run which python on Linux and OSX, where python on the classical Windows command prompt, or Get-Command python on PowerShell.

Examples

Just a few examples to get you an idea of how easy PyScaffold is to use:

putup my_little_project

The simplest way of using PyScaffold. A directory my_little_project is created with a Python package named exactly the same. The MIT license will be used.

putup -i my_little_project

If you are unsure on how to use PyScaffold, or keep typing putup --help all the time, the experimental --interactive (or simply -i), is your best friend. It will open your default text editor with a file containing examples and explanations on how to use putup (think of it as an “editable” --help text, once the file is saved and closed all the values you leave there are processed by PyScaffold). You might find some familiarities in the way this option works with git rebase -i, including the capacity of choosing a different text editor by setting the EDITOR (or VISUAL) environment variable in your terminal.

putup skynet -l GPL-3.0-only -d "Finally, the ultimate AI!" -u https://sky.net

This will create a project and package named skynet licensed under the GPL3. The description inside setup.cfg is directly set to “Finally, the ultimate AI!” and the homepage to https://sky.net.

putup Scikit-Gravity -p skgravity -l BSD-3-Clause

This will create a project named Scikit-Gravity but the package will be named skgravity with license new-BSD 1.

putup youtub --django --pre-commit -d "Ultimate video site for hot tub fans"

This will create a web project and package named youtub that also includes the files created by Django’s django-admin 2. The description in setup.cfg will be set and a file .pre-commit-config.yaml is created with a default setup for pre-commit.

putup thoroughly_tested --cirrus

This will create a project and package thoroughly_tested with files tox.ini and .cirrus.yml for tox and Cirrus CI.

putup my_zope_subpackage --name my-zope-subpackage --namespace zope --package subpackage

This will create a project under the my_zope_subpackage directory with the installation name of my-zope-subpackage (this is the name used by pip and PyPI), but with the following corresponding import statement:

from zope import subpackage
# zope is the namespace and subpackage is the package name

To be honest, there is really only the Zope project that comes to my mind which is using this exotic feature of Python’s packaging system. Chances are high, that you will never ever need a namespace package in your life. To learn more about namespaces in the Python ecosystem, check PEP 420.

1

Notice the usage of SPDX identifiers for specifying the license in the CLI

2

Requires the installation of pyscaffoldext-django.

Package Configuration

Projects set up with PyScaffold rely on setuptools, and therefore can be easily configured/customised via setup.cfg. Check out the example below:

# Docs on setup.cfg:
# http://setuptools.readthedocs.io/en/latest/setuptools.html#configuring-setup-using-setup-cfg-files

[metadata]
name = my_project
description = A test project that was set up with PyScaffold
author = Florian Wilhelm
author_email = Florian.Wilhelm@blue-yonder.com
license = MIT
url = https://...
long_description = file: README.rst
platforms = any
classifiers =
    Development Status :: 5 - Production/Stable
    Topic :: Utilities
    Programming Language :: Python
    Programming Language :: Python :: 3
    Environment :: Console
    Intended Audience :: Developers
    License :: OSI Approved :: MIT License
    Operating System :: POSIX :: Linux
    Operating System :: Unix
    Operating System :: MacOS
    Operating System :: Microsoft :: Windows

[options]
zip_safe = False
packages = find_namespace:
python_requires = >=3.6
include_package_data = True
package_dir =
    =src
# Add here dependencies of your project (semicolon/line-separated)
install_requires =
    pandas
    scikit-learn

[options.packages.find]
where = src
exclude =
    tests

[options.extras_require]
# Add here additional requirements for extra features, like:
# pdf = ReportLab>=1.2; RXP
# rest = docutils>=0.3; pack ==1.1, ==1.3
all = django; cookiecutter
# Add here test requirements (semicolon/line-separated)
testing =
    pytest
    pytest-cov

[options.entry_points]
# Add here console scripts like:
# console_scripts =
#     script_name = ${package}.module:function
# For example:
# console_scripts =
#     fibonacci = ${package}.skeleton:run
# And any other entry points, for example:
# pyscaffold.cli =
#     awesome = pyscaffoldext.awesome.extension:AwesomeExtension

[tool:pytest]
# Options for py.test:
# Specify command line options as you would do when invoking py.test directly.
# e.g. --cov-report html (or xml) for html/xml output or --junitxml junit.xml
# in order to write a coverage file that can be read by Jenkins.
addopts =
    --cov my_project --cov-report term-missing
    --verbose
norecursedirs =
    dist
    build
    .tox
testpaths = tests
markers =
    slow: mark tests as slow (deselect with '-m "not slow"')

[bdist_wheel]
universal = 1

[devpi:upload]
# Options for the devpi: PyPI server and packaging tool
# VCS export must be deactivated since we are using setuptools-scm
no_vcs = 1
formats =
    sdist
    bdist_wheel

[flake8]
# Some sane defaults for the code style checker flake8
max_line_length = 88
extend_ignore = E203, W503
# ^  Black-compatible
#    E203 and W503 have edge cases handled by black
exclude =
    .tox
    build
    dist
    .eggs
    docs/conf.py

[pyscaffold]
# PyScaffold's parameters when the project was created.
# This will be used when updating. Do not change!
version = 4.0
package = my_package
extensions =
    namespace
namespace = ns1.ns2

You might also want to have a look on pyproject.toml for specifying dependencies required during the build:

[build-system]
# AVOID CHANGING REQUIRES: IT WILL BE UPDATED BY PYSCAFFOLD!
requires = ["setuptools>=46.1.0", "setuptools_scm[toml]>=5", "wheel"]
build-backend = "setuptools.build_meta"

[tool.setuptools_scm]
# For smarter version schemes and other configuration options,
# check out https://github.com/pypa/setuptools_scm
version_scheme = "no-guess-dev"

Please note PyScaffold will add some internal information to setup.cfg, we do that to make updates a little smarter.

Note

To avoid splitting the configuration and build parameters among several files, PyScaffold uses the same file as setuptools (setup.cfg). Storing configuration in pyproject.toml is not supported. In the future, if the default build metadata location changes (as proposed by PEP 621), PyScaffold will follow the same pattern.

PyScaffold’s Own Configuration

PyScaffold also allows you to save your favourite configuration to a file that will be automatically read every time you run putup, this way you can avoid always retyping the same command line options.

The locations of the configuration files vary slightly across platforms, but in general the following rule applies:

  • Linux: $XDG_CONFIG_HOME/pyscaffold/default.cfg with fallback to ~/.config/pyscaffold/default.cfg

  • OSX: ~/Library/Preferences/pyscaffold/default.cfg

  • Windows(≥7): %APPDATA%\pyscaffold\pyscaffold\default.cfg

The file format resembles the setup.cfg generated automatically by PyScaffold, but with only the metadata and pyscaffold sections, for example:

[metadata]
author = John Doe
author-email = john.joe@gmail.com
license = MPL-2.0

[pyscaffold]
extensions =
    cirrus
    pre-commit

With this file in place, typing only:

$ putup myproj

will have the same effect as if you had typed:

$ putup --license MPL-2.0 --cirrus --pre-commit myproj

Note

For the time being, only the following options are allowed in the config file:

  • metadata section: author, author-email and license

  • pyscaffold section: extensions (and associated opts)

Options associated with extensions are the ones prefixed by an extension name.

To prevent PyScaffold from reading an existing config file, you can pass the --no-config option in the CLI. You can also save the given options when creating a new project with the --save-config option. Finally, to read the configurations from a location other then the default, use the --config PATH option. See putup --help for more details.

Warning

Experimental Feature - We are still evaluating how this new and exciting feature will work, so its API (including file format and name) is not considered stable and might change between minor versions. As previously stated, if the configuration file for setuptools changes (e.g. with PEP 621), PyScaffold will follow that and change its own configuration.

This means that in future versions, PyScaffold will likely adopt a more pyproject.toml-style configuration (and as a consequence the file name and extension might change).