### Install QuestDB Client (Minimal) Source: https://py-questdb-client.readthedocs.io/en/latest/index.html Install the minimal QuestDB client library without DataFrame support. This is suitable if you only need to send individual rows. ```bash python3 -m pip install -U questdb ``` -------------------------------- ### Verify QuestDB Installation (Basic) Source: https://py-questdb-client.readthedocs.io/en/latest/installation.html Run these Python statements in an interactive shell to verify the basic installation of the QuestDB client and its buffer functionality. ```python >>> import questdb.ingress >>> buf = questdb.ingress.Buffer() >>> buf.row('test', symbols={'a': 'b'}) >>> str(buf) 'test,a=b\n' ``` -------------------------------- ### Install QuestDB Client with DataFrame Support (pip) Source: https://py-questdb-client.readthedocs.io/en/latest/_sources/installation.rst.txt Use this command to install the QuestDB client and its optional dataframe dependencies using pip. ```bash python3 -m pip install -U questdb[dataframe] ``` -------------------------------- ### Migrating to QuestDB 2.x Sender API with Configuration String Source: https://py-questdb-client.readthedocs.io/en/latest/changelog.html This example demonstrates migrating to QuestDB 2.x using a configuration string for sender initialization. It mirrors the previous TCP with TLS example but utilizes a string for all connection and auto-flush parameters. ```python from questdb.ingress import Sender conf = ( 'tcp::addr=localhost:9009;' + 'username=testUser1;' + 'token=5UjEMuA0Pj5pjK8a-fa24dyIf-Es5mYny3oE_Wmus48;' + 'token_x=token_x=fLKYEaoEb9lrn3nkwLDA-M_xnuFOdSt9y0Z7_vWSHLU;' + 'token_y=token_y=Dt5tbS1dEDMSYfym3fgMv0B99szno-dFc1rYF9t0aac;' + 'auto_flush_rows=off;' + 'auto_flush_interval=off;' + 'auto_flush_bytes=64512;') with Sender.from_conf(conf) as sender: sender.row( 'test_table', symbols={'sym': 'AAPL'}, columns={'price': 100.0}, at=ServerTimestamp) ``` -------------------------------- ### Install QuestDB Client with DataFrame Support (pip, venv) Source: https://py-questdb-client.readthedocs.io/en/latest/installation.html Install the QuestDB client and its dataframe dependencies within a virtual environment using pip. ```bash pip install -U questdb[dataframe] ``` -------------------------------- ### Install QuestDB Client within a Virtual Environment (pip) Source: https://py-questdb-client.readthedocs.io/en/latest/_sources/installation.rst.txt Install the QuestDB client with dataframe support inside a virtual environment using pip. ```bash pip install -U questdb[dataframe] ``` -------------------------------- ### Initialize and Use Sender Source: https://py-questdb-client.readthedocs.io/en/latest/_sources/sender.rst.txt Basic example of initializing a Sender from a configuration string, establishing a connection, and closing it. The establish method must be called once, while close is idempotent. ```python from questdb.ingress import Sender conf = 'http::addr=localhost:9000;' sender = Sender.from_conf(conf) sender.establish() # ... sender.close() ``` -------------------------------- ### Verify QuestDB Installation (Pandas DataFrame) Source: https://py-questdb-client.readthedocs.io/en/latest/installation.html Verify the installation by checking if you can serialize a Pandas DataFrame using the QuestDB client. This requires the optional dataframe dependencies to be installed. ```python >>> import questdb.ingress >>> import pandas as pd >>> df = pd.DataFrame({'a': [1, 2]}) >>> buf = questdb.ingress.Buffer() >>> buf.dataframe(df, table_name='test') >>> str(buf) 'test a=1i\ntest a=2i\n' ``` -------------------------------- ### Configure TCP Protocol Version Source: https://py-questdb-client.readthedocs.io/en/latest/_sources/conf.rst.txt Example of a configuration string for TCP connections specifying protocol_version=2. ```text tcp::addr=localhost:9000;protocol_version=2; ``` -------------------------------- ### QuestDB Protocol Enum Examples Source: https://py-questdb-client.readthedocs.io/en/latest/api.html Examples of using the Protocol enum for different connection types. ```python Protocol.Http Protocol.Https Protocol.Tcp Protocol.Tcps ``` -------------------------------- ### Install QuestDB Client without DataFrame Support (pip) Source: https://py-questdb-client.readthedocs.io/en/latest/_sources/installation.rst.txt Use this command to install the QuestDB client without the optional dataframe dependencies using pip. ```bash python3 -m pip install -U questdb ``` -------------------------------- ### TLS Configuration with OS Certificate Store Source: https://py-questdb-client.readthedocs.io/en/latest/_sources/conf.rst.txt Example configuration string for HTTPS with TLS enabled, using the OS-provided certificate store for verification. ```text https::addr=localhost:9009;tls_ca=os_roots; ``` -------------------------------- ### QuestDB TlsCa Enum Examples Source: https://py-questdb-client.readthedocs.io/en/latest/api.html Examples of using the TlsCa enum for specifying TLS certificate verification mechanisms. ```python TlsCa.OsRoots TlsCa.PemFile TlsCa.WebpkiAndOsRoots TlsCa.WebpkiRoots ``` -------------------------------- ### Configure TCP Connection with Protocol v2 Source: https://py-questdb-client.readthedocs.io/en/latest/changelog.html Example of configuring a TCP connection to explicitly use protocol version 2. This is an alternative to HTTP(s) auto-negotiation. ```text tcp::addr=localhost:9009;protocol_version=2; ``` -------------------------------- ### TLS Configuration with Self-Signed Certificate Source: https://py-questdb-client.readthedocs.io/en/latest/_sources/conf.rst.txt Example configuration string for HTTPS with TLS enabled, using a PEM-encoded file for a self-signed certificate authority. ```text https::addr=localhost:9009;tls_roots=/path/to/cert.pem; ``` -------------------------------- ### TCP Connection with Authentication and TLS Source: https://py-questdb-client.readthedocs.io/en/latest/_sources/examples.rst.txt Establishes a TCP connection that is authenticated and uses TLS for secure communication. This example builds upon basic connection methods. ```python from questdb.ingress import Sender with Sender(host='localhost', port=9009, protocol='tcp', auth_token='your_token', use_tls=True) as sender: sender.row('trades', {'price': 10.5, 'qty': 100}) sender.row('trades', {'price': 11.2, 'qty': 50}) ``` -------------------------------- ### Buffer.dataframe() Source: https://py-questdb-client.readthedocs.io/en/latest/api.html Add a pandas DataFrame to the buffer. This method requires pandas, numpy, and pyarrow to be installed. It can trigger auto-flushing and supports transactions to avoid this. ```APIDOC ## dataframe(_df_ , _*_ , _table_name : str | None = None_, _table_name_col : None | int | str = None_, _symbols : str | bool | List[int] | List[str] = 'auto'_, _at : ServerTimestampType | int | str | TimestampNanos | datetime.datetime_) Add a pandas DataFrame to the buffer. Also see the `Sender.dataframe()` method if you’re not using the buffer explicitly. It supports the same parameters and also supports auto-flushing. This feature requires the `pandas`, `numpy` and `pyarrow` package to be installed. Adding a dataframe can trigger auto-flushing behaviour, even between rows of the same dataframe. To avoid this, you can use HTTP and transactions (see `Sender.transaction()`). ``` -------------------------------- ### Verify DataFrame Ingestion with QuestDB (Python) Source: https://py-questdb-client.readthedocs.io/en/latest/_sources/installation.rst.txt Verify the ability to serialize a Pandas DataFrame into the QuestDB ingress buffer format. This requires pandas and pyarrow to be installed. ```python >>> import questdb.ingress >>> import pandas as pd >>> df = pd.DataFrame({'a': [1, 2]}) >>> buf = questdb.ingress.Buffer() >>> buf.dataframe(df, table_name='test') >>> str(buf) 'test a=1i\ntest a=2i\n' ``` -------------------------------- ### Pandas DataFrame to QuestDB Source: https://py-questdb-client.readthedocs.io/en/latest/_sources/examples.rst.txt Shows how to insert data from a Pandas DataFrame into the 'trades' table. Ensure Pandas is installed and your DataFrame is correctly structured. ```python import pandas as pd from questdb.ingress import Sender df = pd.DataFrame({ 'ts': pd.to_datetime(['2023-01-01T10:00:00Z', '2023-01-01T10:01:00Z']), 'price': [10.5, 11.2], 'qty': [100, 50] }).set_index('ts') with Sender(host='localhost', port=9000) as sender: sender.dataframe(df, table_name='trades') ``` -------------------------------- ### Send Data with Symbol and String Columns Source: https://py-questdb-client.readthedocs.io/en/latest/_sources/sender.rst.txt Example of sending a row with both symbol and string columns. Symbols are efficient for categorical data, while strings are for one-off values. ```python from questdb.ingress import Sender, TimestampNanos import datetime conf = 'http::addr=localhost:9000;' with Sender.from_conf(conf) as sender: sender.row( 'trades', symbols={ 'symbol': 'ETH-USD', 'side': 'sell'}, columns={ 'price': 2615.54, 'amount': 0.00044} at=datetime.datetime(2021, 1, 1, 12, 0, 0)) ``` -------------------------------- ### Load Pandas DataFrame from Parquet and Insert into QuestDB Source: https://py-questdb-client.readthedocs.io/en/latest/examples.html This example demonstrates loading data from a Parquet file into a Pandas DataFrame and then inserting it into QuestDB. The table name is automatically inferred from the DataFrame's index name. ```python from questdb.ingress import Sender import pandas as pd def write_parquet_file(): df = pd.DataFrame({ 'location': pd.Categorical( ['BP-5541', 'UB-3355', 'SL-0995', 'BP-6653']), 'provider': pd.Categorical( ['BP Pulse', 'Ubitricity', 'Source London', 'BP Pulse']), 'speed_kwh': pd.Categorical( [50, 7, 7, 120]), 'connector_type': pd.Categorical( ['Type 2 & 2+CCS', 'Type 1 & 2', 'Type 1 & 2', 'Type 2 & 2+CCS']), 'current_type': pd.Categorical( ['dc', 'ac', 'ac', 'dc']), 'price_pence': [54, 34, 32, 59], 'in_use': [True, False, False, True], 'ts': [ pd.Timestamp('2022-12-30 12:15:00'), pd.Timestamp('2022-12-30 12:16:00'), pd.Timestamp('2022-12-30 12:18:00'), pd.Timestamp('2022-12-30 12:19:00')]}) name = 'ev_chargers' df.index.name = name # We set the dataframe's index name here! filename = f'{name}.parquet' df.to_parquet(filename) return filename def example(host: str = 'localhost', port: int = 9000): filename = write_parquet_file() df = pd.read_parquet(filename) with Sender.from_conf(f"http::addr={host}:{port};") as sender: # Note: Table name is looked up from the dataframe's index name. sender.dataframe(df, at='ts') if __name__ == '__main__': example() ``` -------------------------------- ### TCP Authentication and TLS Source: https://py-questdb-client.readthedocs.io/en/latest/examples.html Connects to QuestDB using TCP, with authentication and TLS enabled. Similar to the HTTP example, it sends rows and flushes automatically or manually. ```python from questdb.ingress import Sender, IngressError, TimestampNanos import sys def example(host: str = 'localhost', port: int = 9009): try: conf = ( f"tcps::addr={host}:{port};" + "username=testUser1;" + "token=5UjEMuA0Pj5pjK8a-fa24dyIf-Es5mYny3oE_Wmus48;" + "token_x=fLKYEaoEb9lrn3nkwLDA-M_xnuFOdSt9y0Z7_vWSHLU;" + "token_y=Dt5tbS1dEDMSYfym3fgMv0B99szno-dFc1rYF9t0aac;") with Sender.from_conf(conf) as sender: # Record with provided designated timestamp (using the 'at' param) # Notice the designated timestamp is expected in Nanoseconds, # but timestamps in other columns are expected in Microseconds. # The API provides convenient functions sender.row( 'trades', symbols={ 'symbol': 'ETH-USD', 'side': 'sell'}, columns={ 'price': 2615.54, 'amount': 0.00044, }, at=TimestampNanos.now()) # You can call `sender.row` multiple times inside the same `with` # block. The client will buffer the rows and send them in batches. # You can flush manually at any point. sender.flush() # If you don't flush manually, the client will flush automatically # when a row is added and either: # * The buffer contains 75000 rows (if HTTP) or 600 rows (if TCP) # * The last flush was more than 1000ms ago. # Auto-flushing can be customized via the `auto_flush_..` params. # Any remaining pending rows will be sent when the `with` block ends. except IngressError as e: sys.stderr.write(f'Got error: {e}\n') if __name__ == '__main__': example() ``` -------------------------------- ### Configure Auto-Flush Interval with Time Delay Source: https://py-questdb-client.readthedocs.io/en/latest/_sources/conf.rst.txt Demonstrates how auto_flush_interval delays flushing until a new row is added after the interval has passed. This example shows 'row 1' being flushed along with 'row 2' after a 60-second sleep, exceeding the 1-second interval. ```python from questdb.ingress import Sender, TimestampNanos import time conf = "http::addr=localhost:9009;auto_flush_interval=1000;" with Sender.from_conf(conf) as sender: # row 1 sender.row('table1', columns={'val': 1}, at=TimestampNanos.now()) time.sleep(60) # sleep for 1 minute # row 2 sender.row('table2', columns={'val': 2}, at=TimestampNanos.now()) ``` -------------------------------- ### Ingest Ticking Data with Custom Auto-Flush Source: https://py-questdb-client.readthedocs.io/en/latest/examples.html This example demonstrates how to ingest random ticking data into QuestDB with custom auto-flush configurations. It uses non-default settings for buffer size and flush interval, disabling row-count based flushing. Press Ctrl+C to terminate. ```python from questdb.ingress import Sender, TimestampNanos import random import uuid import time def example(host: str = 'localhost', port: int = 9009): table_name: str = str(uuid.uuid1()) conf: str = ( f"tcp::addr={host}:{port};" + "auto_flush_bytes=1024;" + # Flush if the internal buffer exceeds 1KiB "auto_flush_rows=off;" # Disable auto-flushing based on row count "auto_flush_interval=5000;") # Flush if last flushed more than 5s ago with Sender.from_conf(conf) as sender: total_rows = 0 try: print("Ctrl^C to terminate...") while True: time.sleep(random.randint(0, 750) / 1000) # sleep up to 750 ms print('Inserting row...') sender.row( table_name, symbols={ 'src': random.choice(('ALPHA', 'BETA', 'OMEGA')), 'dst': random.choice(('ALPHA', 'BETA', 'OMEGA'))}, columns={ 'price': random.randint(200, 500), 'qty': random.randint(1, 5)}, at=TimestampNanos.now()) total_rows += 1 # If the internal buffer is empty, then auto-flush triggered. if len(sender) == 0: print('Auto-flush triggered.') except KeyboardInterrupt: print(f"table: {table_name}, total rows sent: {total_rows}") print("bye!") if __name__ == '__main__': example() ``` -------------------------------- ### Insert Pandas DataFrame into Multiple QuestDB Tables Source: https://py-questdb-client.readthedocs.io/en/latest/examples.html This example demonstrates inserting data into multiple QuestDB tables based on a categorical column ('metric'). It also shows how to use categorical columns for SYMBOL types and specify the timestamp column by index. ```python from questdb.ingress import Sender, IngressError import sys import pandas as pd def example(host: str = 'localhost', port: int = 9000): df = pd.DataFrame({ 'metric': pd.Categorical( ['humidity', 'temp_c', 'voc_index', 'temp_c']), 'sensor': pd.Categorical( ['paris-01', 'london-02', 'london-01', 'paris-01']), 'value': [ 0.83, 22.62, 100.0, 23.62], 'ts': [ pd.Timestamp('2022-08-06 07:35:23.189062'), pd.Timestamp('2022-08-06 07:35:23.189062'), pd.Timestamp('2022-08-06 07:35:23.189062'), pd.Timestamp('2022-08-06 07:35:23.189062')]}) try: with Sender.from_conf(f"http::addr={host}:{port};") as sender: sender.dataframe( df, table_name_col='metric', # Table name from 'metric' column. symbols='auto', # Category columns as SYMBOL. (Default) at=-1) # Last column contains the designated timestamps. except IngressError as e: sys.stderr.write(f'Got error: {e}\n') if __name__ == '__main__': example() ``` -------------------------------- ### Initialize Sender from Configuration String Source: https://py-questdb-client.readthedocs.io/en/latest/sender.html Initializes the Sender client using a configuration string. Ensure the configuration string is correctly formatted for QuestDB. ```python from questdb.ingress import Sender conf = 'http::addr=localhost:9000;' with Sender.from_conf(conf) as sender: ... ``` -------------------------------- ### Initialize Sender from Configuration String Source: https://py-questdb-client.readthedocs.io/en/latest/_sources/sender.rst.txt Initializes the Sender client using a configuration string. The 'with' statement ensures the sender is properly closed. ```python from questdb.ingress import Sender conf = 'http::addr=localhost:9000;' with Sender.from_conf(conf) as sender: ... ``` -------------------------------- ### Sender Configuration String Source: https://py-questdb-client.readthedocs.io/en/latest/_sources/conf.rst.txt Use Sender.from_conf with a configuration string to set up the sender. The configuration string specifies protocol, address, and authentication details. ```python from questdb.ingress import Sender conf = "http::addr=localhost:9009;username=admin;password=quest;" with Sender.from_conf(conf) as sender: ... ``` -------------------------------- ### Sender from Environment Variable Source: https://py-questdb-client.readthedocs.io/en/latest/_sources/conf.rst.txt Initialize the sender using Sender.from_env() to load configuration from the QDB_CLIENT_CONF environment variable. ```python from questdb.ingress import Sender with Sender.from_env() as sender: ... ``` -------------------------------- ### Write Pandas DataFrame to QuestDB Source: https://py-questdb-client.readthedocs.io/en/latest/api.html Ingest data from a Pandas DataFrame into QuestDB. This method supports auto-flushing and can specify a table name and timestamp column. Ensure Pandas is installed (`pip install pandas`). ```python import pandas as pd import questdb.ingress as qi df = pd.DataFrame({ 'car': pd.Categorical(['Nic 42', 'Eddi', 'Nic 42', 'Eddi']), 'position': [1, 2, 1, 2], 'speed': [89.3, 98.2, 3, 4], 'lat_gforce': [0.1, -0.2, -0.6, 0.4], 'accelleration': [0.1, -0.2, 0.6, 4.4], 'tyre_pressure': [2.6, 2.5, 2.6, 2.5], 'ts': [ pd.Timestamp('2022-08-09 13:56:00'), pd.Timestamp('2022-08-09 13:56:01'), pd.Timestamp('2022-08-09 13:56:02'), pd.Timestamp('2022-08-09 13:56:03')] }) with qi.Sender.from_env() as sender: sender.dataframe(df, table_name='race_metrics', at='ts') ``` -------------------------------- ### Construct TimestampNanos from current time Source: https://py-questdb-client.readthedocs.io/en/latest/api.html Recommended way to get the current timestamp in nanoseconds since the UNIX epoch (UTC). ```python TimestampNanos.now() ``` -------------------------------- ### Constructing a Sender from Environment Variable Source: https://py-questdb-client.readthedocs.io/en/latest/api.html Create a sender instance using configuration from the QDB_CLIENT_CONF environment variable. Additional parameters can be provided to override or supplement the environment configuration. ```python from questdb.ingress import Sender sender = Sender.from_env() ``` -------------------------------- ### Construct TimestampMicros from current time Source: https://py-questdb-client.readthedocs.io/en/latest/api.html Recommended way to get the current timestamp in microseconds since the UNIX epoch (UTC). ```python TimestampMicros.now() ``` -------------------------------- ### Buffer.transaction() Source: https://py-questdb-client.readthedocs.io/en/latest/api.html Start a transaction block for sending data. This is useful for grouping multiple row insertions within a single atomic operation. ```APIDOC ## transaction(_table_name : str_) Start a HTTP Transactions block. ``` -------------------------------- ### Sender.establish Source: https://py-questdb-client.readthedocs.io/en/latest/api.html Prepares the sender for use by establishing a connection to the QuestDB server. ```APIDOC ## Sender.establish ### Description Prepare the sender for use. If using ILP/HTTP this will initialize the HTTP connection pool. If using ILP/TCP this will cause connection to the server and block until the connection is established. If the TCP connection is set up with authentication and/or TLS, this method will return only _after_ the handshake(s) is/are complete. ### Method `establish()` ### Parameters None ### Request Example None ### Response #### Success Response (200) None #### Response Example None ``` -------------------------------- ### Configure Sender from Environment Variable Source: https://py-questdb-client.readthedocs.io/en/latest/sender.html Load client configuration from environment variables and customize specific parameters like auto-flush interval. Useful for flexible deployment configurations. ```bash export QDB_CLIENT_CONF='http::addr=localhost:9000;' ``` -------------------------------- ### Creating a Buffer via Sender's new_buffer() Source: https://py-questdb-client.readthedocs.io/en/latest/api.html Illustrates how to create a new buffer instance using the sender's new_buffer() method, which pre-configures the buffer with the sender's settings for init_buf_size and max_name_len. ```python from questdb.ingress import Sender, Buffer sender = Sender('http', 'localhost', 9009, init_buf_size=16384, max_name_len=64) buf = sender.new_buffer() assert buf.init_buf_size == 16384 assert buf.max_name_len == 64 ``` -------------------------------- ### Initialize Sender from Environment Variable Source: https://py-questdb-client.readthedocs.io/en/latest/sender.html Initializes the Sender client by reading configuration from an environment variable. This is a more secure method for managing sensitive information like passwords. ```bash export QDB_CLIENT_CONF='http::addr=localhost:9000;' ``` ```python from questdb.ingress import Sender with Sender.from_env() as sender: ... ``` -------------------------------- ### Customizing Sender from Environment Variables Source: https://py-questdb-client.readthedocs.io/en/latest/_sources/sender.rst.txt Shows how to load Sender configuration from environment variables and override specific parameters, such as auto-flush interval, using keyword arguments. ```python from questdb.ingress import Sender, Protocol from datetime import timedelta with Sender.from_env(auto_flush_interval=timedelta(seconds=10)) as sender: ... ``` -------------------------------- ### Programmatic Sender Construction Source: https://py-questdb-client.readthedocs.io/en/latest/_sources/sender.rst.txt Demonstrates constructing a Sender instance programmatically using keyword arguments for configuration, including TCP protocol, host, port, and auto-flush settings. ```python from questdb.ingress import Sender, Protocol from datetime import timedelta with Sender(Protocol.Tcp, 'localhost', 9009, auto_flush=True, auto_flush_interval=timedelta(seconds=10)) as sender: ... ``` -------------------------------- ### Creating and Using a Buffer for Ingestion Source: https://py-questdb-client.readthedocs.io/en/latest/api.html Demonstrates how to create a Buffer instance and add rows to it. Rows are buffered and can be sent to QuestDB using a Sender's flush method. The buffer can be reused after flushing. ```python from questdb.ingress import Buffer buf = Buffer() buf.row( 'table_name1', symbols={'s1', 'v1', 's2', 'v2'}, columns={'c1': True, 'c2': 0.5}) buf.row( 'table_name2', symbols={'questdb': '❤️'}, columns={'like': 100000}) # Append any additional rows then, once ready, call sender.flush(buffer) # a `Sender` instance. # The sender auto-cleared the buffer, ready for reuse. buf.row( 'table_name1', symbols={'s1', 'v1', 's2', 'v2'}, columns={'c1': True, 'c2': 0.5}) # etc. ``` -------------------------------- ### Add QuestDB Client with DataFrame Support (Poetry) Source: https://py-questdb-client.readthedocs.io/en/latest/installation.html Add the QuestDB client and its dataframe dependencies to your project using Poetry. ```bash poetry add questdb[dataframe] ``` -------------------------------- ### Sender from Environment Variable Source: https://py-questdb-client.readthedocs.io/en/latest/api.html Construct a sender instance using configuration from the QDB_CLIENT_CONF environment variable. Additional parameters can be provided to override or supplement the configuration. ```APIDOC ## _static _from_env() Construct a sender from the `QDB_CLIENT_CONF` environment variable. The environment variable must be set to a valid configuration string. The additional arguments are used to specify additional parameters which are not present in the configuration string. Note that any parameters already present in the configuration string cannot be overridden. ``` -------------------------------- ### Add QuestDB Client with DataFrame Support (Poetry) Source: https://py-questdb-client.readthedocs.io/en/latest/_sources/installation.rst.txt Add the QuestDB client and its optional dataframe dependencies to your project using Poetry. ```bash poetry add questdb[dataframe] ``` -------------------------------- ### Get Raw Payload as Bytes Source: https://py-questdb-client.readthedocs.io/en/latest/changelog.html Illustrates how to access the raw binary payload of a sender or buffer for debugging purposes. This replaces the legacy string conversion method. ```python # for debugging payload = bytes(sender) ``` -------------------------------- ### Create Buffer with Automatic Protocol Version Source: https://py-questdb-client.readthedocs.io/en/latest/changelog.html Shows how to create a buffer using the sender, which automatically determines the protocol version. This is the recommended way to create buffers following constructor changes. ```python buf = sender.new_buffer() # protocol_version determined automatically buf.row( 'table', columns={'arr': np.array([1.5, 3.0], dtype=np.float64)}, at=timestamp) ``` -------------------------------- ### Sending data within an HTTP transaction Source: https://py-questdb-client.readthedocs.io/en/latest/changelog.html This example demonstrates how to send a set of rows for a single table transactionally over HTTP. Use the `sender.transaction()` context manager to group rows for a commit. ```python conf = 'http::addr=localhost:9000;' with Sender.from_conf(conf) as sender: with sender.transaction('test_table') as txn: # Same arguments as the sender methods, minus the table name. txn.row(...) txn.dataframe(...) ``` -------------------------------- ### Verify QuestDB Ingress Buffer (Python) Source: https://py-questdb-client.readthedocs.io/en/latest/_sources/installation.rst.txt Verify basic ingress buffer functionality by creating a buffer and adding a row. This snippet demonstrates the creation of a Buffer object and adding a simple row with symbols. ```python >>> import questdb.ingress >>> buf = questdb.ingress.Buffer() >>> buf.row('test', symbols={'a': 'b'}) >>> str(buf) 'test,a=b\n' ``` -------------------------------- ### Environment Variable Configuration Source: https://py-questdb-client.readthedocs.io/en/latest/_sources/conf.rst.txt Configure the sender by setting the QDB_CLIENT_CONF environment variable. This is useful for keeping sensitive information out of code. ```bash export QDB_CLIENT_CONF="http::addr=localhost:9009;username=admin;password=quest;" ``` -------------------------------- ### Buffer Constructor Equivalency Source: https://py-questdb-client.readthedocs.io/en/latest/api.html Shows that creating a Buffer with default arguments is equivalent to explicitly setting init_buf_size and max_name_len to their default values. ```python # These two buffer constructions are equivalent. buf1 = Buffer() buf2 = Buffer(init_buf_size=65536, max_name_len=127) ``` -------------------------------- ### QuestDB Server Configuration for Development Source: https://py-questdb-client.readthedocs.io/en/latest/_sources/troubleshooting.rst.txt Tune these parameters for development/testing to see data more frequently. This is not recommended for production environments. ```ini # server.conf cairo.max.uncommitted.rows=1 line.tcp.maintenance.job.interval=100 ``` -------------------------------- ### Sender.from_conf Source: https://py-questdb-client.readthedocs.io/en/latest/api.html Constructs a sender instance from a configuration string, allowing for additional parameters to be specified. ```APIDOC ## Sender.from_conf ### Description Construct a sender from a configuration string. The additional arguments are used to specify additional parameters which are not present in the configuration string. Note that any parameters already present in the configuration string cannot be overridden. ### Method `static _from_conf(_conf_str_ , `*_`, `bind_interface =None`, `username =None`, `password =None`, `token =None`, `token_x =None`, `token_y =None`, `auth_timeout =None`, `tls_verify =None`, `tls_ca =None`, `tls_roots =None`, `max_buf_size =None`, `retry_timeout =None`, `request_min_throughput =None`, `request_timeout =None`, `auto_flush =None`, `auto_flush_rows =None`, `auto_flush_bytes =None`, `auto_flush_interval =None`, `protocol_version =None`, `init_buf_size =None`, `max_name_len =None`) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **conf_str** (str) - The configuration string. - **bind_interface** (str | None) - The interface to bind to. - **username** (str | None) - The username for authentication. - **password** (str | None) - The password for authentication. - **token** (str | None) - The authentication token. - **token_x** (str | None) - Token X parameter. - **token_y** (str | None) - Token Y parameter. - **auth_timeout** (int | None) - Authentication timeout in seconds. - **tls_verify** (bool | None) - Whether to verify TLS certificates. - **tls_ca** (str | None) - Path to the CA certificate file. - **tls_roots** (str | None) - Path to the TLS roots file. - **max_buf_size** (int | None) - Maximum buffer size in bytes. - **retry_timeout** (int | None) - Retry timeout in seconds. - **request_min_throughput** (int | None) - Minimum request throughput. - **request_timeout** (int | None) - Request timeout in seconds. - **auto_flush** (bool | None) - Enable auto-flushing. - **auto_flush_rows** (int | None) - Auto-flush threshold in rows. - **auto_flush_bytes** (int | None) - Auto-flush threshold in bytes. - **auto_flush_interval** (int | None) - Auto-flush interval in seconds. - **protocol_version** (str | None) - The protocol version. - **init_buf_size** (int | None) - Initial buffer size. - **max_name_len** (int | None) - Maximum name length. ### Request Example None ### Response #### Success Response (200) None #### Response Example None ``` -------------------------------- ### Add QuestDB Client without DataFrame Support (Poetry) Source: https://py-questdb-client.readthedocs.io/en/latest/_sources/installation.rst.txt Add the QuestDB client without the optional dataframe dependencies to your project using Poetry. ```bash poetry add questdb ``` -------------------------------- ### Reuse Sender Object for Multiple Requests Source: https://py-questdb-client.readthedocs.io/en/latest/_sources/sender.rst.txt Demonstrates creating a sender object from configuration and reusing it for multiple data ingestion requests, including explicit flushing. ```python from questdb.ingress import Sender conf = 'http::addr=localhost:9000;' with Sender.from_conf(conf) as sender: # Use the sender object for multiple requests sender.row(...) sender.row(...) # remember auto-flush may trigger after any row sender.row(...) sender.flush() # you can flush explicitly at any point too # ... sender.row(...) sender.dataframe(...) # auto-flush may trigger within a dataframe too sender.flush() ``` -------------------------------- ### QuestDB Server Configuration for Development Source: https://py-questdb-client.readthedocs.io/en/latest/troubleshooting.html Tune QuestDB server configuration parameters for development and testing to see data immediately. This reduces commit lag and uncommitted row limits. ```ini # server.conf cairo.max.uncommitted.rows=1 line.tcp.maintenance.job.interval=100 ``` -------------------------------- ### Explicit Buffer Management Source: https://py-questdb-client.readthedocs.io/en/latest/_sources/examples.rst.txt Demonstrates explicit construction of Buffer objects for advanced use cases like sending messages to multiple QuestDB instances or decoupling serialization from sending. This bypasses auto-flushing. ```python from questdb.ingress import Sender, Buffer with Sender(host='localhost', port=9000) as sender: buffer = Buffer() buffer.row('trades', {'price': 10.5, 'qty': 100}) buffer.row('trades', {'price': 11.2, 'qty': 50}) sender.flush(buffer) ``` -------------------------------- ### Sender.new_buffer() Source: https://py-questdb-client.readthedocs.io/en/latest/api.html Creates a new buffer instance configured with the same settings (init_buf_size, max_name_len) as the sender. ```APIDOC ## new_buffer() Make a new configured buffer. The buffer is set up with the configured init_buf_size and max_name_len. ``` -------------------------------- ### Create and use a sender transaction Source: https://py-questdb-client.readthedocs.io/en/latest/api.html This snippet shows how to create a transaction for a specific table using a `with` statement. Rows and dataframes can then be added within the transaction context. ```python with sender.transaction('table_name') as txn: txn.row(..) txn.dataframe(..) ``` -------------------------------- ### Update QuestDB Client (Poetry) Source: https://py-questdb-client.readthedocs.io/en/latest/_sources/installation.rst.txt Update the QuestDB client dependency in your project using Poetry. ```bash poetry update questdb ``` -------------------------------- ### Migrating to QuestDB 2.x Sender API (TCP with TLS) Source: https://py-questdb-client.readthedocs.io/en/latest/changelog.html This snippet shows the equivalent QuestDB 2.x code for a previous 1.x version using TCP with TLS. It highlights the new `Protocol.Tcps` and explicit authentication arguments, along with updated auto-flush settings and the mandatory `at=ServerTimestamp`. ```python from questdb.ingress import Sender, Protocol, ServerTimestamp sender = Sender( Protocol.Tcps, 'localhost', 9009, username='testUser1', token='5UjEMuA0Pj5pjK8a-fa24dyIf-Es5mYny3oE_Wmus48', token_x='token_x=fLKYEaoEb9lrn3nkwLDA-M_xnuFOdSt9y0Z7_vWSHLU', token_y='token_y=Dt5tbS1dEDMSYfym3fgMv0B99szno-dFc1rYF9t0aac', auto_flush_rows='off', auto_flush_interval='off', auto_flush_bytes=64512) with sender: sender.row( 'test_table', symbols={'sym': 'AAPL'}, columns={'price': 100.0}, at=ServerTimestamp) ``` -------------------------------- ### Send Data to Multiple Databases with Clear=False Source: https://py-questdb-client.readthedocs.io/en/latest/sender.html Handle buffers explicitly when sending data to multiple databases using the `.flush(buf, clear=False)` option. This allows appending data to the same buffer across multiple flushes without clearing it. The `clear=False` parameter defaults to `True`. ```python from questdb.ingress import Buffer, Sender, TimestampNanos buf = Buffer() buf.row( 'trades', symbols={'symbol': 'ETH-USD', 'side': 'sell'}, columns={'price': 2615.54, 'amount': 0.00044}, at=TimestampNanos.now()) conf1 = 'http::addr=db1.host.com:9000;' conf2 = 'http::addr=db2.host.com:9000;' with Sender.from_conf(conf1) as sender1, Sender.from_conf(conf2) as sender2: sender1.flush(buf1, clear=False) sender2.flush(buf2, clear=False) buf.clear() ``` -------------------------------- ### Ticking Data with Auto-Flush Settings Source: https://py-questdb-client.readthedocs.io/en/latest/_sources/examples.rst.txt Mimics application behavior by creating random ticking data at random intervals with non-default auto-flush settings. Useful for simulating real-time data streams. ```python import random import time from questdb.ingress import Sender with Sender(host='localhost', port=9000, auto_flush_rows=1000, auto_flush_interval_sec=1) as sender: for _ in range(10000): sender.row('trades', { 'price': random.uniform(10.0, 12.0), 'qty': random.randint(10, 1000) }) time.sleep(random.uniform(0.001, 0.01)) ``` -------------------------------- ### Sending Data with Server Timestamp Source: https://py-questdb-client.readthedocs.io/en/latest/_sources/sender.rst.txt Demonstrates sending a row of data to QuestDB using ServerTimestamp to let the server assign the timestamp. Note: This is a legacy feature and not recommended. ```python from questdb.ingress import Sender, ServerTimestamp conf = 'http::addr=localhost:9000;' with Sender.from_conf(conf) as sender: sender.row( 'trades', symbols={'symbol': 'ETH-USD', 'side': 'sell'}, columns={'price': 2615.54, 'amount': 0.00044}, at=ServerTimestamp) # Legacy feature, not recommended. ```