Skip to main content

clawID

Invisible & visible watermarking SDK for AI-generated images and video.

PyPI Python CI License: MIT

A research project by hawky.ai — the AI content provenance platform.

clawID embeds a UUID-based watermark into images and video frames — invisible to the human eye but detectable by the SDK. Inspired by Google SynthID. Built for AI-generated asset provenance tracking.

Links: PyPI · GitHub · Hugging Face Space · hawky.ai


Features

  • Invisible watermarking via DWT-QIM (Discrete Wavelet Transform + Quantization Index Modulation)
  • Resize-robust mode (algorithm='fm') — survives ±35% resize, JPEG compression, and minor edits
  • Visible watermarking — overlay text/logo with configurable opacity and position
  • Video support — watermark every Nth frame; detect from any single watermarked frame
  • REST API — FastAPI server with /embed and /detect endpoints
  • Storage backends — SQLite, PostgreSQL, MongoDB, Redis
  • CLIclawid embed, clawid detect, clawid embed-video, clawid detect-video

Installation

# Core (images only)
pip install clawid

# With video support
pip install "clawid[video]"

# With REST API
pip install "clawid[api]"

# Everything
pip install "clawid[all]"

Quick Start

Images

from clawid import embed, detect

# Embed invisible watermark
meta = embed(
    source='photo.jpg',
    output_path='photo_wm.png',
    metadata={'uid': 'creator123', 'platform': 'hawky.ai'},
)
print(meta['clawid'])  # e.g. "3f2a1b4c-..."

# Detect
result = detect('photo_wm.png')
print(result['uid'])       # creator123
print(result['platform'])  # hawky.ai

Resize-robust mode

meta = embed(
    source='photo.jpg',
    output_path='photo_wm.png',
    metadata={'uid': 'creator123'},
    algorithm='fm',   # survives ±35% resize
)

Video

from clawid import embed_video, detect_video

meta = embed_video(
    'input.mp4',
    'output_wm.mp4',
    metadata={'uid': 'creator123', 'platform': 'hawky.ai'},
    frame_stride=5,   # watermark every 5th frame
)

result = detect_video('output_wm.mp4')
print(result['uid'])  # creator123

Visible watermark

meta = embed(
    source='photo.jpg',
    output_path='photo_wm.png',
    metadata={'uid': 'creator123'},
    mode='visible',     # or 'both' for invisible + visible
    opacity=0.6,
    position='bottom-right',
)

CLI

# Embed
clawid embed -i photo.jpg -o photo_wm.png --uid creator123 --platform hawky.ai

# Embed (resize-robust)
clawid embed -i photo.jpg -o photo_wm.png --uid creator123 --algorithm fm

# Detect
clawid detect -i photo_wm.png

# Video
clawid embed-video -i input.mp4 -o output_wm.mp4 --uid creator123
clawid detect-video -i output_wm.mp4

# Save to SQLite store on embed, enrich on detect
clawid embed -i photo.jpg -o wm.png --uid creator123 --store sqlite:///clawid.db
clawid detect -i wm.png --store sqlite:///clawid.db

REST API

pip install "clawid[api]"
clawid serve --store sqlite:///clawid.db --port 8000

Endpoints:

Method Path Description
POST /embed Upload image, get back watermarked image + metadata
POST /detect Upload image, get back detected metadata
GET /docs Interactive Swagger UI
# Embed via API
curl -X POST http://localhost:8000/embed \
  -F "file=@photo.jpg" \
  -F "uid=creator123" \
  -F "platform=hawky.ai" \
  --output photo_wm.png

# Detect via API
curl -X POST http://localhost:8000/detect \
  -F "file=@photo_wm.png"

Storage Backends

from clawid.storage import from_uri

# SQLite (local)
with from_uri('sqlite:///clawid.db') as store:
    store.save(meta['clawid'], meta)
    record = store.get(meta['clawid'])

# PostgreSQL
with from_uri('postgresql://user:pass@localhost/mydb') as store:
    store.save(meta['clawid'], meta)

# MongoDB
with from_uri('mongodb://localhost:27017/mydb') as store:
    store.save(meta['clawid'], meta)

# Redis
with from_uri('redis://localhost:6379/0') as store:
    store.save(meta['clawid'], meta)

How It Works

Invisible watermark (DWT-QIM)

The payload (UUID + metadata, CBOR-encoded + CRC-checked) is serialised to bits, then each bit is embedded by quantizing a coefficient in the Haar wavelet LL2 sub-band. Each LL2 coefficient represents a 4×4 pixel block, so a change of delta/16 ≈ 2+ pixels per block — above the uint8 quantization step — making the watermark survive JPEG compression and format round-trips.

Mode Delta PSNR Survives
qim (default) 32 ~51 dB PNG/JPEG q≥75, minor edits
fm (resize-robust) 192 ~36 dB ±35% resize, PNG/JPEG q≥75

Video watermarking

Each video is processed frame by frame. Every Nth frame (frame_stride, default 5) receives the same DWT-QIM watermark with the same clawid UUID. Detection samples up to 10 frames and uses majority vote — detection succeeds as long as at least one watermarked frame survives.


Docker

docker compose up
# API available at http://localhost:8000

Development

git clone https://github.com/Hawky-ai/clawID
cd clawid
pip install -e ".[dev,api,video]"
pytest

Links

PyPI https://pypi.org/project/clawid/
GitHub https://github.com/Hawky-ai/clawID
Hugging Face https://huggingface.co/spaces/Hawky-ai/clawID
hawky.ai https://hawky.ai

License

MIT — Copyright © 2024 hawky.ai

Download files

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

Source Distribution

clawid-0.2.4.tar.gz (41.1 kB view details)

Uploaded Source

Built Distribution

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

clawid-0.2.4-py3-none-any.whl (37.3 kB view details)

Uploaded Python 3

File details

Details for the file clawid-0.2.4.tar.gz.

File metadata

  • Download URL: clawid-0.2.4.tar.gz
  • Upload date:
  • Size: 41.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.2

File hashes

Hashes for clawid-0.2.4.tar.gz
Algorithm Hash digest
SHA256 0f3d2e6379426b864a23123a5a0e2bfbde8549e9f39d51d5da2323e9792f733f
MD5 36903dbd57db52cfc920a252fd7699a4
BLAKE2b-256 f06bc0ecc2624930947237b4e6dcb244f80f7b002a2f2002bbb744715b7f0c8f

See more details on using hashes here.

File details

Details for the file clawid-0.2.4-py3-none-any.whl.

File metadata

  • Download URL: clawid-0.2.4-py3-none-any.whl
  • Upload date:
  • Size: 37.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.2

File hashes

Hashes for clawid-0.2.4-py3-none-any.whl
Algorithm Hash digest
SHA256 af4d05b579b991973ba189b945a61b53f1a444b49a06be516d2b297c4159fbce
MD5 bd5424e9751f461cb6bd4eb68e8f2e53
BLAKE2b-256 d12d5d056fbc2ac62afc39fa8abdffcfb2cd6bbc03aa13f7579abc7bcadd9bf7

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.2.4 This release

2 files

0.2.3

2 files

0.2.2

2 files

0.2.1

2 files

0.2.0

2 files

0.1.0

2 files

Supported by

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