Skip to content
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
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ This repo contains the samples for [Keploy's](https://keploy.io) Python-based Ap

3. [FastAPI-Postgres](https://github.com/keploy/samples-python/tree/main/fastapi-postgres) - This application is a student management API built using Python's FastAPI and PostgreSQL for data storage. It allows you to perform basic CRUD (Create, Read, Update, Delete) operations on student data.

4. [FastAPI-Twilio](https://github.com/keploy/samples-python/tree/main/fastapi-twilio) - This application is a SMS sending API built using Python's FastAPI and Twilio for their SMS sharing service.

## Community Support ❤️

We'd love to collaborate with you to make Keploy great. To get started:
Expand Down
3 changes: 3 additions & 0 deletions fastapi-twilio/.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
TWILIO_ACCOUNT_SID=YOUR_ACCOUNT_SID
TWILIO_AUTH_TOKEN=YOUR_ACCOUNT_AUTH_TOKEN
TWILIO_NUMBER=YOUR_PURCHASED_PHONE_NUMBER
2 changes: 2 additions & 0 deletions fastapi-twilio/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
./venv
./__pycache__
11 changes: 11 additions & 0 deletions fastapi-twilio/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
FROM python:3.11.5-bullseye

WORKDIR /app

COPY . /app/

RUN pip install --no-cache-dir --upgrade -r /app/requirements.txt

EXPOSE 8000

CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
84 changes: 84 additions & 0 deletions fastapi-twilio/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
# FastAPI-Twilio Application

A sample FastAPI-Twilio app to test Keploy integration capabilities using [FastAPI](https://fastapi.tiangolo.com/) and [Twilio](https://www.twilio.com/en-us). <br>

## Installation Setup

```bash
git clone https://github.com/keploy/samples-python.git && cd samples-python/fastapi-twilio
pip3 install -r requirements.txt
```

## Installation Keploy

Keploy can be installed on Linux directly and on Windows with the help of WSL. Based on your system architecture, install the keploy latest binary release

**1. AMD Architecture**

```shell
curl --silent --location "https://github.com/keploy/keploy/releases/latest/download/keploy_linux_amd64.tar.gz" | tar xz -C /tmp

sudo mkdir -p /usr/local/bin && sudo mv /tmp/keploy /usr/local/bin && keploy
```

<details>
<summary> 2. ARM Architecture </summary>

```shell
curl --silent --location "https://github.com/keploy/keploy/releases/latest/download/keploy_linux_arm64.tar.gz" | tar xz -C /tmp

sudo mkdir -p /usr/local/bin && sudo mv /tmp/keploy /usr/local/bin && keploy
```

</details>

### Get your Twilio Credentials

You can get your Twilio credentials by signing in to [Twilio Console](https://console.twilio.com/).
Once you get the Twilio Account SID, Auth Token, and Phone Number, modify the `.env` file with your credentials.

### Capture the Testcases

This command will start the recording of API calls:-

```shell
keploy record -c "uvicorn main:app --reload"
```

Make API Calls using Hoppscotch, Postman or cURL command. Keploy with capture those calls to generate the test-suites containing testcases and data mocks.

### Make the POST requests

1. Replace the place holder below i.e. `YOUR_REGISTERED_PERSONAL_PHONE_NUMBER` with your registered personal phone number that you linked with Twilio.

```bash
curl --location 'http://127.0.0.1:8000/send-sms/' \
--header 'Content-Type: application/json' \
--data '{
"Body": "Test, testtt, testttttttssss :)",
"To": "YOUR_REGISTERED_PERSONAL_PHONE_NUMBER",
}'
```

2. Replace the place holder below i.e. `SOME_WRONG_PHONE_NUMBER` with any wrong phone number and make the request.

```bash
curl --location 'http://127.0.0.1:8000/send-sms/' \
--header 'Content-Type: application/json' \
--data '{
"Body": "Test, testtt, testttttttssss :)",
"To": "SOME_WRONG_PHONE_NUMBER",
}'
```

Now all these API calls were captured as **editable** testcases and written to `keploy/tests` folder. The keploy directory would also have `mocks` file that contains all the outputs of Twilio operations.

## Run the Testcases

Now let's run the application in test mode.

```shell
keploy test -c "uvicorn main:app --reload" --delay 10
```

So, no need to setup fake apis like Twilio or write mocks for them. Keploy automatically mocks them and, **The application thinks it's talking to Twilio 😄**
64 changes: 64 additions & 0 deletions fastapi-twilio/keploy-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
record:
path: ""
# mandatory
command: ""
proxyport: 0
containerName: ""
networkName: ""
delay: 5
passThroughPorts: []
test:
path: ""
# mandatory
command: ""
proxyport: 0
containerName: ""
networkName: ""
testSets: []
globalNoise: |-
{
"global": {
"body": {},
"header": {}
},
"test-sets": {
"test-set-name": {
"body": {},
"header": {}
}
}
}
delay: 5
apiTimeout: 5
passThroughPorts: []
#
# Example on using globalNoise
# globalNoise: |-
# {
# "global": {
# "body": {
# # to ignore some values for a field,
# # pass regex patterns to the corresponding array value
# "url": ["https?://\S+", "http://\S+"],
# },
# "header": {
# # to ignore the entire field, pass an empty array
# "Date: [],
# }
# },
# # to ignore fields or the corresponding values for a specific test-set,
# # pass the test-set-name as a key to the "test-sets" object and
# # populate the corresponding "body" and "header" objects
# "test-sets": {
# "test-set-1": {
# "body": {
# # ignore all the values for the "url" field
# "url": []
# },
# "header": {
# # we can also pass the exact value to ignore for a field
# "User-Agent": ["PostmanRuntime/7.34.0"]
# }
# }
# }
# }
162 changes: 162 additions & 0 deletions fastapi-twilio/keploy/test-set-0/mocks.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
version: api.keploy.io/v1beta1
kind: Http
name: mocks
spec:
metadata:
name: Http
operation: POST
type: HTTP_CLIENT
req:
method: POST
proto_major: 1
proto_minor: 1
url: /2010-04-01/Accounts/AC19413687d9ce28c80cda944730f8b286/Messages.json
header:
Accept: '*/*'
Accept-Encoding: gzip, deflate
Authorization: Basic QUMxOTQxMzY4N2Q5Y2UyOGM4MGNkYTk0NDczMGY4YjI4NjpjMTc0MDc5YzU2NTA0N2FmYWJmNDk5MWI2ZGQ1MmFiYg==
Connection: keep-alive
Content-Length: "82"
Content-Type: application/x-www-form-urlencoded
User-Agent: python-requests/2.31.0
body: Body=Test%2C+testtt%2C+testttttttssss+%3A%29&From=%2B16413324066&To=%2B91700004379
body_type: ""
timestamp: 0001-01-01T00:00:00Z
resp:
status_code: 400
header:
Access-Control-Allow-Credentials: "true"
Access-Control-Allow-Headers: Accept, Authorization, Content-Type, If-Match, If-Modified-Since, If-None-Match, If-Unmodified-Since, Idempotency-Key
Access-Control-Allow-Methods: GET, POST, DELETE, OPTIONS
Access-Control-Allow-Origin: '*'
Access-Control-Expose-Headers: ETag
Connection: keep-alive
Content-Length: 158,158
Content-Type: application/json
Date: Tue, 14 Nov 2023 09:26:29 GMT
Strict-Transport-Security: max-age=31536000
Twilio-Concurrent-Requests: "1"
Twilio-Request-Duration: "0.051"
Twilio-Request-Id: RQec3c4676524fe2951583489e90bc1b33
X-Api-Domain: api.twilio.com
X-Home-Region: us1
X-Powered-By: AT-5000
X-Shenanigans: none
body: '{"code": 21211, "message": "The ''To'' number +9170000XXXX is not a valid phone number", "more_info": "https://www.twilio.com/docs/errors/21211", "status": 400}'
body_type: ""
status_message: ""
proto_major: 0
proto_minor: 0
timestamp: 0001-01-01T00:00:00Z
objects: []
created: 1699953989
reqTimestampMock: 2023-11-14T14:56:28.791864295+05:30
resTimestampMock: 2023-11-14T14:56:29.304057844+05:30
---
version: api.keploy.io/v1beta1
kind: Http
name: mocks
spec:
metadata:
name: Http
operation: POST
type: HTTP_CLIENT
req:
method: POST
proto_major: 1
proto_minor: 1
url: /2010-04-01/Accounts/AC19413687d9ce28c80cda944730f8b286/Messages.json
header:
Accept: '*/*'
Accept-Encoding: gzip, deflate
Authorization: Basic QUMxOTQxMzY4N2Q5Y2UyOGM4MGNkYTk0NDczMGY4YjI4NjpjMTc0MDc5YzU2NTA0N2FmYWJmNDk5MWI2ZGQ1MmFiYg==
Connection: keep-alive
Content-Length: "83"
Content-Type: application/x-www-form-urlencoded
User-Agent: python-requests/2.31.0
body: Body=Test%2C+testtt%2C+testttttttssss+%3A%29&From=%2B16413324066&To=%2B917000043797
body_type: ""
timestamp: 0001-01-01T00:00:00Z
resp:
status_code: 201
header:
Access-Control-Allow-Credentials: "true"
Access-Control-Allow-Headers: Accept, Authorization, Content-Type, If-Match, If-Modified-Since, If-None-Match, If-Unmodified-Since, Idempotency-Key
Access-Control-Allow-Methods: GET, POST, DELETE, OPTIONS
Access-Control-Allow-Origin: '*'
Access-Control-Expose-Headers: ETag
Connection: keep-alive
Content-Length: 834,834
Content-Type: application/json
Date: Tue, 14 Nov 2023 09:26:35 GMT
Twilio-Concurrent-Requests: "1"
Twilio-Request-Duration: "0.131"
Twilio-Request-Id: RQ2f5288499581f3fe12524b11bbb3d866
X-Api-Domain: api.twilio.com
X-Home-Region: us1
X-Powered-By: AT-5000
X-Shenanigans: none
body: '{"body": "Sent from your Twilio trial account - Test, testtt, testttttttssss :)", "num_segments": "1", "direction": "outbound-api", "from": "+16413324066", "date_updated": "Tue, 14 Nov 2023 09:26:35 +0000", "price": null, "error_message": null, "uri": "/2010-04-01/Accounts/AC19413687d9ce28c80cda944730f8b286/Messages/SM2f5288499581f3fe12524b11bbb3d866.json", "account_sid": "AC19413687d9ce28c80cda944730f8b286", "num_media": "0", "to": "+917000043797", "date_created": "Tue, 14 Nov 2023 09:26:35 +0000", "status": "queued", "sid": "SM2f5288499581f3fe12524b11bbb3d866", "date_sent": null, "messaging_service_sid": null, "error_code": null, "price_unit": "USD", "api_version": "2010-04-01", "subresource_uris": {"media": "/2010-04-01/Accounts/AC19413687d9ce28c80cda944730f8b286/Messages/SM2f5288499581f3fe12524b11bbb3d866/Media.json"}}'
body_type: ""
status_message: ""
proto_major: 0
proto_minor: 0
timestamp: 0001-01-01T00:00:00Z
objects: []
created: 1699953995
reqTimestampMock: 2023-11-14T14:56:34.833506359+05:30
resTimestampMock: 2023-11-14T14:56:35.27188354+05:30
---
version: api.keploy.io/v1beta1
kind: Http
name: mocks
spec:
metadata:
name: Http
operation: POST
type: HTTP_CLIENT
req:
method: POST
proto_major: 1
proto_minor: 1
url: /2010-04-01/Accounts/AC19413687d9ce28c80cda944730f8b286/Messages.json
header:
Accept: '*/*'
Accept-Encoding: gzip, deflate
Authorization: Basic QUMxOTQxMzY4N2Q5Y2UyOGM4MGNkYTk0NDczMGY4YjI4NjpjMTc0MDc5YzU2NTA0N2FmYWJmNDk5MWI2ZGQ1MmFiYg==
Connection: keep-alive
Content-Length: "81"
Content-Type: application/x-www-form-urlencoded
User-Agent: python-requests/2.31.0
body: Body=Test%2C+testtt%2C+testttttttssss+%3A%29&From=%2B16413324066&To=%2B9170000437
body_type: ""
timestamp: 0001-01-01T00:00:00Z
resp:
status_code: 400
header:
Access-Control-Allow-Credentials: "true"
Access-Control-Allow-Headers: Accept, Authorization, Content-Type, If-Match, If-Modified-Since, If-None-Match, If-Unmodified-Since, Idempotency-Key
Access-Control-Allow-Methods: GET, POST, DELETE, OPTIONS
Access-Control-Allow-Origin: '*'
Access-Control-Expose-Headers: ETag
Connection: keep-alive
Content-Length: 335,335
Content-Type: application/json
Date: Tue, 14 Nov 2023 09:27:21 GMT
Twilio-Concurrent-Requests: "1"
Twilio-Request-Duration: "0.080"
Twilio-Request-Id: RQb54d7f05d29e83bc89889cc136bcd99d
X-Api-Domain: api.twilio.com
X-Home-Region: us1
X-Powered-By: AT-5000
X-Shenanigans: none
body: '{"code": 21608, "message": "The number +917000XXXX is unverified. Trial accounts cannot send messages to unverified numbers; verify +917000XXXX at twilio.com/user/account/phone-numbers/verified, or purchase a Twilio number to send messages to unverified numbers", "more_info": "https://www.twilio.com/docs/errors/21608", "status": 400}'
body_type: ""
status_message: ""
proto_major: 0
proto_minor: 0
timestamp: 0001-01-01T00:00:00Z
objects: []
created: 1699954041
reqTimestampMock: 2023-11-14T14:57:20.914415283+05:30
resTimestampMock: 2023-11-14T14:57:21.298027703+05:30
Loading