Sandhill API Reference
This document provides API reference for Sandhill code not covered by the user documentation. If you plan on developing additional data processors, filters, or the like, this may be useful. Otherwise, you can safely ignore these documentation pages.
Routes
Core routing API should not be needed even when developing new functionality for your instance. Still, it's provided here for the curious.
sandhill.routes.static
Sandhill overrides/additions to the default Flask /static
route.
favicon()
Wrapper to calling handle_static for the ever popular favicon file.
Returns:
Type | Description |
---|---|
file stream
|
The favicon.ico file stream from inside |
Raises:
Type | Description |
---|---|
HTTPException
|
On HTTP error |
Source code in sandhill/routes/static.py
handle_static(filename)
Replacement for the default Flask /static
path handler. Retrieves the requested static file by first looking for it inside the instance/static/
directory. If the file is not found, this method will then look for the file in the core sandhill/templates/
directory.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
filename |
str
|
The requested file path within |
required |
Returns:
Type | Description |
---|---|
file stream
|
File stream of the file object |
Raises:
Type | Description |
---|---|
HTTPException
|
On HTTP error |
Source code in sandhill/routes/static.py
sandhill.routes.error
Sandhill HTTP error handling
handle_http_abort(exc)
Overrides the default Flask template for abort codes.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
exc |
HTTPException
|
A HTTPException from a 4xx or 5xx HTTP code |
required |
Returns:
Type | Description |
---|---|
Response
|
The Flask error response |
Source code in sandhill/routes/error.py
sandhill.routes.main
The main route provides the entry point for Sandhill, loading and adding routes.
add_routes()
Decorator function that adds all routes to the Flask app based on JSON route configs loaded from instance/configs/routes/
.
Source code in sandhill/routes/main.py
main(*args, **kwargs)
Entry point for the whole Sandhill application, handling all routes and determining if a route has output to respond with after all processing is completed.
Based on the route_config that the path matches to, it will load all the required data processors before rendering the result.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
*args |
Unused |
()
|
|
**kwargs |
Unused |
{}
|
Returns:
Type | Description |
---|---|
A valid response for Flask to render out, or raises HTTP 500 |
Source code in sandhill/routes/main.py
Data Processors
Sandhill routes are composed of a list of data processors. These are single actions that Sandhill may take while processing a request. See the data processor documentation for full details.
Utils
Utilities are bits of helper code used elsewhere in Sandhill. Functions or
classes in utils/
may be useful in writing instance specific code for your
Sandhill site.
sandhill.utils.api
Functionality to support API calls.
api_get(**kwargs)
Perform an API call using requests.get()
and return the response object. This function adds logging surrounding the call.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
**kwargs |
dict
|
Arguments to |
{}
|
Raises:
Type | Description |
---|---|
RequestException
|
If the call cannot return a response. |
Source code in sandhill/utils/api.py
api_get_multi(requests_kwargs)
Perform multiple API calls in parellel using futures, returning a list of responses.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
requests_kwargs |
list of dict
|
Each arguments to [ |
required |
Returns:
Type | Description |
---|---|
A generator yielding response objects |
Source code in sandhill/utils/api.py
establish_url(url, fallback)
Set URL to fallback if provided URL is none; also checks the URL validity.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
url |
str
|
A possible URL. |
required |
fallback |
str
|
A secondary URL to fallback to if |
required |
Raises:
Type | Description |
---|---|
HTTPException
|
If URL to be returned is not a valid formatted URL. |
Source code in sandhill/utils/api.py
sandhill.utils.config_loader
Utilities for loading of loading config/
files.
get_all_routes(routes_dir='config/routes/')
Finds all routes in JSON files with within given directory and order them according to the desired load order.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
routes_dir |
str
|
The directory to look for route configs. |
'config/routes/'
|
Returns:
Type | Description |
---|---|
list
|
All of the route rules found in desired order. |
Source code in sandhill/utils/config_loader.py
load_json_config(file_path)
Load a JSON file.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
file_path |
str
|
The full path to the JSON file to load |
required |
Returns:
Type | Description |
---|---|
dict
|
The contents of the loaded JSON file, or an empty dictionary upon error loading or parsing the file. |
Source code in sandhill/utils/config_loader.py
load_json_configs(path, recurse=False)
Loads all the config files in the provided path.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
path |
string
|
The directory path from which to load the config files. |
required |
recurse |
bool
|
If set to True, does a recursive walk into the path. |
False
|
Returns:
Type | Description |
---|---|
dict
|
Dictionary with keys of each file path and values of their loaded JSON. |
Source code in sandhill/utils/config_loader.py
load_route_config(route_rule, routes_dir='config/routes/')
Return the json data for the provided directory.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
route_rule |
str
|
the route rule to match to in the json configs (the |
required |
routes_dir |
str
|
the path to look for route configs. Default = config/routes/ |
'config/routes/'
|
Returns:
Type | Description |
---|---|
OrderedDict
|
The loaded json of the matched route config, or empty dict if not found |
Source code in sandhill/utils/config_loader.py
load_routes_from_configs(routes_dir='config/routes/')
Given a path relative to the instance/
dir, load all JSON files within and extract the "route" keys.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
routes_dir |
string
|
The relative path to the JSON files |
'config/routes/'
|
Returns:
Type | Description |
---|---|
list
|
A list of routes from the configs |
Source code in sandhill/utils/config_loader.py
sandhill.utils.context
Context related functionality
app_context()
Create a flask app context if not already present.
Returns:
Type | Description |
---|---|
A context manager class instance. |
Source code in sandhill/utils/context.py
context_processors()
The list of Sandhill context processor functions.
Returns:
Type | Description |
---|---|
dict
|
Context processors mapped as: name => function |
Source code in sandhill/utils/context.py
list_custom_context_processors()
Get the full list of the available custom context processors.
Returns:
Type | Description |
---|---|
list
|
A list of strings of the context processor names. |
Source code in sandhill/utils/context.py
sandhill.utils.error_handling
Methods to help handle errors
catch(exc_class, exc_msg=None, **kwargs)
Decorator to catch general exceptions and handle in a standarized manor.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
exc_class |
Exception
|
Type of exception to catch |
required |
exc_msg |
String) (optional
|
Message to log; the parameter Ex: |
None
|
**kwargs |
Optional arguments: return_val (Any): Value to return after the exception has been handled return_arg (str): Function kwarg to be returned after the exception has been handled abort (int): Status code to abort with |
{}
|
Returns:
Type | Description |
---|---|
Any
|
Only if return_val or return_arg is provided in kwargs. |
Raises:
Type | Description |
---|---|
HTTPException
|
If no return_val or return_arg is provided in kwargs. |
Examples:
@catch(KeyError, "Some error message", return_val=None)
def myfunc():
...
@catch((KeyError, IndexError), "Some error message", return_arg='myval')
def myfunc(myval):
...
Source code in sandhill/utils/error_handling.py
dp_abort(http_code)
Data processor abort. Will abort with the given status code if the data processor has an on_fail
key set and the value is 0
.
If the value is non-0
, the 'on_fail' code will override the passed code.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
http_code |
int
|
A valid HTTP status code |
required |
Raises:
Type | Description |
---|---|
HTTPException
|
Can raises exception if data processor's |
Source code in sandhill/utils/error_handling.py
sandhill.utils.generic
Generic functions that could be used in most any context.
getconfig(name, default=None)
Get the value of the given config name. It will first check in the environment for the variable name, otherwise look in the app.config, otherwise use the default param
Parameters:
Name | Type | Description | Default |
---|---|---|---|
name |
str
|
Name of the config variable to look for |
required |
default |
str | None
|
The defaut value if not found elsewhere |
None
|
Returns:
Type | Description |
---|---|
str
|
Value of the config variable, default value otherwise |
Source code in sandhill/utils/generic.py
getdescendant(obj, list_keys, extract=False, put=None)
Gets key values from the dictionary/list if they exist;
will check recursively through the obj
.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
obj |
dict | list
|
A dict/list to check, possibly containing nested dicts/lists. |
required |
list_keys |
list | str
|
List of descendants to follow (or . delimited string) |
required |
extract |
bool
|
If set to true, will remove the last matching value from the |
False
|
put |
Any
|
Replace the found value with this new value in the |
None
|
Returns:
Type | Description |
---|---|
Any
|
The last matching value from list_keys, or None if no match |
Raises:
Type | Description |
---|---|
IndexError
|
When attempting to put a list index that is invalid. |
Examples:
# Get "key1" of mydict, then index 2 of that result, then "key3" of that result
v = getdescendant(mydict, "key1.2.key3")
# Same as above, only also remove the found item from mydict
v = getdescendant(mydict, "key1.2.key3", extract=True)
# Replace value with new value
v = getdescendant(mydict, "key1.2.key3", put="Replacement value!")
# Append to a list
v = getdescendant(mydict, "key1.2.[]", put="Append this value.")
Source code in sandhill/utils/generic.py
getmodulepath(path)
Get the Python module path for a directory or file in Sandhill
Parameters:
Name | Type | Description | Default |
---|---|---|---|
path |
str
|
A file or dir path in Sandhill |
required |
Returns:
Type | Description |
---|---|
str
|
module (e.g. 'instance' or 'sandhill.filters.filters') |
Source code in sandhill/utils/generic.py
ifnone(*args)
Returns the default value if the key is not in the dictionary or if a non-dictionary is provided it will return the default if it is not set.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
*args |
Any
|
With 3 args:
With 2 args:
|
()
|
Returns:
Type | Description |
---|---|
(Any) The default_value if the value is None or the key is not in the dict. |
Raises:
Type | Description |
---|---|
TypeError
|
If invalid number of arguments passed. |
Source code in sandhill/utils/generic.py
overlay_dicts_matching_key(target: list[dict], overlays: list[dict], key: Hashable)
Given the target, find and replace matching dicts, for all matching dicts in the list of overlays, using the value for the provided key to compare them.
For each overlay dict, overlay the values on top of any matching original dict from the target.
If multiple overlays match an original target dict, both overlays will use the original dict as a base for the overlay.
If no matching dict was found in the original target list, the overlay will be appended to the target as is.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
target |
list
|
The list of dicts to search and update. |
required |
overlays |
list
|
The list of dict match and overlay. |
required |
key |
Hashable
|
The key (both dicts) for the comparison value. |
required |
Source code in sandhill/utils/generic.py
pop_dict_matching_key(haystack: list[dict], match: dict, key: Hashable) -> list[dict]
Search the haystack for all dicts that have the same value as the passed match dict for the given key.
Matched dicts are removed from the haystack and returned as a list.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
haystack |
list
|
A list of dicts to search through. |
required |
match |
dict
|
The dict to match against. |
required |
key |
Hashable
|
The key (both dicts) for the comparison value. |
required |
Returns:
Type | Description |
---|---|
list
|
A list of matching dicts removed from the haystack. |
Source code in sandhill/utils/generic.py
recursive_merge(dict1: dict, dict2: dict, sanity: int = 100) -> dict
Given 2 dictionaries, merge them together, overriding dict1 values by dict2 if existing in both.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
dict1 |
dict
|
Base dictionary, keys will be overridden if the keys are in both. |
required |
dict2 |
dict
|
Prioritized dictionary, keys will be kept if the keys are in both. |
required |
sanity |
int
|
The depth to reach before raising an error. |
100
|
Returns:
Name | Type | Description |
---|---|---|
dict |
dict
|
dict1 and dict2 merged |
Raises:
Type | Description |
---|---|
RecursionError
|
if dictionary depth reaches sanity |
TypeError
|
dict1 and dict2 needs to be dictionaries, sanity needs to be an integer |
Source code in sandhill/utils/generic.py
tolist(*args)
Combine arguments, appending them to a list; args may be scalars or lists. If args is a list, then the values of the list are appended (not the list itself).
Parameters:
Name | Type | Description | Default |
---|---|---|---|
*args |
Any
|
Items to combine. |
()
|
Returns:
Type | Description |
---|---|
list
|
The combined list. |
Source code in sandhill/utils/generic.py
tolistfromkeys(fromdict, *args)
From a given dict, find all keys and return them within a list.
If found keys are already a list, then extends the return list with the matched value instead of appending a list within a list.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
fromdict |
dict
|
Dictionary to search within. |
required |
*args |
str | int
|
Keys to find. |
()
|
Returns:
Type | Description |
---|---|
list
|
The list with found key values. |
Source code in sandhill/utils/generic.py
touniquelist(*args)
Combine arguments while excluding duplicate values. Same functionality as tolist()
only with duplicate values being removed.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
*args |
Any
|
Items to combine. |
()
|
Returns:
Type | Description |
---|---|
list
|
The combined list with duplicates removed. |
Source code in sandhill/utils/generic.py
utils.html.HTMLTagFilter
Class used to filter through HTML and remove all tags except for those set as allowed.
Used by the filtertags()
template filter.
sandhill.utils.jsonpath
Wrapper functions for JSONPath queries.
find(data, path=None, deepcopy=True)
Get the values for a given JSONPath.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
data |
dict | list
|
The JSON data |
required |
path |
str
|
The JSONPath to find |
None
|
Returns:
Type | Description |
---|---|
list
|
A list of matches, empty if none found |
Source code in sandhill/utils/jsonpath.py
put(data, path, value, deepcopy=True)
Set a value at the given JSONPath location.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
data |
dict | list
|
The JSON data |
required |
path |
str
|
The JSONPath to find Last element in path will be removed, which must be a specific Field or Index only |
required |
value |
any
|
The value to set |
required |
Returns:
Type | Description |
---|---|
dict | list
|
The modified JSON data |
Source code in sandhill/utils/jsonpath.py
append(data, path, value, deepcopy=True)
Append a value to the given JSONPath location. Location must be a list.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
data |
dict | list
|
The JSON data |
required |
path |
str
|
The JSONPath to a list(s) |
required |
value |
any
|
The value to append |
required |
Returns:
Type | Description |
---|---|
dict | list
|
The modified JSON data |
Source code in sandhill/utils/jsonpath.py
delete(data, path, deepcopy=True)
Delete item(s) from JSON data.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
data |
dict | list
|
The JSON data |
required |
path |
str
|
The JSONPath to the object(s) to delete Last element in path will be removed, which must be a specific Field or Index only |
required |
Returns:
Type | Description |
---|---|
dict | list
|
The modified JSON data |
Source code in sandhill/utils/jsonpath.py
eval_within(string: str, context: dict)
Given a string containing JSONPath queries, replace the queries with the values they found.
JSONPath queries will query within the context.
Example context
Example query strings
# No given context
"$.elem1.elem2" # would query the first item in the context dictionary
# Specified conext
"$parent.elem3" # would query the the "parent" key in the context dictionary
Parameters:
Name | Type | Description | Default |
---|---|---|---|
string |
str
|
The string to search within for JSONPath queries |
required |
context |
dict
|
A dictionary of contexts upon which a JSONPath could query. |
required |
Source code in sandhill/utils/jsonpath.py
sandhill.utils.request
Client request related functions
match_request_format(view_args_key, allowed_formats, default_format='text/html')
Match a request mimetype to the given view_args_key or the allowed mimetypes provided by client.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
view_args_key |
str | None
|
the key in the url request to check within for matching format. |
required |
allowed_formats |
list
|
list of acceptable mimetypes. |
required |
default_format |
str
|
the mimetype to use by default if view_args_key value is not allowed. |
'text/html'
|
Returns:
Name | Type | Description |
---|---|---|
result_format |
str
|
the mimetype for the format to return. |
Source code in sandhill/utils/request.py
overlay_with_query_args(query_config, request_args=None, *, allow_undefined=False)
Given a query config, overlay request.args on the defaults to generate a combined list of query arguments
Parameters:
Returns:
Type | Description |
---|---|
dict
|
A dict of the combined query arguments |
Source code in sandhill/utils/request.py
utils.solr.Solr
Class for handling Solr related logic, such as encoding/decoding.
sandhill.utils.template
Template and Jinja2 utilities
evaluate_conditions(conditions, ctx, match_all=True)
Render each conditions' evaluate
using the given context; the result must match a value in the conditions' match_when
or none of the conditions' match_when_not
.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
conditions |
list
|
List of dict containing keys 'value' and 'allowed' |
required |
ctx |
dict
|
Context dictionary for template variables |
required |
match_all |
bool
|
If all conditions need to be matched for it to be considered a match. Default: True |
True
|
Returns:
Type | Description |
---|---|
int
|
returns the number of matches matched ONLY if all are matched, else returns 0 |
Raises:
Type | Description |
---|---|
KeyError
|
when "match_when"/"match_when_not" or "evaluate" is not in conditions |
Source code in sandhill/utils/template.py
render_template_json(json_obj, ctx)
Serialize a JSON, render it as a template, then convert back to JSON
Parameters:
Name | Type | Description | Default |
---|---|---|---|
json_obj |
dict | list
|
JSON represented in Python |
required |
ctx |
dict
|
Context for the jinja template |
required |
Returns:
Type | Description |
---|---|
dict | list
|
The updated JSON structure |
Raises:
Type | Description |
---|---|
JSONDecodeError
|
If the resulting templace is unable to be parsed as JSON |
Source code in sandhill/utils/template.py
render_template_string(template_str, ctx)
Renders Jinja templates with added Sandhill filters/context processors.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
template_str |
string
|
jinja template variable |
required |
ctx |
dict
|
Context for the jinja template |
required |
Returns:
Type | Description |
---|---|
str
|
The rendered template as a string. |
Raises:
Type | Description |
---|---|
TemplateError
|
On invalid template. |
Source code in sandhill/utils/template.py
sandhill.utils.test
Dummy functions for use in unit tests.
sandhill.utils.xml
XML loading and handling functionality.
load(source) -> etree._Element
Load an XML document.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
source |
XML source. Either path, url, string, or loaded LXML Element |
required |
Returns:
Type | Description |
---|---|
_Element
|
Loaded XML object tree, or None on invalid source |
Source code in sandhill/utils/xml.py
xpath(source, query) -> list
Retrieve the matching xpath content from an XML source
Parameters:
Name | Type | Description | Default |
---|---|---|---|
query |
str
|
XPath query to match against |
required |
source |
XML source. Either path, url, or string |
required |
Returns:
Type | Description |
---|---|
list
|
Matching results from XPath query, or None on failure |
Source code in sandhill/utils/xml.py
xpath_by_id(source, query) -> dict
For the matching xpath content, organize into dict with key being the id param of the matched tags. Elements without an id attribute will not be returned.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
query |
str
|
XPath query to match against |
required |
source |
XML source. Either path, url, or string |
required |
Returns:
Type | Description |
---|---|
dict | None
|
Dict mapping with keys of id, and values of content within matching elements, or None on failure |
Source code in sandhill/utils/xml.py
Bootstrap
This is the code that starts up Sandhill, initializing the application. Have a look at the bootstrap documentation for more details.
bootstrap
The core of the bootstrap module handles, among other things, loading other Python code.
bootstrap.request
Standard changes Sandhill makes to the default Flask request
object.
Specifically, it:
- Adds
query_args
, a normal Python dictionary with args as keys.
bootstrap.g
Standard changes Sandhill makes to the default Flask g
object.
Specifically, it:
- Adds
instance_path
available ing
object.
bootstrap.debugtoolbar
Bootstrap hook to add FlaskDebugToolbar to the Flaks application when debug mode is enabled.
bootstrap.disable_debug_caching
sandhill.bootstrap.disable_debug_caching.disable_browser_cache(response)
Adds headers to disable browser caching when app is in debug mode.