A Python script to manage retention commitment transfers between CUNY libraries participating in the Shared Print program.
When a CUNY library can no longer retain a book it committed to keep, this script helps transfer that commitment to another library:
- Looks up the item in Alma using the leaving school's API
- Finds all CUNY schools that hold a copy (via Network Zone)
- Selects a replacement school using these rules:
- Must be a Shared Print participant
- Prefers CUNY Graduate Center if they hold it
- Otherwise picks the largest participating school that holds it
- Flags items for withdrawal review if no other schools hold them
| Phase | Description | Status |
|---|---|---|
| Phase 1 | Barcode lookup and replacement selection | ✅ Complete |
| Phase 2 | Draft email generation | ✅ Complete |
| Phase 3 | Update leaving school's Alma records | ✅ Complete |
| Phase 4 | Update taking school's Alma records | ✅ Complete |
| Phase 5 | Update WorldCat holdings | ✅ Complete |
- Python 3.x
- Alma API keys (Network Zone + Institution Zone keys for participating schools)
# Clone the repository
git clone https://github.com/kristen-fredericksen/cuny-shared-print-retention.git
cd cuny-shared-print-retention
# Create virtual environment
python3 -m venv venv
source venv/bin/activate
# Install dependencies
pip install -r requirements.txt
# Set up configuration
cp .env.example .env
# Edit .env with your API keys-
.envfile - Contains all API keys. See.env.examplefor the full format:- Network Zone key (
ALMA_NZ_API_KEY) - Per-campus keys for each Shared Print school (
ALMA_PROD_{campus}) - Sandbox equivalents if needed (
ALMA_SANDBOX_NZ_API_KEY,ALMA_SANDBOX_{campus})
The campus code is the part after
01CUNY_in the Alma Institution Code — for example,01CUNY_QC→ALMA_PROD_QC. - Network Zone key (
-
data/schools_template.csv- Contains school metadata (no API keys):- Name, Size (1=largest), Shared Print (Yes/No)
- Alma Institution Code, OCLC Symbol, MARC Org Code, Primo View ID
- Chief Librarian Name and Email
- OCLC Collection ID (7-digit data sync collection ID; required for Phase 5 WorldCat CSV generation)
A sample file showing the expected format (with placeholder data) is committed as
schools_sample.csv.
The easiest way to use this tool is through the Streamlit web app:
Option A — Double-click to launch:
- Open Finder, navigate to the
library-retentionfolder - Double-click
run_app.command - The app will open in your browser automatically
Option B — Launch from terminal:
Important: You must
cdinto the project folder first, or the app won't find its files.
cd /Users/kristenfredericksen/Library/CloudStorage/OneDrive-CUNY/agentic-projects/library-retention
source venv/bin/activate
streamlit run src/app.pyThe app has two tabs matching the two-step workflow:
- Step 1 — Lookup: Upload your barcodes Excel file, view results, and download draft emails
- Step 2 — Update: Upload the pending JSON from Step 1, record yes/no/skip for each school, and apply Alma + WorldCat updates
You can also run the script directly from the terminal.
Create an Excel file with two columns:
| Barcode | School Code |
|---|---|
| 31699001195116 | 01CUNY_JJ |
| 31228005903455 | 01CUNY_BC |
- Barcode: The item's barcode
- School Code: The Alma Institution Code of the school leaving retention
Every time you open a new terminal,
cdto the project folder and activate the virtual environment:cd /Users/kristenfredericksen/Library/CloudStorage/OneDrive-CUNY/agentic-projects/library-retention source venv/bin/activateYou'll see
(venv)at the start of your prompt when it's active.
# Sandbox mode (safe for testing)
python3 src/retention_transfer.py data/your_barcodes.xlsx --sandbox
# Production mode
python3 src/retention_transfer.py data/your_barcodes.xlsx
# Specify a custom output directory for .eml files
python3 src/retention_transfer.py data/your_barcodes.xlsx output/emails --sandboxShortcut: If you set up the retention shell alias (see below), just type retention instead of the cd and source commands.
The script will:
-
Display a summary of items:
- Items with recommended replacement schools
- Items flagged for withdrawal review (no other schools hold them)
- Items ineligible due to status (not "Item in place")
- Barcodes not found in Alma
-
Generate
.emlfiles for each replacement school:- Saved to
output/emails/by default - Double-click to open in Outlook as a draft message
- Includes school-specific Primo VE links for each title
- Batches multiple titles per school into one email
- Saved to
-
Generate WorldCat update files (Phase 5):
- Taking school CSV — saved to
output/worldcat/taking/- OCLC Full Format Shared Print file (14 columns)
- Filename:
<collectionID>.<OCLCsymbol>.sharedprint_retention_transfer_<YYYYMMDD>.csv - Upload via: WorldShare Metadata > My Files > Uploads > file type "Data sync LHR"
- Only generated for schools with an OCLC Collection ID in the schools CSV
- Leaving school instructions — saved to
output/worldcat/leaving/- Lists all records that need retention commitments removed
- Includes OCLC numbers, barcodes, and step-by-step removal instructions
- Taking school CSV — saved to
When updating records, the following changes will be made:
For the LEAVING school:
- Alma holdings record: Remove 583 field
- Alma item record: Set "Committed to Retain" to "No"
- Alma item record: Clear "Retention Reason"
- WorldCat LHR: Remove 583 field
For the TAKING school:
- Alma holdings record: Add 583 field
- Alma item record: Set "Committed to Retain" to "Yes"
- Alma item record: Set "Retention Reason" to "CUNY Shared Print"
- WorldCat LHR: Add 583 field
To avoid typing the full cd and source commands every time, you can add a shortcut to your terminal. Run this once:
echo 'alias retention="cd /Users/kristenfredericksen/Library/CloudStorage/OneDrive-CUNY/agentic-projects/library-retention && source venv/bin/activate"' >> ~/.zshrc && source ~/.zshrcAfter that, just type retention in any terminal window to navigate to the project and activate the virtual environment.
The following files contain sensitive data and are excluded from git:
.env(API keys)data/folder (school information including librarian contacts, and barcode files)
schools_sample.csv (project root) is committed as a format reference with placeholder data.
Internal CUNY use only.