Skip to main content

drupal-jsonapi-params-python

Python port of drupal-jsonapi-params — a query string builder for Drupal's JSON:API. Pure Python, no dependencies, Python 3.9+.

Scope: query string generation only. No HTTP, no auth, no response parsing.

Installation

pip install drupal-jsonapi-params

Or for development:

git clone https://github.com/VincenzoGambino/drupal-jsonapi-params-python.git
cd drupal-jsonapi-params-python
pip install -e ".[dev]"

Quick start

from drupal_jsonapi_params import DrupalJsonApiParams, FilterOperator

api = DrupalJsonApiParams()
(
    api
    .add_group("publish_status", "OR", "parent_group")
    .add_group("parent_group", "AND")
    .add_filter("status", "1")
    .add_filter("status", "2", "<>", "publish_status")
    .add_page_limit(5)
    .add_page_offset(20)
    .add_fields("node--article", ["field_a.id", "field_b.uid"])
    .add_include(["field_a.id", "field_b.uid"])
    .add_sort("id", "DESC")
    .add_sort("uid")
)

# URL-encoded (default)
print(api.get_query_string())

# Unencoded (useful for debugging / reading)
print(api.get_query_string(encode=False))

JS → Python API reference

JavaScript Python
new DrupalJsonApiParams() DrupalJsonApiParams()
addFilter(path, value, op, group, key) add_filter(path, value, operator, member_of, key)
addInclude(fields) add_include(fields)
addFields(type, fields) add_fields(resource_type, fields)
addSort(path, direction) add_sort(path, direction)
addPageLimit(n) add_page_limit(n)
addPageOffset(n) add_page_offset(n)
addGroup(name, conjunction, memberOf) add_group(name, conjunction, member_of)
addCustomParam({key: val}) add_custom_param({"key": val})
getQueryString({encode: false}) get_query_string(encode=False)
getQueryString({addQueryPrefix: true}) get_query_string(add_query_prefix=True)
getQueryObject() get_query_object()
clear() clear()
initialize(input) initialize(input)
initializeWithQueryString(s) initialize_with_query_string(s)
initializeWithQueryObject(obj) initialize_with_query_object(obj)
setQsOption({...}) set_output_options(encode=..., add_query_prefix=...)
getQsOption() get_output_options()
Operators.equal FilterOperator.EQUAL

Side-by-side examples

Simple equality filter

JavaScript

const api = new DrupalJsonApiParams();
api.addFilter('status', '1');
api.getQueryString({ encode: false });
// → filter[status]=1

Python

api = DrupalJsonApiParams()
api.add_filter("status", "1")
api.get_query_string(encode=False)
# → filter[status]=1

IN filter

JavaScript

api.addFilter('uid.name', ['admin', 'john'], 'IN');

Python

api.add_filter("uid.name", ["admin", "john"], "IN")
# or with enum:
api.add_filter("uid.name", ["admin", "john"], FilterOperator.IN)

BETWEEN filter

JavaScript

api.addFilter('changed', ['0', '123456789'], 'BETWEEN');

Python

api.add_filter("changed", ["0", "123456789"], "BETWEEN")

IS NULL filter

JavaScript

api.addFilter('status', null, 'IS NULL');

Python

api.add_filter("status", None, "IS NULL")

Grouped filters

JavaScript

api
  .addGroup('and-group', 'AND')
  .addFilter('uid.name', 'admin', '=', 'and-group')
  .addFilter('status', '1', '=', 'and-group');

Python

(
    api
    .add_group("and-group", "AND")
    .add_filter("uid.name", "admin", "=", "and-group")
    .add_filter("status", "1", "=", "and-group")
)

Round-trip

JavaScript

const qs = api.getQueryString();
api.clear();
api.initializeWithQueryString(qs);

Python

qs = api.get_query_string()
api.clear()
api.initialize_with_query_string(qs)

Custom parameters

JavaScript

api.addCustomParam({ foo: 'bar' })
   .addCustomParam({ foo: { bar: 'baz' } });

Python

api.add_custom_param({"foo": "bar"}).add_custom_param({"foo": {"bar": "baz"}})

Output options (qs compatibility)

The JS library delegates serialization to the qs library and exposes its full options via getQueryString() / setQsOption().

This Python port supports only the two options that are relevant for Drupal JSON:API usage:

JS (qs option) Python Default
encode: false get_query_string(encode=False) True
addQueryPrefix: true get_query_string(add_query_prefix=True) False

Other qs options (e.g. arrayFormat, delimiter, sort, charset) are not supported. The bracket-notation format used by Drupal's JSON:API is always applied.

You can also persist options across calls:

api.set_output_options(encode=False, add_query_prefix=True)
api.get_query_string()  # uses stored options

FilterOperator enum

from drupal_jsonapi_params import FilterOperator

FilterOperator.EQUAL          # "="
FilterOperator.NOT_EQUAL      # "<>"
FilterOperator.GREATER_THAN   # ">"
FilterOperator.LESS_THAN      # "<"
FilterOperator.IN             # "IN"
FilterOperator.NOT_IN         # "NOT IN"
FilterOperator.BETWEEN        # "BETWEEN"
FilterOperator.NOT_BETWEEN    # "NOT BETWEEN"
FilterOperator.IS_NULL        # "IS NULL"
FilterOperator.IS_NOT_NULL    # "IS NOT NULL"
FilterOperator.CONTAINS       # "CONTAINS"
FilterOperator.STARTS_WITH    # "STARTS_WITH"
FilterOperator.ENDS_WITH      # "ENDS_WITH"

Because FilterOperator extends str, you can pass either the enum member or its string value interchangeably:

api.add_filter("title", "Foo", FilterOperator.CONTAINS)
api.add_filter("title", "Foo", "CONTAINS")  # equivalent

Note: FilterOperator.NOT_EQUAL uses "<>", Drupal's canonical not-equal operator. The JS library's test suite uses "!=", but Drupal's JSON:API may reject it — you can pass either string directly if needed.

Metadata

Release files for drupal-jsonapi-params 0.1.0

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

Source distribution (sdist)

Source distribution for drupal-jsonapi-params 0.1.0
File Size Uploaded
drupal_jsonapi_params-0.1.0.tar.gz 12.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for drupal-jsonapi-params 0.1.0
File Interpreter ABI Platform
drupal_jsonapi_params-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 22.4 kB

Release files / drupal_jsonapi_params-0.1.0.tar.gz

Download URL drupal_jsonapi_params-0.1.0.tar.gz
Size 12.8 kB
Tags Source
SHA-256 checksum
How to use checksums
ffd42b7cf50ec84c965324b96fe6b2ea6b30778f34ea7c57bfc741c67bff8aa5
BLAKE2b-256 checksum
How to use checksums
d4ff052d6909ec883e4a90701d99e4e5cdb5e66254aa5d33e1f00c088ace99f2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on May 5, 2026.

Transparency log

Release files / drupal_jsonapi_params-0.1.0-py3-none-any.whl

Download URL drupal_jsonapi_params-0.1.0-py3-none-any.whl
Size 9.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
33acf040028738fbf49f32394e24507370bcfc73cc0bbd62a5b8b6122b5c31c6
BLAKE2b-256 checksum
How to use checksums
286f10dfc075648f92fc7b3ff9bb6b871fbf4b93ebffa4f4a0acaeb5f73b8f46
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on May 5, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

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