diff --git a/.github/workflows/build-wheels.yml b/.github/workflows/build-wheels.yml new file mode 100644 index 00000000..48eca7cb --- /dev/null +++ b/.github/workflows/build-wheels.yml @@ -0,0 +1,66 @@ +name: Build-wheels + +# This workflow builds "wheels", which are the binary package installers hosted on PyPI. +# GitHub Actions is super helpful here because each one needs to be compiled in its own +# target environment. The wheel files are saved as artifacts, which you can download from +# the GitHub website. Wheels should be uploaded manually to PyPI -- see CONTRIBUTING.md. + +# The Linux wheels cannot be generated using `ubuntu-latest` because they require a +# special Docker image to ensure cross-Linux compatibility. There are at least a couple +# of third-party actions set up using the official image; we could switch to another if +# this ever breaks. + +on: + # push: + pull_request: + release: + workflow_dispatch: + +jobs: + + build-manylinux: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 +# with: +# ref: 'v0.6' # enable to check out prior version of codebase + - name: Build wheels + uses: RalfG/python-wheels-manylinux-build@v0.3.3 + with: + python-versions: 'cp35-cp35m cp36-cp36m cp37-cp37m cp38-cp38 cp39-cp39' + build-requirements: 'cython numpy' + - name: Save artifacts + uses: actions/upload-artifact@v2 + with: + name: wheels + path: dist/*-manylinux*.whl + + build: + runs-on: ${{ matrix.os }} + defaults: + run: + shell: bash -l {0} # needed for conda persistence + strategy: + matrix: + os: [macos-latest, windows-latest] + python-version: [3.6, 3.7, 3.8, 3.9] + steps: + - uses: actions/checkout@v2 +# with: +# ref: 'v0.6' # enable to check out prior version of codebase + - name: Set up Python ${{ matrix.python-version }} + uses: conda-incubator/setup-miniconda@v2 + with: + python-version: ${{ matrix.python-version }} + - name: Set up environment + run: | + conda config --append channels conda-forge + conda install cython numpy clang llvm-openmp + - name: Build wheel + run: | + python setup.py bdist_wheel + - name: Save artifacts + uses: actions/upload-artifact@v2 + with: + name: wheels + path: dist/*.whl diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 5e107e78..35be4c67 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -1,7 +1,7 @@ name: Coverage # This workflow generates a coverage report (how much of the codebase is covered by the -# unit tests) and uploads the information to Coveralls.io for reporting and analysis. +# unit tests) and posts headline metrics to the PR thread. on: # push: @@ -21,13 +21,15 @@ jobs: run: | pip install . pip install osmnet - - name: Run unit tests + - name: Generate coverage report run: | - pip install 'pytest<4.0' 'pytest-cov<2.10' + pip install 'pytest<4.0' 'pytest-cov<2.10' coverage python setup.py test --pytest-args "--cov pandana --cov-report term-missing" - - name: Upload to Coveralls - run: | - pip install coveralls - coveralls + echo "coverage=$(coverage report | grep '^TOTAL' | grep -oE '[^ ]+$')" >> $GITHUB_ENV + - name: Post comment on PR + uses: unsplash/comment-on-pr@master env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + msg: "Test coverage is ${{ env.coverage }}" + check_for_duplicate_msg: true diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3ffc153b..9fba74e7 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -68,11 +68,17 @@ You can contact Sam Maurer, the lead maintainer, at `maurer@urbansim.com`. - Check https://pypi.org/project/pandana/ for the new version +The binary package installers or "wheels" are built using a GitHub Actions workflow, because each one needs to be compiled in its own target environment. This should run automatically when a PR is opened, to confirm nothing is broken, and again when a release is tagged in GitHub. You can download the resulting wheel files from the Action status page and then upload them to PyPI using the same command as above. + ## Distributing a release on Conda Forge (for conda installation): -- The [conda-forge/pandana-feedstock](https://github.com/conda-forge/pandana-feedstock) repository controls the Conda Forge release +- The [conda-forge/pandana-feedstock](https://github.com/conda-forge/pandana-feedstock) repository controls the Conda Forge release, including which GitHub users have maintainer status for the repo - Conda Forge bots usually detect new releases on PyPI and set in motion the appropriate feedstock updates, which a current maintainer will need to approve and merge +- Maintainers can add on additional changes before merging the PR, for example to update the requirements or edit the list of maintainers + +- You can also fork the feedstock and open a PR manually. It seems like this must be done from a personal account (not a group account like UDST) so that the bots can be granted permission for automated cleanup + - Check https://anaconda.org/conda-forge/pandana for the new version (may take a few minutes for it to appear) diff --git a/README.md b/README.md index 19be6f79..6b51c3ff 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -[![Coverage Status](https://coveralls.io/repos/github/UDST/pandana/badge.svg?branch=master)](https://coveralls.io/github/UDST/pandana?branch=master) +![Coverage Status](https://img.shields.io/badge/coverage-95%25-green) # Pandana @@ -11,11 +11,12 @@ Documentation: http://udst.github.io/pandana ### Installation -Pandana runs on Mac, Linux, and Windows with Python 2.7, 3.6, 3.7, and 3.8. +As of March 2021, binary installers are provided for Mac, Linux, and Windows through both PyPI and Conda Forge. -The easiest way to install Pandana is using the [Anaconda](https://www.anaconda.com/distribution/) package manager. Pandana's Anaconda distributions are pre-compiled and include multi-threading support on all platforms. +- `pip install pandana` +- `conda install pandana --channel conda-forge` -`conda install pandana --channel conda-forge` +Pandana works best in Python 3.6+, although binary installers for Python 3.5 remain available on Pip. The last version of Pandana with Python 2.7 binaries is v0.4.4 on Conda Forge. See the documentation for information about other [installation options](http://udst.github.io/pandana/installation.html). @@ -25,7 +26,6 @@ See the documentation for information about other [installation options](http:// [Pandana-demo.ipynb](examples/Pandana-demo.ipynb) - ### Acknowledgments Pandana was created by [Fletcher Foti](https://github.com/fscottfoti), with subsequent contributions from [Matt Davis](https://github.com/jiffyclub), [Federico Fernandez](https://github.com/federicofernandez), [Sam Maurer](https://github.com/smmaurer), and others. Sam Maurer is currently the lead maintainer. Pandana relies on contraction hierarchy code from [Dennis Luxen](https://github.com/DennisOSRM) and his [OSRM project](https://github.com/DennisOSRM/Project-OSRM). diff --git a/docs/source/conf.py b/docs/source/conf.py index e915973f..543ab7dd 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -50,7 +50,7 @@ # General information about the project. project = 'pandana' -copyright = '2020, UrbanSim Inc.' +copyright = '2021, UrbanSim Inc.' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the diff --git a/docs/source/index.rst b/docs/source/index.rst index 4b893394..9489f030 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -8,7 +8,7 @@ Pandana Pandana is a Python library for network analysis that uses `contraction hierarchies `_ to calculate super-fast travel accessibility metrics and shortest paths. The numerical code is in C++. -v0.6, released November 11, 2020 +v0.6, released November 11, 2020. Docs updated March 2021. Acknowledgments diff --git a/docs/source/installation.rst b/docs/source/installation.rst index 1aa7d7ff..001c3d4d 100644 --- a/docs/source/installation.rst +++ b/docs/source/installation.rst @@ -1,95 +1,65 @@ Installation ============ -Pandana is a Python package that includes a C++ extension for numerical operations. Pandana is tested on Mac, Linux, and Windows with Python 2.7, 3.6, 3.7, and 3.8. +Pandana is a Python package that includes a C++ extension for numerical operations. -The easiest way to install Pandana is using the `Anaconda`_ package manager. Pandana's Anaconda distributions are pre-compiled and include multi-threading support on all platforms. -If you install Pandana from Pip or from the source code on GitHub, you'll need to compile the C++ components locally. This is automatic, but won't work unless the right build tools are in place. See full instructions below. - - -Anaconda (recommended!) +Standard installation ------------------------------ -Pandana is hosted on Conda Forge:: - - conda install pandana --channel conda-forge - - -.. _pip: +As of March 2021, binary installers are provided for Mac, Linux, and Windows through both PyPI and Conda Forge. -Pip (requires local compilation) --------------------------------- - -Pandana is also hosted on PyPI:: +You can install Pandana using Pip:: pip install pandana -Pandana's C++ components will compile automatically if the right tools are present. See instructions below for individual operating systems. +Or Conda:: + conda install pandana --channel conda-forge -.. _github: +Pandana works best in Python 3.6+, although binary installers for Python 3.5 remain available on Pip. The last version of Pandana with Python 2.7 binaries is v0.4.4 on Conda Forge. -GitHub (requires local compilation) ------------------------------------ -If you'll be modifying the code, you can install Pandana from the `GitHub source `_:: +ARM-based Macs +------------------------------ - git clone https://github.com/udst/pandana.git - cd pandana - pip install cython numpy - python setup.py develop +Pandana's binary installers are optimized for x86 (Intel) Macs from 2020 and earlier, but will also run on newer ARM-based Macs. -Pandana's C++ components will compile automatically if the right tools are present. See instructions below for individual operating systems. +If you'd like to compile Pandana locally for ARM, see instructions in `issue #152 `_. In our testing, natively compiled binaries run about 35% faster than the x86 binaries with Rosetta translation. We aim to provide osx-arm64 binaries on Pip and Conda as soon as it's feasible. -Tips for local compilation --------------------------- +Compiling from source code +------------------------------ -If you cannot install using Conda, Pandana's C++ code will need to be compiled locally on your machine. +You may want to compile Pandana locally if you're modifying the source code or need to use a version that's missing binary installers for your platform. -Compiling in MacOS -~~~~~~~~~~~~~~~~~~ +Mac users should start by running ``xcode-select --install`` to make sure you have Apple's Xcode command line tools, which are needed behind the scenes. Windows users will need the `Microsoft Visual C++ Build Tools `_. -MacOS comes with C++ compilers, but the built-in ones don't allow multi-threading in Pandana. So, run this if possible before installing Pandana from source code:: +Pandana's build-time requirements are ``cython``, ``numpy``, and a C++ compiler that supports the c++11 standard. Additionally, the compiler needs to support OpenMP to allow Pandana to use multithreading. - xcode-select --install - conda install cython numpy llvm-openmp clang +The smoothest route is to get the compilers from Conda Forge -- you want the ``clang`` and ``llvm-openmp`` packages. Running Pandana's setup script will trigger compilation:: -Pandana will automatically detect that these are installed, and compile itself with multi-threading enabled. + conda install cython numpy clang llvm-openmp + python setup.py develop -If you prefer to use a different compiler, provide a path in the ``CC`` environment variable and we'll use that one instead. See writeup in `PR #137 `_ for some more discussion of this. +You'll see a lot of status messages go by, but hopefully no errors. -If you get a compilation error like ``'wchar.h' file not found`` in MacOS 10.14, you can resolve it by installing some additional header files:: +MacOS 10.14 (but not later versions) often needs additional header files installed. If you see a compilation error like ``'wchar.h' file not found`` in MacOS 10.14, you can resolve it by running this command:: open /Library/Developer/CommandLineTools/Packages/macOS_SDK_headers_for_macOS_10.14.pkg -Compiling in Linux -~~~~~~~~~~~~~~~~~~ - -Pandana's setup script expects a version of the GCC compiler with support for OpenMP. This appears to be GCC 4.8+, but we haven't done extensive testing. If you run into problems, try doing a fresh install of the core build tools:: - - sudo apt-get install --reinstall build-essential - -Compiling in Windows -~~~~~~~~~~~~~~~~~~~~ - -Compilation is automatic but requires that `Microsoft Visual C++ Build Tools `_ are installed. -Certain older machines may need the `Microsoft Visual C++ 2008 SP1 Redistributable Package (x64) `_ or something similar in order to use Pandana. This provides runtime components of the Visual C++ libraries. - - -Multi-threading ---------------- - -After installing Pandana, running :code:`examples/simple_example.py` will display the number of threads that Pandana is using. +Advanced compilation tips +------------------------------ -If you're installing from source code on a Mac, see "Compiling in MacOS" above for more information about enabling multi-threading. +If you prefer not to use Conda, you can skip the ``clang`` and ``llvm-openmp`` packages. Compilation will likely work fine with your system's built-in toolchain. -.. note:: - The multi-threading status indicator may be incorrect in certain Windows environments. See GitHub `issue #138 `_ for the latest information on this. +The default C++ compiler on Macs doesn't support OpenMP, though, meaning that Pandana won't be able to use multithreading. +You can set the ``CC`` environment variable to specify a compiler of your choice. See writeup in `PR #137 `_ for discussion of this. If you need to make additional modifications, you can edit the compilation script in your local copy of ``setup.py``. +Multithreading +------------------------------ -.. _Anaconda: https://www.anaconda.com/distribution/ +You can check how many threads Pandana is able to use on your machine by running the ``examples/simple_example.py`` script.