Categories Reference Guide
This guide is for version 5.0-rc.6+
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.
| name | arguments | returns |
|---|---|---|
| set_database | db :GraphAccess | None |
IMPORTANT: this method MUST be called before using this class!
:param db: Database-interface object, created with the GraphAccess library
:return: None
|
||
| name | arguments | returns |
|---|---|---|
| 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
|
||
| name | arguments | returns |
|---|---|---|
| get_category_info | category_uri :str | dict |
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}
|
||
| name | arguments | returns |
|---|---|---|
| is_root_category | category_uri :str | bool |
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
|
||
| name | arguments | returns |
|---|---|---|
| get_all_categories | exclude_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} ]
|
||
| name | arguments | returns |
|---|---|---|
| count_subcategories | category_uri :str | int |
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
|
||
| name | arguments | returns |
|---|---|---|
| count_parent_categories | category_uri :str | int |
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
|
||
| name | arguments | returns |
|---|---|---|
| get_subcategories | category_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
|
||
| name | arguments | returns |
|---|---|---|
| get_parent_categories | category_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
|
||
| name | arguments | returns |
|---|---|---|
| get_sibling_categories | category_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']}
|
||
| name | arguments | returns |
|---|---|---|
| create_parent_map | category_uri :str | dict |
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
|
||
| name | arguments | returns |
|---|---|---|
| create_categories_root | data_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
|
||
| name | arguments | returns |
|---|---|---|
| add_subcategory | data_dict :dict, category_uri=None | str |
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)
|
||
| name | arguments | returns |
|---|---|---|
| delete_category | uri :str | None |
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
|
||
| name | arguments | returns |
|---|---|---|
| add_subcategory_relationship | data_dict :dict | None |
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
|
||
| name | arguments | returns |
|---|---|---|
| get_see_also | from_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}]
|
||
| name | arguments | returns |
|---|---|---|
| create_see_also | from_category :str, to_category :str | None |
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
|
||
| name | arguments | returns |
|---|---|---|
| remove_see_also | from_category :str, to_category :str | None |
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
|
||
| name | arguments | returns |
|---|---|---|
| import_ontology | df :pd.DataFrame, root_uri :str | int |
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
|
||
| name | arguments | returns |
|---|---|---|
| viewer_handler | category_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']}
|
||
| name | arguments | returns |
|---|---|---|
| add_relationship_before | from_id :str, to_id :str, rel_name :str | None |
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
|
||
| name | arguments | returns |
|---|---|---|
| remove_relationship_before | from_id: str, to_id :str, rel_name: str | None |
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
|
||
| name | arguments | returns |
|---|---|---|
| create_bread_crumbs | category_uri :str | list |
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'
]
|
||
| name | arguments | returns |
|---|---|---|
| pin_category | uri, op :str | None |
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
|
||
| name | arguments | returns |
|---|---|---|
| is_pinned | uri :str | bool |
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
|
||
| name | arguments | returns |
|---|---|---|
| get_categories_linked_to_content_item | item_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
|
||
| name | arguments | returns |
|---|---|---|
| get_content_items_by_category | uri | [{}] |
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'}
]
|
||
| name | arguments | returns |
|---|---|---|
| add_content_at_beginning | category_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
|
||
| name | arguments | returns |
|---|---|---|
| link_content_at_end | category_uri :str, item_uri :str | None |
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
|
||
| name | arguments | returns |
|---|---|---|
| add_content_at_end | category_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
|
||
| name | arguments | returns |
|---|---|---|
| add_content_after_element | category_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
|
||
| name | arguments | returns |
|---|---|---|
| detach_from_category | category_uri :str, item_uri :str | None |
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
|
||
| name | arguments | returns |
|---|---|---|
| relocate_across_categories | items :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
|
||
| name | arguments | returns |
|---|---|---|
| get_items_schema_data | category_uri :str, exclude_system=True | dict |
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']
}
|
||
| name | arguments | returns |
|---|---|---|
| check_for_duplicates | category_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
|
||
| name | arguments | returns |
|---|---|---|
| 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
|
||
| name | arguments | returns |
|---|---|---|
| reassign_positional_values | category_name :str | None |
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
|
||
| name | arguments | returns |
|---|---|---|
| reposition_content | category_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:
|
||
| name | arguments | returns |
|---|---|---|
| relocate_positions | category_uri :str, n_to_skip: int, pos_shift: int | int |
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
|
||
| name | arguments | returns |
|---|---|---|
| swap_content_items | uri_1 :str, uri_2 :str, cat_id :str | None |
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
|
||