# -*- coding: utf-8 -*-
from setuptools import setup

packages = \
['rqlalchemy']

package_data = \
{'': ['*']}

install_requires = \
['pyrql>=0.7.8,<0.8.0', 'sqlalchemy>=2.0,<3.0']

setup_kwargs = {
    'name': 'rqlalchemy',
    'version': '0.5.0',
    'description': '"Resource Query Language for SQLAlchemy"',
    'long_description': '# RQLAlchemy\n\n[![Build Status](https://github.com/pjwerneck/rqlalchemy/actions/workflows/pytest.yml/badge.svg?branch=develop)](https://github.com/pjwerneck/rqlalchemy/actions/workflows/pytest.yml)\n\n## Resource Query Language extension for SQLAlchemy\n\n**Overview**\n\nResource Query Language (RQL) is a query language designed for use in URIs, with object-style data structures.\n\n`rqlalchemy` is an RQL extension for SQLAlchemy, making it easy to expose SQLAlchemy tables or models as an HTTP API endpoint and perform complex queries using only query string parameters.\n\n**Installing**\n\n```bash\npip install rqlalchemy\n```\n\n**Usage**\n\nSupport RQL queries in your application by using the `select()` construct provided by RQLAlchemy. After creating the selectable, use the `rql()` method to apply the RQL query string, and then use the `execute()` method with the session to retrieve the results.\n\nFor example, in a Flask HTTP API with a users collection endpoint querying the `User` model:\n\n```python\nfrom urllib.parse import unquote\nfrom flask import request\n\nfrom rqlalchemy import select\n\n@app.route(\'/users\')\ndef get_users_collection():\n    qs = unquote(request.query_string.decode(request.charset))\n    users = select(User).rql(qs).execute(session)\n\n    return render_response(users)\n```\n\nThe `.execute()` method handles the session and adjusts the results accordingly, returning scalars, lists of dicts, or a single scalar result when appropriate. There\'s no need to use `session.execute()` or `session.scalars()` directly unless you want to handle the results yourself.\n\n**Pagination**\n\nRQLAlchemy offers limit/offset pagination with the `rql_paginate()` method, returning the requested page, RQL expressions for previous and next pages if available, and the total number of items.\n\n```python\nfrom urllib.parse import unquote\nfrom flask import request\n\nfrom rqlalchemy import select\n\n@app.route(\'/users\')\ndef get_users_collection():\n    qs = unquote(request.query_string.decode(request.charset))\n    res = select(User).rql(qs).rql_paginate(session)\n\n    response = {\n        "data": res.page,\n        "total": res.total,\n    }\n\n    if res.previous_page:\n        response["previous"] = \'/users?\' + res.previous_page\n\n    if res.next_page:\n        response["next"] = \'/users?\' + res.next_page\n\n    return render_response(response)\n```\n\nPagination requires a limit, as a `RQLSelect._rql_default_limit` value, a query string `limit(x)`, or the `limit` parameter to the `rql()` method. Calling `rql_paginate()` without a limit will raise `RQLQueryError`.\n\n**Reference Table**\n\n| RQL                     | SQLAlchemy equivalent                              | Observation                                                                                                                     |\n|-------------------------|----------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------|\n| QUERYING                |                                                    |                                                                                                                                 |\n| select(a,b,c,...)       | select(Model.a, Model.b, Model.c,...)              |                                                                                                                                 |\n| values(a)               | [o.a for o in query.from_self(a)]                  |                                                                                                                                 |\n| limit(count,start?)     | .limit(count).offset(start)                        |                                                                                                                                 |\n| sort(attr1)             | .order_by(attr)                                    |                                                                                                                                 |\n| sort(-attr1)            | .order_by(attr.desc())                             |                                                                                                                                 |\n| distinct()              | .distinct()                                        |                                                                                                                                 |\n| first()                 | .limit(1)                                          |                                                                                                                                 |\n| one()                   | [query.one()]                                      |                                                                                                                                 |\n| FILTERING               |                                                    |                                                                                                                                 |\n| eq(attr,value)          | .where(Model.attr == value)                        |                                                                                                                                 |\n| ne(attr,value)          | .where(Model.attr != value)                        |                                                                                                                                 |\n| lt(attr,value)          | .where(Model.attr < value)                         |                                                                                                                                 |\n| le(attr,value)          | .where(Model.attr <= value)                        |                                                                                                                                 |\n| gt(attr,value)          | .where(Model.attr > value)                         |                                                                                                                                 |\n| ge(attr,value)          | .where(Model.attr >= value)                        |                                                                                                                                 |\n| in(attr,value)          | .where(Model.attr.in_(value)                       |                                                                                                                                 |\n| out(attr,value)         | .where(not_(Model.attr.in_(value)))                |                                                                                                                                 |\n| contains(attr,value)    | .where(Model.contains(value))                      | Produces a LIKE expression when querying against a string, or an IN expression when querying against an iterable relationship   |\n| excludes(attr,value)    | .where(not_(Model.contains(value)))                | See above.                                                                                                                      |\n| and(expr1,expr2,...)    | .where(and_(expr1, expr2, ...))                    |                                                                                                                                 |\n| or(expr1,expr2,...)     | .where(or_(expr1, expr2, ...))                     |                                                                                                                                 |\n| AGGREGATING             |                                                    | All aggregation functions return scalar results.                                                                                |\n| aggregate(a,b\\(c\\),...) | select(Model.a, func.b(Model.c)).group_by(Model.a) |                                                                                                                                 |\n| sum(attr)               | select(func.sum(Model.attr))                       |                                                                                                                                 |\n| mean(attr)              | select(func.avg(Model.attr))                       |                                                                                                                                 |\n| max(attr)               | select(func.max(Model.attr))                       |                                                                                                                                 |\n| min(attr)               | select(func.min(Model.attr))                       |                                                                                                                                 |\n| count()                 | select(func.count())                               |                                                                                                                                 |\n\n',
    'author': 'Pedro Werneck',
    'author_email': 'pjwerneck@gmail.com',
    'maintainer': 'None',
    'maintainer_email': 'None',
    'url': 'https://github.com/pjwerneck/rqlalchemy',
    'packages': packages,
    'package_data': package_data,
    'install_requires': install_requires,
    'python_requires': '>=3.8,<4.0',
}


setup(**setup_kwargs)
