Python client driver for Fauna
Version: 2.0.0 | Repository: fauna/fauna-python |
---|
Fauna’s Python client driver lets you run FQL queries from Python applications.
This guide shows how to set up the driver and use it to run FQL queries. The examples use Fauna’s demo data.
This driver can only be used with FQL v10. It’s not compatible with earlier versions of FQL. To use earlier FQL versions, use the faunadb package. |
Installation
The driver is available on PyPI. To install it, run:
pip install fauna
Basic usage
The following application:
-
Initializes a client instance to connect to Fauna
-
Composes a basic FQL query using an
fql
template -
Runs the query using
Client.query()
from fauna import fql
from fauna.client import Client
from fauna.encoding import QuerySuccess
from fauna.errors import FaunaException
# Initialize the client to connect to Fauna
client = Client(secret='YOUR_FAUNA_SECRET')
try:
# Compose a query
query = fql(
"""
Product.sortedByPriceLowToHigh() {
name,
description,
price
}"""
)
# Run the query
res: QuerySuccess = client.query(query)
print(res.data)
except FaunaException as e:
print(e)
finally:
# Clean up any remaining resources
client.close()
Connect to Fauna
To connect to Fauna, initialize a Client
instance using a Fauna key,
access token, or JWT:
client = Client(secret='YOUR_FAUNA_SECRET') # Your key, access token, or JWT
If not specified, secret
defaults to the FAUNA_SECRET
environment variable.
For other configuration options, see Client configuration.
Multiple connections
You can use a single client instance to run multiple asynchronous queries at once. The driver manages HTTP connections as needed. Your app doesn’t need to implement connection pools or other connection management strategies.
You can create multiple client instances to connect to Fauna using different credentials or client configurations.
Run FQL queries
Use fql
templates to compose FQL queries. Run the queries using
Client.query()
:
query = fql("Product.sortedByPriceLowToHigh()")
client.query(query)
By default, Client.query()
uses query options from the
Client configuration. You can pass options to Client.query()
to override
these defaults. See Query options.
Variable interpolation
The driver supports queries with Python primitives, lists, and dicts.
Use ${}
to pass native Python variables to fql
queries as
kwargs. You can escape a variable by prepending an additional $
.
# Create a native Python var
collection_name = 'Product'
# Pass the var to an FQL query
query = fql('''
let collection = Collection(${collection_name})
collection.sortedByPriceLowToHigh()''',
collection_name=collection_name)
client.query(query);
Passed variables are encoded to an appropriate type and passed to Fauna’s HTTP API. This helps prevent injection attacks.
Subqueries
You can use native variables to pass an FQL query to another FQL query. This lets you create reusable subqueries:
# Create a reusable FQL subquery
def get_product(name):
return fql(
'Product.byName(${name}).first()',
name=name)
# Use the subquery in another FQL query
query = fql('''
let product = ${get_product}
product?.update({
name: "pizza pie"
})''',
get_product=get_product('pizza'))
client.query(query);
Pagination
Use Client.paginate()
to iterate a set that contains more than one page of
results. Client.paginate()
accepts the same Query options as
Client.query()
.
# Adjust `pageSize()` size as needed.
query = fql('''
Product.sortedByPriceLowToHigh()
.pageSize(2)''')
pages = client.paginate(query);
for products in pages:
for product in products:
print(products)
Query statistics
Successful query responses and ServiceError
errors return
query statistics:
from fauna import fql
from fauna.client import Client
from fauna.errors import ServiceError
client = Client(secret='YOUR_FAUNA_SECRET')
try:
query = fql('"Hello world"')
res = client.query(query)
print(res.stats)
except ServiceError as e:
if e.stats is not None:
print(e.stats)
# more error handling...
User-defined classes
Serialization and deserialization with user-defined classes is not supported.
When composing FQL queries, adapt your classes into dicts or lists. When instantiating classes from a query result, build them from the expected result.
class MyClass:
def __init__ (self, my_prop):
self.my_prop = my_prop
def to_dict(self):
return { 'my_prop': self.my_prop }
@static_method
def from_result(obj):
return MyClass(obj['my_prop'])
Client configuration
The Client
instance comes with reasonable configuration defaults. We recommend
using the defaults in most cases.
If needed, you can configure the client to override the defaults. This also lets you set default Query options.
from datetime import timedelta
from fauna.client import Client
from fauna.client.headers import Header
from fauna.client.endpoints import Endpoints
config = {
# Configure the client
'secret': 'YOUR_FAUNA_SECRET',
'endpoint': Endpoints.Default,
'client_buffer_timeout': timedelta(seconds=5),
'http_read_timeout': None,
'http_write_timeout': timedelta(seconds=5),
'http_connect_timeout': timedelta(seconds=5),
'http_pool_timeout': timedelta(seconds=5),
'http_idle_timeout': timedelta(seconds=5),
'max_attempts': 3,
'max_backoff': 20,
# Set default query options
'additional_headers': {'foo': 'bar'},
'linearized': False,
'max_contention_retries': 5,
'query_tags': {'name': 'hello world query'},
'query_timeout': timedelta(seconds=60),
'typecheck': True,
}
client = Client(**config)
The following table outlines supported parameters for the Client()
constructor
and their defaults.
Parameter | Type | Required | Description | ||
---|---|---|---|---|---|
|
|
Yes |
Fauna key, access token, or JWT used to authorize requests. Defaults to the
|
||
|
|
URL for the Fauna endpoint. Defaults to the |
|||
|
|
Additional time beyond the query timeout for the driver to abort if no
response is received. Used to account for network latency. Defaults to
If a client timeout occurs, the driver throws an instance of |
|||
|
|
Maximum time the driver waits to receive data, such as a chuck of the response
body, from Fauna after sending a request. Defaults to
If a read timeout occurs, the driver throws an instance of
|
|||
|
|
Maximum time the driver waits to send to Fauna over the network. Defaults
to If a write timeout occurs, the driver throws an instance of
|
|||
|
|
Maximum time to wait for the connection to Fauna to complete. Defaults to
If a connection timeout occurs, the driver throws an instance of
|
|||
|
|
Maximum time the driver waits to get a connection from the connection pool.
Defaults to A timeout may occur if 20 connections are currently in use and one isn’t
released before the timeout. If a connection pool timeout occurs, the driver
throws an instance of |
|||
|
|
Maximum amount of time an idle (keep-alive) connection remains open before
closing. Defaults to
|
|||
|
|
Maximum number of retry attempts for a query. Defaults to To disable retries, set |
|||
|
|
Maximum time, in seconds, to wait before retrying a query if the request returns a 429 HTTP status code. Defaults to 20 seconds. |
|||
|
|
Additional HTTP headers to include in requests. Defaults to |
|||
|
|
If Maps to the |
|||
|
|
Maximum number of times Fauna retries a query after a contention error.
These are server-side retries. Defaults to Maps to the
|
|||
|
|
Key-value tags used to identify the query. Defaults to Query tags are included in query logs and the response body for successful queries. The tags are typically used for monitoring. Maps to the |
|||
|
|
Maximum amount of time Fauna runs a query before marking it as failed.
Defaults to Maps to the If a query timeout occurs, the driver throws an instance of
|
|||
|
|
If If Maps to the |
Environment variables
By default, secret
and endpoint
default to the respective FAUNA_SECRET
and
FAUNA_ENDPOINT
environment variables.
For example, if you set the following environment variables:
export FAUNA_SECRET=YOUR_FAUNA_SECRET
export FAUNA_ENDPOINT=https://db.fauna.com/
You can initialize the client with a default configuration:
client = Client()
Retries
By default, the client automatically retries a query if the request returns a 429 HTTP status code. Retries use an exponential backoff.
Use the Client configuration's max_backoff
parameter to set the maximum
time between retries. Similarly, use max_attempts
to set the maximum number of
retry attempts.
Query options
The Client configuration sets default query options for the following methods:
-
Client.query()
-
Client.paginate()
You can pass an QueryOptions
argument to override these defaults:
options = QueryOptions(
additional_headers={'foo': 'bar'},
linearized=False,
max_contention_retries=5,
query_tags={'name': 'hello world query'},
query_timeout=timedelta(seconds=60),
traceparent='00-750efa5fb6a131eb2cf4db39f28366cb-000000000000000b-00',
typecheck=True
)
client.query(fql('"Hello world"'), options)
The following table outlines supported properties for the QueryOptions
class.
Property | Type | Required | Description |
---|---|---|---|
|
|
Additional HTTP headers to include in the request. |
|
|
|
If Maps to the |
|
|
|
Maximum number of times Fauna retries the query after a contention error. These are server-side retries. Maps to the
|
|
|
|
Key-value tags used to identify the query. Query tags are included in query logs and the response body for successful queries. The tags are typically used for monitoring. Maps to the |
|
|
|
Maximum amount of time Fauna runs the query before marking it as failed. Maps to the If a query timeout occurs, the driver throws an instance of
|
|
|
|
W3C-compliant traceparent ID for the request. If you provide an invalid
traceparent ID, Fauna generates a valid one. Defaults to The traceparent ID is included in query logs. Traceparent IDs are typically used for monitoring. |
|
|
|
If If Maps to the |
Event Streaming
The driver supports Event Streaming.
Start a stream
To get a stream token, append
toStream()
or
changesOn()
to a set from a
supported
source.
To start and subscribe to the stream, pass the stream token to
Client.stream()
:
import fauna
from fauna import fql
from fauna.client import Client, StreamOptions
client = Client(secret='YOUR_FAUNA_SECRET')
response = client.query(fql('''
let set = Product.all()
{
initialPage: set.pageSize(10),
streamToken: set.toStream()
}
'''))
initialPage = response.data['initialPage']
streamToken = response.data['streamToken']
client.stream(streamToken)
You can also pass a query that produces a stream token directly to
Client.stream()
:
query = fql('Product.all().changesOn(.price, .quantity)')
client.stream(query)
Iterate on a stream
Client.stream()
returns an iterator that emits events as they occur.
You can use a generator expression to iterate through the events:
query = fql('Product.all().changesOn(.price, .quantity)')
with client.stream(query) as stream:
for event in stream:
eventType = event['type']
if (eventType == 'add'):
print('Add event: ', event)
## ...
elif (eventType == 'update'):
print('Update event: ', event)
## ...
elif (eventType == 'remove'):
print('Remove event: ', event)
## ...
Close a stream
Use <stream>.close()
to close a stream:
query = fql('Product.all().changesOn(.price, .quantity)')
count = 0
with client.stream(query) as stream:
for event in stream:
print('Stream event', event)
# ...
count+=1
if (count == 2):
stream.close()
Error handling
If a non-retryable error occurs when opening or processing a stream, Fauna
raises a FaunaException
:
import fauna
from fauna import fql
from fauna.client import Client
from fauna.errors import FaunaException
client = Client(secret='YOUR_FAUNA_SECRET')
try:
with client.stream(fql(
'Product.all().changesOn(.price, .quantity)'
)) as stream:
for event in stream:
print(event)
# ...
except FaunaException as e:
print('error ocurred with stream: ', e)
Stream options
The Client configuration sets default options for the
Client.stream()
method.
You can pass a StreamOptions
object to override these defaults:
options = StreamOptions(
max_attempts=5,
max_backoff=1,
start_ts=1710968002310000,
status_events=True
)
client.stream(fql('Product.all().toStream()'), options)
The following table outlines supported properties for the StreamOptions
class.
Property | Type | Required | Description |
---|---|---|---|
|
|
Maximum number of retry attempts for a query. |
|
|
|
Maximum time, in seconds, to wait before retrying a query if the request returns a 429 HTTP status code. |
|
|
|
Stream start time in microseconds since the Unix epoch. Used to
reconnect a disconnected stream.
The period between the stream start and the |
|
|
|
If
Defaults to |
Is this article helpful?
Tell Fauna how the article can be improved:
Visit Fauna's forums
or email docs@fauna.com
Thank you for your feedback!