Skip to main content

Python implementation of structured URI query language

Project description

pysquril

PYthon Structured URI Query Language. A library for implementing versioned, queryable, and auditable document oriented datastores. Features:

  • Useful for implementing generic document oriented REST APIs
  • Multi-tenancy
  • Enforces uniqueness on records, otherwise schemaless
  • SQL-like query language
  • Ability to apply queries to multiple tables (document sets) simultaneously
  • Audit (with rollback) - who, what, when, why
    • default events: update, delete
    • optional events: create, read
  • PostgreSQL and sqlite database backends

Getting to know pysquril

Use the helper class to run interactive queries on your own input data:

pysquril % poetry run python
>>> from pysquril.interactive import B
>>> B().D([{"x": 0, "y": 1}, {"x": 100, "y": 4, "z": [1,2]}]).Q("select=x,z[1]")
[[0, None], [100, 2]]
>>> B().D([{"x": 0, "y": 1}, {"x": 100, "y": 4, "z": [1,2]}]).Q("select=x,z[1]&order=x.desc")
[[100, 2], [0, None]]
>>> B().D([{"x": 0, "y": 1}, {"x": 100, "y": 4, "z": [1,2]}]).Q("select=x,z[1]&where=y=gt.1")
[[100, 2]]

Example library usage

import sqlite3

from pysquril.backends import SqliteBackend, sqlite_init

# get a connection pool
# most real world usage would use persistent storage
engine = sqlite_init(":memory:")

# instantiate a backend, for a given tenant, and identity
tenant = "tenant1"
backend = SqliteBackend(
    engine,
    schema=tenant,
    requestor="some-user",
    requestor_name="Some Person Name",
)

# add some data
table = "mytable"
backend.table_insert(
    table_name=table,
    data={"saying": "good", "being": ["glad"], "id": 0},
)
backend.table_insert(
    table_name=table,
    data={"saying": "good", "being": ["content", "detached"], "id": 1},
)

# query the data
print(list(backend.table_select(table_name=table, uri_query="select=being")))

# change the second record, with a reason
reason_for_update = "a more accurate description"
backend.table_update(
    table_name=table,
    uri_query=f"set=saying&where=being[0]=eq.'content'&message='{reason_for_update}'",
    data={"saying": "excellent"},
)

# check the audit
print(list(backend.table_select(table_name=f"{table}_audit", uri_query="")))

# restore the data to its prior state
backend.table_restore(
    table_name=table,
    uri_query="restore&primary_key=id",
)

# check that the data is back to its original state
result = list(
    backend.table_select(
        table_name=table,
        uri_query="select=saying&where=being[0]=eq.'content'",
    )
)
assert result[0][0] == "good"

Tests

poetry install
poetry run pytest -vs --durations=0 pysquril/tests.py

Generating docs

npm install -g ebnf2railroad
ebnf2railroad pysquril/docs/grammar.ebnf -o pysquril/docs/grammar.html

License

BSD.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pysquril-1.0.2.tar.gz (27.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pysquril-1.0.2-py3-none-any.whl (29.1 kB view details)

Uploaded Python 3

File details

Details for the file pysquril-1.0.2.tar.gz.

File metadata

  • Download URL: pysquril-1.0.2.tar.gz
  • Upload date:
  • Size: 27.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/5.1.1 CPython/3.12.7

File hashes

Hashes for pysquril-1.0.2.tar.gz
Algorithm Hash digest
SHA256 31866b9b5a74da5b6aa85c53269a51b8d9ab699be6382a66c3fdb5ce3a37a7bf
MD5 c4ca32cbebac709d312f3b5ba0f27f29
BLAKE2b-256 889a3a681a23da29fca2a641c9585a94c3642547ddc1cb3321043769ce027848

See more details on using hashes here.

File details

Details for the file pysquril-1.0.2-py3-none-any.whl.

File metadata

  • Download URL: pysquril-1.0.2-py3-none-any.whl
  • Upload date:
  • Size: 29.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/5.1.1 CPython/3.12.7

File hashes

Hashes for pysquril-1.0.2-py3-none-any.whl
Algorithm Hash digest
SHA256 4b1ac757271dafc1a6837f5731e6686fe37c7a901212950d49a1077482510cfe
MD5 e2a9f22718d6cdcf35c9a4cfdc33baa3
BLAKE2b-256 106b0cc032ff0d488e8116af0fdbaa1ec1a60f4091658602fe90f732c368aff9

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page