Skip to main content

pyspecter

Python version PyPI version PyPI download

A Python library to query nested structure, inspired by specter

If you are dealing with nested python structure and it require complex rule to search the data underneath like:

  • Key start with a pattern
  • Value to be filter
  • Conditional path to walk into
  • ...

this is the right library fit the use case as it extract the Navigation rule to a list, saving your a lot of trouble writting your own logic to navigate the nested data.

Get started

image

Examples

m = {"A":{"B1":[10,20],"B2":2,"B3":3}
     ,"C":{"B1":[1,2],"B2":[3,4]}
     ,"D":[1,2,3,4]
     ,"E":[None,2,3,4]
     ,"F":{"G":1}
     ,"H":["A1","A2","A3"]}

Navigate to specific item

FIRST/LAST

assert query(m, ["D", S.FIRST]) == 1
assert query(m, ["A", S.FIRST]) == ("B1", [10, 20]) # first element from dict.items()

assert query(m, ["D", S.LAST]) == 4
assert query(m, ["A", S.LAST]) == ("B3", 3) # last element from dict.items()

Nth

Navigate to the Nth element

assert query(m, ["D", (S.NTH, 1)]) == 2
assert query(m, ["D",(S.NTH, 1, 2)]) == [ 2, 3 ]

Operation on dict

Navigate to values or keys of current position

assert query(m, ["C", S.MVALS]) == [[1, 2], [3, 4]]
assert query(m, ["C", S.MKEYS]) == ['B1', 'B2']

Navigate to a sub map of current position

assert query(m, ["A", (S.SUB_MAP, "B1")]) == {"B1":[10,20]}

Annotate with index with current position

assert query(m, ["A", S.INDEXED_VALS]) == [(0, ("B1", [10,20])), (1, ("B2", 2)), (2, ("B3", 3))]
assert query(m, ["C", "B1", S.INDEXED_VALS]) == [(0, 1), (1, 2)]

Filtering

filter elements by supplying a function

assert query(m, ["A", "B1", (S.FILTER, lambda x: x > 10)]) == [20]
assert query(m, ["C", (S.FILTER, lambda k, v: k.endswith("2"))]) == [[3, 4]]

Navigate to map which its key or value satisify a custom function

assert query(m, ["A", (S.MKEY_IF, lambda x:x.endswith("1"))]) == [[10, 20]]
assert query(m, ["A", (S.MVAL_IF, lambda x:x==[10,20])]) == [[10, 20]]

Branching paths

Branching by multiple paths

mpath = {"A":{"B":1,
              "C":[2,3,4,5]}}
assert query(mpath,["A",
                    (S.MULTI_PATH,["B"]
                                 ,["C", S.LAST])]) == [1,5]

Conditional Navigation

Navigate to a specifie path

assert query(m, ["D", (S.NTH_PATH, 2)]) == [3]

Navigate to a position if and only if the path exists

assert query(m, [(S.MUST,"F","G")]) == 1
assert query(m, [(S.MUST,"F","G","NOT_EXISTS")]) == None 

Navigate to a range

assert query(m, ["D",(S.SRANGE,2,3)]) == [3]

Navigate to a 2nd path if 1st path exists, else return None

assert query(m,[(S.IF_PATH,["C","B1"],["E"])]) == [None,2,3,4]
assert query(m,[(S.IF_PATH,["C","B1"],["NOT_EXISTS"])]) == None

Navigate to a 2nd path if 1st path exists, else navigate to 3rd path

assert query(m,[(S.IF_PATH,["C","B3"],["E"],["F"])]) == {'G': 1}

Navigate to values of dict if key satisfy a regex expression:

assert query(m, ["A",(S.REGEX,r"B[23]")]) == [ 2,3 ]

Navigate to values of list if elements satisfy a regex expression:

assert query(m, ["H",(S.REGEX,r"\S1")]) == [ "A1" ]

Navigate with optional path node

assert query(m, [(S.MAYBE,"F","G")]) == 1

Handling None value

Return default value if current position is None

assert query(None,[(S.NONE_VAL,10)]) == 10

If current position is not a None,then return the value of current position

assert query(5,[(S.NONE_VAL,10)]) == 5

Operation on results

user can operate on the query result by

  • REUDCE -> perform reduce on the list or dict result ,from left to right.
m2 = {"A":{"B":["C1","C2","C3"]}}
assert query(m2, ["A","B",(H.REDUCE,lambda acc,x:acc+"|"+x, ">>>")]) == ">>>|C1|C2|C3"
assert query(m2, ["A","B",(H.REDUCE,lambda acc,x:acc+"|"+x)]) == "C1|C2|C3"

m2 = {"A":{"B":1,"D":2}}
assert query(m2, ["A",(H.REDUCE,lambda acc,x:acc+"|"+str(x[1]),">>")]) == ">>|1|2"
assert query(m2, ["A",(H.REDUCE,lambda acc,x:acc+"|"+str(x[0]),">>")]) == ">>|B|D"
  • MAP -> performn a transformation on the list or dict result
m2 = {"A":{"B":["C1","C2","C3"]}}
assert query(m2, ["A","B",(H.MAP,lambda x:x+"!")]) == ["C1!","C2!","C3!"]

m2 = {"A":{"B":"C1","D":"C2"}}
assert query(m2, ["A",(H.MAP,(lambda k,v: v+"!"))]) == ["C1!","C2!"]
  • SUM -> sum() the result list, with optional custom function passed before summing.
m2 = {"A":{"B":[1,2]}}
assert query(m2, ["A","B",H.SUM]) == 3

m2 = {"A":{"B":"1","D":"2"}}
assert query(m2, ["A",S.MVALS,(H.SUM,lambda x: int(x))]) == 3
  • MAX/MIN -> Using built-in max()/min() on the list result, with optioanl custom function passed before max/min
m2 = {"A":{"B":[3,5,2]}}
assert query(m2, ["A","B",H.MIN]) == 2
assert query(m2, ["A","B",(H.MIN,str)]) == "2"
assert query(m2, ["A","B",H.MAX]) == 5
assert query(m2, ["A","B",(H.MAX, str)]) == "5"
  • ORDER -> using sorted() to sort the result list, with optional custom function passed before sorting.
m2 = {"A":{"B":[3,5,2]}}
m2 = {"A":{"B":[3,5,2]}}
assert query(m2, ["A","B",H.ORDER]) == [2,3,5]
assert query(m2, ["A","B",(H.ORDER, str)]) == ["2","3","5"]

Metadata

Release files for pyspecter 0.1.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pyspecter 0.1.1
File Size Uploaded
pyspecter-0.1.1.tar.gz 6.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for pyspecter 0.1.1
File Interpreter ABI Platform
pyspecter-0.1.1-py3-none-any.whl Python 3 none any Details

Total release size: 12.3 kB

Release files / pyspecter-0.1.1.tar.gz

Download URL pyspecter-0.1.1.tar.gz
Size 6.1 kB
Tags Source
SHA-256 checksum
How to use checksums
aeb2a4254f55c3863b5004cbd08f82f4b1eea1428d80f2a4553ab3db2dd01a55
BLAKE2b-256 checksum
How to use checksums
693e9cf1083e08aada33115d2deb5215626a38c32325f76f1a26e29a005af047
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.2 CPython/3.9.17

Release files / pyspecter-0.1.1-py3-none-any.whl

Download URL pyspecter-0.1.1-py3-none-any.whl
Size 6.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
1101f053408fd7927eb7bf6cb89c6aeff3c0ba6de756195e773ada01f4a6ad43
BLAKE2b-256 checksum
How to use checksums
1d0fae4b663ae3324346bec9ff6a7a3b46583f4f94252b533fb4cc1f0af8167c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.2 CPython/3.9.17

Release history Release notifications | RSS feed

This release

0.1.1 This release

2 release files

0.1.0

2 release files

0.0.8

2 release files

0.0.7

2 release files

0.0.6

2 release files

0.0.5

2 release files

0.0.4

2 release files

0.0.2

1 release file

0.0.1

1 release file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page