Managing Node Settings¶
You can manage the settings on any node (including categories, boards and grouphubs)
using the khoros.core.Khoros.Settings
subclass, which leverages the
khoros.objects.settings
module.
This guide demonstrates various ways that you can retrieve, define and update the node settings within your Khoros Communities environment.
Prerequisites¶
Throughout this guide we will assume that the Khoros core object has already been
instantiated as khoros
as shown below.
>>> from khoros import Khoros
>>> khoros = Khoros(helper='/Users/example/helper.yml')
Retrieving node settings¶
This section demonstrates how easy it is to retrieve a specific setting value from a node.
Caution
These methods and functions assume you are querying a board by default. An additional parameter must be passed in order to query a category or grouphub node, as will be explained.
Retrieving board settings¶
A specific setting for a board can be retrieved using the
khoros.core.Khoros.Settings.get_node_setting()
method, which leverages the
underlying khoros.objects.settings.get_node_setting()
function.
In this method, the first parameter is the name of the setting to retrieve and the second parameter is the Node ID for the node to be queried. Depending on the field name, the method (and underlying function) will attempt to select the appropriate Community API for the job.
For example, because most–if not all–custom settings set up by Khoros within the v2 API begin with
the c_
prefix (with the c
implying custom), if a setting with the name c_primary_moderator
was provided as the first parameter then the v2 API will automatically be selected and a LiQL query will
be utilized to retrieve the value.
Alternatively, as API v1 values are generally defined in namespace
notation, a field with the name custom.primary_moderator
would leverage the v1 API within the method/function
to retrieve the value.
>>> khoros.settings.get_node_setting('c_primary_moderator',
... 'product-blog')
'cmmgr123'
>>> khoros.settings.get_node_setting('custom.primary_moderator',
... 'product-blog')
'cmmgr123'
However, if you want to ensure that the appropriate API version is leveraged then you can explicitly
define it using the v1
parameter by defining it as either True
or False
.
>>> khoros.settings.get_node_setting('c_primary_moderator',
... 'product-blog',
... v1=False)
'cmmgr123'
>>> khoros.settings.get_node_setting('custom.primary_moderator',
... 'product-blog',
... v1=True)
'cmmgr123'
Retrieving category settings¶
Retrieving a node setting from a category is nearly identical to retrieving board settings, with the one caveat that you must explicitly define the node type in the third parameter, as illustrated below.
>>> khoros.settings.get_node_setting('c_primary_moderator',
... 'our-awesome-product',
... 'category')
'cmmgr123'
>>> khoros.settings.get_node_setting('custom.primary_moderator',
... 'our-awesome-product',
... 'category')
'cmmgr123'
Caution
It is important to note that the node type should be defined in singular form rather than in
plural. This means that category
, board
and grouphub
are the three acceptable values.
Retrieving group hub settings¶
Similar to retrieving category settings, you must explicitly define the node type using the grouphub
value
to successfully retrieve the value, as demonstrated below.
>>> khoros.settings.get_node_setting('c_primary_moderator',
... 'api-users-group',
... 'grouphub')
'cmmgr123'
>>> khoros.settings.get_node_setting('custom.primary_moderator',
... 'api-users-group',
... 'grouphub')
'mgr123'
Defining node settings¶
It is just as easy to define or update node settings with this library, which is done using the
khoros.core.Khoros.Settings.define_node_setting()
method and the underlying function
khoros.objects.settings.define_node_setting()
.
The primary difference is that you will obviously need to specify the value of the metadata field when invoking the method. This value will always be a string for custom metadata as this is how said fields are always configured. As such, it is always a good idea to leverage literal string interpolation when there is any uncertainty about the data type.
With the khoros.core.Khoros.Settings.define_node_setting()
method, the first parameter is
the name of the custom field, the second parameter is the value to write to said field, the third
parameter is the Node ID of the affected node and the fourth parameter is the node type.
You will know your operation was successful when the standard success response is received as a JSON string or object, as shown in the examples below.
>>> khoros.settings.define_node_setting('custom.primary_moderator',
... 'johnDoe',
... 'product-blog')
'{"status": "success"}'
>>> khoros.settings.define_node_setting('custom.primary_moderator',
... 'johnDoe',
... 'our-awesome-product',
... 'category')
'{"status": "success"}'
>>> khoros.settings.define_node_setting('custom.primary_moderator',
... 'johnDoe',
... 'api-users-group',
... 'grouphub')
'{"status": "success"}'
Working with JSON strings¶
Utilizing JSON objects in custom metadata can add many opportunities for customization and automation with your community. Rather than just storing a basic text string value in your metadata, you could store multiple values by treating the string as a JSON object.
For example, instead of just tracking the username of the node’s primary moderator as was done in the examples above, you may wish to keep other relevant data in the same field. This could be accomplished with a JSON object similar to the following:
{
"primary_moderator": {
"full_name": "John Doe",
"login": "johnDoe",
"email": "john.doe@example.com"
}
}
By converting the JSON object to a string, you can pass it as the metadata value as shown in the example below.
>>> import json
>>>
>>> # Store the metadata
>>> moderator_info = {
... 'primary_moderator': {
... 'full_name': 'John Doe',
... 'login': 'johnDoe',
... 'email': 'john.doe@example.com'
... }
... }
>>> khoros.settings.define_node_setting('custom.moderator_info',
... json.dumps(moderator_info),
... 'product-blog')
'{"status": "success"}'
>>>
>>> # Retrieve the metadata
>>> data = khoros.settings.get_node_setting('custom.moderator_info',
... 'product-blog')
>>> moderator_info = json.loads(data)
>>> print(f'The primary moderator is ${moderator_info["primary_moderator"]["full_name"]}.')
The primary moderator is John Doe.
You also have the option of using the convert_json
Boolean parameter in the
khoros.settings.get_node_setting()
method to automatically convert the JSON string
to a Python dictionary to save yourself the step of converting it manually with the
json.loads()
function.
>>> data = khoros.settings.get_node_setting('custom.moderator_info',
... 'product-blog',
... convert_json=True)
>>> print(f'The primary moderator is ${data["primary_moderator"]["full_name"]}.')
The primary moderator is John Doe.
Note
A future release will introduce the ability to dump JSON to a string when defining node settings.
Troubleshooting¶
This section addresses some of the most commonly experienced issues when managing node settings.
An unexpected error has occurred when defining a node setting¶
Whenever an attempt is made to define a custom metadata field that does not exist, an
Unexpected Error
message will be returned, as shown below.
>>> khoros.settings.define_node_setting('custom.fake_field',
... 'John Doe',
... 'product-blog')
{'status': 'error', 'error': {'code': 100, 'message': 'An Unexpected Error has occurred.'}}
Unable to define node settings using the API v2 field name¶
Community API v2 metadata field names are considered read-only and have the sole purpose of allowing
you to retrieve the data with a LiQL query. Therefore, it is by design that you are unable to write
to said field. Attempting to do so will likely return an Unexpected Error
message, as shown below.
>>> khoros.settings.define_node_setting('c_primary_moderator',
... 'johnDoe',
... 'product-blog')
{'status': 'error', 'error': {'code': 100, 'message': 'An Unexpected Error has occurred.'}}
No board with the specified dispid error¶
When a Node ID is not recognized in the Khoros Communities environment, the error message
No board with the specified dispid
will be returned in the API response, as shown below.
>>> khoros.settings.get_node_setting('custom.primary_moderator', 'api-users-group')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Users/johndoe/Development/khoros/khoros/core.py", line 3605, in get_node_setting
return objects_module.settings.get_node_setting(self.khoros_object, setting_name, node_id, node_type, v1,
File "/Users/johndoe/Development/khoros/khoros/objects/settings.py", line 58, in get_node_setting
setting_value = _get_v1_node_setting(khoros_object, setting_name, node_id, node_type)
File "/Users/johndoe/Development/khoros/khoros/objects/settings.py", line 125, in _get_v1_node_setting
raise errors.exceptions.GETRequestError(status_code=_settings_data['error']['code'],
khoros.errors.exceptions.GETRequestError: The GET request returned the 101 status code with the following message: No board with the specified dispid.
When this error message is received, you should first ask yourself if the node being queried
matches the node type defined in the parameter. For example, the query above does not have a
node type defined in the parameter, which means it is defaulting to the board
type. However,
the node in question in this circumstance is a group hub, which would explain the error.