Flask-Z3950

Z39.50 integration for Flask applications.

Installation

Install the required development packages:

$ sudo apt-get install libxml2-dev libxslt-dev python-dev lib32z1-dev

Now, install Flask-Z3950:

$ pip install Flask-Z3950

Quickstart

To set up a Z39.50 gateway you can do this:

from flask import Flask
from flask.ext.z3950 import Z3950Manager

app = Flask(__name__)
db_config = {"db": "Voyager", "host": "z3950.loc.gov", "port": 7090}
app.config["Z3950_DATABASES"] = {"loc": db_config}

z3950_manager = Z3950Manager(app)
z3950_manager.register_blueprint(url_prefix='/z3950')

You can now search multiple databases and retrieve records in a variety of formats. For example, the following query will return all records in the Library of Congress database with the title “1066 and all that”, as JSON:

http://{your-base-url}/z3950/search/loc/json?query=(ti=1066 and all that)

Note

See the HTTP API documentation for further details.

If you decide you don’t want to make use of the pre-defined view functions, simply don’t register the blueprint. You can still retrieve and perform searches with your configured databases, like so:

z3950_db = z3950_manager.databases['loc']
dataset = z3950_db.search('ti=1066 and all that')

print dataset.to_str()

Configuration

The following configuration settings exist for Flask-Z3950:

Z3950_DATABASES

A dictionary containing Z39.50 database configuration details, where keys are database identifiers and values are nested dictionaries containing configuration details for that database.

Each nested dictionary is used to initialise a new Z3950Database, so the nested dictionary keys should be named the same as the parameters used to initialise that class.

Query Syntax

The default query syntax is CCL but a number of alternative syntaxes are provided, each with different complexities. Documentation for the most common of these syntaxes can be found below:

  • CCL: ISO 8777
  • CQL: The Common Query Language
  • PQF: Index Data’s Prefix Query Format
  • C2: Cheshire II query syntax

Building a CCL query

Many Z39.50 databases report their configurations in terms of attributes and use values. So, while there are lots of valid ways to build a CCL query, below is the style that I find the most effective.

The basic syntax for a query string is:

'(attribute, value)="item"'

Multiple attributes can be joined by using a comma:

'(attribute, value),(attribute, value)="item"'

Multiple fields can be searched by using logical operators:

'(attribute, value)="item"and(attribute, value)="item"'

Logical operators can also be used while searching within a particular field:

'(attribute, value)="item or another_item"'

Example

Taking the British Library’s Z39.50 configuration as an example, the following query would print the result of searching the library’s database for the ISBN number 188012422X.

# Assumes z3950_db is a configured Z3950Database object
query = '(1,7)="188012422X"'
print z3950_db.search(query)

Note

Implementations can vary greatly so refer to the documentation for your chosen database for a list of accepted attributes.

Transforming MARC records

If raw MARC data is returned from a database search it can be transformed into a variety of different formats, such as MARCXML, JSON and HTML. For more details, see the API documentation for Dataset.

HTTP API

Search Errors

GET /search/(db)/json

Query db and return the results as JSON.

Example request:

GET /search/loc/json?query= HTTP/1.1

Example response:

HTTP/1.1 400 BAD REQUEST
Content-Type: application/json

{
    "data": null,
    "message": "The \"query\" parameter is missing",
    "status": "error"
}
GET /search/(db)/marcxml

Query db and return the results as MARCXML.

Example request:

GET /search/loc/marcxml?query= HTTP/1.1

Example response:

HTTP/1.1 400 BAD REQUEST
Content-Type: application/xml

<?xml version="1.0" encoding="utf-8"?>
<errors>
  <error>The "query" parameter is missing</error>
</errors>

Note

If an error occurs while sending a request to the HTML or RAW data endpoints the request is aborted with a 400 or 500 status code (depending on the cause of the error).

Configuration

GET /databases

List all currently available databases as JSON.

Example request:

GET /databases HTTP/1.1

Example response:

HTTP/1.1 200 OK
Content-Type: application/json

{
    "status": "success",
    "message": "Databases available: 1",
    "data": {
        "db": {
            "host": "somehost",
            "elem_set_name": "F",
            "db": "somedb",
            "port": 123,
            "syntax": "USMARC"
        }
    }
}

Changelog

Here is a list of noteable changes between each Flask-Z3950 release.

Version 0.3.1

Released August 11th, 2016

  • Fix init_app instantiation bug.

Version 0.3.0

Released August 8th, 2016

  • Add view function for listing available databases.

Version 0.2.5

Released May 19th, 2016

  • Fix setup.py test integration

Version 0.2.4

Released May 5th, 2016

  • Bundle non-Python files in PyPi package.

Version 0.2.3

Released May 5th, 2016

  • Fix HTML pagination
  • Catch UnicodeDecodeError
  • PEP8 fixes

Version 0.2.2

Released February 1st, 2016

  • Fix HTML and MARCXML transformations.

Version 0.2.1

Released January 21th, 2016

  • Replace broken PyPi requirement.

Version 0.2.0

Released January 21th, 2016

  • Add default search view functions.
  • Add metadata to datasets.
  • Fix inconsistencies in setup.

Version 0.1.1

Released on January 17th, 2016

  • Initial public release.