From 20786afa065ed917d58d1efbe76a14bf88dbb570 Mon Sep 17 00:00:00 2001 From: MrWaradana Date: Mon, 23 Feb 2026 16:23:46 +0700 Subject: [PATCH] refactor: Update Pydantic schemas by removing redundant `nullable` attributes and add comprehensive test execution documentation. --- docs/test.md | 85 +++++++ poetry.lock | 184 +++++++++++++-- pyproject.toml | 6 + src/__pycache__/__init__.cpython-311.pyc | Bin 139 -> 143 bytes src/__pycache__/api.cpython-311.pyc | Bin 5602 -> 5606 bytes src/__pycache__/config.cpython-311.pyc | Bin 4832 -> 4836 bytes src/__pycache__/enums.cpython-311.pyc | Bin 1061 -> 1065 bytes src/__pycache__/exceptions.cpython-311.pyc | Bin 8455 -> 8459 bytes src/__pycache__/logging.cpython-311.pyc | Bin 4987 -> 5130 bytes src/__pycache__/main.cpython-311.pyc | Bin 5990 -> 5916 bytes src/__pycache__/models.cpython-311.pyc | Bin 7220 -> 6595 bytes src/__pycache__/rate_limiter.cpython-311.pyc | Bin 331 -> 335 bytes src/acquisition_cost/schema.py | 16 +- src/auth/__pycache__/__init__.cpython-311.pyc | Bin 144 -> 148 bytes src/auth/__pycache__/model.cpython-311.pyc | Bin 531 -> 535 bytes src/auth/__pycache__/service.cpython-311.pyc | Bin 3805 -> 3809 bytes .../__pycache__/__init__.cpython-311.pyc | Bin 148 -> 152 bytes src/database/__pycache__/core.cpython-311.pyc | Bin 8684 -> 8688 bytes .../__pycache__/service.cpython-311.pyc | Bin 6534 -> 6565 bytes src/database/core.py | 4 +- .../__pycache__/__init__.cpython-311.pyc | Bin 149 -> 153 bytes .../__pycache__/model.cpython-311.pyc | Bin 10372 -> 10376 bytes .../__pycache__/router.cpython-311.pyc | Bin 16620 -> 16624 bytes .../__pycache__/schema.cpython-311.pyc | Bin 16479 -> 15553 bytes src/equipment/schema.py | 216 +++++++++--------- .../__pycache__/__init__.cpython-311.pyc | Bin 156 -> 160 bytes .../__pycache__/model.cpython-311.pyc | Bin 2593 -> 2597 bytes .../__pycache__/router.cpython-311.pyc | Bin 2432 -> 2436 bytes .../__pycache__/schema.cpython-311.pyc | Bin 3751 -> 3601 bytes .../__pycache__/service.cpython-311.pyc | Bin 2914 -> 2918 bytes src/equipment_master/schema.py | 22 +- src/manpower_cost/schema.py | 16 +- src/manpower_master/schema.py | 16 +- .../__pycache__/__init__.cpython-311.pyc | Bin 150 -> 154 bytes .../__pycache__/model.cpython-311.pyc | Bin 1082 -> 1086 bytes .../__pycache__/router.cpython-311.pyc | Bin 6436 -> 6440 bytes .../__pycache__/schema.cpython-311.pyc | Bin 4216 -> 4034 bytes .../__pycache__/service.cpython-311.pyc | Bin 14448 -> 14452 bytes src/masterdata/schema.py | 32 +-- src/masterdata_simulations/schema.py | 18 +- src/models.py | 23 +- .../__pycache__/config.cpython-311.pyc | Bin 2412 -> 2416 bytes .../equipment/__pycache__/Eac.cpython-311.pyc | Bin 15661 -> 15665 bytes .../__pycache__/Prediksi.cpython-311.pyc | Bin 52567 -> 52571 bytes src/plant_fs_transaction_data/schema.py | 52 ++--- .../__pycache__/__init__.cpython-311.pyc | Bin 156 -> 160 bytes .../__pycache__/model.cpython-311.pyc | Bin 2631 -> 2635 bytes .../__pycache__/router.cpython-311.pyc | Bin 4711 -> 4715 bytes .../__pycache__/schema.cpython-311.pyc | Bin 7960 -> 7676 bytes .../__pycache__/service.cpython-311.pyc | Bin 3699 -> 3703 bytes src/plant_masterdata/schema.py | 120 +++++----- .../__pycache__/__init__.cpython-311.pyc | Bin 162 -> 166 bytes .../__pycache__/model.cpython-311.pyc | Bin 5379 -> 5383 bytes .../__pycache__/router.cpython-311.pyc | Bin 8334 -> 8338 bytes .../__pycache__/schema.cpython-311.pyc | Bin 11848 -> 11353 bytes .../__pycache__/service.cpython-311.pyc | Bin 14708 -> 14712 bytes src/plant_transaction_data/schema.py | 162 ++++++------- .../schema.py | 208 ++++++++--------- src/simulations/schema.py | 26 +-- src/uploaded_file/schema.py | 20 +- .../__pycache__/__init__.cpython-311.pyc | Bin 148 -> 152 bytes .../__pycache__/model.cpython-311.pyc | Bin 1760 -> 1764 bytes .../__pycache__/router.cpython-311.pyc | Bin 4623 -> 4627 bytes .../__pycache__/schema.cpython-311.pyc | Bin 4364 -> 4204 bytes .../__pycache__/service.cpython-311.pyc | Bin 3879 -> 3883 bytes src/yeardata/schema.py | 38 +-- tests/conftest.py | 34 ++- tests/unit/test_masterdata_service.py | 2 + 68 files changed, 772 insertions(+), 528 deletions(-) create mode 100644 docs/test.md diff --git a/docs/test.md b/docs/test.md new file mode 100644 index 0000000..674da1e --- /dev/null +++ b/docs/test.md @@ -0,0 +1,85 @@ +# Panduan Menjalankan Script Testing di BE LCCA Digital Twin + +Proyek ini menggunakan **Pytest** sebagai framework pengujian. Infrastruktur testing terletak di direktori `tests/` dan dikonfigurasi untuk menangani sifat asynchronous dari aplikasi FastAPI serta isolasi database. + +--- + +## **1. Persiapan Lingkungan (Environment Setup)** +Pastikan Anda berada di root direktori proyek dan environment sudah siap. + +### **Opsi A: Menggunakan Virtual Environment (Direkomendasikan)** +Aktifkan `venv` sebelum menjalankan perintah apapun: +```bash +source venv/bin/activate +``` + +### **Opsi B: Menggunakan Poetry** +Jika Anda lebih suka menggunakan Poetry secara langsung tanpa aktivasi manual: +```bash +poetry run pytest +``` + +--- + +## **2. Menjalankan Pengujian** + +| Tujuan | Perintah | +| :--- | :--- | +| **Jalankan Unit Tests** | `pytest tests/unit` | +| **Jalankan E2E Tests** | `pytest tests/e2e` | +| **Jalankan semua test** | `pytest` | +| **Tampilkan statement print** | `pytest -s` | +| **Berhenti di kegagalan pertama** | `pytest -x` | +| **Jalankan file spesifik** | `pytest tests/unit/test_example.py` | + +> **Catatan**: Verbose output (`-v`) sudah aktif secara default di konfigurasi `pyproject.toml`. + +--- + +## **3. Peringatan Penting (Caution for E2E Tests)** + +⚠️ **PENTING**: Saat menjalankan pengujian **End-to-End (E2E)**, pastikan Anda menggunakan **Testing Database**. + +* **JANGAN PERNAH** menjalankan E2E tests menggunakan database **Production** atau **Development**. +* Pengujian E2E seringkali melakukan operasi manipulasi data (create, update, delete) dan pembersihan database secara otomatis yang dapat mengakibatkan **kehilangan data permanen**. +* Selalu gunakan database terpisah (misalnya PostgreSQL instance khusus testing atau SQLite) yang aman untuk dihapus isinya sewaktu-waktu. + +--- + +## **4. Gambaran Infrastruktur Testing** +Direktori `tests/` berisi beberapa utility script yang memudahkan proses testing: + +* **`conftest.py`**: Berisi fixture global. Sudah terkonfigurasi dengan: + * `client`: `AsyncClient` untuk simulasi request API ke aplikasi FastAPI Anda. + * `setup_db`: Secara otomatis membuat dan menghapus database test (SQLite in-memory) untuk setiap sesi pengujian. +* **`factories.py`**: Menggunakan `factory-boy` untuk menghasilkan mock data untuk model Anda. +* **`database.py`**: Mengonfigurasi session database untuk kebutuhan pengujian. + +--- + +## **5. Menulis Test Pertama Anda** +Agar `pytest` mengenali sebuah file sebagai test, file tersebut harus dinamai dengan format `test_*.py` atau `*_test.py`. + +**Contoh (`tests/test_api.py`):** +```python +import pytest + +@pytest.mark.asyncio +async def test_api_status(client): + """Contoh pengujian menggunakan fixture 'client' dari conftest.py""" + response = await client.get("/") + assert response.status_code == 200 +``` + +--- + +## **6. Tips Troubleshooting** +* **Masalah Module Path**: Jika Anda menemui error `ModuleNotFoundError`, jalankan test dengan menambahkan direktori saat ini ke `PYTHONPATH`: + ```bash + export PYTHONPATH=$PYTHONPATH:. + pytest + ``` +* **Menjalankan Test yang Gagal Saja**: Untuk menghemat waktu, jalankan hanya test yang gagal pada sesi sebelumnya: + ```bash + pytest --lf + ``` \ No newline at end of file diff --git a/poetry.lock b/poetry.lock index 5415881..75a7063 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,20 @@ -# This file is automatically @generated by Poetry 1.8.5 and should not be changed by hand. +# This file is automatically @generated by Poetry 2.2.1 and should not be changed by hand. + +[[package]] +name = "aiosqlite" +version = "0.22.1" +description = "asyncio bridge to the standard sqlite3 module" +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "aiosqlite-0.22.1-py3-none-any.whl", hash = "sha256:21c002eb13823fad740196c5a2e9d8e62f6243bd9e7e4a1f87fb5e44ecb4fceb"}, + {file = "aiosqlite-0.22.1.tar.gz", hash = "sha256:043e0bd78d32888c0a9ca90fc788b38796843360c855a7262a532813133a0650"}, +] + +[package.extras] +dev = ["attribution (==1.8.0)", "black (==25.11.0)", "build (>=1.2)", "coverage[toml] (==7.10.7)", "flake8 (==7.3.0)", "flake8-bugbear (==24.12.12)", "flit (==3.12.0)", "mypy (==1.19.0)", "ufmt (==2.8.0)", "usort (==1.0.8.post1)"] +docs = ["sphinx (==8.1.3)", "sphinx-mdinclude (==0.6.2)"] [[package]] name = "annotated-types" @@ -6,6 +22,7 @@ version = "0.7.0" description = "Reusable constraint types to use with typing.Annotated" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53"}, {file = "annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89"}, @@ -17,6 +34,7 @@ version = "4.8.0" description = "High level compatibility layer for multiple asynchronous event loop implementations" optional = false python-versions = ">=3.9" +groups = ["main"] files = [ {file = "anyio-4.8.0-py3-none-any.whl", hash = "sha256:b5011f270ab5eb0abf13385f851315585cc37ef330dd88e27ec3d34d651fd47a"}, {file = "anyio-4.8.0.tar.gz", hash = "sha256:1d9fe889df5212298c0c0723fa20479d1b94883a2df44bd3897aa91083316f7a"}, @@ -30,7 +48,7 @@ typing_extensions = {version = ">=4.5", markers = "python_version < \"3.13\""} [package.extras] doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx_rtd_theme"] -test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21)"] +test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "trustme", "truststore (>=0.9.1) ; python_version >= \"3.10\"", "uvloop (>=0.21) ; platform_python_implementation == \"CPython\" and platform_system != \"Windows\" and python_version < \"3.14\""] trio = ["trio (>=0.26.1)"] [[package]] @@ -39,6 +57,8 @@ version = "5.0.1" description = "Timeout context manager for asyncio programs" optional = false python-versions = ">=3.8" +groups = ["main"] +markers = "python_version == \"3.10\"" files = [ {file = "async_timeout-5.0.1-py3-none-any.whl", hash = "sha256:39e3809566ff85354557ec2398b55e096c8364bacac9405a7a1fa429e77fe76c"}, {file = "async_timeout-5.0.1.tar.gz", hash = "sha256:d9321a7a3d5a6a5e187e824d2fa0793ce379a202935782d555d6e9d2735677d3"}, @@ -50,6 +70,7 @@ version = "0.30.0" description = "An asyncio PostgreSQL driver" optional = false python-versions = ">=3.8.0" +groups = ["main"] files = [ {file = "asyncpg-0.30.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bfb4dd5ae0699bad2b233672c8fc5ccbd9ad24b89afded02341786887e37927e"}, {file = "asyncpg-0.30.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:dc1f62c792752a49f88b7e6f774c26077091b44caceb1983509edc18a2222ec0"}, @@ -107,8 +128,21 @@ async-timeout = {version = ">=4.0.3", markers = "python_version < \"3.11.0\""} [package.extras] docs = ["Sphinx (>=8.1.3,<8.2.0)", "sphinx-rtd-theme (>=1.2.2)"] -gssauth = ["gssapi", "sspilib"] -test = ["distro (>=1.9.0,<1.10.0)", "flake8 (>=6.1,<7.0)", "flake8-pyi (>=24.1.0,<24.2.0)", "gssapi", "k5test", "mypy (>=1.8.0,<1.9.0)", "sspilib", "uvloop (>=0.15.3)"] +gssauth = ["gssapi ; platform_system != \"Windows\"", "sspilib ; platform_system == \"Windows\""] +test = ["distro (>=1.9.0,<1.10.0)", "flake8 (>=6.1,<7.0)", "flake8-pyi (>=24.1.0,<24.2.0)", "gssapi ; platform_system == \"Linux\"", "k5test ; platform_system == \"Linux\"", "mypy (>=1.8.0,<1.9.0)", "sspilib ; platform_system == \"Windows\"", "uvloop (>=0.15.3) ; platform_system != \"Windows\" and python_version < \"3.14.0\""] + +[[package]] +name = "backports-asyncio-runner" +version = "1.2.0" +description = "Backport of asyncio.Runner, a context manager that controls event loop life cycle." +optional = false +python-versions = "<3.11,>=3.8" +groups = ["main"] +markers = "python_version == \"3.10\"" +files = [ + {file = "backports_asyncio_runner-1.2.0-py3-none-any.whl", hash = "sha256:0da0a936a8aeb554eccb426dc55af3ba63bcdc69fa1a600b5bb305413a4477b5"}, + {file = "backports_asyncio_runner-1.2.0.tar.gz", hash = "sha256:a5aa7b2b7d8f8bfcaa2b57313f70792df84e32a2a746f585213373f900b42162"}, +] [[package]] name = "certifi" @@ -116,6 +150,7 @@ version = "2025.1.31" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" +groups = ["main"] files = [ {file = "certifi-2025.1.31-py3-none-any.whl", hash = "sha256:ca78db4565a652026a4db2bcdf68f2fb589ea80d0be70e03929ed730746b84fe"}, {file = "certifi-2025.1.31.tar.gz", hash = "sha256:3d5da6925056f6f18f119200434a4780a94263f10d1c21d032a6f6b2baa20651"}, @@ -127,6 +162,7 @@ version = "3.4.1" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de"}, {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176"}, @@ -228,6 +264,7 @@ version = "8.1.8" description = "Composable command line interface toolkit" optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "click-8.1.8-py3-none-any.whl", hash = "sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2"}, {file = "click-8.1.8.tar.gz", hash = "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a"}, @@ -242,6 +279,8 @@ version = "0.4.6" description = "Cross-platform colored terminal text." optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" +groups = ["main"] +markers = "platform_system == \"Windows\" or sys_platform == \"win32\"" files = [ {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, @@ -253,6 +292,7 @@ version = "1.3.1" description = "Python library for calculating contours of 2D quadrilateral grids" optional = false python-versions = ">=3.10" +groups = ["main"] files = [ {file = "contourpy-1.3.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a045f341a77b77e1c5de31e74e966537bba9f3c4099b35bf4c2e3939dd54cdab"}, {file = "contourpy-1.3.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:500360b77259914f7805af7462e41f9cb7ca92ad38e9f94d6c8641b089338124"}, @@ -326,6 +366,7 @@ version = "0.12.1" description = "Composable style cycles" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "cycler-0.12.1-py3-none-any.whl", hash = "sha256:85cef7cff222d8644161529808465972e51340599459b8ac3ccbac5a854e0d30"}, {file = "cycler-0.12.1.tar.gz", hash = "sha256:88bb128f02ba341da8ef447245a9e138fae777f6a23943da4540077d3601eb1c"}, @@ -341,6 +382,7 @@ version = "1.2.18" description = "Python @deprecated decorator to deprecate old python classes, functions or methods." optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" +groups = ["main"] files = [ {file = "Deprecated-1.2.18-py2.py3-none-any.whl", hash = "sha256:bd5011788200372a32418f888e326a09ff80d0214bd961147cfed01b5c018eec"}, {file = "deprecated-1.2.18.tar.gz", hash = "sha256:422b6f6d859da6f2ef57857761bfb392480502a64c3028ca9bbe86085d72115d"}, @@ -350,7 +392,7 @@ files = [ wrapt = ">=1.10,<2" [package.extras] -dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "setuptools", "tox"] +dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "setuptools ; python_version >= \"3.12\"", "tox"] [[package]] name = "dnspython" @@ -358,6 +400,7 @@ version = "2.7.0" description = "DNS toolkit" optional = false python-versions = ">=3.9" +groups = ["main"] files = [ {file = "dnspython-2.7.0-py3-none-any.whl", hash = "sha256:b4c34b7d10b51bcc3a5071e7b8dee77939f1e878477eeecc965e9835f63c6c86"}, {file = "dnspython-2.7.0.tar.gz", hash = "sha256:ce9c432eda0dc91cf618a5cedf1a4e142651196bbcd2c80e89ed5a907e5cfaf1"}, @@ -378,6 +421,7 @@ version = "2.2.0" description = "A robust email address syntax and deliverability validation library." optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "email_validator-2.2.0-py3-none-any.whl", hash = "sha256:561977c2d73ce3611850a06fa56b414621e0c8faa9d66f2611407d87465da631"}, {file = "email_validator-2.2.0.tar.gz", hash = "sha256:cb690f344c617a714f22e66ae771445a1ceb46821152df8e165c5f9a364582b7"}, @@ -393,6 +437,7 @@ version = "2.0.0" description = "An implementation of lxml.xmlfile for the standard library" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "et_xmlfile-2.0.0-py3-none-any.whl", hash = "sha256:7a91720bc756843502c3b7504c77b8fe44217c85c537d85037f0f536151b2caa"}, {file = "et_xmlfile-2.0.0.tar.gz", hash = "sha256:dab3f4764309081ce75662649be815c4c9081e88f0837825f90fd28317d4da54"}, @@ -404,6 +449,8 @@ version = "1.2.2" description = "Backport of PEP 654 (exception groups)" optional = false python-versions = ">=3.7" +groups = ["main"] +markers = "python_version == \"3.10\"" files = [ {file = "exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b"}, {file = "exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc"}, @@ -418,6 +465,7 @@ version = "3.3.1" description = "A versatile test fixtures replacement based on thoughtbot's factory_bot for Ruby." optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "factory_boy-3.3.1-py2.py3-none-any.whl", hash = "sha256:7b1113c49736e1e9995bc2a18f4dbf2c52cf0f841103517010b1d825712ce3ca"}, {file = "factory_boy-3.3.1.tar.gz", hash = "sha256:8317aa5289cdfc45f9cae570feb07a6177316c82e34d14df3c2e1f22f26abef0"}, @@ -436,6 +484,7 @@ version = "30.10.0" description = "Faker is a Python package that generates fake data for you." optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "Faker-30.10.0-py3-none-any.whl", hash = "sha256:5f05ee92ddf0e1736d95dca41b2a16ee06d987b736fa4ddecdb047abf2e9024b"}, {file = "faker-30.10.0.tar.gz", hash = "sha256:c2e627d3becec67f7a45400d3670018b5abb3f0728b7dfaa06c135b7df1ce3fb"}, @@ -451,6 +500,7 @@ version = "0.115.8" description = "FastAPI framework, high performance, easy to learn, fast to code, ready for production" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "fastapi-0.115.8-py3-none-any.whl", hash = "sha256:753a96dd7e036b34eeef8babdfcfe3f28ff79648f86551eb36bfc1b0bf4a8cbf"}, {file = "fastapi-0.115.8.tar.gz", hash = "sha256:0ce9111231720190473e222cdf0f07f7206ad7e53ea02beb1d2dc36e2f0741e9"}, @@ -477,6 +527,7 @@ version = "0.0.7" description = "Run and manage FastAPI apps from the command line with FastAPI CLI. 🚀" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "fastapi_cli-0.0.7-py3-none-any.whl", hash = "sha256:d549368ff584b2804336c61f192d86ddea080c11255f375959627911944804f4"}, {file = "fastapi_cli-0.0.7.tar.gz", hash = "sha256:02b3b65956f526412515907a0793c9094abd4bfb5457b389f645b0ea6ba3605e"}, @@ -496,6 +547,7 @@ version = "4.56.0" description = "Tools to manipulate font files" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "fonttools-4.56.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:331954d002dbf5e704c7f3756028e21db07097c19722569983ba4d74df014000"}, {file = "fonttools-4.56.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:8d1613abd5af2f93c05867b3a3759a56e8bf97eb79b1da76b2bc10892f96ff16"}, @@ -550,18 +602,18 @@ files = [ ] [package.extras] -all = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "fs (>=2.2.0,<3)", "lxml (>=4.0)", "lz4 (>=1.7.4.2)", "matplotlib", "munkres", "pycairo", "scipy", "skia-pathops (>=0.5.0)", "sympy", "uharfbuzz (>=0.23.0)", "unicodedata2 (>=15.1.0)", "xattr", "zopfli (>=0.1.4)"] +all = ["brotli (>=1.0.1) ; platform_python_implementation == \"CPython\"", "brotlicffi (>=0.8.0) ; platform_python_implementation != \"CPython\"", "fs (>=2.2.0,<3)", "lxml (>=4.0)", "lz4 (>=1.7.4.2)", "matplotlib", "munkres ; platform_python_implementation == \"PyPy\"", "pycairo", "scipy ; platform_python_implementation != \"PyPy\"", "skia-pathops (>=0.5.0)", "sympy", "uharfbuzz (>=0.23.0)", "unicodedata2 (>=15.1.0) ; python_version <= \"3.12\"", "xattr ; sys_platform == \"darwin\"", "zopfli (>=0.1.4)"] graphite = ["lz4 (>=1.7.4.2)"] -interpolatable = ["munkres", "pycairo", "scipy"] +interpolatable = ["munkres ; platform_python_implementation == \"PyPy\"", "pycairo", "scipy ; platform_python_implementation != \"PyPy\""] lxml = ["lxml (>=4.0)"] pathops = ["skia-pathops (>=0.5.0)"] plot = ["matplotlib"] repacker = ["uharfbuzz (>=0.23.0)"] symfont = ["sympy"] -type1 = ["xattr"] +type1 = ["xattr ; sys_platform == \"darwin\""] ufo = ["fs (>=2.2.0,<3)"] -unicode = ["unicodedata2 (>=15.1.0)"] -woff = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "zopfli (>=0.1.4)"] +unicode = ["unicodedata2 (>=15.1.0) ; python_version <= \"3.12\""] +woff = ["brotli (>=1.0.1) ; platform_python_implementation == \"CPython\"", "brotlicffi (>=0.8.0) ; platform_python_implementation != \"CPython\"", "zopfli (>=0.1.4)"] [[package]] name = "greenlet" @@ -569,6 +621,8 @@ version = "3.1.1" description = "Lightweight in-process concurrent programming" optional = false python-versions = ">=3.7" +groups = ["main"] +markers = "python_version < \"3.14\" and (platform_machine == \"aarch64\" or platform_machine == \"ppc64le\" or platform_machine == \"x86_64\" or platform_machine == \"amd64\" or platform_machine == \"AMD64\" or platform_machine == \"win32\" or platform_machine == \"WIN32\")" files = [ {file = "greenlet-3.1.1-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:0bbae94a29c9e5c7e4a2b7f0aae5c17e8e90acbfd3bf6270eeba60c39fce3563"}, {file = "greenlet-3.1.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0fde093fb93f35ca72a556cf72c92ea3ebfda3d79fc35bb19fbe685853869a83"}, @@ -655,6 +709,7 @@ version = "0.14.0" description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1" optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761"}, {file = "h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d"}, @@ -666,6 +721,7 @@ version = "1.0.7" description = "A minimal low-level HTTP client." optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "httpcore-1.0.7-py3-none-any.whl", hash = "sha256:a3fff8f43dc260d5bd363d9f9cf1830fa3a458b332856f34282de498ed420edd"}, {file = "httpcore-1.0.7.tar.gz", hash = "sha256:8551cb62a169ec7162ac7be8d4817d561f60e08eaa485234898414bb5a8a0b4c"}, @@ -687,6 +743,7 @@ version = "0.6.4" description = "A collection of framework independent HTTP protocol utils." optional = false python-versions = ">=3.8.0" +groups = ["main"] files = [ {file = "httptools-0.6.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:3c73ce323711a6ffb0d247dcd5a550b8babf0f757e86a52558fe5b86d6fefcc0"}, {file = "httptools-0.6.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:345c288418f0944a6fe67be8e6afa9262b18c7626c3ef3c28adc5eabc06a68da"}, @@ -742,6 +799,7 @@ version = "0.27.2" description = "The next generation HTTP client." optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "httpx-0.27.2-py3-none-any.whl", hash = "sha256:7bb2708e112d8fdd7829cd4243970f0c223274051cb35ee80c03301ee29a3df0"}, {file = "httpx-0.27.2.tar.gz", hash = "sha256:f7c2be1d2f3c3c3160d441802406b206c2b76f5947b11115e6df10c6c65e66c2"}, @@ -755,7 +813,7 @@ idna = "*" sniffio = "*" [package.extras] -brotli = ["brotli", "brotlicffi"] +brotli = ["brotli ; platform_python_implementation == \"CPython\"", "brotlicffi ; platform_python_implementation != \"CPython\""] cli = ["click (==8.*)", "pygments (==2.*)", "rich (>=10,<14)"] http2 = ["h2 (>=3,<5)"] socks = ["socksio (==1.*)"] @@ -767,6 +825,7 @@ version = "3.10" description = "Internationalized Domain Names in Applications (IDNA)" optional = false python-versions = ">=3.6" +groups = ["main"] files = [ {file = "idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3"}, {file = "idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9"}, @@ -781,6 +840,7 @@ version = "2.0.0" description = "brain-dead simple config-ini parsing" optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"}, {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, @@ -792,6 +852,7 @@ version = "3.1.5" description = "A very fast and expressive template engine." optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb"}, {file = "jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb"}, @@ -809,6 +870,7 @@ version = "1.4.2" description = "Lightweight pipelining with Python functions" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "joblib-1.4.2-py3-none-any.whl", hash = "sha256:06d478d5674cbc267e7496a410ee875abd68e4340feff4490bcb7afb88060ae6"}, {file = "joblib-1.4.2.tar.gz", hash = "sha256:2382c5816b2636fbd20a09e0f4e9dad4736765fdfb7dca582943b9c1366b3f0e"}, @@ -820,6 +882,7 @@ version = "1.4.8" description = "A fast implementation of the Cassowary constraint solver" optional = false python-versions = ">=3.10" +groups = ["main"] files = [ {file = "kiwisolver-1.4.8-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:88c6f252f6816a73b1f8c904f7bbe02fd67c09a69f7cb8a0eecdbf5ce78e63db"}, {file = "kiwisolver-1.4.8-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c72941acb7b67138f35b879bbe85be0f6c6a70cab78fe3ef6db9c024d9223e5b"}, @@ -909,6 +972,7 @@ version = "4.0.1" description = "Rate limiting utilities" optional = false python-versions = ">=3.9" +groups = ["main"] files = [ {file = "limits-4.0.1-py3-none-any.whl", hash = "sha256:67667e669f570cf7be4e2c2bc52f763b3f93bdf66ea945584360bc1a3f251901"}, {file = "limits-4.0.1.tar.gz", hash = "sha256:a54f5c058dfc965319ae3ee78faf222294659e371b46d22cd7456761f7e46d5a"}, @@ -920,9 +984,9 @@ packaging = ">=21,<25" typing-extensions = "*" [package.extras] -all = ["aetcd", "coredis (>=3.4.0,<5)", "emcache (>=0.6.1)", "emcache (>=1)", "etcd3", "motor (>=3,<4)", "pymemcache (>3,<5.0.0)", "pymongo (>4.1,<5)", "redis (>3,!=4.5.2,!=4.5.3,<6.0.0)", "redis (>=4.2.0,!=4.5.2,!=4.5.3)"] +all = ["aetcd", "coredis (>=3.4.0,<5)", "emcache (>=0.6.1) ; python_version < \"3.11\"", "emcache (>=1) ; python_version >= \"3.11\" and python_version < \"3.13.0\"", "etcd3", "motor (>=3,<4)", "pymemcache (>3,<5.0.0)", "pymongo (>4.1,<5)", "redis (>3,!=4.5.2,!=4.5.3,<6.0.0)", "redis (>=4.2.0,!=4.5.2,!=4.5.3)"] async-etcd = ["aetcd"] -async-memcached = ["emcache (>=0.6.1)", "emcache (>=1)"] +async-memcached = ["emcache (>=0.6.1) ; python_version < \"3.11\"", "emcache (>=1) ; python_version >= \"3.11\" and python_version < \"3.13.0\""] async-mongodb = ["motor (>=3,<4)"] async-redis = ["coredis (>=3.4.0,<5)"] etcd = ["etcd3"] @@ -937,6 +1001,7 @@ version = "3.0.0" description = "Python port of markdown-it. Markdown parsing, done right!" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb"}, {file = "markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1"}, @@ -961,6 +1026,7 @@ version = "3.0.2" description = "Safely add untrusted strings to HTML/XML markup." optional = false python-versions = ">=3.9" +groups = ["main"] files = [ {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7e94c425039cde14257288fd61dcfb01963e658efbc0ff54f5306b06054700f8"}, {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9e2d922824181480953426608b81967de705c3cef4d1af983af849d7bd619158"}, @@ -1031,6 +1097,7 @@ version = "3.10.0" description = "Python plotting package" optional = false python-versions = ">=3.10" +groups = ["main"] files = [ {file = "matplotlib-3.10.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:2c5829a5a1dd5a71f0e31e6e8bb449bc0ee9dbfb05ad28fc0c6b55101b3a4be6"}, {file = "matplotlib-3.10.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a2a43cbefe22d653ab34bb55d42384ed30f611bcbdea1f8d7f431011a2e1c62e"}, @@ -1088,6 +1155,7 @@ version = "0.1.2" description = "Markdown URL utilities" optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8"}, {file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"}, @@ -1099,6 +1167,7 @@ version = "2.2.3" description = "Fundamental package for array computing in Python" optional = false python-versions = ">=3.10" +groups = ["main"] files = [ {file = "numpy-2.2.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:cbc6472e01952d3d1b2772b720428f8b90e2deea8344e854df22b0618e9cce71"}, {file = "numpy-2.2.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:cdfe0c22692a30cd830c0755746473ae66c4a8f2e7bd508b35fb3b6a0813d787"}, @@ -1163,6 +1232,7 @@ version = "1.0.0" description = "Simple financial functions" optional = false python-versions = ">=3.5" +groups = ["main"] files = [ {file = "numpy-financial-1.0.0.tar.gz", hash = "sha256:f84341bc62b2485d5604a73d5fac7e91975b4b9cd5f4a5a9cf608902ea00cb40"}, {file = "numpy_financial-1.0.0-py3-none-any.whl", hash = "sha256:bae534b357516f12258862d1f0181d911032d0467f215bfcd1c264b4da579047"}, @@ -1177,6 +1247,7 @@ version = "3.1.5" description = "A Python library to read/write Excel 2010 xlsx/xlsm files" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "openpyxl-3.1.5-py2.py3-none-any.whl", hash = "sha256:5282c12b107bffeef825f4617dc029afaf41d0ea60823bbb665ef3079dc79de2"}, {file = "openpyxl-3.1.5.tar.gz", hash = "sha256:cf0e3cf56142039133628b5acffe8ef0c12bc902d2aadd3e0fe5878dc08d1050"}, @@ -1191,6 +1262,7 @@ version = "24.2" description = "Core utilities for Python packages" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759"}, {file = "packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f"}, @@ -1202,6 +1274,7 @@ version = "2.2.3" description = "Powerful data structures for data analysis, time series, and statistics" optional = false python-versions = ">=3.9" +groups = ["main"] files = [ {file = "pandas-2.2.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1948ddde24197a0f7add2bdc4ca83bf2b1ef84a1bc8ccffd95eda17fd836ecb5"}, {file = "pandas-2.2.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:381175499d3802cde0eabbaf6324cce0c4f5d52ca6f8c377c29ad442f50f6348"}, @@ -1288,6 +1361,7 @@ version = "1.0.1" description = "A Python package for describing statistical models and for building design matrices." optional = false python-versions = ">=3.6" +groups = ["main"] files = [ {file = "patsy-1.0.1-py2.py3-none-any.whl", hash = "sha256:751fb38f9e97e62312e921a1954b81e1bb2bcda4f5eeabaf94db251ee791509c"}, {file = "patsy-1.0.1.tar.gz", hash = "sha256:e786a9391eec818c054e359b737bbce692f051aee4c661f4141cc88fb459c0c4"}, @@ -1305,6 +1379,7 @@ version = "11.1.0" description = "Python Imaging Library (Fork)" optional = false python-versions = ">=3.9" +groups = ["main"] files = [ {file = "pillow-11.1.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:e1abe69aca89514737465752b4bcaf8016de61b3be1397a8fc260ba33321b3a8"}, {file = "pillow-11.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c640e5a06869c75994624551f45e5506e4256562ead981cce820d5ab39ae2192"}, @@ -1384,7 +1459,7 @@ docs = ["furo", "olefile", "sphinx (>=8.1)", "sphinx-copybutton", "sphinx-inline fpx = ["olefile"] mic = ["olefile"] tests = ["check-manifest", "coverage (>=7.4.2)", "defusedxml", "markdown2", "olefile", "packaging", "pyroma", "pytest", "pytest-cov", "pytest-timeout", "trove-classifiers (>=2024.10.12)"] -typing = ["typing-extensions"] +typing = ["typing-extensions ; python_version < \"3.10\""] xmp = ["defusedxml"] [[package]] @@ -1393,6 +1468,7 @@ version = "1.5.0" description = "plugin and hook calling mechanisms for python" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"}, {file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"}, @@ -1408,6 +1484,7 @@ version = "2.9.10" description = "psycopg2 - Python-PostgreSQL Database Adapter" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "psycopg2-binary-2.9.10.tar.gz", hash = "sha256:4b3df0e6990aa98acda57d983942eff13d824135fe2250e6522edaa782a06de2"}, {file = "psycopg2_binary-2.9.10-cp310-cp310-macosx_12_0_x86_64.whl", hash = "sha256:0ea8e3d0ae83564f2fc554955d327fa081d065c8ca5cc6d2abb643e2c9c1200f"}, @@ -1456,6 +1533,7 @@ files = [ {file = "psycopg2_binary-2.9.10-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:bb89f0a835bcfc1d42ccd5f41f04870c1b936d8507c6df12b7737febc40f0909"}, {file = "psycopg2_binary-2.9.10-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f0c2d907a1e102526dd2986df638343388b94c33860ff3bbe1384130828714b1"}, {file = "psycopg2_binary-2.9.10-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:f8157bed2f51db683f31306aa497311b560f2265998122abe1dce6428bd86567"}, + {file = "psycopg2_binary-2.9.10-cp313-cp313-win_amd64.whl", hash = "sha256:27422aa5f11fbcd9b18da48373eb67081243662f9b46e6fd07c3eb46e4535142"}, {file = "psycopg2_binary-2.9.10-cp38-cp38-macosx_12_0_x86_64.whl", hash = "sha256:eb09aa7f9cecb45027683bb55aebaaf45a0df8bf6de68801a6afdc7947bb09d4"}, {file = "psycopg2_binary-2.9.10-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b73d6d7f0ccdad7bc43e6d34273f70d587ef62f824d7261c4ae9b8b1b6af90e8"}, {file = "psycopg2_binary-2.9.10-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ce5ab4bf46a211a8e924d307c1b1fcda82368586a19d0a24f8ae166f5c784864"}, @@ -1484,6 +1562,7 @@ version = "2.10.6" description = "Data validation using Python type hints" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "pydantic-2.10.6-py3-none-any.whl", hash = "sha256:427d664bf0b8a2b34ff5dd0f5a18df00591adcee7198fbd71981054cef37b584"}, {file = "pydantic-2.10.6.tar.gz", hash = "sha256:ca5daa827cce33de7a42be142548b0096bf05a7e7b365aebfa5f8eeec7128236"}, @@ -1496,7 +1575,7 @@ typing-extensions = ">=4.12.2" [package.extras] email = ["email-validator (>=2.0.0)"] -timezone = ["tzdata"] +timezone = ["tzdata ; python_version >= \"3.9\" and platform_system == \"Windows\""] [[package]] name = "pydantic-core" @@ -1504,6 +1583,7 @@ version = "2.27.2" description = "Core functionality for Pydantic validation and serialization" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "pydantic_core-2.27.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:2d367ca20b2f14095a8f4fa1210f5a7b78b8a20009ecced6b12818f455b1e9fa"}, {file = "pydantic_core-2.27.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:491a2b73db93fab69731eaee494f320faa4e093dbed776be1a829c2eb222c34c"}, @@ -1616,6 +1696,7 @@ version = "2.19.1" description = "Pygments is a syntax highlighting package written in Python." optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "pygments-2.19.1-py3-none-any.whl", hash = "sha256:9ea1544ad55cecf4b8242fab6dd35a93bbce657034b0611ee383099054ab6d8c"}, {file = "pygments-2.19.1.tar.gz", hash = "sha256:61c16d2a8576dc0649d9f39e089b5f02bcd27fba10d8fb4dcc28173f7a45151f"}, @@ -1630,6 +1711,7 @@ version = "3.2.1" description = "pyparsing module - Classes and methods to define and execute parsing grammars" optional = false python-versions = ">=3.9" +groups = ["main"] files = [ {file = "pyparsing-3.2.1-py3-none-any.whl", hash = "sha256:506ff4f4386c4cec0590ec19e6302d3aedb992fdc02c761e90416f158dacf8e1"}, {file = "pyparsing-3.2.1.tar.gz", hash = "sha256:61980854fd66de3a90028d679a954d5f2623e83144b5afe5ee86f43d762e5f0a"}, @@ -1644,6 +1726,7 @@ version = "8.3.4" description = "pytest: simple powerful testing with Python" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "pytest-8.3.4-py3-none-any.whl", hash = "sha256:50e16d954148559c9a74109af1eaf0c945ba2d8f30f0a3d3335edde19788b6f6"}, {file = "pytest-8.3.4.tar.gz", hash = "sha256:965370d062bce11e73868e0335abac31b4d3de0e82f4007408d242b4f8610761"}, @@ -1660,12 +1743,34 @@ tomli = {version = ">=1", markers = "python_version < \"3.11\""} [package.extras] dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] +[[package]] +name = "pytest-asyncio" +version = "1.3.0" +description = "Pytest support for asyncio" +optional = false +python-versions = ">=3.10" +groups = ["main"] +files = [ + {file = "pytest_asyncio-1.3.0-py3-none-any.whl", hash = "sha256:611e26147c7f77640e6d0a92a38ed17c3e9848063698d5c93d5aa7aa11cebff5"}, + {file = "pytest_asyncio-1.3.0.tar.gz", hash = "sha256:d7f52f36d231b80ee124cd216ffb19369aa168fc10095013c6b014a34d3ee9e5"}, +] + +[package.dependencies] +backports-asyncio-runner = {version = ">=1.1,<2", markers = "python_version < \"3.11\""} +pytest = ">=8.2,<10" +typing-extensions = {version = ">=4.12", markers = "python_version < \"3.13\""} + +[package.extras] +docs = ["sphinx (>=5.3)", "sphinx-rtd-theme (>=1)"] +testing = ["coverage (>=6.2)", "hypothesis (>=5.7.1)"] + [[package]] name = "python-dateutil" version = "2.9.0.post0" description = "Extensions to the standard Python datetime module" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" +groups = ["main"] files = [ {file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"}, {file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"}, @@ -1680,6 +1785,7 @@ version = "1.0.1" description = "Read key-value pairs from a .env file and set them as environment variables" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "python-dotenv-1.0.1.tar.gz", hash = "sha256:e324ee90a023d808f1959c46bcbc04446a10ced277783dc6ee09987c37ec10ca"}, {file = "python_dotenv-1.0.1-py3-none-any.whl", hash = "sha256:f7b63ef50f1b690dddf550d03497b66d609393b40b564ed0d674909a68ebf16a"}, @@ -1694,6 +1800,7 @@ version = "0.0.20" description = "A streaming multipart parser for Python" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "python_multipart-0.0.20-py3-none-any.whl", hash = "sha256:8a62d3a8335e06589fe01f2a3e178cdcc632f3fbe0d492ad9ee0ec35aab1f104"}, {file = "python_multipart-0.0.20.tar.gz", hash = "sha256:8dd0cab45b8e23064ae09147625994d090fa46f5b0d1e13af944c331a7fa9d13"}, @@ -1705,6 +1812,7 @@ version = "2024.2" description = "World timezone definitions, modern and historical" optional = false python-versions = "*" +groups = ["main"] files = [ {file = "pytz-2024.2-py2.py3-none-any.whl", hash = "sha256:31c7c1817eb7fae7ca4b8c7ee50c72f93aa2dd863de768e1ef4245d426aa0725"}, {file = "pytz-2024.2.tar.gz", hash = "sha256:2aa355083c50a0f93fa581709deac0c9ad65cca8a9e9beac660adcbd493c798a"}, @@ -1716,6 +1824,7 @@ version = "6.0.2" description = "YAML parser and emitter for Python" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086"}, {file = "PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf"}, @@ -1778,6 +1887,7 @@ version = "2.32.3" description = "Python HTTP for Humans." optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6"}, {file = "requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760"}, @@ -1799,6 +1909,7 @@ version = "13.9.4" description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" optional = false python-versions = ">=3.8.0" +groups = ["main"] files = [ {file = "rich-13.9.4-py3-none-any.whl", hash = "sha256:6049d5e6ec054bf2779ab3358186963bac2ea89175919d699e378b99738c2a90"}, {file = "rich-13.9.4.tar.gz", hash = "sha256:439594978a49a09530cff7ebc4b5c7103ef57baf48d5ea3184f21d9a2befa098"}, @@ -1818,6 +1929,7 @@ version = "0.13.2" description = "Rich toolkit for building command-line applications" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "rich_toolkit-0.13.2-py3-none-any.whl", hash = "sha256:f3f6c583e5283298a2f7dbd3c65aca18b7f818ad96174113ab5bec0b0e35ed61"}, {file = "rich_toolkit-0.13.2.tar.gz", hash = "sha256:fea92557530de7c28f121cbed572ad93d9e0ddc60c3ca643f1b831f2f56b95d3"}, @@ -1834,6 +1946,7 @@ version = "1.6.1" description = "A set of python modules for machine learning and data mining" optional = false python-versions = ">=3.9" +groups = ["main"] files = [ {file = "scikit_learn-1.6.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d056391530ccd1e501056160e3c9673b4da4805eb67eb2bdf4e983e1f9c9204e"}, {file = "scikit_learn-1.6.1-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:0c8d036eb937dbb568c6242fa598d551d88fb4399c0344d95c001980ec1c7d36"}, @@ -1888,6 +2001,7 @@ version = "1.15.1" description = "Fundamental algorithms for scientific computing in Python" optional = false python-versions = ">=3.10" +groups = ["main"] files = [ {file = "scipy-1.15.1-cp310-cp310-macosx_10_13_x86_64.whl", hash = "sha256:c64ded12dcab08afff9e805a67ff4480f5e69993310e093434b10e85dc9d43e1"}, {file = "scipy-1.15.1-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:5b190b935e7db569960b48840e5bef71dc513314cc4e79a1b7d14664f57fd4ff"}, @@ -1937,7 +2051,7 @@ numpy = ">=1.23.5,<2.5" [package.extras] dev = ["cython-lint (>=0.12.2)", "doit (>=0.36.0)", "mypy (==1.10.0)", "pycodestyle", "pydevtool", "rich-click", "ruff (>=0.0.292)", "types-psutil", "typing_extensions"] doc = ["intersphinx_registry", "jupyterlite-pyodide-kernel", "jupyterlite-sphinx (>=0.16.5)", "jupytext", "matplotlib (>=3.5)", "myst-nb", "numpydoc", "pooch", "pydata-sphinx-theme (>=0.15.2)", "sphinx (>=5.0.0,<8.0.0)", "sphinx-copybutton", "sphinx-design (>=0.4.0)"] -test = ["Cython", "array-api-strict (>=2.0,<2.1.1)", "asv", "gmpy2", "hypothesis (>=6.30)", "meson", "mpmath", "ninja", "pooch", "pytest", "pytest-cov", "pytest-timeout", "pytest-xdist", "scikit-umfpack", "threadpoolctl"] +test = ["Cython", "array-api-strict (>=2.0,<2.1.1)", "asv", "gmpy2", "hypothesis (>=6.30)", "meson", "mpmath", "ninja ; sys_platform != \"emscripten\"", "pooch", "pytest", "pytest-cov", "pytest-timeout", "pytest-xdist", "scikit-umfpack", "threadpoolctl"] [[package]] name = "shellingham" @@ -1945,6 +2059,7 @@ version = "1.5.4" description = "Tool to Detect Surrounding Shell" optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686"}, {file = "shellingham-1.5.4.tar.gz", hash = "sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de"}, @@ -1956,6 +2071,7 @@ version = "1.17.0" description = "Python 2 and 3 compatibility utilities" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" +groups = ["main"] files = [ {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, @@ -1967,6 +2083,7 @@ version = "0.1.9" description = "A rate limiting extension for Starlette and Fastapi" optional = false python-versions = ">=3.7,<4.0" +groups = ["main"] files = [ {file = "slowapi-0.1.9-py3-none-any.whl", hash = "sha256:cfad116cfb84ad9d763ee155c1e5c5cbf00b0d47399a769b227865f5df576e36"}, {file = "slowapi-0.1.9.tar.gz", hash = "sha256:639192d0f1ca01b1c6d95bf6c71d794c3a9ee189855337b4821f7f457dddad77"}, @@ -1984,6 +2101,7 @@ version = "1.3.1" description = "Sniff out which async library your code is running under" optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2"}, {file = "sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc"}, @@ -1995,6 +2113,7 @@ version = "2.0.37" description = "Database Abstraction Library" optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "SQLAlchemy-2.0.37-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:da36c3b0e891808a7542c5c89f224520b9a16c7f5e4d6a1156955605e54aef0e"}, {file = "SQLAlchemy-2.0.37-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e7402ff96e2b073a98ef6d6142796426d705addd27b9d26c3b32dbaa06d7d069"}, @@ -2090,6 +2209,7 @@ version = "0.13.0" description = "A library to filter SQLAlchemy queries." optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "sqlalchemy-filters-0.13.0.tar.gz", hash = "sha256:40f2daead93c4db2409cf5e5abf67a420179f9e5c1df5c15fa1b474f6533b105"}, {file = "sqlalchemy_filters-0.13.0-py3-none-any.whl", hash = "sha256:aa4595b90d152eb76fa312a3e03d5d675f0c2e16762751f340f5449468689d9a"}, @@ -2110,6 +2230,7 @@ version = "0.41.2" description = "Various utility functions for SQLAlchemy." optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "SQLAlchemy-Utils-0.41.2.tar.gz", hash = "sha256:bc599c8c3b3319e53ce6c5c3c471120bd325d0071fb6f38a10e924e3d07b9990"}, {file = "SQLAlchemy_Utils-0.41.2-py3-none-any.whl", hash = "sha256:85cf3842da2bf060760f955f8467b87983fb2e30f1764fd0e24a48307dc8ec6e"}, @@ -2127,8 +2248,8 @@ intervals = ["intervals (>=0.7.1)"] password = ["passlib (>=1.6,<2.0)"] pendulum = ["pendulum (>=2.0.5)"] phone = ["phonenumbers (>=5.9.2)"] -test = ["Jinja2 (>=2.3)", "Pygments (>=1.2)", "backports.zoneinfo", "docutils (>=0.10)", "flake8 (>=2.4.0)", "flexmock (>=0.9.7)", "isort (>=4.2.2)", "pg8000 (>=1.12.4)", "psycopg (>=3.1.8)", "psycopg2 (>=2.5.1)", "psycopg2cffi (>=2.8.1)", "pymysql", "pyodbc", "pytest (==7.4.4)", "python-dateutil (>=2.6)", "pytz (>=2014.2)"] -test-all = ["Babel (>=1.3)", "Jinja2 (>=2.3)", "Pygments (>=1.2)", "arrow (>=0.3.4)", "backports.zoneinfo", "colour (>=0.0.4)", "cryptography (>=0.6)", "docutils (>=0.10)", "flake8 (>=2.4.0)", "flexmock (>=0.9.7)", "furl (>=0.4.1)", "intervals (>=0.7.1)", "isort (>=4.2.2)", "passlib (>=1.6,<2.0)", "pendulum (>=2.0.5)", "pg8000 (>=1.12.4)", "phonenumbers (>=5.9.2)", "psycopg (>=3.1.8)", "psycopg2 (>=2.5.1)", "psycopg2cffi (>=2.8.1)", "pymysql", "pyodbc", "pytest (==7.4.4)", "python-dateutil", "python-dateutil (>=2.6)", "pytz (>=2014.2)"] +test = ["Jinja2 (>=2.3)", "Pygments (>=1.2)", "backports.zoneinfo ; python_version < \"3.9\"", "docutils (>=0.10)", "flake8 (>=2.4.0)", "flexmock (>=0.9.7)", "isort (>=4.2.2)", "pg8000 (>=1.12.4)", "psycopg (>=3.1.8)", "psycopg2 (>=2.5.1)", "psycopg2cffi (>=2.8.1)", "pymysql", "pyodbc", "pytest (==7.4.4)", "python-dateutil (>=2.6)", "pytz (>=2014.2)"] +test-all = ["Babel (>=1.3)", "Jinja2 (>=2.3)", "Pygments (>=1.2)", "arrow (>=0.3.4)", "backports.zoneinfo ; python_version < \"3.9\"", "colour (>=0.0.4)", "cryptography (>=0.6)", "docutils (>=0.10)", "flake8 (>=2.4.0)", "flexmock (>=0.9.7)", "furl (>=0.4.1)", "intervals (>=0.7.1)", "isort (>=4.2.2)", "passlib (>=1.6,<2.0)", "pendulum (>=2.0.5)", "pg8000 (>=1.12.4)", "phonenumbers (>=5.9.2)", "psycopg (>=3.1.8)", "psycopg2 (>=2.5.1)", "psycopg2cffi (>=2.8.1)", "pymysql", "pyodbc", "pytest (==7.4.4)", "python-dateutil", "python-dateutil (>=2.6)", "pytz (>=2014.2)"] timezone = ["python-dateutil"] url = ["furl (>=0.4.1)"] @@ -2138,6 +2259,7 @@ version = "0.45.3" description = "The little ASGI library that shines." optional = false python-versions = ">=3.9" +groups = ["main"] files = [ {file = "starlette-0.45.3-py3-none-any.whl", hash = "sha256:dfb6d332576f136ec740296c7e8bb8c8a7125044e7c6da30744718880cdd059d"}, {file = "starlette-0.45.3.tar.gz", hash = "sha256:2cbcba2a75806f8a41c722141486f37c28e30a0921c5f6fe4346cb0dcee1302f"}, @@ -2155,6 +2277,7 @@ version = "0.14.4" description = "Statistical computations and models for Python" optional = false python-versions = ">=3.9" +groups = ["main"] files = [ {file = "statsmodels-0.14.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7a62f1fc9086e4b7ee789a6f66b3c0fc82dd8de1edda1522d30901a0aa45e42b"}, {file = "statsmodels-0.14.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:46ac7ddefac0c9b7b607eed1d47d11e26fe92a1bc1f4d9af48aeed4e21e87981"}, @@ -2197,7 +2320,7 @@ scipy = ">=1.8,<1.9.2 || >1.9.2" [package.extras] build = ["cython (>=3.0.10)"] -develop = ["colorama", "cython (>=3.0.10)", "cython (>=3.0.10,<4)", "flake8", "isort", "joblib", "matplotlib (>=3)", "pytest (>=7.3.0,<8)", "pytest-cov", "pytest-randomly", "pytest-xdist", "pywinpty", "setuptools-scm[toml] (>=8.0,<9.0)"] +develop = ["colorama", "cython (>=3.0.10)", "cython (>=3.0.10,<4)", "flake8", "isort", "joblib", "matplotlib (>=3)", "pytest (>=7.3.0,<8)", "pytest-cov", "pytest-randomly", "pytest-xdist", "pywinpty ; os_name == \"nt\"", "setuptools-scm[toml] (>=8.0,<9.0)"] docs = ["ipykernel", "jupyter-client", "matplotlib", "nbconvert", "nbformat", "numpydoc", "pandas-datareader", "sphinx"] [[package]] @@ -2206,6 +2329,7 @@ version = "3.5.0" description = "threadpoolctl" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "threadpoolctl-3.5.0-py3-none-any.whl", hash = "sha256:56c1e26c150397e58c4926da8eeee87533b1e32bef131bd4bf6a2f45f3185467"}, {file = "threadpoolctl-3.5.0.tar.gz", hash = "sha256:082433502dd922bf738de0d8bcc4fdcbf0979ff44c42bd40f5af8a282f6fa107"}, @@ -2217,6 +2341,8 @@ version = "2.2.1" description = "A lil' TOML parser" optional = false python-versions = ">=3.8" +groups = ["main"] +markers = "python_version == \"3.10\"" files = [ {file = "tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249"}, {file = "tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6"}, @@ -2258,6 +2384,7 @@ version = "0.15.1" description = "Typer, build great CLIs. Easy to code. Based on Python type hints." optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "typer-0.15.1-py3-none-any.whl", hash = "sha256:7994fb7b8155b64d3402518560648446072864beefd44aa2dc36972a5972e847"}, {file = "typer-0.15.1.tar.gz", hash = "sha256:a0588c0a7fa68a1978a069818657778f86abe6ff5ea6abf472f940a08bfe4f0a"}, @@ -2275,6 +2402,7 @@ version = "4.12.2" description = "Backported and Experimental Type Hints for Python 3.8+" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"}, {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, @@ -2286,6 +2414,7 @@ version = "2025.1" description = "Provider of IANA time zone data" optional = false python-versions = ">=2" +groups = ["main"] files = [ {file = "tzdata-2025.1-py2.py3-none-any.whl", hash = "sha256:7e127113816800496f027041c570f50bcd464a020098a3b6b199517772303639"}, {file = "tzdata-2025.1.tar.gz", hash = "sha256:24894909e88cdb28bd1636c6887801df64cb485bd593f2fd83ef29075a81d694"}, @@ -2297,13 +2426,14 @@ version = "2.3.0" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false python-versions = ">=3.9" +groups = ["main"] files = [ {file = "urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df"}, {file = "urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d"}, ] [package.extras] -brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] +brotli = ["brotli (>=1.0.9) ; platform_python_implementation == \"CPython\"", "brotlicffi (>=0.8.0) ; platform_python_implementation != \"CPython\""] h2 = ["h2 (>=4,<5)"] socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] zstd = ["zstandard (>=0.18.0)"] @@ -2314,6 +2444,7 @@ version = "0.32.1" description = "The lightning-fast ASGI server." optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "uvicorn-0.32.1-py3-none-any.whl", hash = "sha256:82ad92fd58da0d12af7482ecdb5f2470a04c9c9a53ced65b9bbb4a205377602e"}, {file = "uvicorn-0.32.1.tar.gz", hash = "sha256:ee9519c246a72b1c084cea8d3b44ed6026e78a4a309cbedae9c37e4cb9fbb175"}, @@ -2327,12 +2458,12 @@ httptools = {version = ">=0.6.3", optional = true, markers = "extra == \"standar python-dotenv = {version = ">=0.13", optional = true, markers = "extra == \"standard\""} pyyaml = {version = ">=5.1", optional = true, markers = "extra == \"standard\""} typing-extensions = {version = ">=4.0", markers = "python_version < \"3.11\""} -uvloop = {version = ">=0.14.0,<0.15.0 || >0.15.0,<0.15.1 || >0.15.1", optional = true, markers = "(sys_platform != \"win32\" and sys_platform != \"cygwin\") and platform_python_implementation != \"PyPy\" and extra == \"standard\""} +uvloop = {version = ">=0.14.0,<0.15.0 || >0.15.0,<0.15.1 || >0.15.1", optional = true, markers = "sys_platform != \"win32\" and sys_platform != \"cygwin\" and platform_python_implementation != \"PyPy\" and extra == \"standard\""} watchfiles = {version = ">=0.13", optional = true, markers = "extra == \"standard\""} websockets = {version = ">=10.4", optional = true, markers = "extra == \"standard\""} [package.extras] -standard = ["colorama (>=0.4)", "httptools (>=0.6.3)", "python-dotenv (>=0.13)", "pyyaml (>=5.1)", "uvloop (>=0.14.0,!=0.15.0,!=0.15.1)", "watchfiles (>=0.13)", "websockets (>=10.4)"] +standard = ["colorama (>=0.4) ; sys_platform == \"win32\"", "httptools (>=0.6.3)", "python-dotenv (>=0.13)", "pyyaml (>=5.1)", "uvloop (>=0.14.0,!=0.15.0,!=0.15.1) ; sys_platform != \"win32\" and sys_platform != \"cygwin\" and platform_python_implementation != \"PyPy\"", "watchfiles (>=0.13)", "websockets (>=10.4)"] [[package]] name = "uvloop" @@ -2340,6 +2471,8 @@ version = "0.21.0" description = "Fast implementation of asyncio event loop on top of libuv" optional = false python-versions = ">=3.8.0" +groups = ["main"] +markers = "sys_platform != \"win32\" and sys_platform != \"cygwin\" and platform_python_implementation != \"PyPy\"" files = [ {file = "uvloop-0.21.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ec7e6b09a6fdded42403182ab6b832b71f4edaf7f37a9a0e371a01db5f0cb45f"}, {file = "uvloop-0.21.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:196274f2adb9689a289ad7d65700d37df0c0930fd8e4e743fa4834e850d7719d"}, @@ -2391,6 +2524,7 @@ version = "1.0.4" description = "Simple, modern and high performance file watching and code reload in python." optional = false python-versions = ">=3.9" +groups = ["main"] files = [ {file = "watchfiles-1.0.4-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:ba5bb3073d9db37c64520681dd2650f8bd40902d991e7b4cfaeece3e32561d08"}, {file = "watchfiles-1.0.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9f25d0ba0fe2b6d2c921cf587b2bf4c451860086534f40c384329fb96e2044d1"}, @@ -2474,6 +2608,7 @@ version = "14.2" description = "An implementation of the WebSocket Protocol (RFC 6455 & 7692)" optional = false python-versions = ">=3.9" +groups = ["main"] files = [ {file = "websockets-14.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e8179f95323b9ab1c11723e5d91a89403903f7b001828161b480a7810b334885"}, {file = "websockets-14.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0d8c3e2cdb38f31d8bd7d9d28908005f6fa9def3324edb9bf336d7e4266fd397"}, @@ -2552,6 +2687,7 @@ version = "1.17.2" description = "Module for decorators, wrappers and monkey patching." optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "wrapt-1.17.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:3d57c572081fed831ad2d26fd430d565b76aa277ed1d30ff4d40670b1c0dd984"}, {file = "wrapt-1.17.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b5e251054542ae57ac7f3fba5d10bfff615b6c2fb09abeb37d2f1463f841ae22"}, @@ -2635,6 +2771,6 @@ files = [ ] [metadata] -lock-version = "2.0" +lock-version = "2.1" python-versions = "^3.10" -content-hash = "8d70f1df8b24fbd51e128ed36fbf43c4ccfdcd3b7dbd1f0f718870cab0c4d568" +content-hash = "a67faa975147cf6652ac87a3767b499a2c0e344cb4d3f7c47d0526e81fe2bbd0" diff --git a/pyproject.toml b/pyproject.toml index 053e01d..294260e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -29,6 +29,12 @@ pandas = "^2.2.3" numpy-financial = "^1.0.0" numpy = "^2.2.3" statsmodels = "^0.14.4" +pytest-asyncio = "^1.3.0" +aiosqlite = "^0.22.1" + +[tool.pytest.ini_options] +asyncio_default_fixture_loop_scope = "function" +addopts = "-v" [build-system] diff --git a/src/__pycache__/__init__.cpython-311.pyc b/src/__pycache__/__init__.cpython-311.pyc index a55b27f4dbeabf2de4a24ecd56e5fd495264d78f..426c2483b7abe0c04ad706bbaffb96541c02573f 100644 GIT binary patch delta 48 zcmeBX>}TXz&dbZi00akfc`_&Rm`Et;XXNLm>L+IA=IbY=>gFUTC+Zg$CF@TNF$VxD Chz-X8 delta 44 ycmeBY>}KRy&dbZi00j2C)@4lOF%gk-wu(tfEsIG?)y+vxPK+roN{*QrVGaNR#0?<; diff --git a/src/__pycache__/api.cpython-311.pyc b/src/__pycache__/api.cpython-311.pyc index 7e81a85ee4cf0c43e16c93ad03996bc91e175123..dc55969c6178fe27322c40735f0f575b97b6f50a 100644 GIT binary patch delta 53 zcmaE){Y;y0IWI340}#aSx6eGnzmabTtAwn6Mt*Lpeqv^BzJ5}wZccJ?qJD8vvi{~< HtQ-OWzlRX> delta 49 zcmaE+{YaZ{IWI340}x0?cxSo@Y~%IWI340}$BnT9;wBkvEu0MB3RZCMC5jCMi`nCpkGWrno3MW^)D8Mn(WZ CwGN;F diff --git a/src/__pycache__/exceptions.cpython-311.pyc b/src/__pycache__/exceptions.cpython-311.pyc index 08447c596d0ffffda77c5f4d15555c697a806468..8b0dca67de4dd6b5c6a4e96f765a8d8115088558 100644 GIT binary patch delta 52 zcmZp7>UQE?&dbZi00ch|_GRjAf-`v35 GE(-vlW)O`4 delta 48 zcmeBnYIovY&dbZi00f2Iy_ugk^2RfZC^%ciq@f-<-g- zl#|Jgc{4lDbf(EseEgHw^4U!GNlMktNls3TDK1Km*_^_(l#}TR z(`Ig-=}ePZ_>CrC;gg)~&mX}kGI<66!pVLDos9mQZwMGNZq^mr!>Fjq=*Reh0XtbF H2DAYZ9C4QG&9pJEK|I&BoacRy^pz zo1nrV6!Fl5#6!K5D7`5Nf;Uqw2sw!bPa=Z1o}5V4x_s#cUzh|Chk}m=Q zFQCzT|Im1{2Y^l13`5!mzhA8;UvtNKfV^-YjKT>RdpX$_0a&3qh*}Y4QSru^VXtO~ z2o;yll1V-k0cZ{t+B{X!90Ui3EKzw`*xn=$cHqN1@ESiJh5$~P=d4n#WR+`Wt5U1< zA34t~NJ1E+kIXZy02ps`)QsjJ;C>Xp#>2#Yu}udn!!f8;=@I|eO#h=~gz z6{SsG*Axfq3VGw77%9`uLg$-*w{TRU5T9mcjuuCtB^Ha}68-kZGze7(=`C!yx79k* zAi@rwr_>d4V6?F=gG#a|uf=I=7%O%awNVLj0cJ!7f zZ`rVAqLbL6E&DglT8D%*-m@!s@A}fza)kusc;uG^IPnXJd;*cBnQkJx4sshH*9AFJ kl4r>=ITBR5sT1oUzX9@HkpD_n<-O#sERhfLQ<1s-0X!JE9smFU delta 793 zcmaJ;O=uHA6rR~lnv$fcY?G7*v}voxTCyQZ6l!dhw%R8B(Ssr(u&g_y-I7hhB+;s% zMZ8H+n2Qt-9wZ_yVhJ9+^(2K}wo*{`R1iEDJP4kA(;6%YK6u}L@6CMkzQ?{)zpJq~ z9UWc-L7vvl1qGpRqG*NZ5Baga7W;t5=@>n4;@r4|sF#kD!{i9*CDGNsh8v+3$owGV5KIbzN@Jvdb)X@^9LW8^h#+#b zFlA+O87rI1TGP2{j9L;Nk-K2V49G+AV+{;S$o(M4>A)?C#Gbes&{%1;QEnF0|5Kd! zM==MAD|<5{!aO95-1xJFbPnR0iw|;%fQzO>V#+&YSfrny{FAnoq#7c3r8CN**S@? zHZL4{AVn@hgPjpDDj){n$a=ZVhWVxvdE^AdGnPqUrMo(#jt_jOMyXh(i&YjE65*O9 zgwFf-9uqG2ra1w#XcTIMYOGYNQuY?HIdLXT{%TKKB~mNU5mtjz{IAL;Y_Th2jCYW4 zscCjylX|+Nc3;vCowAX#+lD-WrQ3Gj>2+men12cl@MO53`@^dGB4H1m+d}DWl(td& nE0Vt;UfZejqr90V zHpG;J2fYFBAO{mnNU8>J#k&cK@!-LD+Km1KCdNSE#G&$_jI+ORA@9+2hzW04^ z9*#dcmiaoJPH^Jx1wa+f9MMj6Ll3Jp%;#S!nR0o+XVGY?8wZd}(_a!p)0lL0V;*82W$H1AVn{%TO8=<1 zp4ms4<&Z>8D=$s_3i*pa#fQnOLM0U>rd(&qT%I;{f9t#u6-EYV%x}4;5c#=WUvX_z z*G${3H_;JG*R{Hb^*UJ#zb#j(#e%})3jHd45H-+}*0OvvGfH^@50fCgnl6Jfgp2fp zYvjGi30@|jMdtV_`7PqeIVuiB%k+HYV5Ji$q+6Z`HOp8grnpE=e-e);YY-s?kS5V+ zZSo)`gOulMzNy>DUvUi;>>6Bfy2?Ec~~RRv

X^2R4F~?Hb5x=&TQW*Y7Pl1qL`r zhj)U)&E2=%U%7R%T^wo;$!&S0U8%J*QoB@noQ@8NPdEzC0B*hmZ>Iqu(4LAz9C7ne zazEQTy>|hFkm>kAw$acW$Auo&2Emy!vOD+_j6}DI}9wjnwQA;xrxb1%FHTa z?+%{=Kjst6@u;hcVhpeUDW1Ny?9+M-|AZt8D>RpdGgj@k&)ii-()j%5f zB7g(127oC9VYoD~4?JXvTL3ozt^+_8L2M1XYY6-6_!E#p@r8d~1PFuxXzO?B2A^bS z0(eCs&EoJhY!Z#JZfFj@V{i=2S)%a2!b#93yla+b=_|-y@7_(I$^c{ma^z8QWP@E4 znHQ#GF1B$W==&+qAXp#kc0XLccnG99kZLV|Wz0kPx~U^v0C60|$Z6SLXMaVvxr%hZ zbE}PmH@hBYfP!wP-FcECYbn+wY|mNgdz;~TY=WM{mW58^2zhj)j3RXR^{b%7 delta 2586 zcmaJ?S!^3c7~WYQaeU{nox@4&G;ZpmghG#?5<=AU;A(&z57~yM&hDgj*tL^cyH$GN zfFe|JNDcE)9(X7`q*OehDt!P6p-M=ok8V||(F#$Xka&TV_Jtx*{(qdKaSChCw=@6$ z&wuRv|35$My!M>`vd`z1;Q4m>!}Q1~8v!L? z1eKuRIrS=|TB#QE3cbdtRceip5)x~d9yTIMM9gh^ol*z7D)oA!L1_>)x87((l_-&9 z>5!y(<|NHan-*-6^c4*8*d(QSe!0HTA|wJJ5nPag52N%bF~O+exeC_-Bp* z(#-#GWMTmzTTVS~=4gg(E9tSRx@lrGG1kJ*Igf(qPtIMQ7*Lo8!OI&f;xD$r)bg6S zR4%O=G=zTAi;7aozR7(KswDXFijj z&Qr^k$?JM*T&MlXO4f;cpGMe$@C<@*CkQjkp3kQ>%YnGdlG9qb(JmD4;zO0gPGPi* ze_eTX@Ohy2Ctd%o+lRW{Dx;|!)yBqWEO&lNTbY-e=tUE~e9=8pGSSPcJp;)nxn1@_ z4&cTE{9{jRLHLGi6~@}Ln!NY%gf2={QivugvPdWb2_=^mfK9UvN=dur*c`y3bg`JY#LGQFdQ(Pnygg7+eIri+nhw*nte`6%Zf*HfPUx0>c{kV_GL2@>ElC| zb0W*e)0((j;9z$J3o{e`>u)V`aszT2_BVyy3mHe1T!4RK-55pg{WlZz6>Rf}=)grl`k@|%hJ zBUbP@&5gk+FnFCz>3PZy!;_nOXIb_-+{@BtxQDa{YmBOOnUeiO zJm#%^v}c!!Py#u|Mf7 zj|;tK*sWL!p{xt2NJALq*ZgfIbt?ba|K-R==h$%+bRuX7LRT7QmJP~)g>Y6eINaBF zU~rI4qC}aY38W!t{BB^NWN2csE4W>bzXjCa90>nBdi02m!VK;X6J9KbFvZ`i9wJlx zPW7j8k=U|jAJ1lW_AW{i%WhJAVl}Dxg_;;S#jn;hinf*vmw%5+R5^_xqInx#!{I_L@+y%>GkL=-osly;K1tPF={gkGQ!nno{4Qm?$S;u<;+(~? z3GXqa^@yOy8Cfl_(;oH-FbE9uBWO&^HbTfRQd3dldm`QZRwT^tMx1;q(#8uB=i>K~ cDze>2pl&w9h2%Y?K3HeP_+NED+VNZc3v|UQ`~Uy| diff --git a/src/__pycache__/rate_limiter.cpython-311.pyc b/src/__pycache__/rate_limiter.cpython-311.pyc index d9d7738dd1592f0b3b03859790c8a44035846eee..75029b1f710337947d585bfe414201a482ed9190 100644 GIT binary patch delta 49 zcmX@jbe@TKIWI340}vd{<;kp^$h${EO+O<)H&s6|GdEv9DOEQoIXO|kxF}hF;@vy| DX9W-t delta 45 zcmX@lbef5GIWI340}$BnT9;8bk#~=XlCxDzN@`h5QmSrFa&lr!aZz&2#D{qRITa6Y diff --git a/src/acquisition_cost/schema.py b/src/acquisition_cost/schema.py index ec995a3..23dbdd8 100644 --- a/src/acquisition_cost/schema.py +++ b/src/acquisition_cost/schema.py @@ -7,14 +7,14 @@ from src.models import CommonParams, DefaultBase, Pagination class AcquisitionCostDataBase(DefaultBase): - category_no: Optional[str] = Field(None, nullable=True) - name: Optional[str] = Field(None, nullable=True) - cost_unit_3_n_4: Optional[float] = Field(None, nullable=True) - cost_unit_3: Optional[float] = Field(None, nullable=True) - created_at: Optional[datetime] = Field(None, nullable=True) - updated_at: Optional[datetime] = Field(None, nullable=True) - created_by: Optional[str] = Field(None, nullable=True) - updated_by: Optional[str] = Field(None, nullable=True) + category_no: Optional[str] = Field(None) + name: Optional[str] = Field(None) + cost_unit_3_n_4: Optional[float] = Field(None) + cost_unit_3: Optional[float] = Field(None) + created_at: Optional[datetime] = Field(None) + updated_at: Optional[datetime] = Field(None) + created_by: Optional[str] = Field(None) + updated_by: Optional[str] = Field(None) class AcquisitionCostDataCreate(AcquisitionCostDataBase): diff --git a/src/auth/__pycache__/__init__.cpython-311.pyc b/src/auth/__pycache__/__init__.cpython-311.pyc index 224f452c1b83dc15720bd262e530484613ff9cf6..e42b5d501a8fb9db5018a502a71ae35baf18f743 100644 GIT binary patch delta 53 zcmbQhIE9gCIWI340}vd{<;k4LVDVyrm; DO*;=r diff --git a/src/auth/__pycache__/model.cpython-311.pyc b/src/auth/__pycache__/model.cpython-311.pyc index e8edab19542908b0688046baa3f2f6a7d49b1d06..628300a98685d725385f12350a82f596998e1b83 100644 GIT binary patch delta 56 zcmbQtGM$BYIWI340}vd{<;l$6$ji$ptD>KgpPQk(ZZIQo-3OCMC5jCMi`nCpkGWrno3MCb6_6BWAKW G;{yP9D-cHj diff --git a/src/auth/__pycache__/service.cpython-311.pyc b/src/auth/__pycache__/service.cpython-311.pyc index 9eeaf7f6c26ad4f6e9d93d12beaf9d3ca9adc7bf..daf1c8333770a8e7bec23a46b02343c1f8d32543 100644 GIT binary patch delta 57 zcmcaB`%so|IWI340}wPzX=Fa<*vPkyNmfliBR@A)KQS{mUq2~THzzqcQNOq-SwFF~ LBtw7kT_zp??7$Ks delta 53 zcmaDTdsmikIWI340}!0KWss@Exsh)hlcbWfRZL21Sxi!@ZccJ?VoY&Sa!g`rNk+`# HhfF*Gx@r-V diff --git a/src/database/__pycache__/__init__.cpython-311.pyc b/src/database/__pycache__/__init__.cpython-311.pyc index 4badd8cf6a0fba5f59c388c289357c5970b1acde..72fb57c1819d074cdb374c36908e0aa65964ccf6 100644 GIT binary patch delta 57 zcmbQjID?UAIWI340}vd{<;k4LW1^_7pOK%Ns-Kvdo3Edgs+*IXoTy)1l&qhUSdy5O LSe&XqG1eRazX%an delta 53 zcmbQiIE9gCIWI340}$BnT9+}A$3#}$*(xR_wJatnRW~O&IWeZVC^;r2u_Q4mu{bqm HVxlDIFT=eJC`epi;*FPA%!((W9}SAMy|_jS(X}~lvtdq$+-D0(=e+FT&Jl+ncD0s~HTgTd_rHniDOemN5W1*uBzy2Ph+flq0(hsXy;8Ibf!h9XUnmFhs^7l%!5eoARhs$EgR<`6L> FW&o=#K4<^{ delta 188 zcmZ2#+-A(ToR^o20SF``yfc+VHu6ca%BneA#iXQ`#U!Qb<|HR4#uOJN$D|~dBqk*m zr^amdWOe3ZY}wq)@6X6mWK_d2xq(M~GP9rqJ8KGS4Q~qDWG_K^M%Kw$f(yl2tAIw= zuvRevNfwaY9M)h4P4>x3LP?W5h0ZaCPL2?E<%$E^o(IImeUq09Z`+(M@_|tXB({>F cNE1jEsRM~$95%W6DWy57c18J{i^YtX0a{!!<^TWy diff --git a/src/database/core.py b/src/database/core.py index 8202f9f..a0209e0 100644 --- a/src/database/core.py +++ b/src/database/core.py @@ -2,8 +2,8 @@ from starlette.requests import Request from sqlalchemy_utils import get_mapper from sqlalchemy.sql.expression import true -from sqlalchemy.orm import object_session, sessionmaker, Session -from sqlalchemy.ext.declarative import declarative_base, declared_attr +from sqlalchemy.orm import object_session, sessionmaker, Session, declarative_base +from sqlalchemy.ext.declarative import declared_attr from sqlalchemy import create_engine, inspect from pydantic import BaseModel from fastapi import Depends diff --git a/src/equipment/__pycache__/__init__.cpython-311.pyc b/src/equipment/__pycache__/__init__.cpython-311.pyc index 207a0bf16d6d0f392e7255aca446a2e7e614f11f..419a16b9eea66fb130f3e40122f6129468859461 100644 GIT binary patch delta 58 zcmbQrIFpfQIWI340}vd{<;k4LW1^&^pOK%Ns-Kvdo3Edgs+*IXoTy)1l&qgxSejXo Mo0?amKQYc60MqFb00000 delta 54 zcmbQqIF*rSIWI340}$BnT9+}A$3#xU*(xR_wJatnRW~O&IWeZVC^;szur#wEH#M&$ IW@3^#0Hl=>hX4Qo diff --git a/src/equipment/__pycache__/model.cpython-311.pyc b/src/equipment/__pycache__/model.cpython-311.pyc index 468b9f5ced71b0dad5404a3f46e006a91e93f4d8..b10150a5e8961e44f74b454b614e814b45458810 100644 GIT binary patch delta 63 zcmZn(>nEk^<|HR4>K7L!>!%i$ RW)|e8=9TDgPGyr<0suSi6IB2J delta 59 zcmeAOYzgFB&dbZi00cWfbZ0iGY~-_KlT&rJib+W=i%Ck=%}Gv9j43Wkj!7*n%`C`G N%`1u7oXIAy1OP0H6Py45 diff --git a/src/equipment/__pycache__/router.cpython-311.pyc b/src/equipment/__pycache__/router.cpython-311.pyc index 2b8e1a6a13064e710a837d06ed752cad4213bbce..28b9e73544dc9b732e4e3a80cc9fdc0dd92070f7 100644 GIT binary patch delta 65 zcmaFU$oQd=k#9LKFBbz4cyae+<{NJ0+sLJ)rJs?Xo2s9fnVYYll&YJPoSdj%T$HSz TT3DJ{keixUqQChr7rz+*n9>zl delta 61 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 delta 61 zcmZ3$IERsEIWI340}$BnT9+}A$3#`%*(xR_wJatnRW~O&IWeZVC^;szur#wEH#M&$ PJ~y$rB(*4JVx~C&F;oX6EMWC#CA2KC#31ZV={O&dbZi00h^3D>D5y@_uJl)pfRtNl7h>NlMktNls3TDK1KmNi8hREXYmG TD~ZodEG|hcirK8o63z+$ltmS} diff --git a/src/equipment_master/__pycache__/schema.cpython-311.pyc b/src/equipment_master/__pycache__/schema.cpython-311.pyc index 307c7b6285ab618f05c0d77b874448406b26c289..ef16ea4dff3f48610c94086e8953486974354d5e 100644 GIT binary patch literal 3601 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 diff --git a/src/equipment_master/__pycache__/service.cpython-311.pyc b/src/equipment_master/__pycache__/service.cpython-311.pyc index 6d7dc6c6a8b4af66bb17325233b65c0ff0606d0e..a923155c29bd3079316aae24bc38619ec7dd087d 100644 GIT binary patch delta 69 zcmaDP_Dqa-IWI340}x!|iOV$K$m`9dX{4W#pPQo&G delta 55 zcmbQmIE|5KIWI340}$BnT9+}A$3$M!*(xR_wJatnRW~O&IWeZVC^;rKvA86)C?&BZ JF=k@2IRLhc5!wI% diff --git a/src/masterdata/__pycache__/model.cpython-311.pyc b/src/masterdata/__pycache__/model.cpython-311.pyc index ae67aeb30de10edd73fa669148af84c76dc16daf..892b12a129b5f9502e020012a0ebbb13e4536700 100644 GIT binary patch delta 63 zcmdnRv5$jyIWI340}w=gGtZo{k=Kt&SxY}7KQ~oBF*7$`KPgo=CpkG$zqlw_KR2ujXtOlag8%la#8PlboCwQ(TlBlbcvvl3J9K NSdtjCxsK@oBLMXJ67&E7 diff --git a/src/masterdata/__pycache__/router.cpython-311.pyc b/src/masterdata/__pycache__/router.cpython-311.pyc index 4be777cda6f028ee92146a0172e24aa023d87c44..6f989a245658fd58b3c76e93919b01f4879a5810 100644 GIT binary patch delta 64 zcmZ2tw8DsQIWI340}vc-?98ke+{nkvrmU@>k)NBYpO~4Oub-5vo0FWJs9#)^te=}$ ST#{Opl30?czuAiIl@I`Kz7)Rz delta 60 zcmZ2sw8V&SIWI340}$-|(4EO9w2_aOO diff --git a/src/masterdata/__pycache__/schema.cpython-311.pyc b/src/masterdata/__pycache__/schema.cpython-311.pyc index 1ebe3df49bd98813b37dd5b66cf18d4357e73a21..f6c2f5a02e67f628560d24c98b898bd3cd34f945 100644 GIT binary patch delta 1840 zcmaJ7%Q6yCMR?#BP7HF2_Owp*NyQ|vN-57-Ah zt$M_u?JA_5V8?7?&_2Xow}~M#U}eWc=RF&AvC%5zpBX4Gdp`hH7-Ihfc4UZk+r^-3 zh0PO;+@OEkukbt-NtO4}9Wq(- zL#`S?I0w*ie7aVWDryLcSCO!sO*_BdJ$x5rmQuY(& z(psS)Wy@+ITkLP1Ef-dlqLlgaYt@U@2>4dD@-=vZ`mtYE;KWEX-X^>0R=U2pIitP4 zbx9|22!q7UsYE-}uI!2XV*PzB+>AEP>tq(fAhTvNa}YYH+!r5;IvH(-+tC(?IS7N~ zSfMF+^kAZEw@o__Ie;UM{_cp@cB`#w{rcutP5agzounWPk}}6GG(*kGuGkXm3!7mr zx&_T*5C(~v@l^ZPL2fU%001jPSo)4HEm7iQ-V4@{qs#`WdDVIlZq7Oh4xN+Q9Vv zq!Gmhn+)tP^z7f)-K@#L@>boWc%hz|Ulzc+?oOa*-9@nOf~rUrC8PSFo$BXmfXuQ% zT)%>V=DjhnZPKTTNKYV~M-UKL{RR9tiEz^UY6Q8y^VKO_P9sDSVh9NaYk=6f{42n5 z@0x*-=Fke;u7(So8`a4;gh9s5(Ftw6xwO5}*Z|j_)yWiuL8i>fSaZF-w7b#TK*xfR zgfK{w6_|os55#F#NMG5`H}c@nvQ8op28o#dbDQhh&F`vPRd6R1zTBzzr+4B6{di>I znq>}_3(eq#5H8|A_FB!*e@0evmR9J(4v|+2mEJflty3VYDf+D|>tq8= z(O+C2Wh_0Mn8Y5#Qk_8|L+9OzUUi1b?$72e)vsX^9z$j6r}ddbb&fhcxn7?+`i|!@ z@BhJj@iyMJ<18zZT3AWCPBqLtRyz=w8`uVK;F6iha^xHeIeN$YeQ&EA_4-Ql%rb1u zY#{8Q>`*NIWQ*s*)nZ9rUsK*v-=;tN=!dgi&d*yx%O4_pG>~EfFLt?M(7riD_NXt> K9sgehU*iR2#FK3R literal 4216 zcma)9&2JmW6`v)Sx~$Pz8ewoFPQ6R+Dy0>rfX2qH96QaP=a4@nnRD6!^_Wg<&T z*Vtt^@;~&l3lPC#FD=lMiyr7&C!g}(tmNfa<*a6Z znwj5kcHhjr_jdSgG%6CfzQ6lL`5z%d{*8@`D{x+Uag!tDYoZW^Q%Qvs2#0l_%2j*? zU&UYWv$kL5D}h3Q)p<2o2^B&Wp&+n!Kn+*Kf>?#Rj-h#>Ih43~*N%HwxSp8tHrA7~{r( z8>gW@Zd^%j6Y1(RG+W{vL6Hq=lq*#7IsC87y5R^P9UA3>s;mOb@9y5&04DsNtkb&( z3RRuJ2W6@%&==XD_vM;uAmxZ3%lqZ3j00g`-Q zkb-X)7MA)IPVqhQf8&E?h1NdR%@y%-&3i>SLF(IA_~<@TA8__GghmXjpD)mVui|j zO`{d?tN-%MA^vjb<=Z#NW1kj>rsIS0;fJzXqs3~ia#7U{&GGB>b4M&`6kJ^?%7!D> z4$fI#Uh$hEIMMbSUFH?D%MAe#m{T9>N1)DZ`KkB=-TimcwM|$ zl&jSPgGGa0ENY|3UqQHvqQHIiKsK}q>_}mUzg#sm+(8Y~iFOU)I>HTr$K(YddHLr0 z%AP_W?%ktrsil&o6(xNyL0W+okX9%=<*I!2<*E7vri$68Y zYkBKhzI`oU-#EV2SUh>lP09Pzi8)fw{}nS-(}6*nw48?=ho^UHiTxXotQECH7FLp_MGOc{xrTlBFZ;ZC;)lrWv78cn-@=iU_$N>LlD;umQPXodxIIjuyi; zVgcnv%^3ELBVhb&d66Tcc{BH0KuO05kuAz2Bjosb}aW=&p#V)2qaaidXdZlC7Oi3Mw7p*^tx!82y^ z3s5Y6!A@tvzqg;}&GeF$UTUY8FmQl}|4SCX#D?2Kq@kGUJOoV&gC>PRlfs~>4F=5B z>y6!J{xoYQ=dI*?J2?+B-Q?$?Sp2*lA3v@&cEH-WWW}X+T!LVM*PUDIR@}Mcw0m3= zatFI!;I4SC$x^wmd;4}-KHZZ1{rl0ku(#nk8p4}!>zKB^g|&I1zTp~ziXKD!(1F(r z+#b)6T{tyRzU$i;P&oFj@qvH&o$>c->Svyhxkfr6H~H&ZQn24z9-i*-O1WgXp3`Uj zPl47Dege0Se&ktSCw6qSkv%EEZbGpbLdBgB4jMioO!oZ~>Y2p(2NQ$jQz|QtudHlI zfqu(_@R*@CFCc+154Vm>)nl_TQs1m^{t@o_rfVu{hntGK(rxNKDZuK}K-c;QdrTkq z*4{fFI)So5E3o>Z{yF5~`5JBkvv=rh7Li53TSq7AnaxbL{{C^k5o<@%CZC03F@%ac zHyqV7w^!#;4Vdn^U7Rl!{}aCN{5N@EKyIdfRC$(%W?*yNVkTROowx7s0t z(D==B>^<|StiavwkU?nt{yFxZdDK;o3wOvMpb~n|JWAlW6e|0n`7SC`s63}Y8AWA3 oG=7W9C@Rk>Q07qC56u-+=1_S~31JRAY7iRIbL>4ELNRCi0mo^gO8@`> diff --git a/src/masterdata/__pycache__/service.cpython-311.pyc b/src/masterdata/__pycache__/service.cpython-311.pyc index 0f5f22e0dc22e566318f59707d115d1da5ba09f4..79d928cc1dc42ffdaa62d793eb714cd68bf315c1 100644 GIT binary patch delta 64 zcmexR@TGunIWI340}ynCMy6x_Y*<@ delta 56 zcmew$^hStxIWI340}$-|(4FbKk@ps}jEb{WOiF55Oj4?DPI7W$OmR_iOm2QkX-;Z! K%w~3$OjZCFpc5JZ diff --git a/src/modules/equipment/__pycache__/Eac.cpython-311.pyc b/src/modules/equipment/__pycache__/Eac.cpython-311.pyc index 6b8e5e2095b13574c9cf05763081b2c34c8d508e..337131275f9427471eee3f353aa109abb7b1b23b 100644 GIT binary patch delta 71 zcmZ2mwXuqCIWI340}$-cYRHUn-pJ?Aq@}N)k)NBYpO~4Oub-5vo0FWJs9#)^te=~o ZQks)mte;v~npu#WnpdK~xtVE|6#z0R7*hZM delta 67 zcmdm3wYG|HIWI340}$-|(4G0fWh0+IlbW`(RZL21Sxi!@ZccJ?VoY&Sa!hW1N@-4N VaZGAqX=XugYFua$1CUIWI340}vd{<;mQ!kvEr3(?CBXKQ~oBF*7$`KPgo=CpkG$zqlw_zaS?u XuOvPta$JOWIWI340}$BnT9V diff --git a/src/plant_masterdata/__pycache__/router.cpython-311.pyc b/src/plant_masterdata/__pycache__/router.cpython-311.pyc index 0637c71177b435478ae4891ce2d4f7abf5e70bef..cef3673d16c4a2bedf9bfe438620f58d26e5a773 100644 GIT binary patch delta 69 zcmaE^@>+#=IWI340}!}`c4qQyfFUU#E XD~ZodEG|hcN=Yn9)ZaXX^)e3t-`N)s delta 65 zcmaE@@?3>?IWI340}$-|(4ASZkvEA|RoB@nCMC5jCMi`nCpkGWrno3MrXVLVuOvP< TvA86)C?&BZF=q1&*2_Eq+%OlR diff --git a/src/plant_masterdata/__pycache__/schema.cpython-311.pyc b/src/plant_masterdata/__pycache__/schema.cpython-311.pyc index 49fa0130b7955d7d0c1cf97d604790d4a78e5e7a..af0a54a2964115715e362414552301b7207090ba 100644 GIT binary patch literal 7676 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 literal 7960 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 Mj8T6x2j6ct0Op?&wg3PC delta 71 zcmZqIYS!Xi&dbZi00h^3D>5%^|}55;gz; delta 72 zcmbQ_*yqT%oR^o20SI<}=+0a(xsflHUEA2%DkdehEG8*cHzzqcF{ZdEIi?^dF|Q=P aq$n}3I5D{-Ge0jrC9xziX7eoe9})m;l^Qw# diff --git a/src/plant_transaction_data/__pycache__/schema.cpython-311.pyc b/src/plant_transaction_data/__pycache__/schema.cpython-311.pyc index b3bdb63b8c6ec42ca7374d0c560f2f66c418dffa..37b55b8517ddb673b755f5b7a0810de5e96e13c1 100644 GIT binary patch literal 11353 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 delta 53 zcmbQiIE9gCIWI340}$BnT9+}A$3#}$*(xR_wJatnRW~O&IWeZVC^@DwHL)lqu_Q5O HVxlk!&rQ`&%*@T#PfFFzNls4GFD^>fuS`uW PN=Yn9)Zd)KQo{rQ238VF delta 57 zcmaFD`+%2sIWI340}x0?cxMJ}NlMktNls3TDK1KmsZ32QN=Yn9 LjM<#QQo{rQ&*u@U diff --git a/src/yeardata/__pycache__/router.cpython-311.pyc b/src/yeardata/__pycache__/router.cpython-311.pyc index e17ef971fef8ed51f7540dd8197989c170ec7f90..07b7983ecfe9fbd8b44398bb1126004ff20df722 100644 GIT binary patch delta 61 zcmeBInXJOQoR^o20SH_|J2N9U^187qYU*d?=cei>X6EMWC#CATfP!ozDXR4Vn_r delta 57 zcmbQN(yzk1oR^o20SI<}=+4}+k=Kn?R@K=mCMC5jCMi`nCpkGWrno3MrZP3LC?&BZ LF=lfK>wF#n2xSvo diff --git a/src/yeardata/__pycache__/schema.cpython-311.pyc b/src/yeardata/__pycache__/schema.cpython-311.pyc index f67b454b5342e3c8963f9385b66a1935c5cacdcc..15b320e826aaab1cd6c7c75e7092188cd8de0b36 100644 GIT binary patch delta 1855 zcma)5%}-)i6zAhIqI`*pB8UPlTF2o-MukzUtreV%(l)8np@K2Mdo3mk@d1g=w1uS$ z7bMpO3(`CjVo6F9CesC*ChR)Pdy}_#Ax+aiV7h8oUG-k5&d89qmvetP@BYsDox^?S zo!ehpwclwp0}`^}K>6^C{%6{hRQ9JFej^=K*5p?*iR613{8noI1gw%6nS_-yQbxht zsr6mS2}gEk?I~FW+dqE&C}H~;<$q)hz+a>m)oWUCS!Ny^=$!>qGP6z9o4YQ$r-7$3 zi{UlJ8%7IjvfH%=rSSRS$FL4IPH$J&Z9&k=FV^l_m}@X*iGu&NzJWXMa!Yl>#HS`lFGY;qb$MPe{p~9o0vShf>ArK;lLFj)*SslEBXR0S? z@e#6aW9znH-7Y*l%O{Ju^E3k6#4y+v{qHsu4W@a5LUH6zV1GjJClGj>PgZjk5=Q(4 z1_{yWtv;?VG~P!WPmnW=ongTlMqs?;=L6++1c)ETAS})=)eZG*Q;LESG#|zDQDHuc zfTeU=Rh07x5I-NqAS(J+>$%2mGlq6z$QQ@HxZsN;@D?AgvXuh_h#$uwE_xR0iaOIc zL4iHwiC|Ae@I(-pC?)w^nKVcI2nG>xYp0oev5P)^f}$sAi^E%-u*D&8zaDO|KN30O za~N>q@_NIOZ-N(k^bv!WS-i{&%Pa!ZRb|~!BNt4376VrF`s$7bXzI~c6nXctcVF=C zBQVJ;tA+{*BmO=H`=V*8DfcORlaa?$8hqg)XHPdbR>>+UYxOg%zTZ^mk>i(;(1}q|i%ejS_3{ckMz)XAREi k!mjq8Z8zJl(+;}bz+cMM<1~{yV%NCM=RfEoQb61I8*xSOTmS$7 delta 2015 zcma)7&rcgi6!xy4VH5l#G;shMgX`kZq&NX5!PW}mLP#1_O_iwY6dWsw!)ze13H5p% zC5OiDsT??1og9$DVGoE}4V7G_2Op7o;ndDZt7?VR{smRlsy+2kb;bk~ezjfCe)IOd z?|pu6X2<>|yb$qz>G2$Pu2SPo;w2&2;TmEr z(V;q#fJD@UnpdS2U{S!|3qc$d-JTuZFT^0eD!SWtIQbXxE7O7>ilGByZfuI7(*AiK z)ukTl*c4%?HY3kLWo?l%-aR?q|IG1WaJF{%4&vcHXAnPe?rIs|V%`^fycOpC$$8L9 z9L0Y-4_b+1xF0$@cdqt!TYlaaz60$t5?7C}h-@p^y?JGhvtZkfb!vOPmn}Yi3PFGS zzLBpWh(j)^)Y$GV{HKO-rHZMLCPqN7=h-Oq-m{WefUb_Q@;7EPmdM1s^^mb+@##{0-MV zZ7yfvThh>k-o+ixf}!i(T$&vXhaTqeCWi^zg;=I5F;?m28Cfe(rZSmP&3v9a``5SWN9R8 zMY84hE7GF>nU6r04GP)+%?n3Omx*dhJx9hSNH{}F;fxi|l&{QBSBeXB1Tt(;$k@r@ zx~q=X6>{TalFgH(PLsNo)Cu&M)79cKV=`N(pxd!{HC;Qm*0Vl9uHPfEDH@xyVp9Y< z7L(?sr4#{XPf?h%2L@|?)(KkAlk^N3n56@=)<9{NKxpxC)wNV2!0cHHvvy*rR;(-Q zVR)C|W@{9*k{#$?jG9n2>H@j&5eXgdPivQh}Annz+ZW6I-h+? zfY~DyM(pS*GhIDb?;+7ribhjbG}U;e+N~oI0&L4t6jHB|4(4pVPb4hUuxy3phR)Gv z9s)8O6lD9~DGd%@X;Fnf>~>$i9OFmiG>0=Bb{(KW?&A<=_a8n6uuDYdJ`N4FB!6lgQ5k>j>A)e+;OSjOG;zuRhh0kir%WHhpLtF+H57)J z!gO+1_Pdep0G#PI7XhesNKCQ|U(OVr delta 57 zcmZ22w_J{QIWI340}x#Et;l?_kvET7R?XQeCMC5jCMi`nCpkGWrno3MrZP3LC?&BZ LF=q1|=6-Gf1Zfjf diff --git a/src/yeardata/schema.py b/src/yeardata/schema.py index ee20353..039a4e7 100644 --- a/src/yeardata/schema.py +++ b/src/yeardata/schema.py @@ -7,25 +7,25 @@ from src.models import DefaultBase, Pagination class YeardataBase(DefaultBase): - year: Optional[int] = Field(None, nullable=True, ge=1900) - rp_per_kwh: Optional[float] = Field(None, nullable=True, ge=0, le=1_000_000_000_000_000) - total_lost: Optional[float] = Field(None, nullable=True, ge=0, le=1_000_000_000_000_000) - man_hour: Optional[float] = Field(None, nullable=True, ge=0, le=1_000_000_000_000_000) - asset_crit_ens_energy_not_served: Optional[float] = Field(None, nullable=True, ge=0, le=1_000_000_000_000_000) - asset_crit_bpp_system: Optional[float] = Field(None, nullable=True, ge=0, le=1_000_000_000_000_000) - asset_crit_bpp_pembangkit: Optional[float] = Field(None, nullable=True, ge=0, le=1_000_000_000_000_000) - asset_crit_dmn_daya_mampu_netto: Optional[float] = Field(None, nullable=True, ge=0, le=1_000_000_000_000_000) - asset_crit_marginal_cost: Optional[float] = Field(None, nullable=True, ge=0, le=1_000_000_000_000_000) - asset_crit_efdh_equivalent_forced_derated_hours: Optional[float] = Field(None, nullable=True, ge=0, le=1_000_000_000_000_000) - asset_crit_foh_forced_outage_hours: Optional[float] = Field(None, nullable=True, ge=0, le=1_000_000_000_000_000) - asset_crit_extra_fuel_cost: Optional[float] = Field(None, nullable=True, ge=0, le=1_000_000_000_000_000) - cf: Optional[float] = Field(None, nullable=True, ge=0, le=1_000_000_000_000_000) - eaf: Optional[float] = Field(None, nullable=True, ge=0, le=1_000_000_000_000_000) - rbd_simulation_id: Optional[str] = Field(None, nullable=True) - created_at: Optional[datetime] = Field(None, nullable=True) - updated_at: Optional[datetime] = Field(None, nullable=True) - created_by: Optional[str] = Field(None, nullable=True) - updated_by: Optional[str] = Field(None, nullable=True) + year: Optional[int] = Field(None, ge=1900) + rp_per_kwh: Optional[float] = Field(None, ge=0, le=1_000_000_000_000_000) + total_lost: Optional[float] = Field(None, ge=0, le=1_000_000_000_000_000) + man_hour: Optional[float] = Field(None, ge=0, le=1_000_000_000_000_000) + asset_crit_ens_energy_not_served: Optional[float] = Field(None, ge=0, le=1_000_000_000_000_000) + asset_crit_bpp_system: Optional[float] = Field(None, ge=0, le=1_000_000_000_000_000) + asset_crit_bpp_pembangkit: Optional[float] = Field(None, ge=0, le=1_000_000_000_000_000) + asset_crit_dmn_daya_mampu_netto: Optional[float] = Field(None, ge=0, le=1_000_000_000_000_000) + asset_crit_marginal_cost: Optional[float] = Field(None, ge=0, le=1_000_000_000_000_000) + asset_crit_efdh_equivalent_forced_derated_hours: Optional[float] = Field(None, ge=0, le=1_000_000_000_000_000) + asset_crit_foh_forced_outage_hours: Optional[float] = Field(None, ge=0, le=1_000_000_000_000_000) + asset_crit_extra_fuel_cost: Optional[float] = Field(None, ge=0, le=1_000_000_000_000_000) + cf: Optional[float] = Field(None, ge=0, le=1_000_000_000_000_000) + eaf: Optional[float] = Field(None, ge=0, le=1_000_000_000_000_000) + rbd_simulation_id: Optional[str] = Field(None) + created_at: Optional[datetime] = Field(None) + updated_at: Optional[datetime] = Field(None) + created_by: Optional[str] = Field(None) + updated_by: Optional[str] = Field(None) @field_validator( "asset_crit_ens_energy_not_served", diff --git a/tests/conftest.py b/tests/conftest.py index c6eb1a2..04fa40a 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -57,14 +57,34 @@ TestingSessionLocal = sessionmaker( autoflush=False, ) -@pytest.fixture(scope="session") -def event_loop(): +def pytest_sessionfinish(session, exitstatus): + """ + Called after whole test run finished, right before returning the exit status to the system. + Used here to dispose of all SQLAlchemy engines to prevent hanging. + """ + from src.database.core import engine as db_engine, collector_engine + + async def dispose_all(): + # Dispose of both test engine and production engines + await engine.dispose() + await db_engine.dispose() + await collector_engine.dispose() + try: - loop = asyncio.get_running_loop() - except RuntimeError: - loop = asyncio.new_event_loop() - yield loop - # loop.close() # Avoid closing if it might be shared + loop = asyncio.get_event_loop() + if loop.is_running(): + # If the loop is already running, we create a task + loop.create_task(dispose_all()) + else: + loop.run_until_complete(dispose_all()) + except Exception: + # Fallback for environment where no loop is available or loop is closed + try: + asyncio.run(dispose_all()) + except Exception: + pass + +# Removed custom event_loop fixture @pytest_asyncio.fixture(autouse=True) async def setup_db(): diff --git a/tests/unit/test_masterdata_service.py b/tests/unit/test_masterdata_service.py index b549f26..bfcf680 100644 --- a/tests/unit/test_masterdata_service.py +++ b/tests/unit/test_masterdata_service.py @@ -6,6 +6,7 @@ from src.masterdata.schema import MasterDataCreate @pytest.mark.asyncio async def test_create_masterdata_service(): mock_db = AsyncMock() + mock_db.add = MagicMock() masterdata_in = MasterDataCreate( name="Test", description="Desc", @@ -23,6 +24,7 @@ async def test_create_masterdata_service(): @pytest.mark.asyncio async def test_get_masterdata_service(): mock_db = AsyncMock() + mock_db.add = MagicMock() mock_result = MagicMock() mock_masterdata = MagicMock() mock_masterdata.id = "test-id"