Metadata-Version: 2.4
Name: fastapi-utk
Version: 1.0.1
Summary: FastAPI Ultimate Toolkit
Author-email: v1a0 <contact@v1a0.dev>
Project-URL: homepage, https://github.com/v1a0/fastapi-utk
Project-URL: example, https://github.com/v1a0/fastapi-utk/tree/main/example
Classifier: Programming Language :: Python :: 3.13
Classifier: Framework :: FastAPI
Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
Classifier: Operating System :: OS Independent
Requires-Python: >=3.12
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: fastapi>=0.115.12
Requires-Dist: pydantic>=2.11.5
Dynamic: license-file

# FastAPI Ultimate Toolkit

The most useful tools for any FastAPI project

<img width="400" src="./docs/images/logo.png" />

## Installation

```shell
pip install fastapi-utk
```

## Features

- Api
    - Pagination
        - Pagination
        - PaginationConfig
        - Paginator
        - Paginated
- Utils
    - NotSet

# Use cases

[>>> CLICK THE LINK TO SEE EXAMPLE PROJECT <<<](./example)

## Pagination

### Example

```python
import typing as tp
from fastapi_utk import Paginated, Pagination, Paginator

from my_app import router
from my_app.response_models import User

pagination = Pagination()


@router.get("/users")
def get_users(
        paginator: tp.Annotated[Paginator, pagination.Depends()],
) -> Paginated[User]:
    total, users = get_users_from_db(..., limit=paginator.limit, offset=paginator.offset)

    return paginator(
        [
            User(
                id=user.id,
                age=user.age,
                name=user.name,
            )
            for user in users
        ],
        total=total,
    )
```

### Response

<img width="400" src="./docs/images/img-2.jpg" />

### Schema

<img width="400" src="./docs/images/img-1.jpg" />


### Extra

```python
import typing as tp
from fastapi_utk import Paginated, Pagination, Paginator

# Use Pagination class to specify global pagination configuration
pagination = Pagination()


# If for some routes you need non-default configuration, set it right in depends
@router.get("foos")
def foo(
        paginator: tp.Annotated[
            Paginator,
            pagination.Depends(
                default_page=1,  # default page number if query param is not set
                default_page_size=10,  # default page size if query param is not set
                max_page_size=100,  # maximum page size
                url_page_query_param_name="fooPage",  # query param name to set a page number
                url_page_size_query_param_name="fooPageSize",
                # query param name to set page size, set `None` to disable this option
            )
        ]
) -> Paginated[MyModel]:  # use Paginated[...] to warp collection response 
    # ...

    return paginator(..., total=...)  # total is used to calculate amount of pages

# /users?fooPage=1&fooPageSize=100
```


----------------------------

## Sorting

### Example

```python
import typing as tp
from fastapi_utk import Sorting, SortingOption

from my_app import router
from my_app.response_models import User

sorting = Sorting()


@router.get("/users")
def get_users(
        sort_by: tp.Annotated[
            list[SortingOption],
            sorting.Depends(
                choices=["age", "name"],
                default=["-age"]
            )
        ],
) -> list[User]:
    total, users = get_users_from_db(..., _sort_by=sort_by)

    return [
        User(
            id=user.id,
            age=user.age,
            name=user.name,
        )
        for user in users
    ]
```


----------------------------
