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.
- Full API docs: https://ghost.fluidvip.com/app/docs/
- Python 3.8+ (depends on
requests).
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
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
37e5f95100704c689dd36637bf661403d729ad41b43adf6ccc9b0c4a3660b34b
|
|
| MD5 |
3d8d1dc6e3d84d6dc188158847781ca2
|
|
| BLAKE2b-256 |
f9ca9839b6f3c0e15722f52a0fbf9623ef1de18c0e0ddc9ee8ee6a1fcce74e45
|
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
07a6d34e86790f90624ed13c99d8f4c925706ff37ec39643ceb23c2d983e83ef
|
|
| MD5 |
b665ea1952af81adfbdd9327e75eb6fe
|
|
| BLAKE2b-256 |
407afdfcaf95dfd9da12446218b3a91fc2fd62de06da7eec657b6a28ac442b1b
|