Spaces:
Running
Running
| title: Cipher MD API Bundle | |
| emoji: π | |
| colorFrom: blue | |
| colorTo: indigo | |
| sdk: docker | |
| app_port: 7860 | |
| # π Cipher-MD API Bundle | |
| > All requests go through the **Gateway** on port `7860`. | |
| > Base URL: `https://your-space.hf.space` | |
| **Gateway prefix routing:** | |
| | Prefix | Service | Internal Port | | |
| |--------|---------|---------------| | |
| | `/visuals/...` | Visuals Engine (Node.js) | 7861 | | |
| | `/audio_server/...` | Audio Engine (FastAPI) | 7862 | | |
| | `/cipher_sticker/...` | Sticker Engine (Flask) | 7863 | | |
| | `/scanner/...` | Scanner Engine (FastAPI) | 7864 | | |
| --- | |
| ## π Table of Contents | |
| 1. [Gateway](#-gateway) | |
| 2. [Visuals Engine](#-1-visuals-engine) | |
| - [GET /welcome check](#get-visuals) | |
| - [POST /welcome](#post-visualswelcome) | |
| - [POST /watermark](#post-visualswatermark) | |
| - [POST /chart/candle](#post-visualschartcandle) | |
| - [POST /chart/p2p](#post-visualschartp2p) | |
| - [POST /chart/forex](#post-visualschartforex) | |
| - [POST /chart/gold](#post-visualschartgold) | |
| - [POST /chart/cse](#post-visualschartcse) | |
| - [POST /chart/fear](#post-visualschartfear) | |
| - [POST /chart/nft](#post-visualschartnft) | |
| - [POST /chart/arb](#post-visualschartarb) | |
| 3. [Audio Engine](#-2-audio-engine) | |
| - [GET /audio_server](#get-audio_server) | |
| - [GET /audio_server/effects](#get-audio_servereffects) | |
| - [POST /audio_server/info](#post-audio_serverinfo) | |
| - [POST /audio_server/process](#post-audio_serverprocess) | |
| - [POST /audio_server/trim](#post-audio_servertrim) | |
| 4. [Sticker Engine](#-3-sticker-engine) | |
| - [GET /cipher_sticker](#get-cipher_sticker) | |
| - [POST /cipher_sticker/sticker](#post-cipher_stickersticker) | |
| - [POST /cipher_sticker/pack](#post-cipher_stickerpack) | |
| 5. [Scanner Engine](#-4-scanner-engine) | |
| - [GET /scanner](#get-scanner) | |
| - [POST /scanner/scan](#post-scannerscan) | |
| --- | |
| ## π Gateway | |
| ### `GET /` | |
| **Server status + RAM info** | |
| ```python | |
| import requests | |
| res = requests.get("https://your-space.hf.space/") | |
| print(res.json()) | |
| ``` | |
| **Response:** | |
| ```json | |
| { | |
| "message": "π Cipher-MD Smart API Gateway is Running!", | |
| "status": "Active", | |
| "ram_monitoring": true, | |
| "free_ram_mb": 2048, | |
| "queued_requests": 0 | |
| } | |
| ``` | |
| --- | |
| ## π¨ 1. Visuals Engine | |
| ### `GET /visuals/` | |
| Server check. | |
| ```python | |
| import requests | |
| res = requests.get("https://your-space.hf.space/visuals/") | |
| print(res.text) # "π Cipher-MD ULTRA-SHARP ENGINE" | |
| ``` | |
| --- | |
| ### `POST /visuals/welcome` | |
| Welcome image generate ΰΆΰΆ»ΰΆ±ΰ·ΰ· (profile pic + group name + member count + optional username). | |
| **Form-data Parameters:** | |
| | Parameter | Type | Required | Description | | |
| |-----------|------|----------|-------------| | |
| | `image` | file | β | Profile picture (PNG/JPG) | | |
| | `title` | string | β | Group name | | |
| | `count` | string | β | Member number | | |
| | `userName` | string | β | New member's name (shown separately in cyan) | | |
| > **Note:** Sinhala text in `title` or `userName` is automatically translated to English via Google Translate. | |
| ```python | |
| import requests | |
| with open("profile.jpg", "rb") as img: | |
| res = requests.post( | |
| "https://your-space.hf.space/visuals/welcome", | |
| files={"image": img}, | |
| data={ | |
| "title": "Cipher Squad", | |
| "count": "42", | |
| "userName": "Kamal" # Optional β omit if not needed | |
| } | |
| ) | |
| with open("welcome.png", "wb") as f: | |
| f.write(res.content) | |
| ``` | |
| **Response:** `image/png` binary (1024Γ1024 px welcome card) | |
| --- | |
| ### `POST /visuals/watermark` | |
| Image-ek-ta watermark danna. | |
| **Form-data Parameters:** | |
| | Parameter | Type | Required | Description | | |
| |-----------|------|----------|-------------| | |
| | `image` | file | β | Any PNG/JPG image | | |
| | `watermarkText` | string | β | Custom watermark text (default: `CIPHER-MD GEN ENGINE`) | | |
| ```python | |
| import requests | |
| with open("photo.png", "rb") as img: | |
| res = requests.post( | |
| "https://your-space.hf.space/visuals/watermark", | |
| files={"image": img}, | |
| data={"watermarkText": "Β© My Bot 2025"} # Optional | |
| ) | |
| with open("watermarked.png", "wb") as f: | |
| f.write(res.content) | |
| ``` | |
| **Response:** `image/png` binary (same dimensions as input) | |
| --- | |
| ### `POST /visuals/chart/candle` | |
| Candlestick chart generate ΰΆΰΆ»ΰΆ±ΰ·ΰ·. | |
| **JSON Body Parameters:** | |
| | Parameter | Type | Required | Description | | |
| |-----------|------|----------|-------------| | |
| | `symbol` | string | β | Trading pair (e.g. `BTC`) | | |
| | `change` | string | β | 24h % change (e.g. `"+2.5"`) | | |
| | `currentPrice` | string | β | Current price | | |
| | `candles` | array | β | Array of OHLCV candle objects | | |
| **Candle object:** | |
| ```json | |
| { "open": 65000, "high": 66000, "low": 64500, "close": 65800, "volume": 1200 } | |
| ``` | |
| ```python | |
| import requests | |
| payload = { | |
| "symbol": "BTC", | |
| "change": "+2.5", | |
| "currentPrice": "65800", | |
| "candles": [ | |
| {"open": 64000, "high": 65500, "low": 63800, "close": 65200, "volume": 980}, | |
| {"open": 65200, "high": 66100, "low": 64900, "close": 65800, "volume": 1200}, | |
| {"open": 65800, "high": 67000, "low": 65500, "close": 66500, "volume": 1500}, | |
| ] | |
| } | |
| res = requests.post( | |
| "https://your-space.hf.space/visuals/chart/candle", | |
| json=payload | |
| ) | |
| with open("candle_chart.png", "wb") as f: | |
| f.write(res.content) | |
| ``` | |
| **Response:** `image/png` binary (4K chart β 2400Γ1500 px) | |
| --- | |
| ### `POST /visuals/chart/p2p` | |
| USDT/LKR P2P rate line chart. | |
| **JSON Body Parameters:** | |
| | Parameter | Type | Required | Description | | |
| |-----------|------|----------|-------------| | |
| | `currentRate` | number | β | Current rate | | |
| | `history` | array | β | Array of `{rate: number}` objects | | |
| ```python | |
| import requests | |
| res = requests.post( | |
| "https://your-space.hf.space/visuals/chart/p2p", | |
| json={ | |
| "currentRate": 325.5, | |
| "history": [ | |
| {"rate": 310}, {"rate": 315}, {"rate": 318}, | |
| {"rate": 320}, {"rate": 325}, {"rate": 325.5} | |
| ] | |
| } | |
| ) | |
| with open("p2p_chart.png", "wb") as f: | |
| f.write(res.content) | |
| ``` | |
| **Response:** `image/png` binary (4K line chart) | |
| --- | |
| ### `POST /visuals/chart/forex` | |
| USD/LKR official rate chart. | |
| **JSON Body Parameters:** | |
| | Parameter | Type | Required | Description | | |
| |-----------|------|----------|-------------| | |
| | `currentRate` | number | β | Current rate | | |
| | `history` | array | β | Array of `{rate: number}` objects | | |
| ```python | |
| import requests | |
| res = requests.post( | |
| "https://your-space.hf.space/visuals/chart/forex", | |
| json={ | |
| "currentRate": 298.5, | |
| "history": [{"rate": 290}, {"rate": 293}, {"rate": 295}, {"rate": 298.5}] | |
| } | |
| ) | |
| with open("forex_chart.png", "wb") as f: | |
| f.write(res.content) | |
| ``` | |
| **Response:** `image/png` binary (4K line chart, green theme) | |
| --- | |
| ### `POST /visuals/chart/gold` | |
| Gold (24K) price chart. | |
| **JSON Body Parameters:** | |
| | Parameter | Type | Required | Description | | |
| |-----------|------|----------|-------------| | |
| | `currentRate` | number | β | Current gold price | | |
| | `history` | array | β | Array of `{value: number}` or `{price: number}` objects | | |
| ```python | |
| import requests | |
| res = requests.post( | |
| "https://your-space.hf.space/visuals/chart/gold", | |
| json={ | |
| "currentRate": 580000, | |
| "history": [ | |
| {"value": 570000}, {"value": 575000}, {"value": 580000} | |
| ] | |
| } | |
| ) | |
| with open("gold_chart.png", "wb") as f: | |
| f.write(res.content) | |
| ``` | |
| **Response:** `image/png` binary (4K line chart, gold theme) | |
| --- | |
| ### `POST /visuals/chart/cse` | |
| CSE ASPI Index chart. | |
| **JSON Body Parameters:** | |
| | Parameter | Type | Required | Description | | |
| |-----------|------|----------|-------------| | |
| | `currentRate` | number | β | Current ASPI value | | |
| | `history` | array | β | Array of `{value: number}` objects | | |
| ```python | |
| import requests | |
| res = requests.post( | |
| "https://your-space.hf.space/visuals/chart/cse", | |
| json={ | |
| "currentRate": 12500, | |
| "history": [{"value": 12000}, {"value": 12200}, {"value": 12500}] | |
| } | |
| ) | |
| with open("cse_chart.png", "wb") as f: | |
| f.write(res.content) | |
| ``` | |
| **Response:** `image/png` binary (4K line chart, purple theme) | |
| --- | |
| ### `POST /visuals/chart/fear` | |
| Fear & Greed Index chart. | |
| **JSON Body Parameters:** | |
| | Parameter | Type | Required | Description | | |
| |-----------|------|----------|-------------| | |
| | `history` | array | β | Array of `{value: number}` (0β100) | | |
| > Color is auto-selected: green if last value > 50, red if β€ 50. | |
| ```python | |
| import requests | |
| res = requests.post( | |
| "https://your-space.hf.space/visuals/chart/fear", | |
| json={ | |
| "history": [ | |
| {"value": 30}, {"value": 45}, {"value": 60}, | |
| {"value": 55}, {"value": 72} | |
| ] | |
| } | |
| ) | |
| with open("fear_chart.png", "wb") as f: | |
| f.write(res.content) | |
| ``` | |
| **Response:** `image/png` binary (4K line chart) | |
| --- | |
| ### `POST /visuals/chart/nft` | |
| NFT collection info card. | |
| **JSON Body Parameters (inside `data` key):** | |
| | Parameter | Type | Required | Description | | |
| |-----------|------|----------|-------------| | |
| | `data.name` | string | β | Collection name | | |
| | `data.chain` | string | β | Blockchain (e.g. `ethereum`) | | |
| | `data.floor_price` | number | β | Floor price | | |
| | `data.floor_price_symbol` | string | β | Symbol (e.g. `ETH`) | | |
| | `data.total_volume` | number | β | Total trade volume | | |
| | `data.owner_count` | number | β | Owner count | | |
| | `data.image_url` | string | β | Collection image URL | | |
| ```python | |
| import requests | |
| res = requests.post( | |
| "https://your-space.hf.space/visuals/chart/nft", | |
| json={ | |
| "data": { | |
| "name": "Bored Ape Yacht Club", | |
| "chain": "ethereum", | |
| "floor_price": 12.5, | |
| "floor_price_symbol": "ETH", | |
| "total_volume": 850000, | |
| "owner_count": 6400, | |
| "image_url": "https://example.com/nft.png" | |
| } | |
| } | |
| ) | |
| with open("nft_card.png", "wb") as f: | |
| f.write(res.content) | |
| ``` | |
| **Response:** `image/png` binary (800Γ400 px card) | |
| --- | |
| ### `POST /visuals/chart/arb` | |
| Crypto arbitrage monitor card. | |
| **JSON Body Parameters:** | |
| | Parameter | Type | Required | Description | | |
| |-----------|------|----------|-------------| | |
| | `coin` | string | β | Coin name (e.g. `BTC`) | | |
| | `exData` | array | β | Array of exchange objects | | |
| **Exchange object:** | |
| ```json | |
| { "name": "Binance", "price": 65800 } | |
| ``` | |
| ```python | |
| import requests | |
| res = requests.post( | |
| "https://your-space.hf.space/visuals/chart/arb", | |
| json={ | |
| "coin": "BTC", | |
| "exData": [ | |
| {"name": "Binance", "price": 65800}, | |
| {"name": "Bybit", "price": 65750}, | |
| {"name": "Kraken", "price": 65900}, | |
| {"name": "OKX", "price": 65820} | |
| ] | |
| } | |
| ) | |
| with open("arb_card.png", "wb") as f: | |
| f.write(res.content) | |
| ``` | |
| **Response:** `image/png` binary (900Γ600 px arbitrage card) | |
| --- | |
| ## ποΈ 2. Audio Engine | |
| ### `GET /audio_server/` | |
| Server status check. | |
| ```python | |
| import requests | |
| res = requests.get("https://your-space.hf.space/audio_server/") | |
| print(res.json()) | |
| ``` | |
| **Response:** | |
| ```json | |
| { | |
| "service": "Cipher-MD Audio Engine", | |
| "version": "3.0", | |
| "endpoints": ["/process", "/info", "/effects", "/trim"] | |
| } | |
| ``` | |
| --- | |
| ### `GET /audio_server/effects` | |
| Available effects list. | |
| ```python | |
| import requests | |
| res = requests.get("https://your-space.hf.space/audio_server/effects") | |
| print(res.json()) | |
| ``` | |
| **Response:** | |
| ```json | |
| { | |
| "effects": { | |
| "bass": ["bass_studio", "bass_edm", "bass_car", "bass_slap", "bass_heavy", "8d_bass"], | |
| "spatial": ["8d_audio", "3d_surround", "wide_stereo", "hall_reverb", "stadium"], | |
| "vocal": ["vocal_boost", "crystal_clear", "presence"], | |
| "creative": ["nightcore", "daycore", "slow_reverb", "vaporwave", "lofi_chill", | |
| "reverse", "underwater", "robot", "chipmunk", "telephone"], | |
| "mastering": ["compressor", "limiter", "loudness", "concert", "clean_master"] | |
| }, | |
| "level_range": "1-20 (bass effects only)", | |
| "formats": ["mp3", "ogg", "wav"] | |
| } | |
| ``` | |
| --- | |
| ### `POST /audio_server/info` | |
| Audio file metadata ΰΆΰΆ±ΰ·ΰΆ±ΰ·ΰ·. | |
| **Form-data Parameters:** | |
| | Parameter | Type | Required | Description | | |
| |-----------|------|----------|-------------| | |
| | `file` | file | β | MP3/WAV/OGG/MP4/any audio | | |
| ```python | |
| import requests | |
| with open("song.mp3", "rb") as f: | |
| res = requests.post( | |
| "https://your-space.hf.space/audio_server/info", | |
| files={"file": f} | |
| ) | |
| print(res.json()) | |
| ``` | |
| **Response:** | |
| ```json | |
| { | |
| "duration": 214.5, | |
| "size_bytes": 8621056, | |
| "bit_rate": 320000, | |
| "format": "mp3", | |
| "codec": "mp3", | |
| "sample_rate": "44100", | |
| "channels": 2, | |
| "title": "Shape of You", | |
| "artist": "Ed Sheeran" | |
| } | |
| ``` | |
| --- | |
| ### `POST /audio_server/process` | |
| Audio effect apply ΰΆΰΆ»ΰΆ±ΰ·ΰ·. | |
| **Form-data Parameters:** | |
| | Parameter | Type | Required | Default | Description | | |
| |-----------|------|----------|---------|-------------| | |
| | `file` | file | β | β | MP3/WAV/OGG audio file | | |
| | `effect` | string | β | `bass_studio` | Effect name (see `/effects`) | | |
| | `level` | int | β | `10` | Bass strength 1β20 (bass effects only) | | |
| | `output_format` | string | β | `mp3` | Output format: `mp3` / `ogg` / `wav` | | |
| | `use_dj_mix` | bool | β | `false` | Mix with `assets/intro.mp3` + `assets/outro.mp3` | | |
| **Effect Categories:** | |
| | Effect | Description | | |
| |--------|-------------| | |
| | `bass_studio` | Studio-quality bass boost | | |
| | `bass_edm` | EDM-style heavy bass | | |
| | `bass_car` | Deep sub-bass (car system) | | |
| | `bass_slap` | Punchy mid-bass slap | | |
| | `bass_heavy` | Maximum sub-bass | | |
| | `8d_audio` | 8D panning effect | | |
| | `8d_bass` | 8D + bass combo | | |
| | `3d_surround` | 3D surround simulation | | |
| | `wide_stereo` | Wide stereo widening | | |
| | `hall_reverb` | Concert hall reverb | | |
| | `stadium` | Stadium echo effect | | |
| | `vocal_boost` | Enhance vocals | | |
| | `crystal_clear` | Clarity boost | | |
| | `presence` | Mid presence boost | | |
| | `nightcore` | Fast + high pitch | | |
| | `daycore` | Slow + reverb | | |
| | `slow_reverb` | Slowed + reverb | | |
| | `vaporwave` | Vaporwave aesthetic | | |
| | `lofi_chill` | Lo-fi style | | |
| | `reverse` | Reverse audio | | |
| | `underwater` | Underwater effect | | |
| | `robot` | Robot voice | | |
| | `chipmunk` | Chipmunk high pitch | | |
| | `telephone` | Phone call effect | | |
| | `compressor` | Dynamic compression | | |
| | `limiter` | Peak limiter | | |
| | `loudness` | Broadcast loudness | | |
| | `concert` | Concert ambience | | |
| | `clean_master` | Professional master | | |
| ```python | |
| import requests | |
| # Simple bass boost | |
| with open("song.mp3", "rb") as f: | |
| res = requests.post( | |
| "https://your-space.hf.space/audio_server/process", | |
| files={"file": ("song.mp3", f, "audio/mpeg")}, | |
| data={ | |
| "effect": "bass_car", | |
| "level": "15", | |
| "output_format": "mp3" | |
| } | |
| ) | |
| with open("output.mp3", "wb") as out: | |
| out.write(res.content) | |
| ``` | |
| ```python | |
| # With DJ intro/outro mix (requires assets/intro.mp3 + assets/outro.mp3) | |
| with open("song.mp3", "rb") as f: | |
| res = requests.post( | |
| "https://your-space.hf.space/audio_server/process", | |
| files={"file": ("song.mp3", f, "audio/mpeg")}, | |
| data={ | |
| "effect": "bass_studio", | |
| "level": "12", | |
| "output_format": "mp3", | |
| "use_dj_mix": "true" | |
| } | |
| ) | |
| with open("dj_output.mp3", "wb") as out: | |
| out.write(res.content) | |
| ``` | |
| **Response:** `audio/mpeg` (or `audio/ogg` / `audio/wav`) binary | |
| **Filename header:** `Cipher_<effect>.mp3` | |
| **Error Responses:** | |
| ```json | |
| { "detail": "output_format must be mp3, ogg, or wav" } | |
| { "detail": "DJ Mix requires intro.mp3 and outro.mp3 in the assets folder. Set use_dj_mix=false to process without them." } | |
| { "detail": "FFmpeg processing failed: ..." } | |
| ``` | |
| --- | |
| ### `POST /audio_server/trim` | |
| Audio cut/trim + optional effect. | |
| **Form-data Parameters:** | |
| | Parameter | Type | Required | Default | Description | | |
| |-----------|------|----------|---------|-------------| | |
| | `file` | file | β | β | Audio file | | |
| | `start` | float | β | `0.0` | Start time in seconds | | |
| | `end` | float | β | `-1` | End time in seconds (-1 = until end) | | |
| | `output_format` | string | β | `mp3` | `mp3` / `ogg` / `wav` | | |
| | `effect` | string | β | `""` | Optional effect to apply after trim | | |
| | `level` | int | β | `10` | Bass level if effect is bass-type | | |
| ```python | |
| import requests | |
| # Trim 30s to 90s + apply nightcore | |
| with open("song.mp3", "rb") as f: | |
| res = requests.post( | |
| "https://your-space.hf.space/audio_server/trim", | |
| files={"file": ("song.mp3", f, "audio/mpeg")}, | |
| data={ | |
| "start": "30", | |
| "end": "90", | |
| "output_format": "mp3", | |
| "effect": "nightcore" | |
| } | |
| ) | |
| with open("trimmed.mp3", "wb") as out: | |
| out.write(res.content) | |
| ``` | |
| ```python | |
| # Trim only (no effect) β 0s to 60s | |
| with open("song.mp3", "rb") as f: | |
| res = requests.post( | |
| "https://your-space.hf.space/audio_server/trim", | |
| files={"file": ("song.mp3", f, "audio/mpeg")}, | |
| data={"start": "0", "end": "60"} | |
| ) | |
| with open("clip.mp3", "wb") as out: | |
| out.write(res.content) | |
| ``` | |
| **Response:** `audio/mpeg` binary, filename: `Cipher_trimmed.mp3` | |
| --- | |
| ## π 3. Sticker Engine | |
| ### `GET /cipher_sticker/` | |
| Server check. | |
| ```python | |
| import requests | |
| res = requests.get("https://your-space.hf.space/cipher_sticker/") | |
| print(res.text) # "π₯ Cipher_MD Smart Engine (Guaranteed < 1MB) Running!" | |
| ``` | |
| --- | |
| ### `POST /cipher_sticker/sticker` | |
| Single animated/static WhatsApp sticker generate ΰΆΰΆ»ΰΆ±ΰ·ΰ·. | |
| **Form-data Parameters:** | |
| | Parameter | Type | Required | Description | | |
| |-----------|------|----------|-------------| | |
| | `file` | file | β | Video (MP4/GIF/MOV/AVI/MKV/WEBM) or image (PNG/JPG) | | |
| | Any extra form field | string | β | Added as WebP metadata (e.g. `packname`, `author`) | | |
| > Auto-compresses to stay under **1MB** (WhatsApp limit). | |
| > Smart resize attempts: 512px β 384px β 320px β 256px. | |
| ```python | |
| import requests | |
| # Animated sticker from video | |
| with open("clip.mp4", "rb") as f: | |
| res = requests.post( | |
| "https://your-space.hf.space/cipher_sticker/sticker", | |
| files={"file": ("clip.mp4", f, "video/mp4")}, | |
| data={ | |
| "packname": "Cipher Stickers", # Optional metadata | |
| "author": "Cipher MD Bot" # Optional metadata | |
| } | |
| ) | |
| with open("sticker.webp", "wb") as out: | |
| out.write(res.content) | |
| ``` | |
| ```python | |
| # Static sticker from image | |
| with open("photo.png", "rb") as f: | |
| res = requests.post( | |
| "https://your-space.hf.space/cipher_sticker/sticker", | |
| files={"file": ("photo.png", f, "image/png")}, | |
| data={"author": "My Bot"} | |
| ) | |
| with open("static_sticker.webp", "wb") as out: | |
| out.write(res.content) | |
| ``` | |
| **Response:** `image/webp` binary (animated or static WebP, <1MB) | |
| **Error Responses:** | |
| ```json | |
| { "error": "No file uploaded" } | |
| { "error": "Failed to generate valid sticker" } | |
| ``` | |
| --- | |
| ### `POST /cipher_sticker/pack` | |
| Long video β multiple stickers pack (ZIP file). | |
| **Form-data Parameters:** | |
| | Parameter | Type | Required | Description | | |
| |-----------|------|----------|-------------| | |
| | `file` | file | β | Video file (max 2 minutes / 130 seconds) | | |
| | Any extra form field | string | β | Metadata for ALL stickers in pack (e.g. `packname`, `author`) | | |
| > Video is split into **10-second segments**, each compressed to <1MB. | |
| > Returns a **ZIP** containing numbered WebP files (1.webp, 2.webp, ...). | |
| ```python | |
| import requests | |
| # Generate sticker pack from 1-minute video | |
| with open("video.mp4", "rb") as f: | |
| res = requests.post( | |
| "https://your-space.hf.space/cipher_sticker/pack", | |
| files={"file": ("video.mp4", f, "video/mp4")}, | |
| data={ | |
| "packname": "Cipher Animated Pack", | |
| "author": "Cipher MD" | |
| } | |
| ) | |
| with open("sticker_pack.zip", "wb") as out: | |
| out.write(res.content) | |
| # Extract the ZIP | |
| import zipfile, io | |
| with zipfile.ZipFile(io.BytesIO(res.content)) as z: | |
| z.extractall("sticker_pack/") | |
| print("Stickers:", z.namelist()) # ['1.webp', '2.webp', '3.webp', ...] | |
| ``` | |
| **Response:** `application/zip` binary | |
| **Filename header:** `<uuid>.zip` | |
| **Error Responses:** | |
| ```json | |
| { "error": "No file uploaded" } | |
| { "error": "Video too long (Max 2 mins)" } | |
| ``` | |
| --- | |
| ## π 4. Scanner Engine | |
| ### `GET /scanner/` | |
| Server check. | |
| ```python | |
| import requests | |
| res = requests.get("https://your-space.hf.space/scanner/") | |
| print(res.json()) | |
| ``` | |
| **Response:** | |
| ```json | |
| { "message": "Cipher-MD Scanner Engine is Running! π" } | |
| ``` | |
| --- | |
| ### `POST /scanner/scan` | |
| Image watermark reveal/remove ΰΆΰΆ»ΰΆ±ΰ·ΰ·. | |
| **Form-data Parameters:** | |
| | Parameter | Type | Required | Description | | |
| |-----------|------|----------|-------------| | |
| | `image` | file | β | PNG/JPG image to scan | | |
| ```python | |
| import requests | |
| with open("suspicious_image.png", "rb") as f: | |
| res = requests.post( | |
| "https://your-space.hf.space/scanner/scan", | |
| files={"image": ("suspicious_image.png", f, "image/png")} | |
| ) | |
| if res.status_code == 200: | |
| with open("revealed.png", "wb") as out: | |
| out.write(res.content) | |
| else: | |
| print(res.json()) # {"error": "..."} | |
| ``` | |
| **Response:** `image/png` binary (revealed watermark image) | |
| **Error Responses:** | |
| ```json | |
| { "error": "Processing failed" } | |
| { "error": "<exception message>" } | |
| ``` | |
| --- | |
| ## π¦ Dependencies | |
| ### Node.js (Visuals + Gateway) | |
| ``` | |
| express, skia-canvas, multer, axios, | |
| wa-sticker-formatter, http-proxy-middleware | |
| ``` | |
| ### Python (Audio + Sticker + Scanner) | |
| ``` | |
| fastapi, uvicorn, python-multipart, aiofiles, | |
| flask, ffmpeg (system), ffprobe (system) | |
| ``` | |
| --- | |
| ## β‘ Notes | |
| - All heavy operations (audio processing, sticker generation) run with **auto temp file cleanup**. | |
| - The Gateway has **RAM monitoring** β requests are queued when free RAM < 500MB. | |
| - Gateway timeout: **5 minutes** per request. | |
| - Audio `level` parameter only affects bass-type effects (`bass_*`, `8d_bass`). For other effects it is ignored. | |
| - Sticker engine guarantees output **< 1MB** by progressively reducing quality and size. | |