crossrefapi Python Library

repository·master·Indexed 43 days ago

https://github.com/fabiobatalha/crossrefapi

A Python library for interacting with the Crossref REST API, version 1.7.0. It provides high-level abstractions for querying and filtering metadata for works, journals, funders, and members. Key features include DOI retrieval via the Works class, faceting, pagination using cursors, and a Depositor class for submitting Digital Object Metadata via the doMDUpload operation. Includes an Etiquette class to configure custom User-Agent headers for polite API usage.

Tokens
5.1K
Snippets
25
Records
43
Agent score
6%

What's inside crossrefapi

  1. Deposit Metadata to Crossref using Depositor

    master

    The library implements the doMDUpload operation, allowing you to submit Digital Object Metadata to Crossref.

    Prerequisites:

    1. An active publisher account with crossref.org.
    2. A valid XML file following the Crossref DTD.

    Workflow:

    1. Initialize a Depositor instance with your prefix, Crossref username, and password.
    2. Use register_doi to submit your XML metadata. Note that this initiates a request; it does not guarantee immediate registration.
    3. Use request_doi_status_by_filename to poll for the status of your submission until a success or error status is retrieved.
    from crossref.restful import Depositor
    
    # Load your XML
    request_xml = open('path/to/your_metadata.xml', 'r').read()
    
    # Initialize depositor
    depositor = Depositor('your prefix', 'your crossref user', 'your crossref password')
    
    # Submit the request
    response = depositor.register_doi('your_batch_id', request_xml)
    
    # Check status
    status_response = depositor.request_doi_status_by_filename('your_batch_id.xml')
    print(status_response.text)
  2. Configure polite requests using Etiquette

    master

    To follow Crossref API etiquette, create an Etiquette object and pass it to the endpoint class (e.g., Works). This sets a custom User-Agent header that identifies your project, version, URL, and contact email, which is recommended for responsible API usage.

    from crossref.restful import Works, Etiquette
    
    # Define your project identity
    my_etiquette = Etiquette(
        'My Project Name', 
        'My Project version', 
        'My Project URL', 
        'My contact email'
    )
    
    # Pass etiquette to the client
    works = Works(etiquette=my_etiquette)
    
    # Use the client as normal
    for i in works.sample(5).select('DOI'):
        print(i)
  3. Configure API Etiquette for Polite Requests

    master

    To follow Crossref's best practices (etiquette), you can provide metadata about your application. This information is sent in the User-Agent header, which helps Crossref identify your requests and contact you if necessary. This is highly recommended for stable and polite API usage.

    from crossref import Etiquette
    
    etiquette = Etiquette(
        application_name="my_research_app",
        application_version="1.0.0",
        application_url="https://example.com",
        contact_email="dev@example.com"
    )
    # Pass this etiquette object when initializing your API client
  4. Filter queries in endpoint methods

    master

    When using methods that support filtering (like query or filter on certain endpoints), you can refine results using keyword arguments.

    Important: Parameter Naming Convention Because Crossref API filter names may contain special characters, you must transform them for Python keyword arguments:

    • Replace dots (.) with double underscores (__)
    • Replace dashes (-) with single underscores (_)

    Example: A filter named has-public-references must be passed as has_public_references=True.

  5. Check DOI registration status with request_doi_status_by_filename

    master

    The request_doi_status_by_filename method allows you to monitor the progress of a submitted XML batch. You can control the type of data returned using the data_type parameter.

    Available data_type options:

    • result (default behavior): Retrieves the status of the DOI registering process (e.g., queued, completed).
    • contents: Retrieves the submitted XML content that was used during the request.

    Status Monitoring: You should parse the returned XML response to check the status attribute in the <doi_batch_diagnostic> element. Continue polling until you reach a terminal state (like completed).

    # To get the registration status (e.g., queued, completed)
    response = depositor.request_doi_status_by_filename('testing_20171011.xml', data_type='result')
    
    # To retrieve the original XML content submitted
    response = depositor.request_doi_status_by_filename('testing_20171011.xml', data_type='contents')
  6. Initialize Depositor with Etiquette

    master

    To follow Crossref's polite request guidelines (Etiquette), you can pass an Etiquette object when initializing the Depositor. This identifies your project and provides contact information to Crossref.

    Required fields for Etiquette:

    • Project Name
    • Project Version
    • Project URL
    • Contact Email
    from crossref.restful import Depositor, Etiquette
    
    etiquette = Etiquette('My Project Name', 'My Project version', 'My Project URL', 'My contact email')
    depositor = Depositor('your prefix', 'your crossref user', 'your crossref password', etiquette)
  7. Filter and select results with Works.filter() and Works.select()

    master

    You can chain .filter() and .select() methods to refine your search results.

    • Filtering: Use Works.FILTER_VALIDATOR to find valid parameters. When using parameters in Python, replace dots (.) with double underscores (__) and hyphens (-) with underscores (_).
    • Selecting: Use Works.FIELDS_SELECT to specify which fields to return. You can pass a single string or a list of strings.
    from crossref.restful import Works
    
    works = Works()
    
    # Filter by license URL and publication year, take a sample, and select only the 'title' field
    for i in works.filter(license__url='https://creativecommons.org/licenses/by', from_pub_date='2016').sample(5).select('title'):
        print(i)
    
    # Selecting multiple specific fields
    for i in works.filter(has_funder='true', has_license='true').sample(5).select(['DOI', 'prefix']):
        print(i)
  8. Count query results with .count()

    master

    The .count() method returns the total number of items a query result should retrieve (the total-results attribute from the API). It does not iterate through or fetch the actual documents, making it a lightweight way to check result sizes.

    from crossref.restful import Works
    
    works = Works()
    # Count total works matching a query
    count = works.query('zika').count()
    
    # Count works matching a query and a filter
    filtered_count = works.query('zika').filter(from_online_pub_date='2017').count()
  9. Perform faceting with Works.facet() and Prefixes.facet()

    master

    Faceting allows you to see the distribution of values for a specific field (like issn) within a result set.

    • Works.facet(field, limit): Returns facets for the entire Crossref database.
    • Prefixes.works(prefix).facet(field, limit): Returns facets for works belonging to a specific DOI prefix.
    • Prefixes.works(prefix).query(term).facet(field, limit): Returns facets for works matching a query within a specific prefix.
    from crossref.restful import Works, Prefixes
    
    # Global facet
    works = Works()
    print(works.facet('issn', 10))
    
    # Facet within a specific prefix
    prefixes = Prefixes()
    print(prefixes.works('10.1590').facet('issn', 10))
    
    # Facet within a query inside a specific prefix
    print(prefixes.works('10.1590').query('zika').facet('issn', 10))
  10. Inspect the generated API URL with .url

    master

    The .url method returns the exact URL that will be used to query the Crossref API. This is useful for debugging complex queries involving .query(), .filter(), .sort(), and .order().

    from crossref.restful import Works
    
    works = Works()
    # Inspect a complex URL construction
    url = works.query('zika').filter(from_online_pub_date='2017').query(author='Mari').sort('published').order('asc').url
    print(url)