Skip to content

Client API Reference

Andrew Calder edited this page Oct 10, 2022 · 17 revisions

class Client

This part of the documentation covers all the primary methods within the Client class.

Methods:

def __init__(token=None, base_url=None, session=None, auth=None, verify=True, timeout=15.0, retries=3):

Instantiates a new Client with a binding to Blackduck's REST API.

Arguments:

  • token (str): Access Token obtained from the Hub UI: System -> My Access Tokens
  • base_url (str): e.g. "https://your.blackduck.url"
  • session (requests.Session): custom session if specified. For advanced users only. If not provided, a HubSession with recommended defaults will be generated and used. Any custom session must incorporate a base_url in every request as a plain requests.Session() will not work. See HubSession implementation for an example.
  • auth (requests.auth.AuthBase): custom authorization if specified. For advanced users only. If not provided, one based on the access token is generated and used.
  • verify (bool): TLS certificate verification. Defaults to True.
  • timeout (float): request timeout in seconds. Defaults to 15 seconds.
  • retries (int): maximum number of times to retry a request. Defaults to 3.

Example

from blackduck import Client

with open("token.txt", 'r') as tf:
    access_token = tf.readline().strip()

bd = Client(
    token=access_token,
    base_url="https://your.blackduck.url",
    verify=False,  # due to self-signed certificate
    timeout=60.0,  # longer timeout for a large DB / bad connection
    retries=5,  # up the retries too
)

def list_resources(self, parent=None):

List named resources that can be fetched.

The names and corresponding URLs are extracted from the parent's json_data['_meta']['links'].

Arguments:

  • parent (dict/json): resource object from prior get_resource invocations. Defaults to None (for root /api/ base).

Returns:

  • dict(str -> str): of public resource names to urls. To obtain the url to the parent itself, use key 'href'.

Example

for project in bd.get_resource('projects'):
    resource_dict = bd.list_resources(project)

    # Obtain url to the parent itself
    url = resource_dict['href']  # e.g. /api/projects/de69a1e2-a703-44a9-8e9d-c3b8472972cb

    # Obtain url for the project versions
    url = resource_dict['versions']  # e.g. /api/projects/de69a1e2-a703-44a9-8e9d-c3b8472972cb/versions

def get_resource(name, parent=None, items=True, **kwargs):

Fetch a named resource.

Arguments:

  • name (str): resource name i.e. specific key from list_resources()
  • parent (dict/json): resource object from prior get_resource() call. Use None for root /api/ base.
  • items (bool): enable resource generator for paginated results. Defaults to True.
  • **kwargs: passed to session.request

Returns:

  • generator (items=True) or dict (items=False) containing returned json

Example

for project in bd.get_resource('projects'):
    print(project['name'])

is equivalent to:

resources_dict = list_resources()
url = resources_dict['projects']
for project in bd.get_items(url):
    print(project['name'])

An example that is not paginated:

reg_dict = bd.get_resource('registration', items=False)

is equivalent to:

resources_dict = bd.list_resources()
url = resources_dict['registration']
reg_dict = bd.get_json(url)

def get_metadata(name, parent=None, **kwargs):

Fetch named resource metadata and other useful data such as totalCount.

Arguments:

  • name (str): resource name i.e. specific key from list_resources()
  • parent (dict/json): resource object from prior get_resource() call. Use None for root /api/ base.
  • **kwargs: passed to session.request

Returns:

  • dict/json: named resource metadata

Example

for project in bd.get_resource('projects'):
    m = bd.get_metadata('versions', project)
    print("Num versions: " + m['totalCount'])

is a shortcut for:

for project in bd.get_resource('projects'):
    m = bd.get_resource('versions', project, items=False, params={'limit': 1})
    print("Num versions: " + m['totalCount'])

def get_json(url, **kwargs):

GET request to url endpoint and return json result but preserve underlying error handling.

Proper error handling done by get_json will check for HTTPErrors and JSONDecodeErrors and will log the Response object's status code and content body before re-raising the exception. This informs the user to a proper course of action much more effectively than a stack trace alone.

Arguments:

Returns:

  • json/dict: requested object

Example

items = bd.get_json("/api/projects?offset=0&limit=100")['items']

is much safer than (due to added error handling) but is in essence the following:

r = bd.session.get("/api/projects?offset=0&limit=100")
r.raise_for_status()
items = r.json()['items']

def get_items(url, page_size=250, **kwargs):

Send necessary GET requests to url endpoint to progressively fetch all items using pagination. Automatically provide the necessary offset and limit parameters.

Arguments:

  • url (str): of endpoint
  • page_size (int): Number of items to get per page. Defaults to 250.
  • **kwargs: passed to session.request

Yields:

  • generator(dict/json): of items

Example

for project in bd.get_items("/api/projects"):
    print(project['name'])

def http_error_handler(r):

Handle an unexpected HTTPError or Response by logging useful information.

Arguments:

  • r (requests.HTTPError OR requests.Response): to handle

Example

project_url = "/api/projects/de69a1e2-a703-44a9-8e9d-c3b8472972cb"

try:
    r = bd.session.delete(project_url)
    r.raise_for_status()
    print("deleted project")
except requests.HTTPError as err:
    bd.http_error_handler(err)

Or without exceptions:

r = bd.session.delete(project_url)
if r.status_code == 204:
    print("deleted project")
else:
    bd.http_error_handler(r)