Streamlining Acquisitions Workflows with WorldShare APIs
Our relatively small library at Westfield State University wanted to streamline our workflows and move from a laborious process with excessive duplication of effort to a more automated solution. The new system, which we are currently rolling out at our institution, uses an Amazon scraper, the Google Sheets API, and several OCLC APIs—including the WorldCat Search API and the (WorldShare Management Services) WMS Acquisitions API—to automate routine tasks that previously had to be done by hand. In this post, I will detail some of the code we built up around OCLC’s APIs to make this happen.
If the selector is on Amazon (where we do the bulk of our acquisitions), they can build and import an Amazon Wish List, import a single item using the Amazon URL, or use an ISBN to import information from WorldCat so that the tool will find the item on Amazon and pull in that information as well. All of this information will be added to the Google sheet at the bottom, including a red Y as a warning if we already own the item.
When the selector is ready to purchase the item, they click the button on the right to create a purchase order in WMS and to send an email to the acquisitions staff to ask them to place a new order. From there, the acquisitions staff completes the ordering and invoicing from within WMS.
To accomplish this, we first developed a set of Python wrappers for OCLC Web Services. These wrappers handle the nuts and bolts of getting and representing information from the APIs, such as knowing the endpoint URLs, HTTP verbs, how to handle authorization, etc. Abstracting out these details allows us to concentrate more on what we want to do and less on how to do it.
For instance, rather than manually finding and constructing a URL each time we want to make a request, our URL manager knows which URL to use with which verb and can construct the query string for us. And, rather than re-typing an authorization flow each time we want to make a request, there is an Auth object that handles keys, HMAC signatures, and so on.
Each of these objects has one piece of the web service puzzle—a design choice known as the single responsibility principle—and together they allow us to use the same pieces for working with different APIs.
We then use these objects to create functions that will fetch or send the relevant data to or from an OCLC API. For instance, to make a new purchase order in the system, we can call a function with the following signature:
create_purchase_order(auth, name, vendor_id, **kwargs)
In this example, auth is an Auth object, name and vendor_id are required fields for creating a purchase order, and kwargs is a catch-all that allows us to fill in other fields as key=value pairs. If successful, this will give us back a PurchaseOrder object that we can interact with much like a regular Python object with a few convenience properties.
>>from oclc_wrappers import create_purchase_order
>>from config import AuthObject # We’ve built an AuthObject and put it in a config file for ease of use
>> po = create_purchase_order(AuthObject, ‘My purchase order’, ‘1a-2b-3c’)
“My purchase order”
“My purchase order”
>>po.number # auto-generated by WMS
This library of wrappers is still very much a work in progress. In particular, only server-side HMAC and WSKey Lite are currently implemented; there is no support for access tokens built in. Additionally, many web services are still completely unimplemented, as the bulk of the work we have been doing has been in the Acquisitions module with brief excursions to the WorldCat Search API.
However, we are beginning the process of open-sourcing the OCLC wrappers and the Amazon scrapers through GitHub, and we would love to see community involvement. This work has already made our workflows much simpler and less error-prone and has reduced our duplication of effort drastically.