# Example server application in Python

This tutorial shows how to set up a simple HTTP server with a database and configure an Efento Gateway to send measurement data to it. In the example, we use **Python**, **Flask**, and a **PostgreSQL** database, but the same concept can easily be implemented in other programming languages or with different databases.

{% hint style="info" %}
If you have any questions or run into issues, feel free to contact us at **help.efento.io**.
{% endhint %}

## Before you start

Before beginning, ensure that you have installed and configured the following components:

* **PyCharm** or any Python 3 IDE
* **PostgreSQL** database
* **Efento Gateway** and **Efento Bluetooth Low Energy loggers**

## PostgreSQL Database Setup

{% stepper %}
{% step %}

### Create the database

After installing PostgreSQL, you will be prompted to create your first database during setup. By default, it will be created using the following credentials:

```
DATABASE_HOST = 'localhost'
DATABASE_USER = 'postgres'
DATABASE_PASSWORD = 'your_password'
DATABASE_NAME = 'postgres'
```

You may change these values if needed. Be sure to write down your credentials, as they will be required later.

To check or modify database credentials, open **pgAdmin**, then navigate to:\
**Object → Properties → General**

<figure><img src="/files/qwUHY9NVBqODHWMmubyd" alt=""><figcaption></figcaption></figure>
{% endstep %}

{% step %}

### Create the measurements table

To store measurements sent from the Efento Gateway, you must create a table. In this example, we create a very simple structure containing five columns, all of type `text`. This design is only for demonstration purposes - your production database should be structured according to your project needs.

You may create the table using pgAdmin’s interface or by running a SQL query.

In pgAdmin, select your database and navigate to:\
**Tools → Query Tool**

<figure><img src="/files/RwOHz5Ff6sERE1SiSkIp" alt=""><figcaption></figcaption></figure>

Insert the query below and click **Execute (▶)**:

```sql
CREATE TABLE measurements (
    measured_at text,
    serial_number text,
    low_battery text,
    type text,
    value text
);
```

Running `CREATE TABLE` creates a new, initially empty table owned by the user who executed the command.
{% endstep %}
{% endstepper %}

## Python Server

The script you will create sets up a simple HTTP server. Efento Gateway sends data as **JSON over REST**, and a single message may contain multiple measurements.

When the server receives a request:

1. It parses the JSON payload.
2. It saves all measurements to the PostgreSQL database.
3. It returns **HTTP 201** to confirm that the data was successfully processed.
4. If something goes wrong (e.g., database connection failure), the server returns **HTTP 503**, and the gateway will automatically retry sending the data later.

<figure><img src="/files/uPqHiHt348AqEFDmLWxj" alt=""><figcaption></figcaption></figure>

{% stepper %}
{% step %}

### Install the required Python components

To run the server, you will need:

* **Flask** – a micro-framework for building web applications\
  Install it via PyCharm or using:

  ```
  pip install -U Flask
  ```
* **psycopg2** – a popular PostgreSQL adapter for Python\
  Install using:

  ```
  pip install psycopg2
  ```

{% endstep %}

{% step %}

### Run the script

Copy the code below into a `.py` file. Update the database credentials, run the script, and the server will begin listening for data from the Efento Gateway.

{% code expandable="true" %}

```python
import psycopg2
from flask import Flask, request, Response, json, g

app = Flask(__name__)

# Enter your database host, database user, database password and database name
DATABASE_HOST = 'DATABASE_HOST'
DATABASE_USER = 'DATABASE_USER'
DATABASE_PASSWORD = 'DATABASE_PASSWORD'
DATABASE_NAME = 'DATABASE_NAME'

# Making the initial connection:
conn = psycopg2.connect(
    dbname=DATABASE_NAME,
    user=DATABASE_USER,
    host=DATABASE_HOST,
    password=DATABASE_PASSWORD
)

# Set up "/api/v4/measurements" endpoint, which will be receiving the data sent by Efento Gateway using POST method.
@app.route('/api/v4/measurements', methods=['POST'])
def respond():
    data = request.json
    record = []
    response_handle = []

    # iteration in list data/measurement
    for measurement in data['measurements']:
        # iteration in list data/measurement/params, creating a list of sensor parameters(measured_at,serial,battery) and measurement results
        for param in measurement['params']:
            record.extend([(measurement['measured_at'], measurement['serial'], measurement['battery'], param['type'],
                            param['value'])])
        response_handle.append(measurement['response_handle'])
    response = json.dumps(({'Y': response_handle, 'N': []}))

    measurements = "INSERT INTO measurements(measured_at, serial_number, low_battery, type, value) VALUES (%s, %s, %s, %s, %s)"
    with conn.cursor() as cur:
        try:
            # inserting a list of sensor parameters and measurement to table in PostgresSQL
            cur.executemany(measurements, record)
            conn.commit()
            cur.close()
        except (Exception, psycopg2.DatabaseError) as error:
            print(error)
            return Response(status="503")
    return Response(response, status="201")

# Start the application on Your port. Default port 5000
if __name__ == "__main__":
    app.run(host='0.0.0.0', port=5000)
```

{% endcode %}
{% endstep %}

{% step %}

### Configure Efento Gateway

#### Ethernet Gateway

1. Log in to the Efento Gateway web panel. Navigate to:\
   **Settings → Server settings**
2. In **Connection to Server**, select **Custom Settings**.
3. Enter the **server address** (your PC/server IP or domain) in the *Server Address* field.
4. Set the **Server Port** to `5000`.
5. Switch **TLS OFF** for this tutorial.

<figure><img src="/files/XzbqUTv5V28FrCIjnAJO" alt=""><figcaption></figcaption></figure>

{% hint style="warning" %}
When TLS is disabled, data is sent unencrypted. For production deployments, always [upload your server certificate in the CA Certificate](/efento-gateways/ethernet-gateway/other-settings.md#custom-ca-certificates) tab and enable encrypted HTTPS communication (TLS - ON).

For development or demonstration purposes you may [use a self-signed certificate](/efento-gateways/integration/self-signing-ca-certificate.md).
{% endhint %}
{% endstep %}
{% endstepper %}

## Results

Once the Python script is running, all data sent from the Efento Gateway will be saved in your PostgreSQL database.

To view measurements:

1. Open **pgAdmin 4**
2. Select your database
3. Go to **Tools → Query Tool**
4. Enter and execute:

```sql
SELECT * FROM measurements;
```

You will now see all measurements received from the Efento Gateway stored in your database.

<figure><img src="/files/8AhQOZmlpshjr4I8yRjw" alt=""><figcaption></figcaption></figure>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.efento.io/efento-gateways/integration/example-server-application-in-python.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
