<jupyter_start><jupyter_text>vars-kb-serverThis is a RESTful read-only service for retrieving information from MBARI's knowledgebase (KB). The source code is available at . MBARI has a public knowledgebase available at   Define URLs<jupyter_code>endpoint = "http://dsg.mbari.org/kb/v1"

concept_url = "%s/concept" % (endpoint)
phylogeny_url = "%s/phylogeny" % (endpoint)
links_url = "%s/links" % (endpoint)<jupyter_output><empty_output><jupyter_text>Configure imports and define helper functions<jupyter_code>import datetime
import json
import pprint
import random
import requests
import urllib
import uuid

def show(s, data = None):
    pp = pprint.PrettyPrinter(indent=1)
    print("--- " + s)
    if data:
      pp.pprint(data)
    
def iso8601():
    return datetime.datetime.now(datetime.timezone.utc).isoformat()[0:-6] + "Z"
    
def parse_response(r):
    try:
       return json.loads(r.text)
    except:
        s = "URL: %s\n%s (%s): %s" % (r.request.url, r.status_code, r.reason, r.text)
        print(s)
        return {}
    
    
def delete(url):
    return parse_response(requests.delete(url))

def get(url):
    return parse_response(requests.get(url))
    
def post(url, data = {}):
    return parse_response(requests.post(url, data))

def put(url, data = {}):
    return parse_response(requests.put(url, data))<jupyter_output><empty_output><jupyter_text>Concept APIThis API is for fetching a listing of all available concepts AND details about a particular concept<jupyter_code># Fetch the names of all concepts
concepts = get(concept_url)
show("GET: " + concept_url, concepts)
# Get the root node of the concept hierarchy
url = concept_url + "/root"
root = get(url)
show("GET: " + url, root)
# Get a concept by name
url = concept_url + "/Nanomia bijuga"
concept = get(url)
show("GET: " + url, concept)<jupyter_output>--- GET: http://dsg.mbari.org/kb/v1/concept/Nanomia bijuga
{'alternateNames': [],
 'descriptors': [{'linkName': 'is-bioluminescent',
                  'linkValue': 'bioluminescent',
                  'toConcept': 'self'}],
 'media': [{'caption': '',
            'credit': 'MBARI 2001: V2100-05\n',
            'isPrimary': False,
            'mimeType': 'image/png',
            'url': 'http://dsg.mbari.org/images/dsg/external/Cnidaria/Siphonophora/Nanomia_bijuga_01.png'},
           {'caption': '',
            'credit': 'MBARI 2010: D199',
            'isPrimary': False,
            'mimeType': 'image/png',
            'url': 'http://dsg.mbari.org/images/dsg/external/Cnidaria/Siphonophora/Nanomia_bijuga_02.png'},
           {'caption': '',
            'credit': 'MBARI 2010: D199',
            'isPrimary': False,
            'mimeType': 'image/png',
            'url': 'http://dsg.mbari.org/images/dsg/external/Cnidaria/Siphonophora/Nanomia_bijuga_05.png'},
           {'caption': 'Close up [...]<jupyter_text>Phylogeny APIThis API fetches either the ancestors __or__ the descendants of a concept (e.g. Phylogenetic tree)<jupyter_code># Fetch ancestors
url = phylogeny_url + "/up/Asteroidea"
p = get(url)
show("Get: " + url, p)
# Fetch descendants
url = phylogeny_url + "/down/Asteroidea"
p = get(url)
show("Get: " + url, p)<jupyter_output>--- Get: http://dsg.mbari.org/kb/v1/phylogeny/down/Asteroidea
{'children': [{'children': [], 'name': 'Asteroidea sp. 9', 'rank': 'species'},
              {'children': [], 'name': 'Asteroidea sp. 6', 'rank': 'species'},
              {'children': [{'children': [{'children': [{'children': [],
                                                         'name': 'Brisinga',
                                                         'rank': 'genus'},
                                                        {'children': [],
                                                         'name': 'Hymenodiscus',
                                                         'rank': 'genus'}],
                                           'name': 'Brisingidae',
                                           'rank': 'family'},
                                          {'children': [{'children': [{'children': [],
                                                                       'name': 'Freyellaster '
               [...]<jupyter_text>Links APILinks are predefined associations that can be used for annotations. Think of an association as additional descriptive information that can be applied to an annotation. In our VARS knowledgebase, a link can be used by a concept __and__ any of its descendants. Wehave found it's important to define and constrain. When annotating, we need to know what links can be used for a particular concept.<jupyter_code># Find links for a concept
url = links_url + "/Asteroidea"
p = get(url)
show("GET: " + url, p)<jupyter_output>--- GET: http://dsg.mbari.org/kb/v1/links/Asteroidea
[{'linkName': 'age-days', 'linkValue': '0', 'toConcept': 'self'},
 {'linkName': 'age-months', 'linkValue': '0', 'toConcept': 'self'},
 {'linkName': 'age-seconds', 'linkValue': '0', 'toConcept': 'self'},
 {'linkName': 'age-years', 'linkValue': '0', 'toConcept': 'self'},
 {'linkName': 'arranging', 'linkValue': 'nil', 'toConcept': 'physical object'},
 {'linkName': 'attaching-to',
  'linkValue': 'nil',
  'toConcept': 'physical object'},
 {'linkName': 'audio-comment', 'linkValue': 'nil', 'toConcept': 'self'},
 {'linkName': 'bioluminescing', 'linkValue': 'nil', 'toConcept': 'nil'},
 {'linkName': 'broken', 'linkValue': 'nil', 'toConcept': 'nil'},
 {'linkName': 'bubbling', 'linkValue': 'nil', 'toConcept': 'nil'},
 {'linkName': 'buried', 'linkValue': 'nil', 'toConcept': 'nil'},
 {'linkName': 'burrowing', 'linkValue': 'nil', 'toConcept': 'nil'},
 {'linkName': 'catching', 'linkValue': 'nil', 'toConcept': 'physical object'},
 {'linkName': 'caugh[...]
{'fraction_non_alphanumeric': 0.16442894507410635, 'fraction_numerical': 0.008195292066259808, 'mean_word_length': 2.7687253613666227, 'pattern_counts': {'":': 0, '<': 18, '<?xml version=': 0, '>': 18, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 19, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '5', 'dir': 'jupyter-structured-clean-dedup', 'id': '256099', 'license': 'Apache-2.0', 'n_tokens_mistral': 1866, 'n_tokens_neox': 1773, 'n_words': 454, 'path': 'src/site/notebooks/vars-kb-server Tutorial.ipynb', 'repo_name': 'mbari-media-management/vars-kb-server', 'size': '5735'}