### Install habanero using uv Source: https://github.com/sckott/habanero/blob/main/README.rst Install the habanero library using the uv package manager, with examples for both legacy and pyproject.toml project setups. ```console uv pip install habanero # uv w/ pyproject.toml uv add habanero ``` -------------------------------- ### Install habanero using pip Source: https://github.com/sckott/habanero/blob/main/README.rst Install the stable version of the habanero library using pip. ```console pip install habanero ``` -------------------------------- ### Install habanero with Bibtex Support Source: https://github.com/sckott/habanero/blob/main/docs/intro/install.md Install habanero with the bibtex extra for citation formatting using content negotiation. ```console pip install habanero[bibtex] ``` -------------------------------- ### Install habanero Development Version Source: https://github.com/sckott/habanero/blob/main/docs/intro/install.md Install the latest development version of habanero directly from its GitHub repository. ```console pip install git+https://github.com/sckott/habanero.git#egg=habanero ``` -------------------------------- ### Install habanero Stable Release Source: https://github.com/sckott/habanero/blob/main/docs/intro/install.md Install the latest stable version of habanero using pip or uv. ```console pip install habanero ``` ```console uv pip install habanero ``` ```console uv add habanero ``` -------------------------------- ### Content negotiation for citations Source: https://github.com/sckott/habanero/blob/main/README.rst Use the `cn` module for content negotiation to get citations in various formats. Examples show fetching in default format, citeproc-json, rdf-xml, text, and bibentry. ```python from habanero import cn cn.content_negotiation(ids = '10.1126/science.169.3946.635') cn.content_negotiation(ids = '10.1126/science.169.3946.635', format = "citeproc-json") cn.content_negotiation(ids = "10.1126/science.169.3946.635", format = "rdf-xml") cn.content_negotiation(ids = "10.1126/science.169.3946.635", format = "text") cn.content_negotiation(ids = "10.1126/science.169.3946.635", format = "text", style = "apa") cn.content_negotiation(ids = "10.1126/science.169.3946.635", format = "bibentry") ``` -------------------------------- ### Crossref Client Initialization Source: https://github.com/sckott/habanero/blob/main/README.rst Initialize the Crossref client to start making API requests. ```APIDOC ## Initialize Client ### Description Instantiate the `Crossref` client to interact with the Crossref API. ### Code Example ```python from habanero import Crossref cr = Crossref() ``` ``` -------------------------------- ### Get Crossref Filter Names and Details Source: https://github.com/sckott/habanero/blob/main/docs/modules/filters.md Use this snippet to retrieve available filter names and their details from the Crossref API. Ensure the 'habanero' library is installed. ```python from habanero import Crossref cr = Crossref() cr.filter_names() cr.filter_details() ``` -------------------------------- ### Look Up DOI Prefixes Source: https://context7.com/sckott/habanero/llms.txt Query the /prefixes route to retrieve metadata about DOI prefixes or list their registered works. This example shows basic instantiation. ```python from habanero import Crossref cr = Crossref(mailto="you@example.com") ``` -------------------------------- ### Fetch Crossref members and their works Source: https://github.com/sckott/habanero/blob/main/README.rst Retrieve information about a specific Crossref member by their ID and optionally fetch their associated works. The example uses Member ID 98 for Hindawi. ```python # ids here is the Crossref Member ID; 98 = Hindawi cr.members(ids = 98, works = True) ``` -------------------------------- ### Load Habanero Library Source: https://github.com/sckott/habanero/blob/main/docs/docs/usecases.md Import and initialize the Crossref client. This is the first step for any interaction with the Crossref API. ```python from habanero import Crossref cr = Crossref() ``` -------------------------------- ### Instantiate the Crossref Client Source: https://context7.com/sckott/habanero/llms.txt Instantiate the main Crossref client. Optional parameters include base_url, api_key, mailto (for polite pool access), ua_string (custom user-agent), and timeout. Setting mailto is recommended for better rate-limit behavior. ```python from habanero import Crossref # Minimal – uses https://api.crossref.org, 5-second timeout cr = Crossref() # Polite pool + custom user-agent + longer timeout cr = Crossref( mailto="researcher@university.edu", ua_string="MyResearchTool/1.0", timeout=30, ) print(cr) # < Crossref # URL: https://api.crossref.org # KEY: None # MAILTO: researcher@university.edu # ADDITIONAL UA STRING: MyResearchTool/1.0 # Timeout: 30 # > ``` -------------------------------- ### Citation Counts Source: https://github.com/sckott/habanero/blob/main/README.rst Get the citation count for a given DOI. ```APIDOC ## Citation Counts ### Description Retrieve the citation count for a specific Digital Object Identifier (DOI). ### Module `habanero.counts` ### Method `citation_count(doi: str)` ### Parameters - **doi** (str) - Required - The DOI for which to get the citation count. ### Request Example ```python from habanero import counts citation_data = counts.citation_count(doi = "10.1016/j.fbr.2012.01.001") ``` ### Response Example (Success) (Response will contain citation count information for the provided DOI) ``` -------------------------------- ### Build habanero locally Source: https://github.com/sckott/habanero/blob/main/README.rst Clone the habanero repository and build it locally for development or testing. ```console git clone https://github.com/sckott/habanero.git cd habanero make install ``` -------------------------------- ### List and Search Licenses Source: https://context7.com/sckott/habanero/llms.txt Retrieve a list of all available licenses or search for licenses by keyword. The output includes license URLs and potentially work counts. ```python result = cr.licenses() urls = [lic["URL"] for lic in result["message"]["items"]] print(urls[:5]) ``` ```python result = cr.licenses(query="creative commons", limit=10) for lic in result["message"]["items"]: print(lic["URL"], lic.get("work-count")) ``` -------------------------------- ### Get citation count for a DOI Source: https://github.com/sckott/habanero/blob/main/README.rst Use the `counts` module to retrieve the citation count for a given DOI. ```python from habanero import counts counts.citation_count(doi = "10.1016/j.fbr.2012.01.001") ``` -------------------------------- ### Content Negotiation with Different Formats Source: https://github.com/sckott/habanero/blob/main/docs/modules/cn.md Demonstrates how to use the `content_negotiation` function from the `habanero.cn` module to retrieve data in various formats. Specify the desired format using the `format` parameter. ```python from habanero import cn cn.content_negotiation(ids = '10.1126/science.169.3946.635') ``` ```python cn.content_negotiation(ids = '10.1126/science.169.3946.635', format = "citeproc-json") ``` ```python cn.content_negotiation(ids = "10.1126/science.169.3946.635", format = "rdf-xml") ``` ```python cn.content_negotiation(ids = "10.1126/science.169.3946.635", format = "crossref-xml") ``` ```python cn.content_negotiation(ids = "10.1126/science.169.3946.635", format = "text") ``` ```python cn.content_negotiation(ids = "10.1126/science.169.3946.635", format = "bibentry") ``` -------------------------------- ### Get Citation Count Source: https://github.com/sckott/habanero/blob/main/docs/modules/counts.md Use the `citation_count` function to retrieve the number of citations for a given DOI. Multiple DOIs can be passed. ```python from habanero import counts counts.citation_count(doi = "10.1371/journal.pone.0042793") counts.citation_count(doi = "10.1016/j.fbr.2012.01.001") ``` -------------------------------- ### Crossref Client Instantiation Source: https://context7.com/sckott/habanero/llms.txt Instantiate the Crossref client with optional parameters for base URL, API key, mailto, user-agent string, and timeout. Setting `mailto` is recommended for better rate-limit behavior. ```APIDOC ## `Crossref` — instantiate the client The main entry point. Accepts optional `base_url`, `api_key`, `mailto`, `ua_string`, and `timeout` parameters. Set `mailto` to be placed in Crossref's *polite pool* for better rate-limit behaviour. ```python from habanero import Crossref # Minimal – uses https://api.crossref.org, 5-second timeout cr = Crossref() # Polite pool + custom user-agent + longer timeout cr = Crossref( mailto="researcher@university.edu", ua_string="MyResearchTool/1.0", timeout=30, ) print(cr) # < Crossref # URL: https://api.crossref.org # KEY: None # MAILTO: researcher@university.edu # ADDITIONAL UA STRING: MyResearchTool/1.0 # Timeout: 30 # > ``` ``` -------------------------------- ### Enable verbose logging for rate-limit inspection Source: https://context7.com/sckott/habanero/llms.txt Enables `httpx` debug logging to inspect request headers, including rate limit information, and diagnose connectivity issues. Requires setting up basic logging configuration. ```python import logging import httpx from habanero import Crossref logging.basicConfig( format="%(levelname)s [%(asctime)s] %(name)s - %(message)s", datefmt="%Y-%m-%d %H:%M:%S", level=logging.DEBUG, ) cr = Crossref(mailto="you@example.com") result = cr.works(query="ecology", limit=2) # DEBUG output will show request URL, headers (User-Agent, X-USER-AGENT), # and response headers including X-Rate-Limit-Limit / X-Rate-Limit-Interval ``` -------------------------------- ### Get citation count for a DOI Source: https://context7.com/sckott/habanero/llms.txt Retrieves the number of times a work has been cited using the Crossref OpenURL service. Supports single DOI lookups and batch lookups with basic error handling. ```python from habanero import counts # --- Single DOI lookup --- count = counts.citation_count(doi="10.1371/journal.pone.0042793") print(f"Cited {count} times") # e.g., Cited 142 times # --- Another example --- count2 = counts.citation_count(doi="10.1016/j.fbr.2012.01.001") print(count2) # --- Batch lookups with error handling --- doi_list = [ "10.1371/journal.pone.0042793", "10.1038/nature12373", "10.1126/science.169.3946.635", ] for doi in doi_list: try: n = counts.citation_count(doi=doi) print(f"{doi}: {n} citations") except Exception as e: print(f"{doi}: error – {e}") ``` -------------------------------- ### citation_count() — get citation count for a DOI Source: https://context7.com/sckott/habanero/llms.txt Looks up the number of times a work has been cited using the Crossref OpenURL service. Supports single DOI lookups and batch lookups with error handling. ```APIDOC ## `citation_count()` — get citation count for a DOI ### Description Look up the number of times a work has been cited, using the Crossref OpenURL service. ### Method Signature ```python counts.citation_count(doi: str) ``` ### Parameters * **doi** (str) - The Digital Object Identifier (DOI) of the work. ### Usage Example ```python from habanero import counts # Single DOI lookup count = counts.citation_count(doi="10.1371/journal.pone.0042793") print(f"Cited {count} times") # Another example count2 = counts.citation_count(doi="10.1016/j.fbr.2012.01.001") print(count2) # Batch lookups with error handling doi_list = [ "10.1371/journal.pone.0042793", "10.1038/nature12373", "10.1126/science.169.3946.635", ] for doi in doi_list: try: n = counts.citation_count(doi=doi) print(f"{doi}: {n} citations") except Exception as e: print(f"{doi}: error – {e}") ``` ``` -------------------------------- ### Error handling with `RequestError` Source: https://context7.com/sckott/habanero/llms.txt Demonstrates how to catch `habanero.RequestError` for HTTP errors and how to use `warn=True` for graceful batch processing. ```APIDOC ## Error handling with `RequestError` ### Description habanero raises `habanero.RequestError` (a subclass of `Exception`) on HTTP errors, exposing the status code and message. Use `warn=True` on search methods to demote errors to warnings for batch workloads. ### Usage Example ```python from habanero import Crossref from habanero.exceptions import RequestError cr = Crossref(mailto="you@example.com") # Catch a request error try: result = cr.works(ids="10.9999/this-doi-does-not-exist") except RequestError as e: print(f"Status: {e.status_code}") # e.g., Status: 404 print(f"Error: {e.error}") # e.g., Error: Not found # Graceful batch handling with warn=True dois = [ "10.1371/journal.pone.0033693", # valid "10.9999/bad-doi-1", # invalid "10.9999/bad-doi-2", # invalid ] import warnings with warnings.catch_warnings(record=True) as caught: warnings.simplefilter("always") results = cr.works(ids=dois, warn=True) valid = [r for r in results if r is not None] print(f"Valid results: {len(valid)}") # 1 print(f"Warnings raised: {len(caught)}") # 2 ``` ``` -------------------------------- ### Explore Crossref Filter Names and Details Source: https://context7.com/sckott/habanero/llms.txt Programmatically discover available filter parameters for works, members, and funders routes. This includes listing filter names and retrieving detailed descriptions and possible values for each filter. ```python from habanero import Crossref cr = Crossref() # --- List all works filter names --- print(cr.filter_names()) # ['alternative_id', 'archive', 'article_number', 'award_funder', 'award_number', ...] ``` ```python # --- Member and funder filters --- print(cr.filter_names("members")) print(cr.filter_names("funders")) ``` ```python # --- Full detail: possible values and description --- details = cr.filter_details() for name, info in list(details.items())[:3]: print(f"{name}: {info['description']}") ``` ```python # --- Works filter details --- works_filters = cr.filter_details("works") # e.g., works_filters['has_full_text'] -> # {'possible_values': None, 'description': 'Filter to works that have a full text ...'} ``` -------------------------------- ### Query Crossref Prefixes Source: https://context7.com/sckott/habanero/llms.txt Fetch prefix information and associated works. Supports filtering, sorting, and deep paging. ```python from habanero import Crossref cr = Crossref(mailto="you@example.com") # --- Single prefix --- result = cr.prefixes(ids="10.1016") print(result["message"]["name"]) # e.g., "Elsevier BV" # --- Multiple prefixes at once --- result = cr.prefixes(ids=["10.1016", "10.1371", "10.1093"]) for item in result: print(item["message"]["name"]) # --- Get works for a prefix with filter and sorting --- result = cr.prefixes( ids="10.1371", works=True, limit=5, sort="published", order="desc", filter={"type": "journal-article"}, ) dois = [item["DOI"] for item in result["message"]["items"]] print(dois) # --- Field query: search editor names --- result = cr.prefixes( ids="10.1371", works=True, query_editor="cooper", filter={"type": "journal-article"}, limit=10, ) editors = [x.get("editor") for x in result["message"]["items"]] print([e for e in editors if e is not None]) # --- Deep paging --- pages = cr.prefixes(ids="10.1016", works=True, cursor="*", cursor_max=200, limit=50) items = [item for page in pages for item in page["message"]["items"]] print(f"Fetched {len(items)} works") ``` -------------------------------- ### Crossref.licenses() Source: https://context7.com/sckott/habanero/llms.txt Query the /licenses route to enumerate the licenses associated with Crossref works. ```APIDOC ## `Crossref.licenses()` — list deposit licenses Query the `/licenses` route to enumerate the licenses associated with Crossref works. ### Description Enumerate the licenses associated with Crossref works. ### Method ```python cr.licenses() ``` ### Request Example ```python cr.licenses() ``` ### Response - **message** (dict) - Contains the query results. - **items** (list) - A list of licenses associated with Crossref works. ``` -------------------------------- ### Content Negotiation Source: https://github.com/sckott/habanero/blob/main/README.rst Retrieve citations in various formats using content negotiation. ```APIDOC ## Content Negotiation ### Description Obtain citation information in a variety of formats through content negotiation. ### Module `habanero.cn` ### Method `content_negotiation(ids: str, format: str = None, style: str = None)` ### Parameters - **ids** (str) - Required - The DOI for which to retrieve citation information. - **format** (str) - Optional - The desired output format (e.g., "citeproc-json", "rdf-xml", "text", "bibentry"). - **style** (str) - Optional - The citation style to use when `format` is "text" (e.g., "apa"). ### Request Examples ```python from habanero import cn # Get citation in default format citation_default = cn.content_negotiation(ids = '10.1126/science.169.3946.635') # Get citation in citeproc-json format citation_json = cn.content_negotiation(ids = '10.1126/science.169.3946.635', format = "citeproc-json") # Get citation in rdf-xml format citation_rdf = cn.content_negotiation(ids = "10.1126/science.169.3946.635", format = "rdf-xml") # Get citation in plain text format citation_text = cn.content_negotiation(ids = "10.1126/science.169.3946.635", format = "text") # Get citation in plain text with APA style citation_apa = cn.content_negotiation(ids = "10.1126/science.169.3946.635", format = "text", style = "apa") # Get citation in bibentry format citation_bibentry = cn.content_negotiation(ids = "10.1126/science.169.3946.635", format = "bibentry") ``` ### Response Example (Success) (Response content will be in the requested format) ``` -------------------------------- ### Fetch available CSL citation styles Source: https://context7.com/sckott/habanero/llms.txt Fetches a list of available Citation Style Language (CSL) style names from the official GitHub repository. These names can be used with the `style` argument in `content_negotiation()`. ```python from habanero import cn styles = cn.csl_styles() print(f"Total styles: {len(styles)}") print(styles[:10]) # ['academy-of-management-review', 'acm-sig-proceedings', 'acta-anaesthesiologica-scandinavica', ...] # Check if a style is available print("apa" in styles) # True print("nature" in styles) # True print("harvard1" in styles) # True # Use a discovered style for content negotiation nature_cite = cn.content_negotiation( ids="10.1126/science.169.3946.635", format="text", style="nature", ) print(nature_cite) ``` -------------------------------- ### Crossref.filter_names() / Crossref.filter_details() Source: https://context7.com/sckott/habanero/llms.txt Programmatically discover available filter parameters for the works, members, and funders routes. `filter_names()` lists filter names, while `filter_details()` provides descriptions and possible values for each filter. ```APIDOC ## `Crossref.filter_names()` / `Crossref.filter_details()` — explore available filters Programmatically discover all filter parameters available for the works, members, and funders routes. ### Method ```python cr.filter_names(type=None) cr.filter_details(type=None) ``` ### Parameters #### Query Parameters - **type** (str) - Optional - Specifies the type of filters to retrieve ('works', 'members', 'funders'). Defaults to all types. ### Request Example ```python # List all works filter names print(cr.filter_names()) # ['alternative_id', 'archive', 'article_number', 'award_funder', 'award_number', ...] # Member and funder filters print(cr.filter_names("members")) print(cr.filter_names("funders")) # Full detail: possible values and description details = cr.filter_details() for name, info in list(details.items())[:3]: print(f"{name}: {info['description']}") # Works filter details works_filters = cr.filter_details("works") # e.g., works_filters['has_full_text'] -> # {'possible_values': None, 'description': 'Filter to works that have a full text ...'} ``` ### Response #### Success Response (200) - **filter_names** (list of str) - A list of available filter names. - **filter_details** (dict) - A dictionary where keys are filter names and values are dictionaries containing 'description' and 'possible_values'. ``` -------------------------------- ### Handle Crossref RequestError Source: https://context7.com/sckott/habanero/llms.txt Demonstrates how to catch `habanero.RequestError` for HTTP errors, accessing the status code and error message. Also shows how to use `warn=True` for graceful batch handling, demoting errors to warnings. ```python from habanero import Crossref from habanero.exceptions import RequestError cr = Crossref(mailto="you@example.com") # --- Catch a request error --- try: result = cr.works(ids="10.9999/this-doi-does-not-exist") except RequestError as e: print(f"Status: {e.status_code}") # e.g., Status: 404 print(f"Error: {e.error}") # e.g., Error: Not found # --- Graceful batch handling with warn=True --- dois = [ "10.1371/journal.pone.0033693", # valid "10.9999/bad-doi-1", # invalid "10.9999/bad-doi-2", # invalid ] import warnings with warnings.catch_warnings(record=True) as caught: warnings.simplefilter("always") results = cr.works(ids=dois, warn=True) valid = [r for r in results if r is not None] print(f"Valid results: {len(valid)}") # 1 print(f"Warnings raised: {len(caught)}") # 2 ``` -------------------------------- ### content_negotiation Source: https://github.com/sckott/habanero/blob/main/docs/modules/cn.md Performs content negotiation for a given identifier, allowing retrieval of information in different formats. ```APIDOC ## content_negotiation ### Description Performs content negotiation for a given identifier. This function allows you to retrieve information associated with a specific ID in various formats. ### Method `cn.content_negotiation()` ### Parameters #### Path Parameters None #### Query Parameters - **ids** (string) - Required - The identifier for which to perform content negotiation. - **format** (string) - Optional - The desired format for the returned content. Supported formats include 'citeproc-json', 'rdf-xml', 'crossref-xml', 'text', and 'bibentry'. If not specified, a default format is used. ### Request Example ```python from habanero import cn # Example with default format cn.content_negotiation(ids = '10.1126/science.169.3946.635') # Example with specific formats cn.content_negotiation(ids = '10.1126/science.169.3946.635', format = "citeproc-json") cn.content_negotiation(ids = "10.1126/science.169.3946.635", format = "rdf-xml") cn.content_negotiation(ids = "10.1126/science.169.3946.635", format = "crossref-xml") cn.content_negotiation(ids = "10.1126/science.169.3946.635", format = "text") cn.content_negotiation(ids = "10.1126/science.169.3946.635", format = "bibentry") ``` ### Response #### Success Response (200) - The response format depends on the `format` parameter specified. It can be JSON, XML, plain text, or a bibliography entry. ``` -------------------------------- ### Crossref.prefixes() Source: https://context7.com/sckott/habanero/llms.txt Query the /prefixes route to retrieve metadata about a given prefix, optionally including works associated with that prefix. Supports filtering, sorting, and deep paging. ```APIDOC ## `Crossref.prefixes()` — retrieve metadata about a given prefix Query the `/prefixes` route to retrieve metadata about a given prefix, optionally including works associated with that prefix. Supports filtering, sorting, and deep paging. ### Description Retrieve metadata about a given prefix, optionally including works associated with that prefix. Supports filtering, sorting, and deep paging. ### Method ```python cr.prefixes(ids, works=None, limit=None, sort=None, order=None, filter=None, query_editor=None, cursor=None, cursor_max=None) ``` ### Parameters - **ids** (str or list) - The prefix ID(s) to query. - **works** (bool, optional) - If True, include works associated with the prefix. - **limit** (int, optional) - The maximum number of items to return. - **sort** (str, optional) - The field to sort the results by (e.g., 'published'). - **order** (str, optional) - The order of sorting ('asc' or 'desc'). - **filter** (dict, optional) - A dictionary of filters to apply (e.g., `{"type": "journal-article"}`). - **query_editor** (str, optional) - Query editor names. - **cursor** (str, optional) - Cursor for deep paging. - **cursor_max** (int, optional) - Maximum number of items to fetch with deep paging. ### Request Example ```python # Single prefix result = cr.prefixes(ids="10.1016") print(result["message"]["name"]) # Multiple prefixes result = cr.prefixes(ids=["10.1016", "10.1371", "10.1093"]) # Get works for a prefix with filter and sorting result = cr.prefixes( ids="10.1371", works=True, limit=5, sort="published", order="desc", filter={"type": "journal-article"}, ) # Field query: search editor names result = cr.prefixes( ids="10.1371", works=True, query_editor="cooper", filter={"type": "journal-article"}, limit=10, ) # Deep paging pages = cr.prefixes(ids="10.1016", works=True, cursor="*", cursor_max=200, limit=50) ``` ### Response - **message** (dict) - Contains the query results, including metadata and items. - **name** (str) - The name of the prefix. - **items** (list) - A list of works associated with the prefix, if `works=True`. - **DOI** (str) - The Digital Object Identifier of the work. ``` -------------------------------- ### Verbose logging / rate-limit inspection Source: https://context7.com/sckott/habanero/llms.txt Enables `httpx` debug logging to inspect request headers, including rate limit information, and diagnose connectivity issues. ```APIDOC ## Verbose logging / rate-limit inspection ### Description Enable `httpx` debug logging to inspect request headers (including `X-Rate-Limit-Limit` and `X-Rate-Limit-Interval`) and diagnose connectivity issues. ### Usage Example ```python import logging import httpx from habanero import Crossref logging.basicConfig( format="%(levelname)s [%(asctime)s] %(name)s - %(message)s", datefmt="%Y-%m-%d %H:%M:%S", level=logging.DEBUG, ) cr = Crossref(mailto="you@example.com") result = cr.works(query="ecology", limit=2) # DEBUG output will show request URL, headers (User-Agent, X-USER-AGENT), # and response headers including X-Rate-Limit-Limit / X-Rate-Limit-Interval ``` ``` -------------------------------- ### csl_styles() — list available CSL citation styles Source: https://context7.com/sckott/habanero/llms.txt Fetches the full list of Citation Style Language (CSL) style names from the official GitHub repository. These names can be used as the `style` argument to `content_negotiation()`. ```APIDOC ## `csl_styles()` — list available CSL citation styles ### Description Fetch the full list of Citation Style Language (CSL) style names from the official GitHub repository. Use these names as the `style` argument to `content_negotiation()`. ### Method Signature ```python cn.csl_styles() ``` ### Usage Example ```python from habanero import cn styles = cn.csl_styles() print(f"Total styles: {len(styles)}") print(styles[:10]) # Check if a style is available print("apa" in styles) # True print("nature" in styles) # True print("harvard1" in styles) # True # Use a discovered style for content negotiation nature_cite = cn.content_negotiation( ids="10.1126/science.169.3946.635", format="text", style="nature", ) print(nature_cite) ``` ``` -------------------------------- ### content_negotiation() Source: https://context7.com/sckott/habanero/llms.txt Fetch formatted citations for one or more DOIs via the `https://doi.org` content-negotiation service. Supports various formats including BibTeX, RIS, APA/CSL text, and JSON. ```APIDOC ## `content_negotiation()` — retrieve citations in standard formats Fetch a formatted citation for one or more DOIs via the `https://doi.org` content-negotiation service. Supports BibTeX, RIS, APA/CSL text, RDF-XML, Turtle, citeproc-JSON, crossref-XML, DataCite-XML, and more. ### Method ```python cn.content_negotiation(ids, format=None, style=None) ``` ### Parameters #### Path Parameters - **ids** (str or list of str) - Required - One or more DOIs for which to retrieve citations. #### Query Parameters - **format** (str) - Optional - The desired output format (e.g., 'bibtex', 'ris', 'text', 'citeproc-json'). Defaults to 'bibtex'. - **style** (str) - Optional - A CSL style for 'text' format (e.g., 'apa', 'elsevier-harvard'). ### Request Example ```python # Default: BibTeX bibtex = cn.content_negotiation(ids="10.1126/science.169.3946.635") print(bibtex) # @article{Frank_1970, doi = {10.1126/science.169.3946.635}, ...} # RIS format ris = cn.content_negotiation(ids="10.1126/science.169.3946.635", format="ris") print(ris) # Formatted text with a CSL style apa = cn.content_negotiation(ids="10.1126/science.169.3946.635", format="text", style="apa") print(apa) # Frank, H. S. (1970). The Structure of Ordinary Water. Science, 169(3946), 635–641. elsevier = cn.content_negotiation(ids="10.1126/science.169.3946.635", format="text", style="elsevier-harvard") print(elsevier) # citeproc-JSON import json citeproc = cn.content_negotiation(ids="10.1126/science.169.3946.635", format="citeproc-json") data = json.loads(citeproc) print(data["title"]) # DataCite DOI bibtex_dc = cn.content_negotiation(ids="10.15468/t4rau8", format="bibtex") print(bibtex_dc) # Multiple DOIs (warns on failures, does not raise) dois = ["10.5167/UZH-30455", "10.5167/UZH-49216", "10.5167/UZH-503"] results = cn.content_negotiation(ids=dois) print(results) ``` ### Response #### Success Response (200) - **citation** (str) - The formatted citation string in the requested format. ``` -------------------------------- ### Faceted Search for License Types Source: https://github.com/sckott/habanero/blob/main/docs/docs/usecases.md Perform a faceted search to retrieve works and group them by license type. Use this to understand the distribution of licenses for scholarly works. ```python res = cr.works(facet = "license:*") ``` -------------------------------- ### Retrieve Citations in Standard Formats Source: https://context7.com/sckott/habanero/llms.txt Fetch formatted citations for one or more DOIs using the doi.org content-negotiation service. Supports various formats like BibTeX, RIS, APA, JSON, and XML. Handles multiple DOIs by returning results, with warnings for failures. ```python from habanero import cn import warnings doi = "10.1126/science.169.3946.635" # --- Default: BibTeX --- bibtex = cn.content_negotiation(ids=doi) print(bibtex) # @article{Frank_1970, doi = {10.1126/science.169.3946.635}, ...} ``` ```python # --- RIS format --- ris = cn.content_negotiation(ids=doi, format="ris") print(ris) ``` ```python # --- Formatted text with a CSL style --- apa = cn.content_negotiation(ids=doi, format="text", style="apa") print(apa) # Frank, H. S. (1970). The Structure of Ordinary Water. Science, 169(3946), 635–641. ``` ```python elsevier = cn.content_negotiation(ids=doi, format="text", style="elsevier-harvard") print(elsevier) ``` ```python # --- citeproc-JSON --- import json citeproc = cn.content_negotiation(ids=doi, format="citeproc-json") data = json.loads(citeproc) print(data["title"]) ``` ```python # --- DataCite DOI --- bibtex_dc = cn.content_negotiation(ids="10.15468/t4rau8", format="bibtex") print(bibtex_dc) ``` ```python # --- Multiple DOIs (warns on failures, does not raise) --- dois = ["10.5167/UZH-30455", "10.5167/UZH-49216", "10.5167/UZH-503"] results = cn.content_negotiation(ids=dois) print(results) ``` -------------------------------- ### Count Unique Licenses Source: https://github.com/sckott/habanero/blob/main/docs/docs/usecases.md Extract the count of unique license types from the search results. This provides a quick overview of the variety of licenses available. ```python res['message']['facets']['license']['value-count'] ``` -------------------------------- ### Search or Fetch Scholarly Works Source: https://context7.com/sckott/habanero/llms.txt Query the /works route to search content or fetch records by DOI. Supports filtering, sorting, field selection, facets, and cursor-based deep paging. Use warn=True to return None for bad DOIs instead of raising an error. ```python from habanero import Crossref cr = Crossref(mailto="you@example.com") # --- Fetch a single work by DOI --- result = cr.works(ids="10.1371/journal.pone.0033693") print(result["message"]["title"]) # ['Ecological Guild Evolution and the Discovery of the World\'s Smallest Vertebrate'] # --- Free-text query with limit --- result = cr.works(query="climate change", limit=5, sort="published", order="desc") print(result["message"]["total-results"]) dois = [item["DOI"] for item in result["message"]["items"]] print(dois) # --- Filters (dict, repeatable values as list) --- result = cr.works( filter={\"has_full_text\": True, \"type\": \"journal-article\", \"from_pub_date\": \"2023-01-01\"}, limit=10, select=["DOI", "title", "published"], ) for item in result["message"]["items"]: print(item["DOI"], item.get("title", [""])[0]) # --- Field queries (query_* kwargs) --- result = cr.works(query="ecology", query_author="carl boettiger", limit=5) authors = [item["author"][0]["family"] for item in result["message"]["items"]] print(authors) # --- Cursor deep paging (returns list of page dicts) --- pages = cr.works( query="machine learning", cursor="*", cursor_max=500, limit=100, progress_bar=True, ) all_items = [item for page in pages for item in page["message"]["items"]] print(f"Retrieved {len(all_items)} works") # --- warn=True: bad DOIs return None instead of raising --- dois = ["10.1371/journal.pone.0033693", "10.9999/not-a-real-doi"] results = cr.works(ids=dois, warn=True) print([type(r).__name__ for r in results]) # ['dict', 'NoneType'] ``` -------------------------------- ### WorksContainer Source: https://context7.com/sckott/habanero/llms.txt A convenience wrapper around raw works API responses that exposes each metadata field as a list attribute, simplifying bulk data extraction. ```APIDOC ## `WorksContainer` — structured access to works results A convenience wrapper around raw works API responses that exposes each metadata field as a list attribute, making bulk data extraction simple. ### Usage ```python from habanero import WorksContainer # Wrap a multi-work response res = cr.works(ids=["10.1136/jclinpath-2020-206745", "10.1136/esmoopen-2020-000776"]) wc = WorksContainer(res) print(wc.doi) # ['10.1136/jclinpath-2020-206745', '10.1136/esmoopen-2020-000776'] print(wc.title) # [['Full title A'], ['Full title B']] print(wc.abstract) # [None, 'Abstract text...'] print(wc.license) # [[{...}], [{...}]] # Wrap a list-style response res2 = cr.works(query="climate", limit=5) wc2 = WorksContainer(res2) print(wc2.doi) print(wc2.is_referenced_by_count) # Works from a member, wrapped res3 = cr.members(ids=98, works=True, limit=10) wc3 = WorksContainer(res3) print(f"Titles: {wc3.title[:3]}") # Works from deep paging, wrapped pages = cr.works(query="CRISPR", cursor="*", cursor_max=200, limit=100) wc4 = WorksContainer(pages) print(f"Total wrapped: {len(wc4.works)}") ``` ### Attributes - **doi** (list of str) - List of DOIs. - **title** (list of list of str) - List of titles, where each title is a list of strings. - **abstract** (list of str or None) - List of abstracts, can contain None. - **license** (list of list of dict) - List of license information dictionaries. - **is_referenced_by_count** (list of int) - List of counts of references. ``` -------------------------------- ### Crossref.prefixes() - Look Up DOI Prefixes Source: https://context7.com/sckott/habanero/llms.txt Query the `/prefixes` route to retrieve metadata about DOI prefixes or list their registered works. Supports fetching by prefix and filtering. ```APIDOC ## `Crossref.prefixes()` — look up DOI prefixes Query the `/prefixes` route to retrieve metadata about DOI prefixes (e.g., `10.1016` for Elsevier), or list their registered works. ```python from habanero import Crossref cr = Crossref(mailto="you@example.com") # --- Fetch prefix metadata --- result = cr.prefixes(ids="10.1016") print(result["message"]["items"]) # --- Get works for a prefix --- result = cr.prefixes(ids="10.1016", works=True, limit=5) dois = [item["DOI"] for item in result["message"]["items"]] print(dois) # --- Filter prefixes by member ID --- result = cr.prefixes(filter={"member": 98}, limit=5) print([p["prefix"] for p in result["message"]["items"]]) ``` ``` -------------------------------- ### CSL Styles Source: https://github.com/sckott/habanero/blob/main/README.rst Retrieve a list of available Citation Style Language (CSL) styles. ```APIDOC ## CSL Styles ### Description Retrieve a list of available Citation Style Language (CSL) styles that can be used with content negotiation. ### Module `habanero.cn` ### Method `csl_styles()` ### Request Example ```python from habanero import cn styles = cn.csl_styles() ``` ### Response Example (Success) (Response will be a list of available CSL style names.) ``` -------------------------------- ### Fetch Random DOIs Source: https://context7.com/sckott/habanero/llms.txt Retrieve a random sample of DOIs from the Crossref corpus. You can specify the number of DOIs to fetch, with a maximum of 100. ```python from habanero import Crossref cr = Crossref(mailto="you@example.com") # --- Default: 10 random DOIs --- dois = cr.random_dois() print(dois) ``` ```python # --- Specify count (max 100) --- dois = cr.random_dois(50) print(f"Got {len(dois)} random DOIs") print(dois[:3]) # ['10.xxxx/...', '10.yyyy/...', '10.zzzz/...'] ``` -------------------------------- ### Find License with Most Works Source: https://github.com/sckott/habanero/blob/main/docs/docs/usecases.md Identify the specific license that has the highest number of associated works. This is useful for pinpointing the dominant license in the dataset. ```python max(gt1000, key=lambda k: gt1000[k]) ``` -------------------------------- ### List Crossref Work Types Source: https://context7.com/sckott/habanero/llms.txt Enumerate Crossref work types and retrieve works of a specific type. Supports field queries and deep paging. ```python from habanero import Crossref cr = Crossref(mailto="you@example.com") # --- List all types --- result = cr.types() type_ids = [t["id"] for t in result["message"]["items"]] print(type_ids) # ['book-section', 'monograph', 'report-component', 'report', 'peer-review', ...] # --- Fetch a single type --- result = cr.types(ids="journal-article") print(result["message"]["label"]) # "Journal Article" # --- Works of a given type with field query --- result = cr.types( ids="journal-article", works=True, query_bibliographic="gender", limit=5, ) print([x.get("title") for x in result["message"]["items"]]) # --- Deep paging works by type --- pages = cr.types(ids="journal-article", works=True, cursor="*", cursor_max=120, progress_bar=True) items = [item for page in pages for item in page["message"]["items"]] print(f"Fetched {len(items)} journal-article works") ``` -------------------------------- ### Fetch Crossref works by DOI Source: https://github.com/sckott/habanero/blob/main/README.rst Retrieve specific work data from the Crossref API by providing its DOI. ```python # fetch data by DOI cr.works(ids = '10.1371/journal.pone.0033693') ``` -------------------------------- ### Search Publisher Members Source: https://context7.com/sckott/habanero/llms.txt Query the /members route to retrieve Crossref member publisher metadata, optionally including their works. Supports filtering, searching by query, and deep paging for member works. ```python from habanero import Crossref cr = Crossref(mailto="you@example.com") # --- Fetch member by id --- result = cr.members(ids=98) print(result["message"]["primary-name"]) # e.g., "Wiley" # --- Get works for a member --- result = cr.members(ids=98, works=True, limit=5) dois = [z["DOI"] for z in result["message"]["items"]] print(dois) # --- Search members by query --- result = cr.members(query="oxford", limit=3) names = [m["primary-name"] for m in result["message"]["items"]] print(names) # --- Filter members with public references --- result = cr.members(filter={"has_public_references": True}, limit=5) print([m["id"] for m in result["message"]["items"]]) # --- Deep paging for member works --- pages = cr.members(ids=98, works=True, cursor="*", cursor_max=200, progress_bar=True) all_works = [item for page in pages for item in page["message"]["items"]] print(f"Total works: {len(all_works)}") ``` -------------------------------- ### Filter Licenses with Over 1000 Works Source: https://github.com/sckott/habanero/blob/main/docs/docs/usecases.md Filter the license facets to find those associated with more than 1000 works. This helps identify the most common licenses. ```python gt1000 = {k:v for (k,v) in res['message']['facets']['license']['values'].items() if v > 1000} len(gt1000) ``` -------------------------------- ### Query Crossref works Source: https://github.com/sckott/habanero/blob/main/README.rst Perform a search query for works on the Crossref API. Access the total number of results and the list of items from the response message. ```python # query x = cr.works(query = "ecology") x['message'] x['message']['total-results'] x['message']['items'] ```