Skip to main content

FoxNose Python SDK

PyPI version Python versions CI codecov Docs License

FoxNose is a managed knowledge layer for RAG and AI agents — auto-embeddings, hybrid search, and zero ETL pipelines to maintain.

This is the official Python SDK for FoxNose Management and Flux APIs.

Features

  • Type-safe clients - Full type hints and Pydantic models
  • Sync and async - Both synchronous and asynchronous clients
  • Automatic retries - Configurable retry with exponential backoff
  • JWT authentication - Built-in token refresh support
  • Flux introspection - Discover routes and live schema via /_router and /_schema

Documentation

SDK Documentation: foxnose-python.readthedocs.io

FoxNose Platform:

Installation

pip install foxnose-sdk

Quick Start

To get started, you'll need a FoxNose account. Create one here.

from foxnose_sdk.management import ManagementClient
from foxnose_sdk.auth import JWTAuth

client = ManagementClient(
    base_url="https://api.foxnose.net",
    environment_key="your-environment-key",
    auth=JWTAuth.from_static_token("YOUR_ACCESS_TOKEN"),
)

# List collections
collections = client.list_collections()
for collection in collections.results:
    print(f"{collection.name} ({collection.key})")

client.close()

Note (0.6.0): Folder-named methods (list_folders, create_folder, add_api_folder, list_folder_versions, list_folder_fields, etc.) remain as deprecated aliases that emit a one-shot DeprecationWarning on first use per process. They keep their original wire behaviour (hitting the legacy /folders/... URL alias on the server) and will be removed in 1.0. Prefer the *_collection* names in new code.

Async Client

from foxnose_sdk.management import AsyncManagementClient

async def main():
    client = AsyncManagementClient(
        base_url="https://api.foxnose.net",
        environment_key="your-environment-key",
        auth=JWTAuth.from_static_token("YOUR_ACCESS_TOKEN"),
    )

    collections = await client.list_collections()
    await client.aclose()

Components on Collections

Collections can embed Components as nested fields with explicit pin semantics (component, component_version, auto_update). The NestedFieldMeta helper builds the meta block for you, and sync_collection_component advances pinned fields to a target Component version on demand.

from foxnose_sdk import (
    ManagementClient,
    FoxnoseConfig,
    NestedFieldMeta,
)
from foxnose_sdk.auth import JWTAuth

client = ManagementClient(
    FoxnoseConfig(base_url="https://api.foxnose.com"),
    environment_key="prod",
    auth=JWTAuth("ACCESS_TOKEN"),
)

# Embed a Component as a pinned nested field on a Collection draft.
client.create_collection_field(
    "articles",
    "v2-draft",
    {
        "key": "seo",
        "name": "SEO",
        "type": "nested",
        "required": True,
        "meta": NestedFieldMeta(
            component="cmp-seo-metadata",
            component_version="ver-abc12345",
            auto_update=False,  # default — pin until explicit sync
        ).to_meta(),
    },
)

# Later, advance every pinned nested field to its Component's current
# version (empty body = sync all pinned).
result = client.sync_collection_component("articles")
print(result.synced_paths, result.schema_version)

# Advance specific paths to a chosen Component version.
result = client.sync_collection_component(
    "articles",
    field_paths=["seo"],
    to_versions={"seo": "ver-def67890"},
)

sync_collection_component returns a SyncComponentResponse with synced_paths, skipped (per-path reasons), and schema_version (UID of the newly published Collection schema version, or None if no field needed advancing). On compatibility conflict the server returns 409 component_sync_conflict; quota exhaustion returns 422 too_many_versions. Both surface as FoxnoseAPIError.

Handling billing errors

Billing and quota responses raise typed subclasses of FoxnoseAPIError, so existing except FoxnoseAPIError handlers keep working while new code can read the typed attributes:

from foxnose_sdk import (
    SpendCapExceeded,
    PlanExhausted,
    PlanLimitExceeded,
    RateLimitExceeded,
)

try:
    client.create_collection({"name": "Blog"})
except SpendCapExceeded as e:  # HTTP 402
    print(f"Spend cap {e.cap_usd}; resets at {e.cycle_resets_at}: {e.raise_cap_url}")
except PlanExhausted as e:  # HTTP 402
    print(f"Allowance for {e.axis} exhausted; resets at {e.window_resets_at}")
except PlanLimitExceeded as e:  # HTTP 403
    print(f"{e.entity}: {e.current}/{e.limit}. Upgrade: {e.upgrade_url}")
except RateLimitExceeded as e:  # HTTP 429
    print(f"Rate limited; retry after {e.retry_after}s")

All four subclass FoxnoseAPIError, so a single except FoxnoseAPIError still catches them if you don't need the typed fields.

Flux Client

from foxnose_sdk.flux import FluxClient
from foxnose_sdk.auth import SimpleKeyAuth

client = FluxClient(
    base_url="https://<env_key>.fxns.io",
    api_prefix="v1",
    auth=SimpleKeyAuth("PUBLIC_KEY", "SECRET_KEY"),
)

resources = client.list_resources("blog-posts")

# Writes require a write-capable key. Create publishes immediately; `key` is an
# optional external id used to deduplicate. update_resource is a full replace.
created = client.create_resource("blog-posts", {"title": "Hello"}, key="my-id")
client.update_resource("blog-posts", created["resource_key"], {"title": "Hello (edited)"})

client.close()

Development

# Install with dev dependencies
pip install -e .[test,docs]

# Run tests
pytest

# Run tests with coverage
pytest --cov=foxnose_sdk --cov-report=term-missing

# Build docs
mkdocs serve

License

Apache 2.0 - see LICENSE for details.

Release files for foxnose-sdk 0.8.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for foxnose-sdk 0.8.0
File Size Uploaded
foxnose_sdk-0.8.0.tar.gz 117.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for foxnose-sdk 0.8.0
File Interpreter ABI Platform
foxnose_sdk-0.8.0-py3-none-any.whl Python 3 none any Details

Total release size: 167.5 kB

Release files / foxnose_sdk-0.8.0.tar.gz

Download URL foxnose_sdk-0.8.0.tar.gz
Size 117.8 kB
Tags Source
SHA-256 checksum
How to use checksums
101d259c02ec81b158286ce2d760f23fd12af47759a29492d8d809d09d98a749
BLAKE2b-256 checksum
How to use checksums
be45fd8fb34f87dd1ef5e1510d41d1b40fd535ccc309bc7daa895290b6eac38b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release files / foxnose_sdk-0.8.0-py3-none-any.whl

Download URL foxnose_sdk-0.8.0-py3-none-any.whl
Size 49.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
7856c04d934c4e82e774b2a3d81885111fd42a99697308f168c332dbfb93842a
BLAKE2b-256 checksum
How to use checksums
1905ff56f7cb11caabc38938380087088be2bcf78a70f2f1b42bed58bb5f4a17
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release history Release notifications | RSS feed

0.8.1

2 release files

This release

0.8.0 This release

2 release files

0.7.1

2 release files

0.7.0

2 release files

0.6.0

2 release files

0.5.0

2 release files

0.4.2

2 release files

0.4.1

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page