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 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 tests/

For more detailed testing information, including PostgreSQL setup requirements, see tests/README.md.

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.2.0.tar.gz (28.5 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.2.0-py3-none-any.whl (33.2 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: pysquril-1.2.0.tar.gz
  • Upload date:
  • Size: 28.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for pysquril-1.2.0.tar.gz
Algorithm Hash digest
SHA256 4dd010d8d22d8586b9e2c01490c228b816c20d20271f31bd06f42fdcacea9f8d
MD5 159a76f181eb56b7ee6ee41d7a2a4ef8
BLAKE2b-256 fa0c77d6a97e5f0fe31603d1414a0f432f4ef0b36185ca311d07f6c84e4a2023

See more details on using hashes here.

File details

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

File metadata

  • Download URL: pysquril-1.2.0-py3-none-any.whl
  • Upload date:
  • Size: 33.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for pysquril-1.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 e0e57094280e0aafe88508a4c5182898a9d6e6f220765b89039da8d56c721c55
MD5 15d502ca2dccfc69c284f30ed29992a3
BLAKE2b-256 01bc9aaecd8d9b0ebac953600887c5697811197363b8c3e1ce090f8b923cff97

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