Metadata-Version: 2.4
Name: vqflow
Version: 0.1.0
Summary: Download and generate versioned VQFlow dataset exports from Python.
Author: VQFlow Labs
License-Expression: Apache-2.0
Project-URL: Repository, https://github.com/vqflowlabs/vqflow-python-packages
Classifier: Development Status :: 3 - Alpha
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Operating System :: OS Independent
Classifier: Typing :: Typed
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Dynamic: license-file

# vqflow

Download versioned VQFlow dataset exports from Python. When an export version
does not exist, the SDK requests it, waits for generation and downloads its ZIP.
Both the resource interface and fluent builder use the same export workflow.

Requires Python 3.10 or newer. Install the released package from PyPI with:

```sh
python -m pip install vqflow
```

For development, install from an authorized repository checkout:

```sh
python -m pip install ./packages/vqflow
```

## Connect

Provide your API key and HTTPS API base URL at runtime. The base URL must include
the API prefix, such as `/api/v1`. The SDK reads only `VQFLOW_API_KEY` and
`VQFLOW_API_URL` when the corresponding constructor arguments are omitted; it
does not load environment files or machine credential stores.

```python
import os
from vqflow import VQFlow

vqf = VQFlow(
    api_key=os.environ["VQFLOW_API_KEY"],
    base_url=os.environ["VQFLOW_API_URL"],
)
```

Use an API key with access to the selected dataset. Downloading an existing
export can use a read-only key. Generating a missing version requires a key
permitted to create exports. The SDK respects the account's existing permissions.

## Resource interface

```python
dataset = (
    vqf.workspace("sample-workspace")
    .project("sample-project")
    .dataset("sample-dataset")
)

dataset_export_path = dataset.export("coco", "training-v1", "./datasets")
```

Use exact workspace, project and dataset names rather than display titles.
Selection is lazy: navigation methods do not issue requests until an export runs.
`dataset_export_path` is a `pathlib.Path` to the downloaded ZIP, named
`vqflow-export-<export-id>.zip` inside the destination directory. Archives remain
zipped. Existing local files are not overwritten unless `overwrite=True`.

The second `export()` argument is always the **dataset export version**. If
multiple datasets share a name, select the source dataset explicitly:

```python
dataset = (
    vqf.workspace("sample-workspace")
    .project("sample-project")
    .dataset("sample-dataset", dataset_version="source-v2")
)
```

Omitting `dataset_version` requires an unambiguous dataset. Explicit `None`
selects the unversioned dataset. The SDK never silently selects the latest match.

Supported formats are `coco`, `category_folders`, and `vqflow_native`. You can
also use the `ExportFormat` enum. ZIP is the result container for all formats.

## Export builder

```python
from vqflow import DatasetExportBuilder

builder = (
    DatasetExportBuilder(vqf)
    .withWorkspace("sample-workspace")
    .withProject("sample-project")
    .withDataset("sample-dataset")
    .withFormat("coco")
    .withVersion("training-v1")
    .withDestination("./datasets")
)

dataset_export_path = builder.export()
```

The `with...` methods configure the builder. Only `export()` and
`exportCurated()` perform requests. Use `withDatasetVersion(...)` when the source
dataset needs disambiguation; `withVersion(...)` always names the export version.

## Media selection

Exports include all media in the selected dataset unless status filters are
specified. Review and QA filters combine with **AND**:

```python
from vqflow import ReviewStatus, QAStatus

dataset_export_path = (
    builder
    .withVersion("approved-v1")
    .withReview(ReviewStatus.APPROVED)
    .withQA(QAStatus.APPROVED)
    .export()
)
```

The curated shortcut requires both review and QA to be approved:

```python
dataset_export_path = builder.withVersion("curated-v1").exportCurated()
```

`exportCurated()` overrides both filters for that call and leaves the builder's
saved filters unchanged. Each filter supports `APPROVED`, `REJECTED`, `PENDING`,
and `NONE`, as an enum or case-insensitive string. Python `None` removes the
filter; the string `"NONE"` selects media whose actual status is `NONE`.

The resource interface accepts the same filters:

```python
dataset_export_path = dataset.export(
    "coco", "approved-v1", "./datasets", review="APPROVED", qa="APPROVED"
)
```

## Code supplied by VQFlow

The portal's generated code supplies the API address and the exact dataset and
export identities. An exact export ID preserves the stored export's original
media selection, including selections beyond the SDK's review/QA filters:

```python
# Keep your API key private. Do not share it or commit it to source control.
dataset_export_path = dataset.export(
    "coco", "training-v1", "./datasets", export_id=44
)
```

The builder equivalent is `.withExportId(44).export()`. An explicit ID never
creates a replacement if that export is missing, and it cannot be combined with
review/QA overrides or `exportCurated()`. Use a new export version without an
explicit ID when requesting a different selection.

With an explicit export ID, the workspace, project, dataset name and optional
dataset version are checked against the export's saved snapshot. Current
workspace and dataset lists are not consulted, so the code remains usable after
the source dataset moves or its version changes, provided the account still has
access to the stored export. Without an export ID, navigation selects the current
dataset as usual.

Generated code containing an API key is private to you. Do not share the snippet,
include it in a public notebook, or commit it to source control. Revoke a key in
VQFlow if it has been exposed.

## Existing versions and generation

The SDK searches all result pages for the exact dataset and export version. It
selects the requested format and ZIP result, then verifies the saved task's
selection. Other formats may coexist under the same export-version label.

- A ready matching export is downloaded using a fresh access URL.
- A matching queued or running export is awaited and reused.
- An absent export version starts one normal background export.
- A version with incompatible format or filters raises an export conflict.
- Duplicate matching exports and same-name datasets raise an ambiguity error.
- Legacy exports without verifiable selection metadata require a new export
  version. They are not assumed to contain all media.
- A failed or cancelled export raises an error. It is not treated as missing.

Choose a new export version when changing the selection. Existing versions are
reused without rebuilding them from the dataset's current contents. An empty
selection is reported through the normal server export failure.

## Waiting, failures and retries

```python
dataset_export_path = dataset.export(
    "coco", "training-v1", "./datasets",
    wait_timeout=7200,
    poll_interval=5,
)
```

The default wait limit is two hours. A timeout does not cancel server work;
`ExportTimeoutError` retains the task/export identifiers. Calling export again
with the same version reuses that task. Scheduled server retries remain active
work even when a previous attempt has an error.

The SDK never automatically repeats an export-creation POST after an uncertain
network outcome. `ExportCreationUncertainError` asks the caller to check the
export version before trying again. The current API does not provide an atomic
get-or-create operation: concurrent clients can create duplicate version
records. The SDK detects observed duplicates and does not silently choose one.

Typed errors are exported from `vqflow`, including `AuthenticationError`,
`PermissionDeniedError`, `NotFoundError`, `AmbiguousResourceError`,
`ExportConflictError`, `ExportFailedError`, `ExportTimeoutError`,
`ExportCreationUncertainError`, `TransportError`, `ProtocolError`, and
`DownloadError`. Errors omit raw server responses and credential-bearing URLs.

Call `vqf.close()` when finished, or use `with VQFlow(...) as vqf:`.

## Credential and download handling

API keys are supplied only to the configured API. ZIP downloads use a separate
unauthenticated connection. HTTPS is required; redirects and ambient proxy
configuration are disabled. Archive data streams to a temporary file and is
published at the final path only after a successful download and validation.

Never put real keys, passwords, confidential data or captured API responses in
source, examples, tests or package artifacts. Supply credentials only at runtime.

## License

Licensed under Apache-2.0. The complete license is included in the distribution.
