The portfolio data, risk and mean-CVaR optimisation service, prepared for students who run it on their own DGX Spark without root, Docker or Tailscale. - deploy/apptainer/qc.sh: install, start/stop/status/logs, cli/api/python, data import/export and Yahoo setup/update. cuOpt and quantcore run as two Apptainer instances of the user and talk over 127.0.0.1; the API and the test bench listen on 127.0.0.1 only. Builds quantcore.sif without root, or falls back to a plain Python image plus a virtualenv when the Spark allows no unprivileged builds. Detects taken ports and suggests free ones. - deploy/apptainer/quantcore.def + constraints.txt: the image, with the library versions of the verified production container pinned. - cuOpt under Apptainer: NVIDIA's image sets HOME=/opt/cuopt, read-only in a SIF, so the solver died on its first job; qc.sh gives it a writable home. - solvers: a cuOpt that disappears during a solve now falls back to HiGHS instead of answering 500 (requests' ConnectionError escaped the fallback). - client: idempotent GETs retry a dropped keep-alive connection, which made `quantcore-api update --wait` fail when a poll met uvicorn's 5 s timeout. - config: cuOpt defaults to http://127.0.0.1:5000 and `quantcore serve` to 127.0.0.1; the Docker images keep passing their own values. - docs/SPARK_APPTAINER.md: the students' guide; README, USAGE, ARCHITECTURE and SPARK_DEPLOYMENT point to it. Tested on a DGX Spark (GB10, Apptainer 1.5.4, unprivileged user) in both modes: selftest on every endpoint, optimisation on cuOpt, Yahoo update, port conflicts; 139 tests pass in the container against the live cuOpt. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
49 lines
1.2 KiB
Plaintext
49 lines
1.2 KiB
Plaintext
# Library versions of the quantcore image, taken from the container that runs on the lecturer's Spark
|
|
# (Python 3.12.14, aarch64, 2026-10-07). deploy/apptainer/quantcore.def installs with `pip install -c`,
|
|
# so a student's build in December gets the same SciPy/HiGHS, pandas and numpy as the verified one.
|
|
# To move to newer libraries: delete the pins, build, run the tests, and freeze again:
|
|
# apptainer exec quantcore.sif pip freeze --exclude quantcore
|
|
annotated-doc==0.0.5
|
|
annotated-types==0.8.0
|
|
anyio==4.15.1
|
|
beautifulsoup4==4.15.0
|
|
certifi==2026.7.22
|
|
cffi==2.1.1
|
|
charset-normalizer==3.5.1
|
|
click==8.5.0
|
|
curl_cffi==0.16.3
|
|
fastapi==0.141.1
|
|
h11==0.16.0
|
|
httptools==0.8.0
|
|
idna==3.20
|
|
lxml==6.1.3
|
|
msgpack==1.2.2
|
|
multitasking==0.0.13
|
|
numpy==2.5.3
|
|
pandas==3.0.6
|
|
peewee==4.5.1
|
|
platformdirs==4.11.12
|
|
protobuf==7.36.2
|
|
pyarrow==25.0.1
|
|
pycparser==3.0
|
|
pydantic==2.13.5
|
|
pydantic-settings==2.15.0
|
|
pydantic_core==2.46.5
|
|
python-dateutil==2.9.0.post0
|
|
python-dotenv==1.2.3
|
|
pytz==2026.3.post1
|
|
PyYAML==6.0.3
|
|
requests==2.34.2
|
|
scipy==1.18.1
|
|
six==1.17.0
|
|
soupsieve==2.9.2
|
|
starlette==1.7.0
|
|
typing-inspection==0.4.4
|
|
typing_extensions==4.16.0
|
|
urllib3==2.8.0
|
|
uvicorn==0.53.0
|
|
uvloop==0.22.1
|
|
watchfiles==1.3.0
|
|
websockets==17.1
|
|
yfinance==1.7.0
|