Skip to main content

Tools to help plan deliveries for Bellingham Food Bank.

Project description

Bellingham Food Bank delivery planning toolkit

Summary

This set of command-line tools cuts some cruft around creating delivery route manifests. It's made from the reference_package template repo: https://github.com/crickets-and-comb/reference_package. See the docs: https://crickets-and-comb.github.io/bfb_delivery/.

The plan is to continue to build this package out to take on more of the tasks food-bank staff do manually to plan the delivery routes.

They use Circuit (https://getcircuit.com) to create optimized routes from lists of addresses and products, but there are some tedious tasks to prepare the data for Circuit and then to format the optimized routes into manifests for printing:

  1. Put all the stops in a single spreadsheet.
  2. Upload stop to Circuit to produce a single huge route as a starting point.
  3. Download the optimized route.
  4. Manually "chunk" the route by driver (assign stops to drivers according to how many boxes a driver can carry, what is a sensible set of stops, per-driver constraints, etc.).
  5. Split those routes into separate worksheets.
  6. Upload those smaller routes to Circuit again to optimize them.
  7. Set attributes etc. and launch optimization.
  8. Download the optimized CSVs.
  9. Combine the output CSVs into a single Excel workbook with a worksheet for each route.
  10. Finally format the sheets into printable manifests with a combination of Excel macro and manual steps.

Staff spend several hours each week on the manual pieces of this, the chunking alone taking about four hours.

What it does so far

At this point, the bfb_delivery package will:

  1. Download the optimized route.
  2. Split those routes into separate worksheets.
  3. Download the optimized CSVs.
  4. Combine the output CSVs into a single Excel workbook with a worksheet for each route.
  5. Finally format the sheets into printable manifests with a combination of Excel macro and manual steps.

The last three steps exectue in a single command. Next up is wrapping that up into a single command that also uploads the routes and optimizes them on Circuit, dispatches them, and then creates the final manifests -- leaving only the "chunking" step (step 3) for the hoomans.

See docs for more details: https://crickets-and-comb.github.io/bfb_delivery/.

Dev plan

We have no intention or desire to replace Circuit. In addition to optimizing routes, Circuit pushes routes to an app drivers can use, etc. But, there are some processes outside of that to further automate/support:

  • Chunking by driver (step 3 above): This may be the most challenging piece. I'm only a little confident I can solve this well enough to justify using my solution. So, I will save it for after I've cleared the low-hanging fruit. My first inclination is to try using a sort of recursive k-nearest neighbors (KNN) to group stops into potential routes, but that may change once I research existing routing algorithms.

  • To that end, implementing a mapping tool to check routes will be helpful in both dev and production. This would be essential to removing the first upload to Circuit to make a long dummy route, if we're able to build a sufficient a chunking solution. (That first upload doesn't cost the food bank anything but a trivial amount of time and fiddling around, but matching its sufficiency as a starting point is a good first benchmark.)

  • There are additional constraints to consider per driver. It may not be possible to encode all of them, but knocking out some of them may help cut down time, and doing this before chunking will better define the problem and add some validations.

  • The Circuit API supports uploading, optimizing, and exporting, which enables wrapping more of the steps into a single ETL pipeline. We have built the required export segment of the pipeline, and now need to build the upload and optimizing segments. There may be limitations to what attribute mapping, entity updates, etc. can be done via API.

  • DB: There's no plan to develop, host, and support a DB. We're using Excel, CSVs, etc. to keep close to users' knowledge and skill bases, and existing workflow and resources. A DB would be especially useful for encoding driver restrictions etc., but a simple spreadsheet should suffice. If we did start using a DB, however, we'd need to create CRUD interfaces to it.

  • GUI: There's no real plan to develop a GUI, but it might be a good portfolio project to try out Vercel or something.

The plan of attack has been to start with the low-hanging fruit of ETL before moving onto the bigger problem of chunking. Fully integrating with the Circuit API is the last step before taking on the chunking, and the integration is now halfway done with read capability.

Frankenstein's "Agile" caveat

The tools thus far are a series of small tools that were then wrapped by bigger tools, which were then wrapped by a larger tool, etc. This is a natural developmental result of incrementally and tentatively taking over this workflow as a volunteer as I gained trust and access to the org's data, information, and resources. Also, the project was largely unsolicited (but fully approved), so I was hesitant to ask too much of the staff to define and clarify requirements etc. It hasn't been used yet by staff in production (though certainly tested live), so I haven't yet discovered any of the improvements or mistaken assumptions that real users will find. As such, there are some optmizations that could happen to reduce the unnecessary output etc., but I am hesitant to do that until we find what works best for the users.

Structure

    src/bfb_delivery/api            Public and internal API.
    src/bfb_delivery/cli            Command-line-interface.
    src/bfb_delivery/lib            Implementation.
    tests/e2e                       End-to-end tests.
    test/integration                Integration tests.
    tests/unit                      Unit tests.

Dependencies

Installation

Run pip install bfb_delivery. See https://pypi.org/project/bfb-delivery/.

Usage Examples

See docs for full usage.

Public API

bfb_delivery is a library from which you can import functions. Import the public split_chunked_route function like this:

    from bfb_delivery import split_chunked_route
    # These are okay too:
    # from bfb_delivery.api import split_chunked_route
    # from bfb_delivery.api.public import split_chunked_route

Or, if you're a power user and want any extra options that may exist, you may want to import the internal version like this:

    from bfb_delivery.api.internal import split_chunked_route

Unless you're developing, avoid importing directly from library:

    # Don't do this:
    from bfb_delivery.lib.formatting.sheet_shaping import split_chunked_route

CLI

Try the CLI with this package installed:

$ split_chunked_route --input_path "some/path_to/raw_chunked_sheet.xlsx"

See other options in the help menu:

$ split_chunked_route --help

CLI tools (see docs for more information):

  • split_chunked_route
  • create_manifests
  • combine_route_tables
  • format_combined_routes

Dev

Setting up shared tools

There are some shared dev tools in a Git submodule called shared. See https://github.com/crickets-and-comb/shared. When you first clone this repo, you need to initialize the submodule:

$ git submodule init
$ git submodule update

See https://git-scm.com/book/en/v2/Git-Tools-Submodules

Dev installation

You'll want this package's site-package files to be the source files in this repo so you can test your changes without having to reinstall. We've got some tools for that.

First build and activate the env before installing this package:

$ make build-env
$ conda activate bfb_delivery_py3.12

(Note, you will need Python activated, e.g. via conda base env, for build-env to work, since it uses Python to grab PACKAGE_NAME in the Makefile. You could alternatively just hardcode the name.)

Then, install this package and its dev dependencies:

$ make install

This installs all the dependencies in your conda env site-packages, but the files for this package's installation are now your source files in this repo.

Dev workflow

You can list all the make tools you might want to use:

$ make list-targets

Go check them out in Makefile.

QC and testing

Before pushing commits, you'll usually want to rebuild the env and run all the QC and testing:

$ make clean full

When making smaller commits, you might just want to run some of the smaller commands:

$ make clean format full-qc full-test

CI test run

Before opening a PR or pushing to it, you'll want to run locally the same CI pipeline that GitHub will run (.github/workflows/QC-and-build.yml). This runs on multiple images, so you'll need to install Docker and have it running on your machine: https://www.docker.com/

Once that's installed and running, you can use act. You'll need to install that as well. I develop on a Mac, so I used homebrew to install it (which you'll also need to install: https://brew.sh/):

$ brew install act

Then, run it from the repo directory:

$ make run-act

That will run .github/workflows/QC-and-build.yml and every other action tagged to the pull_request event. Also, since act doesn't work with Mac and Windows architecture, it skips/fails them, but it is a good test of the Linux build.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

bfb_delivery-0.5.2.tar.gz (37.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

bfb_delivery-0.5.2-py3-none-any.whl (42.7 kB view details)

Uploaded Python 3

File details

Details for the file bfb_delivery-0.5.2.tar.gz.

File metadata

  • Download URL: bfb_delivery-0.5.2.tar.gz
  • Upload date:
  • Size: 37.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.12.8

File hashes

Hashes for bfb_delivery-0.5.2.tar.gz
Algorithm Hash digest
SHA256 d049a22e48a62905f7b52b38545035b5404a005170c466a0e70245170e8321a2
MD5 ee55d00887a2b3776e9c53f19fb6fef3
BLAKE2b-256 7834990ecced1e17b80f2eea7bb39c05f85e4c53725a2705695681f7502dca52

See more details on using hashes here.

Provenance

The following attestation bundles were made for bfb_delivery-0.5.2.tar.gz:

Publisher: CI_CD.yml on crickets-and-comb/bfb_delivery

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file bfb_delivery-0.5.2-py3-none-any.whl.

File metadata

  • Download URL: bfb_delivery-0.5.2-py3-none-any.whl
  • Upload date:
  • Size: 42.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.12.8

File hashes

Hashes for bfb_delivery-0.5.2-py3-none-any.whl
Algorithm Hash digest
SHA256 d7813739300e8ef2f5070adbece1f19b6bfa4ee88843c31c069b94481eebaf98
MD5 f98064787adfa5dab233846028fb561f
BLAKE2b-256 38aeede55491c1c82a78f511a7747a7aefd0b7a9c0b5e85f3934600d3085ee0e

See more details on using hashes here.

Provenance

The following attestation bundles were made for bfb_delivery-0.5.2-py3-none-any.whl:

Publisher: CI_CD.yml on crickets-and-comb/bfb_delivery

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page