Python API
JSON
- class RPA.JSON.JSON
JSON is a library for manipulating JSON files and strings.
JSON is a common data interchange format inspired by a subset of the Javascript programming language, but these days is a de facto standard in modern web APIs and is language agnostic.
Serialization
The term serialization refers to the process of converting Robot Framework or Python types to JSON or the other way around.
Basic types can be easily converted between the domains, and the mapping is as follows:
JSON
Python
object
dict
array
list
string
str
number (int)
int
number (real)
float
true
True
false
False
null
None
About JSONPath
Reading and writing values from/to JSON serializable objects is done using JSONPath. It’s a syntax designed to quickly and easily refer to specific elements in a JSON structure. The specific flavor used in this library is based on jsonpath-ng.
Compared to Python’s normal dictionary access, JSONPath expressions can target multiple elements through features such as conditionals and wildcards, which can simplify many JSON-related operations. It’s analogous to XPath for XML structures.
Syntax example
For this example consider the following structure:
{ "clients": [ { "name": "Johnny Example", "email": "john@example.com", "orders": [ {"address": "Streetroad 123", "price": 103.20}, {"address": "Streetroad 123", "price": 98.99} ] }, { "name": "Jane Example", "email": "jane@example.com", "orders": [ {"address": "Waypath 321", "price": 22.00}, {"address": "Streetroad 123", "price": 2330.01} ] } ] }
In the simplest case JSONPath can replace nested access:
*** Tasks *** Nested access # First order of first client, with direct dictionary access ${value}= Set variable ${json}["clients"][0]["orders"][0] # JSONPath access ${value}= Get value from JSON ${json} $.clients[0].orders[0]
But the power comes from complicated expressions:
*** Tasks *** Complicated expressions # Find delivery addresses for all orders ${prices}= Get values from JSON $..address # Find orders that cost over 100 ${expensives}= Get values from JSON $..orders[?(@.price>100)]
Supported Expressions
The supported syntax elements are:
Element
Description
$
Root object/element
@
Current object/element inside expressions
.
or[]
Child operator
..
Recursive descendant operator
``parent``
Parent operator, see functions
*
Wilcard, any element
,
Select multiple fields
[n]
Array index
[a:b:c]
Array slice (start, end, step)
[a,b]
Union of indices or names
[?()]
Apply a filter expression
()
Script expression
[\\field]
Sort descending by
field
, cannot be combined with filters.[/field]
Sort ascending by
field
, cannot be combined with filters.``str()``
Convert value to string, see functions
``sub()``
Regex substitution function, see functions
``len``
Calculate value’s length, see functions
``split()``
String split function, see functions
+
-
*
/
Arithmetic functions, see functions
Functions
This library allows JSON path expressions to include certain functions which can provide additional benefit to users. These functions are generally encapsulated in backticks (
`
). Some functions require you to pass arguments similar to a Python function.For example, let’s say a JSON has nodes on the JSON path
$.books[*].genres
which are represented as strings of genres with commas separating each genre. So for one book, this node might have a value likehorror,young-adult
. You can return a list of first genre for each book by using thesplit
function like so:*** Task *** Get genres ${genres}= Get values from JSON $.books[*].genres.```split(,, 0, -1)```
Each functions parameters are defined here:
Function
Usage
str()
No parameters, but parenthesis are required
sub(/regex/, repl)
The regex pattern must be provided in regex and the replacement value provided in repl
len
No parameters and no parenthesis
split(char, segment, max_split)
Separator character provided as char, which index from the resulting array to be returns provided as segment, and maximum number of splits to perform provided as max_split,
-1
for all splits.parent
No parameters, no parenthesis
Arithmetic Functions
JSON Path can be written and combined to concatenate string values or perform arithmetic functions on numerical values. Each JSONPath expression used must return the same type, and when performing such functions between returned lists, each list must be the same length. An example is included in documentation for the keyword
Get values from JSON
.Additional Information
There are a multitude of different script expressions in addition to the elements listed above, which can be seen in the aforementioned article.
For further library usage examples, see the individual keywords.
- ROBOT_LIBRARY_DOC_FORMAT = 'REST'
- ROBOT_LIBRARY_SCOPE = 'GLOBAL'
- add_to_json(doc: Optional[Union[Dict[Hashable, Optional[Union[str, int, float, bool, list, dict]]], List[Optional[Union[str, int, float, bool, list, dict]]], str, int, float, bool, list, dict]], expr: str, value: Optional[Union[Dict[Hashable, Optional[Union[str, int, float, bool, list, dict]]], List[Optional[Union[str, int, float, bool, list, dict]]], str, int, float, bool, list, dict]]) Optional[Union[Dict[Hashable, Optional[Union[str, int, float, bool, list, dict]]], List[Optional[Union[str, int, float, bool, list, dict]]], str, int, float, bool, list, dict]]
Add items into a JSON serializable object and return the result.
If the target is a list, the values are appended to the end. If the target is a dict, the keys are either added or updated.
- Parameters
doc – JSON serializable object
expr – JSONPath expression
value – values to either append or update
- Returns
JSON serializable object of the updated JSON
Robot Framework Example:
*** Task *** Change the name value for all people &{before}= Convert string to JSON {"People": [{"Name": "Mark"}, {"Name": "Jane"}]} &{person}= Create dictionary Name=John &{after}= Add to JSON ${before} $.People ${person}
Python Example:
from RPA.JSON import JSON # Change the name value for all people js = JSON() before = js.convert_string_to_json('{"People": [{"Name": "Mark"}, {"Name": "Jane"}]}') person = {"Name": "John"} after = js.add_to_json(before, "$.People", person) print(after)
- convert_json_to_string(doc: Optional[Union[Dict[Hashable, Optional[Union[str, int, float, bool, list, dict]]], List[Optional[Union[str, int, float, bool, list, dict]]], str, int, float, bool, list, dict]]) str
Convert a JSON serializable object to a string and return it.
- Parameters
doc – JSON serializable object
- Returns
string of the JSON serializable object
Robot Framework Example:
*** Task *** Convert to string ${obj}= Create dictionary Key=Value ${json}= Convert JSON to string ${obj} Should be equal ${json} {"Key": "Value"}
Python Example:
from RPA.JSON import JSON from robot.libraries.BuiltIn import BuiltIn obj = {"Key": "Value"} json = JSON().convert_json_to_string(obj) BuiltIn().should_be_equal(json, '{"Key": "Value"}')
- convert_string_to_json(doc: str) Optional[Union[Dict[Hashable, Optional[Union[str, int, float, bool, list, dict]]], List[Optional[Union[str, int, float, bool, list, dict]]], str, int, float, bool, list, dict]]
Convert a string to a JSON serializable object and return it.
- Parameters
doc – JSON string
- Returns
JSON serializable object of the string
Robot Framework Example:
*** Task *** Convert to json ${json}= Set variable {"Key": "Value"} &{obj}= Convert string to JSON ${json} Should be equal ${obj.Key} Value
Python Example:
from RPA.JSON import JSON from robot.libraries.BuiltIn import BuiltIn json = '{"Key": "Value"}' obj = JSON().convert_string_to_json(json) BuiltIn().should_be_equal(obj["Key"], "Value")
- delete_from_json(doc: Optional[Union[Dict[Hashable, Optional[Union[str, int, float, bool, list, dict]]], List[Optional[Union[str, int, float, bool, list, dict]]], str, int, float, bool, list, dict]], expr: str) Optional[Union[Dict[Hashable, Optional[Union[str, int, float, bool, list, dict]]], List[Optional[Union[str, int, float, bool, list, dict]]], str, int, float, bool, list, dict]]
Delete values from a JSON serializable object and return the result. Will delete all values that match the expression.
- Parameters
doc – JSON serializable object or string
expr – JSONPath expression
- Returns
JSON serializable object with values removed
Example:
*** Task *** Delete all people &{before}= Convert string to JSON {"People": [{"Name": "Mark"}, {"Name": "Jane"}]} &{after}= Delete from JSON ${before} $.People[*]
from RPA.JSON import JSON # Delete all people before = {"People": [{"Name": "Mark"}, {"Name": "Jane"}]} after = JSON().delete_from_json(before, "$.People[*]") print(after)
- get_value_from_json(doc: Optional[Union[Dict[Hashable, Optional[Union[str, int, float, bool, list, dict]]], List[Optional[Union[str, int, float, bool, list, dict]]], str, int, float, bool, list, dict]], expr: str, default: Optional[Any] = None) str
Get a single value from a JSON serializable object that matches the given expression.
Raises a ValueError if there is more than one match. Returns the given default argument (or None) if there were no matches.
- Parameters
doc – JSON serializable object or string
expr – jsonpath expression
default – default value to return in the absence of a match
- Returns
string containing the match OR default if there are no matches
- Raises
ValueError – if more than one match is discovered
Short Robot Framework Example:
*** Task *** Get the name value for the first person &{people}= Convert string to JSON {"People": [{"Name": "Mark"}, {"Name": "Jane"}]} ${first}= Get value from JSON ${people} $.People[0].Name
Short Python Example:
from RPA.JSON import JSON # Get the name value for the second person. people = {"People": [{"Name": "Mark"}, {"Name": "Jane"}]} second = JSON().get_value_from_json(people, "$.People[1].Name") print(second)
Extended Robot Framework Example:
*** Settings *** Library RPA.JSON Suite Setup Ingest JSON *** Variables *** ${JSON_STRING} { ... "clients": [ ... { ... "name": "Johnny Example", ... "email": "john@example.com", ... "orders": [ ... {"address": "Streetroad 123", "state": "TX", "price": 103.20, "id":"guid-001"}, ... {"address": "Streetroad 123", "state": "TX", "price": 98.99, "id":"guid-002"} ... ] ... }, ... { ... "name": "Jane Example", ... "email": "jane@example.com", ... "orders": [ ... {"address": "Waypath 321", "state": "WA", "price": 22.00, "id":"guid-003"}, ... {"address": "Streetroad 123", "state": "TX", "price": 2330.01, "id":"guid-004"}, ... {"address": "Waypath 321", "state": "WA", "price": 152.12, "id":"guid-005"} ... ] ... } ... ] ... } ${ID} guid-003 *** Tasks *** Get email for specific order id ${email}= Get value from json ${JSON_DOC} $.clients[?(@..id=="${ID}")].email Log \nOUTPUT IS\n ${email} console=${True} Should be equal as strings ${email} jane@example.com *** Keywords *** Ingest JSON ${doc}= Convert string to json ${JSON_STRING} Set suite variable ${JSON_DOC} ${doc}
- get_values_from_json(doc: Optional[Union[Dict[Hashable, Optional[Union[str, int, float, bool, list, dict]]], List[Optional[Union[str, int, float, bool, list, dict]]], str, int, float, bool, list, dict]], expr: str) list
Get all values from a JSON serializable object that match the given expression.
- Parameters
doc – JSON serializable object or string
expr – JSONPath expression
- Returns
list of values that match
Short Robot Framework Example:
*** Task *** Get all the names for all people &{people}= Convert string to JSON {"People": [{"Name": "Mark"}, {"Name": "Jane"}]} @{names}= Get values from JSON ${people} $.People[*].Name
Short Python Example:
from RPA.JSON import JSON # Get all the names for all people people = {"People": [{"Name": "Mark"}, {"Name": "Jane"}]} names = JSON().get_values_from_json(people, "$.People[*].Name") print(second)
Extended Robot Framework Example:
*** Settings *** Library RPA.JSON Suite Setup Ingest JSON *** Variables *** ${JSON_STRING} { ... "clients": [ ... { ... "name": "Johnny Example", ... "email": "john@example.com", ... "orders": [ ... {"address": "Streetroad 123", "state": "TX", "price": 103.20, "id":"guid-001"}, ... {"address": "Streetroad 123", "state": "TX", "price": 98.99, "id":"guid-002"} ... ] ... }, ... { ... "name": "Jane Example", ... "email": "jane@example.com", ... "orders": [ ... {"address": "Waypath 321", "state": "WA", "price": 22.00, "id":"guid-003"}, ... {"address": "Streetroad 123", "state": "TX", "price": 2330.01, "id":"guid-004"}, ... {"address": "Waypath 321", "state": "WA", "price": 152.12, "id":"guid-005"} ... ] ... } ... ] ... } ${ID} guid-003 *** Tasks *** Get All Prices and Order Ids # Arithmetic operations only work when lists are of equal lengths and types. ${prices}= Get values from json ... ${JSON_DOC} ... $.clients[*].orders[*].id + " has price " + $.clients[*].orders[*].price.```str()``` Log \nOUTPUT IS\n ${prices} console=${True} Should be equal as strings ${prices} ... ['guid-001 has price 103.2', 'guid-002 has price 98.99', 'guid-003 has price 22.0', 'guid-004 has price 2330.01', 'guid-005 has price 152.12'] Find Only Valid Emails With Regex # The regex used in this example is simplistic and # will not work with all email addresses ${emails}= Get values from json ... ${JSON_DOC} ... $.clients[?(@.email =~ "[a-zA-Z]+@[a-zA-Z]+\.[a-zA-Z]+")].email Log \nOUTPUT IS\n ${emails} console=${True} Should be equal as strings ${emails} ['john@example.com', 'jane@example.com'] Find Orders From Texas Over 100 # The regex used in this example is simplistic and # will not work with all email addresses ${orders}= Get values from json ... ${JSON_DOC} ... $.clients[*].orders[?(@.price > 100 & @.state == "TX")] Log \nOUTPUT IS\n ${orders} console=${True} Should be equal as strings ${orders} ... [{'address': 'Streetroad 123', 'state': 'TX', 'price': 103.2, 'id': 'guid-001'}, {'address': 'Streetroad 123', 'state': 'TX', 'price': 2330.01, 'id': 'guid-004'}] *** Keywords *** Ingest JSON ${doc}= Convert string to json ${JSON_STRING} Set suite variable ${JSON_DOC} ${doc}
- load_json_from_file(filename: str, encoding='utf-8') Optional[Union[Dict[Hashable, Optional[Union[str, int, float, bool, list, dict]]], List[Optional[Union[str, int, float, bool, list, dict]]], str, int, float, bool, list, dict]]
Load JSON data from a file, and return it as JSON serializable object. Depending on the input file the object can be either a dictionary, a list, or a scalar value.
- Parameters
filename – path to input file
encoding – file character encoding
- Returns
JSON serializable object of the JSON file
Example:
*** Task *** Load json &{auth}= Load JSON from file auth.json Log Current auth token: ${auth.token}
- save_json_to_file(doc: Optional[Union[Dict[Hashable, Optional[Union[str, int, float, bool, list, dict]]], List[Optional[Union[str, int, float, bool, list, dict]]], str, int, float, bool, list, dict]], filename: str, indent: Optional[int] = None, encoding: str = 'utf-8') None
Save a JSON serializable object or a string containing a JSON value into a file.
- Parameters
doc – JSON serializable object or string
filename – path to output file
indent – if given this value is used for json file indent
encoding – file character encoding
Robot Framework Example:
*** Tasks *** Save dictionary to file ${john}= Create dictionary name=John mail=john@example.com Save JSON to file ${john} john.json Save string to file ${mark}= Set variable {"name": "Mark", "mail": "mark@example.com"} Save JSON to file ${mark} mark.json
Python Example:
from RPA.JSON import JSON # Save dictionary to file. john = {"name": "John", "mail": "john@example.com"} JSON().save_json_to_file(john, "john.json")
- update_value_to_json(doc: Optional[Union[Dict[Hashable, Optional[Union[str, int, float, bool, list, dict]]], List[Optional[Union[str, int, float, bool, list, dict]]], str, int, float, bool, list, dict]], expr: str, value: Optional[Union[Dict[Hashable, Optional[Union[str, int, float, bool, list, dict]]], List[Optional[Union[str, int, float, bool, list, dict]]], str, int, float, bool, list, dict]]) Optional[Union[Dict[Hashable, Optional[Union[str, int, float, bool, list, dict]]], List[Optional[Union[str, int, float, bool, list, dict]]], str, int, float, bool, list, dict]]
Update existing values in a JSON serializable object and return the result. Will change all values that match the expression.
- Parameters
doc – JSON or string
expr – JSONPath expression
value – New value for the matching item(s)
- Returns
JSON serializable object with updated results
Short Robot Framework Example:
*** Tasks *** Change the name key for all people &{before}= Convert string to JSON {"People": [{"Name": "Mark"}, {"Name": "Jane"}]} &{after}= Update value to JSON ${before} $.People[*].Name JohnMalkovich
from RPA.JSON import JSON # Change the name key for all people before = {"People": [{"Name": "Mark"}, {"Name": "Jane"}]} after = JSON().update_value_to_json(before, "$.People[*].Name","JohnMalkovich") print(after)
Extended Robot Framework Example:
*** Settings *** Library RPA.JSON Library Collections Suite Setup Ingest JSON *** Variables *** ${JSON_STRING} { ... "clients": [ ... { ... "name": "Johnny Example", ... "email": "john@example.com", ... "id": "user-001", ... "orders": [ ... {"address": "Streetroad 123", "state": "TX", "price": 103.20, "id":"guid-001"}, ... {"address": "Streetroad 123", "state": "TX", "price": 98.99, "id":"guid-002"} ... ] ... }, ... { ... "name": "Jane Example", ... "email": "jane@example.com", ... "id": "user-002", ... "orders": [ ... {"address": "Waypath 321", "state": "WA", "price": 22.00, "id":"guid-003"}, ... {"address": "Streetroad 123", "state": "TX", "price": 2330.01, "id":"guid-004"}, ... {"address": "Waypath 321", "state": "WA", "price": 152.12, "id":"guid-005"} ... ] ... } ... ] ... } ${ID} guid-003 *** Tasks *** Update user email ${updated_doc}= Update value to json ... ${JSON_DOC} ... $.clients[?(@.id=="user-001")].email ... johnny@example.com Log \nNEW JSON IS\n ${updated_doc} console=${True} ${new_email}= Get value from json ${updated_doc} $.clients[?(@.id=="user-001")].email Should be equal as strings ${new_email} johnny@example.com Add additional charge to all prices in WA # This example also shows how the update keyword changes the original JSON doc in memory. ${id_price}= Get values from json ... ${JSON_DOC} ... $.clients[*].orders[?(@.state=="WA")].id,price FOR ${order_id} ${price} IN @{id_price} Update value to json ${JSON_DOC} $.clients[*].orders[?(@.id=="${order_id}")].price ${{${price} * 1.06}} END Log \nNEW JSON IS\n ${JSON_DOC} console=${True} ${one_price}= Get value from json ${JSON_DOC} $..orders[?(@.id==${ID})].price Should be equal as numbers ${one_price} 23.32 *** Keywords *** Ingest JSON ${doc}= Convert string to json ${JSON_STRING} Set suite variable ${JSON_DOC} ${doc}