neon-serverless
Unofficial Python serverless Postgres driver for Neon — SQL over HTTP, sync and async. Neon ships an official driver for JavaScript/TypeScript (@neondatabase/serverless); this is a community Python counterpart, not affiliated with or endorsed by Neon, Inc.
Instead of opening a TCP connection and speaking the Postgres wire protocol, every query is a single HTTPS request to Neon's SQL-over-HTTP endpoint. That makes it a great fit for:
- serverless functions (AWS Lambda, Vercel, Cloud Run, ...) where connections are short-lived
- environments where outbound TCP on port 5432 is blocked
- low-latency single-shot queries without connection setup cost
No libpq, no compiled extensions — the only dependency is httpx.
Install
pip install neon-serverless
Quickstart
import os
from neon_serverless import neon
sql = neon(os.environ["DATABASE_URL"])
rows = sql("SELECT * FROM posts WHERE author = $1", ["alice"])
# [{'id': 1, 'title': 'Hello', ...}, ...]
Async:
from neon_serverless import neon_async
sql = neon_async(os.environ["DATABASE_URL"])
rows = await sql("SELECT * FROM posts WHERE id = $1", [42])
Parameters
Use Postgres placeholders $1, $2, ... with a list of params. Supported Python types:
| Python | Sent as |
|---|---|
None, bool, int, float, str |
JSON scalar |
bytes |
bytea hex literal |
datetime, date, time |
ISO string |
Decimal |
string (exact) |
UUID |
string |
list / tuple |
Postgres array literal |
dict |
JSON text |
Result types
Values are decoded by Postgres type OID:
int2/int4/int8 → int (exact, no 2^53 limit), float4/float8 → float, numeric → Decimal, bool → bool, bytea → bytes, json/jsonb → dict/list, uuid → UUID, date/time/timestamp → naive datetime objects, timestamptz/timetz → timezone-aware, arrays → list. Anything else (including interval) stays a str. Values that can't be parsed (e.g. infinity timestamps, BC dates) fall back to their raw string.
Options
sql = neon(
conn_string,
full_results=False, # True: return FullQueryResults(command, row_count, rows, fields)
array_mode=False, # True: rows as lists instead of dicts
auth_token=None, # str or callable; sent as Authorization: Bearer (Neon RLS)
endpoint=None, # override SQL endpoint URL (default https://<host>/sql)
timeout=30.0,
)
res = sql("SELECT 1 AS x", full_results=True) # per-call override
res.command, res.row_count, res.rows, res.fields
Transactions
Multiple queries in one atomic HTTP request:
results = sql.transaction(
[
("INSERT INTO logs (msg) VALUES ($1)", ["hi"]),
"SELECT count(*) FROM logs",
],
isolation_level="Serializable", # ReadUncommitted | ReadCommitted | RepeatableRead | Serializable
read_only=False,
deferrable=False,
)
Queries run in a single transaction: all succeed or all roll back. Note there is no interactive BEGIN ... COMMIT — you must submit the whole batch up front (same constraint as the JS driver's transaction()).
Errors
Failed queries raise NeonDbError with the standard Postgres error fields:
from neon_serverless import NeonDbError
try:
sql("SELECT * FROM missing")
except NeonDbError as e:
print(e.code) # 42P01
print(e.severity) # ERROR
print(e.detail, e.hint, e.table, e.constraint, ...)
When NOT to use this
For long-running servers with steady traffic, a pooled TCP driver (psycopg or asyncpg) is faster per-query — Neon speaks standard Postgres too. This driver shines when connections are short-lived or TCP is unavailable.
Not yet supported (PRs welcome): WebSocket mode (full wire protocol with sessions, LISTEN/NOTIFY, cursors), COPY.
License
MIT
Metadata
Release files for neon-serverless 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| neon_serverless-0.1.0.tar.gz | 58.4 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| neon_serverless-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 70.2 kB
Release files / neon_serverless-0.1.0.tar.gz
| Download URL | neon_serverless-0.1.0.tar.gz |
|---|---|
| Size | 58.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
936fb8725f3a10e99e8a0331df228e4e0e333f663c1bee561d5046b45dcc2f01
|
|
BLAKE2b-256 checksum How to use checksums |
5465297306a952bee13dcef67d57294ff8e7ca7ccf783da05cc0f89cef49bde2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.4
|
Release files / neon_serverless-0.1.0-py3-none-any.whl
| Download URL | neon_serverless-0.1.0-py3-none-any.whl |
|---|---|
| Size | 11.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
db02b04079565fe4f692b9198b19f79149814e44b19cdd8bd7cc5ac7f82d26b8
|
|
BLAKE2b-256 checksum How to use checksums |
03a27158b13982dcd192b5b4dbf2e04c4a20698160203688aaa2cce6df4f5300
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.4
|
Security for neon-serverless 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.