Skip to content

Create a sample app for clickhouse #389

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Jun 2, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions sample-apps/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,6 @@ Overview :
- `flask-mssql/` is a Flask app using MSSQL.
- It runs **single-threaded**
- Runs on 8104. Without Aikido runs on 8105
- `flask-clickhouse-uwsgi/` is a Flask UWSGI app using Clickhouse
- It runs **multi-threaded**
- Runs on 8106. Without Aikido runs on 8107
6 changes: 6 additions & 0 deletions sample-apps/databases/clickhouse_init.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
CREATE TABLE IF NOT EXISTS dogs (
id UUID DEFAULT generateUUIDv4(),
dog_name String,
isAdmin UInt8
) ENGINE = MergeTree()
ORDER BY id;
17 changes: 17 additions & 0 deletions sample-apps/databases/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,25 @@ services:
- "1433:1433"
volumes:
- mssql_db_data:/var/opt/mssql
clickhouse_database:
image: yandex/clickhouse-server
container_name: sample_clickhouse_db
restart: always
volumes:
- clickhouse_data:/var/lib/clickhouse
- ./clickhouse_init.sql:/docker-entrypoint-initdb.d/clickhouse_init.sql
ports:
- "8123:8123"
- "9000:9000"
environment:
CLICKHOUSE_USER: 'default'
CLICKHOUSE_PASSWORD: ''
CLICKHOUSE_DB: 'db'


volumes:
mysql_db_data:
postgres_db_data:
mongo_db_data:
mssql_db_data:
clickhouse_data:
21 changes: 21 additions & 0 deletions sample-apps/flask-clickhouse-uwsgi/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
.PHONY: clean
clean:
@poetry env remove $(shell poetry env list | grep 'Activated' | awk '{print $$1}')

.PHONY: install
install:
poetry install --quiet

.PHONY: run
run: install
@echo "Running sample app flask-clickhouse-uwsgi with Zen on port 8106"
AIKIDO_DEBUG=true AIKIDO_BLOCK=true AIKIDO_TOKEN="AIK_secret_token" \
AIKIDO_REALTIME_ENDPOINT="http://localhost:5000/" \
AIKIDO_ENDPOINT="http://localhost:5000/" AIKIDO_DISABLE=0 \
poetry run uwsgi --ini uwsgi.ini

.PHONY: runZenDisabled
runZenDisabled: install
@echo "Running sample app flask-clickhouse-uwsgi without Zen on port 8107"
AIKIDO_DISABLE=1 \
poetry run uwsgi --ini uwsgi2.ini
13 changes: 13 additions & 0 deletions sample-apps/flask-clickhouse-uwsgi/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Flask Sample app with uWSGI & Clickhouse
It runs 4 processes (**multi-process**) which handle requests **multi-threaded**

## Getting Started
Run :
```bash
make run # Runs app with zen
make runZenDisabled # Runs app with zen disabled.
```

- You'll be able to access the Flask Server at : [localhost:8106](http://localhost:8106)
- To Create a reference test dog use `http://localhost:8106/create/doggo`
- To test a sql injection enter the following dog name : `Malicious dog', 1); -- `
40 changes: 40 additions & 0 deletions sample-apps/flask-clickhouse-uwsgi/app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import aikido_zen # Aikido package import
aikido_zen.protect()

from flask import Flask, render_template, request
from clickhouse_driver import Client

app = Flask(__name__)

# Configure ClickHouse client
clickhouse_client = Client(host='127.0.0.1', port=9000, user='default', password='', database='default')

@app.route("/")
def homepage():
# Fetch all dogs from ClickHouse
dogs = clickhouse_client.execute("SELECT * FROM dogs")
return render_template('index.html', title='Homepage', dogs=dogs)

@app.route('/dogpage/<string:dog_id>')
def get_dogpage(dog_id):
# Fetch a specific dog by ID from ClickHouse
dog = clickhouse_client.execute("SELECT * FROM dogs WHERE id = '{}'".format(dog_id))
if dog:
dog = dog[0] # Get the first result
return render_template('dogpage.html', title='Dog', dog=dog, isAdmin=("Yes" if dog[2] else "No"))
else:
return "Dog not found", 404

@app.route("/create", methods=['GET'])
def show_create_dog_form():
return render_template('create_dog.html')

@app.route("/create", methods=['POST'])
def create_dog():
dog_name = request.form['dog_name']
# Insert a new dog into ClickHouse
clickhouse_client.execute("INSERT INTO dogs (dog_name, isAdmin) VALUES ('{}' , 0)".format(dog_name))
return f'Dog {dog_name} created successfully'

if __name__ == '__main__':
app.run()
977 changes: 977 additions & 0 deletions sample-apps/flask-clickhouse-uwsgi/poetry.lock

Large diffs are not rendered by default.

22 changes: 22 additions & 0 deletions sample-apps/flask-clickhouse-uwsgi/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
[project]
name = "flask-clickhouse-uwsgi-app"
version = "0.1.0"
description = "Sample app Flask & Clickhouse"
requires-python = ">3.9.1,<4.0"
dependencies = [
"flask (>=3.1.0,<4.0.0)",
"cryptography (>=44.0.0,<45.0.0)",
"aikido_zen",
"uwsgi (>=2.0.28,<3.0.0)",
"clickhouse-driver (>=0.2.0,<1.0.0)"
]

[build-system]
requires = ["poetry-core>=2.0.0,<3.0.0"]
build-backend = "poetry.core.masonry.api"

[tool.poetry]
package-mode = false

[tool.poetry.dependencies]
aikido_zen = { path = "../../" }
17 changes: 17 additions & 0 deletions sample-apps/flask-clickhouse-uwsgi/templates/create_dog.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Create Dog</title>
</head>
<body>
<h1>Create a Dog</h1>
<form action="/create" method="post">
<label for="dog_name">Dog Name:</label>
<input type="text" id="dog_name" name="dog_name" required>
<button type="submit">Create Dog</button>
</form>
</body>
</html>
25 changes: 25 additions & 0 deletions sample-apps/flask-clickhouse-uwsgi/templates/dogpage.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<!DOCTYPE html>
<html>
<head>
<title>{{ title }}</title>
<style>
body {
font-family: sans-serif;
}
h1 {
font-family: monospace;
text-align: center;
border: 1px solid black;
border-left: none;
border-right: none;
margin: 4px;
}
</style>
</head>
<body>
<h1>{{ title }}</h1>
<p><em>Name :</em> {{dog[1]}}</p>
<p><em>Is admin dog? </em>{{ isAdmin }}</p>
<p><em>ID :</em> {{dog[0]}}</p>
</body>
</html>
48 changes: 48 additions & 0 deletions sample-apps/flask-clickhouse-uwsgi/templates/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<!DOCTYPE html>
<html>
<head>
<title>{{ title }}</title>
<style>
body {
font-family: sans-serif;
}
/* Style for the list */
ul {
list-style-type:disc;
}

/* Style for list items */
li {
margin-bottom: 10px;
}

/* Style for links */
a {
text-decoration: none;
color: #48507f;
}

/* Hover effect for links */
a:hover {
color: #007bff;
}
h1 {
font-family: monospace;
text-align: center;
border: 1px solid black;
border-left: none;
border-right: none;
margin: 4px;
}
</style>
</head>
<body>
<h1>{{ title }}</h1>
<h2>List</h2>
<ul>
{% for dog in dogs %}
<li><a href="/dogpage/{{ dog[0] }}">{{ dog[1] }}</a></li>
{% endfor %}
</ul>
</body>
</html>
10 changes: 10 additions & 0 deletions sample-apps/flask-clickhouse-uwsgi/uwsgi.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[uwsgi]
module = app:app
master = true
processes = 4
http = 0.0.0.0:8106

# Log settings
log-slow = true
log-level = debug
log-format = %(addr) - %(user) [%(ltime)] "%(method) %(uri) %(proto)" %(status) %(size) "%(referer)" "%(uagent)"
10 changes: 10 additions & 0 deletions sample-apps/flask-clickhouse-uwsgi/uwsgi2.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[uwsgi]
module = app:app
master = true
processes = 4
http = 0.0.0.0:8107

# Log settings
log-slow = true
log-level = debug
log-format = %(addr) - %(user) [%(ltime)] "%(method) %(uri) %(proto)" %(status) %(size) "%(referer)" "%(uagent)"
Loading