<jupyter_start><jupyter_text><NAME> Minuteman Library NetworkThis Python script will allow you to enter/scan item barcodes to gather a list of bib/item details, via the Sierra APIs, without needing to have Sierra running on your device.  The data includes fields that are helpful for shelf reading, weeding and title curation purposes.  The resulting table can then be exported as an Excel or CSV file.Staff in Minuteman Libraries may [watch a short video demoing this tool](https://drive.google.com/file/d/14FX5BtiHhxWgGBdzUSgYfcHGhftK4_Ws). Step 1: Initialize the script Click on the play button (that may only appear when you hover over '[ ]') directly below, next to the text 'Show code'.<jupyter_code>#@title
import requests
import json
from base64 import b64encode
import pandas as pd
from datetime import datetime
from datetime import timedelta
from pandas import json_normalize 
from google.colab import files
from google.colab import data_table
data_table.enable_dataframe_formatter()

column_names = ["barcode","callNumber","title","author","publishYear","location.code","location.name","itemType","status.code","status.display","createdDate","updatedDate","lastCheckoutDate","CheckoutTotal","yearToDateCirc","lastYearCirc","id","bibIds"]
df = pd.DataFrame(columns = column_names)
temp_column_names = ["barcode","id","updatedDate","createdDate","bibIds","callNumber","itemType","location.code","location.name","status.code","status.display","yearToDateCirc","CheckoutTotal","lastYearCirc","lastCheckoutDate"]
bib_column_names = ["id","publishYear","title","author"]

expiration_time = datetime.now() + timedelta(seconds=3600)
# config api    

#enter API credentials
base_url = ''
client_key = ''
client_secret = ''
auth_string = b64encode((client_key + ':' + client_secret).encode('ascii')).decode('utf-8')
header = {}
header["authorization"] = 'Basic ' + auth_string
header["Content-Type"] = 'application/x-www-form-urlencoded'
url = base_url + '/token'
response = requests.post(url, headers=header)
json_response = json.loads(response.text)
token = json_response["access_token"]
s = requests.Session()<jupyter_output><empty_output><jupyter_text>Step 2: Enter barcodesScan/enter a barcode into the form below.  The script will rerun automatically whenever new information is entered into this field.  When a valid barcode is entered it will be added to the table that displays.  If you enter an invalid number an error will display above the table.NOTE: The field will retain the previously entered barcode so you must overwrite it each time you wish to enter a new number.  The simpliest method for this is to double click on the number so it is highlighted, and then enter the new barcode.<jupyter_code>#@title Scan Barcode { run: "auto", display-mode: "form" }

barcode = ''  #@param {type: "string"}
#@markdown ---

barcode = barcode.strip()
def get_token():
  # config api    
  
  #enter API credentials
  base_url = ''
  client_key = ''
  client_secret = ''
  auth_string = b64encode((client_key + ':' + client_secret).encode('ascii')).decode('utf-8')
  header = {}
  header["authorization"] = 'Basic ' + auth_string
  header["Content-Type"] = 'application/x-www-form-urlencoded'
  url = base_url + '/token'
  response = s.post(url, headers=header)
  json_response = json.loads(response.text)
  token = json_response["access_token"]
  return token

if datetime.now() >= expiration_time:
  token = get_token()

if len(barcode) == 14 and barcode.isdigit():

  url = base_url + '/items/query?offset=0&limit=1'
  header = {"Authorization": "Bearer " + token, "Content-Type": "application/json;charset=UTF-8"}
  query = {"queries": [{ "target": { "record": {"type":"item"},"field": {"tag": "b"}},"expr": {"op": "equals","operands": [barcode]}}]}
  item_request = s.post(url, data=json.dumps(query), headers = header)
  item_url = json.loads(item_request.text)

  if item_url['entries'] != []:
    for entry in item_url['entries']:
      temp_df = pd.DataFrame()
      bib_df = pd.DataFrame(columns = bib_column_names)
      r_entry = s.get(url=entry['link'] + '?fields=id,location,status,barcode,bibIds,barcode,createdDate,updatedDate,callNumber,itemType,fixedFields',headers=header, verify=True)
      temp_df = temp_df.append(json_normalize(r_entry.json()))
      bibs = json.loads(r_entry.text)
    
      for entry in bibs['bibIds']:
        bib_entry = s.get(url=base_url + '/bibs/' + entry +'?fields=id,title,author,publishYear',headers=header, verify=True)
        bib_df = bib_df.append(json_normalize(bib_entry.json()))
        #bib_df["id"] = bib_df["id"].astype(str)
      temp_df['bibIds'] = [','.join(map(str, l)) for l in temp_df['bibIds']]
      temp_df = temp_df.rename(columns={'fixedFields.109.value':'yearToDateCirc','fixedFields.110.value':'lastYearCirc','fixedFields.76.value':'CheckoutTotal','fixedFields.78.value':'lastCheckoutDate'})
      temp_df['updatedDate'] = temp_df['updatedDate'].str[:10]
      temp_df['createdDate'] = temp_df['createdDate'].str[:10]
      temp_df['lastCheckoutDate'] = temp_df['lastCheckoutDate'].str[:10]
      #temp_df['status.duedate'] = temp_df['status.duedate'].str[:10]

    merge_df = temp_df[temp_column_names].join(bib_df.set_index(['id']), on=['bibIds'], how='left')
    merge_df['id'] = 'i' + merge_df['id'].astype(str) + 'a'
    merge_df['bibIds'] = 'b' + merge_df['bibIds'].astype(str) + 'a'
    merge_df = merge_df.fillna('')
    df = df.append(merge_df)
  else:
    print("Invalid barcode entered, try again")
    
else:  
  print("Invalid barcode entered, try again")

df<jupyter_output><empty_output><jupyter_text>Step 3: Export Table Run this code block to download a copy of your list to Excel<jupyter_code>#@title
df.to_excel("item_list.xlsx", encoding = 'utf-8-sig', index=False)
files.download('/content/item_list.xlsx')<jupyter_output><empty_output><jupyter_text>Run this code block to download a copy of your list as a csv<jupyter_code>#@title
df.to_csv("item_list.csv", encoding = 'utf-8-sig',index=False)
files.download('/content/item_list.csv')<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.1462248598747115, 'fraction_numerical': 0.007583250906693043, 'mean_word_length': 5.696467991169978, 'pattern_counts': {'":': 11, '<': 18, '<?xml version=': 0, '>': 19, 'https://': 1, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '4', 'dir': 'jupyter-structured-clean-dedup', 'id': '602538', 'license': 'MIT', 'n_tokens_mistral': 2010, 'n_tokens_neox': 1935, 'n_words': 463, 'path': 'Barcode_Scanner.ipynb', 'repo_name': 'Minuteman-Library-Network/Barcode-Scanner', 'size': '6076'}