From 5f8c42c9997d58ffa4a4dab71e99c393c9e7055b Mon Sep 17 00:00:00 2001
From: Igor Kuznetsov <kuznetsovin@gmail.com>
Date: Mon, 10 Mar 2025 15:35:20 +0300
Subject: [PATCH] feat(python): add python example with asyncio

---
 picodata-python-example/README.md           | 35 +++++++++
 picodata-python-example/docker-compose.yml  | 81 +++++++++++++++++++++
 picodata-python-example/picodata_example.py | 26 +++++++
 3 files changed, 142 insertions(+)
 create mode 100644 picodata-python-example/README.md
 create mode 100644 picodata-python-example/docker-compose.yml
 create mode 100755 picodata-python-example/picodata_example.py

diff --git a/picodata-python-example/README.md b/picodata-python-example/README.md
new file mode 100644
index 0000000..4642073
--- /dev/null
+++ b/picodata-python-example/README.md
@@ -0,0 +1,35 @@
+# Working with Picodata using Python asyncpg
+
+## Requirements
+
+- Python 3.9
+- [asyncpg](https://pypi.org/project/asyncpg/)
+
+## Running this example
+
+1. Install dependencies
+
+``` sh
+pip install asyncpg
+```
+
+2. Run Picodata cluster
+
+``` sh
+docker-compose up -d
+```
+
+3. Run `picodata_example.py`
+
+``` sh
+python picodata_example.py
+```
+
+In case of successful run you should see logs like the following in your console:
+
+``` sh
+table create
+delete ok:  DELETE 0
+insert ok INSERT 0 1
+result:  <Record id=1 item='test'>
+```
diff --git a/picodata-python-example/docker-compose.yml b/picodata-python-example/docker-compose.yml
new file mode 100644
index 0000000..332560a
--- /dev/null
+++ b/picodata-python-example/docker-compose.yml
@@ -0,0 +1,81 @@
+version: '3.9'
+
+services:
+  picodata-1-1:
+    image: docker.binary.picodata.io/picodata:25.1.1-distroless
+    container_name: picodata-1-1
+    hostname: picodata-1-1
+    environment:
+      PICODATA_PEER: picodata-1-1:3301
+      PICODATA_LISTEN: picodata-1-1:3301
+      PICODATA_INSTANCE_DIR: /pico/data/picodata-1-1
+      PICODATA_ADVERTISE: picodata-1-1:3301
+      PICODATA_FAILURE_DOMAIN: HOST=picodata-1
+      PICODATA_INIT_REPLICATION_FACTOR: 2
+      PICODATA_HTTP_LISTEN: picodata-1-1:8001
+      PICODATA_PG_LISTEN: picodata-1-1:5432
+      PICODATA_ADMIN_PASSWORD: T0psecret
+      PICODATA_LOG_LEVEL: info
+    volumes:
+      - $PWD/tmp:/pico
+    ports:
+      - "13301:3301"
+      - "18301:8001"
+      - "55432:5432"
+
+  picodata-1-2:
+    image: docker.binary.picodata.io/picodata:25.1.1-distroless
+    container_name: picodata-1-2
+    hostname: picodata-1-2
+    environment:
+      PICODATA_PEER: picodata-1-1:3301
+      PICODATA_LISTEN: picodata-1-2:3301
+      PICODATA_INSTANCE_DIR: /pico/data/picodata-1-2
+      PICODATA_ADVERTISE: picodata-1-2:3301
+      PICODATA_FAILURE_DOMAIN: HOST=picodata-1
+      PICODATA_INIT_REPLICATION_FACTOR: 2
+      PICODATA_HTTP_LISTEN: picodata-1-2:8001
+      PICODATA_LOG_LEVEL: info
+    volumes:
+      - $PWD/tmp:/pico
+    ports:
+      - "13302:3301"
+      - "18302:8001"
+
+  picodata-2-1:
+    image: docker.binary.picodata.io/picodata:25.1.1-distroless
+    container_name: picodata-2-1
+    hostname: picodata-2-1
+    environment:
+      PICODATA_PEER: picodata-1-1:3301
+      PICODATA_LISTEN: picodata-2-1:3301
+      PICODATA_INSTANCE_DIR: /pico/data/picodata-2-1
+      PICODATA_ADVERTISE: picodata-2-1:3301
+      PICODATA_FAILURE_DOMAIN: HOST=picodata-2
+      PICODATA_INIT_REPLICATION_FACTOR: 2
+      PICODATA_HTTP_LISTEN: picodata-2-1:8001
+      PICODATA_LOG_LEVEL: info
+    volumes:
+      - $PWD/tmp:/pico
+    ports:
+      - "13303:3301"
+      - "18303:8001"
+
+  picodata-2-2:
+    image: docker.binary.picodata.io/picodata:25.1.1-distroless
+    container_name: picodata-2-2
+    hostname: picodata-2-2
+    environment:
+      PICODATA_PEER: picodata-1-1:3301
+      PICODATA_LISTEN: picodata-2-2:3301
+      PICODATA_INSTANCE_DIR: /pico/data/picodata-2-2
+      PICODATA_ADVERTISE: picodata-2-2:3301
+      PICODATA_FAILURE_DOMAIN: HOST=picodata-2
+      PICODATA_INIT_REPLICATION_FACTOR: 2
+      PICODATA_HTTP_LISTEN: picodata-2-2:8001
+      PICODATA_LOG_LEVEL: info
+    volumes:
+      - $PWD/tmp:/pico
+    ports:
+      - "13304:3301"
+      - "18304:8001"
diff --git a/picodata-python-example/picodata_example.py b/picodata-python-example/picodata_example.py
new file mode 100755
index 0000000..e2aed49
--- /dev/null
+++ b/picodata-python-example/picodata_example.py
@@ -0,0 +1,26 @@
+#!/usr/bin/env python3
+
+import asyncio
+import asyncpg
+
+async def main():
+    conn = await asyncpg.connect('postgresql://admin:T0psecret@localhost:55432')
+
+    await conn.execute('''
+        CREATE TABLE "warehouse" (id INTEGER NOT NULL, item TEXT NOT NULL, PRIMARY KEY (id)) USING memtx DISTRIBUTED BY (id) OPTION (TIMEOUT = 3.0);
+    ''')
+    print("table create")
+
+    res = await conn.execute('DELETE FROM \"warehouse\";')
+    print("delete ok: ", res)
+
+    res = await conn.execute('INSERT INTO \"warehouse\" VALUES ($1::int, $2::varchar)', 1, "test")
+    print("insert ok", res)
+
+    res = await conn.fetchrow('SELECT * FROM warehouse WHERE id = $1::int', 1)
+    print("result: ", res)
+
+    # Close the connection.
+    await conn.close()
+
+asyncio.run(main())
-- 
GitLab