From 4aebd9ab45576e7dc8667118c8ea32cb3a1dc400 Mon Sep 17 00:00:00 2001 From: Animesh Pathak Date: Fri, 14 Jun 2024 09:39:13 +0000 Subject: [PATCH 1/2] Revert "fix: docker and readme instruction" This reverts commit 1195b762fe8bf9e222de57676ceb1bb0bb84c4c5. --- fastapi-postgres/README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/fastapi-postgres/README.md b/fastapi-postgres/README.md index eca7442..d902662 100644 --- a/fastapi-postgres/README.md +++ b/fastapi-postgres/README.md @@ -32,8 +32,6 @@ Keploy can be installed on Linux directly and on Windows with the help of WSL. B docker-compose up -d ``` -> Note: Update the `SQLALCHEMY_DATABASE_URL` in the `database.py` file if you want to use a keploy with docker. - ### Capture the Testcases This command will start the recording of API calls using ebpf:- From b96e84bc1595fb90f8de060db2693e2a937a3115 Mon Sep 17 00:00:00 2001 From: Animesh Pathak Date: Fri, 14 Jun 2024 09:46:44 +0000 Subject: [PATCH 2/2] fix: refactor flask-mongo change Signed-off-by: Animesh Pathak --- flask-mongo/Dockerfile | 6 +- flask-mongo/README.md | 643 +++++++++++++++++++++++++++++---- flask-mongo/app.py | 80 ++-- flask-mongo/docker-compose.yml | 6 +- flask-mongo/requirements.txt | 10 +- 5 files changed, 613 insertions(+), 132 deletions(-) diff --git a/flask-mongo/Dockerfile b/flask-mongo/Dockerfile index 961d93b..f892efb 100644 --- a/flask-mongo/Dockerfile +++ b/flask-mongo/Dockerfile @@ -1,5 +1,5 @@ # Use the official Python image as the base image -FROM python:3.10.12 +FROM python:3.9 # Set the working directory within the container WORKDIR /app @@ -11,7 +11,7 @@ COPY . . RUN pip3 install -r requirements.txt # Expose the port that the Flask app will run on -EXPOSE 5000 +EXPOSE 6000 # Start the Flask application -CMD ["python3", "app.py"] +CMD ["python3", "app.py"] \ No newline at end of file diff --git a/flask-mongo/README.md b/flask-mongo/README.md index 8a6cd42..526fad3 100644 --- a/flask-mongo/README.md +++ b/flask-mongo/README.md @@ -1,103 +1,600 @@ -# Sample Flask+Mongo app to demo Keploy +This application is a simple student management API built using Python's Flask framework and MongoDB for data storage. It allows you to perform basic CRUD (Create, Read, Update, Delete) operations on student records. The API supports CORS (Cross-Origin Resource Sharing) to facilitate cross-domain requests. -## Clone the sample flask-mongo application +## Table of Contents -```bash -git clone https://github.com/keploy/samples-python.git && cd samples-python/flask-mongo-local -``` - -## Install all dependencies +# Introduction -```bash -pip install -r requirements.txt -``` +๐Ÿช„ Dive into the world of Student CRUD Apps and see how seamlessly Keploy integrated with [Flask](https://flask.palletsprojects.com/en/3.0.x/) and [MongoDB](https://www.mongodb.com/). Buckle up, it's gonna be a fun ride! ๐ŸŽข -## Start the MongoDB server +## Pre-Requisite ๐Ÿ› ๏ธ -```bash -sudo service mongod start -``` +- Install WSL (`wsl --install`) for Windows Windows. -## Setup Keploy +## Optional ๐Ÿ› ๏ธ -Let's get started by setting up the Keploy alias with this command: +- Install Colima( `brew install colima && colima start` ) for MacOS MacOs. +## Get Started! ๐ŸŽฌ -```bash -curl --silent -O -L https://keploy.io/install.sh && source install.sh -``` +## Setup the MongoDB Database ๐Ÿ“ฆ -You should see something like this: +Create a docker network, run - ```bash - โ–“โ–ˆโ–ˆโ–“โ–„ - โ–“โ–“โ–“โ–“โ–ˆโ–ˆโ–“โ–ˆโ–“โ–„ - โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–“โ–’ - โ–€โ–“โ–“โ–ˆโ–ˆโ–ˆโ–„ โ–„โ–„ โ–„ โ–Œ - โ–„โ–Œโ–Œโ–“โ–“โ–ˆโ–ˆโ–ˆโ–ˆโ–„ โ–ˆโ–ˆ โ–“โ–ˆโ–€ โ–„โ–Œโ–€โ–„ โ–“โ–“โ–Œโ–„ โ–“โ–ˆ โ–„โ–Œโ–“โ–“โ–Œโ–„ โ–Œโ–Œ โ–“ - โ–“โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–Œโ–“โ–“ โ–ˆโ–ˆโ–“โ–ˆโ–„ โ–“โ–ˆโ–„โ–“โ–“ โ–โ–ˆโ–Œ โ–ˆโ–ˆ โ–“โ–ˆ โ–ˆโ–Œ โ–ˆโ–ˆ โ–ˆโ–Œ โ–ˆโ–“ - โ–“โ–“โ–“โ–“โ–€โ–€โ–€โ–€โ–“โ–“โ–“โ–“โ–“โ–“โ–Œ โ–ˆโ–ˆ โ–ˆโ–“ โ–“โ–Œโ–„โ–„ โ–โ–ˆโ–“โ–„โ–“โ–ˆโ–€ โ–ˆโ–“โ–ˆ โ–€โ–ˆโ–„โ–„โ–ˆโ–€ โ–ˆโ–“โ–ˆ - โ–“โ–Œ โ–โ–ˆโ–Œ โ–ˆโ–Œ - โ–“ - -Keploy CLI - -Available Commands: - example Example to record and test via keploy - generate-config generate the keploy configuration file - record record the keploy testcases from the API calls - test run the recorded testcases and execute assertions - update Update Keploy - -Flags: - --debug Run in debug mode - -h, --help help for keploy - -v, --version version for keploy - -Use "keploy [command] --help" for more information about a command. +docker network create backend ``` -## Lights, Camera, Record! ๐ŸŽฅ - -To initiate the recording of API calls, execute this command in your terminal: +Start the MongoDB instance- ```bash -keploy record -c "python3 app.py" +docker run -p 27017:27017 -d --network backend --name mongo mongo ``` -Now, your app will start running, and you have to make some API calls!! - -And once you are done, you can stop the recording and give yourself a pat on the back! With that simple spell, you've conjured up a test case with a mock! Explore the **keploy** directory and you'll discover your handiwork in `tests` directory and `mocks.yml`. - -## Check Test Coverage - -We have a `test-app.py` where all the unit test cases has been written. Now using Keploy, we can check it's code coverage!! -Now to run your unit tests with Keploy, you can run the command given below: +## Clone a simple Student Management API ๐Ÿงช ```bash -python3 -m coverage run -p --data-file=.coverage.unit -m pytest -s test_keploy.py test_app.py +git clone https://github.com/keploy/samples-python.git && cd samples-python/flask-mongo ``` -To combine the coverage from the unit tests, and Keploy's API tests we can use the command below: +## Installation ๐Ÿ“ฅ -```bash -python3 -m coverage combine -``` +Depending on your OS, choose your adventure: -Finally, to generate the coverage report for the test run, you can run: +-
+ Linux Linux or Windows Windows -```bash -python3 -m coverage report -``` + Alright, let's equip ourselves with the **latest Keploy binary**: -and if you want the coverage in an html file, you can run: + ```bash + curl --silent --location "https://github.com/keploy/keploy/releases/latest/download/keploy_linux_amd64.tar.gz" | tar xz -C /tmp -```bash -python3 -m coverage html -``` + sudo mkdir -p /usr/local/bin && sudo mv /tmp/keploy /usr/local/bin && keploy + ``` + + If everything goes right, your screen should look a bit like this: -## Wrapping it up ๐ŸŽ‰ + Moving on... +
+ Run App with Docker Container Docker -Congrats on the journey so far! You've seen Keploy's power, flexed your coding muscles, and had a bit of fun too! Now, go out there and keep exploring, innovating, and creating! Remember, with the right tools and a sprinkle of fun, anything's possible.๐Ÿ˜Š๐Ÿš€ + #### Add alias for Keploy: -Happy coding! โœจ๐Ÿ‘ฉโ€๐Ÿ’ป๐Ÿ‘จโ€๐Ÿ’ปโœจ + ```bash + alias keploy='sudo docker run --pull always --name keploy-v2 -p 16789:16789 --privileged --pid=host -it -v "$(pwd)":/files -v /sys/fs/cgroup:/sys/fs/cgroup -v /sys/kernel/debug:/sys/kernel/debug -v /sys/fs/bpf:/sys/fs/bpf -v /var/run/docker.sock:/var/run/docker.sock -v '"$HOME"'/.keploy-config:/root/.keploy-config -v '"$HOME"'/.keploy:/root/.keploy --rm ghcr.io/keploy/keploy' + ``` + + ### Lights, Camera, Record! ๐ŸŽฅ + + Build the app image: + + ```bash + docker build -t flask-app:1.0 . + ``` + + Capture the test-cases- + + ```shell + keploy record -c "docker run -p 6000:6000 --name flask-app --network backend flask-app:1.0" + ``` + + ๐Ÿ”ฅ**Make some API calls**. Postman, Hoppscotch or even curl - take your pick! + + Let's make URLs short and sweet: + + ### Generate testcases + + To generate testcases we just need to **make some API calls.** + + **1. Make a POST request** + + ```bash + curl -X PUT -H "Content-Type: application/json" -d '{"name": "Jane Smith", "age": 21}' http://localhost:6000/students/12345 + ``` + + **2. Make a GET request** + + ```bash + curl http://localhost:6000/students + ``` + + **3. Make a PUT request** + + ```bash + curl -X PUT -H "Content-Type: application/json" -d '{"name": "Jane Smith", "age": 21}' http://localhost:6000/students/12345 + ``` + + **4. Make a GET request** + + ```bash + curl http://localhost:6000/students/12345 + ``` + + **5. Make a DELETE request** + + ```bash + curl -X DELETE http://localhost:6000/students/12345 + ``` + + Give yourself a pat on the back! With that simple spell, you've conjured up a test case with a mock! Explore the **Keploy directory** and you'll discover your handiwork in `test-1.yml` and `mocks.yml`. + + ```yaml + version: api.keploy.io/v1beta2 + kind: Http + name: test-1 + spec: + metadata: {} + req: + method: POST + proto_major: 1 + proto_minor: 1 + url: http://localhost:6000/students + header: + Accept: "*/*" + Content-Length: "56" + Content-Type: application/json + Host: localhost:6000 + User-Agent: curl/7.81.0 + body: '{"student_id": "12344", "name": "John Doeww", "age": 10}' + body_type: "" + timestamp: 2023-11-13T13:02:32.241333562Z + resp: + status_code: 200 + header: + Content-Length: "48" + Content-Type: application/json + Date: Mon, 13 Nov 2023 13:02:32 GMT + Server: Werkzeug/2.2.2 Python/3.9.18 + body: | + { + "message": "Student created successfully" + } + body_type: "" + status_message: "" + proto_major: 0 + proto_minor: 0 + timestamp: 2023-11-13T13:02:34.752123715Z + objects: [] + assertions: + noise: + - header.Date + created: 1699880554 + curl: |- + curl --request POST \ + --url http://localhost:6000/students \ + --header 'Host: localhost:6000' \ + --header 'User-Agent: curl/7.81.0' \ + --header 'Accept: */*' \ + --header 'Content-Type: application/json' \ + --data '{"student_id": "12344", "name": "John Doeww", "age": 10}' + ``` + + This is how `mocks.yml` generated would look like:- + + ```yaml + version: api.keploy.io/v1beta2 + kind: Mongo + name: mocks + spec: + metadata: + operation: '{ OpMsg flags: 0, sections: [{ SectionSingle msg: {"find":"students","filter":{"student_id":"12345"},"projection":{"_id":{"$numberInt":"0"}},"limit":{"$numberInt":"1"},"singleBatch":true,"lsid":{"id":{"$binary":{"base64":"vPKsEFRdTLytlbnyVimqIA==","subType":"04"}}},"$db":"studentsdb"} }], checksum: 0 }' + requests: + - header: + length: 187 + requestId: 2127584089 + responseTo: 0 + Opcode: 2013 + message: + flagBits: 0 + sections: + - '{ SectionSingle msg: {"find":"students","filter":{"student_id":"12345"},"projection":{"_id":{"$numberInt":"0"}},"limit":{"$numberInt":"1"},"singleBatch":true,"lsid":{"id":{"$binary":{"base64":"vPKsEFRdTLytlbnyVimqIA==","subType":"04"}}},"$db":"studentsdb"} }' + checksum: 0 + read_delay: 3469848802 + responses: + - header: + length: 166 + requestId: 154 + responseTo: 2127584089 + Opcode: 2013 + message: + flagBits: 0 + sections: + - '{ SectionSingle msg: {"cursor":{"firstBatch":[{"student_id":"12345","name":"John Doe","age":{"$numberInt":"20"}}],"id":{"$numberLong":"0"},"ns":"studentsdb.students"},"ok":{"$numberDouble":"1.0"}} }' + checksum: 0 + read_delay: 869555 + created: 1699880576 + reqTimestampMock: 2023-11-13T13:02:56.385067848Z + resTimestampMock: 2023-11-13T13:02:56.386374941Z + ``` + + Want to see if everything works as expected? + + #### Run Tests + + Time to put things to the test ๐Ÿงช + + ```shell + keploy test -c "sudo docker run -p 6000:6000 --rm --network backend --name flask-app flask-app:1.0" --delay 10 + ``` + + > The `--delay` flag? Oh, that's just giving your app a little breather (in seconds) before the test cases come knocking. + + Final thoughts? Dive deeper! Try different API calls, tweak the DB response in the `mocks.yml`, or fiddle with the request or response in `test-x.yml`. Run the tests again and see the magic unfold!โœจ๐Ÿ‘ฉโ€๐Ÿ’ป๐Ÿ‘จโ€๐Ÿ’ปโœจ + + ## Wrapping it up ๐ŸŽ‰ + + Congrats on the journey so far! You've seen Keploy's power, flexed your coding muscles, and had a bit of fun too! Now, go out there and keep exploring, innovating, and creating! Remember, with the right tools and a sprinkle of fun, anything's possible.๐Ÿ˜Š๐Ÿš€ + + Happy coding! โœจ๐Ÿ‘ฉโ€๐Ÿ’ป๐Ÿ‘จโ€๐Ÿ’ปโœจ + +
+
+ +
+ Run App on ๐Ÿง Linux + + We'll be running our sample application right on Linux, but just to make things a tad more thrilling, we'll have the database (PostgreSQL) chill on Docker. Ready? Let's get the party started!๐ŸŽ‰ + + ### ๐Ÿ“ผ Roll the Tape - Recording Time! + + Install the dependencies: + + ```bash + pip install -r requirements.txt + ``` + + Now, let's Capture the test-cases- + + In `app.py`, replace the MongoDB connection URL with - `mongodb://0.0.0.0:27017/` + + Ready, set, record! Here's how: + + ```bash + keploy record -c "python3 app.py" + ``` + + Keep an eye out for the `-c `flag! It's the command charm to run the app. + + Alright, magician! With the app alive and kicking, let's weave some test cases. The spell? Making some API calls! Postman, Hoppscotch, or the classic curl - pick your wand. + + ### Generate testcases + + To generate testcases we just need to **make some API calls.** + + **1. Make a POST request** + + ```bash + curl -X PUT -H "Content-Type: application/json" -d '{"name": "Jane Smith", "age": 21}' http://localhost:6000/students/12345 + ``` + + **2. Make a GET request** + + ```bash + curl http://localhost:6000/students + ``` + + **3. Make a PUT request** + + ```bash + curl -X PUT -H "Content-Type: application/json" -d '{"name": "Jane Smith", "age": 21}' http://localhost:6000/students/12345 + ``` + + **4. Make a GET request** + + ```bash + curl http://localhost:6000/students/12345 + ``` + + **5. Make a DELETE request** + + ```bash + curl -X DELETE http://localhost:6000/students/12345 + ``` + + Give yourself a pat on the back! With that simple spell, you've conjured up a test case with a mock! Explore the **Keploy directory** and you'll discover your handiwork in `test-1.yml` and `mocks.yml`. + + ```yaml + version: api.keploy.io/v1beta2 + kind: Http + name: test-1 + spec: + metadata: {} + req: + method: POST + proto_major: 1 + proto_minor: 1 + url: http://localhost:6000/students + header: + Accept: "*/*" + Content-Length: "56" + Content-Type: application/json + Host: localhost:6000 + User-Agent: curl/7.81.0 + body: '{"student_id": "12344", "name": "John Doeww", "age": 10}' + body_type: "" + timestamp: 2023-11-13T13:02:32.241333562Z + resp: + status_code: 200 + header: + Content-Length: "48" + Content-Type: application/json + Date: Mon, 13 Nov 2023 13:02:32 GMT + Server: Werkzeug/2.2.2 Python/3.9.18 + body: | + { + "message": "Student created successfully" + } + body_type: "" + status_message: "" + proto_major: 0 + proto_minor: 0 + timestamp: 2023-11-13T13:02:34.752123715Z + objects: [] + assertions: + noise: + - header.Date + created: 1699880554 + curl: |- + curl --request POST \ + --url http://localhost:6000/students \ + --header 'Host: localhost:6000' \ + --header 'User-Agent: curl/7.81.0' \ + --header 'Accept: */*' \ + --header 'Content-Type: application/json' \ + --data '{"student_id": "12344", "name": "John Doeww", "age": 10}' + ``` + + This is how `mocks.yml` generated would look like:- + + ```yaml + version: api.keploy.io/v1beta2 + kind: Mongo + name: mocks + spec: + metadata: + operation: '{ OpMsg flags: 0, sections: [{ SectionSingle msg: {"find":"students","filter":{"student_id":"12345"},"projection":{"_id":{"$numberInt":"0"}},"limit":{"$numberInt":"1"},"singleBatch":true,"lsid":{"id":{"$binary":{"base64":"vPKsEFRdTLytlbnyVimqIA==","subType":"04"}}},"$db":"studentsdb"} }], checksum: 0 }' + requests: + - header: + length: 187 + requestId: 2127584089 + responseTo: 0 + Opcode: 2013 + message: + flagBits: 0 + sections: + - '{ SectionSingle msg: {"find":"students","filter":{"student_id":"12345"},"projection":{"_id":{"$numberInt":"0"}},"limit":{"$numberInt":"1"},"singleBatch":true,"lsid":{"id":{"$binary":{"base64":"vPKsEFRdTLytlbnyVimqIA==","subType":"04"}}},"$db":"studentsdb"} }' + checksum: 0 + read_delay: 3469848802 + responses: + - header: + length: 166 + requestId: 154 + responseTo: 2127584089 + Opcode: 2013 + message: + flagBits: 0 + sections: + - '{ SectionSingle msg: {"cursor":{"firstBatch":[{"student_id":"12345","name":"John Doe","age":{"$numberInt":"20"}}],"id":{"$numberLong":"0"},"ns":"studentsdb.students"},"ok":{"$numberDouble":"1.0"}} }' + checksum: 0 + read_delay: 869555 + created: 1699880576 + reqTimestampMock: 2023-11-13T13:02:56.385067848Z + resTimestampMock: 2023-11-13T13:02:56.386374941Z + ``` + + Want to see if everything works as expected? + + #### Run Tests + + Time to put things to the test ๐Ÿงช + + ```shell + keploy test -c "python3 app.py" --delay 10 + ``` + + > The `--delay` flag? Oh, that's just giving your app a little breather (in seconds) before the test cases come knocking. + + Final thoughts? Dive deeper! Try different API calls, tweak the DB response in the `mocks.yml`, or fiddle with the request or response in `test-x.yml`. Run the tests again and see the magic unfold!โœจ๐Ÿ‘ฉโ€๐Ÿ’ป๐Ÿ‘จโ€๐Ÿ’ปโœจ + + ## Wrapping it up ๐ŸŽ‰ + + Congrats on the journey so far! You've seen Keploy's power, flexed your coding muscles, and had a bit of fun too! Now, go out there and keep exploring, innovating, and creating! Remember, with the right tools and a sprinkle of fun, anything's possible. ๐Ÿ˜Š๐Ÿš€ + + Happy coding! โœจ๐Ÿ‘ฉโ€๐Ÿ’ป๐Ÿ‘จโ€๐Ÿ’ปโœจ +
+ +
+ +
+ +-
+ MacOS MacOs + + Dive straight in, but first in case you're using **Keploy** with **Colima**, give it a gentle nudge with (`colima start`). Let's make sure it's awake and ready for action! + + ### Add alias for Keploy ๐Ÿฐ: + + For the sake of convenience (and a bit of Mac magic ๐Ÿช„), let's set up a shortcut for Keploy: + + ### Use Keploy with Docker-Desktop + + Note: To run Keploy on MacOS through [Docker](https://docs.docker.com/desktop/release-notes/#4252) the version must be `4.25.2` or above. + + #### Creating Docker Volume + + ```bash + docker volume create --driver local --opt type=debugfs --opt device=debugfs debugfs + ``` + + ```bash + alias keploy='sudo docker run --pull always --name keploy-v2 -p 16789:16789 --privileged --pid=host -it -v "$(pwd)":/files -v /sys/fs/cgroup:/sys/fs/cgroup -v debugfs:/sys/kernel/debug:rw -v /sys/fs/bpf:/sys/fs/bpf -v /var/run/docker.sock:/var/run/docker.sock -v '"$HOME"'/.keploy-config:/root/.keploy-config -v '"$HOME"'/.keploy:/root/.keploy --rm ghcr.io/keploy/keploy' + ``` + + ### Use Keploy with Colima + + ```bash + alias keploy='sudo docker run --pull always --name keploy-v2 -p 16789:16789 --privileged --pid=host -it -v "$(pwd)":/files -v /sys/fs/cgroup:/sys/fs/cgroup -v /sys/kernel/debug:/sys/kernel/debug -v /sys/fs/bpf:/sys/fs/bpf -v /var/run/docker.sock:/var/run/docker.sock -v '"$HOME"'/.keploy-config:/root/.keploy-config -v '"$HOME"'/.keploy:/root/.keploy --rm ghcr.io/keploy/keploy' + ``` + + ### Lights, Camera, Record! ๐ŸŽฅ + + Build the app image: + + ```bash + docker build -t flask-app:1.0 . + ``` + + Capture the test-cases- + + ```shell + keploy record -c "docker run -p 6000:6000 --name DjangoApp --network backend --name flask-app flask-app:1.0" + ``` + + ๐Ÿ”ฅ**Make some API calls**. Postman, Hoppscotch or even curl - take your pick! + + Let's make URLs short and sweet: + + ### Generate testcases + + To generate testcases we just need to **make some API calls.** + + **1. Make a POST request** + + ```bash + curl -X PUT -H "Content-Type: application/json" -d '{"name": "Jane Smith", "age": 21}' http://localhost:6000/students/12345 + ``` + + **2. Make a GET request** + + ```bash + curl http://localhost:6000/students + ``` + + **3. Make a PUT request** + + ```bash + curl -X PUT -H "Content-Type: application/json" -d '{"name": "Jane Smith", "age": 21}' http://localhost:6000/students/12345 + ``` + + **4. Make a GET request** + + ```bash + curl http://localhost:6000/students/12345 + ``` + + **5. Make a DELETE request** + + ```bash + curl -X DELETE http://localhost:6000/students/12345 + ``` + + Give yourself a pat on the back! With that simple spell, you've conjured up a test case with a mock! Explore the **Keploy directory** and you'll discover your handiwork in `test-1.yml` and `mocks.yml`. + + ```yaml + version: api.keploy.io/v1beta2 + kind: Http + name: test-1 + spec: + metadata: {} + req: + method: POST + proto_major: 1 + proto_minor: 1 + url: http://localhost:6000/students + header: + Accept: "*/*" + Content-Length: "56" + Content-Type: application/json + Host: localhost:6000 + User-Agent: curl/7.81.0 + body: '{"student_id": "12344", "name": "John Doeww", "age": 10}' + body_type: "" + timestamp: 2023-11-13T13:02:32.241333562Z + resp: + status_code: 200 + header: + Content-Length: "48" + Content-Type: application/json + Date: Mon, 13 Nov 2023 13:02:32 GMT + Server: Werkzeug/2.2.2 Python/3.9.18 + body: | + { + "message": "Student created successfully" + } + body_type: "" + status_message: "" + proto_major: 0 + proto_minor: 0 + timestamp: 2023-11-13T13:02:34.752123715Z + objects: [] + assertions: + noise: + - header.Date + created: 1699880554 + curl: |- + curl --request POST \ + --url http://localhost:6000/students \ + --header 'Host: localhost:6000' \ + --header 'User-Agent: curl/7.81.0' \ + --header 'Accept: */*' \ + --header 'Content-Type: application/json' \ + --data '{"student_id": "12344", "name": "John Doeww", "age": 10}' + ``` + + This is how `mocks.yml` generated would look like:- + + ```yaml + version: api.keploy.io/v1beta2 + kind: Mongo + name: mocks + spec: + metadata: + operation: '{ OpMsg flags: 0, sections: [{ SectionSingle msg: {"find":"students","filter":{"student_id":"12345"},"projection":{"_id":{"$numberInt":"0"}},"limit":{"$numberInt":"1"},"singleBatch":true,"lsid":{"id":{"$binary":{"base64":"vPKsEFRdTLytlbnyVimqIA==","subType":"04"}}},"$db":"studentsdb"} }], checksum: 0 }' + requests: + - header: + length: 187 + requestId: 2127584089 + responseTo: 0 + Opcode: 2013 + message: + flagBits: 0 + sections: + - '{ SectionSingle msg: {"find":"students","filter":{"student_id":"12345"},"projection":{"_id":{"$numberInt":"0"}},"limit":{"$numberInt":"1"},"singleBatch":true,"lsid":{"id":{"$binary":{"base64":"vPKsEFRdTLytlbnyVimqIA==","subType":"04"}}},"$db":"studentsdb"} }' + checksum: 0 + read_delay: 3469848802 + responses: + - header: + length: 166 + requestId: 154 + responseTo: 2127584089 + Opcode: 2013 + message: + flagBits: 0 + sections: + - '{ SectionSingle msg: {"cursor":{"firstBatch":[{"student_id":"12345","name":"John Doe","age":{"$numberInt":"20"}}],"id":{"$numberLong":"0"},"ns":"studentsdb.students"},"ok":{"$numberDouble":"1.0"}} }' + checksum: 0 + read_delay: 869555 + created: 1699880576 + reqTimestampMock: 2023-11-13T13:02:56.385067848Z + resTimestampMock: 2023-11-13T13:02:56.386374941Z + ``` + + Want to see if everything works as expected? + + #### Run Tests + + Time to put things to the test ๐Ÿงช + + ```shell + keploy test -c "sudo docker run -p 6000:6000 --rm --network backend --name flask-app flask-app:1.0" --delay 10 + ``` + + > The `--delay` flag? Oh, that's just giving your app a little breather (in seconds) before the test cases come knocking. + + Final thoughts? Dive deeper! Try different API calls, tweak the DB response in the `mocks.yml`, or fiddle with the request or response in `test-x.yml`. Run the tests again and see the magic unfold!โœจ๐Ÿ‘ฉโ€๐Ÿ’ป๐Ÿ‘จโ€๐Ÿ’ปโœจ + + ## Wrapping it up ๐ŸŽ‰ + + Congrats on the journey so far! You've seen Keploy's power, flexed your coding muscles, and had a bit of fun too! Now, go out there and keep exploring, innovating, and creating! Remember, with the right tools and a sprinkle of fun, anything's possible.๐Ÿ˜Š๐Ÿš€ + + Happy coding! โœจ๐Ÿ‘ฉโ€๐Ÿ’ป๐Ÿ‘จโ€๐Ÿ’ปโœจ +
\ No newline at end of file diff --git a/flask-mongo/app.py b/flask-mongo/app.py index 730db9f..9e88224 100644 --- a/flask-mongo/app.py +++ b/flask-mongo/app.py @@ -1,56 +1,42 @@ from flask import Flask, request, jsonify from pymongo import MongoClient from flask_cors import CORS -from bson import ObjectId +import collections.abc app = Flask(__name__) cors = CORS(app, resources={r"/api/*": {"origins": "*"}}) -client = MongoClient('mongodb://localhost:27017/task_manager') -db = client['task_manager'] -collection = db['tasks'] - -@app.route('/api/tasks', methods=['POST']) -def create_task(): - data = request.get_json() - task = { - 'title': data['title'], - 'description': data['description'] - } - result = collection.insert_one(task) - return jsonify({'message': 'Task created successfully', 'id': str(result.inserted_id)}), 201 - -@app.route('/api/tasks', methods=['GET']) -def get_all_tasks(): - tasks = [] - for task in collection.find(): - tasks.append({ - 'id': str(task['_id']), - 'title': task['title'], - 'description': task['description'] - }) - return jsonify({'tasks': tasks}) - -@app.route('/api/tasks/', methods=['PUT']) -def update_task(task_id): - data = request.get_json() - updated_task = { - 'title': data['title'], - 'description': data['description'] - } - try: - result = collection.update_one({'_id': ObjectId(task_id)}, {'$set': updated_task}) - if result.modified_count == 0: - return jsonify({'error': 'Task not found or no changes were made'}), 404 - else: - return jsonify({'message': 'Task updated successfully'}) - except Exception as e: - return jsonify({'error': str(e)}), 500 - -@app.route('/api/tasks/', methods=['DELETE']) -def delete_task(task_id): - collection.delete_one({'_id': ObjectId(task_id)}) - return jsonify({'message': 'Task deleted successfully'}) +# Connect to MongoDB +client = MongoClient('mongodb://mongo:27017/') +db = client['studentsdb'] +students_collection = db['students'] + +@app.route('/students', methods=['GET']) +def get_students(): + students = list(students_collection.find({}, {'_id': 0})) + return jsonify(students) + +@app.route('/students/', methods=['GET']) +def get_student(student_id): + student = students_collection.find_one({'student_id': student_id}, {'_id': 0}) + return jsonify(student) + +@app.route('/students', methods=['POST']) +def create_student(): + new_student = request.json + students_collection.insert_one(new_student) + return jsonify({'message': 'Student created successfully'}) + +@app.route('/students/', methods=['PUT']) +def update_student(student_id): + updated_student = request.json + students_collection.update_one({'student_id': student_id}, {'$set': updated_student}) + return jsonify({'message': 'Student updated successfully'}) + +@app.route('/students/', methods=['DELETE']) +def delete_student(student_id): + students_collection.delete_one({'student_id': student_id}) + return jsonify({'message': 'Student deleted successfully'}) if __name__ == '__main__': - app.run(host='0.0.0.0', port=5000, debug=True) + app.run(host='0.0.0.0', port=6000, debug=True) \ No newline at end of file diff --git a/flask-mongo/docker-compose.yml b/flask-mongo/docker-compose.yml index 1d71e32..2970065 100644 --- a/flask-mongo/docker-compose.yml +++ b/flask-mongo/docker-compose.yml @@ -1,4 +1,4 @@ -version: "3" +version: '3' services: mongo: image: mongo @@ -16,7 +16,7 @@ services: build: context: . ports: - - "5000:5000" + - "6000:6000" depends_on: - mongo networks: @@ -26,4 +26,4 @@ networks: backend: external: true volumes: - data: + data: \ No newline at end of file diff --git a/flask-mongo/requirements.txt b/flask-mongo/requirements.txt index 324ca18..7a03746 100644 --- a/flask-mongo/requirements.txt +++ b/flask-mongo/requirements.txt @@ -1,6 +1,4 @@ -Flask==3.0.3 -Flask-Cors==4.0.0 -pymongo==4.6.3 -coverage==7.4.4 -bson==0.5.10 -keploy==2.0.0a33 \ No newline at end of file +Flask +pymongo==4.4.1 +Flask-Cors==3.0.10 +Werkzeug==2.2.2 \ No newline at end of file