https://github.com/qequ/jmespathcustomfunctions
https://github.com/qequ/jmespathcustomfunctions
Last synced: about 1 year ago
JSON representation
- Host: GitHub
- URL: https://github.com/qequ/jmespathcustomfunctions
- Owner: qequ
- Created: 2022-06-22T17:45:45.000Z (almost 4 years ago)
- Default Branch: main
- Last Pushed: 2022-06-22T18:07:12.000Z (almost 4 years ago)
- Last Synced: 2024-10-12T00:42:32.959Z (over 1 year ago)
- Language: Python
- Size: 4.88 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.rst
Awesome Lists containing this project
README
jmespathCustomFunctions
========
Custom Functions
~~~~~~~~~~~~~~~~
(Reference: `jmespath.py repo `__)
The JMESPath language has numerous
`built-in functions
`__, but it is
also possible to add your own custom functions. Keep in mind that
custom function support in jmespath.py is experimental and the API may
change based on feedback.
**If you have a custom function that you've found useful, consider submitting
it to jmespath.site and propose that it be added to the JMESPath language.**
You can submit proposals
`here `__.
To create custom functions:
* Create a subclass of ``jmespath.functions.Functions``.
* Create a method with the name ``_func_``.
* Apply the ``jmespath.functions.signature`` decorator that indicates
the expected types of the function arguments.
* Provide an instance of your subclass in a ``jmespath.Options`` object.
Below are a few examples:
.. code:: python
import jmespath
from jmespath import functions
# 1. Create a subclass of functions.Functions.
# The function.Functions base class has logic
# that introspects all of its methods and automatically
# registers your custom functions in its function table.
class CustomFunctions(functions.Functions):
# 2 and 3. Create a function that starts with _func_
# and decorate it with @signature which indicates its
# expected types.
# In this example, we're creating a jmespath function
# called "unique_letters" that accepts a single argument
# with an expected type "string".
@functions.signature({'types': ['string']})
def _func_unique_letters(self, s):
# Given a string s, return a sorted
# string of unique letters: 'ccbbadd' -> 'abcd'
return ''.join(sorted(set(s)))
# Here's another example. This is creating
# a jmespath function called "my_add" that expects
# two arguments, both of which should be of type number.
@functions.signature({'types': ['number']}, {'types': ['number']})
def _func_my_add(self, x, y):
return x + y
# 4. Provide an instance of your subclass in a Options object.
options = jmespath.Options(custom_functions=CustomFunctions())
# Provide this value to jmespath.search:
# This will print 3
print(
jmespath.search(
'my_add(`1`, `2`)', {}, options=options)
)
# This will print "abcd"
print(
jmespath.search(
'foo.bar | unique_letters(@)',
{'foo': {'bar': 'ccbbadd'}},
options=options)
)
Another example
.. code:: python
import jmespath
from jmespath import functions
class RemoveFunctions(functions.Functions):
@functions.signature({'types': ['object'], "variadic": True}, {'types': ['boolean']})
def _func_remove_null(self, obj, recursive):
if recursive:
return self._func_remove_recursive(obj, None)
else:
return self._func_remove(obj, None)
@functions.signature({'types': ['object'], "variadic": True}, {'types': ['boolean']})
def _func_remove_empty(self, obj, recursive):
if recursive:
return self._func_remove_recursive(obj, None, '')
else:
return self._func_remove(obj, None, '')
def _func_remove(self, obj, *args):
return {k: v for k, v in obj.items() if not v in list(args)}
def _func_remove_recursive(self, obj, *args):
ret_dict = {}
for k in obj:
if not obj[k] in list(args):
ret_dict[k] = obj[k]
if isinstance(obj[k], dict):
ret_dict[k] = self._func_remove_recursive(obj[k], *args)
return ret_dict
options = jmespath.Options(custom_functions=RemoveFunctions())
# print: {'a': 'a', 'd': {'b': 'b'}}
print(
jmespath.search(
'{a: `a`, c: null, d: {a: null, b: `b`}} | remove_empty(@, `true`)', {}, options=options)
)
# print {'a': 'a', 'd': {'b': 'b'}}
print(
jmespath.search(
'{a: `a`, c: null, d: {a: null, b: `b`, c:``}} | remove_empty(@, `true`)', {}, options=options)
)