Skip to content

Consolidate SDK and CLI into unified vastai package#345

Merged
vastzuby merged 27 commits intomasterfrom
combined-cli-sdk
Apr 9, 2026
Merged

Consolidate SDK and CLI into unified vastai package#345
vastzuby merged 27 commits intomasterfrom
combined-cli-sdk

Conversation

@vastzuby
Copy link
Copy Markdown
Contributor

@vastzuby vastzuby commented Mar 25, 2026

replaces the monolithic vast.py with a modular vastai/ package.
one pip package for both the cli and sdk.
everything is backwards and forwards compatible.

splits vast.py into its own modules:

  • cli commands
  • api layer
  • sdk
  • async/sync clients
  • data models

also adds:

  • vastai_sdk/ for a backward-compat shim so existing imports still work
  • sdk-wrapper/ for publishing vastai-sdk to pypi
  • full test suite (401 tests), workflow will run on PRs
  • new deployments feature, 2fa stuff
  • two-job ci workflow (publishes vastai + vastai-sdk to pypi)

vast.py is still there as a deprecated shim for backwards compatibility

Replace the monolithic vast.py with a modular package structure:
- vastai/cli/ — CLI entry point, parser, and per-domain command modules
- vastai/api/ — HTTP client and per-domain API functions
- vastai/sdk.py — VastAI class wrapping all API functions
- vastai/serverless/ — serverless client and server (unchanged)
- vastai/utils.py — shared utilities

Also adds:
- vastai_sdk/ backward-compat shim (import vastai_sdk still works)
- sdk-wrapper/ for publishing vastai-sdk PyPI package
- Full test suite (401 tests)
- Docker support, benchmarks, examples, docs
- Two-job CI workflow (publishes vastai + vastai-sdk to PyPI)
- PR test workflow with change detection

Code sourced from vast-sdk combined-cli-sdk branch.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@vastzuby vastzuby requested a review from stackanthony as a code owner March 25, 2026 19:06
Comment thread docs/vast-sdk-testing-infra-architecture.md Outdated
@sammy-vastai
Copy link
Copy Markdown
Contributor

 Code Review: combined-cli-sdk branch                                                                                                        
                                                                                                                                              
  Overview                                                                                                                                    
                                                                                                                                              
  This is a major restructuring that consolidates the Vast.ai CLI and SDK into a unified vastai package. It adds ~44k lines of new Python     
  across 191 files in 13 commits. Key changes:                                                                                                
                                                                                                                                              
  - Reorganizes flat vast.py monolith into a proper vastai/ package (api, cli, data, serverless, sync, async_ modules)                        
  - Adds a new VastAI SDK class (vastai/sdk.py) wrapping all API operations                                                                   
  - Adds a serverless client/server framework (vastai/serverless/)                                                                            
  - Adds a vastai-sdk PyPI wrapper package (sdk-wrapper/) for backward compat                                                                 
  - Adds a serve-vast-deployment CLI entry point                                                                                              
  - Keeps vast.py and vast_config.py as deprecated shims                                                                                      
  - New CI workflow for PR-scoped test runs                                                                                                   
  - Publishes two packages from the same repo (vastai + vastai-sdk)                                                                           
                                                                                                                                              
  Strengths                                                                                                                                   
                                                                                                                                              
  - Excellent test coverage: 60 test files covering CLI, API, SDK, serverless, data objects, and more (~18k+ lines of tests)                  
  - Backward compatibility preserved: vast.py, vast_config.py, and vastai_sdk import shim all maintained                                      
  - Clean package structure: Well-organized module hierarchy with clear separation of concerns                                                
  - CI improvements: Smart path-based change detection (dorny/paths-filter) to run only relevant tests                                        
  - Graceful degradation: vastai/__init__.py catches ImportError for optional serverless deps                                                 
                                                                                                                                              
  Concerns                                                                                                                                    
                                                                                                                                              
  High Risk                                                                                                                                   
                                                                                                                                              
  1. Massive dependency footprint expansion — New deps include fastapi, uvicorn, aiohttp, nltk, transformers, psutil, pycryptodome, pillow,   
  etc. These are all required (not optional), meaning a simple pip install vastai for CLI-only use now pulls in PyTorch/transformers/NLTK.    
  This will significantly increase install time and size. Consider making serverless deps optional extras (e.g., pip install                  
  vastai[serverless]).                                                                                                                        
  2. Entry point change — vastai = "vast:main" → vastai = "vastai.cli.main:main". Existing installations will work after upgrade, but the old 
  vast.py:main still exists — verify there's no import conflict.                                                                              
  3. requires-python loosened — Changed from ">3.9.1, <4.0" to ">=3.9", which now includes 3.9.0 and removes the Python 4 upper bound. Minor, 
  but intentional?                                                                                                                            
                                                                                                                                              
  Medium Risk                                                                                                                                 
                                                                                                                                              
  4. __import__('sys') in CLI code — Found an inline __import__('sys').stderr usage. Should just be a normal import.                          
  5. Subprocess calls — ~20 subprocess invocations added, mostly in PDF generation, tests, and deployment scripts. The PDF/doc generation ones
   use list args (good), but worth a quick audit of the deployment subprocess.run(["sh", "-c", entry]) path for injection if entry comes from 
  user input.                                                                                                                                 
  6. Bare except: in main.py:113 — except: without specifying an exception type will catch SystemExit, KeyboardInterrupt, etc.                
  7. poetry.lock grew by ~4k lines — Expected given the new deps, but the lockfile should be regenerated clean to ensure consistency.         
                                                                                                                                              
  Low Risk                                                                                                                                    
                                                                                                                                              
  8. Trailing whitespace/EOF issues — ~25 files have trailing whitespace or missing final newlines (flagged by git diff --check). Cosmetic but
   sloppy.                                                                                                                                    
  9. Deleted files are all safe — TODO.md, __init__.py (root), mypy.ini, utils/pypi_api.py, vast.ai-logo.xcf — none critical.                 
  10. No hardcoded secrets — All api_key= values in the diff are test fixtures with dummy values like "k", "mykey123".                        
  11. eval() calls — Only model.eval() (PyTorch), not eval(string). Safe.                                                                     
                                                                                                                                              
  Recommendations                                                                                                                             
                                                                                                                                              
  1. Strongly consider optional extras for serverless/ML deps — this is the biggest usability concern                                         
  2. Fix the bare except: in vastai/cli/main.py:113                                                                                           
  3. Clean up trailing whitespace (a pre-commit hook would handle this)                                                                       
  4. Replace __import__('sys') with a normal import                                                                                           
  5. Audit subprocess.run(["sh", "-c", entry]) for shell injection                                                                            
                                                                                                                                              
  Verdict                                                                                                                                     
                                                                                                                                              
  Conditionally safe to merge, with the dependency bloat being the main practical concern. The code is well-structured, well-tested, and      
  backward compatible. The biggest risk isn't correctness — it's that every CLI user now installs transformers and fastapi. If that's         
  acceptable for your user base, this is ready. If not, split deps into extras first.                                                         
                                                                                                                                             

@sammy-vastai
Copy link
Copy Markdown
Contributor

This is a CLI, why are we trying to install the transformers and uvicorn packages?

# Dependency Audit: `combined-cli-sdk` branch

## Summary

`poetry install --dry-run` shows **83 packages** installed for what is primarily a CLI tool. Several heavy dependencies are either unused entirely or only needed by the optional serverless subsystem.

## Unused Dependencies (safe to remove)

These are declared as required in `pyproject.toml` but **nothing in `vastai/` imports them**:

| Dependency | Where it's referenced | Transitive bloat |
|---|---|---|
| `transformers~=4.52` | 0 imports in `vastai/`, only 2 example files | `tokenizers`, `safetensors`, `huggingface-hub`, `numpy`, `regex`, `filelock`, `fsspec`, `tqdm` |
| `nltk~=3.9` | 0 imports in `vastai/`, only 2 example files | `joblib`, `regex`, `tqdm` |
| `hf_transfer>=0.1.9` | 0 imports anywhere in the repo | `hf-xet` |
| `fastapi>=0.110,<1.0` | 0 imports anywhere in the repo | `pydantic`, `pydantic-core`, `starlette`, `typing-inspection`, `annotated-types` |
| `uvicorn[standard]>=0.24,<0.32` | 0 imports anywhere in the repo | `httptools`, `uvloop`, `watchfiles`, `websockets`, `python-dotenv` |

**Action:** Remove all five from `[project] dependencies`.

## Serverless-Only Dependencies (should be optional extras)

These are imported exclusively within `vastai/serverless/` and `vastai/async_/`. The package already handles their absence gracefully — `vastai/__init__.py` wraps serverless imports in `try/except ImportError`.

| Dependency | Used by |
|---|---|
| `aiohttp>=3.9.1` | `serverless/client/`, `serverless/server/`, `async_/client.py` |
| `aiodns>=3.6.0` | aiohttp DNS resolution |
| `pycares==4.11.0` | aiodns backend |
| `aiofiles>=23.0` | `serverless/` file handling |
| `anyio~=4.4` | `serverless/` async primitives |
| `psutil~=6.0` | `serverless/server/lib/data_types.py` |
| `pycryptodome~=3.20` | `serverless/server/lib/backend.py` (RSA signature verification) |

**Action:** Move to `[project.optional-dependencies]` as a `serverless` extra.

## Recommended `pyproject.toml` Changes

### Remove from `[project] dependencies`:

transformers~=4.52
nltk~=3.9
hf_transfer>=0.1.9
fastapi>=0.110,<1.0
uvicorn[standard]>=0.24,<0.32


### Add optional extras:
```toml
[project.optional-dependencies]
serverless = [
  "aiohttp>=3.9.1",
  "aiodns>=3.6.0",
  "pycares==4.11.0",
  "aiofiles>=23.0",
  "anyio~=4.4",
  "psutil~=6.0",
  "pycryptodome~=3.20",
]

Install commands after change:

pip install vastai              # CLI + SDK only (~30-35 packages)
pip install vastai[serverless]  # CLI + SDK + serverless (~50 packages)

Impact

Before After (estimated)
Packages installed 83 ~30-35 (CLI only)
Heavy ML deps Yes (transformers, numpy, tokenizers) No
Serverless available by default Yes Opt-in via [serverless] extra
Backward compat N/A vastai/__init__.py already handles missing serverless deps

Copy link
Copy Markdown
Contributor

@sammy-vastai sammy-vastai left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dependency bloat

@vastzuby
Copy link
Copy Markdown
Contributor Author

vastzuby commented Apr 8, 2026

@sammy-vastai

  1. removed unused dependencies
  2. no import conflict, this is intended
  3. reverted this, good catch
  4. fixed
  5. i didnt touch this code, worth investigating in future PR though
  6. fixed
  7. regenerated the poetry.lock without unused deps

@vastzuby
Copy link
Copy Markdown
Contributor Author

vastzuby commented Apr 8, 2026

@sammy-vastai mixed feelings for making serverless optional

on one hand, lighter install for cli users (20 less packages)
but then users cant just pip install vastai and use serverless, they'll have to pip install vastai[serverless] too

@LucasArmandVast thoughts?

@sammy-vastai
Copy link
Copy Markdown
Contributor

sammy-vastai commented Apr 8, 2026

I'm ok either way, but just as a CC FYI

Here’s your cleaned up and well-formatted version (tightened wording, consistent tables, clearer structure):


Serverless Dependency Impact

The serverless dependencies add 21 extra packages on top of the CLI-only baseline:

┌──────────────────────────┬──────────┐
│ Install Type             │ Packages │
├──────────────────────────┼──────────┤
│ CLI-only (no serverless) │ 20       │
│ Full install (current)   │ 41       │
│ Added by serverless      │ 21       │
└──────────────────────────┴──────────┘

The 6 direct serverless dependencies:

  • aiohttp
  • aiodns
  • pycares
  • anyio
  • psutil
  • pycryptodome

These pull in 15 additional transitive dependencies (e.g., multidict, yarl, frozenlist, aiosignal, attrs, etc.).

👉 Net effect: ~2× increase in total package count

If serverless were optional (pip install vastai[serverless]), CLI-only users would install roughly half as many packages.


Maintenance & CLI Utility

┌──────────────┬──────────────────────────────┬──────────────┬─────────────────────────────────────────────┬────────────────────────────────────────────┐
│ Package      │ Maintained?                  │ Last Release │ Usage                                       │ CLI Utility                                │
├──────────────┼──────────────────────────────┼──────────────┼─────────────────────────────────────────────┼────────────────────────────────────────────┤
│ aiohttp      │ Yes (very active)            │ 2026-03-31   │ Serverless + async client                   │ Possible (async CLI future)                │
│ aiodns       │ Yes                          │ 2026-01-10   │ aiohttp DNS (transitive)                   │ No                                         │
│ pycares      │ Yes                          │ 2026-01-01   │ aiodns backend (transitive)                │ No                                         │
│ anyio        │ Yes (very active)            │ 2026-03-24   │ backend.py (file I/O)                      │ Minimal                                    │
│ psutil       │ Yes                          │ 2026-01-28   │ system metrics                             │ Possible                                   │
│ pycryptodome │ ⚠️ Slower updates (~11 mo)   │ 2025-05-17   │ RSA (serverless backend)                   │ No (overlaps with cryptography)            │
└──────────────┴──────────────────────────────┴──────────────┴─────────────────────────────────────────────┴────────────────────────────────────────────┘

Key takeaways:

  • aiohttp → only dependency with clear future CLI potential
  • pycryptodome → redundant with cryptography (worth consolidating)
  • aiodns / pycares → purely transitive, no standalone value
  • anyio / psutil → niche usage, not justified for all users

👉 Overall: These dependencies are well-maintained, but strongly belong in optional extras, not the core CLI install.


Package Size Impact

Individual sizes aren’t large, but they accumulate:

┌──────────────────┬──────────────┐
│ Package          │ Installed    │
├──────────────────┼──────────────┤
│ aiohttp          │ 7.6 MB       │
│ pycares          │ 2.0 MB       │
│ psutil           │ 2.3 MB       │
│ anyio            │ 1.3 MB       │
│ multidict        │ 1.0 MB       │
│ frozenlist       │ 0.8 MB       │
│ propcache        │ 0.8 MB       │
│ yarl             │ 0.5 MB       │
│ pycryptodome     │ 0.1 MB       │
│ aiodns           │ 0.1 MB       │
│ others           │ ~0.3 MB      │
├──────────────────┼──────────────┤
│ Total (serverless deps) │ 16.7 MB │
└──────────────────┴──────────────┘

Overall install size impact:

┌─────────────────┬──────────┐
│ Install Type    │ Size     │
├─────────────────┼──────────┤
│ CLI-only        │ 64.9 MB  │
│ Full install    │ 188.3 MB │
│ Serverless adds │ ~123 MB  │
└─────────────────┴──────────┘

Bottom Line

  • Doubles dependency count
  • Adds ~123 MB to install size
  • Little to no immediate CLI benefit
  • Includes at least one redundant crypto library

👉 Strong recommendation:
Make serverless dependencies optional (extras_require) and keep the CLI lean.

@LucasArmandVast
Copy link
Copy Markdown
Contributor

LucasArmandVast commented Apr 8, 2026

This was originally all going into the vast_sdk repo, but we changed it to this repo since its more popular. This changes this repo from vast-cli into a generic public vastai monorepo. So, I would actually argue that the optional selection should go the other way around, that vast-cli becomes a subset of vastai, and can be optionally installed via vastai[cli] in standalone. pip install vastai gives you the whole toolkit.

@LucasArmandVast
Copy link
Copy Markdown
Contributor

I think it would be a bad user experience if you pip install vastai, and then in python do import vastai and it says "Module not found".

The serverless packages aren't just for serverless, they are also for the new generic vast async client, which also uses aiohttp and its dependencies.

@vastzuby vastzuby merged commit 4d0cc7a into master Apr 9, 2026
3 checks passed
@vastzuby vastzuby deleted the combined-cli-sdk branch April 10, 2026 21:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants