Skip to main content

Official Python client for the FluidGhost API — spoof a photo, video, or carousel with your API key and get back distinct 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 does one thing: spoof media with your API key, over the submit → poll → download loop. It handles a single photo, a video, or a whole carousel.

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. An API key is spoof-only: it can submit jobs and read/download their results, and nothing else.

Spoof a photo or video

run() submits a job and waits for it to finish. Results are 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). Photos and videos both go through the same call — the type is detected from the file.

import os
from fluidghost import FluidGhost

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

job = fg.run(
    image="photo.jpg",                 # or a video: "clip.mp4"
    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")

Spoof a carousel (matched set)

A carousel is a set of photos posted together. spoof_carousel() submits one linked job per file — sharing a session and a running filename sequence so the outputs read as one cohesive post — and waits for all of them.

jobs = fg.spoof_carousel(
    ["slide1.jpg", "slide2.jpg", "slide3.jpg"],
    recipe_id="full-refresh",
)

for job in jobs:
    v = job["variants"][0]
    data = fg.download_variant(job["jobId"], v["index"])
    with open(v["fileName"], "wb") as f:
        f.write(data)

For a fully cohesive set (the same device across every slide), pass a recipe_config or preset_id that pins a device — otherwise each slide picks its own device family.

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".
preset_id A saved preset created in the dashboard (e.g. "sys:full-refresh").
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}.

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-2.0.0.tar.gz (7.2 kB view details)

Uploaded Source

Built Distribution

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

fluidghost-2.0.0-py3-none-any.whl (7.8 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for fluidghost-2.0.0.tar.gz
Algorithm Hash digest
SHA256 d01ec3140e8f7e93d225b13171b290a61cbc4125790cb7e614e225ca475af42e
MD5 ef6a4530d5c8ba11dfb18cc0c7f6bbdc
BLAKE2b-256 9a93bc2eb9f1bc6e922aa40f5504140a8372d841677306cc6f7842a20f07dfda

See more details on using hashes here.

File details

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

File metadata

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

File hashes

Hashes for fluidghost-2.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 56ed6e19f42d95426628914c9ae6560bcea78445a6bb0a1662df99f2ba335e23
MD5 a7ffeea88d6bdf4b0bfcaf9b0caa9cca
BLAKE2b-256 6cdb612abff4eaa7ae54419f60f7f0cab2c003063ab0ddfdd9fa4b839a395a82

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