From 2ca3137c0b9627ceb92d74a1b7c425ecbc370d90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CNaeel=E2=80=9D?= Date: Wed, 11 Mar 2026 16:37:22 +0400 Subject: [PATCH] =?UTF-8?q?feat:=20=D0=BF=D1=80=D0=B8=D0=BC=D0=B5=D1=80=20?= =?UTF-8?q?pg-list-python=20=E2=80=94=20=D1=81=D0=BF=D0=B8=D1=81=D0=BE?= =?UTF-8?q?=D0=BA=20=D0=B8=D0=B7=20PostgreSQL=20=D0=B1=D0=B5=D0=B7=20?= =?UTF-8?q?=D0=B4=D0=B6=D0=BE=D0=B1=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- examples/pg-list-python/code/catalog.py | 47 +++++++++++++++++++ examples/pg-list-python/code/requirements.txt | 1 + examples/pg-list-python/function.tf | 29 ++++++++++++ examples/pg-list-python/main.tf | 17 +++++++ examples/pg-list-python/variables.tf | 14 ++++++ 5 files changed, 108 insertions(+) create mode 100644 examples/pg-list-python/code/catalog.py create mode 100644 examples/pg-list-python/code/requirements.txt create mode 100644 examples/pg-list-python/function.tf create mode 100644 examples/pg-list-python/main.tf create mode 100644 examples/pg-list-python/variables.tf diff --git a/examples/pg-list-python/code/catalog.py b/examples/pg-list-python/code/catalog.py new file mode 100644 index 0000000..54ef884 --- /dev/null +++ b/examples/pg-list-python/code/catalog.py @@ -0,0 +1,47 @@ +# 2026-03-11 +# catalog.py — читает список продуктов из PostgreSQL. +# Таблица demo_products создаётся автоматически при первом вызове. +# Точка входа: list_products(event) + +import json +import os +import psycopg2 + + +def list_products(event): + dsn = os.environ["PG_DSN"] + conn = psycopg2.connect(dsn) + try: + with conn.cursor() as cur: + _ensure_table(cur) + conn.commit() + + cur.execute("SELECT id, name, price FROM demo_products ORDER BY id") + rows = cur.fetchall() + finally: + conn.close() + + products = [{"id": row[0], "name": row[1], "price": row[2]} for row in rows] + return {"products": products, "count": len(products)} + + +def _ensure_table(cur): + # Создаём таблицу и наполняем демо-данными — только один раз + cur.execute(""" + CREATE TABLE IF NOT EXISTS demo_products ( + id SERIAL PRIMARY KEY, + name TEXT NOT NULL, + price NUMERIC(10,2) NOT NULL + ) + """) + cur.execute("SELECT COUNT(*) FROM demo_products") + if cur.fetchone()[0] == 0: + cur.executemany( + "INSERT INTO demo_products (name, price) VALUES (%s, %s)", + [ + ("Ноутбук", 89999.00), + ("Мышь", 1299.00), + ("Клавиатура", 3499.00), + ("Монитор", 32000.00), + ], + ) diff --git a/examples/pg-list-python/code/requirements.txt b/examples/pg-list-python/code/requirements.txt new file mode 100644 index 0000000..37ec460 --- /dev/null +++ b/examples/pg-list-python/code/requirements.txt @@ -0,0 +1 @@ +psycopg2-binary diff --git a/examples/pg-list-python/function.tf b/examples/pg-list-python/function.tf new file mode 100644 index 0000000..6638c65 --- /dev/null +++ b/examples/pg-list-python/function.tf @@ -0,0 +1,29 @@ +# 2026-03-11 +# function.tf — HTTP-функция: читает из PostgreSQL и возвращает список записей. +# Нет джобов, нет инициализации — только функция + HTTP триггер. + +resource "sless_function" "product_catalog" { + name = "product-catalog" + runtime = "python3.11" + entrypoint = "catalog.list_products" + memory_mb = 128 + timeout_sec = 10 + + source_dir = "${path.module}/code" + + # DSN передаётся через env — функция не знает об инфраструктуре + env_vars = { + PG_DSN = var.pg_dsn + } +} + +resource "sless_trigger" "product_catalog_http" { + name = "product-catalog-http" + type = "http" + function = sless_function.product_catalog.name + enabled = true +} + +output "catalog_url" { + value = sless_trigger.product_catalog_http.url +} diff --git a/examples/pg-list-python/main.tf b/examples/pg-list-python/main.tf new file mode 100644 index 0000000..7d3d427 --- /dev/null +++ b/examples/pg-list-python/main.tf @@ -0,0 +1,17 @@ +# 2026-03-11 +# main.tf — провайдер для pg-list-python примера. + +terraform { + required_providers { + sless = { + source = "terra.k8c.ru/naeel/sless" + version = "~> 0.1.14" + } + } +} + +provider "sless" { + endpoint = "https://sless-api.kube5s.ru" + token = var.token + nubes_endpoint = "https://deck-api.ngcloud.ru/api/v1" +} diff --git a/examples/pg-list-python/variables.tf b/examples/pg-list-python/variables.tf new file mode 100644 index 0000000..ab59478 --- /dev/null +++ b/examples/pg-list-python/variables.tf @@ -0,0 +1,14 @@ +# 2026-03-11 +# variables.tf + +variable "token" { + description = "JWT токен облака" + type = string + sensitive = true +} + +variable "pg_dsn" { + description = "DSN подключения к PostgreSQL" + type = string + default = "postgres://sless:sless-pg-password@postgres.sless.svc.cluster.local:5432/sless?sslmode=disable" +}