Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
9aa0901
Add WASM compatibility for componentize-py builds
kesmit13 Mar 19, 2026
73dcaad
Add WIT interface definition for WASM UDF components
kesmit13 Mar 19, 2026
49521d1
Add type annotations to WASM numpy stub and UDF handler
kesmit13 Mar 20, 2026
5d1e9e6
Add code generation for UDF handler function registration
kesmit13 Mar 23, 2026
aed95df
Replace top-level optional imports with lazy import helpers
kesmit13 Mar 23, 2026
24df239
Fix Python 3.10+ union syntax in udf_handler type annotation
kesmit13 Mar 23, 2026
5eef5fd
feat: add call_function_accel C function to accel.c
kesmit13 Mar 23, 2026
0e4bb40
Add WASM build script for wasm32-wasip2 target
kesmit13 Mar 25, 2026
a18eb52
Remove WASM numpy_stub, now unnecessary with lazy imports
kesmit13 Mar 25, 2026
248f897
Add collocated Python UDF server with pre-fork process mode
kesmit13 Mar 27, 2026
e4d8627
Fix @@register propagation in collocated server process mode
kesmit13 Mar 31, 2026
1b90ab6
Fix broken pipe in collocated UDF server under concurrent load
kesmit13 Apr 1, 2026
c732dff
Guard np.dtype check in normalize_dtype for environments without numpy
kesmit13 Apr 1, 2026
1b62a6c
Guard WASI-incompatible POSIX APIs in accel.c with #ifndef __wasi__
kesmit13 Apr 1, 2026
c65793a
Call setup_logging() in FunctionHandler.initialize() for WASM handler
kesmit13 Apr 1, 2026
b66653a
Add WASI stubs for mmap_read/mmap_write/recv_exact and fix accel logging
kesmit13 Apr 1, 2026
34e2452
Address PR #121 review comments: memory safety, correctness, hardening
kesmit13 Apr 2, 2026
fe1d8ad
Fix recv_exact protocol desync and unchecked PyObject_Length returns
kesmit13 Apr 2, 2026
548edcc
Fix _iquery DataFrame conversion for non-tuple results_type
kesmit13 Apr 2, 2026
2753f6e
Fix MYSQL_TYPE_NULL data pointer advancement in call_function_rowdat_1
kesmit13 Apr 7, 2026
8aa88c0
Fix missing PyErr_Occurred checks in call_function_accel
kesmit13 Apr 8, 2026
a7fb74d
Add decimal, datetime, date, and time type support across all UDF paths
kesmit13 Apr 9, 2026
f3d069a
Lazy-load IPython in singlestoredb.utils.events
kesmit13 Apr 9, 2026
5dfacae
Fix refcount leak, unaligned reads, and YEAR type mismatch in accel.c
kesmit13 Apr 9, 2026
a22fc43
Enable VECTOR type with element type validation in dtypes
kesmit13 Apr 10, 2026
4c7fb60
Add JSON wire format type conversions for UDF data types
kesmit13 Apr 10, 2026
87e9253
Restore socket timeout after partial-read recovery in _recv_exact_py
kesmit13 Apr 10, 2026
5de453c
Rename collocated UDF package to plugin
kesmit13 Apr 14, 2026
14d5e83
Update docs and plugin/ terminology after collocated→plugin rename
kesmit13 Apr 14, 2026
3043c59
Add missing -MYSQL_TYPE_BLOB case in numpy sizing pass
kesmit13 Apr 15, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 65 additions & 21 deletions ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,14 @@ singlestoredb/
│ ├── mmap.py # Memory-mapped execution
│ ├── json.py # JSON serialization
│ ├── rowdat_1.py # ROWDAT_1 format
│ └── arrow.py # Apache Arrow format
│ ├── arrow.py # Apache Arrow format
│ └── plugin/ # Plugin UDF server (Unix socket)
│ ├── __main__.py # CLI entry point
│ ├── server.py # Socket server with thread/process pool
│ ├── connection.py # Connection handling
│ ├── control.py # Control protocol
│ ├── registry.py # Function registry & discovery
│ └── wasm.py # WASM component interface
├── ai/ # AI/ML integration
│ ├── chat.py # Chat completion factory
Expand Down Expand Up @@ -603,9 +610,9 @@ Located in `singlestoredb/fusion/handlers/`:
## External Functions (UDFs)

The functions module (`singlestoredb/functions/`) enables deploying Python functions
as SingleStore external functions. UDF servers can be deployed as HTTP using
an ASGI application or a collocated socket server that uses mmap files to
transfer data.
as SingleStore external functions. UDF servers can be deployed in three modes: as HTTP using an ASGI application
(remote), a memory-mapped collocated server (lowest latency), or as a plugin
server using Unix sockets with a thread/process pool (CLI-driven).

### Architecture

Expand All @@ -629,6 +636,7 @@ transfer data.
├─────────────────────────────────────────────────────────────────────┤
│ asgi.py │ HTTP server via ASGI (Uvicorn; JSON or ROWDAT_1) │
│ mmap.py │ Memory-mapped shared memory (collocated; ROWDAT_1) │
│ plugin/ │ Plugin UDF server (Unix socket + thread/process pool) │
│ json.py │ JSON serialization over HTTP │
│ rowdat_1.py│ ROWDAT_1 binary format │
│ arrow.py │ Apache Arrow columnar format │
Expand Down Expand Up @@ -659,6 +667,33 @@ python -m singlestoredb.functions.ext.asgi \
my_functions
```

### Plugin Server CLI

The plugin server can be launched via the CLI for Unix socket-based UDF serving:

```bash
# Launch the plugin server
python -m singlestoredb.functions.ext.plugin \
--plugin-name myfuncs \
--search-path /home/user/libs \
--socket /tmp/my-udf.sock

# Or use the console_scripts entry point
python-udf-server --plugin-name myfuncs
```

**CLI Arguments:**

| Argument | Env Variable | Default | Description |
|----------|-------------|---------|-------------|
| `--plugin-name` | `PLUGIN_NAME` | (required) | Python module to import |
| `--search-path` | `PLUGIN_SEARCH_PATH` | `""` | Colon-separated search dirs for the module |
| `--socket` | `PLUGIN_SOCKET_PATH` | auto-generated | Unix socket path |
| `--n-workers` | `PLUGIN_N_WORKERS` | `0` (CPU count) | Worker threads/processes |
| `--max-connections` | `PLUGIN_MAX_CONNECTIONS` | `32` | Socket backlog |
| `--log-level` | `PLUGIN_LOG_LEVEL` | `info` | Logging level (debug/info/warning/error) |
| `--process-mode` | `PLUGIN_PROCESS_MODE` | `process` | Concurrency mode: `thread` or `process` |

### Type Mapping

The `signature.py` module maps Python types to SQL types:
Expand All @@ -682,29 +717,30 @@ The `signature.py` module maps Python types to SQL types:
┌─────────────────────────────────────────────────────────────────────┐
│ SingleStore Database │
└─────────────────────────────────────────────────────────────────────┘
│ │
│ ASGI/HTTP │ Memory-mapped
│ (remote) │ (collocated)
▼ ▼
┌─────────────┐ ┌─────────────┐
│ asgi.py │ │ mmap.py │
│ Uvicorn │ │ Shared │
│ HTTP/2 │ │ Memory │
└─────────────┘ └─────────────┘
│ │
└────────────────────┘
┌─────────────────┐
│ Python UDF │
│ Functions │
└─────────────────┘
│ │
│ ASGI/HTTP │ Memory-mapped │ Plugin
│ (remote) │ (collocated) │ (Unix socket)
▼ ▼
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ asgi.py │ │ mmap.py │ │ plugin/ │
│ Uvicorn │ │ Shared │ │ Unix sock │
│ HTTP/2 │ │ Memory │ │ + pool │
└─────────────┘ └─────────────┘ └─────────────┘
│ │
└────────────────────┴────────────────────
┌─────────────────┐
│ Python UDF │
│ Functions │
└─────────────────┘
```

| Mode | File | Use Case |
|------|------|----------|
| ASGI | `asgi.py` | Remote execution via HTTP, scalable |
| Memory-mapped | `mmap.py` | Collocated execution, lowest latency |
| Plugin | `plugin/` | Unix socket server, thread/process pool, CLI-driven |
| JSON | `json.py` | Simple serialization, debugging |
| ROWDAT_1 | `rowdat_1.py` | Binary format, efficient |
| Arrow | `arrow.py` | Columnar format, analytics |
Expand Down Expand Up @@ -1043,6 +1079,13 @@ with free_tier.start() as server:
| `SINGLESTOREDB_MANAGEMENT_TOKEN` | Management API token | None |
| `SINGLESTORE_LICENSE` | License key for Docker | None |
| `USE_DATA_API` | Use HTTP API for tests | 0 |
| `PLUGIN_NAME` | Plugin server: Python module to import | None |
| `PLUGIN_SEARCH_PATH` | Plugin server: colon-separated module search dirs | `""` |
| `PLUGIN_SOCKET_PATH` | Plugin server: Unix socket path | auto-generated |
| `PLUGIN_N_WORKERS` | Plugin server: worker count (0 = CPU count) | `0` |
| `PLUGIN_MAX_CONNECTIONS` | Plugin server: socket backlog | `32` |
| `PLUGIN_LOG_LEVEL` | Plugin server: logging level | `info` |
| `PLUGIN_PROCESS_MODE` | Plugin server: `thread` or `process` | `process` |

### B. Cursor Type Matrix

Expand Down Expand Up @@ -1096,4 +1139,5 @@ Feature options:
| Management API | `singlestoredb/management/workspace.py` |
| Fusion handlers | `singlestoredb/fusion/handler.py` |
| UDF decorator | `singlestoredb/functions/decorator.py` |
| Plugin UDF server | `singlestoredb/functions/ext/plugin/server.py` |
| Test fixtures | `singlestoredb/pytest.py` |
4 changes: 4 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,10 @@ pytest -v --cov=singlestoredb.connection singlestoredb/tests/test_connection.py
# Test UDF functionality
pytest singlestoredb/tests/test_udf.py

# Manual testing of the plugin UDF server
python -m singlestoredb.functions.ext.plugin \
--plugin-name myfuncs --search-path /path/to/modules

# Test against specific server (skips Docker)
SINGLESTOREDB_URL=admin:pass@localhost:3306 pytest -v singlestoredb/tests

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ analytics and vector search.
- **Vector Store**: Pinecone-compatible vector database API for similarity search
applications with built-in connection pooling
- **User-Defined Functions**: Deploy Python functions as SingleStore UDFs with
automatic type mapping
automatic type mapping (HTTP/ASGI or plugin-mode via CLI)
- **SQLAlchemy Support**: Integrate with SQLAlchemy through the optional
`sqlalchemy-singlestoredb` adapter
- **Fusion SQL**: Extend SQL with custom client-side command handlers
Expand Down
Loading
Loading