WebDuck: DuckDB as a Service

theanonymousone1 pts0 comments

WebDuck - DuckDB as a Service with REST API and Web UI<br>WebDuck<br>DuckDB as a Service<br>Fast, simple DuckDB-as-a-Service with REST API and Web UI. Install via pip, deploy with Docker, query your data in seconds.<br>Get StartedView on GitHub

Web UI<br>Projects

Browse View

Quickstart<br>pip<br>pip install webduck# Unix<br>pipx install webduck# macOS

Docker<br>docker run --name webduck<br>-p 8998:8998<br>-v webduck_data:/app/data<br>-e WEBDUCK_ADMIN_USER=admin<br>-e WEBDUCK_ADMIN_PASS=secret<br>autumoswitzerland/webduck

Terminal

Features

REST API<br>Full REST API with JWT auth, optional DB passwords, and project management.

Web UI<br>Dark-mode interface with SQL editor, data browser, and CSV, Parquet, JSON import/export.

DuckDB Engine<br>Built on DuckDB with file-locking for safe concurrent access and fast analytics.

SQL Upload<br>Execute multi-statement SQL scripts from files with sequential execution.

Import/Export<br>CSV, Parquet and JSON import via drag & drop, one-click export with browser download.

i18n<br>English + German out of the box, extensible via PO/Gettext.

API Examples<br>Query your data from any language<br>cURLPythonPHPJava<br># Login - get JWT token<br>TOKEN=$(curl -s -X POST http://localhost:8998/admin/login \<br>-H "Content-Type: application/json" \<br>-d '{"username": "admin", "password": "secret"}' | jq -r '.access_token')

# Create a project<br>curl -X POST http://localhost:8998/admin/projects \<br>-H "Authorization: Bearer $TOKEN" \<br>-H "Content-Type: application/json" \<br>-d '{"name": "myproject"}'

# Create a database<br>curl -X POST http://localhost:8998/admin/projects/myproject/databases \<br>-H "Authorization: Bearer $TOKEN" \<br>-H "Content-Type: application/json" \<br>-d '{"name": "mydb"}'

# Set DB password (optional — without it, API is open)<br>curl -X PUT http://localhost:8998/admin/projects/myproject/databases/mydb/password \<br>-H "Authorization: Bearer $TOKEN" \<br>-H "Content-Type: application/json" \<br>-d '{"password":"dbpass","access_level":"write"}'

# Query data — no password = open<br>curl -X POST http://localhost:8998/db/myproject/mydb/query \<br>-H "Content-Type: application/json" \<br>-d '{"sql": "SELECT * FROM users LIMIT 10"}'

# Query with DB password set<br>curl -X POST http://localhost:8998/db/myproject/mydb/query \<br>-H "Content-Type: application/json" \<br>-H "X-Project-Key: myproject:dbpass" \<br>-d '{"sql": "SELECT * FROM users LIMIT 10"}'<br>import requests

BASE = "http://localhost:8998"

# Login<br>token = requests.post(<br>f"{BASE}/admin/login",<br>json={"username": "admin", "password": "secret"}<br>).json()["access_token"]<br>headers = {"Authorization": f"Bearer {token}"}

# Create project<br>requests.post(f"{BASE}/admin/projects",<br>json={"name": "myproject"}, headers=headers)

# Create database<br>requests.post(f"{BASE}/admin/projects/myproject/databases",<br>json={"name": "mydb"}, headers=headers)

# Set DB password (optional)<br>requests.put(f"{BASE}/admin/projects/myproject/databases/mydb/password",<br>json={"password": "dbpass", "access_level": "write"}, headers=headers)

# Query data — no password = open<br>result = requests.post(f"{BASE}/db/myproject/mydb/query",<br>json={"sql": "SELECT * FROM users LIMIT 10"})<br>print(result.json())

# Query with DB password set<br>result = requests.post(f"{BASE}/db/myproject/mydb/query",<br>json={"sql": "SELECT * FROM users LIMIT 10"},<br>headers={"X-Project-Key": "myproject:dbpass"})<br>print(result.json())<br>php<br>// Login<br>$login = http_post_json(<br>"http://localhost:8998/admin/login",<br>["username" => "admin", "password" => "secret"]<br>);<br>$token = json_decode($login, true)['access_token'];<br>$headers = ["Authorization: Bearer $token"];

// Create project<br>http_post_json(<br>"http://localhost:8998/admin/projects",<br>["name" => "myproject"], $headers<br>);

// Create database<br>http_post_json(<br>"http://localhost:8998/admin/projects/myproject/databases",<br>["name" => "mydb"], $headers<br>);

// Set DB password (optional)<br>http_put_json(<br>"http://localhost:8998/admin/projects/myproject/databases/mydb/password",<br>["password" => "dbpass", "access_level" => "write"], $headers<br>);

// Query data — no password = open<br>$response = http_post_json(<br>"http://localhost:8998/db/myproject/mydb/query",<br>["sql" => "SELECT * FROM users LIMIT 10"]<br>);<br>print_r(json_decode($response, true));

// Query with DB password set<br>$response = http_post_json(<br>"http://localhost:8998/db/myproject/mydb/query",<br>["sql" => "SELECT * FROM users LIMIT 10"],<br>["X-Project-Key: myproject:dbpass"]<br>);<br>print_r(json_decode($response, true));<br>var client = HttpClient.newHttpClient();<br>var base = "http://localhost:8998";

// Login<br>var loginReq = HttpRequest.newBuilder()<br>.uri(URI.create(base + "/admin/login"))<br>.header("Content-Type", "application/json")<br>.POST(HttpRequest.BodyPublishers.ofString(<br>"{\"username\": \"admin\", \"password\": \"secret\"}"))<br>.build();<br>var token = JsonParser.parseString(<br>client.send(loginReq, HttpResponse.BodyHandlers.ofString()).body())<br>.getAsJsonObject().get("access_token").getAsString();

// Create project<br>client.send(HttpRequest.newBuilder()<br>.uri(URI.create(base + "/admin/projects"))<br>.header("Content-Type",...

admin password json myproject query http

Related Articles