Skip to content

Commit c1adb7f

Browse files
authored
Merge branch 'main' into feat/change-default-urls-to-serverless
2 parents 914266f + 861e1b4 commit c1adb7f

91 files changed

Lines changed: 12783 additions & 976 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/publish.yml

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,20 @@ name: Publish WorkFlow
22

33
on:
44
release:
5-
types: [created]
5+
types: [published]
66

77
jobs:
88
build:
99
runs-on: ubuntu-latest
10-
strategy:
11-
matrix:
12-
python-version: [3.8]
1310
steps:
1411
- name: 🛎️ Checkout
1512
uses: actions/checkout@v4
1613
with:
1714
ref: ${{ github.head_ref }}
18-
- name: 🐍 Set up Python ${{ matrix.python-version }}
15+
- name: 🐍 Set up Python
1916
uses: actions/setup-python@v5
2017
with:
21-
python-version: ${{ matrix.python-version }}
18+
python-version: '3.10'
2219
- name: 🦾 Install dependencies
2320
run: |
2421
python -m pip install --upgrade pip
@@ -31,6 +28,29 @@ jobs:
3128
run: |
3229
make publish -e PYPI_USERNAME=$PYPI_USERNAME -e PYPI_PASSWORD=$PYPI_PASSWORD -e PYPI_TEST_PASSWORD=$PYPI_TEST_PASSWORD
3330
31+
build-slim:
32+
needs: build
33+
runs-on: ubuntu-latest
34+
steps:
35+
- name: 🛎️ Checkout
36+
uses: actions/checkout@v4
37+
with:
38+
ref: ${{ github.head_ref }}
39+
- name: 🐍 Set up Python
40+
uses: actions/setup-python@v5
41+
with:
42+
python-version: '3.10'
43+
- name: 🦾 Install dependencies
44+
run: |
45+
python -m pip install --upgrade pip
46+
pip install ".[dev]"
47+
- name: 🚀 Publish roboflow-slim to PyPi
48+
env:
49+
PYPI_USERNAME: ${{ secrets.PYPI_USERNAME }}
50+
PYPI_PASSWORD: ${{ secrets.PYPI_PASSWORD }}
51+
run: |
52+
make publish-slim -e PYPI_USERNAME=$PYPI_USERNAME -e PYPI_PASSWORD=$PYPI_PASSWORD
53+
3454
deploy-docs:
3555
needs: build
3656
runs-on: ubuntu-latest
@@ -45,7 +65,7 @@ jobs:
4565
- name: 🐍 Set up Python
4666
uses: actions/setup-python@v5
4767
with:
48-
python-version: '3.8'
68+
python-version: '3.10'
4969

5070
- name: 📚 Install MkDocs and dependencies
5171
run: |

.github/workflows/test.yml

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,15 @@ on:
66
pull_request:
77
branches: [main]
88

9+
permissions:
10+
contents: read
11+
912
jobs:
1013
build:
1114
strategy:
1215
matrix:
1316
os: ["ubuntu-latest", "windows-latest"]
14-
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]
17+
python-version: ["3.10", "3.11", "3.12", "3.13"]
1518
runs-on: ${{ matrix.os }}
1619
env:
1720
PYTHONUTF8: 1
@@ -35,3 +38,24 @@ jobs:
3538
make check_code_quality
3639
- name: 🧪 Run tests
3740
run: "python -m unittest"
41+
42+
test-slim:
43+
runs-on: ubuntu-latest
44+
steps:
45+
- name: 🛎️ Checkout
46+
uses: actions/checkout@v4
47+
with:
48+
ref: ${{ github.event.pull_request.head.ref }}
49+
repository: ${{ github.event.pull_request.head.repo.full_name }}
50+
- name: 🐍 Set up Python 3.10
51+
uses: actions/setup-python@v5
52+
with:
53+
python-version: '3.10'
54+
- name: 🦾 Install slim dependencies
55+
run: |
56+
python -m pip install --upgrade pip
57+
pip install -r requirements-slim.txt
58+
pip install -e . --no-deps
59+
pip install responses
60+
- name: 🧪 Run slim-compatible tests
61+
run: "python -m unittest tests.test_slim_compat tests.test_vision_events"

.pre-commit-config.yaml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ ci:
66

77
repos:
88
- repo: https://github.com/pre-commit/pre-commit-hooks
9-
rev: v5.0.0
9+
rev: v6.0.0
1010
hooks:
1111
- id: check-added-large-files
1212
- id: check-case-conflict
@@ -24,14 +24,14 @@ repos:
2424
- id: trailing-whitespace
2525

2626
- repo: https://github.com/PyCQA/bandit
27-
rev: 1.8.3
27+
rev: 1.9.3
2828
hooks:
2929
- id: bandit
3030
args: ["-c", "pyproject.toml"]
3131
additional_dependencies: ["bandit[toml]"]
3232

3333
- repo: https://github.com/astral-sh/ruff-pre-commit
34-
rev: v0.11.12
34+
rev: v0.15.2
3535
hooks:
3636
- id: ruff-format
3737
- id: ruff

CLAUDE.md

Lines changed: 37 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -84,28 +84,54 @@ The Roboflow Python SDK follows a hierarchical object model that mirrors the Rob
8484
- **rfapi** (`roboflow/adapters/rfapi.py`) - Low-level API communication
8585
- **deploymentapi** (`roboflow/adapters/deploymentapi.py`) - Model deployment operations
8686

87-
### CLI Interface
88-
89-
The `roboflow` command line tool (`roboflow/roboflowpy.py`) provides:
90-
- Authentication: `roboflow login`
91-
- Dataset operations: `roboflow download`, `roboflow upload`, `roboflow import`
92-
- Inference: `roboflow infer`
93-
- Project/workspace management: `roboflow project`, `roboflow workspace`
87+
### CLI Package (`roboflow/cli/`)
88+
89+
The CLI is built on [typer](https://typer.tiangolo.com/) (which uses Click under the hood). `roboflow/roboflowpy.py` is a backwards-compatibility shim that delegates to `roboflow.cli.main`.
90+
91+
**Package structure:**
92+
- `__init__.py` — Root `typer.Typer()` app with global `@app.callback()` for `--json`, `--workspace`, `--api-key`, `--quiet`. Explicitly registers all handler apps via `app.add_typer()`.
93+
- `_output.py``output(args, data, text)` for JSON/text output, `output_error(args, msg, hint, exit_code)` for structured errors, `suppress_sdk_output()` to silence SDK noise, `stub()` for unimplemented commands
94+
- `_compat.py``ctx_to_args(ctx, **kwargs)` bridge that converts `typer.Context` to the `SimpleNamespace` that output helpers expect
95+
- `_table.py``format_table(rows, columns)` for columnar list output
96+
- `_resolver.py``resolve_resource(shorthand)` for parsing `project`, `ws/project`, `ws/project/3`
97+
- `handlers/` — One file per command group, each exporting a `typer.Typer()` app. `_aliases.py` registers backwards-compat top-level commands via `register_aliases(app)`.
98+
99+
**Adding a new command:**
100+
1. Create `roboflow/cli/handlers/mycommand.py`
101+
2. Create a module-level `mycommand_app = typer.Typer(help="...", no_args_is_help=True)`
102+
3. Add commands with `@mycommand_app.command("verb")` decorators
103+
4. Each command takes `ctx: typer.Context` + typed params, calls `ctx_to_args(ctx, **params)` to create args namespace
104+
5. Use `output()` for all output, `output_error()` for all errors
105+
6. Wrap SDK calls in `with suppress_sdk_output():` to prevent "loading..." noise
106+
7. Register in `roboflow/cli/__init__.py`: `app.add_typer(mycommand_app, name="mycommand")`
107+
8. Add tests using `typer.testing.CliRunner` in `tests/cli/test_mycommand_handler.py`
108+
109+
**Agent experience requirements for all CLI commands:**
110+
- Support `--json` for structured output (stable schema)
111+
- No interactive prompts when all required flags are provided
112+
- Structured error output: `{"error": {"message": "...", "hint": "..."}}` on stderr
113+
- Exit codes: 0 = success, 1 = error, 2 = auth error, 3 = not found
114+
- Actionable error messages: always tell the user what went wrong AND what to do
115+
116+
**Documentation policy:** `CLI-COMMANDS.md` in this repo is a quickstart only. The full command reference lives in `roboflow-product-docs` (published to docs.roboflow.com). When adding commands, update both.
94117

95118
### Key Design Patterns
96119

97120
1. **Hierarchical Access**: Always access objects through their parent (Workspace → Project → Version → Model)
98121
2. **API Key Flow**: API key is passed down through the object hierarchy
99122
3. **Format Flexibility**: Supports multiple dataset formats (YOLO, COCO, Pascal VOC, etc.)
100123
4. **Batch Operations**: Upload and download operations support concurrent processing
124+
5. **CLI Noun-Verb Pattern**: Commands follow `roboflow <noun> <verb>` (e.g. `roboflow project list`). Common operations have top-level aliases (`login`, `upload`, `download`)
125+
6. **CLI Explicit Registration**: Handler apps are explicitly imported and registered via `app.add_typer()` in `__init__.py` — clear dependency chain, no runtime discovery
126+
7. **Backwards Compatibility**: Legacy command names and flag signatures are preserved as hidden aliases
101127

102128
## Project Configuration
103129

104-
- **Python Version**: 3.8+
105-
- **Main Dependencies**: See `requirements.txt`
106-
- **Entry Point**: `roboflow=roboflow.roboflowpy:main`
130+
- **Python Version**: 3.10+
131+
- **Main Dependencies**: See `requirements.txt` (includes `typer>=0.12.0`)
132+
- **Entry Point**: `roboflow=roboflow.roboflowpy:main` (shim delegates to `roboflow.cli.main`)
107133
- **Code Style**: Enforced by ruff with Google docstring convention
108-
- **Type Checking**: mypy configured for Python 3.8
134+
- **Type Checking**: mypy configured for Python 3.10
109135

110136
## Important Notes
111137

0 commit comments

Comments
 (0)