diff --git a/README.md b/README.md index c4e8a23..d99979a 100644 --- a/README.md +++ b/README.md @@ -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: diff --git a/fastapi-twilio/.env b/fastapi-twilio/.env new file mode 100644 index 0000000..4bacefa --- /dev/null +++ b/fastapi-twilio/.env @@ -0,0 +1,3 @@ +TWILIO_ACCOUNT_SID=YOUR_ACCOUNT_SID +TWILIO_AUTH_TOKEN=YOUR_ACCOUNT_AUTH_TOKEN +TWILIO_NUMBER=YOUR_PURCHASED_PHONE_NUMBER \ No newline at end of file diff --git a/fastapi-twilio/.gitignore b/fastapi-twilio/.gitignore new file mode 100644 index 0000000..bdd515a --- /dev/null +++ b/fastapi-twilio/.gitignore @@ -0,0 +1,2 @@ +./venv +./__pycache__ \ No newline at end of file diff --git a/fastapi-twilio/Dockerfile b/fastapi-twilio/Dockerfile new file mode 100644 index 0000000..e8aa5dd --- /dev/null +++ b/fastapi-twilio/Dockerfile @@ -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"] diff --git a/fastapi-twilio/README.md b/fastapi-twilio/README.md new file mode 100644 index 0000000..06bbc82 --- /dev/null +++ b/fastapi-twilio/README.md @@ -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).
+ +## 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 +``` + +
+ 2. ARM Architecture + +```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 +``` + +
+ +### 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 😄** diff --git a/fastapi-twilio/keploy-config.yaml b/fastapi-twilio/keploy-config.yaml new file mode 100755 index 0000000..c7e3e02 --- /dev/null +++ b/fastapi-twilio/keploy-config.yaml @@ -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"] + # } + # } + # } + # } diff --git a/fastapi-twilio/keploy/test-set-0/mocks.yaml b/fastapi-twilio/keploy/test-set-0/mocks.yaml new file mode 100755 index 0000000..cd2a8bf --- /dev/null +++ b/fastapi-twilio/keploy/test-set-0/mocks.yaml @@ -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 diff --git a/fastapi-twilio/keploy/test-set-0/tests/test-1.yaml b/fastapi-twilio/keploy/test-set-0/tests/test-1.yaml new file mode 100755 index 0000000..c088b98 --- /dev/null +++ b/fastapi-twilio/keploy/test-set-0/tests/test-1.yaml @@ -0,0 +1,58 @@ +version: api.keploy.io/v1beta1 +kind: Http +name: test-1 +spec: + metadata: {} + req: + method: POST + proto_major: 1 + proto_minor: 1 + url: http://127.0.0.1:8000/send-sms/ + header: + Accept: '*/*' + Accept-Encoding: gzip, deflate, br + Connection: keep-alive + Content-Length: "75" + Content-Type: application/json + Host: 127.0.0.1:8000 + Postman-Token: c871b715-7aae-46b6-8e0d-1341aa426624 + User-Agent: PostmanRuntime/7.34.0 + body: |- + { + "Body": "Test, testtt, testttttttssss :)", + "To": "+91700004379" + } + body_type: "" + timestamp: 2023-11-14T14:56:25.800517709+05:30 + resp: + status_code: 200 + header: + Content-Length: "73" + Content-Type: application/json + Date: Tue, 14 Nov 2023 09:26:25 GMT + Server: uvicorn + body: '{"message":"Failed to send SMS. Please check the provided phone number."}' + body_type: "" + status_message: "" + proto_major: 0 + proto_minor: 0 + timestamp: 2023-11-14T14:56:32.013566624+05:30 + objects: [] + assertions: + noise: + header.Date: [] + created: 1699953992 +curl: |- + curl --request POST \ + --url http://127.0.0.1:8000/send-sms/ \ + --header 'User-Agent: PostmanRuntime/7.34.0' \ + --header 'Accept: */*' \ + --header 'Postman-Token: c871b715-7aae-46b6-8e0d-1341aa426624' \ + --header 'Host: 127.0.0.1:8000' \ + --header 'Accept-Encoding: gzip, deflate, br' \ + --header 'Connection: keep-alive' \ + --header 'Content-Type: application/json' \ + --data '{ + "Body": "Test, testtt, testttttttssss :)", + "To": "+91700004379" + }' diff --git a/fastapi-twilio/keploy/test-set-0/tests/test-2.yaml b/fastapi-twilio/keploy/test-set-0/tests/test-2.yaml new file mode 100755 index 0000000..bb9db1e --- /dev/null +++ b/fastapi-twilio/keploy/test-set-0/tests/test-2.yaml @@ -0,0 +1,58 @@ +version: api.keploy.io/v1beta1 +kind: Http +name: test-2 +spec: + metadata: {} + req: + method: POST + proto_major: 1 + proto_minor: 1 + url: http://127.0.0.1:8000/send-sms/ + header: + Accept: '*/*' + Accept-Encoding: gzip, deflate, br + Connection: keep-alive + Content-Length: "76" + Content-Type: application/json + Host: 127.0.0.1:8000 + Postman-Token: a3780363-733f-4c88-915b-d4d69384822c + User-Agent: PostmanRuntime/7.34.0 + body: |- + { + "Body": "Test, testtt, testttttttssss :)", + "To": "+917000043797" + } + body_type: "" + timestamp: 2023-11-14T14:56:33.722179585+05:30 + resp: + status_code: 200 + header: + Content-Length: "36" + Content-Type: application/json + Date: Tue, 14 Nov 2023 09:26:33 GMT + Server: uvicorn + body: '{"message":"SMS sent successfully!"}' + body_type: "" + status_message: "" + proto_major: 0 + proto_minor: 0 + timestamp: 2023-11-14T14:56:37.588988851+05:30 + objects: [] + assertions: + noise: + header.Date: [] + created: 1699953997 +curl: |- + curl --request POST \ + --url http://127.0.0.1:8000/send-sms/ \ + --header 'Content-Type: application/json' \ + --header 'User-Agent: PostmanRuntime/7.34.0' \ + --header 'Accept: */*' \ + --header 'Postman-Token: a3780363-733f-4c88-915b-d4d69384822c' \ + --header 'Host: 127.0.0.1:8000' \ + --header 'Accept-Encoding: gzip, deflate, br' \ + --header 'Connection: keep-alive' \ + --data '{ + "Body": "Test, testtt, testttttttssss :)", + "To": "+917000043797" + }' diff --git a/fastapi-twilio/keploy/test-set-0/tests/test-3.yaml b/fastapi-twilio/keploy/test-set-0/tests/test-3.yaml new file mode 100755 index 0000000..3a01fb6 --- /dev/null +++ b/fastapi-twilio/keploy/test-set-0/tests/test-3.yaml @@ -0,0 +1,58 @@ +version: api.keploy.io/v1beta1 +kind: Http +name: test-3 +spec: + metadata: {} + req: + method: POST + proto_major: 1 + proto_minor: 1 + url: http://127.0.0.1:8000/send-sms/ + header: + Accept: '*/*' + Accept-Encoding: gzip, deflate, br + Connection: keep-alive + Content-Length: "74" + Content-Type: application/json + Host: 127.0.0.1:8000 + Postman-Token: 5e8c1a07-c35d-4816-8b32-c6bcfd28d94d + User-Agent: PostmanRuntime/7.34.0 + body: |- + { + "Body": "Test, testtt, testttttttssss :)", + "To": "+9170000437" + } + body_type: "" + timestamp: 2023-11-14T14:57:19.642139975+05:30 + resp: + status_code: 200 + header: + Content-Length: "73" + Content-Type: application/json + Date: Tue, 14 Nov 2023 09:27:18 GMT + Server: uvicorn + body: '{"message":"Failed to send SMS. Please check the provided phone number."}' + body_type: "" + status_message: "" + proto_major: 0 + proto_minor: 0 + timestamp: 2023-11-14T14:57:23.973137683+05:30 + objects: [] + assertions: + noise: + header.Date: [] + created: 1699954043 +curl: |- + curl --request POST \ + --url http://127.0.0.1:8000/send-sms/ \ + --header 'Accept: */*' \ + --header 'Postman-Token: 5e8c1a07-c35d-4816-8b32-c6bcfd28d94d' \ + --header 'Host: 127.0.0.1:8000' \ + --header 'Accept-Encoding: gzip, deflate, br' \ + --header 'Connection: keep-alive' \ + --header 'Content-Type: application/json' \ + --header 'User-Agent: PostmanRuntime/7.34.0' \ + --data '{ + "Body": "Test, testtt, testttttttssss :)", + "To": "+9170000437" + }' diff --git a/fastapi-twilio/keploy/testReports/report-1.yaml b/fastapi-twilio/keploy/testReports/report-1.yaml new file mode 100755 index 0000000..acf2233 --- /dev/null +++ b/fastapi-twilio/keploy/testReports/report-1.yaml @@ -0,0 +1,284 @@ +version: api.keploy.io/v1beta1 +name: report-1 +status: PASSED +success: 3 +failure: 0 +total: 3 +tests: + - kind: Http + name: report-1 + status: PASSED + started: 1699954104 + completed: 1699954106 + test_case_path: /home/shashwat/test/python-twilio/keploy/test-set-0 + mock_path: "" + test_case_id: test-1 + req: + method: POST + proto_major: 1 + proto_minor: 1 + url: http://127.0.0.1:8000/send-sms/ + header: + Accept: '*/*' + Accept-Encoding: gzip, deflate, br + Connection: keep-alive + Content-Length: "75" + Content-Type: application/json + Host: 127.0.0.1:8000 + Postman-Token: c871b715-7aae-46b6-8e0d-1341aa426624 + User-Agent: PostmanRuntime/7.34.0 + body: |- + { + "Body": "Test, testtt, testttttttssss :)", + "To": "+91700004379" + } + body_type: "" + timestamp: 0001-01-01T00:00:00Z + resp: + status_code: 200 + header: + Content-Length: "73" + Content-Type: application/json + Date: Tue, 14 Nov 2023 09:26:25 GMT + Server: uvicorn + body: '{"message":"Failed to send SMS. Please check the provided phone number."}' + body_type: "" + status_message: "" + proto_major: 0 + proto_minor: 0 + timestamp: 0001-01-01T00:00:00Z + noise: + header.Date: [] + result: + status_code: + normal: true + expected: 200 + actual: 200 + headers_result: + - normal: true + expected: + key: Content-Length + value: + - "73" + actual: + key: Content-Length + value: + - "73" + - normal: true + expected: + key: Content-Type + value: + - application/json + actual: + key: Content-Type + value: + - application/json + - normal: true + expected: + key: Date + value: + - Tue, 14 Nov 2023 09:26:25 GMT + actual: + key: Date + value: + - Tue, 14 Nov 2023 09:28:24 GMT + - normal: true + expected: + key: Server + value: + - uvicorn + actual: + key: Server + value: + - uvicorn + body_result: + - normal: true + type: JSON + expected: '{"message":"Failed to send SMS. Please check the provided phone number."}' + actual: '{"message":"Failed to send SMS. Please check the provided phone number."}' + dep_result: [] + - kind: Http + name: report-1 + status: PASSED + started: 1699954106 + completed: 1699954107 + test_case_path: /home/shashwat/test/python-twilio/keploy/test-set-0 + mock_path: "" + test_case_id: test-2 + req: + method: POST + proto_major: 1 + proto_minor: 1 + url: http://127.0.0.1:8000/send-sms/ + header: + Accept: '*/*' + Accept-Encoding: gzip, deflate, br + Connection: keep-alive + Content-Length: "76" + Content-Type: application/json + Host: 127.0.0.1:8000 + Postman-Token: a3780363-733f-4c88-915b-d4d69384822c + User-Agent: PostmanRuntime/7.34.0 + body: |- + { + "Body": "Test, testtt, testttttttssss :)", + "To": "+917000043797" + } + body_type: "" + timestamp: 0001-01-01T00:00:00Z + resp: + status_code: 200 + header: + Content-Length: "36" + Content-Type: application/json + Date: Tue, 14 Nov 2023 09:26:33 GMT + Server: uvicorn + body: '{"message":"SMS sent successfully!"}' + body_type: "" + status_message: "" + proto_major: 0 + proto_minor: 0 + timestamp: 0001-01-01T00:00:00Z + noise: + header.Date: [] + result: + status_code: + normal: true + expected: 200 + actual: 200 + headers_result: + - normal: true + expected: + key: Content-Type + value: + - application/json + actual: + key: Content-Type + value: + - application/json + - normal: true + expected: + key: Date + value: + - Tue, 14 Nov 2023 09:26:33 GMT + actual: + key: Date + value: + - Tue, 14 Nov 2023 09:28:26 GMT + - normal: true + expected: + key: Server + value: + - uvicorn + actual: + key: Server + value: + - uvicorn + - normal: true + expected: + key: Content-Length + value: + - "36" + actual: + key: Content-Length + value: + - "36" + body_result: + - normal: true + type: JSON + expected: '{"message":"SMS sent successfully!"}' + actual: '{"message":"SMS sent successfully!"}' + dep_result: [] + - kind: Http + name: report-1 + status: PASSED + started: 1699954107 + completed: 1699954108 + test_case_path: /home/shashwat/test/python-twilio/keploy/test-set-0 + mock_path: "" + test_case_id: test-3 + req: + method: POST + proto_major: 1 + proto_minor: 1 + url: http://127.0.0.1:8000/send-sms/ + header: + Accept: '*/*' + Accept-Encoding: gzip, deflate, br + Connection: keep-alive + Content-Length: "74" + Content-Type: application/json + Host: 127.0.0.1:8000 + Postman-Token: 5e8c1a07-c35d-4816-8b32-c6bcfd28d94d + User-Agent: PostmanRuntime/7.34.0 + body: |- + { + "Body": "Test, testtt, testttttttssss :)", + "To": "+9170000437" + } + body_type: "" + timestamp: 0001-01-01T00:00:00Z + resp: + status_code: 200 + header: + Content-Length: "73" + Content-Type: application/json + Date: Tue, 14 Nov 2023 09:27:18 GMT + Server: uvicorn + body: '{"message":"Failed to send SMS. Please check the provided phone number."}' + body_type: "" + status_message: "" + proto_major: 0 + proto_minor: 0 + timestamp: 0001-01-01T00:00:00Z + noise: + header.Date: [] + result: + status_code: + normal: true + expected: 200 + actual: 200 + headers_result: + - normal: true + expected: + key: Content-Type + value: + - application/json + actual: + key: Content-Type + value: + - application/json + - normal: true + expected: + key: Date + value: + - Tue, 14 Nov 2023 09:27:18 GMT + actual: + key: Date + value: + - Tue, 14 Nov 2023 09:28:27 GMT + - normal: true + expected: + key: Server + value: + - uvicorn + actual: + key: Server + value: + - uvicorn + - normal: true + expected: + key: Content-Length + value: + - "73" + actual: + key: Content-Length + value: + - "73" + body_result: + - normal: true + type: JSON + expected: '{"message":"Failed to send SMS. Please check the provided phone number."}' + actual: '{"message":"Failed to send SMS. Please check the provided phone number."}' + dep_result: [] +test_set: test-set-0 diff --git a/fastapi-twilio/main.py b/fastapi-twilio/main.py new file mode 100644 index 0000000..82800cd --- /dev/null +++ b/fastapi-twilio/main.py @@ -0,0 +1,39 @@ +from fastapi import FastAPI +import requests +from dotenv import load_dotenv +from pydantic import BaseModel +import os + + +load_dotenv() + + +class Message(BaseModel): + Body: str + To: str + +app = FastAPI() + + +@app.post('/send-sms/') +def send_sms(data: Message): + twilio_account_sid = os.getenv('TWILIO_ACCOUNT_SID') + twilio_auth_token = os.getenv('TWILIO_AUTH_TOKEN') + twilio_phone_number = os.getenv('TWILIO_NUMBER') + + url = f'https://api.twilio.com/2010-04-01/Accounts/{twilio_account_sid}/Messages.json' + + payload = { + 'Body': data.Body, + 'From': twilio_phone_number, + 'To': data.To + } + + try: + response = requests.post(url=url, data=payload, auth=(twilio_account_sid, twilio_auth_token)) + if response.status_code == 201: + return {"message": "SMS sent successfully!"} + else: + return {"message": "Failed to send SMS. Please check the provided phone number."} + except Exception as e: + return {"message": str(e)} diff --git a/fastapi-twilio/requirements.txt b/fastapi-twilio/requirements.txt new file mode 100644 index 0000000..d86cb8b --- /dev/null +++ b/fastapi-twilio/requirements.txt @@ -0,0 +1,28 @@ +aiohttp==3.8.6 +aiohttp-retry==2.8.3 +aiosignal==1.3.1 +annotated-types==0.6.0 +anyio==3.7.1 +async-timeout==4.0.3 +attrs==23.1.0 +certifi==2023.7.22 +charset-normalizer==3.3.2 +click==8.1.7 +exceptiongroup==1.1.3 +fastapi==0.104.1 +frozenlist==1.4.0 +h11==0.14.0 +idna==3.4 +multidict==6.0.4 +pydantic==2.4.2 +pydantic_core==2.10.1 +PyJWT==2.8.0 +python-dotenv==1.0.0 +requests==2.31.0 +sniffio==1.3.0 +starlette==0.27.0 +twilio==8.10.1 +typing_extensions==4.8.0 +urllib3==2.0.7 +uvicorn==0.24.0.post1 +yarl==1.9.2