Metadata-Version: 2.5
Name: visynx
Version: 0.3.1
Summary: Visynx Python SDK: run your Visynx computer vision models (object detection, segmentation, pose, classification) hosted or on your own hardware, including NVIDIA Jetson.
Project-URL: Homepage, https://visynx.com
Project-URL: Documentation, https://docs.visynx.com/
Project-URL: Changelog, https://docs.visynx.com/changelog/
Author: Visynx
License: MIT License
        
        Copyright (c) 2026 Visynx
        
        Permission is hereby granted, free of charge, to any person obtaining a copy
        of this software and associated documentation files (the "Software"), to deal
        in the Software without restriction, including without limitation the rights
        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        copies of the Software, and to permit persons to whom the Software is
        furnished to do so, subject to the following conditions:
        
        The above copyright notice and this permission notice shall be included in all
        copies or substantial portions of the Software.
        
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
        SOFTWARE.
License-File: LICENSE
Keywords: api client,computer vision,computer-vision,image classification,inference,jetson,machine-learning,object-detection,onnx,pose estimation,sdk,segmentation,tensorrt,visynx
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Classifier: Topic :: Scientific/Engineering :: Image Recognition
Classifier: Typing :: Typed
Requires-Python: >=3.9
Requires-Dist: pillow>=9.0
Requires-Dist: requests>=2.25
Provides-Extra: dev
Requires-Dist: numpy>=1.21; extra == 'dev'
Requires-Dist: pytest>=7; extra == 'dev'
Requires-Dist: ruff>=0.5; extra == 'dev'
Provides-Extra: docs
Requires-Dist: mkdocs-material>=9.5; extra == 'docs'
Requires-Dist: mkdocstrings[python]>=0.26; extra == 'docs'
Provides-Extra: local
Requires-Dist: numpy>=1.21; extra == 'local'
Requires-Dist: onnxruntime>=1.15; extra == 'local'
Description-Content-Type: text/markdown

# Visynx

[![PyPI version](https://img.shields.io/pypi/v/visynx)](https://pypi.org/project/visynx/)
[![Python versions](https://img.shields.io/pypi/pyversions/visynx)](https://pypi.org/project/visynx/)
[![License: MIT](https://img.shields.io/badge/license-MIT-blue)](https://pypi.org/project/visynx/)

<!-- --8<-- [start:intro] -->
[Visynx](https://visynx.com) is a computer vision platform: you label images, train
object detection and segmentation models, and deploy them, all in one place. `visynx`
is the official Visynx Python SDK. Give it an API key and a model name and you get
predictions back in Python, run on Visynx's GPUs or on your own machine or NVIDIA
Jetson. It is for developers and researchers who trained a model in Visynx and want to
use it from code: in a script, a backend service, a notebook, or a device on the edge.

Train a model in Visynx, grab an API key, and you are three lines from predictions —
detection, segmentation, pose, classification, and semantic segmentation, all through one call.

## Features

- **Hosted inference in three lines**: `predict()` takes a path, a folder, an open
  file, a PIL image or a numpy array, and runs on Visynx's GPUs.
- **Every model type, one result**: object detection, instance and semantic
  segmentation, pose (keypoints) and classification all return the same `Result`.
- **Extras on the hosted GPUs**: SAM 2 instance polygons (`segment=True`) and
  monocular depth (`depth=True`), with nothing extra to install.
- **Run it yourself**: download native, ONNX (FP32/FP16) or quantized edge exports
  and run them offline with `visynx[local]` (Professional and Enterprise plans).
- **NVIDIA Jetson**: TensorRT engines in FP16 or INT8, CSI and USB cameras, and
  one-command device pairing.
- **Typed errors**: one exception per failure, each quoting the request ID, with
  `429`s retried automatically.
- **A light install**: the core package depends only on `requests` and `Pillow`.
<!-- --8<-- [end:intro] -->

<!-- --8<-- [start:install] -->
## Installation

```bash
pip install visynx
```

`visynx` supports Python 3.9 to 3.13 on Linux, macOS and Windows. To run downloaded
models on your own hardware (Professional and Enterprise plans), install the local
extra, which adds `numpy` and `onnxruntime`:

```bash
pip install "visynx[local]"
```

You also need a Visynx API key: create one in the Visynx app under
**Settings → API Keys**.
<!-- --8<-- [end:install] -->

<!-- --8<-- [start:usage] -->
## Quickstart

```python
from visynx import Visynx

vf = Visynx(api_key="vf_...")          # or set VISYNX_API_KEY
model = vf.model("shelf-scanner/3")    # your project name and version

result = model.predict("shelf.jpg", confidence=0.4)

for d in result:
    print(d.class_name, round(d.confidence, 2), d.box)

result.save("annotated.jpg")
```

```
bottle 0.94 [412.0, 118.5, 501.2, 388.0]
bottle 0.91 [502.6, 121.0, 590.4, 390.7]
can    0.78 [604.1, 210.3, 664.9, 372.2]
```

`visynx` pulls in only `requests` and `Pillow`. No OpenCV, no numpy, no torch —
the models run on Visynx's GPUs, not yours.

## Naming a model

Your project and its training version — the same name the app shows you:

```python
model = vf.model(train_name="shelf-scanner", version="3")
model = vf.model("shelf-scanner/3")          # the same thing, as one handle
model = vf.model(train_name="shelf-scanner") # newest version
```

## Or take the model with you

**Professional and Enterprise** accounts can download the weights and run them
themselves. Every plan can keep using hosted `predict()` instead — downloading
is an option, not a step.

```bash
pip install "visynx[local]"
```

```python
vf = Visynx(api_key="vf_...")
model = vf.model(train_name="shelf-scanner", version="3")

model.download(path="./models/shelf-scanner")                # native weights
model.download(path="./models/shelf-scanner", format="onnx") # or a portable export
model.download(path="./models/shelf-scanner", format="edge") # ~4x smaller, for devices

local = vf.load_model("./models/shelf-scanner")   # or visynx.load_model(...)
result = local.predict("image.jpg", confidence=0.25)
result.save("annotated.jpg")
```

| Plan | Hosted `predict()` | `download()` | Local `predict()` |
|---|---|---|---|
| Starter | yes | no | no |
| Professional | yes | yes | yes |
| Enterprise | yes | yes | yes |

The check is the server's: an account without the feature gets a
`PlanRequiredError` and no bytes, whether the call comes from here or from
`curl`. Downloading someone else's model is refused the same way.

One local call covers every export and every kind of model — detection, instance
segmentation, pose, classification, semantic segmentation, in FP32, FP16 or
Edge. `visynx` reads what the file is, feeds it the way it expects, and returns
predictions in your image's own pixel coordinates: boxes, outlines, keypoints,
or a blended mask — the same `Result` the hosted call returns.

```python
local.labels                                 # class names, read from the file
local.runtime                                # 'portable' or 'native'
local.device                                 # where it is running
```

### Choosing where it runs

Any format — a checkpoint or any of the exports — takes a `device`:

```python
vf.load_model("./models/x")                  # "auto": the GPU when there is one
vf.load_model("./models/x", device="cpu")    # keep it off the GPU entirely
vf.load_model("./models/x", device="gpu")    # insist on the GPU
```

`"gpu"` is a requirement rather than a preference, so a machine without one gets
a `VisynxError` saying what is missing — never a silent fall back to the CPU at
a tenth of the speed. `"auto"` is the one that falls back, by design.

Portable (`.onnx`) exports need nothing but `visynx[local]`. A native checkpoint
also needs the runtime it was trained with; `python -m visynx setup` installs it.

## Run on NVIDIA Jetson

On a Jetson (JetPack 6), a Jetson export loads through TensorRT. The engine is built
on the device the first time the model loads and cached after that: INT8 when the
export ships calibration, FP16 otherwise. TensorRT needs the `onnxruntime-gpu` build
for JetPack 6 in place of the standard `onnxruntime`.

Pair the device once. This checks the key and saves it, so `Visynx()` needs no
arguments on this device:

```bash
python -m visynx pair
```

```python
import visynx

vf = visynx.Visynx()                                   # the paired key
model = vf.model("shelf-scanner/3")
model.download(path="./models/shelf", format="jetson_fp16")   # or "jetson_int8"

local = visynx.load_model("./models/shelf")
cam = visynx.open_camera("csi://0")         # or "usb://0", or an rtsp:// URL
ok, frame = cam.read()
result = local.predict(frame[..., ::-1])    # OpenCV frames are BGR; predict reads RGB
```

`python -m visynx build-engine ./models/shelf` builds the engine ahead of time, so the
first frame is not the slow one. Cameras need OpenCV
(`pip install opencv-python-headless`). Downloading a model is a Professional and
Enterprise feature; on other plans, hosted `predict()` works on a Jetson like anywhere
else.

## Find your models

```python
for m in vf.models():
    print(m.slug, m.display_name)
# shelf-scanner/3   Shelf Scanner v3
# defect-seg/1      Defect Seg v1
```

`"shelf-scanner/3"` is the model's slug — your project name and its training
version, the same name you see in the app. A raw `"yolo/<job_id>"` also works
and skips the lookup.

## What you get back

`predict()` returns a `Result`: iterate it for detections, or reach for the raw
API payload with `.json()`.

```python
result = model.predict("shelf.jpg")

len(result)              # 3
result.detections[0]     # Detection('bottle', 0.94)
result.json()            # the raw API response, untouched

result.plot()            # a PIL image with boxes drawn on
result.save("out.jpg")   # ...written to disk
```

Each `Detection` carries `class_id`, `class_name`, `confidence`, and `box`
(`[x1, y1, x2, y2]` in absolute pixels). Segmentation models add `polygons`;
pose models add `keypoints`.

## Anything image-shaped works

```python
model.predict("shelf.jpg")                  # a path
model.predict("frames/")                    # a directory -> list of Results
model.predict(open("shelf.jpg", "rb"))      # an open file
model.predict(pil_image)                    # a PIL image
model.predict(numpy_array)                  # a numpy array (from OpenCV, say)
```

## Beyond boxes

Two flags the hosted GPUs do for you, with nothing extra to install. Each runs a
second model, so each costs extra credits:

```python
# Turn every detected box into a precise instance polygon with SAM 2
result = model.predict("shelf.jpg", segment=True)
result.detections[0].polygons

# Add a monocular depth map, and a relative distance per detection
result = model.predict("shelf.jpg", depth=True)
result.detections[0].depth_median      # 0-1, higher is closer
result.depth_image.save("depth.png")
```

Semantic-segmentation models return a dense mask instead of boxes:

```python
result = model.predict("road.jpg")
result.semantic["legend"]     # [{'class_id': 1, 'class_name': 'road', ...}]
result.save("mask.jpg")       # the mask, blended over your image
```

## Get an API key

In Visynx, go to **Settings → API Keys**, create a key, and copy the secret —
it is shown once. Keys start with `vf_`, never expire, and can be locked to
specific IPs or CIDR ranges. Keep it out of source control:

```python
vf = Visynx()                      # reads VISYNX_API_KEY
```

A `predict()` call spends 1 Vision Credit on the checkpoint or the
full-precision graph, and 2 on the optimised runtimes (`format="onnx_fp16"` or
`format="edge"`); `format="auto"` is billed for whichever it runs. `segment=True` and `depth=True`
each add a surcharge for the extra model they run. You are charged only after the
inference succeeds — a failed call is free — and a call retried after a `429` is
billed once, not twice.

Some endpoints are deliberately not reachable with an API key: batch prediction
over a whole dataset, live-camera inference, workflow runs, and the AI-labelling
tools (SAM/DINO/box-prompt). Those run from the Visynx app with a signed-in
session. Calling them with a key returns `PermissionDeniedError`.

## Errors

Every failure is a typed exception, and it quotes the response's `X-Request-ID`
when the server sent one — include it if you contact support. (Authentication
failures are rejected before that header is assigned, so `401`s carry none.)

| Exception | Means | Do |
|---|---|---|
| `AuthenticationError` | key invalid or revoked | create a new key |
| `PermissionDeniedError` | email unverified, or the key's IP allowlist rejected you | verify your email / check the allowlist |
| `InsufficientCreditsError` | out of Vision Credits | top up |
| `PlanRequiredError` | your plan does not include this (e.g. downloading a model) | upgrade, or use hosted `predict()` |
| `ModelNotFoundError` | no such model, or not yours | check `vf.models()` |
| `PayloadTooLargeError` | image over 50 MB | resize before sending |
| `RateLimitError` | rate limited, retries exhausted | back off |
| `MaintenanceError` | platform in maintenance | retry later |

`429`s are retried automatically, honouring the server's `Retry-After`.
All of these subclass `VisynxError`, so one `except VisynxError` catches everything.

## Self-hosting

Point the client at your own deployment:

```python
vf = Visynx(api_key="vf_...", api_url="https://visynx.internal/api")
```

or set `VISYNX_API_URL`.
<!-- --8<-- [end:usage] -->

## Documentation

The full documentation, with installation, a quickstart and the API reference, is at
[docs.visynx.com](https://docs.visynx.com/).

## Links

- Website: [visynx.com](https://visynx.com)
- Documentation: [docs.visynx.com](https://docs.visynx.com/)
- Changelog: [docs.visynx.com/changelog](https://docs.visynx.com/changelog/)
- PyPI: [pypi.org/project/visynx](https://pypi.org/project/visynx/)

## License

MIT
