FastAPI pagination

Overview

FastAPI Pagination

License codecov codecov Downloads PYPI PYPI

Installation

# Basic version
pip install fastapi-pagination

# All available integrations
pip install fastapi-pagination[all]

Available integrations:

Example

from fastapi import FastAPI, Depends
from pydantic import BaseModel

from fastapi_pagination import PaginationParams, Page
from fastapi_pagination.paginator import paginate

app = FastAPI()


class User(BaseModel):
    name: str
    surname: str


users = [
    User(name='Yurii', surname='Karabas'),
    # ...
]


@app.get('/users', response_model=Page[User])
async def get_users(params: PaginationParams = Depends()):
    return paginate(users, params)

Example using implicit params

from fastapi import FastAPI, Depends
from pydantic import BaseModel

from fastapi_pagination import Page, pagination_params
from fastapi_pagination.paginator import paginate

app = FastAPI()


class User(BaseModel):
    name: str
    surname: str


users = [
    User(name='Yurii', surname='Karabas'),
    # ...
]


@app.get('/users', response_model=Page[User], dependencies=[Depends(pagination_params)])
async def get_users():
    return paginate(users)
Comments
  • Problem with sqlalchemy .

    Problem with sqlalchemy .

    async def search_offertypes(order: bool = False, parameter: OffertypeList = Depends(), db: Session = Depends(get_db)) -> Any: return paginate(db.query(OfferType))

    output:

    TypeError: object of type 'Query' has no len()

    question 
    opened by ScrimForever 16
  • LimitOffsetParams don't work

    LimitOffsetParams don't work

    This way pagination works fine:

    from fastapi_pagination import pagination_params
    

    When switching to limit-offset version:

    from fastapi_pagination.limit_offset import pagination_params
    

    same code and adjusted request fail with: "Page should be used with PaginationParams" Request:

    http://0.0.0.0:8080/api/v1/call_records?date_from=2021-01-01&date_till=2021-02-01&limit=50&offset=0
    

    Endpoint:

    @router.get('/call_records', response_model=Page[CallRecord], dependencies=[Depends(pagination_params)], tags=['calls'])
    @handle_exceptions
    async def get_call_records(date_from: datetime.date, date_till: datetime.date):
        records = await core.get_call_records(database, date_from, date_till, None)
        page = paginate(records)
        return page
    
    documentation question 
    opened by kamikaze 15
  • pagination of records with datetimes does not include timezone (UTC) Z letter

    pagination of records with datetimes does not include timezone (UTC) Z letter

    My DB stores "datetime without timezone". When I do a query without the pagination librayr and serialize to pydantic models via parse_obj_as, the daettime string generated includes Z at the end. If I use the same query but use paginate(session, query), the paged results do not specify a timezone at the end.

    I'm on fastapi-pagination v0.9.1

    bug question 
    opened by stealthrabbi 12
  • Paginate inner model field

    Paginate inner model field

    Great library, thanks!

    How would you go about using it on an endpoint which doesn't directly return a sequence, but a model in which a field is the sequence to paginate, e.g.:

    class ResponseType(BaseModel):
        other_data: int
        data_to_paginate: Sequence[str]
    
    question 
    opened by davidbrochart 12
  • Wrong Pagination items from query , on various pages, for query with Out of Order Items

    Wrong Pagination items from query , on various pages, for query with Out of Order Items

    I am getting the wrong pagination items on various pages, which is a bit concerning.

    here is the query:

    SELECT comments.id AS comments_id, comments.cid AS comments_cid, comments.text AS comments_text, comments.time AS comments_time, comments.is_owner AS comments_is_owner, comments.video_id AS comments_video_id, comments.analysis_id AS comments_analysis_id, comments.author AS comments_author, comments.channel AS comments_channel, comments.votes AS comments_votes, comments.reply_count AS comments_reply_count, comments.sentiment AS comments_sentiment, comments.has_sentiment_negative AS comments_has_sentiment_negative, comments.has_sentiment_positive AS comments_has_sentiment_positive, comments.has_sentiment_neutral AS comments_has_sentiment_neutral, comments.is_reply AS comments_is_reply, comments.is_word_spammer AS comments_is_word_spammer, comments.is_my_spammer AS comments_is_my_spammer, comments.is_most_voted_duplicate AS comments_is_most_voted_duplicate, comments.duplicate_count AS comments_duplicate_count, comments.copy_count AS comments_copy_count, comments.is_copy AS comments_is_copy, comments.is_bot_author AS comments_is_bot_author, comments.has_fuzzy_duplicates AS comments_has_fuzzy_duplicates, comments.fuzzy_duplicate_count AS comments_fuzzy_duplicate_count, comments.is_bot AS comments_is_bot, comments.is_human AS comments_is_human, comments.external_phone_numbers AS comments_external_phone_numbers, comments.keywords AS comments_keywords, comments.phrases AS comments_phrases, comments.custom_keywords AS comments_custom_keywords, comments.custom_phrases AS comments_custom_phrases, comments.external_urls AS comments_external_urls, comments.has_external_phone_numbers AS comments_has_external_phone_numbers, comments.text_external_phone_numbers AS comments_text_external_phone_numbers, comments.unicode_characters AS comments_unicode_characters, comments.unicode_alphabet AS comments_unicode_alphabet, comments.unicode_emojis AS comments_unicode_emojis, comments.unicode_digits AS comments_unicode_digits, comments.has_keywords AS comments_has_keywords, comments.has_phrases AS comments_has_phrases, comments.has_unicode_alphabet AS comments_has_unicode_alphabet, comments.has_unicode_emojis AS comments_has_unicode_emojis, comments.has_unicode_characters AS comments_has_unicode_characters, comments.has_unicode_too_many AS comments_has_unicode_too_many, comments.has_unicode_digits AS comments_has_unicode_digits, comments.has_custom_keywords AS comments_has_custom_keywords, comments.has_custom_phrases AS comments_has_custom_phrases, comments.has_unicode_non_english AS comments_has_unicode_non_english, comments.has_external_urls AS comments_has_external_urls, comments.has_duplicates AS comments_has_duplicates, comments.has_copies AS comments_has_copies, comments.created_at AS comments_created_at 
    FROM comments 
    WHERE comments.analysis_id = %(analysis_id_1)s ORDER BY comments.votes DESC
    

    Here is the function:

    @router.get("/{analysis_id}/comments", status_code=status.HTTP_200_OK, )
    async def read_comments(analysis_id: str, params: Params = Depends(), sort: str | None = None, filters: str | None = None, search_query: str | None = None,
                            current_user: schemas.User = Depends(oauth2.get_current_active_user), db: Session = Depends(database.get_db),
                            api_key: APIKey = Depends(apikey.get_api_key)):
    
     # Sort
        if sort == 'top' or sort != 'recent':
            query = db.query(models.Comment).order_by(models.Comment.votes.desc())
        else:
            query = db.query(models.Comment).order_by(models.Comment.created_at.desc())
    
        return paginate(
            query,
            params,
        )
    
    

    The query can include various filters and is dynamic.

    The items on various pages overlap with on item on other pages. Here is one item on page 5: image and then the same id/item is on page 2: image

    The IDs are out of order because they are sorted by voted items and not the id field. If sorted by the id field then there is no issue.

    So to replicate this do an order_by another field.

    bug 
    opened by ikkysleepy 11
  • custom parameter to replace

    custom parameter to replace "total" field on Page

    I'm trying to replace the "total" field in fastapi-pagination because I'm querying a dynamodb database that has query limitations.

    The database is limited to showing more than 1000 rows. To be able to see all the results without querying I have to create a function that counts all the rows in the table and pass it to the "total" field.

    Is this possible and if yes, how?

    Any help appreciated.

    documentation 
    opened by Sibbern 8
  • Unalbe to import pagination_params

    Unalbe to import pagination_params

    Earlier when I have installed fastapi-pagination it was 0.5.2 it was working fine

    Today I installed then the version is .0.6.1

    now it produces following error.

    from fastapi_pagination import pagination_params ImportError: cannot import name 'pagination_params' from 'fastapi_pagination'

    when I am trying to import :

    from fastapi_pagination import pagination_params from fastapi_pagination.paginator import paginate from fastapi_pagination import PaginationParams, Page

    Same code is working fine in 0.5.2

    Any help is appreciated.

    question 
    opened by shyamsukhamit 8
  • SQLModel: Many-to-many relationship data dropped when paginating

    SQLModel: Many-to-many relationship data dropped when paginating

    This is similar to https://github.com/uriyyo/fastapi-pagination/issues/294

    However, when using SQLModel the relationship data is dropped. I'm always getting null for tags in my FastAPI response.

    The queries seem fine. If I remove pagination, a simple unpaginated List of CustomerViews contains the tags. Maybe I'm doing something wrong with the model setup?

    Excuse typos / weirdness. I had to pull this out of a large project and pare it down to make it readable.

    
    # Relevant schema classes ----------------------------------------------
    
    class CustomerViewToTagBase(SQLModel, TimeStampMixin):
        customer_view: int = Field(foreign_key="customer_view.id", primary_key=True)
        tag: int = Field(foreign_key="tag.id", primary_key=True)
    
    class CustomerViewToTag(CustomerViewToTagBase, table=True):
        __tablename__ = "customer_view_to_tag"
    
    class TagBase(SQLModel):
        name: str
    
    class Tag(TagBase, table=True):
        __tablename__ = "tag"
        id: Optional[int] = Field(default=None, primary_key=True)
        customer_views: List["CustomerView"] = Relationship(back_populates="tags", link_model=CustomerViewToTag)
    
    class CustomerViewBase(SQLModel):
        __tablename__ = "customer_view"
        name: Optional[str] = Field(default=None)
    
    class CustomerView(CustomerViewBase, table=True):
        id: Optional[int] = Field(default=None, primary_key=True)
        tags: List["Tag"] = Relationship(back_populates="customer_views", link_model=CustomerViewToTag)
    
    # For FastAPI
    class CustomerViewWithTag(CustomerViewBase):
        id: int
        tags: Optional[List[Tag]]
    
        # I have no idea if this is necessary, I added it based on the linked issue above #294 
        class Config:
            orm_mode = True
    
    
    # Router ------------------------------------------------------------------------
    
    @router.get("/withtags", response_model=Page[CustomerViewWithTag], status_code=200)
    async def get_customer_views_with_tags(
            db_session: AsyncSession = Depends(get_db_session),
            params: Params = Depends(),
            filter: Optional[str] = None
        ):
        async with db_session as db:
            customerviews_query = select(CustomerView).order_by(CustomerView.id).options(selectinload(CustomerView.tags))
    
            if filter is not None:
                customerviews_query = customerviews_query.filter(
                        CustomerView.name.ilike('%' + filter + '%')
                )
    
            # Switching the response_model to a List and the following code makes the relationship work properly
            # res = await db.execute(customerviews_query)
            # return res.scalars().all()
            return await paginate(session=db, query=customerviews_query, params=params)
    
    
    question 
    opened by thebleucheese 6
  • Pagination fails for a generator because

    Pagination fails for a generator because "total" is not allowed to be None

    Hi :) Thank you for the library. I am facing an issue which I hope you could help me out.

    This is my script

    from fastapi_pagination import Page, Params, iterables
    from fastapi import Depends, FastAPI
    from pydantic import BaseModel
    
    
    class User(BaseModel):
        name: str
    
    app = FastAPI()
    
    users = (User(name="Name_"+str(i)) for i in range(1000))
    
    @app.get(
        "/",
        response_model=Page[User],
    )
    def route(params: Params = Depends()):
        #return iterables.paginate(users, params, 1000) # this works
        return iterables.paginate(users, params)
    
    

    Here's the traceback

    WARNING:  StatReload detected file change in 'pag.py'. Reloading...
    INFO:     Shutting down
    INFO:     Waiting for application shutdown.
    INFO:     Application shutdown complete.
    INFO:     Finished server process [40003]
    INFO:     Started server process [40028]
    INFO:     Waiting for application startup.
    INFO:     Application startup complete.
    INFO:     127.0.0.1:54750 - "GET /?page=2&size=50 HTTP/1.1" 500 Internal Server Error
    ERROR:    Exception in ASGI application
    Traceback (most recent call last):
      File "/home/kishore/.cache/pypoetry/virtualenvs/hawkeye-xjjpv_py-py3.9/lib/python3.9/site-packages/uvicorn/protocols/http/h11_impl.py", line 396, in run_asgi
        result = await app(self.scope, self.receive, self.send)
      File "/home/kishore/.cache/pypoetry/virtualenvs/hawkeye-xjjpv_py-py3.9/lib/python3.9/site-packages/uvicorn/middleware/proxy_headers.py", line 45, in __call__
        return await self.app(scope, receive, send)
      File "/home/kishore/.cache/pypoetry/virtualenvs/hawkeye-xjjpv_py-py3.9/lib/python3.9/site-packages/fastapi/applications.py", line 199, in __call__
        await super().__call__(scope, receive, send)
      File "/home/kishore/.cache/pypoetry/virtualenvs/hawkeye-xjjpv_py-py3.9/lib/python3.9/site-packages/starlette/applications.py", line 111, in __call__
        await self.middleware_stack(scope, receive, send)
      File "/home/kishore/.cache/pypoetry/virtualenvs/hawkeye-xjjpv_py-py3.9/lib/python3.9/site-packages/starlette/middleware/errors.py", line 181, in __call__
        raise exc from None
      File "/home/kishore/.cache/pypoetry/virtualenvs/hawkeye-xjjpv_py-py3.9/lib/python3.9/site-packages/starlette/middleware/errors.py", line 159, in __call__
        await self.app(scope, receive, _send)
      File "/home/kishore/.cache/pypoetry/virtualenvs/hawkeye-xjjpv_py-py3.9/lib/python3.9/site-packages/starlette/exceptions.py", line 82, in __call__
        raise exc from None
      File "/home/kishore/.cache/pypoetry/virtualenvs/hawkeye-xjjpv_py-py3.9/lib/python3.9/site-packages/starlette/exceptions.py", line 71, in __call__
        await self.app(scope, receive, sender)
      File "/home/kishore/.cache/pypoetry/virtualenvs/hawkeye-xjjpv_py-py3.9/lib/python3.9/site-packages/starlette/routing.py", line 566, in __call__
        await route.handle(scope, receive, send)
      File "/home/kishore/.cache/pypoetry/virtualenvs/hawkeye-xjjpv_py-py3.9/lib/python3.9/site-packages/starlette/routing.py", line 227, in handle
        await self.app(scope, receive, send)
      File "/home/kishore/.cache/pypoetry/virtualenvs/hawkeye-xjjpv_py-py3.9/lib/python3.9/site-packages/starlette/routing.py", line 41, in app
        response = await func(request)
      File "/home/kishore/.cache/pypoetry/virtualenvs/hawkeye-xjjpv_py-py3.9/lib/python3.9/site-packages/fastapi/routing.py", line 201, in app
        raw_response = await run_endpoint_function(
      File "/home/kishore/.cache/pypoetry/virtualenvs/hawkeye-xjjpv_py-py3.9/lib/python3.9/site-packages/fastapi/routing.py", line 150, in run_endpoint_function
        return await run_in_threadpool(dependant.call, **values)
      File "/home/kishore/.cache/pypoetry/virtualenvs/hawkeye-xjjpv_py-py3.9/lib/python3.9/site-packages/starlette/concurrency.py", line 34, in run_in_threadpool
        return await loop.run_in_executor(None, func, *args)
      File "/usr/lib/python3.9/concurrent/futures/thread.py", line 52, in run
        result = self.fn(*self.args, **self.kwargs)
      File "/home/kishore/kishore_repositories/hx/hawkeye-poc/./pag.py", line 27, in route
        return iterables.paginate(users, params)
      File "/home/kishore/.cache/pypoetry/virtualenvs/hawkeye-xjjpv_py-py3.9/lib/python3.9/site-packages/fastapi_pagination/iterables.py", line 33, in paginate
        return create_page(items, total, params)  # type: ignore
      File "/home/kishore/.cache/pypoetry/virtualenvs/hawkeye-xjjpv_py-py3.9/lib/python3.9/site-packages/fastapi_pagination/api.py", line 36, in create_page
        return page_type.get().create(items, total, params)
      File "/home/kishore/.cache/pypoetry/virtualenvs/hawkeye-xjjpv_py-py3.9/lib/python3.9/site-packages/fastapi_pagination/default.py", line 40, in create
        return cls(
      File "pydantic/main.py", line 406, in pydantic.main.BaseModel.__init__
    pydantic.error_wrappers.ValidationError: 1 validation error for Page
    total
      none is not an allowed value (type=type_error.none.not_allowed)
    

    https://github.com/uriyyo/fastapi-pagination/blob/31a286209878e3caf2b666004fc557ec2e6e3ab3/fastapi_pagination/default.py#L34

    https://github.com/uriyyo/fastapi-pagination/blob/31a286209878e3caf2b666004fc557ec2e6e3ab3/fastapi_pagination/bases.py#L89

    The above two lines seem to be causing the problem if I'm not wrong.

    Is it possible to have it as an optional argument total: int = None or total: conint(ge=0) = None # type: ignore ?

    If you see my example, it works when I pass the length of the generator

    return iterables.paginate(users, params, 1000) # this works
    

    My use case is returning all rows from an OLAP. Since the number of rows are around a Million, I would be returning the rows using a generator and returning maybe 50-100 rows at a time to avoid memory overhead

    I can see 2 ways to solve this.

    1. Find the length of the generator and pass it to iterables.paginate and not bother modifying fastapi-pagination. ( or for this particular use case I could get the row count and pass it without bothering to find the length of the generator)
    2. Modify fastapi-pagination to handle None as a possible parameter for total pages.

    Please let me know your thoughts. I hope this is a reasonable feature to ask.

    opened by kishvanchee 6
  • How to use paginate with sqlalchemy new query syntax

    How to use paginate with sqlalchemy new query syntax

    Hi

    I'm trying to migrate to Sqlalchemy 1.4.23 and activate the new query syntax. But can't figure out how to use paginate function with it.

    fastapi-pagination==0.8.3

    from sqlalchemy.future import select
    from models import UserModel
    
    
    class User:
        def _init__(self, db_session):
            self.db_session = session
    
        def get_users():
            return select(UserModel)
    

    The endpoint looks like this:

    from fastapi_pagination.ext.sqlalchemy import paginate
    from fastapi_pagination import Page, Params
    
    @router.get('/get-users')
    def get_users(self, 
                           page_schema: PaginationParams = Depends(),
                           db_session: Session = Depends(get_request_db)) -> Page[UserSchema]:
        users = User(db_session).get_users()
    
        return paginate(users, page_schema)
    

    I'm getting this error:

    image

    Also tried:

    from sqlalchemy.future import select
    from models import UserModel
    
    
    class User:
        def _init__(self, db_session):
            self.db_session = session
    
        def get_users():
            return self.db_session.execute(select(UserModel))
    

    but got this:

    image

    enhancement 
    opened by rafa761 6
  • Fastapi-pagination Throwing error on linux instance.

    Fastapi-pagination Throwing error on linux instance.

    I am working on a project where pagination is working fine but as i take a step forward to host it on AWS EC2 ubuntu instance, it started throwing error like

    ERROR: Could not find a version that satisfies the requirement fastapi-pagination==0.5.1 ERROR: No matching distribution found for fastapi-pagination==0.5.1

    It also worked fine on heroku, i am not able to understand that this problem is from AWS or package.

    question 
    opened by alam-mahtab 6
  • fastapi-pagination [databases] --> DeprecationWarning

    fastapi-pagination [databases] --> DeprecationWarning

    image

    • test of only 1 funtion with pagination

    in file of crud:

       from fastapi_pagination.ext.databases import paginate
    
       async def smx():
           -- logic --
           return await paginate(db=db, query=table.select().where(), params=params)
    

    Deprication was fixed by Encode/Databases in last versions

    bug 
    opened by vadikam100500 0
  • 📃 Update docs

    📃 Update docs

    Documentation should be updated.

    Topics that should be covered:

    • [ ] General information
    • [ ] Customization
    • [ ] Features
    • [ ] Integrations
    • [ ] Examples

    Related issue: #273 #269 #264

    documentation help wanted good first issue 
    opened by uriyyo 2
Releases(0.11.1)
Single Page App with Flask and Vue.js

Developing a Single Page App with FastAPI and Vue.js Want to learn how to build this? Check out the post. Want to use this project? Build the images a

91 Jan 05, 2023
Fastapi performans monitoring

Fastapi-performans-monitoring This project is a simple performance monitoring for FastAPI. License This project is licensed under the terms of the MIT

bilal alpaslan 11 Dec 31, 2022
A FastAPI WebSocket application that makes use of ncellapp package by @hemantapkh

ncellFastAPI author: @awebisam Used FastAPI to create WS application. Ncellapp module by @hemantapkh NOTE: Not following best practices and, needs ref

Aashish Bhandari 7 Oct 01, 2021
Voucher FastAPI

Voucher-API Requirement Docker Installed on system Libraries Pandas Psycopg2 FastAPI PyArrow Pydantic Uvicorn How to run Download the repo on your sys

Hassan Munir 1 Jan 26, 2022
Prometheus exporter for several chia node statistics

prometheus-chia-exporter Prometheus exporter for several chia node statistics It's assumed that the full node, the harvester and the wallet run on the

30 Sep 19, 2022
Fast, simple API for Apple firmwares.

Loyal Fast, Simple API for fetching Apple Firmwares. The API server is closed due to some reasons. Wait for v2 releases. Features Fetching Signed IPSW

11 Oct 28, 2022
Ansible Inventory Plugin, created to get hosts from HTTP API.

ansible-ws-inventory-plugin Ansible Inventory Plugin, created to get hosts from HTTP API. Features: Database compatible with MongoDB and Filesystem (J

Carlos Neto 0 Feb 05, 2022
Utils for fastapi based services.

Installation pip install fastapi-serviceutils Usage For more details and usage see: readthedocs Development Getting started After cloning the repo

Simon Kallfass 31 Nov 25, 2022
Boilerplate code for quick docker implementation of REST API with JWT Authentication using FastAPI, PostgreSQL and PgAdmin ⭐

FRDP Boilerplate code for quick docker implementation of REST API with JWT Authentication using FastAPI, PostgreSQL and PgAdmin ⛏ . Getting Started Fe

BnademOverflow 53 Dec 29, 2022
FastAPI + Postgres + Docker Compose + Heroku Deploy Template

FastAPI + Postgres + Docker Compose + Heroku Deploy ⚠️ For educational purpose only. Not ready for production use YET Features FastAPI with Postgres s

DP 12 Dec 27, 2022
FastAPI application and service structure for a more maintainable codebase

Abstracting FastAPI Services See this article for more information: https://camillovisini.com/article/abstracting-fastapi-services/ Poetry poetry inst

Camillo Visini 309 Jan 04, 2023
A RESTful API for creating and monitoring resource components of a hypothetical build system. Built with FastAPI and pydantic. Complete with testing and CI.

diskspace-monitor-CRUD Background The build system is part of a large environment with a multitude of different components. Many of the components hav

Nick Hopewell 67 Dec 14, 2022
Dead simple CSRF security middleware for Starlette ⭐ and Fast API ⚡

csrf-starlette-fastapi Dead simple CSRF security middleware for Starlette ⭐ and Fast API ⚡ Will work with either a input type="hidden" field or ajax

Nathaniel Sabanski 9 Nov 20, 2022
implementation of deta base for FastAPIUsers

FastAPI Users - Database adapter for Deta Base Ready-to-use and customizable users management for FastAPI Documentation: https://fastapi-users.github.

2 Aug 15, 2022
Regex Converter for Flask URL Routes

Flask-Reggie Enable Regex Routes within Flask Installation pip install flask-reggie Configuration To enable regex routes within your application from

Rhys Elsmore 48 Mar 07, 2022
Practice-python is a simple Fast api project for dealing with modern rest api technologies.

Practice Python Practice-python is a simple Fast api project for dealing with modern rest api technologies. Deployment with docker Go to the project r

0 Sep 19, 2022
Qwerkey is a social media platform for connecting and learning more about mechanical keyboards built on React and Redux in the frontend and Flask in the backend on top of a PostgreSQL database.

Flask React Project This is the backend for the Flask React project. Getting started Clone this repository (only this branch) git clone https://github

Peter Mai 22 Dec 20, 2022
flask extension for integration with the awesome pydantic package

flask extension for integration with the awesome pydantic package

249 Jan 06, 2023
FastAPI Server Session is a dependency-based extension for FastAPI that adds support for server-sided session management

FastAPI Server-sided Session FastAPI Server Session is a dependency-based extension for FastAPI that adds support for server-sided session management.

DevGuyAhnaf 5 Dec 23, 2022
Get MODBUS data from Sofar (K-TLX) inverter through LSW-3 or LSE module

SOFAR Inverter + LSW-3/LSE Small utility to read data from SOFAR K-TLX inverters through the Solarman (LSW-3/LSE) datalogger. Two scripts to get inver

58 Dec 29, 2022