fastapi-paginator


Namefastapi-paginator JSON
Version 0.1.4 PyPI version JSON
download
home_pagehttps://github.com/JGoutin/fastapi_paginator
SummaryPaginator for FastAPI
upload_time2023-02-09 10:34:51
maintainer
docs_urlNone
authorJGoutin
requires_python>=3.10,<4.0
licenseBSD-2-Clause
keywords paginator fastapi sqlalchemy
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            ![Tests](https://github.com/JGoutin/fastapi_paginator/workflows/tests/badge.svg)
[![codecov](https://codecov.io/gh/JGoutin/fastapi_paginator/branch/main/graph/badge.svg?token=QR5nYeX11F)](https://codecov.io/gh/JGoutin/fastapi_paginator)
[![PyPI](https://img.shields.io/pypi/v/fastapi_paginator.svg)](https://pypi.org/project/fastapi_paginator)

# FastAPI Paginator

Easy to use paginator for [FastAPI](https://fastapi.tiangolo.com/)

Currently, supports only [encode/databases](https://github.com/encode/databases) as 
database library and tested with SQlite and PostgreSQL.

## Features

* Simple FastAPI integration.
* Navigation with page numbers (With total page count returned on first page).
* Navigation from a specific row (since).
* Ordering result (On multiple columns).
* Filtering result using various SQL functions.

## Installation

FastAPI Paginator is available on PyPI, so it can be installed like any other Python 
package.

Example with Pip:
```bash
pip install fastapi_paginator
```

## Usage

### Routes creations in FastAPI

To use it, you only need to create a `fastapi_paginator.Paginator` instance linked to
the database and routes
using `fastapi_paginator.PageParameters` and `fastapi_paginator.Page`.

```python
import databases
import fastapi
import pydantic
import sqlalchemy
import fastapi_paginator

# Already existing database, FastAPI application, "item" table, and "item" model
database = databases.Database(f"sqlite:///local.db}")
app = fastapi.FastAPI()

table = sqlalchemy.Table(
    "table",
    sqlalchemy.MetaData(),
    Column("id", sqlalchemy.Integer, primary_key=True),
    Column("name", sqlalchemy.String, nullable=False),
)

class Item(pydantic.BaseModel):
    """Item in database."""

    class Config:
        """Config."""

        orm_mode = True  # Required

    id: int
    name: str


# Create a paginator for the database (Required only once per database)
paginator = fastapi_paginator.Paginator(database)

# Create a paginated route
@app.get("/list")
async def list_data(
    page_parameters: fastapi_paginator.PageParameters = Depends(),
) -> fastapi_paginator.Page[Item]:
    """List data with pagination."""
    return await paginator(table.select(), Item, page_parameters)
```

### Paginated routes usage from clients


#### Request
Paginator parameters are passed as query parameters, for instance:

```http request
GET /list?order_by=id&page=2
```

##### Query parameters

###### page
The page to return.

When page is not specified or equal to `1`, the request returns `total_page` that is
the maximum number of pages.

*Cannot be used with `since`.*

###### since

The item from where starting to return the result.

When navigating between successive pages, the `next_since` returned value should be used
as `since` for the subsequent requests.

*Cannot be used with `page`*.

*Cannot be used with `order_by` if not ordering on the field used by `since`*.

###### order_by
Sort the resulting items by the specified field name.

Order is descending if `-` is added before the field name, else order is ascending.

This query parameter can be specified multiple time to sort by multiple columns.

**Example:**
"Ordering descending by the `created_at` column: `order_by=-created_at`

###### filter_by

Filter the resulting items.

The query must be in the form `field_name operator argument`, with:
  * `field_name`:  the name on the field on where apply the filter.
  * `operator`:  one operator from the list bellow.
  * `argument`: is the operator argument, it can be one or more value separated by `,`
    (Depending on the operator), valid values must be a primitive JSON type like 
    numbers, double-quoted strings, `true`, `false` and `null`.

This query parameter can be specified multiple time to filter on more criteria
(Using AND logical conjunction).

Available operators:
  * `=`: Equal to a single value (Also supports `null`, `true` and `false`)
  * `<`: Lower than a single value.
  * `<=`: Lower or equal than a single value.
  * `>`: Greater than a single value.
  * `>=`: Greater or equal than a single value.
  * `between`: Between a pair of values (`value_1` <= `field_value` <= `value_2`).
  * `in`: Present in a list of one or more values.
  * `like`: Like a single value (`%` can be used as wildcard for zero to multiple
     characters, `_` as wildcard for a single character, `/` can be used as escape
     character for `%` and `_`).
  * `ilike`: Same as `like`, but case insensitive.
  * `startswith`: String representation starts with a single value.
  * `endswith`: String representation ends with a single value.
  * `contains`: String representation contains a single value.

Any operator can be negated by adding `!` in front of it.

*Warning*: Depending on your HTTP client, the query parameter value may require to be
URL encoded.

**Example:**
Returning only data with a `name` field that does not start with
`Product`: `filter_by=name%20%21like%20%22Product%25%22`
(With URL encoded value of: `name !like "Product%"`')

##### Response

The response is a JSON dictionnary with the following fields:
* `items`: The list returned items.
* `next_since`: Next value to use with `since` query parameter.
* `next_page`: Next value to use with `page` query parameter.
* `total_pages`: Total pages, only computed and returned when on page 1

### Using alternates JSON libraries

It is possible to override the `json.loads` function used in all paginator as follows 
(Example with [orjson](https://github.com/ijl/orjson)):

```python
import orjson
import fastapi_paginator


fastapi_paginator.Paginator.json_loads = orjson.loads
```

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/JGoutin/fastapi_paginator",
    "name": "fastapi-paginator",
    "maintainer": "",
    "docs_url": null,
    "requires_python": ">=3.10,<4.0",
    "maintainer_email": "",
    "keywords": "paginator,fastapi,sqlalchemy",
    "author": "JGoutin",
    "author_email": "",
    "download_url": "https://files.pythonhosted.org/packages/b1/f9/abb23811075331d36f98b5f8363cb029727e5a0fff1cf4c9a64201843fa5/fastapi_paginator-0.1.4.tar.gz",
    "platform": null,
    "description": "![Tests](https://github.com/JGoutin/fastapi_paginator/workflows/tests/badge.svg)\n[![codecov](https://codecov.io/gh/JGoutin/fastapi_paginator/branch/main/graph/badge.svg?token=QR5nYeX11F)](https://codecov.io/gh/JGoutin/fastapi_paginator)\n[![PyPI](https://img.shields.io/pypi/v/fastapi_paginator.svg)](https://pypi.org/project/fastapi_paginator)\n\n# FastAPI Paginator\n\nEasy to use paginator for [FastAPI](https://fastapi.tiangolo.com/)\n\nCurrently, supports only [encode/databases](https://github.com/encode/databases) as \ndatabase library and tested with SQlite and PostgreSQL.\n\n## Features\n\n* Simple FastAPI integration.\n* Navigation with page numbers (With total page count returned on first page).\n* Navigation from a specific row (since).\n* Ordering result (On multiple columns).\n* Filtering result using various SQL functions.\n\n## Installation\n\nFastAPI Paginator is available on PyPI, so it can be installed like any other Python \npackage.\n\nExample with Pip:\n```bash\npip install fastapi_paginator\n```\n\n## Usage\n\n### Routes creations in FastAPI\n\nTo use it, you only need to create a `fastapi_paginator.Paginator` instance linked to\nthe database and routes\nusing `fastapi_paginator.PageParameters` and `fastapi_paginator.Page`.\n\n```python\nimport databases\nimport fastapi\nimport pydantic\nimport sqlalchemy\nimport fastapi_paginator\n\n# Already existing database, FastAPI application, \"item\" table, and \"item\" model\ndatabase = databases.Database(f\"sqlite:///local.db}\")\napp = fastapi.FastAPI()\n\ntable = sqlalchemy.Table(\n    \"table\",\n    sqlalchemy.MetaData(),\n    Column(\"id\", sqlalchemy.Integer, primary_key=True),\n    Column(\"name\", sqlalchemy.String, nullable=False),\n)\n\nclass Item(pydantic.BaseModel):\n    \"\"\"Item in database.\"\"\"\n\n    class Config:\n        \"\"\"Config.\"\"\"\n\n        orm_mode = True  # Required\n\n    id: int\n    name: str\n\n\n# Create a paginator for the database (Required only once per database)\npaginator = fastapi_paginator.Paginator(database)\n\n# Create a paginated route\n@app.get(\"/list\")\nasync def list_data(\n    page_parameters: fastapi_paginator.PageParameters = Depends(),\n) -> fastapi_paginator.Page[Item]:\n    \"\"\"List data with pagination.\"\"\"\n    return await paginator(table.select(), Item, page_parameters)\n```\n\n### Paginated routes usage from clients\n\n\n#### Request\nPaginator parameters are passed as query parameters, for instance:\n\n```http request\nGET /list?order_by=id&page=2\n```\n\n##### Query parameters\n\n###### page\nThe page to return.\n\nWhen page is not specified or equal to `1`, the request returns `total_page` that is\nthe maximum number of pages.\n\n*Cannot be used with `since`.*\n\n###### since\n\nThe item from where starting to return the result.\n\nWhen navigating between successive pages, the `next_since` returned value should be used\nas `since` for the subsequent requests.\n\n*Cannot be used with `page`*.\n\n*Cannot be used with `order_by` if not ordering on the field used by `since`*.\n\n###### order_by\nSort the resulting items by the specified field name.\n\nOrder is descending if `-` is added before the field name, else order is ascending.\n\nThis query parameter can be specified multiple time to sort by multiple columns.\n\n**Example:**\n\"Ordering descending by the `created_at` column: `order_by=-created_at`\n\n###### filter_by\n\nFilter the resulting items.\n\nThe query must be in the form `field_name operator argument`, with:\n  * `field_name`:  the name on the field on where apply the filter.\n  * `operator`:  one operator from the list bellow.\n  * `argument`: is the operator argument, it can be one or more value separated by `,`\n    (Depending on the operator), valid values must be a primitive JSON type like \n    numbers, double-quoted strings, `true`, `false` and `null`.\n\nThis query parameter can be specified multiple time to filter on more criteria\n(Using AND logical conjunction).\n\nAvailable operators:\n  * `=`: Equal to a single value (Also supports `null`, `true` and `false`)\n  * `<`: Lower than a single value.\n  * `<=`: Lower or equal than a single value.\n  * `>`: Greater than a single value.\n  * `>=`: Greater or equal than a single value.\n  * `between`: Between a pair of values (`value_1` <= `field_value` <= `value_2`).\n  * `in`: Present in a list of one or more values.\n  * `like`: Like a single value (`%` can be used as wildcard for zero to multiple\n     characters, `_` as wildcard for a single character, `/` can be used as escape\n     character for `%` and `_`).\n  * `ilike`: Same as `like`, but case insensitive.\n  * `startswith`: String representation starts with a single value.\n  * `endswith`: String representation ends with a single value.\n  * `contains`: String representation contains a single value.\n\nAny operator can be negated by adding `!` in front of it.\n\n*Warning*: Depending on your HTTP client, the query parameter value may require to be\nURL encoded.\n\n**Example:**\nReturning only data with a `name` field that does not start with\n`Product`: `filter_by=name%20%21like%20%22Product%25%22`\n(With URL encoded value of: `name !like \"Product%\"`')\n\n##### Response\n\nThe response is a JSON dictionnary with the following fields:\n* `items`: The list returned items.\n* `next_since`: Next value to use with `since` query parameter.\n* `next_page`: Next value to use with `page` query parameter.\n* `total_pages`: Total pages, only computed and returned when on page 1\n\n### Using alternates JSON libraries\n\nIt is possible to override the `json.loads` function used in all paginator as follows \n(Example with [orjson](https://github.com/ijl/orjson)):\n\n```python\nimport orjson\nimport fastapi_paginator\n\n\nfastapi_paginator.Paginator.json_loads = orjson.loads\n```\n",
    "bugtrack_url": null,
    "license": "BSD-2-Clause",
    "summary": "Paginator for FastAPI",
    "version": "0.1.4",
    "split_keywords": [
        "paginator",
        "fastapi",
        "sqlalchemy"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "c05832f234c6f26401c30c9e9beafb36ce836daae14eb91ffe08afa47ee06beb",
                "md5": "5d30ca5f76a1d09d237ce71b1f85f44f",
                "sha256": "aeb49cb09451cfe194c2457e7deaaf47b2edb42afe74ada41ce2ec4f5fd5ee5b"
            },
            "downloads": -1,
            "filename": "fastapi_paginator-0.1.4-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "5d30ca5f76a1d09d237ce71b1f85f44f",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.10,<4.0",
            "size": 10085,
            "upload_time": "2023-02-09T10:34:49",
            "upload_time_iso_8601": "2023-02-09T10:34:49.831556Z",
            "url": "https://files.pythonhosted.org/packages/c0/58/32f234c6f26401c30c9e9beafb36ce836daae14eb91ffe08afa47ee06beb/fastapi_paginator-0.1.4-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "b1f9abb23811075331d36f98b5f8363cb029727e5a0fff1cf4c9a64201843fa5",
                "md5": "a7e387afcf4400d0d0f2efe7a1e0c682",
                "sha256": "68918dc16d8f6e89e5406cf974d54313ff62c29642f132f654b49b104fa20f48"
            },
            "downloads": -1,
            "filename": "fastapi_paginator-0.1.4.tar.gz",
            "has_sig": false,
            "md5_digest": "a7e387afcf4400d0d0f2efe7a1e0c682",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.10,<4.0",
            "size": 10340,
            "upload_time": "2023-02-09T10:34:51",
            "upload_time_iso_8601": "2023-02-09T10:34:51.574039Z",
            "url": "https://files.pythonhosted.org/packages/b1/f9/abb23811075331d36f98b5f8363cb029727e5a0fff1cf4c9a64201843fa5/fastapi_paginator-0.1.4.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2023-02-09 10:34:51",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "github_user": "JGoutin",
    "github_project": "fastapi_paginator",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "fastapi-paginator"
}
        
Elapsed time: 0.04744s