Categories Reference Guide

This guide is for version 5.0-rc.6+


Source code


Class Categories

    Library for Category-related operations.

    Categories have some attributes, such as "name" and "remarks",
    as well as "BA_subcategory" and "BA_see_also" relationships with other categories.

    The 1st part of this library handles the above entity.

    The 2nd part (possibly to be split off in the future) manages a (for now conflated)
    entity of "Category Page", to which a variety of nodes (e.g. representing records or media)
    are attached with positional attributes - for example to implement an ordered sequence
    of multimedia content on the page of a content-management UI.
    
nameargumentsreturns
set_databasedb :GraphAccessNone
        IMPORTANT: this method MUST be called before using this class!

        :param db:  Database-interface object, created with the GraphAccess library
        :return:    None
        
nameargumentsreturns
initialize_categories(int, str)
        Create a new Schema Class node that represents "Categories",
        and make it an "INSTANCE_OF" of the "Collections" Class

        :return:    An (int, str) pair of integers with the internal database ID
                        and the unique uri assigned to the new Class node
        

LOOKUP CATEGORIES

nameargumentsreturns
get_category_infocategory_uri :strdict
        Return the Name and Remarks field values attached to the given Category

        :param category_uri:    A string identifying the desired Category
        :return:                The Category's properties (or a blank dictionary if not found)
                                    EXAMPLES:   {"uri": "123", "name": "Astronomy", "remarks": "except cosmology"}
                                                {"uri": "1", "name": "HOME", "root": true}
        
nameargumentsreturns
is_root_categorycategory_uri :strbool
        Return True if the given ID corresponds to the ROOT Category, or False otherwise

        :param category_uri:    A string identifying the desired Category
        :return:                True if the given ID corresponds to the ROOT Category, or False otherwise
        
nameargumentsreturns
get_all_categoriesexclude_root=True, include_remarks=False[dict]
        Return all the existing Categories - optionally except the root Category -
        as a list of dictionaries with keys 'uri', 'name', 'pinned' and, optionally, 'remarks',
        sorted by name.

        :param exclude_root:    If True, the root Category is omitted
        :param include_remarks: If True, the 'remarks' property is included alongside all others

        :return:    A list of dictionaries.  EXAMPLE:
                        [{'uri': '2', 'name': 'Work', 'remarks': 'Current or past'},
                         {'uri': '3', 'name': 'Hobbies', pinned: True} ]
        
nameargumentsreturns
count_subcategoriescategory_uri :strint
        Return the number of (direct) Subcategories of the given Category

        :param category_uri:A string identifying the desired Category
        :return:            The number of (direct) Subcategories of the given Category; possibly, zero
        
nameargumentsreturns
count_parent_categoriescategory_uri :strint
        Return the number of (direct) Subcategories of the given Category

        :param category_uri:A string identifying the desired Category
        :return:            The number of (direct) parent categories of the given Category; possibly, zero
        
nameargumentsreturns
get_subcategoriescategory_uri :str[dict]
        Return all the (immediate) subcategories of the given category,
        as a list of dictionaries with all the keys of the Category Class
        EXAMPLE:
            [{'uri': '2', 'name': 'Work', remarks: 'outside employment'},
             {'uri': '3', 'name': 'Hobbies'}]

        :param category_uri:A string identifying the desired Category
        :return:            A list of dictionaries
        
nameargumentsreturns
get_parent_categoriescategory_uri :str[dict]
        Return all the (immediate) parent categories of the given Category,
        as a list of dictionaries with all the keys of the Category Class
        EXAMPLE:
            [{'uri': '2', 'name': 'Work', remarks: 'outside employment'},
             {'uri': '3', 'name': 'Hobbies'}]

        :param category_uri:A string identifying the desired Category
        :return:            A list of dictionaries
        
nameargumentsreturns
get_sibling_categoriescategory_internal_id: int[dict]
        Return the data of all the "siblings" nodes of the given Category

        :param category_internal_id:    The internal database ID of a "Category" data node
        :return:                        A list of dictionaries, with one element for each "sibling";
                                            each element contains the 'internal_id' and 'node_labels' keys,
                                            plus whatever attributes are stored on that node.
                                            EXAMPLE of single element:
                                            {'name': 'French', 'internal_id': 123, 'node_labels': ['Category', 'BA']}
        
nameargumentsreturns
create_parent_mapcategory_uri :strdict
        Consider the set comprising the given Category and all its ancestors (i.e. all its super-categories),
        up to a maximum hop length.

        Create and return a dictionary that maps each of the uri in that set of Categories,
        to a list of the uri's of its parent Categories.

        :param category_uri:A string identifying the desired Category
        :return:            A dictionary mapping integers into lists of integers.
                            The keys are uri's of the given Category and any of its ancestors (super-categories),
                            up to a maximum hop length;
                            the values are lists of the uri's of the parent categories of the Category specified by the key
                            EXAMPLES:       {'123': ['1']}                                  # The given category (123) is a child of the root (1)
                                            {'823': ['709'], '709': ['544'], '544': ['1']}  # A simple 3-hop path from Category 823 to the root (1) :
                                                                                            #       823 is subcategory of 709,
                                                                                            #       which is subcategory of 544, which is subcategory of the root
                                            {'814': ['20', '30'], '20': ['1'], '30': ['79'], '79': ['1']}
                                                                                            # Two paths from Category 814 to the root;
                                                                                            #       814 is subcategory of 20 and 30;
                                                                                            #       20 is an subcategory of the root,
                                                                                            #       while with 30 we have to go thru an extra hop
        

MODIFY CATEGORIES

nameargumentsreturns
create_categories_rootdata_dict=None(int, str)
        Create a ROOT Category node;
        and return its internal database ID and its URI

        :param data_dict:   [OPTIONAL] Dict to specify alternate desired values
                                for the "name" and "remarks" fields of the Root Category
                                (by default, "HOME" and "top level", respectively)
        :return:            The pair (internal database ID, string URI)
                                of the new Data Node just created
        
nameargumentsreturns
add_subcategorydata_dict :dict, category_uri=Nonestr
        Add a new Subcategory to a given, already existing, Category

        :param data_dict:   Dictionary with the following keys:
                                category_uri            URI to identify the Category
                                                            to which to add the new Subcategory
                                subcategory_name        The name to give to the new Subcategory
                                subcategory_remarks     (OPTIONAL)  A comment field for the new Subcategory

        :param category_uri: Optional way to specify the parent Category

        :return:            A string with the "uri" of the Category node just created
                                (which makes use of an auto-increment value)
        
nameargumentsreturns
delete_categoryuri :strNone
        Delete the specified Category, provided that there are no Content Items linked to it.
        In case of error or failure, an Exception is raised.

        :param uri: The uri identifying the desired Category
        :return:    None
        
nameargumentsreturns
add_subcategory_relationshipdata_dict :dictNone
        Add a sub-category ("BA_subcategory_of") relationship
        between the specified 2 existing Categories.
        If the requested new relationship cannot be created (for example, if it already exists),
        raise an Exception

        :param data_dict:   Two keys are expected:
                                "sub"         URI to identify an existing Category node
                                                that is to be made a sub-category of another one
                                "cat"         URI to identify an existing Category node
                                                that is to be made the parent of the other Category

        :return:            None.  If the requested new relationship could not be created,
                                raise an Exception
        
nameargumentsreturns
get_see_alsofrom_category :str[dict]
        From the given Category, follow all the "see also" links, and return data about
        the Categories that are on their receiving end

        :param from_category:   URI of the Category where the "see_also" relationship originates
        :return:                List (possibly empty) of dictionaries of data from Categories linked to
                                    by a "see_also" relationship.  They keys are "name", "remarks", "uri".
                                    EXAMPLE: [{'name': 'Quotes', 'uri': '823', 'remarks': None}]
        
nameargumentsreturns
create_see_alsofrom_category :str, to_category :strNone
        Create a "see_also" link between the given Categories, in the specified direction

        :param from_category:   URI of the Category where the "see_also" relationship originates
        :param to_category:     URI of the Category where the "see_also" relationship terminates
        :return:                None
        
nameargumentsreturns
remove_see_alsofrom_category :str, to_category :strNone
        Remove a "see_also" link between the given Categories, in the specified direction.
        If not found, an Exception is raised.

        :param from_category:   URI of the Category where the "see_also" relationship originates
        :param to_category:     URI of the Category where the "see_also" relationship terminates
        :return:                None
        
nameargumentsreturns
import_ontologydf :pd.DataFrame, root_uri :strint
        Import an ontology of Categories, from a Pandas dataframe whose columns, named "0", "1", "2", ...
        represent levels of increasing depth.
        Each row of the dataframe must have exactly 1 entry, representing a Category name;
        all other entries are expected to be NaN

        EXAMPLE of dataframe (NaN's not shown):
            0           1           2
            Chapter 1
                        Section 1
                                    Paragraph 1
                                    Paragraph 2
                                    Paragraph 3
                        Section 2
                                    Paragraph 1

        Note: the above dataframe may be imported from a header-free CSV file with operations such as
                    pd.read_csv('C:/my_folder/my_file.csv',
                                header=None, encoding = "ISO-8859-1")

        Note: all Category nodes get assigned a unique URI
              based on the namespace currently used by add_subcategory()

        :param df:          A Pandas dataframe with the data to import
        :param root_uri:    A string with the unique URI of an existing Category node that is to be
                                the parent of all the top-level (column "0") imported Categories
        :return:            The number of Category nodes created
        

CATEGORY PAGES

nameargumentsreturns
viewer_handlercategory_uri :str
        Handler function for the Flask page generator "BA_pages_routing.py"

        :param category_uri: A string identifying the desired Category
        :return:             A list of dictionaries, with one element for each "sibling";
                                each element contains the 'internal_id' and 'node_labels' keys,
                                plus whatever attributes are stored on that node.
                                EXAMPLE of single element:
                                {'name': 'French', 'internal_id': 123, 'node_labels': ['Category', 'BA']}
        
nameargumentsreturns
add_relationship_beforefrom_id :str, to_id :str, rel_name :strNone
        A handler to be invoked by the core module before a relationship involving Categories is called.

        If any restriction would apply to adding the parent/child relationship between the specified categories,
        raise an Exception.

        IMPORTANT: NO RELATIONSHIP IS ACTUALLY ADDED

        The restriction are:
            1) the subcategory node cannot be the Root Category
            2) a category cannot be a subcategory of itself

        NOTE: the "BA_subcategory_of" relationship goes FROM the subcategory TO the parent category node

        :param from_id:     String with the uri of the subcategory node
        :param to_id:       String with the uri of the parent-category node
        :param rel_name:    NOT USED
        :return:            None.  If the requested new relationship should not be created, raise an Exception
        
nameargumentsreturns
remove_relationship_beforefrom_id: str, to_id :str, rel_name: strNone
        A handler to be invoked by the core module before a relationship involving Categories is called.

        If any restriction would apply to removing the parent/child relationship between the specified categories,
        raise an Exception.

        IMPORTANT: NO RELATIONSHIP IS ACTUALLY REMOVED

        The restriction is:
            *) the subcategory node cannot become orphaned as a result of the deletion

        NOTE: the "BA_subcategory_of" relationship goes FROM the subcategory TO the parent category node

        :param from_id:     String with the uri of the subcategory node
        :param to_id:       NOT USED.  String with the uri of the parent-category node
        :param rel_name:    NOT USED
        :return:            None.  If the requested new relationship should not be deleted, raise an Exception
        
nameargumentsreturns
create_bread_crumbscategory_uri :strlist
        Return a list of Category ID's together with token strings, providing directives for the HTML structure of
        the bread crumbs

        :param category_uri:A string with the URI of the Category whose "ancestry bread crumbs" we want to construct
        :return:            A list of Category URI's together with token strings,
                            providing directives for the HTML structure of the bread crumbs
                            EXAMPLE 1:  ['1']
                            EXAMPLE 2:  ['START_CONTAINER', ['1', 'ARROW', '799', 'ARROW', '876'], 'END_CONTAINER']
                            EXAMPLE 3:
                                [
                                    'START_CONTAINER',
                                    ['START_BLOCK',
                                                    'START_LINE', ['1', 'ARROW', '799', 'ARROW', '526'], 'END_LINE', 'CLEAR_RIGHT',
                                                    'START_LINE', ['1', 'ARROW', '61'], 'END_LINE',
                                     'END_BLOCK', 'ARROW', '814'],
                                    'END_CONTAINER'
                                ]
        
nameargumentsreturns
pin_categoryuri, op :strNone
        Set or unset the "pinned" property of the specified Category

        :param uri: The URI of a data node representing a Category
        :param op:  Either "set" or "unset"
        :return:    None
        
nameargumentsreturns
is_pinneduri :strbool
        Return True if the given Category has a "pinned" status; otherwise, False

        :param uri: The URI of a data node representing a Category
        :return:    True if the given Category has a "pinned" status; otherwise, False
        

VIEW ITEMS IN CATEGORIES

nameargumentsreturns
get_categories_linked_to_content_itemitem_uri :str[{}]
        Locate and return information about all the Categories
        that the given Content Item is linked to

        :param item_uri:    The URI of a data node representing a Content Item
        :return:            A list of dicts that have the keys "uri", "name", "remarks";
                                any missing value will appear as None
        
nameargumentsreturns
get_content_items_by_categoryuri[{}]
        Return the records for all nodes linked
        to the Category node identified by its uri value

        :param uri: A string identifying the desired Category
        :return:    A list of dictionaries
                    EXAMPLE:
                    [{'schema_code': 'i', 'uri': '1','width': 450, 'basename': 'my_pic', 'suffix': 'PNG', pos: 0, 'class_name': 'Image'},
                     {'schema_code': 'h', 'uri': '1', 'text': 'Overview', pos: 10, 'class_name': 'Header'},
                     {'schema_code': 'n', 'uri': '1', 'basename': 'overview', 'suffix': 'htm', pos: 20, 'class_name': 'Note'},
                     {'schema_code': 'rs', 'class_name': 'Recordset', 'class_handler': 'recordsets', 'uri': '6965', 'pos': 86, 'n_group': '4', 'order_by': 'name', 'class': 'YouTube Channel'}
                    ]
        

ADD REMOVE ITEMS FROM CATEGORIES

nameargumentsreturns
add_content_at_beginningcategory_uri :str, item_class_name: str, item_properties: dict, new_uri=None, namespace="data_node"str
        Add a new Content Item, with the given properties and Class, to the beginning of the specified Category.

        :param category_uri:    The string "uri" of the Category to which this new Content Media is to be attached
        :param item_class_name: For example, "Image"
        :param item_properties: A dictionary with keys such as "width", "height", "caption","basename", "suffix"
        :param new_uri:         Normally, if None (default) the Item ID is auto-generated,
                                    but it can also be provided (if provided, it MUST be unique)
        :param namespace:       Only applicable if new_uri is None : the namespace to use for automatically generating a URI
        :return:                The auto-increment "uri" assigned to the newly-created data node
        
nameargumentsreturns
link_content_at_endcategory_uri :str, item_uri :strNone
        Given an EXISTING data node, link it to the end of the specified Category.
        If a link to that Category already exists, an Exception is raised.

        :param category_uri:String to identify an existing Category
        :param item_uri:    String to identify an existing Content Item
        :return:            None
        
nameargumentsreturns
add_content_at_endcategory_uri :str, item_class_name: str, item_properties: dict, new_uri=None, namespace="data_node"str
        Add a NEW Content Item, with the given properties and Class, to the end of the specified Category collection.
        First, create a new Data Node, and then link it to the given Category, positioned at the end.

        :param category_uri:    A string to identify the Category
                                    to which this Content Media being newly-created is to be attached
        :param item_class_name: For example, "Image"
        :param item_properties: A dictionary with keys such as "width", "height", "caption","basename", "suffix"
                                    NOTE: if the Class was declared as "strict",
                                          then any key not declared in the Schema gets silently ignored
        :param new_uri:         Normally, if None (default) the Item ID is auto-generated,
                                    but it can also be provided (if provided, it MUST be unique)
        :param namespace:       Only applicable if new_uri is None : the namespace to use for automatically generating a URI
        :return:                The "uri" (passed or created) of the newly-created data node
        
nameargumentsreturns
add_content_after_elementcategory_uri :str, item_class_name: str, item_properties: dict, insert_after :str, new_uri=None, namespace="data_node"str
        Add a NEW Content Item, with the given properties and Class, inserted into the given Category after the specified Item
        (in the context of the positional order encoded in the relationship attribute "pos")

        :param category_uri:    String with a unique "uri" identified of the Category
                                    to which this new Content Media is to be attached
        :param item_class_name: For example, "Image"
        :param item_properties: A dictionary with keys specific to the new Content Item,
                                    such as "width", "height", "caption", "basename", "suffix"
        :param insert_after:    The URI of the element after which we want to insert
        :param new_uri:         Normally, if None (default) the Item ID is auto-generated,
                                    but it can also be provided (if provided, it MUST be unique)
        :param namespace:       Only applicable if new_uri is None : the namespace to use for automatically generating a URI
        :return:                The auto-increment "uri" assigned to the newly-created data node
        
nameargumentsreturns
detach_from_categorycategory_uri :str, item_uri :strNone
        Sever the link from the specified Content Item and the given Category.
        If it's the only Category that the Content Item is currently linked to,
        an Exception is raised (to avoid leaving that Content Item "stranded")

        :param category_uri:    The URI of a data node representing a Category
        :param item_uri:        The URI of a data node representing a Content Item
        :return:                None
        
nameargumentsreturns
relocate_across_categoriesitems :Union[List[str], str], from_category :str, to_category :str
        Given an existing list of data nodes (representing "Content Items" attached to the specified "from" Category),
        switch each of them to become a "Content Item" of the "to" Category, positioned at the end of it.

        The category-membership relationships ("BA_in_category") is severed from each the "Content Items" to the "from" Category,
        and a new one is created from that "Content Item" to the "to" Collection.

        Return the number of Content Items successfully relocated.

        :param items:           URI, or list of URI's, of Data Node(s)
                                    representing a "Content Items" attached to the "from" Category below
        :param from_category:   The URI of a Category Data Node to which the above Content Item(s) are connected
        :param to_category:     The URI of a Category Data Node to which the above Content Item(s) needs to be switched to
        :return:                The number of Content Items successfully relocated
        

SCHEMA RELATED

nameargumentsreturns
get_items_schema_datacategory_uri :str, exclude_system=Truedict
        Locate all the schema Classes used by Content Items attached to the given Category,
        and return a dictionary with the Properties (in the Schema order) of each,
        including Properties of their "ancestor" Classes (ancestral thru "INSTANCE_OF" relationships)

        Properties marked as "system" are optionally excluded (default).

        :param category_uri:A string with the "uri" value to identify the desired Category
        :param exclude_system: [OPTIONAL] If True, Property nodes with the attribute "system" set to True will be excluded;
                                    default is True
        :return:            A dictionary whose keys are Class names (of Content Items attached to the given Category),
                            and whose values are the Properties (in their Schema order) of those Classes.
                            Properties declared in "ancestor" Classes (thru "INSTANCE_OF" relationships)
                            are also included.
                            Properties regarded as "system" ones, such as "uri", are excluded.
                            EXAMPLE:
                                {'Header': ['text'],
                                 'Site Link': ['url', 'name', 'date', 'comments', 'rating', 'read'],
                                 'Note': ['title', 'public', 'date_created', 'basename', 'suffix']
                                 'German Vocabulary': ['Gender', 'German', 'English', 'notes'],
                                 'Quote': ['quote', 'attribution', 'notes'],
                                 'Recordset': ['class', 'order_by', 'clause', 'n_group']
                                 }
        

POSITIONING

nameargumentsreturns
check_for_duplicatescategory_name :str[str]
        This is a diagnostic method to check for problems.

        Look for duplicates values in the "pos" attributes
        of the "BA_in_category" links ending in the specified Category node

        :param category_name:   To identifying the Category of interest
        :return:                In case of duplicates, return a list of texts with error reports;
                                    if no duplicates, return an empty list
        
nameargumentsreturns
check_all_categories_for_duplicates[dict]
        This is a diagnostic method to check for problems.

        :return:    A (possibly-empty) list of dicts, detailing all located duplicates
        
nameargumentsreturns
reassign_positional_valuescategory_name :strNone
        To re-assign positional values of Content Items within the given Category
        (starting at 0 and proceeding in increments of Collections.DELTA_POS):

        :param category_name:
        :return:                None
        
nameargumentsreturns
reposition_contentcategory_uri :str, uri: str, move_after_n: int
        Reposition the given Content Item after the n-th item (counting starts with 1) in specified Category.

        Note: there's no harm (though it's wasteful) to move an item to a final sequence position where it already is;
              its "pos" value will change

        :param category_uri:    A string identifying the desired Category
        :param uri:             A string with the URI of the Content Item we're repositioning
        :param move_after_n:    The index (counting from 1) of the item after which we want to position the item being moved
                                    Use n=0 to indicate "move before anything else"
        :return:
        
nameargumentsreturns
relocate_positionscategory_uri :str, n_to_skip: int, pos_shift: intint
        Shift the values of the "pos" attributes on the "BA_in_category" relationships
        from the given Category node, by the given amount;
        however, SKIP the first n_to_skip entries (as sorted by the "pos" attribute)

        EXAMPLE - given the following order of the relationships attached to the given Category:
            pos
        1:   45
        2:   84
        3:   91

        then relocate_positions(category_uri, n_to_skip=1, pos_shift=100) will result in:
            pos
        1:   45     <= got skipped
        2:  184
        3:  191

        :param category_uri:A string identifying the desired Category
        :param n_to_skip:   The number of relationships (after sorting them by "pos") NOT to re-position
                                Must be an integer >= 1 (it'd be pointless to shift everything!)
        :param pos_shift:   The increment by which to shift the values of the "pos" attributes on the relationships

        :return:            The number of repositionings performed
        
nameargumentsreturns
swap_content_itemsuri_1 :str, uri_2 :str, cat_id :strNone
        Swap the positions of the specified Content Items within the given Category

        :param uri_1:   A string with the uri of the 1st Content Item
        :param uri_2:   A string with the uri of the 2nd Content Item
        :param cat_id:  A string with the uri of the Category
        :return:        None