Skip to content

Commit 42dd44d

Browse files
author
Atul Rajput
committed
Add Flask, SQLite Sample App
Signed-off-by: Atul Rajput <eatulrajput.com>
1 parent 6e8a620 commit 42dd44d

File tree

15 files changed

+643
-0
lines changed

15 files changed

+643
-0
lines changed

flask-sqlite/.coverage.keploy

52 KB
Binary file not shown.

flask-sqlite/.coveragerc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
[run]
2+
omit =
3+
/usr/*
4+
sigterm = true

flask-sqlite/.gitignore

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# Python bytecode
2+
__pycache__/
3+
*.py[cod]
4+
*.pyo
5+
6+
# SQLite DB file (do not commit local dev DB)
7+
*.db
8+
instance/
9+
10+
# Keploy reports (tests are OK, reports are not needed)
11+
keploy/reports/
12+
13+
# Coverage reports
14+
coverage.*
15+
*.cover
16+
.hypothesis/
17+
18+
# Keploy traces/cache
19+
*.log
20+
keploy/test-set-*/coverage.*
21+
keploy/test-set-*/mocks/
22+
23+
# Environment files
24+
.env
25+
.venv/
26+
env/
27+
venv/
28+
29+
# IDE files
30+
.vscode/
31+
.idea/
32+
33+
# macOS/Linux system files
34+
.DS_Store
35+
Thumbs.db

flask-sqlite/README.md

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
# Flask + SQLite Sample App with Keploy Integration
2+
3+
This is a simple **Student Management REST API** built using Python's Flask framework and SQLite for storage. It demonstrates basic **CRUD operations** (Create, Read, Update, Delete) and showcases how to write **API tests with [Keploy](https://keploy.io)** by auto-capturing HTTP calls as test cases.
4+
5+
---
6+
7+
## 🚀 Features
8+
9+
- 🧑 Add, retrieve, update, and delete students
10+
- 💾 Uses SQLite — no external DB setup required
11+
- 🔌 RESTful API with JSON input/output
12+
- ✅ Auto-generate test cases using [Keploy CLI](https://docs.keploy.io)
13+
- 🔄 Replay & validate API responses with Keploy
14+
15+
---
16+
17+
## 📦 Tech Stack
18+
19+
- **Flask** — Lightweight web framework
20+
- **Flask-SQLAlchemy** — ORM for SQLite
21+
- **SQLite** — Built-in relational DB
22+
- **Keploy** — Testing toolkit for API auto-mocking and regression testing
23+
24+
---
25+
26+
## 🛠 Installation
27+
28+
1. **Clone the repository**
29+
```bash
30+
git clone https://github.com/<your-username>/samples-python.git
31+
cd samples-python/flask-sqlite
32+
```
33+
34+
2. Set up virtual environment (optional)
35+
```bash
36+
python3 -m venv venv
37+
source venv/bin/activate
38+
```
39+
40+
3. Install Dependencies
41+
42+
```bash
43+
pip install -r requirements.txt
44+
```
45+
4. Run the Flask app
46+
47+
```bash
48+
python app.py
49+
```
50+
---
51+
52+
## API Endpoints
53+
54+
```bash
55+
56+
| Method | Endpoint | Description |
57+
| ------ | ---------------- | -------------------- |
58+
| GET | `/students` | Get all students |
59+
| POST | `/students` | Add a new student |
60+
| PUT | `/students/<id>` | Update student by ID |
61+
| DELETE | `/students/<id>` | Delete student by ID |
62+
63+
```
64+
---
65+
66+
## Sample Curl Commands
67+
68+
### Add a student
69+
70+
```bash
71+
curl -X POST http://localhost:5000/students \
72+
-H "Content-Type: application/json" \
73+
-d '{"name": "Alice", "age": 21}'
74+
75+
# Get all students
76+
curl http://localhost:5000/students
77+
78+
# Update student
79+
curl -X PUT http://localhost:5000/students/1 \
80+
-H "Content-Type: application/json" \
81+
-d '{"name": "Alice Updated", "age": 22}'
82+
83+
# Delete student
84+
curl -X DELETE http://localhost:5000/students/1
85+
86+
```
87+
---
88+
89+
## Running Keploy Tests
90+
91+
Step 1: Record Tests
92+
Start Keploy in record mode:
93+
94+
```bash
95+
keploy record --command "python app.py"
96+
```
97+
Send some API requests via curl or Postman to generate test cases.
98+
99+
Step 2: Replay Tests
100+
After recording, stop the app and run:
101+
102+
```bash
103+
keploy test --command "python app.py"
104+
```
105+
> Keploy will replay the previously captured requests and validate responses.
106+
107+
## Folder Structure
108+
109+
```bash
110+
flask-sqlite/
111+
├── app.py # Flask app entry point
112+
├── models.py # Student model
113+
├── requirements.txt # Python dependencies
114+
├── keploy.yml # Keploy config file
115+
├── keploy/ # Auto-generated test cases
116+
└── README.md # You are here!
117+
```
118+
---
119+
120+
## Contributing
121+
> Want to improve or add another example (e.g. FastAPI, SQLModel, etc.)? Contributions are welcome! Fork this repo, create your example folder, and submit a PR.
122+
123+
## About Keploy
124+
Keploy is a developer-friendly open-source testing toolkit that auto-generates test cases from API calls in real-time and replays them to catch regressions — without writing any test code.
125+
126+
> Built with ❤️ for the Open Source Community.

flask-sqlite/app.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
from flask import Flask, request, jsonify
2+
from models import db, Student
3+
4+
5+
app = Flask(__name__)
6+
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///students.db'
7+
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
8+
9+
db.init_app(app)
10+
11+
@app.route('/')
12+
def home():
13+
return jsonify({"message": "Flask Student API"}), 200
14+
15+
@app.route('/students', methods=['GET'])
16+
def get_students():
17+
students = Student.query.all()
18+
return jsonify([
19+
{"id": s.id, "name": s.name, "age": s.age} for s in students
20+
])
21+
22+
@app.route('/students', methods=['POST'])
23+
def add_student():
24+
data = request.get_json()
25+
student = Student(name=data['name'], age=data['age'])
26+
db.session.add(student)
27+
db.session.commit()
28+
return jsonify({"id": student.id}), 201
29+
30+
@app.route('/students/<int:id>', methods=['PUT'])
31+
def update_student(id):
32+
student = Student.query.get_or_404(id)
33+
data = request.get_json()
34+
student.name = data['name']
35+
student.age = data['age']
36+
db.session.commit()
37+
return jsonify({"message": "Updated"}), 200
38+
39+
@app.route('/students/<int:id>', methods=['DELETE'])
40+
def delete_student(id):
41+
student = Student.query.get_or_404(id)
42+
db.session.delete(student)
43+
db.session.commit()
44+
return jsonify({"message": "Deleted"}), 200
45+
46+
if __name__ == '__main__':
47+
with app.app_context():
48+
db.create_all()
49+
app.run(debug=True)
50+

flask-sqlite/keploy.yml

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
# Generated by Keploy (2.6.11)
2+
path: ""
3+
appId: 0
4+
appName: flask-sqlite
5+
command: .venv/bin/python app.py
6+
templatize:
7+
testSets: []
8+
port: 0
9+
e2e: false
10+
dnsPort: 26789
11+
proxyPort: 16789
12+
debug: false
13+
disableTele: false
14+
disableANSI: false
15+
containerName: ""
16+
networkName: ""
17+
buildDelay: 30
18+
test:
19+
selectedTests: {}
20+
globalNoise:
21+
global: {}
22+
test-sets: {}
23+
delay: 5
24+
host: ""
25+
port: 0
26+
apiTimeout: 5
27+
skipCoverage: false
28+
coverageReportPath: ""
29+
ignoreOrdering: true
30+
mongoPassword: default@123
31+
language: ""
32+
removeUnusedMocks: false
33+
fallBackOnMiss: false
34+
jacocoAgentPath: ""
35+
basePath: ""
36+
mocking: true
37+
ignoredTests: {}
38+
disableLineCoverage: false
39+
disableMockUpload: true
40+
useLocalMock: false
41+
updateTemplate: false
42+
mustPass: false
43+
maxFailAttempts: 5
44+
maxFlakyChecks: 1
45+
record:
46+
filters: []
47+
basePath: ""
48+
recordTimer: 0s
49+
configPath: ""
50+
bypassRules: []
51+
generateGithubActions: false
52+
keployContainer: keploy-v2
53+
keployNetwork: keploy-network
54+
cmdType: native
55+
contract:
56+
services: []
57+
tests: []
58+
path: ""
59+
download: false
60+
generate: false
61+
driven: consumer
62+
mappings:
63+
servicesMapping: {}
64+
self: s1
65+
inCi: false
66+
67+
# Visit [https://keploy.io/docs/running-keploy/configuration-file/] to learn about using keploy through configration file.

flask-sqlite/keploy/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
2+
/reports/
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
# Generated by Keploy (2.6.11)
2+
version: api.keploy.io/v1beta1
3+
kind: Http
4+
name: test-1
5+
spec:
6+
metadata: {}
7+
req:
8+
method: GET
9+
proto_major: 1
10+
proto_minor: 1
11+
url: http://localhost:5000/students
12+
header:
13+
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
14+
Accept-Encoding: gzip, deflate, br, zstd
15+
Accept-Language: en-US,en;q=0.5
16+
Connection: keep-alive
17+
Cookie: _ga_9C3YK4FNWZ=GS2.1.s1746835762$o1$g1$t1746835798$j0$l0$h0; _ga=GA1.1.370021656.1746835763; _clck=1e6823p%7C2%7Cfww%7C0%7C1996; __hstc=181257784.e3804237d83ad93b9ef5fdbdd48354d1.1750295949745.1750295949745.1750295949745.1; hubspotutk=e3804237d83ad93b9ef5fdbdd48354d1; __hssrc=1; _clsk=dk2mvr%7C1750295950556%7C1%7C1%7Cl.clarity.ms%2Fcollect; messagesUtk=a1a71bf707fd412b8e4bf788336568d9
18+
Host: localhost:5000
19+
Priority: u=0, i
20+
Sec-Fetch-Dest: document
21+
Sec-Fetch-Mode: navigate
22+
Sec-Fetch-Site: none
23+
Sec-Fetch-User: ?1
24+
Upgrade-Insecure-Requests: "1"
25+
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:139.0) Gecko/20100101 Firefox/139.0
26+
body: ""
27+
timestamp: 2025-06-19T09:36:00.825424089+05:30
28+
resp:
29+
status_code: 200
30+
header:
31+
Content-Length: "3"
32+
Content-Type: application/json
33+
Date: Thu, 19 Jun 2025 04:06:00 GMT
34+
Server: Werkzeug/3.1.3 Python/3.12.3
35+
body: |
36+
[]
37+
status_message: OK
38+
proto_major: 0
39+
proto_minor: 0
40+
timestamp: 2025-06-19T09:36:02.898108619+05:30
41+
objects: []
42+
assertions:
43+
noise:
44+
header.Date: []
45+
created: 1750305962
46+
curl: |
47+
curl --request GET \
48+
--url http://localhost:5000/students \
49+
--header 'Sec-Fetch-User: ?1' \
50+
--header 'Cookie: _ga_9C3YK4FNWZ=GS2.1.s1746835762$o1$g1$t1746835798$j0$l0$h0; _ga=GA1.1.370021656.1746835763; _clck=1e6823p%7C2%7Cfww%7C0%7C1996; __hstc=181257784.e3804237d83ad93b9ef5fdbdd48354d1.1750295949745.1750295949745.1750295949745.1; hubspotutk=e3804237d83ad93b9ef5fdbdd48354d1; __hssrc=1; _clsk=dk2mvr%7C1750295950556%7C1%7C1%7Cl.clarity.ms%2Fcollect; messagesUtk=a1a71bf707fd412b8e4bf788336568d9' \
51+
--header 'Accept-Language: en-US,en;q=0.5' \
52+
--header 'Sec-Fetch-Dest: document' \
53+
--header 'Sec-Fetch-Mode: navigate' \
54+
--header 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8' \
55+
--header 'Priority: u=0, i' \
56+
--header 'Accept-Encoding: gzip, deflate, br, zstd' \
57+
--header 'User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:139.0) Gecko/20100101 Firefox/139.0' \
58+
--header 'Upgrade-Insecure-Requests: 1' \
59+
--header 'Sec-Fetch-Site: none' \
60+
--header 'Host: localhost:5000' \
61+
--header 'Connection: keep-alive' \

0 commit comments

Comments
 (0)