diff --git a/.github/workflows/dependency-audit.yml b/.github/workflows/dependency-audit.yml new file mode 100644 index 0000000..21333e4 --- /dev/null +++ b/.github/workflows/dependency-audit.yml @@ -0,0 +1,45 @@ +name: Dependency Audit + +on: + pull_request: + paths: + - "requirements.txt" + - "requirements.lock" + push: + branches: [main] + paths: + - "requirements.txt" + - "requirements.lock" + +jobs: + audit: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install pip-audit + run: pip install pip-audit + + - name: Audit pinned dependencies + run: | + if [ -f requirements.lock ]; then + echo "Auditing requirements.lock (pinned)..." + pip-audit -r requirements.lock --desc on + else + echo "::warning::No requirements.lock found — auditing requirements.txt (unpinned)" + pip-audit -r requirements.txt --desc on + fi + + - name: Check lockfile is up to date + run: | + pip install uv + uv pip compile requirements.txt -o /tmp/requirements.lock.check + if ! diff -q requirements.lock /tmp/requirements.lock.check > /dev/null 2>&1; then + echo "::warning::requirements.lock is out of date. Run: uv pip compile requirements.txt -o requirements.lock" + fi diff --git a/pyproject.toml b/pyproject.toml index 09d7c47..ba4e6af 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "coda" -version = "0.16.1" +version = "0.16.2" description = "CoDA - Coding Agents on Databricks Apps" requires-python = ">=3.10" dependencies = [ diff --git a/requirements.lock b/requirements.lock new file mode 100644 index 0000000..1def9ed --- /dev/null +++ b/requirements.lock @@ -0,0 +1,477 @@ +# This file was autogenerated by uv via the following command: +# uv pip compile requirements.txt -o requirements.lock +aiohappyeyeballs==2.6.1 + # via aiohttp +aiohttp==3.13.3 + # via + # litellm + # mlflow +aiosignal==1.4.0 + # via aiohttp +alembic==1.18.4 + # via mlflow +annotated-doc==0.0.4 + # via + # fastapi + # typer +annotated-types==0.7.0 + # via pydantic +anyio==4.12.1 + # via + # claude-agent-sdk + # httpx + # mcp + # openai + # sse-starlette + # starlette + # watchfiles +attrs==25.4.0 + # via + # aiohttp + # jsonschema + # referencing +bidict==0.23.1 + # via python-socketio +blinker==1.9.0 + # via + # flask + # flask-socketio +boto3==1.42.66 + # via mlflow +botocore==1.42.66 + # via + # boto3 + # s3transfer +cachetools==7.0.5 + # via + # mlflow-skinny + # mlflow-tracing +certifi==2026.2.25 + # via + # httpcore + # httpx + # requests +cffi==2.0.0 + # via cryptography +charset-normalizer==3.4.5 + # via requests +claude-agent-sdk==0.1.48 + # via -r requirements.txt +click==8.3.1 + # via + # flask + # flask-socketio + # litellm + # mlflow-skinny + # typer + # uvicorn +cloudpickle==3.1.2 + # via mlflow-skinny +contourpy==1.3.3 + # via matplotlib +cryptography==46.0.5 + # via + # google-auth + # mlflow + # pyjwt +cycler==0.12.1 + # via matplotlib +databricks-sdk==0.99.0 + # via + # -r requirements.txt + # mlflow-skinny + # mlflow-tracing +deprecated==1.3.1 + # via limits +distro==1.9.0 + # via openai +docker==7.1.0 + # via mlflow +fastapi==0.135.1 + # via + # mlflow + # mlflow-skinny +fastuuid==0.14.0 + # via litellm +filelock==3.25.2 + # via huggingface-hub +flask==3.1.3 + # via + # -r requirements.txt + # flask-cors + # flask-socketio + # mlflow +flask-cors==6.0.2 + # via mlflow +flask-socketio==5.6.1 + # via -r requirements.txt +fonttools==4.62.0 + # via matplotlib +frozenlist==1.8.0 + # via + # aiohttp + # aiosignal +fsspec==2026.2.0 + # via huggingface-hub +gepa==0.1.0 + # via mlflow +gitdb==4.0.12 + # via gitpython +gitpython==3.1.46 + # via mlflow-skinny +google-auth==2.49.0 + # via databricks-sdk +googleapis-common-protos==1.73.0 + # via opentelemetry-exporter-otlp-proto-grpc +graphene==3.4.3 + # via mlflow +graphql-core==3.2.8 + # via + # graphene + # graphql-relay +graphql-relay==3.2.0 + # via graphene +grpcio==1.78.0 + # via opentelemetry-exporter-otlp-proto-grpc +gunicorn==25.1.0 + # via mlflow +h11==0.16.0 + # via + # httpcore + # uvicorn + # wsproto +hf-xet==1.4.0 + # via huggingface-hub +httpcore==1.0.9 + # via httpx +httptools==0.7.1 + # via uvicorn +httpx==0.28.1 + # via + # huggingface-hub + # litellm + # mcp + # openai +httpx-sse==0.4.3 + # via mcp +huey==2.6.0 + # via mlflow +huggingface-hub==1.6.0 + # via tokenizers +idna==3.11 + # via + # anyio + # httpx + # requests + # yarl +importlib-metadata==8.7.1 + # via + # litellm + # mlflow-skinny + # opentelemetry-api +itsdangerous==2.2.0 + # via flask +jinja2==3.1.6 + # via + # flask + # flask-socketio + # litellm +jiter==0.13.0 + # via openai +jmespath==1.1.0 + # via + # boto3 + # botocore +joblib==1.5.3 + # via scikit-learn +jsonschema==4.26.0 + # via + # litellm + # mcp +jsonschema-specifications==2025.9.1 + # via jsonschema +kiwisolver==1.5.0 + # via matplotlib +limits==5.8.0 + # via slowapi +litellm==1.82.1 + # via mlflow +mako==1.3.10 + # via alembic +markdown-it-py==4.0.0 + # via rich +markupsafe==3.0.3 + # via + # flask + # jinja2 + # mako + # werkzeug +matplotlib==3.10.8 + # via mlflow +mcp==1.26.0 + # via claude-agent-sdk +mdurl==0.1.2 + # via markdown-it-py +mlflow==3.10.1 + # via -r requirements.txt +mlflow-skinny==3.10.1 + # via mlflow +mlflow-tracing==3.10.1 + # via mlflow +multidict==6.7.1 + # via + # aiohttp + # yarl +numpy==2.4.3 + # via + # contourpy + # matplotlib + # mlflow + # pandas + # scikit-learn + # scipy + # skops +openai==2.26.0 + # via litellm +opentelemetry-api==1.40.0 + # via + # mlflow-skinny + # mlflow-tracing + # opentelemetry-exporter-otlp-proto-grpc + # opentelemetry-sdk + # opentelemetry-semantic-conventions +opentelemetry-exporter-otlp-proto-common==1.40.0 + # via opentelemetry-exporter-otlp-proto-grpc +opentelemetry-exporter-otlp-proto-grpc==1.40.0 + # via -r requirements.txt +opentelemetry-proto==1.40.0 + # via + # mlflow-skinny + # mlflow-tracing + # opentelemetry-exporter-otlp-proto-common + # opentelemetry-exporter-otlp-proto-grpc +opentelemetry-sdk==1.40.0 + # via + # mlflow-skinny + # mlflow-tracing + # opentelemetry-exporter-otlp-proto-grpc +opentelemetry-semantic-conventions==0.61b0 + # via opentelemetry-sdk +packaging==26.0 + # via + # gunicorn + # huggingface-hub + # limits + # matplotlib + # mlflow-skinny + # mlflow-tracing + # skops +pandas==2.3.3 + # via mlflow +pillow==12.1.1 + # via matplotlib +prettytable==3.17.0 + # via skops +propcache==0.4.1 + # via + # aiohttp + # yarl +protobuf==6.33.5 + # via + # databricks-sdk + # googleapis-common-protos + # mlflow-skinny + # mlflow-tracing + # opentelemetry-proto +pyarrow==23.0.1 + # via mlflow +pyasn1==0.6.2 + # via + # pyasn1-modules + # rsa +pyasn1-modules==0.4.2 + # via google-auth +pycparser==3.0 + # via cffi +pydantic==2.12.5 + # via + # fastapi + # litellm + # mcp + # mlflow-skinny + # mlflow-tracing + # openai + # pydantic-settings +pydantic-core==2.41.5 + # via pydantic +pydantic-settings==2.13.1 + # via mcp +pygments==2.19.2 + # via rich +pyjwt==2.11.0 + # via mcp +pyparsing==3.3.2 + # via matplotlib +python-dateutil==2.9.0.post0 + # via + # botocore + # graphene + # matplotlib + # pandas +python-dotenv==1.2.2 + # via + # litellm + # mlflow-skinny + # pydantic-settings + # uvicorn +python-engineio==4.13.1 + # via python-socketio +python-multipart==0.0.22 + # via mcp +python-socketio==5.16.1 + # via flask-socketio +pytz==2026.1.post1 + # via pandas +pyyaml==6.0.3 + # via + # huggingface-hub + # mlflow-skinny + # uvicorn +referencing==0.37.0 + # via + # jsonschema + # jsonschema-specifications +regex==2026.2.28 + # via tiktoken +requests==2.32.5 + # via + # databricks-sdk + # docker + # mlflow-skinny + # tiktoken +rich==14.3.3 + # via typer +rpds-py==0.30.0 + # via + # jsonschema + # referencing +rsa==4.9.1 + # via google-auth +s3transfer==0.16.0 + # via boto3 +scikit-learn==1.8.0 + # via + # mlflow + # skops +scipy==1.17.1 + # via + # mlflow + # scikit-learn + # skops +shellingham==1.5.4 + # via typer +simple-websocket==1.1.0 + # via + # -r requirements.txt + # python-engineio +six==1.17.0 + # via python-dateutil +skops==0.13.0 + # via mlflow +slowapi==0.1.9 + # via mlflow +smmap==5.0.3 + # via gitdb +sniffio==1.3.1 + # via openai +sqlalchemy==2.0.48 + # via + # alembic + # mlflow +sqlparse==0.5.5 + # via mlflow-skinny +sse-starlette==3.3.2 + # via mcp +starlette==0.52.1 + # via + # fastapi + # mcp + # sse-starlette +threadpoolctl==3.6.0 + # via scikit-learn +tiktoken==0.12.0 + # via + # litellm + # mlflow +tokenizers==0.22.2 + # via litellm +tqdm==4.67.3 + # via + # huggingface-hub + # openai +typer==0.24.1 + # via huggingface-hub +typing-extensions==4.15.0 + # via + # aiosignal + # alembic + # anyio + # fastapi + # graphene + # grpcio + # huggingface-hub + # limits + # mcp + # mlflow-skinny + # openai + # opentelemetry-api + # opentelemetry-exporter-otlp-proto-grpc + # opentelemetry-sdk + # opentelemetry-semantic-conventions + # pydantic + # pydantic-core + # referencing + # sqlalchemy + # starlette + # typing-inspection +typing-inspection==0.4.2 + # via + # fastapi + # mcp + # pydantic + # pydantic-settings +tzdata==2025.3 + # via pandas +urllib3==2.6.3 + # via + # botocore + # docker + # requests +uvicorn==0.41.0 + # via + # mcp + # mlflow + # mlflow-skinny +uvloop==0.22.1 + # via uvicorn +watchfiles==1.1.1 + # via + # mlflow + # uvicorn +wcwidth==0.6.0 + # via prettytable +websockets==16.0 + # via uvicorn +werkzeug==3.1.6 + # via + # flask + # flask-cors + # flask-socketio +wrapt==2.1.2 + # via deprecated +wsproto==1.3.2 + # via simple-websocket +yarl==1.23.0 + # via aiohttp +zipp==3.23.0 + # via importlib-metadata