mirror of
https://github.com/grillazz/fastapi-sqlalchemy-asyncpg.git
synced 2025-08-26 16:40:40 +03:00
Merge pull request #134 from grillazz/129-import-xlsx-endpoint
129 import xlsx endpoint
This commit is contained in:
commit
2325704232
2
Makefile
2
Makefile
@ -35,7 +35,7 @@ safety: ## Check project and dependencies with safety https://github.com/pyupio/
|
||||
|
||||
.PHONY: py-upgrade
|
||||
py-upgrade: ## Upgrade project py files with pyupgrade library for python version 3.10
|
||||
pyupgrade --py311-plus `find app -name "*.py"`
|
||||
pyupgrade --py312-plus `find app -name "*.py"`
|
||||
|
||||
.PHONY: lint
|
||||
lint: ## Lint project code.
|
||||
|
31
README.md
31
README.md
@ -26,28 +26,25 @@
|
||||
<li><a href="#how-to-feed-database">How to feed database</a></li>
|
||||
<li><a href="#rainbow-logs-with-rich">Rainbow logs with rich</a></li>
|
||||
<li><a href="#setup-user-auth">Setup user auth</a></li>
|
||||
<li><a href="#local-development-with-poetry">Local development with poetry</a></li>
|
||||
<li><a href="#import-xlsx-files-with-polars-and-calamine">Import xlsx files with polars and calamine</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
[//]: # ( <li><a href="#usage">Usage</a></li>)
|
||||
|
||||
[//]: # ( <li><a href="#roadmap">Roadmap</a></li>)
|
||||
|
||||
[//]: # ( <li><a href="#contributing">Contributing</a></li>)
|
||||
|
||||
[//]: # ( <li><a href="#license">License</a></li>)
|
||||
|
||||
[//]: # ( <li><a href="#contact">Contact</a></li>)
|
||||
<li><a href="#acknowledgments">Acknowledgments</a></li>
|
||||
</ol>
|
||||
</details>
|
||||
|
||||
[//]: # (TODO: Usage,Roadmap, Contributing, License, Contact)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## About The Project
|
||||
|
||||
Example of [FastAPI](https://fastapi.tiangolo.com/) integration supported by almighty [Pydantic 2.0](https://github.com/pydantic/pydantic)
|
||||
with [SQLAlchemy ORM](https://www.sqlalchemy.org/) and PostgreSQL
|
||||
with [SQLAlchemy ORM](https://www.sqlalchemy.org/) and PostgreSQL16
|
||||
connected via fastest Database Client Library for python/asyncio [asyncpg](https://github.com/MagicStack/asyncpg).
|
||||
|
||||
Beside of using latest and greatest version of [SQLAlchemy](https://www.sqlalchemy.org/) with it robustness, powerfulness and speed
|
||||
@ -131,6 +128,14 @@ poetry install
|
||||
```
|
||||
Hope you enjoy it.
|
||||
|
||||
### Import xlsx files with polars and calamine
|
||||
Power of Polars Library in data manipulation and analysis.
|
||||
It uses the polars library to read the Excel data into a DataFrame by passing the bytes to the `pl.read_excel()` function -
|
||||
https://docs.pola.rs/py-polars/html/reference/api/polars.read_excel.html
|
||||
In `pl.read_excel()` “calamine” engine can be used for reading all major types of Excel Workbook (.xlsx, .xlsb, .xls) and is dramatically faster than the other options, using the fastexcel module to bind calamine.
|
||||
|
||||
<p align="right">(<a href="#readme-top">back to top</a>)</p>
|
||||
|
||||
## Acknowledgments
|
||||
Use this space to list resources you find helpful and would like to give credit to.
|
||||
I've included a few of my favorites to kick things off!
|
||||
@ -138,6 +143,7 @@ I've included a few of my favorites to kick things off!
|
||||
* [Open Source Shakespeare Dataset](https://github.com/catherinedevlin/opensourceshakespeare)
|
||||
* [SQL Code Generator](https://github.com/agronholm/sqlacodegen)
|
||||
* [Passlib - password hashing library for Python](https://passlib.readthedocs.io/en/stable/)
|
||||
* [Polars - fast DataFrame library for Rust and Python](https://docs.pola.rs/)
|
||||
|
||||
<p align="right">(<a href="#readme-top">back to top</a>)</p>
|
||||
|
||||
@ -155,7 +161,8 @@ I've included a few of my favorites to kick things off!
|
||||
- **[JUL 25 2023]** add user authentication with JWT and Redis as token storage :lock: :key:
|
||||
- **[SEP 2 2023]** add passlib and bcrypt for password hashing :lock: :key:
|
||||
- **[OCT 21 2023]** refactor shakespeare models to use sqlalchemy 2.0 :fast_forward:
|
||||
- **[FEB 1 2024]** bum project to Python 3.12 :fast_forward:
|
||||
- **[FEB 1 2024]** bump project to Python 3.12 :fast_forward:
|
||||
- **[MAR 15 2024]** add polars and calamine to project :features:
|
||||
<p align="right">(<a href="#readme-top">back to top</a>)</p>
|
||||
|
||||
|
||||
|
@ -1,4 +1,7 @@
|
||||
from fastapi import APIRouter, Depends, status
|
||||
import io
|
||||
from fastapi import APIRouter, Depends, status, UploadFile, HTTPException
|
||||
from sqlalchemy.exc import SQLAlchemyError
|
||||
import polars as pl
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from app.database import get_db
|
||||
@ -48,3 +51,59 @@ async def merge_nonsense(
|
||||
nonsense = Nonsense(**payload.model_dump())
|
||||
await nonsense.save_or_update(db_session)
|
||||
return nonsense
|
||||
|
||||
|
||||
@router.post(
|
||||
"/import",
|
||||
status_code=status.HTTP_201_CREATED,
|
||||
)
|
||||
async def import_nonsense(
|
||||
xlsx: UploadFile,
|
||||
db_session: AsyncSession = Depends(get_db),
|
||||
):
|
||||
"""
|
||||
This function is a FastAPI route handler that imports data from an Excel file into a database.
|
||||
|
||||
Args:
|
||||
xlsx (UploadFile): The Excel file that will be uploaded by the client.
|
||||
db_session (AsyncSession): A SQLAlchemy session for interacting with the database.
|
||||
|
||||
Returns:
|
||||
dict: A dictionary containing the filename and the number of imported records.
|
||||
|
||||
Raises:
|
||||
HTTPException: If an error occurs during the process (either a SQLAlchemy error or an HTTP exception),
|
||||
the function rolls back the session and raises an HTTP exception with a 422 status code.
|
||||
"""
|
||||
try:
|
||||
# Read the uploaded file into bytes
|
||||
file_bytes = await xlsx.read()
|
||||
|
||||
# Use the `polars` library to read the Excel data into a DataFrame
|
||||
nonsense_data = pl.read_excel(
|
||||
source=io.BytesIO(file_bytes),
|
||||
sheet_name="New Nonsense",
|
||||
engine="calamine",
|
||||
)
|
||||
# Iterate over the DataFrame rows and create a list of `Nonsense` objects
|
||||
nonsense_records = [
|
||||
Nonsense(
|
||||
name=nonsense.get("name"),
|
||||
description=nonsense.get("description"),
|
||||
)
|
||||
for nonsense in nonsense_data.to_dicts()
|
||||
]
|
||||
# Add all the `Nonsense` objects to the SQLAlchemy session
|
||||
db_session.add_all(nonsense_records)
|
||||
# Commit the session to save the objects to the database
|
||||
await db_session.commit()
|
||||
# Return a JSON response containing the filename and the number of imported records
|
||||
return {"filename": xlsx.filename, "nonsense_records": len(nonsense_records)}
|
||||
except (SQLAlchemyError, HTTPException, ValueError) as ex:
|
||||
# If an error occurs, roll back the session
|
||||
await db_session.rollback()
|
||||
# Raise an HTTP exception with a 422 status code
|
||||
raise HTTPException(status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail=repr(ex)) from ex
|
||||
finally:
|
||||
# Ensure that the database session is closed, regardless of whether an error occurred or not
|
||||
await db_session.close()
|
||||
|
@ -63,6 +63,7 @@ class Wordform(Base):
|
||||
- `occurrences` (int): The number of occurrences of the word form.
|
||||
|
||||
"""
|
||||
|
||||
__tablename__ = "wordform"
|
||||
__table_args__ = (PrimaryKeyConstraint("id", name="wordform_pkey"), {"schema": "shakespeare"})
|
||||
|
||||
@ -133,6 +134,7 @@ class Chapter(Base):
|
||||
- `paragraph` (list[Paragraph]): The paragraphs associated with the chapter.
|
||||
|
||||
"""
|
||||
|
||||
__tablename__ = "chapter"
|
||||
__table_args__ = (
|
||||
ForeignKeyConstraint(["work_id"], ["shakespeare.work.id"], name="chapter_work_id_fkey"),
|
||||
@ -193,6 +195,7 @@ class Paragraph(Base):
|
||||
- `find(cls, db_session: AsyncSession, character: str) -> List[Paragraph]`: A class method that finds paragraphs associated with a specific character. It takes a database session and the name of the character as arguments, and returns a list of matching paragraphs.
|
||||
|
||||
"""
|
||||
|
||||
__tablename__ = "paragraph"
|
||||
__table_args__ = (
|
||||
ForeignKeyConstraint(["character_id"], ["shakespeare.character.id"], name="paragraph_character_id_fkey"),
|
||||
|
@ -27,11 +27,7 @@ class Stuff(Base):
|
||||
:param name:
|
||||
:return:
|
||||
"""
|
||||
stmt = (
|
||||
select(cls)
|
||||
.options(joinedload(cls.nonsense))
|
||||
.where(cls.name == name)
|
||||
)
|
||||
stmt = select(cls).options(joinedload(cls.nonsense)).where(cls.name == name)
|
||||
result = await db_session.execute(stmt)
|
||||
instance = result.scalars().first()
|
||||
if instance is None:
|
||||
|
177
poetry.lock
generated
177
poetry.lock
generated
@ -474,6 +474,37 @@ typing-extensions = ">=4.8.0"
|
||||
[package.extras]
|
||||
all = ["email-validator (>=2.0.0)", "httpx (>=0.23.0)", "itsdangerous (>=1.1.0)", "jinja2 (>=2.11.2)", "orjson (>=3.2.1)", "pydantic-extra-types (>=2.0.0)", "pydantic-settings (>=2.0.0)", "python-multipart (>=0.0.5)", "pyyaml (>=5.3.1)", "ujson (>=4.0.1,!=4.0.2,!=4.1.0,!=4.2.0,!=4.3.0,!=5.0.0,!=5.1.0)", "uvicorn[standard] (>=0.12.0)"]
|
||||
|
||||
[[package]]
|
||||
name = "fastexcel"
|
||||
version = "0.9.0"
|
||||
description = ""
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "fastexcel-0.9.0-cp310-cp310-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:a5a35bda90994c63dc5f2c954b20bc1d4fe9467cc62f346fdd2c3646978208b2"},
|
||||
{file = "fastexcel-0.9.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5006fcf6b619c7c4653c70400ff1ca68103eb253768ea85a4a62883fb72a8d53"},
|
||||
{file = "fastexcel-0.9.0-cp310-none-win_amd64.whl", hash = "sha256:f3b47371f650f98e214108034803ffaac9267199c2b13ab1e2fd6885dfa2672b"},
|
||||
{file = "fastexcel-0.9.0-cp311-cp311-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:65b93e743f808901cf429fa5f48ecb1f294f2734e98cd49246342c59800d30be"},
|
||||
{file = "fastexcel-0.9.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e55ad5c7b9bc8876201b4a3fb3d325c3cd0a9ae4bd13b4e4aa406234bb10a07e"},
|
||||
{file = "fastexcel-0.9.0-cp311-none-win_amd64.whl", hash = "sha256:9c42a5c750c3af2e9dd102bcc18f4326d29189c7573f0fc386aa4f600b61adb0"},
|
||||
{file = "fastexcel-0.9.0-cp312-cp312-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:c9f0a9184b7f7864209bec53d64c0d04ebd51d947501e91a55159288837997b3"},
|
||||
{file = "fastexcel-0.9.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c5a026b53e9733a605387fc4d43d5cab2c5a535669e17eab1ec26fe41a4a024"},
|
||||
{file = "fastexcel-0.9.0-cp312-none-win_amd64.whl", hash = "sha256:95e50824ae92fd1bf4d02208080cd05e8026cc6b7114574344cd241b3d16e62b"},
|
||||
{file = "fastexcel-0.9.0-cp38-cp38-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:b949af5baee79a988589ca7d0e4a7604fcdd708ad1ecd534737dff536cc412c8"},
|
||||
{file = "fastexcel-0.9.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:62054336a956798158baee9c45173d01b510d83dbb38ba13e543d57f8b5585bc"},
|
||||
{file = "fastexcel-0.9.0-cp38-none-win_amd64.whl", hash = "sha256:b3757c36efa97572bb667558b6173559fc7611443cbc481d6b3af5e8d479830d"},
|
||||
{file = "fastexcel-0.9.0-cp39-cp39-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:5d0c62ef2774040e560fc92b45fe6a091b933ab425293483b22b331daa4ba8c7"},
|
||||
{file = "fastexcel-0.9.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a9403bd6571626f9df048fa7468f699b55053683ce28914028358925a9394b20"},
|
||||
{file = "fastexcel-0.9.0-cp39-none-win_amd64.whl", hash = "sha256:b65d6e76423708432885ef609cf1c16042077b567a5334fb0e110f2e411dcd61"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
pyarrow = ">=8.0.0"
|
||||
|
||||
[package.extras]
|
||||
pandas = ["pandas (>=1.4.4)"]
|
||||
polars = ["polars (>=0.16.14)"]
|
||||
|
||||
[[package]]
|
||||
name = "greenlet"
|
||||
version = "3.0.3"
|
||||
@ -881,6 +912,51 @@ files = [
|
||||
{file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "numpy"
|
||||
version = "1.26.4"
|
||||
description = "Fundamental package for array computing in Python"
|
||||
optional = false
|
||||
python-versions = ">=3.9"
|
||||
files = [
|
||||
{file = "numpy-1.26.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9ff0f4f29c51e2803569d7a51c2304de5554655a60c5d776e35b4a41413830d0"},
|
||||
{file = "numpy-1.26.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2e4ee3380d6de9c9ec04745830fd9e2eccb3e6cf790d39d7b98ffd19b0dd754a"},
|
||||
{file = "numpy-1.26.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d209d8969599b27ad20994c8e41936ee0964e6da07478d6c35016bc386b66ad4"},
|
||||
{file = "numpy-1.26.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ffa75af20b44f8dba823498024771d5ac50620e6915abac414251bd971b4529f"},
|
||||
{file = "numpy-1.26.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:62b8e4b1e28009ef2846b4c7852046736bab361f7aeadeb6a5b89ebec3c7055a"},
|
||||
{file = "numpy-1.26.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a4abb4f9001ad2858e7ac189089c42178fcce737e4169dc61321660f1a96c7d2"},
|
||||
{file = "numpy-1.26.4-cp310-cp310-win32.whl", hash = "sha256:bfe25acf8b437eb2a8b2d49d443800a5f18508cd811fea3181723922a8a82b07"},
|
||||
{file = "numpy-1.26.4-cp310-cp310-win_amd64.whl", hash = "sha256:b97fe8060236edf3662adfc2c633f56a08ae30560c56310562cb4f95500022d5"},
|
||||
{file = "numpy-1.26.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4c66707fabe114439db9068ee468c26bbdf909cac0fb58686a42a24de1760c71"},
|
||||
{file = "numpy-1.26.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:edd8b5fe47dab091176d21bb6de568acdd906d1887a4584a15a9a96a1dca06ef"},
|
||||
{file = "numpy-1.26.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7ab55401287bfec946ced39700c053796e7cc0e3acbef09993a9ad2adba6ca6e"},
|
||||
{file = "numpy-1.26.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:666dbfb6ec68962c033a450943ded891bed2d54e6755e35e5835d63f4f6931d5"},
|
||||
{file = "numpy-1.26.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:96ff0b2ad353d8f990b63294c8986f1ec3cb19d749234014f4e7eb0112ceba5a"},
|
||||
{file = "numpy-1.26.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:60dedbb91afcbfdc9bc0b1f3f402804070deed7392c23eb7a7f07fa857868e8a"},
|
||||
{file = "numpy-1.26.4-cp311-cp311-win32.whl", hash = "sha256:1af303d6b2210eb850fcf03064d364652b7120803a0b872f5211f5234b399f20"},
|
||||
{file = "numpy-1.26.4-cp311-cp311-win_amd64.whl", hash = "sha256:cd25bcecc4974d09257ffcd1f098ee778f7834c3ad767fe5db785be9a4aa9cb2"},
|
||||
{file = "numpy-1.26.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b3ce300f3644fb06443ee2222c2201dd3a89ea6040541412b8fa189341847218"},
|
||||
{file = "numpy-1.26.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:03a8c78d01d9781b28a6989f6fa1bb2c4f2d51201cf99d3dd875df6fbd96b23b"},
|
||||
{file = "numpy-1.26.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9fad7dcb1aac3c7f0584a5a8133e3a43eeb2fe127f47e3632d43d677c66c102b"},
|
||||
{file = "numpy-1.26.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:675d61ffbfa78604709862923189bad94014bef562cc35cf61d3a07bba02a7ed"},
|
||||
{file = "numpy-1.26.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:ab47dbe5cc8210f55aa58e4805fe224dac469cde56b9f731a4c098b91917159a"},
|
||||
{file = "numpy-1.26.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:1dda2e7b4ec9dd512f84935c5f126c8bd8b9f2fc001e9f54af255e8c5f16b0e0"},
|
||||
{file = "numpy-1.26.4-cp312-cp312-win32.whl", hash = "sha256:50193e430acfc1346175fcbdaa28ffec49947a06918b7b92130744e81e640110"},
|
||||
{file = "numpy-1.26.4-cp312-cp312-win_amd64.whl", hash = "sha256:08beddf13648eb95f8d867350f6a018a4be2e5ad54c8d8caed89ebca558b2818"},
|
||||
{file = "numpy-1.26.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7349ab0fa0c429c82442a27a9673fc802ffdb7c7775fad780226cb234965e53c"},
|
||||
{file = "numpy-1.26.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:52b8b60467cd7dd1e9ed082188b4e6bb35aa5cdd01777621a1658910745b90be"},
|
||||
{file = "numpy-1.26.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d5241e0a80d808d70546c697135da2c613f30e28251ff8307eb72ba696945764"},
|
||||
{file = "numpy-1.26.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f870204a840a60da0b12273ef34f7051e98c3b5961b61b0c2c1be6dfd64fbcd3"},
|
||||
{file = "numpy-1.26.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:679b0076f67ecc0138fd2ede3a8fd196dddc2ad3254069bcb9faf9a79b1cebcd"},
|
||||
{file = "numpy-1.26.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:47711010ad8555514b434df65f7d7b076bb8261df1ca9bb78f53d3b2db02e95c"},
|
||||
{file = "numpy-1.26.4-cp39-cp39-win32.whl", hash = "sha256:a354325ee03388678242a4d7ebcd08b5c727033fcff3b2f536aea978e15ee9e6"},
|
||||
{file = "numpy-1.26.4-cp39-cp39-win_amd64.whl", hash = "sha256:3373d5d70a5fe74a2c1bb6d2cfd9609ecf686d47a2d7b1d37a8f3b6bf6003aea"},
|
||||
{file = "numpy-1.26.4-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:afedb719a9dcfc7eaf2287b839d8198e06dcd4cb5d276a3df279231138e83d30"},
|
||||
{file = "numpy-1.26.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95a7476c59002f2f6c590b9b7b998306fba6a5aa646b1e22ddfeaf8f78c3a29c"},
|
||||
{file = "numpy-1.26.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7e50d0a0cc3189f9cb0aeb3a6a6af18c16f59f004b866cd2be1c14b36134a4a0"},
|
||||
{file = "numpy-1.26.4.tar.gz", hash = "sha256:2a02aba9ed12e4ac4eb3ea9421c420301a0c6460d9830d74a9df87efa4912010"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "packaging"
|
||||
version = "21.3"
|
||||
@ -959,6 +1035,43 @@ files = [
|
||||
dev = ["pre-commit", "tox"]
|
||||
testing = ["pytest", "pytest-benchmark"]
|
||||
|
||||
[[package]]
|
||||
name = "polars"
|
||||
version = "0.20.8"
|
||||
description = "Blazingly fast DataFrame library"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "polars-0.20.8-cp38-abi3-macosx_10_12_x86_64.whl", hash = "sha256:73f1d369aeddda5f11411b6497f697f2471bbe6ae55fd936677a10a40995c83c"},
|
||||
{file = "polars-0.20.8-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:dc3a446fe606095b3ad6df3cf3dddd8ad54be7745f255fedb29f8bdf71a60760"},
|
||||
{file = "polars-0.20.8-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d3d58ebc7a24d26930535d06b8772e125038a87a6abab4c5dfd87ea19bba61f3"},
|
||||
{file = "polars-0.20.8-cp38-abi3-manylinux_2_24_aarch64.whl", hash = "sha256:5b733816ac61156c12bd0edd6d7c1a5e63859830ce0e425b6450b335024f0cd5"},
|
||||
{file = "polars-0.20.8-cp38-abi3-win_amd64.whl", hash = "sha256:2300f48ff7120eefe2cac2113990d0b0b5beedad93266b9fedfc8df133e7b13b"},
|
||||
{file = "polars-0.20.8.tar.gz", hash = "sha256:a34f6ce1c5469872b291aaf90467e632e81f92dec6c2e18136bc40cd92877411"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
adbc = ["adbc_driver_sqlite"]
|
||||
all = ["polars[adbc,cloudpickle,connectorx,deltalake,fsspec,gevent,numpy,pandas,plot,pyarrow,pydantic,pyiceberg,sqlalchemy,timezone,xlsx2csv,xlsxwriter]"]
|
||||
cloudpickle = ["cloudpickle"]
|
||||
connectorx = ["connectorx (>=0.3.2)"]
|
||||
deltalake = ["deltalake (>=0.14.0)"]
|
||||
fsspec = ["fsspec"]
|
||||
gevent = ["gevent"]
|
||||
matplotlib = ["matplotlib"]
|
||||
numpy = ["numpy (>=1.16.0)"]
|
||||
openpyxl = ["openpyxl (>=3.0.0)"]
|
||||
pandas = ["pandas", "pyarrow (>=7.0.0)"]
|
||||
plot = ["hvplot (>=0.9.1)"]
|
||||
pyarrow = ["pyarrow (>=7.0.0)"]
|
||||
pydantic = ["pydantic"]
|
||||
pyiceberg = ["pyiceberg (>=0.5.0)"]
|
||||
pyxlsb = ["pyxlsb (>=1.0)"]
|
||||
sqlalchemy = ["pandas", "sqlalchemy"]
|
||||
timezone = ["backports.zoneinfo", "tzdata"]
|
||||
xlsx2csv = ["xlsx2csv (>=0.8.0)"]
|
||||
xlsxwriter = ["xlsxwriter"]
|
||||
|
||||
[[package]]
|
||||
name = "prompt-toolkit"
|
||||
version = "3.0.43"
|
||||
@ -1079,6 +1192,54 @@ files = [
|
||||
[package.extras]
|
||||
tests = ["pytest"]
|
||||
|
||||
[[package]]
|
||||
name = "pyarrow"
|
||||
version = "15.0.0"
|
||||
description = "Python library for Apache Arrow"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "pyarrow-15.0.0-cp310-cp310-macosx_10_15_x86_64.whl", hash = "sha256:0a524532fd6dd482edaa563b686d754c70417c2f72742a8c990b322d4c03a15d"},
|
||||
{file = "pyarrow-15.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:60a6bdb314affa9c2e0d5dddf3d9cbb9ef4a8dddaa68669975287d47ece67642"},
|
||||
{file = "pyarrow-15.0.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:66958fd1771a4d4b754cd385835e66a3ef6b12611e001d4e5edfcef5f30391e2"},
|
||||
{file = "pyarrow-15.0.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1f500956a49aadd907eaa21d4fff75f73954605eaa41f61cb94fb008cf2e00c6"},
|
||||
{file = "pyarrow-15.0.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:6f87d9c4f09e049c2cade559643424da84c43a35068f2a1c4653dc5b1408a929"},
|
||||
{file = "pyarrow-15.0.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:85239b9f93278e130d86c0e6bb455dcb66fc3fd891398b9d45ace8799a871a1e"},
|
||||
{file = "pyarrow-15.0.0-cp310-cp310-win_amd64.whl", hash = "sha256:5b8d43e31ca16aa6e12402fcb1e14352d0d809de70edd185c7650fe80e0769e3"},
|
||||
{file = "pyarrow-15.0.0-cp311-cp311-macosx_10_15_x86_64.whl", hash = "sha256:fa7cd198280dbd0c988df525e50e35b5d16873e2cdae2aaaa6363cdb64e3eec5"},
|
||||
{file = "pyarrow-15.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8780b1a29d3c8b21ba6b191305a2a607de2e30dab399776ff0aa09131e266340"},
|
||||
{file = "pyarrow-15.0.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fe0ec198ccc680f6c92723fadcb97b74f07c45ff3fdec9dd765deb04955ccf19"},
|
||||
{file = "pyarrow-15.0.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:036a7209c235588c2f07477fe75c07e6caced9b7b61bb897c8d4e52c4b5f9555"},
|
||||
{file = "pyarrow-15.0.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:2bd8a0e5296797faf9a3294e9fa2dc67aa7f10ae2207920dbebb785c77e9dbe5"},
|
||||
{file = "pyarrow-15.0.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:e8ebed6053dbe76883a822d4e8da36860f479d55a762bd9e70d8494aed87113e"},
|
||||
{file = "pyarrow-15.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:17d53a9d1b2b5bd7d5e4cd84d018e2a45bc9baaa68f7e6e3ebed45649900ba99"},
|
||||
{file = "pyarrow-15.0.0-cp312-cp312-macosx_10_15_x86_64.whl", hash = "sha256:9950a9c9df24090d3d558b43b97753b8f5867fb8e521f29876aa021c52fda351"},
|
||||
{file = "pyarrow-15.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:003d680b5e422d0204e7287bb3fa775b332b3fce2996aa69e9adea23f5c8f970"},
|
||||
{file = "pyarrow-15.0.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f75fce89dad10c95f4bf590b765e3ae98bcc5ba9f6ce75adb828a334e26a3d40"},
|
||||
{file = "pyarrow-15.0.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0ca9cb0039923bec49b4fe23803807e4ef39576a2bec59c32b11296464623dc2"},
|
||||
{file = "pyarrow-15.0.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:9ed5a78ed29d171d0acc26a305a4b7f83c122d54ff5270810ac23c75813585e4"},
|
||||
{file = "pyarrow-15.0.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:6eda9e117f0402dfcd3cd6ec9bfee89ac5071c48fc83a84f3075b60efa96747f"},
|
||||
{file = "pyarrow-15.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:9a3a6180c0e8f2727e6f1b1c87c72d3254cac909e609f35f22532e4115461177"},
|
||||
{file = "pyarrow-15.0.0-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:19a8918045993349b207de72d4576af0191beef03ea655d8bdb13762f0cd6eac"},
|
||||
{file = "pyarrow-15.0.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:d0ec076b32bacb6666e8813a22e6e5a7ef1314c8069d4ff345efa6246bc38593"},
|
||||
{file = "pyarrow-15.0.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5db1769e5d0a77eb92344c7382d6543bea1164cca3704f84aa44e26c67e320fb"},
|
||||
{file = "pyarrow-15.0.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e2617e3bf9df2a00020dd1c1c6dce5cc343d979efe10bc401c0632b0eef6ef5b"},
|
||||
{file = "pyarrow-15.0.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:d31c1d45060180131caf10f0f698e3a782db333a422038bf7fe01dace18b3a31"},
|
||||
{file = "pyarrow-15.0.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:c8c287d1d479de8269398b34282e206844abb3208224dbdd7166d580804674b7"},
|
||||
{file = "pyarrow-15.0.0-cp38-cp38-win_amd64.whl", hash = "sha256:07eb7f07dc9ecbb8dace0f58f009d3a29ee58682fcdc91337dfeb51ea618a75b"},
|
||||
{file = "pyarrow-15.0.0-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:47af7036f64fce990bb8a5948c04722e4e3ea3e13b1007ef52dfe0aa8f23cf7f"},
|
||||
{file = "pyarrow-15.0.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:93768ccfff85cf044c418bfeeafce9a8bb0cee091bd8fd19011aff91e58de540"},
|
||||
{file = "pyarrow-15.0.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f6ee87fd6892700960d90abb7b17a72a5abb3b64ee0fe8db6c782bcc2d0dc0b4"},
|
||||
{file = "pyarrow-15.0.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:001fca027738c5f6be0b7a3159cc7ba16a5c52486db18160909a0831b063c4e4"},
|
||||
{file = "pyarrow-15.0.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:d1c48648f64aec09accf44140dccb92f4f94394b8d79976c426a5b79b11d4fa7"},
|
||||
{file = "pyarrow-15.0.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:972a0141be402bb18e3201448c8ae62958c9c7923dfaa3b3d4530c835ac81aed"},
|
||||
{file = "pyarrow-15.0.0-cp39-cp39-win_amd64.whl", hash = "sha256:f01fc5cf49081426429127aa2d427d9d98e1cb94a32cb961d583a70b7c4504e6"},
|
||||
{file = "pyarrow-15.0.0.tar.gz", hash = "sha256:876858f549d540898f927eba4ef77cd549ad8d24baa3207cf1b72e5788b50e83"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
numpy = ">=1.16.6,<2"
|
||||
|
||||
[[package]]
|
||||
name = "pydantic"
|
||||
version = "2.6.0"
|
||||
@ -1321,6 +1482,20 @@ files = [
|
||||
[package.extras]
|
||||
cli = ["click (>=5.0)"]
|
||||
|
||||
[[package]]
|
||||
name = "python-multipart"
|
||||
version = "0.0.9"
|
||||
description = "A streaming multipart parser for Python"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "python_multipart-0.0.9-py3-none-any.whl", hash = "sha256:97ca7b8ea7b05f977dc3849c3ba99d51689822fab725c3703af7c866a0c2b215"},
|
||||
{file = "python_multipart-0.0.9.tar.gz", hash = "sha256:03f54688c663f1b7977105f021043b0793151e4cb1c1a9d4a11fc13d622c4026"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
dev = ["atomicwrites (==1.4.1)", "attrs (==23.2.0)", "coverage (==7.4.1)", "hatch", "invoke (==2.2.0)", "more-itertools (==10.2.0)", "pbr (==6.0.0)", "pluggy (==1.4.0)", "py (==1.11.0)", "pytest (==8.0.0)", "pytest-cov (==4.1.0)", "pytest-timeout (==2.2.0)", "pyyaml (==6.0.1)", "ruff (==0.2.1)"]
|
||||
|
||||
[[package]]
|
||||
name = "pyupgrade"
|
||||
version = "3.15.0"
|
||||
@ -2101,4 +2276,4 @@ files = [
|
||||
[metadata]
|
||||
lock-version = "2.0"
|
||||
python-versions = "^3.12"
|
||||
content-hash = "c4ed42d2fb1fa0234845ca0a8fe5701c26ef0351e9fa81c3e941e2c5a8e42067"
|
||||
content-hash = "c377a22c133bd6006c0cec3730e68cca222f16b67fde065f92be47e2af7190fc"
|
||||
|
@ -25,6 +25,9 @@ pyjwt = {version = "2.8.0", extras = ["cryptography"]}
|
||||
redis = "5.0.1"
|
||||
passlib = {version = "^1.7.4", extras = ["bcrypt"]}
|
||||
sourcery = "^1.15.0"
|
||||
polars = "^0.20.8"
|
||||
python-multipart = "^0.0.9"
|
||||
fastexcel = "^0.9.0"
|
||||
|
||||
[tool.poetry.dev-dependencies]
|
||||
devtools = { extras = ["pygments"], version = "*" }
|
||||
|
BIN
tests/api/nonsense.xlsx
Normal file
BIN
tests/api/nonsense.xlsx
Normal file
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user