Skip to content
University of Maryland
CTRL K
    GitHub Atom Feed
    Give Now

    Library Website Tools

    The UMD Libraries provides APIs to access information about physical spaces and hours.

    Libtools REST API

    The Libtools API provides access to information about Libraries’ spaces and hours. It is a RESTful API that returns JSON data.

    Endpoint: https://api.www.lib.umd.edu/api/libtools/

    Find the documentation here with examples: https://api.www.lib.umd.edu/api/libtools/docs

    Example: website-libtools-hours.py

    website-libtools-hours.py
    #!/usr/bin/env -S uv run --script
    # /// script
    # requires-python = ">=3.12"
    # dependencies = []
    # ///
    
    import urllib.request
    import json
    import socket
    import ssl
    import sys
    from urllib.error import HTTPError, URLError
    
    # Retrieve McKeldin hours from libtools search
    
    BASE = 'https://api.www.lib.umd.edu/api/libtools/'
    ENDPOINT = 'mckeldin/hours/today'
    
    # A host name that does not resolve, or a certificate that will not verify,
    # is a settled fact about the URL rather than a passing condition: it means
    # this example is pointed somewhere that no longer answers for it. Every other
    # connection failure -- refused, reset, timed out -- may succeed on a retry.
    PERMANENT_FAILURES = (socket.gaierror, ssl.SSLCertVerificationError)
    
    hours_url = BASE + ENDPOINT
    
    # Get search results as parsed JSON
    try:
        with urllib.request.urlopen(hours_url) as request:
            response = json.loads(request.read())
    except HTTPError as error:
        print(f'{hours_url} returned HTTP {error.code}: {error.reason}', file=sys.stderr)
        # 75 = EX_TEMPFAIL: the service is reachable but cannot serve right now.
        # A 4xx means this request is no longer valid, which is this example's problem.
        sys.exit(75 if error.code >= 500 or error.code == 429 else 1)
    except URLError as error:
        # Nothing answered, so the request was never judged. What stopped it
        # decides whose problem it is.
        print(f'Could not reach {hours_url}: {error.reason}', file=sys.stderr)
        sys.exit(1 if isinstance(error.reason, PERMANENT_FAILURES) else 75)
    except json.JSONDecodeError:
        print(f'{hours_url} did not return JSON', file=sys.stderr)
        # A body that is not JSON means the API changed under this example.
        sys.exit(1)
    
    status = response['status']
    
    print('----')
    print(f'McKeldin Hours: {status}')
    

    Run this example with uv — no download or setup required:

    uv run https://opendata.lib.umd.edu/code/website-libtools-hours.py