@ondeinference / cli / commits / b78a230

Publish to pypi

Seto Elkahfi committed Apr 21, 2026 at 18:13 UTC b78a23059562630171553391d58465547a21a697
6 files changed +339
.github/workflows/release-pypi.yml new
+195
@@ -0,0 +1,195 @@
1 +name: PyPI Release
2 +
3 +on:
4 + push:
5 + tags:
6 + - "v*.*.*"
7 + workflow_dispatch:
8 + inputs:
9 + tag:
10 + description: "Release tag (e.g. v0.1.1)"
11 + required: true
12 +
13 +permissions:
14 + id-token: write
15 + contents: read
16 +
17 +env:
18 + CARGO_TERM_COLOR: always
19 +
20 +jobs:
21 + build-wheels:
22 + name: Build PyPI wheels
23 + runs-on: ${{ matrix.build.OS }}
24 + strategy:
25 + fail-fast: false
26 + matrix:
27 + build:
28 + - {
29 + NAME: linux-x64-glibc,
30 + OS: ubuntu-latest,
31 + TARGET: x86_64-unknown-linux-gnu,
32 + MANYLINUX: "2014",
33 + }
34 + - {
35 + NAME: linux-arm64-glibc,
36 + OS: ubuntu-24.04-arm,
37 + TARGET: aarch64-unknown-linux-gnu,
38 + MANYLINUX: "2014",
39 + }
40 + - {
41 + NAME: win32-x64-msvc,
42 + OS: windows-2022,
43 + TARGET: x86_64-pc-windows-msvc,
44 + }
45 + - {
46 + NAME: win32-arm64-msvc,
47 + OS: windows-2022,
48 + TARGET: aarch64-pc-windows-msvc,
49 + }
50 + - {
51 + NAME: darwin-x64,
52 + OS: macos-latest,
53 + TARGET: x86_64-apple-darwin,
54 + }
55 + - {
56 + NAME: darwin-arm64,
57 + OS: macos-latest,
58 + TARGET: aarch64-apple-darwin,
59 + }
60 + steps:
61 + - name: Checkout
62 + uses: actions/checkout@v4
63 + with:
64 + ref: ${{ github.event.inputs.tag || github.ref }}
65 +
66 + - name: Set the release version
67 + shell: bash
68 + run: |
69 + if [[ "${GITHUB_REF_TYPE}" == "tag" ]]; then
70 + release_version="${GITHUB_REF_NAME#v}"
71 + else
72 + release_version="${{ github.event.inputs.tag }}"
73 + release_version="${release_version#v}"
74 + fi
75 + echo "RELEASE_VERSION=${release_version}" >> "$GITHUB_ENV"
76 +
77 + - name: Read Rust toolchain
78 + shell: bash
79 + run: |
80 + rust_toolchain="$(sed -n 's/^channel = "\(.*\)"/\1/p' rust-toolchain.toml | head -n 1)"
81 + if [ -z "$rust_toolchain" ]; then
82 + echo "Failed to read Rust toolchain from rust-toolchain.toml" >&2
83 + exit 1
84 + fi
85 + echo "RUST_TOOLCHAIN=${rust_toolchain}" >> "$GITHUB_ENV"
86 +
87 + - name: Install Rust toolchain
88 + uses: dtolnay/rust-toolchain@3c5f7ea28cd621ae0bf5283f0e981fb97b8a7af9
89 + with:
90 + toolchain: ${{ env.RUST_TOOLCHAIN }}
91 +
92 + - name: Install Rust target
93 + shell: bash
94 + run: |
95 + rustup target add ${{ matrix.build.TARGET }} --toolchain ${{ env.RUST_TOOLCHAIN }}
96 + rustup target list --installed
97 +
98 + - name: Build wheel
99 + uses: PyO3/maturin-action@v1
100 + with:
101 + target: ${{ matrix.build.TARGET }}
102 + manylinux: ${{ matrix.build.MANYLINUX || 'off' }}
103 + working-directory: pypi
104 + args: --release --locked --compatibility pypi --out dist
105 + before-script-linux: yum install -y perl-core
106 +
107 + - name: Upload wheel artifact
108 + uses: actions/upload-artifact@v4
109 + with:
110 + name: wheels-${{ matrix.build.NAME }}
111 + path: pypi/dist/*
112 +
113 + build-sdist:
114 + name: Build source distribution
115 + runs-on: ubuntu-latest
116 + steps:
117 + - name: Checkout
118 + uses: actions/checkout@v4
119 + with:
120 + ref: ${{ github.event.inputs.tag || github.ref }}
121 +
122 + - name: Read Rust toolchain
123 + shell: bash
124 + run: |
125 + rust_toolchain="$(sed -n 's/^channel = "\(.*\)"/\1/p' rust-toolchain.toml | head -n 1)"
126 + if [ -z "$rust_toolchain" ]; then
127 + echo "Failed to read Rust toolchain from rust-toolchain.toml" >&2
128 + exit 1
129 + fi
130 + echo "RUST_TOOLCHAIN=${rust_toolchain}" >> "$GITHUB_ENV"
131 +
132 + - name: Install Rust toolchain
133 + uses: dtolnay/rust-toolchain@3c5f7ea28cd621ae0bf5283f0e981fb97b8a7af9
134 + with:
135 + toolchain: ${{ env.RUST_TOOLCHAIN }}
136 +
137 + - name: Build sdist
138 + uses: PyO3/maturin-action@v1
139 + with:
140 + command: sdist
141 + working-directory: pypi
142 + args: --out dist
143 +
144 + - name: Upload sdist artifact
145 + uses: actions/upload-artifact@v4
146 + with:
147 + name: sdist
148 + path: pypi/dist/*
149 +
150 + publish-pypi:
151 + name: Publish to PyPI
152 + runs-on: ubuntu-latest
153 + needs:
154 + - build-wheels
155 + - build-sdist
156 + steps:
157 + - name: Checkout
158 + uses: actions/checkout@v4
159 + with:
160 + ref: ${{ github.event.inputs.tag || github.ref }}
161 +
162 + - name: Set the release version
163 + shell: bash
164 + run: |
165 + if [[ "${GITHUB_REF_TYPE}" == "tag" ]]; then
166 + release_version="${GITHUB_REF_NAME#v}"
167 + else
168 + release_version="${{ github.event.inputs.tag }}"
169 + release_version="${release_version#v}"
170 + fi
171 + echo "RELEASE_VERSION=${release_version}" >> "$GITHUB_ENV"
172 +
173 + - name: Download distribution artifacts
174 + uses: actions/download-artifact@v4
175 + with:
176 + pattern: "*"
177 + path: dist
178 + merge-multiple: true
179 +
180 + - name: Check whether release already exists on PyPI
181 + id: pypi-check
182 + shell: bash
183 + run: |
184 + if curl -fsS "https://pypi.org/pypi/onde-cli/${RELEASE_VERSION}/json" >/dev/null 2>&1; then
185 + echo "onde-cli ${RELEASE_VERSION} already exists on PyPI, skipping publish"
186 + echo "exists=true" >> "$GITHUB_OUTPUT"
187 + else
188 + echo "exists=false" >> "$GITHUB_OUTPUT"
189 + fi
190 +
191 + - name: Publish distribution
192 + if: steps.pypi-check.outputs.exists != 'true'
193 + uses: pypa/gh-action-pypi-publish@release/v1
194 + with:
195 + skip-existing: true
.gitignore
+1
@@ -1 +1,2 @@
1 /target
2 +/pypi/dist
Cargo.lock
+1
@@ -1774,6 +1774,7 @@ dependencies = [
1774 name = "smbcloud-gresiq-sdk"
1775 version = "0.3.34"
1776 dependencies = [
1777 + "anyhow",
1778 "log",
1779 "reqwest",
1780 "serde",
pypi/README.md new
+101
@@ -0,0 +1,101 @@
1 +<p align="center">
2 + <img src="https://raw.githubusercontent.com/ondeinference/onde/main/assets/onde-inference-logo.svg" alt="Onde Inference" width="96">
3 +</p>
4 +
5 +<h1 align="center">onde-cli</h1>
6 +
7 +<p align="center">
8 + <strong>Terminal UI for <a href="https://ondeinference.com">Onde Inference</a> — sign up, sign in, and manage your account from the command line.</strong>
9 +</p>
10 +
11 +<p align="center">
12 + <a href="https://ondeinference.com"><img src="https://img.shields.io/badge/ondeinference.com-235843?style=flat-square&labelColor=17211D" alt="Website"></a>
13 + <a href="https://pypi.org/project/onde-cli/"><img src="https://img.shields.io/pypi/v/onde-cli?style=flat-square&labelColor=17211D&color=235843" alt="PyPI"></a>
14 + <a href="https://crates.io/crates/onde-cli"><img src="https://img.shields.io/crates/v/onde-cli?style=flat-square&labelColor=17211D&color=235843" alt="Crates.io"></a>
15 + <a href="https://github.com/ondeinference/onde-cli/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-MIT%20%2F%20Apache--2.0-235843?style=flat-square&labelColor=17211D" alt="License"></a>
16 +</p>
17 +
18 +---
19 +
20 +## Install
21 +
22 +```sh
23 +pip install onde-cli
24 +```
25 +
26 +This installs the native `onde` executable for your platform directly — no compiler, no runtime dependencies, no Node.js.
27 +
28 +## Usage
29 +
30 +```sh
31 +onde
32 +```
33 +
34 +Opens a terminal UI. Create an account or sign in to your Onde Inference account.
35 +
36 +## Keys
37 +
38 +| Key | Action |
39 +|----------|-----------------------|
40 +| `Tab` | Move between fields |
41 +| `Enter` | Submit / sign out |
42 +| `Ctrl+L` | Go to sign in |
43 +| `Ctrl+N` | Go to new account |
44 +| `Ctrl+C` | Quit |
45 +
46 +## Other Installation Methods
47 +
48 +### Cargo
49 +
50 +```sh
51 +cargo install onde-cli
52 +```
53 +
54 +### From source
55 +
56 +```sh
57 +git clone https://github.com/ondeinference/onde-cli
58 +cd onde-cli
59 +cargo build --release
60 +./target/release/onde
61 +```
62 +
63 +## Platform Support
64 +
65 +Pre-built native binaries are shipped for:
66 +
67 +| Platform | Architecture |
68 +|---------------|---------------|
69 +| macOS | arm64, x64 |
70 +| Linux (glibc) | arm64, x64 |
71 +| Windows | arm64, x64 |
72 +
73 +## Debug
74 +
75 +Logs are written to `~/.cache/onde/debug.log`. Nothing is written to the terminal output.
76 +
77 +## Related
78 +
79 +- [Swift SDK](https://github.com/ondeinference/onde-swift)
80 +- [Flutter SDK](https://pub.dev/packages/onde_inference)
81 +- [React Native SDK](https://www.npmjs.com/package/@ondeinference/react-native)
82 +- [Onde Rust crate](https://crates.io/crates/onde)
83 +
84 +## Source & Issues
85 +
86 +This is a native binary distributed via PyPI. The source code lives at
87 +[github.com/ondeinference/onde-cli](https://github.com/ondeinference/onde-cli).
88 +Please report bugs and feature requests there.
89 +
90 +## License
91 +
92 +Dual-licensed under **MIT** and **Apache 2.0**.
93 +
94 +- [MIT License](https://github.com/ondeinference/onde-cli/blob/main/LICENSE-MIT)
95 +- [Apache License 2.0](https://github.com/ondeinference/onde-cli/blob/main/LICENSE-APACHE)
96 +
97 +---
98 +
99 +<p align="center">
100 + <sub>© 2026 <a href="https://ondeinference.com">Onde Inference</a></sub>
101 +</p>
\ No newline at end of file
pypi/pyproject.toml new
+39
@@ -0,0 +1,39 @@
1 +[build-system]
2 +requires = ["maturin>=1.7,<2.0"]
3 +build-backend = "maturin"
4 +
5 +[project]
6 +name = "onde-cli"
7 +description = "Terminal UI for signing up, signing in, and managing your Onde Inference account."
8 +readme = "README.md"
9 +requires-python = ">=3.8"
10 +dynamic = ["version"]
11 +license = { text = "MIT OR Apache-2.0" }
12 +authors = [{ name = "Seto Elkahfi", email = "hej@setoelkahfi.se" }]
13 +keywords = ["onde", "cli", "tui", "inference", "llm", "on-device"]
14 +classifiers = [
15 + "Development Status :: 4 - Beta",
16 + "Environment :: Console",
17 + "Intended Audience :: Developers",
18 + "License :: OSI Approved :: MIT License",
19 + "License :: OSI Approved :: Apache Software License",
20 + "Operating System :: MacOS",
21 + "Operating System :: Microsoft :: Windows",
22 + "Operating System :: POSIX :: Linux",
23 + "Programming Language :: Python :: 3",
24 + "Programming Language :: Rust",
25 + "Topic :: Scientific/Engineering :: Artificial Intelligence",
26 + "Topic :: Software Development :: Libraries",
27 + "Topic :: Utilities",
28 +]
29 +
30 +[project.urls]
31 +Homepage = "https://ondeinference.com"
32 +Documentation = "https://ondeinference.com"
33 +Repository = "https://github.com/ondeinference/onde-cli"
34 +Issues = "https://github.com/ondeinference/onde-cli/issues"
35 +
36 +[tool.maturin]
37 +manifest-path = "../Cargo.toml"
38 +bindings = "bin"
39 +strip = true
rust-toolchain.toml new
+2
@@ -0,0 +1,2 @@
1 +[toolchain]
2 +channel = "stable"