Skip to main content

Official Python client for the FluidGhost API — submit a photo or video, get back distinct uniquified variants with device-authentic metadata.

Project description

fluidghost

Official Python client for the FluidGhost API.

FluidGhost turns one photo or video into a set of distinct variants — each a fresh, standalone capture with its own metadata, its own pixels, and a device-authentic filename. This SDK wraps the HTTP/multipart/auth layer so you can submit → poll → download in a few calls.

Install

pip install fluidghost

Authentication

Mint an API key in the dashboard (Settings → API keys at https://ghost.fluidvip.com). Keep it server-side — never ship it in client code.

  • fg_sk_...secret / data plane: submit jobs, read results, manage presets.
  • fg_mgmt_...management: provisioning only (mint sub-keys for your own users).

Quickstart — submit, wait, download

run() submits a job and waits for it to finish. API-key jobs deliver results as one-time links: download_variant() streams the bytes and the object is deleted on a successful download (a second call raises FluidGhostError with status 410).

import os
from fluidghost import FluidGhost

fg = FluidGhost(api_key=os.environ["FLUIDGHOST_KEY"])

job = fg.run(
    image="photo.jpg",
    recipe_id="full-refresh",
    copies=3,
    options={"noise": 35, "ultraSafe": True},
    on_poll=lambda j: print(j["status"], j.get("progress")),
)

for v in job["variants"]:
    if v["status"] != "completed":
        continue
    data = fg.download_variant(job["jobId"], v["index"])
    with open(v.get("fileName") or f"variant-{v['index']}.jpg", "wb") as f:
        f.write(data)
    print(v.get("fileName"), "risk", v.get("detectionRisk"), v.get("riskBand"))

You can pass in-memory bytes instead of a path with a (filename, bytes) tuple:

fg.create_job(image=("photo.jpg", my_bytes), recipe_id="full-refresh")

Settings

Provide exactly one recipe source (or bind a default preset to your key and omit all three):

Argument Meaning
recipe_id A bundled starter, e.g. "full-refresh" (see get_options()["recipes"]).
preset_id A saved preset, yours or a system one ("sys:full-refresh", "sys:metadata-only").
recipe_config A full recipe graph (advanced).
copies Number of variants, 1–50.
strength Global strength 0–100.
options Extra knobs merged onto the recipe, e.g. {"noise": 35, "ultraSafe": True}.

Other calls

fg.me()                    # {"ownerId": ..., "balance": ..., "tier": ...}
fg.get_options()           # device/city presets, filters, starter recipes, limits
fg.list_jobs()             # your recent jobs
fg.inspect("photo.jpg")    # read EXIF/GPS/MakerNotes, no job

# Presets
fg.list_presets()
fg.create_preset("My look", recipe_config)
fg.update_preset(preset_id, name="Renamed")
fg.delete_preset(preset_id)

Provisioning (management key)

With an fg_mgmt_... key you can mint data-plane sub-keys for your own end users:

mgmt = FluidGhost(api_key=os.environ["FLUIDGHOST_MGMT_KEY"])
sub = mgmt.provision_key(identity="user_123", label="Acme user 123")
print(sub["key"])   # shown once — hand it to that user's integration

Errors

Every non-2xx response raises FluidGhostError, mirroring the API's {error, message, details}:

from fluidghost import FluidGhost, FluidGhostError

try:
    fg.run(image="photo.jpg", recipe_id="full-refresh", copies=3)
except FluidGhostError as e:
    print(e.status, e.code, e.details)
    if e.code == "rate_limited":
        time.sleep(e.retry_after or 5)
    if e.code == "insufficient_balance":
        ...  # top up in the dashboard

Configuration

FluidGhost(
    api_key="fg_sk_live_…",
    base_url="https://api-ghost.fluidvip.com",  # default; override for a proxy
    timeout=60.0,
)

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

fluidghost-1.0.0.tar.gz (7.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

fluidghost-1.0.0-py3-none-any.whl (8.4 kB view details)

Uploaded Python 3

File details

Details for the file fluidghost-1.0.0.tar.gz.

File metadata

  • Download URL: fluidghost-1.0.0.tar.gz
  • Upload date:
  • Size: 7.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.11

File hashes

Hashes for fluidghost-1.0.0.tar.gz
Algorithm Hash digest
SHA256 37e5f95100704c689dd36637bf661403d729ad41b43adf6ccc9b0c4a3660b34b
MD5 3d8d1dc6e3d84d6dc188158847781ca2
BLAKE2b-256 f9ca9839b6f3c0e15722f52a0fbf9623ef1de18c0e0ddc9ee8ee6a1fcce74e45

See more details on using hashes here.

File details

Details for the file fluidghost-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: fluidghost-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 8.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.11

File hashes

Hashes for fluidghost-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 07a6d34e86790f90624ed13c99d8f4c925706ff37ec39643ceb23c2d983e83ef
MD5 b665ea1952af81adfbdd9327e75eb6fe
BLAKE2b-256 407afdfcaf95dfd9da12446218b3a91fc2fd62de06da7eec657b6a28ac442b1b

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page