From 0ca26ade979bae28668a2d8f1c0087bde3363f73 Mon Sep 17 00:00:00 2001 From: shibatanaoto Date: Sat, 8 Feb 2025 19:57:11 +0900 Subject: [PATCH] init projeect for browser-use --- browser_use_e2e_test_app/.gitignore | 4 + .../.mock_user_context.json | 8 + browser_use_e2e_test_app/Dockerfile | 20 + browser_use_e2e_test_app/README.md | 35 ++ .../data/Traffic_Orders_Demo_Data.csv | 361 ++++++++++++++++++ browser_use_e2e_test_app/morph_project.yml | 7 + browser_use_e2e_test_app/package.json | 14 + browser_use_e2e_test_app/pyproject.toml | 17 + browser_use_e2e_test_app/src/pages/index.mdx | 59 +++ .../src/pages/sql_agent.mdx | 20 + .../src/python/example.py | 48 +++ .../src/python/sql_agent.py | 107 ++++++ .../src/sql/example_data.sql | 16 + 13 files changed, 716 insertions(+) create mode 100644 browser_use_e2e_test_app/.gitignore create mode 100644 browser_use_e2e_test_app/.mock_user_context.json create mode 100644 browser_use_e2e_test_app/Dockerfile create mode 100644 browser_use_e2e_test_app/README.md create mode 100755 browser_use_e2e_test_app/data/Traffic_Orders_Demo_Data.csv create mode 100644 browser_use_e2e_test_app/morph_project.yml create mode 100644 browser_use_e2e_test_app/package.json create mode 100644 browser_use_e2e_test_app/pyproject.toml create mode 100644 browser_use_e2e_test_app/src/pages/index.mdx create mode 100644 browser_use_e2e_test_app/src/pages/sql_agent.mdx create mode 100644 browser_use_e2e_test_app/src/python/example.py create mode 100644 browser_use_e2e_test_app/src/python/sql_agent.py create mode 100644 browser_use_e2e_test_app/src/sql/example_data.sql diff --git a/browser_use_e2e_test_app/.gitignore b/browser_use_e2e_test_app/.gitignore new file mode 100644 index 0000000..0c446a8 --- /dev/null +++ b/browser_use_e2e_test_app/.gitignore @@ -0,0 +1,4 @@ +# Morph config files and directories +.gitconifg +.morph +node_modules diff --git a/browser_use_e2e_test_app/.mock_user_context.json b/browser_use_e2e_test_app/.mock_user_context.json new file mode 100644 index 0000000..3ce55a7 --- /dev/null +++ b/browser_use_e2e_test_app/.mock_user_context.json @@ -0,0 +1,8 @@ +{ + "user_id": "cea122ea-b240-49d7-ae7f-8b1e3d40dd8f", + "email": "mock_user@morph-data.io", + "username": "mock_user", + "first_name": "Mock", + "last_name": "User", + "roles": ["Admin"] +} diff --git a/browser_use_e2e_test_app/Dockerfile b/browser_use_e2e_test_app/Dockerfile new file mode 100644 index 0000000..e46934d --- /dev/null +++ b/browser_use_e2e_test_app/Dockerfile @@ -0,0 +1,20 @@ +# Base image for Morph Cloud +FROM public.ecr.aws/i1l4z0u0/morph-cloud:python3.9 + +# Set working directory +WORKDIR /var/task + +# Install Python dependencies with poetry +COPY requirements.txt . +RUN pip install --no-cache-dir -r requirements.txt --target "${MORPH_TASK_ROOT}" + +# Copy source code and dependencies +COPY .morph/frontend/dist /var/task/.morph/frontend/dist +COPY .morph/core /var/task/core +COPY .morph/meta.json .morph/ +COPY morph_project.yml . +COPY data ./data +COPY src ./src + +# Command to run the Lambda function +CMD ["core.morph.api.app.handler"] diff --git a/browser_use_e2e_test_app/README.md b/browser_use_e2e_test_app/README.md new file mode 100644 index 0000000..2befd32 --- /dev/null +++ b/browser_use_e2e_test_app/README.md @@ -0,0 +1,35 @@ +Welcome to your new Morph project! + +### Using the starter project + +Try running the following commands: + +- Run your data app + +```bash +morph serve +``` + +### Resources +- Learn more about Morph [in the docs](https://docs.morph-data.io) +- Check out [the blog](https://www.morph-data.io/blogs) + +### Getting started + +Write connection info in `~/.morph/config.yml` like this: + +```yml +connections: + connection_name: + type: postgres + host: localhost + port: 5432 + user: postgres + password: postgres +``` + +You can set it up by running the following command: + +```bash +morph config +``` diff --git a/browser_use_e2e_test_app/data/Traffic_Orders_Demo_Data.csv b/browser_use_e2e_test_app/data/Traffic_Orders_Demo_Data.csv new file mode 100755 index 0000000..544e94a --- /dev/null +++ b/browser_use_e2e_test_app/data/Traffic_Orders_Demo_Data.csv @@ -0,0 +1,361 @@ +Date,Source,Traffic,Orders +2020-01-31,Coupon,4244,304 +2020-02-29,Coupon,4254,301 +2020-03-31,Coupon,4401,318 +2020-04-30,Coupon,4708,328 +2020-05-31,Coupon,4738,341 +2020-06-30,Coupon,5025,365 +2020-07-31,Coupon,5259,368 +2020-08-31,Coupon,5575,405 +2020-09-30,Coupon,5924,420 +2020-10-31,Coupon,5924,416 +2020-11-30,Coupon,6462,452 +2020-12-31,Coupon,6452,456 +2021-01-31,Coupon,6986,498 +2021-02-28,Coupon,7064,498 +2021-03-31,Coupon,7341,531 +2021-04-30,Coupon,7670,549 +2021-05-31,Coupon,8152,573 +2021-06-30,Coupon,8438,602 +2021-07-31,Coupon,8875,627 +2021-08-31,Coupon,9190,660 +2021-09-30,Coupon,9663,695 +2021-10-31,Coupon,9866,709 +2021-11-30,Coupon,10365,738 +2021-12-31,Coupon,10679,766 +2022-01-31,Coupon,11281,803 +2022-02-28,Coupon,11457,824 +2022-03-31,Coupon,12175,872 +2022-04-30,Coupon,12665,912 +2022-05-31,Coupon,13303,955 +2022-06-30,Coupon,13558,971 +2022-07-31,Coupon,14142,1009 +2022-08-31,Coupon,14851,1065 +2022-09-30,Coupon,15492,1109 +2022-10-31,Coupon,16224,1149 +2022-11-30,Coupon,16819,1198 +2022-12-31,Coupon,17508,1249 +2023-01-31,Coupon,18119,1285 +2023-02-28,Coupon,19196,1373 +2023-03-31,Coupon,19684,1404 +2023-04-30,Coupon,20703,1480 +2023-05-31,Coupon,21644,1555 +2023-06-30,Coupon,22356,1604 +2023-07-31,Coupon,23471,1675 +2023-08-31,Coupon,24277,1727 +2023-09-30,Coupon,25182,1792 +2023-10-31,Coupon,26552,1888 +2023-11-30,Coupon,27496,1959 +2023-12-31,Coupon,28756,2054 +2024-01-31,Coupon,30070,2145 +2024-02-29,Coupon,31022,2215 +2024-03-31,Coupon,32553,2323 +2024-04-30,Coupon,33609,2400 +2024-05-31,Coupon,35251,2517 +2024-06-30,Coupon,36748,2628 +2024-07-31,Coupon,38365,2733 +2024-08-31,Coupon,39672,2826 +2024-09-30,Coupon,41672,2984 +2024-10-31,Coupon,43363,3094 +2024-11-30,Coupon,44924,3203 +2024-12-31,Coupon,47084,3367 +2020-01-31,Google Organic,2729,226 +2020-02-29,Google Organic,2981,241 +2020-03-31,Google Organic,2917,239 +2020-04-30,Google Organic,3011,246 +2020-05-31,Google Organic,3201,264 +2020-06-30,Google Organic,3015,250 +2020-07-31,Google Organic,3296,269 +2020-08-31,Google Organic,3402,274 +2020-09-30,Google Organic,3615,310 +2020-10-31,Google Organic,3648,304 +2020-11-30,Google Organic,3645,305 +2020-12-31,Google Organic,3830,324 +2021-01-31,Google Organic,3720,309 +2021-02-28,Google Organic,3606,310 +2021-03-31,Google Organic,4017,341 +2021-04-30,Google Organic,3794,323 +2021-05-31,Google Organic,4215,361 +2021-06-30,Google Organic,4099,343 +2021-07-31,Google Organic,4069,336 +2021-08-31,Google Organic,4446,362 +2021-09-30,Google Organic,4416,361 +2021-10-31,Google Organic,4518,383 +2021-11-30,Google Organic,4423,363 +2021-12-31,Google Organic,4563,387 +2022-01-31,Google Organic,4952,420 +2022-02-28,Google Organic,4887,414 +2022-03-31,Google Organic,4998,408 +2022-04-30,Google Organic,5108,418 +2022-05-31,Google Organic,5120,422 +2022-06-30,Google Organic,5257,429 +2022-07-31,Google Organic,5226,427 +2022-08-31,Google Organic,5346,455 +2022-09-30,Google Organic,5439,445 +2022-10-31,Google Organic,5704,477 +2022-11-30,Google Organic,5992,496 +2022-12-31,Google Organic,5975,492 +2023-01-31,Google Organic,6157,514 +2023-02-28,Google Organic,6128,518 +2023-03-31,Google Organic,6457,534 +2023-04-30,Google Organic,6373,526 +2023-05-31,Google Organic,6613,561 +2023-06-30,Google Organic,6628,545 +2023-07-31,Google Organic,6787,562 +2023-08-31,Google Organic,7005,585 +2023-09-30,Google Organic,7303,615 +2023-10-31,Google Organic,7199,606 +2023-11-30,Google Organic,7433,611 +2023-12-31,Google Organic,7527,627 +2024-01-31,Google Organic,7985,662 +2024-02-29,Google Organic,8095,681 +2024-03-31,Google Organic,8308,686 +2024-04-30,Google Organic,8277,701 +2024-05-31,Google Organic,8672,718 +2024-06-30,Google Organic,8734,738 +2024-07-31,Google Organic,8876,734 +2024-08-31,Google Organic,9098,768 +2024-09-30,Google Organic,9448,799 +2024-10-31,Google Organic,9635,801 +2024-11-30,Google Organic,9739,823 +2024-12-31,Google Organic,9780,815 +2020-01-31,Google Paid,3814,335 +2020-02-29,Google Paid,4215,354 +2020-03-31,Google Paid,4343,380 +2020-04-30,Google Paid,4221,365 +2020-05-31,Google Paid,4470,394 +2020-06-30,Google Paid,4468,389 +2020-07-31,Google Paid,4732,403 +2020-08-31,Google Paid,4653,397 +2020-09-30,Google Paid,4940,428 +2020-10-31,Google Paid,5055,444 +2020-11-30,Google Paid,5077,435 +2020-12-31,Google Paid,5412,458 +2021-01-31,Google Paid,5315,449 +2021-02-28,Google Paid,5403,470 +2021-03-31,Google Paid,5855,496 +2021-04-30,Google Paid,5635,481 +2021-05-31,Google Paid,6170,538 +2021-06-30,Google Paid,6244,547 +2021-07-31,Google Paid,6353,542 +2021-08-31,Google Paid,6402,545 +2021-09-30,Google Paid,6466,564 +2021-10-31,Google Paid,6761,590 +2021-11-30,Google Paid,6786,587 +2021-12-31,Google Paid,7191,624 +2022-01-31,Google Paid,7243,621 +2022-02-28,Google Paid,7481,638 +2022-03-31,Google Paid,7833,675 +2022-04-30,Google Paid,7937,679 +2022-05-31,Google Paid,8066,703 +2022-06-30,Google Paid,8297,720 +2022-07-31,Google Paid,8416,719 +2022-08-31,Google Paid,8703,742 +2022-09-30,Google Paid,8972,784 +2022-10-31,Google Paid,9160,781 +2022-11-30,Google Paid,9359,800 +2022-12-31,Google Paid,9643,840 +2023-01-31,Google Paid,9886,853 +2023-02-28,Google Paid,10380,889 +2023-03-31,Google Paid,10560,909 +2023-04-30,Google Paid,10805,936 +2023-05-31,Google Paid,10969,955 +2023-06-30,Google Paid,11242,975 +2023-07-31,Google Paid,11590,992 +2023-08-31,Google Paid,12088,1043 +2023-09-30,Google Paid,12432,1065 +2023-10-31,Google Paid,12731,1106 +2023-11-30,Google Paid,13029,1123 +2023-12-31,Google Paid,13219,1132 +2024-01-31,Google Paid,13677,1180 +2024-02-29,Google Paid,13882,1199 +2024-03-31,Google Paid,14288,1239 +2024-04-30,Google Paid,14618,1259 +2024-05-31,Google Paid,14990,1294 +2024-06-30,Google Paid,15286,1313 +2024-07-31,Google Paid,15907,1381 +2024-08-31,Google Paid,16425,1421 +2024-09-30,Google Paid,16725,1441 +2024-10-31,Google Paid,17183,1478 +2024-11-30,Google Paid,17706,1532 +2024-12-31,Google Paid,18167,1579 +2020-01-31,Tiktok Ads,3567,174 +2020-02-29,Tiktok Ads,3352,152 +2020-03-31,Tiktok Ads,3625,165 +2020-04-30,Tiktok Ads,3441,171 +2020-05-31,Tiktok Ads,3435,157 +2020-06-30,Tiktok Ads,3742,186 +2020-07-31,Tiktok Ads,3756,179 +2020-08-31,Tiktok Ads,3769,184 +2020-09-30,Tiktok Ads,3743,171 +2020-10-31,Tiktok Ads,3918,195 +2020-11-30,Tiktok Ads,3676,174 +2020-12-31,Tiktok Ads,3827,179 +2021-01-31,Tiktok Ads,3910,181 +2021-02-28,Tiktok Ads,3837,187 +2021-03-31,Tiktok Ads,4015,199 +2021-04-30,Tiktok Ads,4002,202 +2021-05-31,Tiktok Ads,4079,192 +2021-06-30,Tiktok Ads,4296,211 +2021-07-31,Tiktok Ads,4094,192 +2021-08-31,Tiktok Ads,4432,219 +2021-09-30,Tiktok Ads,4450,222 +2021-10-31,Tiktok Ads,4381,215 +2021-11-30,Tiktok Ads,4428,223 +2021-12-31,Tiktok Ads,4641,219 +2022-01-31,Tiktok Ads,4644,226 +2022-02-28,Tiktok Ads,4486,222 +2022-03-31,Tiktok Ads,4592,227 +2022-04-30,Tiktok Ads,4815,229 +2022-05-31,Tiktok Ads,4665,219 +2022-06-30,Tiktok Ads,4734,219 +2022-07-31,Tiktok Ads,4845,229 +2022-08-31,Tiktok Ads,4805,232 +2022-09-30,Tiktok Ads,4967,235 +2022-10-31,Tiktok Ads,5125,241 +2022-11-30,Tiktok Ads,5257,246 +2022-12-31,Tiktok Ads,5427,272 +2023-01-31,Tiktok Ads,5501,266 +2023-02-28,Tiktok Ads,5548,277 +2023-03-31,Tiktok Ads,5314,247 +2023-04-30,Tiktok Ads,5692,270 +2023-05-31,Tiktok Ads,5720,279 +2023-06-30,Tiktok Ads,5789,274 +2023-07-31,Tiktok Ads,5697,281 +2023-08-31,Tiktok Ads,5896,291 +2023-09-30,Tiktok Ads,6072,285 +2023-10-31,Tiktok Ads,5902,292 +2023-11-30,Tiktok Ads,5961,298 +2023-12-31,Tiktok Ads,6091,296 +2024-01-31,Tiktok Ads,6158,305 +2024-02-29,Tiktok Ads,6236,294 +2024-03-31,Tiktok Ads,6292,295 +2024-04-30,Tiktok Ads,6573,309 +2024-05-31,Tiktok Ads,6611,328 +2024-06-30,Tiktok Ads,6512,316 +2024-07-31,Tiktok Ads,6563,312 +2024-08-31,Tiktok Ads,6938,337 +2024-09-30,Tiktok Ads,6908,327 +2024-10-31,Tiktok Ads,6884,324 +2024-11-30,Tiktok Ads,7175,338 +2024-12-31,Tiktok Ads,7226,347 +2020-01-31,Referral,4997,72 +2020-02-29,Referral,5198,85 +2020-03-31,Referral,4905,73 +2020-04-30,Referral,5081,73 +2020-05-31,Referral,5382,75 +2020-06-30,Referral,5563,85 +2020-07-31,Referral,5528,90 +2020-08-31,Referral,5617,91 +2020-09-30,Referral,5512,85 +2020-10-31,Referral,5796,90 +2020-11-30,Referral,6023,83 +2020-12-31,Referral,5884,79 +2021-01-31,Referral,6168,92 +2021-02-28,Referral,6108,99 +2021-03-31,Referral,6219,85 +2021-04-30,Referral,6359,99 +2021-05-31,Referral,6467,91 +2021-06-30,Referral,6873,103 +2021-07-31,Referral,6800,99 +2021-08-31,Referral,7042,100 +2021-09-30,Referral,6969,106 +2021-10-31,Referral,7059,98 +2021-11-30,Referral,7491,102 +2021-12-31,Referral,7466,110 +2022-01-31,Referral,7662,113 +2022-02-28,Referral,7772,122 +2022-03-31,Referral,7829,119 +2022-04-30,Referral,8202,122 +2022-05-31,Referral,8312,121 +2022-06-30,Referral,8296,121 +2022-07-31,Referral,8482,126 +2022-08-31,Referral,8587,133 +2022-09-30,Referral,8666,123 +2022-10-31,Referral,8763,125 +2022-11-30,Referral,8986,136 +2022-12-31,Referral,9208,138 +2023-01-31,Referral,9376,135 +2023-02-28,Referral,9588,141 +2023-03-31,Referral,9797,143 +2023-04-30,Referral,9789,152 +2023-05-31,Referral,10201,142 +2023-06-30,Referral,10488,149 +2023-07-31,Referral,10490,149 +2023-08-31,Referral,10512,150 +2023-09-30,Referral,10974,170 +2023-10-31,Referral,11111,161 +2023-11-30,Referral,11451,174 +2023-12-31,Referral,11664,174 +2024-01-31,Referral,11799,164 +2024-02-29,Referral,12000,186 +2024-03-31,Referral,12314,188 +2024-04-30,Referral,12229,177 +2024-05-31,Referral,12476,186 +2024-06-30,Referral,12991,185 +2024-07-31,Referral,13074,186 +2024-08-31,Referral,13437,194 +2024-09-30,Referral,13735,211 +2024-10-31,Referral,13773,205 +2024-11-30,Referral,13856,201 +2024-12-31,Referral,14271,210 +2020-01-31,Meta Ads,2806,152 +2020-02-29,Meta Ads,2919,145 +2020-03-31,Meta Ads,2956,150 +2020-04-30,Meta Ads,3127,154 +2020-05-31,Meta Ads,3176,170 +2020-06-30,Meta Ads,3156,161 +2020-07-31,Meta Ads,3163,153 +2020-08-31,Meta Ads,3329,181 +2020-09-30,Meta Ads,3577,187 +2020-10-31,Meta Ads,3723,197 +2020-11-30,Meta Ads,3784,197 +2020-12-31,Meta Ads,3508,184 +2021-01-31,Meta Ads,3980,197 +2021-02-28,Meta Ads,4029,203 +2021-03-31,Meta Ads,3961,211 +2021-04-30,Meta Ads,4054,217 +2021-05-31,Meta Ads,4326,217 +2021-06-30,Meta Ads,4366,229 +2021-07-31,Meta Ads,4270,211 +2021-08-31,Meta Ads,4388,226 +2021-09-30,Meta Ads,4415,235 +2021-10-31,Meta Ads,4507,235 +2021-11-30,Meta Ads,4744,239 +2021-12-31,Meta Ads,4842,240 +2022-01-31,Meta Ads,4968,247 +2022-02-28,Meta Ads,5228,277 +2022-03-31,Meta Ads,5333,279 +2022-04-30,Meta Ads,5300,280 +2022-05-31,Meta Ads,5356,277 +2022-06-30,Meta Ads,5777,304 +2022-07-31,Meta Ads,5746,299 +2022-08-31,Meta Ads,5869,293 +2022-09-30,Meta Ads,6054,304 +2022-10-31,Meta Ads,6171,317 +2022-11-30,Meta Ads,6248,315 +2022-12-31,Meta Ads,6457,324 +2023-01-31,Meta Ads,6526,342 +2023-02-28,Meta Ads,6552,333 +2023-03-31,Meta Ads,6735,354 +2023-04-30,Meta Ads,7081,360 +2023-05-31,Meta Ads,7317,372 +2023-06-30,Meta Ads,7193,367 +2023-07-31,Meta Ads,7494,379 +2023-08-31,Meta Ads,7527,383 +2023-09-30,Meta Ads,8078,411 +2023-10-31,Meta Ads,7943,409 +2023-11-30,Meta Ads,8450,436 +2023-12-31,Meta Ads,8528,449 +2024-01-31,Meta Ads,8609,451 +2024-02-29,Meta Ads,8678,451 +2024-03-31,Meta Ads,9202,474 +2024-04-30,Meta Ads,9307,484 +2024-05-31,Meta Ads,9570,485 +2024-06-30,Meta Ads,9877,518 +2024-07-31,Meta Ads,9900,514 +2024-08-31,Meta Ads,10348,537 +2024-09-30,Meta Ads,10219,521 +2024-10-31,Meta Ads,10575,537 +2024-11-30,Meta Ads,11048,577 +2024-12-31,Meta Ads,11117,572 diff --git a/browser_use_e2e_test_app/morph_project.yml b/browser_use_e2e_test_app/morph_project.yml new file mode 100644 index 0000000..c1f2fc5 --- /dev/null +++ b/browser_use_e2e_test_app/morph_project.yml @@ -0,0 +1,7 @@ +default_connection: DUCKDB +package_manager: poetry +profile: default +project_id: null +result_cache_ttl: 0 +source_paths: +- src diff --git a/browser_use_e2e_test_app/package.json b/browser_use_e2e_test_app/package.json new file mode 100644 index 0000000..52ebc56 --- /dev/null +++ b/browser_use_e2e_test_app/package.json @@ -0,0 +1,14 @@ +{ + "name": "morph-project", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "build": "npm run build -w .morph/frontend" + }, + "dependencies": {}, + "devDependencies": {}, + "workspaces": [ + ".morph/frontend" + ] +} diff --git a/browser_use_e2e_test_app/pyproject.toml b/browser_use_e2e_test_app/pyproject.toml new file mode 100644 index 0000000..807badb --- /dev/null +++ b/browser_use_e2e_test_app/pyproject.toml @@ -0,0 +1,17 @@ +[tool.poetry] +name = "browser_use_e2e_test_app" +version = "0.1.0" +description = "" +authors = ["shibatanaoto "] +readme = "README.md" +packages = [ + { include = "src" } +] + +[tool.poetry.dependencies] +python = ">=3.9,<3.13" +morph-data = "0.1.4" + +[build-system] +requires = ["poetry-core"] +build-backend = "poetry.core.masonry.api" diff --git a/browser_use_e2e_test_app/src/pages/index.mdx b/browser_use_e2e_test_app/src/pages/index.mdx new file mode 100644 index 0000000..4a5b0b5 --- /dev/null +++ b/browser_use_e2e_test_app/src/pages/index.mdx @@ -0,0 +1,59 @@ +import { defineState } from '@morph-data/components'; +export const { chartType } = defineState({ chartType: 'stacked' }); +export const title = "Marketing campaign report" + +# Marketing campaign report + +SQL, Python and MDX. + +This report shows the traffic and orders data from our marketing campaigns across different sources. The data spans from 2023 to 2025, tracking both traffic volume and resulting orders. + +Key points: +- Traffic and orders are tracked monthly +- Data is segmented by traffic source (Coupon, Google Organic, etc.) +- Interactive visualizations allow different views of the data +- Raw data is available in the table below + + +

+ This report is based on the following data retrieved by DuckDB: +

+```sql +select + Date as data, + Source as source, + Traffic as traffic, + Orders as orders +from + read_csv("data/Traffic_Orders_Demo_Data.csv") +where + Date >= '2023-01-01' +``` +
+ +## Campagin Result + + + +### Chart + +
+ +
+ + diff --git a/browser_use_e2e_test_app/src/pages/sql_agent.mdx b/browser_use_e2e_test_app/src/pages/sql_agent.mdx new file mode 100644 index 0000000..dc63836 --- /dev/null +++ b/browser_use_e2e_test_app/src/pages/sql_agent.mdx @@ -0,0 +1,20 @@ +export const title = "AI Agent" + +### Chat with SQL Agent + + +To use this feature, please set your `OPENAI_API_KEY` in `.env` file. + +After setting the API key, let's ask "What is the total traffic and orders for each source?" + + +You can ask questions to the SQL Agent about the data and get the answer in SQL. + + +
+ +
+
+ +
+
diff --git a/browser_use_e2e_test_app/src/python/example.py b/browser_use_e2e_test_app/src/python/example.py new file mode 100644 index 0000000..0f02ed4 --- /dev/null +++ b/browser_use_e2e_test_app/src/python/example.py @@ -0,0 +1,48 @@ +import pandas as pd +import plotly.express as px + +import morph +from morph import MorphGlobalContext + + +@morph.func +@morph.load_data("example_data") +def example_chart(context: MorphGlobalContext): + df = context.data["example_data"] + + chart_type = context.vars["chartType"] + if chart_type == "line": + fig = px.line(df, x="data", y=["traffic", "orders"], color="source") + elif chart_type == "stacked": + fig = px.bar(df, x="data", y="traffic", color="source", barmode="stack") + elif chart_type == "area": + fig = px.area(df, x="data", y="traffic", color="source") + return fig + + +@morph.func +@morph.load_data("example_data") +def example_metrics(context: MorphGlobalContext): + df = context.data["example_data"] + + # Get the latest date + latest_date = df["data"].max() + latest_df = df[df["data"] == latest_date] + + # Get the best campaign in the latest month + best_campaign = latest_df.loc[latest_df["orders"].idxmax(), "source"] + + # Get the total orders and traffic in the latest month + total_orders = latest_df["orders"].sum() + total_traffic = latest_df["traffic"].sum() + + result_df = pd.DataFrame( + [ + {"label": "Latest Date", "value": latest_date.strftime("%Y-%m-%d")}, + {"label": "Best Campaign", "value": best_campaign}, + {"label": "Total Orders", "value": f"{total_orders:,}"}, + {"label": "Total Traffic", "value": f"{total_traffic:,}"}, + ] + ) + + return result_df diff --git a/browser_use_e2e_test_app/src/python/sql_agent.py b/browser_use_e2e_test_app/src/python/sql_agent.py new file mode 100644 index 0000000..f78323c --- /dev/null +++ b/browser_use_e2e_test_app/src/python/sql_agent.py @@ -0,0 +1,107 @@ +import json +import os +from typing import Generator + +from morph_lib.database import execute_sql +from morph_lib.stream import stream_chat +from morph_lib.types import MorphChatStreamChunk +from openai import OpenAI + +import morph +from morph import MorphGlobalContext + + +@morph.func(name="sql_agent") +def sql_agent( + context: MorphGlobalContext, +) -> Generator[MorphChatStreamChunk, None, None]: + if os.getenv("OPENAI_API_KEY") is None: + yield stream_chat("Please set your OPENAI_API_KEY in .env file.") + return + # context.user_info comes from user's authentication info. + if context.user_info is None or "Admin" not in context.user_info["roles"]: + yield stream_chat("You are not authorized to use this feature.") + + client = OpenAI(api_key=os.getenv("OPENAI_API_KEY")) + prompt = context.vars["prompt"] + messages = [ + { + "role": "system", + "content": """Please execute SQL queries on a table named ./data/Traffic_Orders_Demo_Data.csv in DuckDB with the following schema: +Date: text - date +Source: text - traffic source (Coupon, Google Organic など) +Traffic: int - traffic count +Orders: int - order count + +This table contains traffic and order data for the marketing campaigns. + +As a source, you have the following data: +- Coupon +- Google Organic +- Google Paid +- TikTok Ads +- Meta Ads +- Referral +""", + } + ] + messages.append({"role": "user", "content": prompt}) + + response = client.chat.completions.create( + model="gpt-4o", + messages=messages, + functions=[ + { + "name": "generate_sql", + "description": "Generate SQL queries based on user prompt", + "parameters": { + "type": "object", + "properties": { + "sql": { + "type": "string", + "description": "The SQL query generated based on the prompt", + }, + }, + "required": ["sql"], + }, + } + ], + ) + + response_json = json.loads(response.choices[0].message.function_call.arguments) + sql = response_json["sql"] + yield stream_chat( + f""" +## SQL Query +```sql +{sql} +``` +""" + ) + data = execute_sql(sql, "DUCKDB") + data_md = data.to_markdown(index=False) + yield stream_chat( + f""" +{data_md} +""" + ) + messages.extend( + [ + { + "role": "system", + "content": f"""Please answer in markdown format. +You can use the following data: +{data_md} +""", + }, + {"role": "user", "content": prompt}, + ] + ) + response = client.chat.completions.create( + model="gpt-4o", + messages=messages, + stream=True, + ) + + for chunk in response: + yield stream_chat(chunk.choices[0].delta.content) diff --git a/browser_use_e2e_test_app/src/sql/example_data.sql b/browser_use_e2e_test_app/src/sql/example_data.sql new file mode 100644 index 0000000..9403c29 --- /dev/null +++ b/browser_use_e2e_test_app/src/sql/example_data.sql @@ -0,0 +1,16 @@ +{{ + config( + name = "example_data", + connection = "DUCKDB" + ) +}} + +select + Date as data, + Source as source, + Traffic as traffic, + Orders as orders +from + read_csv("./data/Traffic_Orders_Demo_Data.csv") +where + Date >= '2023-01-01'