Build, Optimize, and Distribute Circuit Routes from Chunked Routes Sheet

Once you have a large single-route sheet labeled by driver, representing individual driver routes, you need to upload them to Circuit, optimized them, distribute them to driver apps, and produce driver manifests ready to print, with headers, aggregate data, and color-coded box types. You can do this all at once with the build_routes_from_chunked tool.

This tool replaces the manual tasks of:

  • Splitting the single route grouped by driver into individual Excel worksheets for each driver, grouped into a handful of workbooks for each staff member to upload to Circuit.

  • Uploading to Circuit, mapping fields and routes to drivers, optimizing routes, and distributing them to driver apps.

  • Downloading the optimized routes, copying each route into a single workbook, running an Excel macro, and finishing up with some manual steps.

Important

Before using this tool, you need to log in to Circuit and activate the drivers you want to assign routes to.

Python API documentation at bfb_delivery.api.public.build_routes_from_chunked().

CLI documentation at CLI.

Usage

You call build_routes_from_chunked with the input_path of the chunked spreadsheet, along with any other optional arguments. It will then prompt you to confirm driver assignments to each route. The tool then runs for up to a minute per route and finally prints the filepath to the final manifest.

In Python:

from bfb_delivery import build_routes_from_chunked

build_routes_from_chunked(input_path="path/to/master_chunked_sheet.xlsx")

With CLI:

build_routes_from_chunked --input_path "path/to/master_chunked_sheet.xlsx"

The function will return the filepath to the final manifest. If you’re using the CLI, the filepath will print to the console.

Note

This takes up to a minute per route to run as it uploads the routes to Circuit, optimizes them, and downloads the optimized routes. So, for a typical number of routes, it will take about 30 minutes.

Examining output

Below is an example with three routes (usually about 40-50 routes). The tool will prompt you to assign drivers to each route, e.g. “Enter the number of the driver for ‘02.14 Eric’(ctl+c to start over):”. You use the driver numbers printed to the console to assign drivers to each route, 48 in this example (see input below). The tool will then run for up to a minute per route and finish successfully by printing the filepath to the final manifest.

Note

Notice how the driver status is printed with the driver. The tool will not allow you to assign an inactive driver to a route, re-prompting you if you do enter an inactive driver. If you need to assign an inactive driver, you will need to activate them in Circuit first.

(bfb_delivery_py3.12) MacBook-Pro:bfb_delivery me$ build_routes_from_chunked --input_path .test_data/scratch/test_master_chunked_sample.xlsx --output_dir .test_data/scratch/
2025-02-12 17:49:38,585 - INFO - Writing split chunked workbooks to /Users/me/repos/bfb_delivery/.test_data/scratch/split_chunked
2025-02-12 17:49:38,620 - INFO - Getting all drivers from Circuit ...
2025-02-12 17:49:39,568 - INFO - Finished getting drivers.
1. Active: Hank Hill hank@propane.com
... (more drivers) ...
84. Active: Nosferatu pinebox@bfb.com

Using the driver numbers above, assign drivers to each route:

Route 02.14 Eric:
Best guesses:
48. Active: Eric Cartman emoney@southpark.com


Enter the number of the driver for '02.14 Eric'(ctl+c to start over):48

Assigned 02.14 Eric to Eric Cartman.

Route 02.14 Hank:
Best guesses:
1. Active: Hank Hill hank@propane.com
23. Inactive: Hankie Who hankie@realtalk.com


Enter the number of the driver for '02.14 Hank'(ctl+c to start over):1

Assigned 02.14 Hank to Hank Hill.

Route 02.14 Nos:
Best guesses:
84. Active: Nosferatu pinebox@bfb.com


Enter the number of the driver for '02.14 Nos'(ctl+c to start over):84

Assigned 02.14 Nos to Nosferatu.
02.14 Eric: Eric Cartman, emoney@southpark.com
02.14 Hank: Hank Hill, hank@propane.com
02.14 Nos: Nosferatu pinebox@bfb.com
Confirm the drivers above? (y/n): y
2025-02-12 17:50:16,179 - INFO - Initializing plans ...
2025-02-12 17:50:18,067 - INFO - Finished initializing plans. Initialized 3 plans.
2025-02-12 17:50:18,126 - INFO - Uploading stops. Allow 6+ seconds per plan ...
2025-02-12 17:50:44,995 - INFO - Finished uploading stops. Uploaded 50 stops for 3 plans.
2025-02-12 17:50:45,023 - INFO - Initializing route optimizations. Allow 20+ seconds per plan ...
2025-02-12 17:51:49,759 - INFO - Finished initializing route optimizations for 3 plans.
2025-02-12 17:51:49,782 - INFO - Confirming optimizations have finished ...
2025-02-12 17:51:50,980 - INFO - Finished optimizing routes. Optimized 3 routes.
2025-02-12 17:51:51,019 - INFO - Distributing routes ...
2025-02-12 17:51:53,200 - INFO - Finished distributing routes for 3 plans.
2025-02-12 17:51:53,222 - INFO -
    route_title  initialized  writable  stops_uploaded optimized  distributed
0  02.14 Eric             True      True            True      True         True
1  02.14 Hank             True      True            True      True         True
2  02.14 Nos              True      True            True      True         True

Plans attempted: 3
Plans initialized: 3
Plans with stops: 3
Plans optimized: 3
Plans distributed: 3
2025-02-12 17:51:53,231 - INFO - Getting route plans from Circuit ...
2025-02-12 17:51:53,692 - INFO - Finished getting route plans.
2025-02-12 17:51:53,711 - INFO - Getting stops from Circuit ...
2025-02-12 17:51:57,597 - INFO - Finished getting stops.
2025-02-12 17:51:57,629 - WARNING - Missing neighborhood for 50 stops. Imputing best guesses from Circuit-supplied address.
2025-02-12 17:51:57,655 - WARNING - Output directory exists /Users/me/repos/bfb_delivery/.test_data/scratch/routes_2025-02-14. Overwriting.
2025-02-12 17:51:57,655 - INFO - Writing route CSVs to /Users/me/repos/bfb_delivery/.test_data/scratch/routes_2025-02-14
2025-02-12 17:51:57,676 - INFO - Writing combined routes to /Users/me/repos/bfb_delivery/.test_data/scratch/combined_routes_20250212.xlsx
2025-02-12 17:51:57,711 - INFO - Writing formatted routes to /Users/me/repos/bfb_delivery/.test_data/scratch/final_manifests_20250212.xlsx
2025-02-12 17:51:57,715 - INFO - Formatted workbook saved to:
/Users/me/repos/bfb_delivery/.test_data/scratch/final_manifests_20250212.xlsx
(bfb_delivery_py3.12) MacBook-Pro:bfb_delivery me$

Attention

Pay attention to the output, especially in the middle once optimization/distribution is complete. There’s a summary of the number of plans attempted, initialized, with stops, optimized, and distributed. Just above that is a table of the routes and their statuses, True indicating success for a route at a given step, False indicating failure. You can also find the table as a CSV file in a subdirectory of the output directory, {output_dir}/plans/plans.csv. If any of the routes are not successul at a step, the tool will warn you and skip them on all following steps. You will want to investigate why and run that route the rest of the way from the last successful step, manually or with the underlying tools (see Note on tools this tool wraps below).

Note that the filepaths to some intermediate files will print to the console as well, before finally printing the filepath to the final manifest workbook. In addition to the final manifest, there will be:

  • An Excel workbook of the pre-optmized routes split into separate spreadsheets that you could upload manually. In the example: 2025-02-12 17:49:38,585 - INFO - Writing split chunked workbooks to /Users/me/repos/bfb_delivery/.test_data/scratch/split_chunked

  • Optmized route CSVs downloaded from Circuit that you could combine into a single Excel workbook. In the example: 2025-02-12 17:51:57,655 - INFO - Writing route CSVs to /Users/me/repos/bfb_delivery/.test_data/scratch/routes_2025-02-14

  • An unformatted Excel workbook of all the routes that you could run the old macro on to produce the final manifests. In the example: 2025-02-12 17:51:57,676 - INFO - Writing combined routes to /Users/me/repos/bfb_delivery/.test_data/scratch/combined_routes_20250212.xlsx

This can be helpful if you need to revert to the old method for one of the steps for some reason.

Reviewing final manifests

You should review the manifests before printing them, as you may want to make some final touchups, like adjusting row heights or column widths, or adding notes. These final touchups are slated to be added to the tool in the future.

Optional arguments

You can use optional arguments to specify a few things about the manifest workbook. Use –help to see all the optional arguments in the CLI.

build_routes_from_chunked --help

Output directory

Use the optional argument output_dir to specify the directory to save the workbook file in. The default if not passed is a new directory in the present working directory, named “deliveries_{date}”.

In Python:

build_routes_from_chunked(
    input_path="path/to/master_chunked_sheet.xlsx",
    output_dir="path/to/output_dir/",
)

With CLI:

build_routes_from_chunked --input_path "path/to/master_chunked_sheet.xlsx" --output_dir "path/to/output_dir/"

Start date

Use the optional argument start_date to specify the beginning of the date range to search Circuit for routes. The default if not passed in is the soonest Friday.

from bfb_delivery import build_routes_from_chunked

build_routes_from_chunked(
    input_path="path/to/master_chunked_sheet.xlsx",
    start_date="1947-10-14",
)

With CLI:

build_routes_from_chunked --input_path "path/to/master_chunked_sheet.xlsx" --start_date 1957-10-04

Skip distribution

By default, the tool will distribute the routes to the driver apps. Use the optional argument no_distribute to skip this.

In Python:

build_routes_from_chunked(
    input_path="path/to/master_chunked_sheet.xlsx",
    no_distribute=True,
)

With CLI:

build_routes_from_chunked --input_path "path/to/master_chunked_sheet.xlsx" --no_distribute

Verbose output

Use the optional argument verbose to print more information to the console. This can be useful for debugging, but it is pretty noisy.

In Python:

build_routes_from_chunked(
    input_path="path/to/master_chunked_sheet.xlsx",
    verbose=True,
)

With CLI:

build_routes_from_chunked --input_path "path/to/master_chunked_sheet.xlsx" --verbose

Supplying extra notes

Use the optional argument extra_notes_file to specify a CSV file with extra notes to include in the manifest. The CSV file should have two columns: tag and note. The tag is the text (usually asterisked) that appears in the standard notes field for a delivery. The note is then added to the bottom of the manifest with the tag. For example:

tag,note
Cedarwood Apartments special instructions *,Please call the recipient when you arrive.

This file will put the note “Please call the recipient when you arrive.” at the bottom of the manifest (once) if any stops have a note that contains the text “Cedarwood Apartments special instructions *”.

If you don’t provide extra_notes_file provide, the tool will use the constant notes in the codebase: bfb_delivery.lib.constants.ExtraNotes (currently empty).

In Python:

build_routes_from_chunked(
    input_path="path/to/master_chunked_sheet.xlsx",
    extra_notes_file="path/to/extra_notes.csv",
)

With CLI:

build_routes_from_chunked --input_path "path/to/master_chunked_sheet.xlsx" --extra_notes_file path/to/extra_notes.csv

Note on tools this tool wraps

build_routes_from_chunked wraps other tools that run each segment of the pipeline. First it runs split_chunked_route to split the master chunked sheet into spreadsheets for each route in a single workbook before uploading. It then runs create_manifests_from_circuit, so you don’t have to download and move files around and format them. create_manifests_from_circuit actually wraps create_manifests, which in turn wraps two other tools, combine_route_tables and format_combined_routes into one tool. You can still use any of those tools if you wish, but you can instead just use build_routes_from_chunked. Calling these intermediate tools from build_routes_from_chunked wasn’t necessary, but it was convenient to develop that way and has the added benefit of producing intermediate files at each step that you can use if you need to revert to the old method for some of the steps for some reason (say there was an error in one of the route optimizations and you want to retry it without running all of them again).

        graph TD;
    A[**build_routes_from_chunked**] --> B[**split_chunked_route**]
    B --> B1[Splits master chunked sheet into individual driver route sheets.]
    A --> C[Uploads routes to Circuit, optimizes, and distributes to drivers.]
    A --> D[**create_manifests_from_circuit**]
    D --> E[Gets routes from Circuit.]
    D --> F[**create_manifests**]
    F --> G[**combine_route_tables**]
    F --> H[**format_combined_routes**]
    G --> G1[Combines downloaded routes CSVs into a single workbook.]
    H --> H1[Formats the combined routes into printable manifests.]
    

Subtools wrapped and alternatively available for use

For instance, say you’ve found a bug when using build_routes_from_chunked where the routes uploaded and optimized but for some reason didn’t produce the final printable manifest. You could try downloading the routes manually then running create_manifests, or downloading manually then running combine_route_tables and passing its output to format_combined_routes. For whichever of those steps fails, you can revert to using your old method, but you can still ostensibly use a tool for the other piece that didn’t fail. For example, say combine_route_tables ran fine, but format_combined_routes threw an error, so you reverted to using the old Excel macro and manually formatting. See Split Chunked Route Sheet into Multiple Files, Create Printable Manifests from Optimized Routes from Circuit, Create Printable Manifests from Downloaded Optimized Routes, Combine Driver Route Tables into a Single Workbook and Format Manifests.

Most likely you’ll find that the tool works fine unless the underlying data schemata have changed, but it’s good to know you have options to explore instead of doing it all manually again.

See Also

The Delivery-Planning Workflow

Split Chunked Route Sheet into Multiple Files

Create Printable Manifests from Optimized Routes from Circuit

Create Printable Manifests from Downloaded Optimized Routes

Combine Driver Route Tables into a Single Workbook

Format Manifests

CLI

bfb_delivery.api package