Skip to content

Commit 706c5c6

Browse files
authored
feat(functions): PostgreSQL Python example (#28)
Add example of pythonic serverless function to connect and perform a query on PostgreSQL database.
1 parent d9d4a5d commit 706c5c6

File tree

8 files changed

+169
-0
lines changed

8 files changed

+169
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ Table of Contents:
4141
| **[Python Dependencies](functions/python-dependencies/README.md)** <br/> Example showing how to use Python requirements with Serverless Framework. | python310 | [Serverless Framework] |
4242
| **[Redis TLS](functions/redis-tls/README.md)** <br/> How to connect a function to a Scaleway Redis cluster with TLS enabled. | python310 | [Terraform] |
4343
| **[Rust MNIST](functions/rust-mnist/README.md)** <br/> A Rust function to recognize hand-written digits with a simple neural network. | rust165 | [Serverless Framework] |
44+
| **[PostgreSQL Python](functions/postgre-sql-python/README.md)** <br/> A Python function to perform a query on a PostgreSQL managed database. | python310 | [Serverless Framework] |
4445
| **[Terraform Python](functions/terraform-python-example/README.md)** <br/> A Python function deployed with Terraform. | python310 | [Terraform] |
4546
| **[PostgeSQL Node](functions/postgre-sql-node/README.md)** <br/> A Node function to connect and interact with PostgreSQL database. | node18 | [Serverless Framework] |
4647

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
# Interact with a PostgreSQL database using pythonic functions
2+
3+
## Requirements
4+
5+
This example assumes that you are familiar with some products of Scaleway's ecosystem:
6+
* how serverless functions work. If needed, you can check [Scaleway official documentation](https://www.scaleway.com/en/docs/serverless/functions/quickstart/).
7+
* how a managed database for PostgreSQL works, and especially how to create a database and create users with appropriate permissions. Please refer to scaleway's documentation [here](https://www.scaleway.com/en/docs/managed-databases/postgresql-and-mysql/quickstart/).
8+
9+
This example uses the Scaleway Serverless Framework Plugin. Please set up your environment with the requirements stated in the [Scaleway Serverless Framework Plugin](https://github.com/scaleway/serverless-scaleway-functions) before trying out the example.
10+
11+
12+
## Context
13+
14+
This example shows how to connect to a managed PostgreSQL database and perform a query on it. This example can be extended to adding, deleting, or processing data within a database.
15+
16+
17+
## Description
18+
19+
The function connects to a PostgreSQL database and performs an example query on it. This example uses Python 3.10 runtime. Used packages are specified in `package.json`. As a requirement for this example we use a pre-compiled [`psycopg2` version](https://www.psycopg.org/docs/install.html#install-from-source).
20+
21+
## Setup
22+
23+
### Create a managed PostgreSQL database
24+
25+
Create a PostgreSQL database and a user profile with appropriate access permissions.
26+
27+
### Fill environment variables
28+
29+
Fill your secrets within `serverless.yml` file:
30+
31+
```
32+
secret:
33+
PG_HOST: "your host IP address"
34+
PG_USER: "your database username"
35+
PG_DATABASE: "your database name"
36+
PG_PASSWORD: "your database user password"
37+
PG_PORT: "your database port"
38+
PG_SSL_ROOT_CERT: "path to your database ssl certificate"
39+
```
40+
41+
### Install npm modules
42+
43+
Once your environment is set up, you can install `npm` dependencies from `package.json` file using:
44+
45+
```
46+
npm install
47+
```
48+
49+
### Deploy and call the function
50+
51+
Then deploy your function and get its URL using:
52+
53+
```
54+
./bin/deploy.sh
55+
```
56+
57+
From the given function URL, you can run your function using:
58+
59+
```
60+
curl <function URL>
61+
```
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#!/bin/bash
2+
3+
set -e
4+
5+
./bin/deps.sh
6+
7+
serverless deploy
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#!/bin/bash
2+
3+
set -e
4+
5+
# This command will run pip install with the given requirements.txt file inside
6+
# a docker container compatible with our function runtimes, and pull the installed
7+
# dependencies locally to your package directory. As these dependencies have been
8+
# installed on top of alpine Linux with our compatible system libraries, you will
9+
# be able to upload your source code and deploy your function properly.
10+
PYTHON_VERSION=3.10
11+
docker run --rm -v $(pwd):/home/app/function --workdir /home/app/function rg.fr-par.scw.cloud/scwfunctionsruntimes-public/python-dep:$PYTHON_VERSION pip install -r ./requirements.txt --target ./package
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import psycopg2
2+
from psycopg2 import Error
3+
import os
4+
import logging
5+
6+
PG_HOST=os.environ.get('PG_HOST')
7+
PG_USER=os.environ.get('PG_USER')
8+
PG_DATABASE=os.environ.get('PG_DATABASE')
9+
PG_PASSWORD=os.environ.get('PG_PASSWORD')
10+
PG_PORT=os.environ.get('PG_PORT')
11+
PG_SSL_ROOT_CERT=os.environ.get('PG_SSL_ROOT_CERT')
12+
13+
def handle(event, context):
14+
15+
try:
16+
connection = psycopg2.connect(
17+
database=PG_DATABASE,
18+
user=PG_USER,
19+
host=PG_HOST,
20+
password=PG_PASSWORD,
21+
port=PG_PORT,
22+
sslmode="require",
23+
sslrootcert=PG_SSL_ROOT_CERT,
24+
)
25+
26+
except (Exception, Error) as error:
27+
logging.error("Error while connecting to PostgreSQL database", error)
28+
return {
29+
"statusCode": 500,
30+
"body": {
31+
"message": "Error while connecting to PostgreSQL database, check function logs for more information"
32+
}
33+
}
34+
35+
try:
36+
cursor = connection.cursor()
37+
logging.info("Connected to Database")
38+
cursor.execute("SELECT * FROM table LIMIT 10")
39+
record = cursor.fetchone()
40+
logging.info("Successfully fetched data")
41+
cursor.close()
42+
return {
43+
"statusCode": 200,
44+
"body": {
45+
"message": record
46+
}
47+
}
48+
49+
except (Exception, Error) as error:
50+
logging.error("Error while interacting with PostgreSQL", error)
51+
return {
52+
"statusCode": 500,
53+
"body": {
54+
"message": "Error while getting information from PostgreSQL database, check function logs for more information"
55+
}
56+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"devDependencies": {
3+
"serverless-scaleway-functions": "^0.4.6"
4+
}
5+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
psycopg2-binary == 2.9
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
service: get-all-from-database
2+
3+
configValidationMode: off
4+
5+
provider:
6+
name: scaleway
7+
runtime: python310
8+
secret:
9+
PG_HOST: "your database host IP address"
10+
PG_USER: "your database username"
11+
PG_DATABASE: "your database name"
12+
PG_PASSWORD: "your database user password"
13+
PG_PORT: "your database port"
14+
PG_SSL_ROOT_CERT: "path to your database ssl certificate"
15+
16+
plugins:
17+
- serverless-scaleway-functions
18+
19+
package:
20+
patterns:
21+
- '!node_modules/**'
22+
- '!.gitignore'
23+
- '!.git/**'
24+
25+
functions:
26+
first:
27+
handler: handlers/handler.handle

0 commit comments

Comments
 (0)