Skip to main content

Filterparams

Project description

# Python Filterparams #

Filterparams is a library for parsing URL paramters for filter
purposes in a backend. It provides a syntax to map SQL-like
queries on top of the query parameters and parses it into a
python object.

This is a helper library for providing filter collection APIs.
The primary use case for developing the library is to
use it with a REST-API which uses the [JSONAPI](http://jsonapi.org/)
standard. Because of this the syntax is completely compatible with
the standard and encapsulates everything in the `filter` query
parameter.

## Example ##

Given the URL (non URL escaped for better readability):
```
/users?filter[param][name][like][no_default_name]=doe&filter[param][first_name]=doe%&filter[binding]=(!no_brand_name&first_name)&filter[order]=name&filter[order]=desc(first_name)
```

It can be parsed by the given function:

```python
from urllib.parse import urlsplit, parse_qs
from filterparams import build_parser

url = urlsplit(
'/users?filter[param][name][like][no_default_name]=doe'
'&filter[param][first_name]=doe%&filter[binding]='
'(!no_brand_name&first_name)&filter[order]=name'
'&filter[order]=desc(first_name)'
)
params = parse_qs(url)

valid_filters = ['eq', 'like']
default_filter = 'eq'

parser = build_parser(
valid_filters=valid_filters,
default_filter=default_filter,
)

query = parser(params)
```

Would parse the data. You can access the parsed filters through
`.param_order` and the orders through `.orders`. The param order
in this specific case would be resolved to:

```python
And(
left=Parameter(
name='name',
alias='no_default_name',
filter='like',
value='doe%',
),
right=Parameter(
name='first_name',
alias='first_name',
filter='eq',
value='doe',
)
)
```

The orders would be:

```python
[Order(name='name', direction='asc'),
Order(name='first_name', direction='desc')]
```

## Syntax ##

All arguments must be prefixed by "filter". It is possible to
query for specific data with filters, apply orders to the result
and to combine filters through AND, NOT and OR bindings.

The syntax builds under the filter parameter a virtual object.
The keys of the object are simulated through specifying `[{key}]`
in the passed query parameter. Thus `filter[param]` would point
to the param key in the filter object.

### Filter specification ###

The solution supports to query data through the `param` subkey.

```
filter[param][{parameter_name}][{operation}][{alias}] = {to_query_value}
```

The `operation` and `alias` parameters may be omitted. If no
`alias` is provided the given parameter name is used for it.
If no `operation` is given, the default one is used (in the
example this would be equal).

Example:
```
filter[param][phone_number][like]=001%
```

This would add a filter to all phone numbers which start with "001".

### Filter binding ###

Per default all filters are combined through AND clauses.
You can change that by specifying the `filter[binding]` argument.

This is where the aliases which you can define come into place.
The binding provides means to combine filters with AND and OR.
Also you are able to negate filters here.

The filters are addressed by their alias or name, if no alias is
provided.

If you have a filter `search_for_name`, `search_for_phone_number`
and `search_for_account_number` defined you can say
`search_for_name OR NOT search_for_number AND search_for_account_number`
by specifying the following filter:

```
filter[binding]=search_for_name|(!search_for_phone_number&search_for_account_number)
```

Even though the brackets are useless here, you can use them in
more complex filters.

The following table summarizes the possible configuration options:
<table>
<thead>
<tr>
<th>Type</th>
<th>Symbol</th>
<th>Example</th>
</tr>
</thead>
<tbody>
<tr>
<td>AND</td>
<td>&</td>
<td>a&b</td>
</tr>
<tr>
<td>OR</td>
<td>|</td>
<td>a|b</td>
</tr>
<tr>
<td>NOT</td>
<td>!</td>
<td>!a</td>
</tr>
<tr>
<td>Bracket</td>
<td>()</td>
<td>(a|b)&c</td>
</tr>
</tbody>
</table>

### Ordering ###

To specify a sort order of the results the `filter[order]` parameter
may be used. The value can be specified multiple times. To add
ordering you have to provide the name of the parameter which should
be ordered, not its alias!

If you want to order by `name`, `first_name` and in reverse order
`balance` you can do so by specifying the following query url
parameters:

```
filter[order]=name&filter[order]=first_name&filter[order]=desc(balance)
```

As you can see the `desc()` definition can be used to indicate
reverse ordering.

### Filter definition ###

Not every backend does or should support all possible filter
mechanisms. This is why the filters which should be accepted
by the backend have to be added before processing the query
parameters.

You can limit the allowed filters by building a parse through the
`filterparams.build_parser` function. You can configure the allowed
filters through the `valid_filters` definition. Additionally you
have to add the default filter by using the second `default_filter`
parameter.

```python
from filterparams import build_parser

valid_filters = ['eq', 'like']
default_filter = 'eq'

parser = build_parser(
valid_filters=valid_filters,
default_filter=default_filter,
)

query = parser({})
```

If you don't want any validation you can use the `parse` function.

```python
from filterparams import parse

query = parse({})
```

## Notes ##

- There do no yet exist any public projects which use this library to provide transparent mapping to an underlying
backend. I plan long-term to add another library which does use this package and provide a way to map it on sqlalchemy models.
If you are planning to do this or use it for other data mapping please contact me and I'll add a reference to it in
the README.
- The same as mentioned above is valid for client libraries, which generate the filter query structure in any language.
Again, as soon as the API is stable I'll probably add a JavaScript library.
- Depending on your backend it might not make sense to support all features (ordering, parameter binding) of the
language. You might still want to use it to parse your basic parameters though and ignore the rest.

## Used Libraries ##

For evaluating the filter params ordering the [funcparserlib](https://github.com/vlasovskikh/funcparserlib) ([MIT license](https://github.com/vlasovskikh/funcparserlib/blob/master/LICENSE))
module is used. Additionally the [Werkzeug](https://github.com/mitsuhiko/werkzeug/blob/master/LICENSE) package is used for supporting dicts with multiple values in the same key.

## Other Languages ##

This is a list of projects implementing the same API for other languages.
Currently this list only has one entry.

- Go - [go-filterparams](https://github.com/cbrand/go-filterparams)

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

filterparams-1.0.2.tar.gz (9.9 kB view details)

Uploaded Source

Built Distributions

filterparams-1.0.2-py3.5.egg (13.1 kB view details)

Uploaded Source

filterparams-1.0.2-py3.4.egg (13.1 kB view details)

Uploaded Source

filterparams-1.0.2-py3.3.egg (13.3 kB view details)

Uploaded Source

filterparams-1.0.2-py3.2.egg (11.3 kB view details)

Uploaded Source

filterparams-1.0.2-py3.1.egg (11.1 kB view details)

Uploaded Source

filterparams-1.0.2-py3-none-any.whl (6.8 kB view details)

Uploaded Python 3

filterparams-1.0.2-py2.7.egg (5.6 kB view details)

Uploaded Source

filterparams-1.0.2-py2-none-any.whl (6.9 kB view details)

Uploaded Python 2

File details

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

File metadata

File hashes

Hashes for filterparams-1.0.2.tar.gz
Algorithm Hash digest
SHA256 dfbe999f7742d70b9626d91bf006056ed4d5c8053d82b450c47a291f9bcec2c9
MD5 6a0adf314876022a5f8d9ec2619c8276
BLAKE2b-256 cdc3f88324493684fd88ec5abd0f078aa2cf5cb11bc3998800053e377d11ba20

See more details on using hashes here.

File details

Details for the file filterparams-1.0.2-py3.5.egg.

File metadata

File hashes

Hashes for filterparams-1.0.2-py3.5.egg
Algorithm Hash digest
SHA256 98ea57300bcb4d1ac6839c656275aa6d6f2d231a68b9f3dac6fb9c70f034bf61
MD5 edc25af8a125a8d2a3f9f3564f732458
BLAKE2b-256 51fd4a8f55f57322961f34d9ee63073067190ff3a082016cc4c92319550e99e0

See more details on using hashes here.

File details

Details for the file filterparams-1.0.2-py3.4.egg.

File metadata

File hashes

Hashes for filterparams-1.0.2-py3.4.egg
Algorithm Hash digest
SHA256 de0f2b2c0ca3691a337d19ce4e755f0a8228ca760c94b39ee9d8b805a9345b07
MD5 67e1b31057f4149e868370f9e9f2c41d
BLAKE2b-256 900a1b46ae285bcb3da3bf1c1a616ccc60a426889e3a0c4cb400b3f175b79aee

See more details on using hashes here.

File details

Details for the file filterparams-1.0.2-py3.3.egg.

File metadata

File hashes

Hashes for filterparams-1.0.2-py3.3.egg
Algorithm Hash digest
SHA256 308d1fd02b19436a2c2f8ff849fcbeaae24e365ee835d0c365357f10026449b9
MD5 87e826740018e0622435a710ea01c018
BLAKE2b-256 e170f5deb8de5ad883af2efddd4eefb18dee87504445a33b1cf15eb30e13b52b

See more details on using hashes here.

File details

Details for the file filterparams-1.0.2-py3.2.egg.

File metadata

File hashes

Hashes for filterparams-1.0.2-py3.2.egg
Algorithm Hash digest
SHA256 4f9d13de7f07a5e52bbd9c9574cff95915a61486b95913fa4fa8811c01adbd8f
MD5 bc78fde1701b21a8553dc756f34833fc
BLAKE2b-256 5e7bc2dc43e590f3ae6333148d3d2c870315b76c39471487270930a4e19f2fa3

See more details on using hashes here.

File details

Details for the file filterparams-1.0.2-py3.1.egg.

File metadata

File hashes

Hashes for filterparams-1.0.2-py3.1.egg
Algorithm Hash digest
SHA256 4ce3b91c9034fbd2c686c37a3f18f9880fc0a7e960b25500b377093c3b2d1b5e
MD5 24c7767396e625b7809b309d8c4d61cf
BLAKE2b-256 3b3c8e087c821ce2efd9034eb13f478b76061b6e8f87345dd86cd2a675caffd7

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for filterparams-1.0.2-py3-none-any.whl
Algorithm Hash digest
SHA256 98a2af142d935b5e3b3d99ec30265b81b1ce45f09b9de1b65d52fc6ac385e683
MD5 3f3f34daac7ecc05fcf5fc8950e174a8
BLAKE2b-256 3370020a75fca95ae7eea0f6fe9cb2d14c1f4fc84f742a341c25e637fe9f5f44

See more details on using hashes here.

File details

Details for the file filterparams-1.0.2-py2.7.egg.

File metadata

File hashes

Hashes for filterparams-1.0.2-py2.7.egg
Algorithm Hash digest
SHA256 f72c5c6ebdad25d43e38d912b2ac0e2d6cec9b14b10748514d52596f9fe743e9
MD5 af4be28fe373ccb81a33d3ad9e2c6460
BLAKE2b-256 c89db08705ac4db1df61a7a5faec9b93c8cefeda7794e83f7ee8b6eb2c52b2ae

See more details on using hashes here.

File details

Details for the file filterparams-1.0.2-py2-none-any.whl.

File metadata

File hashes

Hashes for filterparams-1.0.2-py2-none-any.whl
Algorithm Hash digest
SHA256 604c5fbbaf5b5b345c9745ee6d81037bf7eb2d7f0108623dadc6181e5420056f
MD5 6146ae24e9da35c9c78303ba1e8b153a
BLAKE2b-256 354810a03bf21d400cdf2d5c45225349ee37a317ec72e7e00dad0c64fdda8f45

See more details on using hashes here.

Supported by

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