diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml index 14b519c2d..bc8750839 100644 --- a/.github/workflows/python.yml +++ b/.github/workflows/python.yml @@ -44,13 +44,13 @@ jobs: - name: Install uv uses: astral-sh/setup-uv@v6 - + - name: Install style dependencies run: uv sync --locked --only-group style - + - name: Run format style check run: uv run --directory . ruff format --check --config ./pyproject.toml . - + - name: Run isort style check run: uv run --directory . isort --check . @@ -82,3 +82,50 @@ jobs: - name: Check coverage run: | uv run diff-cover coverage.xml --fail-under=90 + + build-pex: + name: Build on ${{ matrix.os }} + runs-on: ${{ matrix.os }} + defaults: + run: + working-directory: ./python + strategy: + fail-fast: false + matrix: + os: [windows-latest] + + steps: + - uses: actions/checkout@v5 + with: + fetch-depth: 0 + + - name: Install uv + uses: astral-sh/setup-uv@v6 + with: + python-version: '3.12' + + - name: Build PEX for macOS / Linux + if: ${{ matrix.os != 'windows-latest' }} + run: | + uvx pex dist/*.whl \ + -e valuecell.server.main:main \ + -o dist/valuecell-${{ runner.os }}-${{ runner.arch }} \ + --scie eager \ + --scie-pbs-stripped + + - name: Build EXE for Windows + if: ${{ matrix.os == 'windows-latest' }} + shell: pwsh + run: | + Get-Command python + Get-Command uv + Get-Command uvx + uvx pip wheel https://files.pythonhosted.org/packages/04/89/76f6f1b744c8608e0d416b588b9d63c2a500ff800065ae610f7c80f532d6/peewee-3.18.2.tar.gz -w .\dist + ls .\dist + + + - name: Upload Artifact + uses: actions/upload-artifact@v4 + with: + name: binary-${{ matrix.os }} + path: ./python/dist/*.whl diff --git a/python/pyproject.toml b/python/pyproject.toml index bdd3137d1..5f78554ac 100644 --- a/python/pyproject.toml +++ b/python/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "valuecell" -version = "0.1.0" +version = "0.1.4" description = "ValueCell is a community-driven, multi-agent platform for financial applications." readme = "README.md" requires-python = ">=3.12" @@ -16,7 +16,6 @@ dependencies = [ "pydantic>=2.0.0", "uvicorn>=0.24.0", "a2a-sdk[http-server]>=0.3.4", - "yfinance>=0.2.65", "requests>=2.32.5", "akshare>=1.17.44", "agno[openai, google, lancedb]>=2.0,<3.0", @@ -44,7 +43,11 @@ dev = [ dev = [ {include-group = "lint"}, {include-group = "style"}, - {include-group = "test"} + {include-group = "test"}, + {include-group = "dist"}, +] +dist = [ + "pex>=2.71.1", ] lint = [ "ruff" diff --git a/python/uv.lock b/python/uv.lock index cec923e0d..b215a800b 100644 --- a/python/uv.lock +++ b/python/uv.lock @@ -679,27 +679,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/3e/7c/15ad426257615f9be8caf7f97990cf3dcbb5b8dd7ed7e0db581a1c4759dd/cryptography-46.0.2-cp38-abi3-win_arm64.whl", hash = "sha256:91447f2b17e83c9e0c89f133119d83f94ce6e0fb55dd47da0a959316e6e9cfa1", size = 2918153, upload-time = "2025-10-01T00:28:51.003Z" }, ] -[[package]] -name = "curl-cffi" -version = "0.13.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "certifi" }, - { name = "cffi" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/4e/3d/f39ca1f8fdf14408888e7c25e15eed63eac5f47926e206fb93300d28378c/curl_cffi-0.13.0.tar.gz", hash = "sha256:62ecd90a382bd5023750e3606e0aa7cb1a3a8ba41c14270b8e5e149ebf72c5ca", size = 151303, upload-time = "2025-08-06T13:05:42.988Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/19/d1/acabfd460f1de26cad882e5ef344d9adde1507034528cb6f5698a2e6a2f1/curl_cffi-0.13.0-cp39-abi3-macosx_10_9_x86_64.whl", hash = "sha256:434cadbe8df2f08b2fc2c16dff2779fb40b984af99c06aa700af898e185bb9db", size = 5686337, upload-time = "2025-08-06T13:05:28.985Z" }, - { url = "https://files.pythonhosted.org/packages/2c/1c/cdb4fb2d16a0e9de068e0e5bc02094e105ce58a687ff30b4c6f88e25a057/curl_cffi-0.13.0-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:59afa877a9ae09efa04646a7d068eeea48915a95d9add0a29854e7781679fcd7", size = 2994613, upload-time = "2025-08-06T13:05:31.027Z" }, - { url = "https://files.pythonhosted.org/packages/04/3e/fdf617c1ec18c3038b77065d484d7517bb30f8fb8847224eb1f601a4e8bc/curl_cffi-0.13.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d06ed389e45a7ca97b17c275dbedd3d6524560270e675c720e93a2018a766076", size = 7931353, upload-time = "2025-08-06T13:05:32.273Z" }, - { url = "https://files.pythonhosted.org/packages/3d/10/6f30c05d251cf03ddc2b9fd19880f3cab8c193255e733444a2df03b18944/curl_cffi-0.13.0-cp39-abi3-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b4e0de45ab3b7a835c72bd53640c2347415111b43421b5c7a1a0b18deae2e541", size = 7486378, upload-time = "2025-08-06T13:05:33.672Z" }, - { url = "https://files.pythonhosted.org/packages/77/81/5bdb7dd0d669a817397b2e92193559bf66c3807f5848a48ad10cf02bf6c7/curl_cffi-0.13.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8eb4083371bbb94e9470d782de235fb5268bf43520de020c9e5e6be8f395443f", size = 8328585, upload-time = "2025-08-06T13:05:35.28Z" }, - { url = "https://files.pythonhosted.org/packages/ce/c1/df5c6b4cfad41c08442e0f727e449f4fb5a05f8aa564d1acac29062e9e8e/curl_cffi-0.13.0-cp39-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:28911b526e8cd4aa0e5e38401bfe6887e8093907272f1f67ca22e6beb2933a51", size = 8739831, upload-time = "2025-08-06T13:05:37.078Z" }, - { url = "https://files.pythonhosted.org/packages/1a/91/6dd1910a212f2e8eafe57877bcf97748eb24849e1511a266687546066b8a/curl_cffi-0.13.0-cp39-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:6d433ffcb455ab01dd0d7bde47109083aa38b59863aa183d29c668ae4c96bf8e", size = 8711908, upload-time = "2025-08-06T13:05:38.741Z" }, - { url = "https://files.pythonhosted.org/packages/6d/e4/15a253f9b4bf8d008c31e176c162d2704a7e0c5e24d35942f759df107b68/curl_cffi-0.13.0-cp39-abi3-win_amd64.whl", hash = "sha256:66a6b75ce971de9af64f1b6812e275f60b88880577bac47ef1fa19694fa21cd3", size = 1614510, upload-time = "2025-08-06T13:05:40.451Z" }, - { url = "https://files.pythonhosted.org/packages/f9/0f/9c5275f17ad6ff5be70edb8e0120fdc184a658c9577ca426d4230f654beb/curl_cffi-0.13.0-cp39-abi3-win_arm64.whl", hash = "sha256:d438a3b45244e874794bc4081dc1e356d2bb926dcc7021e5a8fef2e2105ef1d8", size = 1365753, upload-time = "2025-08-06T13:05:41.879Z" }, -] - [[package]] name = "dataclasses-json" version = "0.6.7" @@ -894,17 +873,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/18/79/1b8fa1bb3568781e84c9200f951c735f3f157429f44be0495da55894d620/filetype-1.2.0-py2.py3-none-any.whl", hash = "sha256:7ce71b6880181241cf7ac8697a2f1eb6a8bd9b429f7ad6d27b8db9ba5f1c2d25", size = 19970, upload-time = "2022-11-02T17:34:01.425Z" }, ] -[[package]] -name = "frozendict" -version = "2.4.6" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/bb/59/19eb300ba28e7547538bdf603f1c6c34793240a90e1a7b61b65d8517e35e/frozendict-2.4.6.tar.gz", hash = "sha256:df7cd16470fbd26fc4969a208efadc46319334eb97def1ddf48919b351192b8e", size = 316416, upload-time = "2024-10-13T12:15:32.449Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/04/13/d9839089b900fa7b479cce495d62110cddc4bd5630a04d8469916c0e79c5/frozendict-2.4.6-py311-none-any.whl", hash = "sha256:d065db6a44db2e2375c23eac816f1a022feb2fa98cbb50df44a9e83700accbea", size = 16148, upload-time = "2024-10-13T12:15:26.839Z" }, - { url = "https://files.pythonhosted.org/packages/ba/d0/d482c39cee2ab2978a892558cf130681d4574ea208e162da8958b31e9250/frozendict-2.4.6-py312-none-any.whl", hash = "sha256:49344abe90fb75f0f9fdefe6d4ef6d4894e640fadab71f11009d52ad97f370b9", size = 16146, upload-time = "2024-10-13T12:15:28.16Z" }, - { url = "https://files.pythonhosted.org/packages/a5/8e/b6bf6a0de482d7d7d7a2aaac8fdc4a4d0bb24a809f5ddd422aa7060eb3d2/frozendict-2.4.6-py313-none-any.whl", hash = "sha256:7134a2bb95d4a16556bb5f2b9736dceb6ea848fa5b6f3f6c2d6dba93b44b4757", size = 16146, upload-time = "2024-10-13T12:15:29.495Z" }, -] - [[package]] name = "frozenlist" version = "1.7.0" @@ -1799,12 +1767,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/fd/69/b547032297c7e63ba2af494edba695d781af8a0c6e89e4d06cf848b21d80/multidict-6.6.4-py3-none-any.whl", hash = "sha256:27d8f8e125c07cb954e54d75d04905a9bba8a439c1d84aca94949d4d03d8601c", size = 12313, upload-time = "2025-08-11T12:08:46.891Z" }, ] -[[package]] -name = "multitasking" -version = "0.0.12" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/17/0d/74f0293dfd7dcc3837746d0138cbedd60b31701ecc75caec7d3f281feba0/multitasking-0.0.12.tar.gz", hash = "sha256:2fba2fa8ed8c4b85e227c5dd7dc41c7d658de3b6f247927316175a57349b84d1", size = 19984, upload-time = "2025-07-20T21:27:51.636Z" } - [[package]] name = "mypy-extensions" version = "1.1.0" @@ -2062,10 +2024,13 @@ wheels = [ ] [[package]] -name = "peewee" -version = "3.18.2" +name = "pex" +version = "2.71.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/04/89/76f6f1b744c8608e0d416b588b9d63c2a500ff800065ae610f7c80f532d6/peewee-3.18.2.tar.gz", hash = "sha256:77a54263eb61aff2ea72f63d2eeb91b140c25c1884148e28e4c0f7c4f64996a0", size = 949220, upload-time = "2025-07-08T12:52:03.941Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a0/6f/200a3388616c304001adbad4cadc33af1e331a9e685963e6a3ef766f0402/pex-2.71.1.tar.gz", hash = "sha256:400ed53417e513fddbb71b94667e07ebb3ecc8fbc172d095a9b2ba817d4b4771", size = 5216265, upload-time = "2025-11-25T22:53:27.394Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b2/8b/84949719ca9816c67b328e0310516aaa115997fb9049a466e4c8add8c5a5/pex-2.71.1-py2.py3-none-any.whl", hash = "sha256:a88ad2bcabed6c096eae2c1acd2a400ee58fd6c42c324953f6d55f559c6ab0ba", size = 3935129, upload-time = "2025-11-25T22:53:24.784Z" }, +] [[package]] name = "pillow" @@ -2136,15 +2101,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/c1/70/6b41bdcddf541b437bbb9f47f94d2db5d9ddef6c37ccab8c9107743748a4/pillow-12.0.0-cp314-cp314t-win_arm64.whl", hash = "sha256:99353a06902c2e43b43e8ff74ee65a7d90307d82370604746738a1e0661ccca7", size = 2525630, upload-time = "2025-10-15T18:23:57.149Z" }, ] -[[package]] -name = "platformdirs" -version = "4.4.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/23/e8/21db9c9987b0e728855bd57bff6984f67952bea55d6f75e055c46b5383e8/platformdirs-4.4.0.tar.gz", hash = "sha256:ca753cf4d81dc309bc67b0ea38fd15dc97bc30ce419a7f58d13eb3bf14c4febf", size = 21634, upload-time = "2025-08-26T14:32:04.268Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/40/4b/2028861e724d3bd36227adfa20d3fd24c3fc6d52032f4a93c133be5d17ce/platformdirs-4.4.0-py3-none-any.whl", hash = "sha256:abd01743f24e5287cd7a5db3752faf1a2d65353f38ec26d98e25a6db65958c85", size = 18654, upload-time = "2025-08-26T14:32:02.735Z" }, -] - [[package]] name = "playwright" version = "1.55.0" @@ -3619,7 +3575,7 @@ wheels = [ [[package]] name = "valuecell" -version = "0.1.0" +version = "0.1.4" source = { editable = "." } dependencies = [ { name = "a2a-sdk", extra = ["http-server"] }, @@ -3641,7 +3597,6 @@ dependencies = [ { name = "sqlalchemy" }, { name = "unstructured" }, { name = "uvicorn" }, - { name = "yfinance" }, ] [package.optional-dependencies] @@ -3657,11 +3612,15 @@ dev = [ dev = [ { name = "diff-cover" }, { name = "isort" }, + { name = "pex" }, { name = "pytest" }, { name = "pytest-asyncio" }, { name = "pytest-cov" }, { name = "ruff" }, ] +dist = [ + { name = "pex" }, +] lint = [ { name = "ruff" }, ] @@ -3702,7 +3661,6 @@ requires-dist = [ { name = "sqlalchemy", specifier = ">=2.0.43" }, { name = "unstructured", specifier = ">=0.18.15" }, { name = "uvicorn", specifier = ">=0.24.0" }, - { name = "yfinance", specifier = ">=0.2.65" }, ] provides-extras = ["dev"] @@ -3710,11 +3668,13 @@ provides-extras = ["dev"] dev = [ { name = "diff-cover", specifier = ">=9.0.0" }, { name = "isort" }, + { name = "pex", specifier = ">=2.71.1" }, { name = "pytest", specifier = ">=7.4.0" }, { name = "pytest-asyncio", specifier = ">=1.0.0" }, { name = "pytest-cov", specifier = ">=4.1.0" }, { name = "ruff" }, ] +dist = [{ name = "pex", specifier = ">=2.71.1" }] lint = [{ name = "ruff" }] style = [ { name = "isort" }, @@ -3982,29 +3942,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/b4/2d/2345fce04cfd4bee161bf1e7d9cdc702e3e16109021035dbb24db654a622/yarl-1.20.1-py3-none-any.whl", hash = "sha256:83b8eb083fe4683c6115795d9fc1cfaf2cbbefb19b3a1cb68f6527460f483a77", size = 46542, upload-time = "2025-06-10T00:46:07.521Z" }, ] -[[package]] -name = "yfinance" -version = "0.2.65" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "beautifulsoup4" }, - { name = "curl-cffi" }, - { name = "frozendict" }, - { name = "multitasking" }, - { name = "numpy" }, - { name = "pandas" }, - { name = "peewee" }, - { name = "platformdirs" }, - { name = "protobuf" }, - { name = "pytz" }, - { name = "requests" }, - { name = "websockets" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/a3/c1/2ef5acda45a71297f4be22e205359e0f93b0171f2b6ebdd681362e725686/yfinance-0.2.65.tar.gz", hash = "sha256:3d465e58c49be9d61f9862829de3e00bef6b623809f32f4efb5197b62fc60485", size = 128666, upload-time = "2025-07-06T16:20:12.769Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/c9/1e/631c80e0f97aef46eb73549b9b0f60d94057294e040740f4cad0cb1f48e4/yfinance-0.2.65-py2.py3-none-any.whl", hash = "sha256:7be13abb0d80a17230bf798e9c6a324fa2bef0846684a6d4f7fa2abd21938963", size = 119438, upload-time = "2025-07-06T16:20:11.251Z" }, -] - [[package]] name = "zipp" version = "3.23.0"