Files
2026-07-09 14:41:31 -04:00

65 lines
3.5 KiB
Markdown

# Remote Poster
Posts notices to a Polaris ILS database via the Polaris Leap (PAPI) API.
## Setup
1. (Recommended) create and activate a virtual environment, then install dependencies:
```
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
```
On macOS with Homebrew Python you may get an "externally managed environment" error if you
skip the venv and `pip install` directly — the venv avoids that.
2. Copy `.env.example` to `.env` and fill in your server, org/workstation IDs, and staff login.
`.env` is gitignored, so real credentials never get committed.
- `POLARIS_USERNAME` **must** include the domain, e.g. `MYLIB\Aladdin`.
- `POLARIS_ORGANIZATION_ID` should match the `OrganizationID` your staff login actually
belongs to (visible in the `PolarisUser` object returned on successful auth) — it's your
*logged-on* org context, not the list of orgs you're posting notices to.
- `POLARIS_PRODUCT_ID` defaults to `7` (Notices). If calls fail, `19`
(PolarisApplicationServices) is the confirmed working alternative — see Notes below.
## Usage
```
python post_notices.py --notice-type 2 --org-ids 3,4,5,6,7,8
```
- `--notice-type`: the Notification Type ID to post (from your Polaris system tables).
- `--org-ids`: comma-separated Organization IDs to post notices *for* (the branches whose
notices go out) — separate from `POLARIS_ORGANIZATION_ID` in `.env`, which is your login context.
- `--delivery-option`: optional, defaults to `1` (Mail) — currently the only value Polaris accepts.
On success it prints a confirmation. On failure (bad credentials, invalid IDs, etc.) it prints
the error from Polaris and exits non-zero.
Every run sends real notices to real patrons — there's no dry-run mode. Double-check
`--notice-type` and `--org-ids` before running.
## Notes on the API (things the published docs get wrong or omit)
While wiring this up against Osceola's live server, two things in the reference doc
(`docs/polaris-papi-reference.md`) turned out to be incomplete or misleading:
1. **The staff authentication URL is shorter than every other endpoint's.** Most PAPI routes
follow `/api/{version}/{language}/{productId}/{siteDomain}/{organizationId}/{workstationId}/...`,
but `authentication/staffuser` only uses `/api/{version}/{language}/{productId}/authentication/staffuser`
— no `siteDomain`, `organizationId`, or `workstationId`. This makes sense in hindsight (those
three describe a *logged-on* session, and you're not logged on yet when authenticating), but
it isn't spelled out anywhere in the rendered help page — it's only visible as a `title="..."`
tooltip attribute in the raw HTML of
`polaris.applicationservices/help/authentication/post_staffuser`, which a normal page read
(rendered text, or an AI summary of the page) won't surface. `polaris_client.py` builds this
URL separately from every other call (`self.auth_url` vs `self.base_url`).
2. **`productId`**: `19` (PolarisApplicationServices) is confirmed working against the live
server; `7` (Notices) was the doc's best guess but untested — worth trying if `19` ever stops
working, but don't be surprised if it 400s/404s.
If you hit a `404` with an empty response body on any call, that almost always means the URL
path itself doesn't match a route (wrong segment count, wrong product ID, etc.) rather than a
credentials problem — Polaris's own application-level errors come back as JSON with a
`Message`/`ErrorCode`, not an empty body.