Quackflight
DuckDB API Server with Arrow Flight SQL Airport support and concurrent writes/reads (quackpipe)
Install / Use
/learn @quackscience/QuackflightREADME
:baby_chick: QuackFlight
Serverless OLAP API built on top of DuckDB exposing HTTP/S and Arrow Flight SQL interfaces
<br>[!IMPORTANT]
- Arrow Flight API for modern data clients (DuckDB Airport)
- Easy HTTP API with multiple formats (JSON,CSV,Parquet)
- Unlocked Concurrent inserts and querying on DuckDB
- Persistent storage using w/ multiuser authentication
- Native access to any DuckDB Extension & Format
- Embedded SQL Query Interface for instant usage
:seedling: Get Started
Run using docker or build from source
docker pull ghcr.io/quackscience/quackflight:latest
docker run -ti --rm -p 8123:8123 -p 8815:8815 ghcr.io/quackscience/quackflight:latest
👉 Usage
See the Examples directory for quick starters
<br>[!NOTE] Quackpipe executes queries in
:memory:unless authentication details are provided for data persistence
🕸️ HTTP API
Execute DuckDB queries using the HTTP POST/GET API (compatible with the ClickHouse HTTP API)
curl -X POST "http://user:persistence@localhost:8123" \
-H "Content-Type: application/json" \
-d 'SELECT version()'
<br>
<img src="https://github.com/user-attachments/assets/deddab90-e409-4b1b-881f-d53f02597a1d" width=80 />
✈️ FLIGHT API
Execute DuckDB queries using the experimental Flight GRPC API and Airport
[!NOTE] Quackpipe executes queries in
:memory:unless anauthorizationheader is provided for data persistence
🎫 Pass Airport Security
CREATE PERSISTENT SECRET airport_flight (
· type airport,
‣ auth_token 'user:persistence',
· scope 'grpc://localhost:8815'
· );
🎫 Take Airport Flights
D select flight_descriptor, endpoint from airport_list_flights('grpc://127.0.0.1:8815', null);
┌─────────────────────────────────┬────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ flight_descriptor │ endpoint │
│ union(cmd blob, path varchar[]) │ struct(ticket blob, "location" varchar[], expiration_time timestamp, app_metadata blob)[] │
├─────────────────────────────────┼────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ show_databases │ [{'ticket': SHOW DATABASES, 'location': [grpc://localhost:8815], 'expiration_time': NULL, 'app_metadata': }] │
│ show_tables │ [{'ticket': SHOW TABLES, 'location': [grpc://localhost:8815], 'expiration_time': NULL, 'app_metadata': }] │
│ show_version │ [{'ticket': SELECT version(), 'location': [grpc://localhost:8815], 'expiration_time': NULL, 'app_metadata': }] │
└─────────────────────────────────┴────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
D select * from airport_take_flight('grpc://localhost:8815/', ['show_version']);
┌─────────────┐
│ "version"() │
│ varchar │
├─────────────┤
│ v1.2.0 │
└─────────────┘
🎫 ATTACH Flights Tables
D --- Attach to Flight Server
D ATTACH 'deltalake' (TYPE AIRPORT, location 'grpc://localhost:8815/');
D --- Create Schema + Table
D CREATE SCHEMA deltalake.test1;
D CREATE TABLE deltalake.test1.people (
name VARCHAR,
love_of_duckdb INT,
tags VARCHAR[]
);
D --- Insert into Flight Table
D INSERT INTO deltalake.test1.people values
('rusty', 5, ['airport', 'datasketches']);
D --- Select from Flight Table
D SELECT * FROM deltalake.test1.people;
┌─────────┬────────────────┬─────────────────────────┐
│ name │ love_of_duckdb │ tags │
│ varchar │ int32 │ varchar[] │
├─────────┼────────────────┼─────────────────────────┤
│ rusty │ 5 │ [airport, datasketches] │
├─────────┴────────────────┴─────────────────────────┤
│ 1 row. 3 columns │
└────────────────────────────────────────────────────┘
Flight Tables can be accessed via HTTP API using the schema name
USE test1; SELECT * FROM people;
🎫 Take Custom Flights w/ Custom Headers + Ticket
D SELECT * FROM airport_take_flight('grpc://localhost:8815', 'SELECT 1', headers := MAP{'authorization':'user:persistence'} );
┌───────┐
│ 1 │
│ int32 │
├───────┤
│ 1 │
└───────┘
🎫 Take Python Flights
from pyarrow.flight import FlightClient, Ticket, FlightCallOptions
import json
import pandas
import tabulate
sql="""SELECT version()"""
flight_ticket = Ticket(sql)
token = (b"authorization", bytes(f"user:persistence".encode('utf-8')))
options = FlightCallOptions(headers=[token])
client = FlightClient(f"grpc://localhost:8815")
reader = client.do_get(flight_ticket, options)
arrow_table = reader.read_all()
# Use pyarrow and pandas to view and analyze data
data_frame = arrow_table.to_pandas()
print(data_frame.to_markdown())
| | "version"() |
|---:|:--------------|
| 0 | v1.2.0 |
<br>
📺 SQL User-Interface
quackflight ships with the DuckDB SQL quack user-interface based on duck-ui
<a href="https://quackpy.fly.dev"> <img src="https://github.com/user-attachments/assets/902a6336-c4f4-4a4e-85d5-78dd62cb7602"> </a>
sequenceDiagram
participant Client
participant QuackFlight
participant DuckDB
Client ->> QuackFlight: ListFlights
QuackFlight ->> Client: Return Flights Table
Client ->> QuackFlight: GetFlightInfo
QuackFlight ->> DuckDB: DuckDB Execute
DuckDB ->> QuackFlight: Arrow Results Stream
QuackFlight ->> Client: FlightInfo(ticket)
Client ->> QuackFlight: do_get(ticket)
QuackFlight ->> Client: Stream of Results
<br>
:black_joker: Disclaimers
[^1]: DuckDB ® is a trademark of DuckDB Foundation. All rights reserved by their respective owners. [^1] [^2]: ClickHouse ® is a trademark of ClickHouse Inc. No direct affiliation or endorsement. [^2] [^3]: Released under the MIT license. See LICENSE for details. All rights reserved by their respective owners. [^3] [^4]: Flight implementation inspired by Duck Takes Flight [^4]
Related Skills
gh-issues
341.2kFetch GitHub issues, spawn sub-agents to implement fixes and open PRs, then monitor and address PR review comments. Usage: /gh-issues [owner/repo] [--label bug] [--limit 5] [--milestone v1.0] [--assignee @me] [--fork user/repo] [--watch] [--interval 5] [--reviews-only] [--cron] [--dry-run] [--model glm-5] [--notify-channel -1002381931352]
oracle
341.2kBest practices for using the oracle CLI (prompt + file bundling, engines, sessions, and file attachment patterns).
tmux
341.2kRemote-control tmux sessions for interactive CLIs by sending keystrokes and scraping pane output.
xurl
341.2kA CLI tool for making authenticated requests to the X (Twitter) API. Use this skill when you need to post tweets, reply, quote, search, read posts, manage followers, send DMs, upload media, or interact with any X API v2 endpoint.
