From 3ac75d7fce3fe76f5b75bfd45f83c556c3a0b351 Mon Sep 17 00:00:00 2001 From: Kumaran Rajendhiran Date: Mon, 25 Nov 2024 14:05:11 +0530 Subject: [PATCH 1/5] Update cookiecutter generated files (#604) --- .../docker/content/nginx.conf.template | 56 ++++++++++- .../docker/content/run_fastagency.sh | 35 +++++-- .../fastapi/my_fastagency_app/fly.toml | 27 ++++++ .../scripts/register_to_fly_io.sh | 4 +- .../docker/content/nginx.conf.template | 18 +++- .../docker/content/run_fastagency.sh | 28 ++++-- .../mesop/my_fastagency_app/fly.toml | 14 +++ .../scripts/register_to_fly_io.sh | 4 +- .../docker/content/nginx.conf.template | 94 ++++++++++++++++++- .../docker/content/run_fastagency.sh | 45 ++++++--- .../nats_n_fastapi/my_fastagency_app/fly.toml | 40 ++++++++ .../scripts/register_to_fly_io.sh | 4 +- .../docker/content/nginx.conf.template | 56 ++++++++++- .../docker/content/run_fastagency.sh | 35 +++++-- .../fastapi/my_fastagency_app/fly.toml | 27 ++++++ .../scripts/register_to_fly_io.sh | 4 +- .../docker/content/nginx.conf.template | 18 +++- .../docker/content/run_fastagency.sh | 28 ++++-- .../no_auth/mesop/my_fastagency_app/fly.toml | 14 +++ .../scripts/register_to_fly_io.sh | 4 +- .../docker/content/nginx.conf.template | 94 ++++++++++++++++++- .../docker/content/run_fastagency.sh | 45 ++++++--- .../nats_n_fastapi/my_fastagency_app/fly.toml | 40 ++++++++ .../scripts/register_to_fly_io.sh | 4 +- 24 files changed, 648 insertions(+), 90 deletions(-) diff --git a/docs/docs_src/getting_started/basic_auth/fastapi/my_fastagency_app/docker/content/nginx.conf.template b/docs/docs_src/getting_started/basic_auth/fastapi/my_fastagency_app/docker/content/nginx.conf.template index 52347c6e..24a2cd5f 100644 --- a/docs/docs_src/getting_started/basic_auth/fastapi/my_fastagency_app/docker/content/nginx.conf.template +++ b/docs/docs_src/getting_started/basic_auth/fastapi/my_fastagency_app/docker/content/nginx.conf.template @@ -1,3 +1,17 @@ +upstream nats_fastapi_backend { + # Enable sticky sessions with IP hash + ip_hash; + + +} + +upstream fastapi_backend { + # Enable sticky sessions with IP hash + ip_hash; + + +} + upstream mesop_backend { # Enable sticky sessions with IP hash ip_hash; @@ -18,9 +32,47 @@ map $fly_machine_id $sticky_action { default "replay"; # Cookie exists but doesn't match - need to replay } -# Main server block +# Fastapi server block +server { + listen $FASTAPI_PORT; + server_name localhost; + + # Security headers + add_header X-Frame-Options "SAMEORIGIN"; + add_header X-Content-Type-Options "nosniff"; + add_header X-XSS-Protection "1; mode=block"; + + location / { + # Handle cookie setting + if ($sticky_action = "set_cookie") { + add_header Set-Cookie "fly-machine-id=$FLY_MACHINE_ID; Max-Age=518400; Path=/"; + } + + # Handle replay + if ($sticky_action = "replay") { + add_header Fly-Replay "instance=$fly_machine_id"; + return 307; + } + + proxy_pass http://fastapi_backend; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_redirect off; + proxy_buffering off; + + # WSGI support + proxy_set_header X-Forwarded-Host $server_name; + + # WebSocket support + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + } +} +# Mesop server block server { - listen $SERVICE_PORT; + listen $MESOP_PORT; server_name localhost; # Security headers diff --git a/docs/docs_src/getting_started/basic_auth/fastapi/my_fastagency_app/docker/content/run_fastagency.sh b/docs/docs_src/getting_started/basic_auth/fastapi/my_fastagency_app/docker/content/run_fastagency.sh index 548457f6..77d9d2a9 100755 --- a/docs/docs_src/getting_started/basic_auth/fastapi/my_fastagency_app/docker/content/run_fastagency.sh +++ b/docs/docs_src/getting_started/basic_auth/fastapi/my_fastagency_app/docker/content/run_fastagency.sh @@ -1,13 +1,9 @@ #!/bin/bash # Accept env variable for PORT - - -FASTAPI_PORT=${FASTAPI_PORT:-8008} - - +export NATS_FASTAPI_PORT=${NATS_FASTAPI_PORT:-8000} +export FASTAPI_PORT=${FASTAPI_PORT:-8008} export MESOP_PORT=${MESOP_PORT:-8888} -export SERVICE_PORT=$MESOP_PORT # Default number of workers if not set WORKERS=${WORKERS:-1} @@ -20,10 +16,23 @@ echo "Fly machine ID: $FLY_MACHINE_ID" # Generate nginx config for ((i=1; i<$WORKERS+1; i++)) do - PORT=$((SERVICE_PORT + i)) + PORT=$((MESOP_PORT + i)) + sed -i "19i\ server 127.0.0.1:$PORT;" nginx.conf.template +done + +for ((i=1; i<$WORKERS+1; i++)) +do + PORT=$((FASTAPI_PORT + i)) + sed -i "12i\ server 127.0.0.1:$PORT;" nginx.conf.template +done + +for ((i=1; i<$WORKERS+1; i++)) +do + PORT=$((NATS_FASTAPI_PORT + i)) sed -i "5i\ server 127.0.0.1:$PORT;" nginx.conf.template done -envsubst '${SERVICE_PORT},${FLY_MACHINE_ID}' < nginx.conf.template >/etc/nginx/conf.d/default.conf + +envsubst '${NATS_FASTAPI_PORT},${FASTAPI_PORT},${MESOP_PORT},${FLY_MACHINE_ID}' < nginx.conf.template >/etc/nginx/conf.d/default.conf echo "Nginx config:" cat /etc/nginx/conf.d/default.conf @@ -32,14 +41,20 @@ nginx -g "daemon off;" & # Run uvicorn server -uvicorn my_fastagency_app.deployment.main_1_fastapi:app --host 0.0.0.0 --port $FASTAPI_PORT > /dev/stdout 2>&1 & +# Start multiple single-worker uvicorn instances on consecutive ports +for ((i=1; i<$WORKERS+1; i++)) +do + PORT=$((FASTAPI_PORT + i)) + echo "Starting fastapi uvicorn on port $PORT" + uvicorn my_fastagency_app.deployment.main_1_fastapi:app --workers=1 --host 0.0.0.0 --port $PORT > /dev/stdout 2>&1 & +done # Run gunicorn server # Start multiple single-worker gunicorn instances on consecutive ports for ((i=1; i<$WORKERS+1; i++)) do - PORT=$((SERVICE_PORT + i)) + PORT=$((MESOP_PORT + i)) echo "Starting gunicorn on port $PORT" gunicorn --workers=1 my_fastagency_app.deployment.main_2_mesop:app --bind 0.0.0.0:$PORT > /dev/stdout 2>&1 & done diff --git a/docs/docs_src/getting_started/basic_auth/fastapi/my_fastagency_app/fly.toml b/docs/docs_src/getting_started/basic_auth/fastapi/my_fastagency_app/fly.toml index 742cfd80..d19237b6 100644 --- a/docs/docs_src/getting_started/basic_auth/fastapi/my_fastagency_app/fly.toml +++ b/docs/docs_src/getting_started/basic_auth/fastapi/my_fastagency_app/fly.toml @@ -21,3 +21,30 @@ primary_region = 'ams' memory = '1gb' cpu_kind = 'shared' cpus = 1 + +[[services]] + http_checks = [] + internal_port = 8008 + processes = ["app"] + protocol = "tcp" + script_checks = [] + + [services.concurrency] + type = "connections" + + [[services.ports]] + handlers = ["tls", "http"] + port = 8008 +[[services]] + http_checks = [] + internal_port = 8888 + processes = ["app"] + protocol = "tcp" + script_checks = [] + + [services.concurrency] + type = "connections" + + [[services.ports]] + handlers = ["tls", "http"] + port = 8888 diff --git a/docs/docs_src/getting_started/basic_auth/fastapi/my_fastagency_app/scripts/register_to_fly_io.sh b/docs/docs_src/getting_started/basic_auth/fastapi/my_fastagency_app/scripts/register_to_fly_io.sh index a49aac06..bfd9711a 100755 --- a/docs/docs_src/getting_started/basic_auth/fastapi/my_fastagency_app/scripts/register_to_fly_io.sh +++ b/docs/docs_src/getting_started/basic_auth/fastapi/my_fastagency_app/scripts/register_to_fly_io.sh @@ -17,7 +17,7 @@ else echo -e "\033[0;32mAlready logged into fly.io\033[0m" fi -export FLY_APP_NAME=my-fastagency-app +export FLY_APP_NAME=$(grep "^app = " fly.toml | awk -F"'" '{print $2}') echo -e "\033[0;32mRegistering app name in fly.io\033[0m" if flyctl apps create $FLY_APP_NAME; then @@ -27,6 +27,6 @@ if flyctl apps create $FLY_APP_NAME; then cat registered_app_domain.txt else echo -e "\033[1;31mError: App name is not available.\033[0m" - echo -e "\033[1;31mPlease change the app name in fly.toml and scripts/register_to_fly_io.sh and run this script again.\033[0m" + echo -e "\033[1;31mPlease change the app name in fly.toml and run this script again.\033[0m" exit 1 fi diff --git a/docs/docs_src/getting_started/basic_auth/mesop/my_fastagency_app/docker/content/nginx.conf.template b/docs/docs_src/getting_started/basic_auth/mesop/my_fastagency_app/docker/content/nginx.conf.template index 52347c6e..626bce1c 100644 --- a/docs/docs_src/getting_started/basic_auth/mesop/my_fastagency_app/docker/content/nginx.conf.template +++ b/docs/docs_src/getting_started/basic_auth/mesop/my_fastagency_app/docker/content/nginx.conf.template @@ -1,3 +1,17 @@ +upstream nats_fastapi_backend { + # Enable sticky sessions with IP hash + ip_hash; + + +} + +upstream fastapi_backend { + # Enable sticky sessions with IP hash + ip_hash; + + +} + upstream mesop_backend { # Enable sticky sessions with IP hash ip_hash; @@ -18,9 +32,9 @@ map $fly_machine_id $sticky_action { default "replay"; # Cookie exists but doesn't match - need to replay } -# Main server block +# Mesop server block server { - listen $SERVICE_PORT; + listen $MESOP_PORT; server_name localhost; # Security headers diff --git a/docs/docs_src/getting_started/basic_auth/mesop/my_fastagency_app/docker/content/run_fastagency.sh b/docs/docs_src/getting_started/basic_auth/mesop/my_fastagency_app/docker/content/run_fastagency.sh index 55aa17d3..a6cb4cf0 100755 --- a/docs/docs_src/getting_started/basic_auth/mesop/my_fastagency_app/docker/content/run_fastagency.sh +++ b/docs/docs_src/getting_started/basic_auth/mesop/my_fastagency_app/docker/content/run_fastagency.sh @@ -1,11 +1,9 @@ #!/bin/bash # Accept env variable for PORT - - - +export NATS_FASTAPI_PORT=${NATS_FASTAPI_PORT:-8000} +export FASTAPI_PORT=${FASTAPI_PORT:-8008} export MESOP_PORT=${MESOP_PORT:-8888} -export SERVICE_PORT=$MESOP_PORT # Default number of workers if not set WORKERS=${WORKERS:-1} @@ -18,10 +16,23 @@ echo "Fly machine ID: $FLY_MACHINE_ID" # Generate nginx config for ((i=1; i<$WORKERS+1; i++)) do - PORT=$((SERVICE_PORT + i)) + PORT=$((MESOP_PORT + i)) + sed -i "19i\ server 127.0.0.1:$PORT;" nginx.conf.template +done + +for ((i=1; i<$WORKERS+1; i++)) +do + PORT=$((FASTAPI_PORT + i)) + sed -i "12i\ server 127.0.0.1:$PORT;" nginx.conf.template +done + +for ((i=1; i<$WORKERS+1; i++)) +do + PORT=$((NATS_FASTAPI_PORT + i)) sed -i "5i\ server 127.0.0.1:$PORT;" nginx.conf.template done -envsubst '${SERVICE_PORT},${FLY_MACHINE_ID}' < nginx.conf.template >/etc/nginx/conf.d/default.conf + +envsubst '${NATS_FASTAPI_PORT},${FASTAPI_PORT},${MESOP_PORT},${FLY_MACHINE_ID}' < nginx.conf.template >/etc/nginx/conf.d/default.conf echo "Nginx config:" cat /etc/nginx/conf.d/default.conf @@ -29,15 +40,12 @@ cat /etc/nginx/conf.d/default.conf nginx -g "daemon off;" & -# Run uvicorn server -uvicorn my_fastagency_app.deployment.main_:app --host 0.0.0.0 --port $FASTAPI_PORT > /dev/stdout 2>&1 & - # Run gunicorn server # Start multiple single-worker gunicorn instances on consecutive ports for ((i=1; i<$WORKERS+1; i++)) do - PORT=$((SERVICE_PORT + i)) + PORT=$((MESOP_PORT + i)) echo "Starting gunicorn on port $PORT" gunicorn --workers=1 my_fastagency_app.deployment.main:app --bind 0.0.0.0:$PORT > /dev/stdout 2>&1 & done diff --git a/docs/docs_src/getting_started/basic_auth/mesop/my_fastagency_app/fly.toml b/docs/docs_src/getting_started/basic_auth/mesop/my_fastagency_app/fly.toml index 742cfd80..ed002a65 100644 --- a/docs/docs_src/getting_started/basic_auth/mesop/my_fastagency_app/fly.toml +++ b/docs/docs_src/getting_started/basic_auth/mesop/my_fastagency_app/fly.toml @@ -21,3 +21,17 @@ primary_region = 'ams' memory = '1gb' cpu_kind = 'shared' cpus = 1 + +[[services]] + http_checks = [] + internal_port = 8888 + processes = ["app"] + protocol = "tcp" + script_checks = [] + + [services.concurrency] + type = "connections" + + [[services.ports]] + handlers = ["tls", "http"] + port = 8888 diff --git a/docs/docs_src/getting_started/basic_auth/mesop/my_fastagency_app/scripts/register_to_fly_io.sh b/docs/docs_src/getting_started/basic_auth/mesop/my_fastagency_app/scripts/register_to_fly_io.sh index a49aac06..bfd9711a 100755 --- a/docs/docs_src/getting_started/basic_auth/mesop/my_fastagency_app/scripts/register_to_fly_io.sh +++ b/docs/docs_src/getting_started/basic_auth/mesop/my_fastagency_app/scripts/register_to_fly_io.sh @@ -17,7 +17,7 @@ else echo -e "\033[0;32mAlready logged into fly.io\033[0m" fi -export FLY_APP_NAME=my-fastagency-app +export FLY_APP_NAME=$(grep "^app = " fly.toml | awk -F"'" '{print $2}') echo -e "\033[0;32mRegistering app name in fly.io\033[0m" if flyctl apps create $FLY_APP_NAME; then @@ -27,6 +27,6 @@ if flyctl apps create $FLY_APP_NAME; then cat registered_app_domain.txt else echo -e "\033[1;31mError: App name is not available.\033[0m" - echo -e "\033[1;31mPlease change the app name in fly.toml and scripts/register_to_fly_io.sh and run this script again.\033[0m" + echo -e "\033[1;31mPlease change the app name in fly.toml and run this script again.\033[0m" exit 1 fi diff --git a/docs/docs_src/getting_started/basic_auth/nats_n_fastapi/my_fastagency_app/docker/content/nginx.conf.template b/docs/docs_src/getting_started/basic_auth/nats_n_fastapi/my_fastagency_app/docker/content/nginx.conf.template index 52347c6e..3e295c7b 100644 --- a/docs/docs_src/getting_started/basic_auth/nats_n_fastapi/my_fastagency_app/docker/content/nginx.conf.template +++ b/docs/docs_src/getting_started/basic_auth/nats_n_fastapi/my_fastagency_app/docker/content/nginx.conf.template @@ -1,3 +1,17 @@ +upstream nats_fastapi_backend { + # Enable sticky sessions with IP hash + ip_hash; + + +} + +upstream fastapi_backend { + # Enable sticky sessions with IP hash + ip_hash; + + +} + upstream mesop_backend { # Enable sticky sessions with IP hash ip_hash; @@ -18,9 +32,85 @@ map $fly_machine_id $sticky_action { default "replay"; # Cookie exists but doesn't match - need to replay } -# Main server block +# Nats fastapi server block +server { + listen $NATS_FASTAPI_PORT; + server_name localhost; + + # Security headers + add_header X-Frame-Options "SAMEORIGIN"; + add_header X-Content-Type-Options "nosniff"; + add_header X-XSS-Protection "1; mode=block"; + + location / { + # Handle cookie setting + if ($sticky_action = "set_cookie") { + add_header Set-Cookie "fly-machine-id=$FLY_MACHINE_ID; Max-Age=518400; Path=/"; + } + + # Handle replay + if ($sticky_action = "replay") { + add_header Fly-Replay "instance=$fly_machine_id"; + return 307; + } + + proxy_pass http://nats_fastapi_backend; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_redirect off; + proxy_buffering off; + + # WSGI support + proxy_set_header X-Forwarded-Host $server_name; + + # WebSocket support + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + } +} +# Fastapi server block +server { + listen $FASTAPI_PORT; + server_name localhost; + + # Security headers + add_header X-Frame-Options "SAMEORIGIN"; + add_header X-Content-Type-Options "nosniff"; + add_header X-XSS-Protection "1; mode=block"; + + location / { + # Handle cookie setting + if ($sticky_action = "set_cookie") { + add_header Set-Cookie "fly-machine-id=$FLY_MACHINE_ID; Max-Age=518400; Path=/"; + } + + # Handle replay + if ($sticky_action = "replay") { + add_header Fly-Replay "instance=$fly_machine_id"; + return 307; + } + + proxy_pass http://fastapi_backend; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_redirect off; + proxy_buffering off; + + # WSGI support + proxy_set_header X-Forwarded-Host $server_name; + + # WebSocket support + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + } +} +# Mesop server block server { - listen $SERVICE_PORT; + listen $MESOP_PORT; server_name localhost; # Security headers diff --git a/docs/docs_src/getting_started/basic_auth/nats_n_fastapi/my_fastagency_app/docker/content/run_fastagency.sh b/docs/docs_src/getting_started/basic_auth/nats_n_fastapi/my_fastagency_app/docker/content/run_fastagency.sh index 1db12dbb..0ba28573 100755 --- a/docs/docs_src/getting_started/basic_auth/nats_n_fastapi/my_fastagency_app/docker/content/run_fastagency.sh +++ b/docs/docs_src/getting_started/basic_auth/nats_n_fastapi/my_fastagency_app/docker/content/run_fastagency.sh @@ -1,15 +1,9 @@ #!/bin/bash # Accept env variable for PORT - -NATS_FASTAPI_PORT=${NATS_FASTAPI_PORT:-8000} - - -FASTAPI_PORT=${FASTAPI_PORT:-8008} - - +export NATS_FASTAPI_PORT=${NATS_FASTAPI_PORT:-8000} +export FASTAPI_PORT=${FASTAPI_PORT:-8008} export MESOP_PORT=${MESOP_PORT:-8888} -export SERVICE_PORT=$MESOP_PORT # Default number of workers if not set WORKERS=${WORKERS:-1} @@ -22,10 +16,23 @@ echo "Fly machine ID: $FLY_MACHINE_ID" # Generate nginx config for ((i=1; i<$WORKERS+1; i++)) do - PORT=$((SERVICE_PORT + i)) + PORT=$((MESOP_PORT + i)) + sed -i "19i\ server 127.0.0.1:$PORT;" nginx.conf.template +done + +for ((i=1; i<$WORKERS+1; i++)) +do + PORT=$((FASTAPI_PORT + i)) + sed -i "12i\ server 127.0.0.1:$PORT;" nginx.conf.template +done + +for ((i=1; i<$WORKERS+1; i++)) +do + PORT=$((NATS_FASTAPI_PORT + i)) sed -i "5i\ server 127.0.0.1:$PORT;" nginx.conf.template done -envsubst '${SERVICE_PORT},${FLY_MACHINE_ID}' < nginx.conf.template >/etc/nginx/conf.d/default.conf + +envsubst '${NATS_FASTAPI_PORT},${FASTAPI_PORT},${MESOP_PORT},${FLY_MACHINE_ID}' < nginx.conf.template >/etc/nginx/conf.d/default.conf echo "Nginx config:" cat /etc/nginx/conf.d/default.conf @@ -33,18 +40,30 @@ cat /etc/nginx/conf.d/default.conf nginx -g "daemon off;" & # Run nats uvicorn server -uvicorn my_fastagency_app.deployment.main_1_nats:app --host 0.0.0.0 --port $NATS_FASTAPI_PORT > /dev/stdout 2>&1 & +# Start multiple single-worker uvicorn instances on consecutive ports +for ((i=1; i<$WORKERS+1; i++)) +do + PORT=$((NATS_FASTAPI_PORT + i)) + echo "Starting nats fastapi uvicorn on port $PORT" + uvicorn my_fastagency_app.deployment.main_1_nats:app --workers=1 --host 0.0.0.0 --port $PORT > /dev/stdout 2>&1 & +done # Run uvicorn server -uvicorn my_fastagency_app.deployment.main_2_fastapi:app --host 0.0.0.0 --port $FASTAPI_PORT > /dev/stdout 2>&1 & +# Start multiple single-worker uvicorn instances on consecutive ports +for ((i=1; i<$WORKERS+1; i++)) +do + PORT=$((FASTAPI_PORT + i)) + echo "Starting fastapi uvicorn on port $PORT" + uvicorn my_fastagency_app.deployment.main_2_fastapi:app --workers=1 --host 0.0.0.0 --port $PORT > /dev/stdout 2>&1 & +done # Run gunicorn server # Start multiple single-worker gunicorn instances on consecutive ports for ((i=1; i<$WORKERS+1; i++)) do - PORT=$((SERVICE_PORT + i)) + PORT=$((MESOP_PORT + i)) echo "Starting gunicorn on port $PORT" gunicorn --workers=1 my_fastagency_app.deployment.main_3_mesop:app --bind 0.0.0.0:$PORT > /dev/stdout 2>&1 & done diff --git a/docs/docs_src/getting_started/basic_auth/nats_n_fastapi/my_fastagency_app/fly.toml b/docs/docs_src/getting_started/basic_auth/nats_n_fastapi/my_fastagency_app/fly.toml index 742cfd80..ef085a35 100644 --- a/docs/docs_src/getting_started/basic_auth/nats_n_fastapi/my_fastagency_app/fly.toml +++ b/docs/docs_src/getting_started/basic_auth/nats_n_fastapi/my_fastagency_app/fly.toml @@ -21,3 +21,43 @@ primary_region = 'ams' memory = '1gb' cpu_kind = 'shared' cpus = 1 + +[[services]] + http_checks = [] + internal_port = 8000 + processes = ["app"] + protocol = "tcp" + script_checks = [] + + [services.concurrency] + type = "connections" + + [[services.ports]] + handlers = ["tls", "http"] + port = 8000 +[[services]] + http_checks = [] + internal_port = 8008 + processes = ["app"] + protocol = "tcp" + script_checks = [] + + [services.concurrency] + type = "connections" + + [[services.ports]] + handlers = ["tls", "http"] + port = 8008 +[[services]] + http_checks = [] + internal_port = 8888 + processes = ["app"] + protocol = "tcp" + script_checks = [] + + [services.concurrency] + type = "connections" + + [[services.ports]] + handlers = ["tls", "http"] + port = 8888 diff --git a/docs/docs_src/getting_started/basic_auth/nats_n_fastapi/my_fastagency_app/scripts/register_to_fly_io.sh b/docs/docs_src/getting_started/basic_auth/nats_n_fastapi/my_fastagency_app/scripts/register_to_fly_io.sh index a49aac06..bfd9711a 100755 --- a/docs/docs_src/getting_started/basic_auth/nats_n_fastapi/my_fastagency_app/scripts/register_to_fly_io.sh +++ b/docs/docs_src/getting_started/basic_auth/nats_n_fastapi/my_fastagency_app/scripts/register_to_fly_io.sh @@ -17,7 +17,7 @@ else echo -e "\033[0;32mAlready logged into fly.io\033[0m" fi -export FLY_APP_NAME=my-fastagency-app +export FLY_APP_NAME=$(grep "^app = " fly.toml | awk -F"'" '{print $2}') echo -e "\033[0;32mRegistering app name in fly.io\033[0m" if flyctl apps create $FLY_APP_NAME; then @@ -27,6 +27,6 @@ if flyctl apps create $FLY_APP_NAME; then cat registered_app_domain.txt else echo -e "\033[1;31mError: App name is not available.\033[0m" - echo -e "\033[1;31mPlease change the app name in fly.toml and scripts/register_to_fly_io.sh and run this script again.\033[0m" + echo -e "\033[1;31mPlease change the app name in fly.toml and run this script again.\033[0m" exit 1 fi diff --git a/docs/docs_src/getting_started/no_auth/fastapi/my_fastagency_app/docker/content/nginx.conf.template b/docs/docs_src/getting_started/no_auth/fastapi/my_fastagency_app/docker/content/nginx.conf.template index 52347c6e..24a2cd5f 100644 --- a/docs/docs_src/getting_started/no_auth/fastapi/my_fastagency_app/docker/content/nginx.conf.template +++ b/docs/docs_src/getting_started/no_auth/fastapi/my_fastagency_app/docker/content/nginx.conf.template @@ -1,3 +1,17 @@ +upstream nats_fastapi_backend { + # Enable sticky sessions with IP hash + ip_hash; + + +} + +upstream fastapi_backend { + # Enable sticky sessions with IP hash + ip_hash; + + +} + upstream mesop_backend { # Enable sticky sessions with IP hash ip_hash; @@ -18,9 +32,47 @@ map $fly_machine_id $sticky_action { default "replay"; # Cookie exists but doesn't match - need to replay } -# Main server block +# Fastapi server block +server { + listen $FASTAPI_PORT; + server_name localhost; + + # Security headers + add_header X-Frame-Options "SAMEORIGIN"; + add_header X-Content-Type-Options "nosniff"; + add_header X-XSS-Protection "1; mode=block"; + + location / { + # Handle cookie setting + if ($sticky_action = "set_cookie") { + add_header Set-Cookie "fly-machine-id=$FLY_MACHINE_ID; Max-Age=518400; Path=/"; + } + + # Handle replay + if ($sticky_action = "replay") { + add_header Fly-Replay "instance=$fly_machine_id"; + return 307; + } + + proxy_pass http://fastapi_backend; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_redirect off; + proxy_buffering off; + + # WSGI support + proxy_set_header X-Forwarded-Host $server_name; + + # WebSocket support + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + } +} +# Mesop server block server { - listen $SERVICE_PORT; + listen $MESOP_PORT; server_name localhost; # Security headers diff --git a/docs/docs_src/getting_started/no_auth/fastapi/my_fastagency_app/docker/content/run_fastagency.sh b/docs/docs_src/getting_started/no_auth/fastapi/my_fastagency_app/docker/content/run_fastagency.sh index 548457f6..77d9d2a9 100755 --- a/docs/docs_src/getting_started/no_auth/fastapi/my_fastagency_app/docker/content/run_fastagency.sh +++ b/docs/docs_src/getting_started/no_auth/fastapi/my_fastagency_app/docker/content/run_fastagency.sh @@ -1,13 +1,9 @@ #!/bin/bash # Accept env variable for PORT - - -FASTAPI_PORT=${FASTAPI_PORT:-8008} - - +export NATS_FASTAPI_PORT=${NATS_FASTAPI_PORT:-8000} +export FASTAPI_PORT=${FASTAPI_PORT:-8008} export MESOP_PORT=${MESOP_PORT:-8888} -export SERVICE_PORT=$MESOP_PORT # Default number of workers if not set WORKERS=${WORKERS:-1} @@ -20,10 +16,23 @@ echo "Fly machine ID: $FLY_MACHINE_ID" # Generate nginx config for ((i=1; i<$WORKERS+1; i++)) do - PORT=$((SERVICE_PORT + i)) + PORT=$((MESOP_PORT + i)) + sed -i "19i\ server 127.0.0.1:$PORT;" nginx.conf.template +done + +for ((i=1; i<$WORKERS+1; i++)) +do + PORT=$((FASTAPI_PORT + i)) + sed -i "12i\ server 127.0.0.1:$PORT;" nginx.conf.template +done + +for ((i=1; i<$WORKERS+1; i++)) +do + PORT=$((NATS_FASTAPI_PORT + i)) sed -i "5i\ server 127.0.0.1:$PORT;" nginx.conf.template done -envsubst '${SERVICE_PORT},${FLY_MACHINE_ID}' < nginx.conf.template >/etc/nginx/conf.d/default.conf + +envsubst '${NATS_FASTAPI_PORT},${FASTAPI_PORT},${MESOP_PORT},${FLY_MACHINE_ID}' < nginx.conf.template >/etc/nginx/conf.d/default.conf echo "Nginx config:" cat /etc/nginx/conf.d/default.conf @@ -32,14 +41,20 @@ nginx -g "daemon off;" & # Run uvicorn server -uvicorn my_fastagency_app.deployment.main_1_fastapi:app --host 0.0.0.0 --port $FASTAPI_PORT > /dev/stdout 2>&1 & +# Start multiple single-worker uvicorn instances on consecutive ports +for ((i=1; i<$WORKERS+1; i++)) +do + PORT=$((FASTAPI_PORT + i)) + echo "Starting fastapi uvicorn on port $PORT" + uvicorn my_fastagency_app.deployment.main_1_fastapi:app --workers=1 --host 0.0.0.0 --port $PORT > /dev/stdout 2>&1 & +done # Run gunicorn server # Start multiple single-worker gunicorn instances on consecutive ports for ((i=1; i<$WORKERS+1; i++)) do - PORT=$((SERVICE_PORT + i)) + PORT=$((MESOP_PORT + i)) echo "Starting gunicorn on port $PORT" gunicorn --workers=1 my_fastagency_app.deployment.main_2_mesop:app --bind 0.0.0.0:$PORT > /dev/stdout 2>&1 & done diff --git a/docs/docs_src/getting_started/no_auth/fastapi/my_fastagency_app/fly.toml b/docs/docs_src/getting_started/no_auth/fastapi/my_fastagency_app/fly.toml index 742cfd80..d19237b6 100644 --- a/docs/docs_src/getting_started/no_auth/fastapi/my_fastagency_app/fly.toml +++ b/docs/docs_src/getting_started/no_auth/fastapi/my_fastagency_app/fly.toml @@ -21,3 +21,30 @@ primary_region = 'ams' memory = '1gb' cpu_kind = 'shared' cpus = 1 + +[[services]] + http_checks = [] + internal_port = 8008 + processes = ["app"] + protocol = "tcp" + script_checks = [] + + [services.concurrency] + type = "connections" + + [[services.ports]] + handlers = ["tls", "http"] + port = 8008 +[[services]] + http_checks = [] + internal_port = 8888 + processes = ["app"] + protocol = "tcp" + script_checks = [] + + [services.concurrency] + type = "connections" + + [[services.ports]] + handlers = ["tls", "http"] + port = 8888 diff --git a/docs/docs_src/getting_started/no_auth/fastapi/my_fastagency_app/scripts/register_to_fly_io.sh b/docs/docs_src/getting_started/no_auth/fastapi/my_fastagency_app/scripts/register_to_fly_io.sh index a49aac06..bfd9711a 100755 --- a/docs/docs_src/getting_started/no_auth/fastapi/my_fastagency_app/scripts/register_to_fly_io.sh +++ b/docs/docs_src/getting_started/no_auth/fastapi/my_fastagency_app/scripts/register_to_fly_io.sh @@ -17,7 +17,7 @@ else echo -e "\033[0;32mAlready logged into fly.io\033[0m" fi -export FLY_APP_NAME=my-fastagency-app +export FLY_APP_NAME=$(grep "^app = " fly.toml | awk -F"'" '{print $2}') echo -e "\033[0;32mRegistering app name in fly.io\033[0m" if flyctl apps create $FLY_APP_NAME; then @@ -27,6 +27,6 @@ if flyctl apps create $FLY_APP_NAME; then cat registered_app_domain.txt else echo -e "\033[1;31mError: App name is not available.\033[0m" - echo -e "\033[1;31mPlease change the app name in fly.toml and scripts/register_to_fly_io.sh and run this script again.\033[0m" + echo -e "\033[1;31mPlease change the app name in fly.toml and run this script again.\033[0m" exit 1 fi diff --git a/docs/docs_src/getting_started/no_auth/mesop/my_fastagency_app/docker/content/nginx.conf.template b/docs/docs_src/getting_started/no_auth/mesop/my_fastagency_app/docker/content/nginx.conf.template index 52347c6e..626bce1c 100644 --- a/docs/docs_src/getting_started/no_auth/mesop/my_fastagency_app/docker/content/nginx.conf.template +++ b/docs/docs_src/getting_started/no_auth/mesop/my_fastagency_app/docker/content/nginx.conf.template @@ -1,3 +1,17 @@ +upstream nats_fastapi_backend { + # Enable sticky sessions with IP hash + ip_hash; + + +} + +upstream fastapi_backend { + # Enable sticky sessions with IP hash + ip_hash; + + +} + upstream mesop_backend { # Enable sticky sessions with IP hash ip_hash; @@ -18,9 +32,9 @@ map $fly_machine_id $sticky_action { default "replay"; # Cookie exists but doesn't match - need to replay } -# Main server block +# Mesop server block server { - listen $SERVICE_PORT; + listen $MESOP_PORT; server_name localhost; # Security headers diff --git a/docs/docs_src/getting_started/no_auth/mesop/my_fastagency_app/docker/content/run_fastagency.sh b/docs/docs_src/getting_started/no_auth/mesop/my_fastagency_app/docker/content/run_fastagency.sh index 55aa17d3..a6cb4cf0 100755 --- a/docs/docs_src/getting_started/no_auth/mesop/my_fastagency_app/docker/content/run_fastagency.sh +++ b/docs/docs_src/getting_started/no_auth/mesop/my_fastagency_app/docker/content/run_fastagency.sh @@ -1,11 +1,9 @@ #!/bin/bash # Accept env variable for PORT - - - +export NATS_FASTAPI_PORT=${NATS_FASTAPI_PORT:-8000} +export FASTAPI_PORT=${FASTAPI_PORT:-8008} export MESOP_PORT=${MESOP_PORT:-8888} -export SERVICE_PORT=$MESOP_PORT # Default number of workers if not set WORKERS=${WORKERS:-1} @@ -18,10 +16,23 @@ echo "Fly machine ID: $FLY_MACHINE_ID" # Generate nginx config for ((i=1; i<$WORKERS+1; i++)) do - PORT=$((SERVICE_PORT + i)) + PORT=$((MESOP_PORT + i)) + sed -i "19i\ server 127.0.0.1:$PORT;" nginx.conf.template +done + +for ((i=1; i<$WORKERS+1; i++)) +do + PORT=$((FASTAPI_PORT + i)) + sed -i "12i\ server 127.0.0.1:$PORT;" nginx.conf.template +done + +for ((i=1; i<$WORKERS+1; i++)) +do + PORT=$((NATS_FASTAPI_PORT + i)) sed -i "5i\ server 127.0.0.1:$PORT;" nginx.conf.template done -envsubst '${SERVICE_PORT},${FLY_MACHINE_ID}' < nginx.conf.template >/etc/nginx/conf.d/default.conf + +envsubst '${NATS_FASTAPI_PORT},${FASTAPI_PORT},${MESOP_PORT},${FLY_MACHINE_ID}' < nginx.conf.template >/etc/nginx/conf.d/default.conf echo "Nginx config:" cat /etc/nginx/conf.d/default.conf @@ -29,15 +40,12 @@ cat /etc/nginx/conf.d/default.conf nginx -g "daemon off;" & -# Run uvicorn server -uvicorn my_fastagency_app.deployment.main_:app --host 0.0.0.0 --port $FASTAPI_PORT > /dev/stdout 2>&1 & - # Run gunicorn server # Start multiple single-worker gunicorn instances on consecutive ports for ((i=1; i<$WORKERS+1; i++)) do - PORT=$((SERVICE_PORT + i)) + PORT=$((MESOP_PORT + i)) echo "Starting gunicorn on port $PORT" gunicorn --workers=1 my_fastagency_app.deployment.main:app --bind 0.0.0.0:$PORT > /dev/stdout 2>&1 & done diff --git a/docs/docs_src/getting_started/no_auth/mesop/my_fastagency_app/fly.toml b/docs/docs_src/getting_started/no_auth/mesop/my_fastagency_app/fly.toml index 742cfd80..ed002a65 100644 --- a/docs/docs_src/getting_started/no_auth/mesop/my_fastagency_app/fly.toml +++ b/docs/docs_src/getting_started/no_auth/mesop/my_fastagency_app/fly.toml @@ -21,3 +21,17 @@ primary_region = 'ams' memory = '1gb' cpu_kind = 'shared' cpus = 1 + +[[services]] + http_checks = [] + internal_port = 8888 + processes = ["app"] + protocol = "tcp" + script_checks = [] + + [services.concurrency] + type = "connections" + + [[services.ports]] + handlers = ["tls", "http"] + port = 8888 diff --git a/docs/docs_src/getting_started/no_auth/mesop/my_fastagency_app/scripts/register_to_fly_io.sh b/docs/docs_src/getting_started/no_auth/mesop/my_fastagency_app/scripts/register_to_fly_io.sh index a49aac06..bfd9711a 100755 --- a/docs/docs_src/getting_started/no_auth/mesop/my_fastagency_app/scripts/register_to_fly_io.sh +++ b/docs/docs_src/getting_started/no_auth/mesop/my_fastagency_app/scripts/register_to_fly_io.sh @@ -17,7 +17,7 @@ else echo -e "\033[0;32mAlready logged into fly.io\033[0m" fi -export FLY_APP_NAME=my-fastagency-app +export FLY_APP_NAME=$(grep "^app = " fly.toml | awk -F"'" '{print $2}') echo -e "\033[0;32mRegistering app name in fly.io\033[0m" if flyctl apps create $FLY_APP_NAME; then @@ -27,6 +27,6 @@ if flyctl apps create $FLY_APP_NAME; then cat registered_app_domain.txt else echo -e "\033[1;31mError: App name is not available.\033[0m" - echo -e "\033[1;31mPlease change the app name in fly.toml and scripts/register_to_fly_io.sh and run this script again.\033[0m" + echo -e "\033[1;31mPlease change the app name in fly.toml and run this script again.\033[0m" exit 1 fi diff --git a/docs/docs_src/getting_started/no_auth/nats_n_fastapi/my_fastagency_app/docker/content/nginx.conf.template b/docs/docs_src/getting_started/no_auth/nats_n_fastapi/my_fastagency_app/docker/content/nginx.conf.template index 52347c6e..3e295c7b 100644 --- a/docs/docs_src/getting_started/no_auth/nats_n_fastapi/my_fastagency_app/docker/content/nginx.conf.template +++ b/docs/docs_src/getting_started/no_auth/nats_n_fastapi/my_fastagency_app/docker/content/nginx.conf.template @@ -1,3 +1,17 @@ +upstream nats_fastapi_backend { + # Enable sticky sessions with IP hash + ip_hash; + + +} + +upstream fastapi_backend { + # Enable sticky sessions with IP hash + ip_hash; + + +} + upstream mesop_backend { # Enable sticky sessions with IP hash ip_hash; @@ -18,9 +32,85 @@ map $fly_machine_id $sticky_action { default "replay"; # Cookie exists but doesn't match - need to replay } -# Main server block +# Nats fastapi server block +server { + listen $NATS_FASTAPI_PORT; + server_name localhost; + + # Security headers + add_header X-Frame-Options "SAMEORIGIN"; + add_header X-Content-Type-Options "nosniff"; + add_header X-XSS-Protection "1; mode=block"; + + location / { + # Handle cookie setting + if ($sticky_action = "set_cookie") { + add_header Set-Cookie "fly-machine-id=$FLY_MACHINE_ID; Max-Age=518400; Path=/"; + } + + # Handle replay + if ($sticky_action = "replay") { + add_header Fly-Replay "instance=$fly_machine_id"; + return 307; + } + + proxy_pass http://nats_fastapi_backend; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_redirect off; + proxy_buffering off; + + # WSGI support + proxy_set_header X-Forwarded-Host $server_name; + + # WebSocket support + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + } +} +# Fastapi server block +server { + listen $FASTAPI_PORT; + server_name localhost; + + # Security headers + add_header X-Frame-Options "SAMEORIGIN"; + add_header X-Content-Type-Options "nosniff"; + add_header X-XSS-Protection "1; mode=block"; + + location / { + # Handle cookie setting + if ($sticky_action = "set_cookie") { + add_header Set-Cookie "fly-machine-id=$FLY_MACHINE_ID; Max-Age=518400; Path=/"; + } + + # Handle replay + if ($sticky_action = "replay") { + add_header Fly-Replay "instance=$fly_machine_id"; + return 307; + } + + proxy_pass http://fastapi_backend; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_redirect off; + proxy_buffering off; + + # WSGI support + proxy_set_header X-Forwarded-Host $server_name; + + # WebSocket support + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + } +} +# Mesop server block server { - listen $SERVICE_PORT; + listen $MESOP_PORT; server_name localhost; # Security headers diff --git a/docs/docs_src/getting_started/no_auth/nats_n_fastapi/my_fastagency_app/docker/content/run_fastagency.sh b/docs/docs_src/getting_started/no_auth/nats_n_fastapi/my_fastagency_app/docker/content/run_fastagency.sh index 1db12dbb..0ba28573 100755 --- a/docs/docs_src/getting_started/no_auth/nats_n_fastapi/my_fastagency_app/docker/content/run_fastagency.sh +++ b/docs/docs_src/getting_started/no_auth/nats_n_fastapi/my_fastagency_app/docker/content/run_fastagency.sh @@ -1,15 +1,9 @@ #!/bin/bash # Accept env variable for PORT - -NATS_FASTAPI_PORT=${NATS_FASTAPI_PORT:-8000} - - -FASTAPI_PORT=${FASTAPI_PORT:-8008} - - +export NATS_FASTAPI_PORT=${NATS_FASTAPI_PORT:-8000} +export FASTAPI_PORT=${FASTAPI_PORT:-8008} export MESOP_PORT=${MESOP_PORT:-8888} -export SERVICE_PORT=$MESOP_PORT # Default number of workers if not set WORKERS=${WORKERS:-1} @@ -22,10 +16,23 @@ echo "Fly machine ID: $FLY_MACHINE_ID" # Generate nginx config for ((i=1; i<$WORKERS+1; i++)) do - PORT=$((SERVICE_PORT + i)) + PORT=$((MESOP_PORT + i)) + sed -i "19i\ server 127.0.0.1:$PORT;" nginx.conf.template +done + +for ((i=1; i<$WORKERS+1; i++)) +do + PORT=$((FASTAPI_PORT + i)) + sed -i "12i\ server 127.0.0.1:$PORT;" nginx.conf.template +done + +for ((i=1; i<$WORKERS+1; i++)) +do + PORT=$((NATS_FASTAPI_PORT + i)) sed -i "5i\ server 127.0.0.1:$PORT;" nginx.conf.template done -envsubst '${SERVICE_PORT},${FLY_MACHINE_ID}' < nginx.conf.template >/etc/nginx/conf.d/default.conf + +envsubst '${NATS_FASTAPI_PORT},${FASTAPI_PORT},${MESOP_PORT},${FLY_MACHINE_ID}' < nginx.conf.template >/etc/nginx/conf.d/default.conf echo "Nginx config:" cat /etc/nginx/conf.d/default.conf @@ -33,18 +40,30 @@ cat /etc/nginx/conf.d/default.conf nginx -g "daemon off;" & # Run nats uvicorn server -uvicorn my_fastagency_app.deployment.main_1_nats:app --host 0.0.0.0 --port $NATS_FASTAPI_PORT > /dev/stdout 2>&1 & +# Start multiple single-worker uvicorn instances on consecutive ports +for ((i=1; i<$WORKERS+1; i++)) +do + PORT=$((NATS_FASTAPI_PORT + i)) + echo "Starting nats fastapi uvicorn on port $PORT" + uvicorn my_fastagency_app.deployment.main_1_nats:app --workers=1 --host 0.0.0.0 --port $PORT > /dev/stdout 2>&1 & +done # Run uvicorn server -uvicorn my_fastagency_app.deployment.main_2_fastapi:app --host 0.0.0.0 --port $FASTAPI_PORT > /dev/stdout 2>&1 & +# Start multiple single-worker uvicorn instances on consecutive ports +for ((i=1; i<$WORKERS+1; i++)) +do + PORT=$((FASTAPI_PORT + i)) + echo "Starting fastapi uvicorn on port $PORT" + uvicorn my_fastagency_app.deployment.main_2_fastapi:app --workers=1 --host 0.0.0.0 --port $PORT > /dev/stdout 2>&1 & +done # Run gunicorn server # Start multiple single-worker gunicorn instances on consecutive ports for ((i=1; i<$WORKERS+1; i++)) do - PORT=$((SERVICE_PORT + i)) + PORT=$((MESOP_PORT + i)) echo "Starting gunicorn on port $PORT" gunicorn --workers=1 my_fastagency_app.deployment.main_3_mesop:app --bind 0.0.0.0:$PORT > /dev/stdout 2>&1 & done diff --git a/docs/docs_src/getting_started/no_auth/nats_n_fastapi/my_fastagency_app/fly.toml b/docs/docs_src/getting_started/no_auth/nats_n_fastapi/my_fastagency_app/fly.toml index 742cfd80..ef085a35 100644 --- a/docs/docs_src/getting_started/no_auth/nats_n_fastapi/my_fastagency_app/fly.toml +++ b/docs/docs_src/getting_started/no_auth/nats_n_fastapi/my_fastagency_app/fly.toml @@ -21,3 +21,43 @@ primary_region = 'ams' memory = '1gb' cpu_kind = 'shared' cpus = 1 + +[[services]] + http_checks = [] + internal_port = 8000 + processes = ["app"] + protocol = "tcp" + script_checks = [] + + [services.concurrency] + type = "connections" + + [[services.ports]] + handlers = ["tls", "http"] + port = 8000 +[[services]] + http_checks = [] + internal_port = 8008 + processes = ["app"] + protocol = "tcp" + script_checks = [] + + [services.concurrency] + type = "connections" + + [[services.ports]] + handlers = ["tls", "http"] + port = 8008 +[[services]] + http_checks = [] + internal_port = 8888 + processes = ["app"] + protocol = "tcp" + script_checks = [] + + [services.concurrency] + type = "connections" + + [[services.ports]] + handlers = ["tls", "http"] + port = 8888 diff --git a/docs/docs_src/getting_started/no_auth/nats_n_fastapi/my_fastagency_app/scripts/register_to_fly_io.sh b/docs/docs_src/getting_started/no_auth/nats_n_fastapi/my_fastagency_app/scripts/register_to_fly_io.sh index a49aac06..bfd9711a 100755 --- a/docs/docs_src/getting_started/no_auth/nats_n_fastapi/my_fastagency_app/scripts/register_to_fly_io.sh +++ b/docs/docs_src/getting_started/no_auth/nats_n_fastapi/my_fastagency_app/scripts/register_to_fly_io.sh @@ -17,7 +17,7 @@ else echo -e "\033[0;32mAlready logged into fly.io\033[0m" fi -export FLY_APP_NAME=my-fastagency-app +export FLY_APP_NAME=$(grep "^app = " fly.toml | awk -F"'" '{print $2}') echo -e "\033[0;32mRegistering app name in fly.io\033[0m" if flyctl apps create $FLY_APP_NAME; then @@ -27,6 +27,6 @@ if flyctl apps create $FLY_APP_NAME; then cat registered_app_domain.txt else echo -e "\033[1;31mError: App name is not available.\033[0m" - echo -e "\033[1;31mPlease change the app name in fly.toml and scripts/register_to_fly_io.sh and run this script again.\033[0m" + echo -e "\033[1;31mPlease change the app name in fly.toml and run this script again.\033[0m" exit 1 fi From d2afdb9cd931f0dc1bcd9ef5762f39acf00008f4 Mon Sep 17 00:00:00 2001 From: Davor Runje Date: Tue, 26 Nov 2024 07:25:36 +0000 Subject: [PATCH 2/5] wip --- docs/docs/SUMMARY.md | 28 +++++++++---------- .../{autogen => ag2}/AutoGenWorkflows.md | 2 +- .../{autogen => ag2}/IOStreamAdapter.md | 2 +- .../ag2/agents/websurfer/WebSurferAgent.md | 11 ++++++++ .../agents/whatsapp/WhatsAppAgent.md} | 2 +- .../runtimes/ag2/autogen/AutoGenWorkflows.md | 11 ++++++++ .../runtimes/ag2/autogen/CurrentMessage.md | 11 ++++++++ .../autogen/IOStreamAdapter.md} | 2 +- .../{autogen => ag2}/autogen/Toolable.md | 2 +- .../runtimes/ag2/tools/WebSurferTool.md | 11 ++++++++ .../{autogen => ag2}/tools/WhatsAppTool.md | 2 +- .../ag2/tools/websurfer/WebSurferAnswer.md | 11 ++++++++ .../tools/websurfer/WebSurferTool.md} | 2 +- .../tools/whatsapp/WhatsAppTool.md} | 2 +- .../agents/websurfer/WebSurferAgent.md | 11 -------- .../autogen/agents/whatsapp/WhatsAppAgent.md | 11 -------- .../tools/websurfer/WebSurferAnswer.md | 11 -------- .../autogen/tools/websurfer/WebSurferTool.md | 11 -------- .../autogen/tools/whatsapp/WhatsAppTool.md | 11 -------- .../my_fastagency_app/workflow.py | 2 +- .../fastapi/my_fastagency_app/pyproject.toml | 2 +- .../my_fastagency_app/workflow.py | 2 +- .../mesop/my_fastagency_app/pyproject.toml | 2 +- .../my_fastagency_app/workflow.py | 2 +- .../my_fastagency_app/pyproject.toml | 2 +- .../fastapi/main_fastapi_custom_client.py | 2 +- .../my_fastagency_app/workflow.py | 2 +- .../fastapi/my_fastagency_app/pyproject.toml | 2 +- .../my_fastagency_app/workflow.py | 2 +- .../mesop/my_fastagency_app/pyproject.toml | 2 +- .../my_fastagency_app/workflow.py | 2 +- .../my_fastagency_app/pyproject.toml | 2 +- docs/docs_src/tutorials/giphy/main.py | 4 +-- docs/docs_src/tutorials/giphy/simple_main.py | 2 +- docs/docs_src/tutorials/whatsapp/main.py | 4 +-- .../adapters/fastapi/security/workflows.py | 2 +- .../custom_user_interactions/main.py | 2 +- .../user_guide/external_rest_apis/main.py | 2 +- .../user_guide/external_rest_apis/security.py | 2 +- .../user_guide/runtimes/autogen/mesop/main.py | 2 +- .../autogen/mesop/using_non_openai_models.py | 2 +- .../user_guide/runtimes/autogen/websurfer.py | 4 +-- .../runtimes/autogen/websurfer_tool.py | 4 +-- .../user_guide/runtimes/autogen/whatsapp.py | 4 +-- .../runtimes/autogen/whatsapp_tool.py | 4 +-- .../user_guide/ui/mesop/main_mesop.py | 2 +- .../ui/mesop/main_mesop_basic_auth.py | 2 +- .../ui/mesop/main_mesop_firebase_auth.py | 2 +- e2e/llm-sans/main.py | 2 +- e2e/llm/main.py | 2 +- examples/cli/main_console.py | 2 +- examples/cli/main_mesop.py | 2 +- examples/cli/main_user_proxy.py | 2 +- .../runtimes/{autogen => ag2}/__init__.py | 0 .../{autogen => ag2}/agents/__init__.py | 0 .../{autogen => ag2}/agents/websurfer.py | 0 .../{autogen => ag2}/agents/whatsapp.py | 0 .../runtimes/{autogen => ag2}/autogen.py | 0 .../{autogen => ag2}/tools/__init__.py | 0 .../{autogen => ag2}/tools/websurfer.py | 0 .../{autogen => ag2}/tools/whatsapp.py | 2 +- scripts/build-docs.sh | 12 ++++---- .../code_injection.ipynb | 0 .../{autogen/tools => ag2}/__init__.py | 0 .../runtime/{autogen => ag2}/test_autogen.py | 4 +-- tests/runtime/ag2/tools/__init__.py | 0 .../{autogen => ag2}/tools/test_web_surfer.py | 4 +-- .../{autogen => ag2}/tools/test_whatsapp.py | 6 ++-- tests/ui/console/test_base.py | 2 +- tests/ui/mesop/test_base.py | 2 +- 70 files changed, 133 insertions(+), 133 deletions(-) rename docs/docs/en/api/fastagency/runtimes/{autogen => ag2}/AutoGenWorkflows.md (69%) rename docs/docs/en/api/fastagency/runtimes/{autogen => ag2}/IOStreamAdapter.md (69%) create mode 100644 docs/docs/en/api/fastagency/runtimes/ag2/agents/websurfer/WebSurferAgent.md rename docs/docs/en/api/fastagency/runtimes/{autogen/autogen/AutoGenWorkflows.md => ag2/agents/whatsapp/WhatsAppAgent.md} (65%) create mode 100644 docs/docs/en/api/fastagency/runtimes/ag2/autogen/AutoGenWorkflows.md create mode 100644 docs/docs/en/api/fastagency/runtimes/ag2/autogen/CurrentMessage.md rename docs/docs/en/api/fastagency/runtimes/{autogen/tools/WebSurferTool.md => ag2/autogen/IOStreamAdapter.md} (67%) rename docs/docs/en/api/fastagency/runtimes/{autogen => ag2}/autogen/Toolable.md (69%) create mode 100644 docs/docs/en/api/fastagency/runtimes/ag2/tools/WebSurferTool.md rename docs/docs/en/api/fastagency/runtimes/{autogen => ag2}/tools/WhatsAppTool.md (68%) create mode 100644 docs/docs/en/api/fastagency/runtimes/ag2/tools/websurfer/WebSurferAnswer.md rename docs/docs/en/api/fastagency/runtimes/{autogen/autogen/CurrentMessage.md => ag2/tools/websurfer/WebSurferTool.md} (65%) rename docs/docs/en/api/fastagency/runtimes/{autogen/autogen/IOStreamAdapter.md => ag2/tools/whatsapp/WhatsAppTool.md} (66%) delete mode 100644 docs/docs/en/api/fastagency/runtimes/autogen/agents/websurfer/WebSurferAgent.md delete mode 100644 docs/docs/en/api/fastagency/runtimes/autogen/agents/whatsapp/WhatsAppAgent.md delete mode 100644 docs/docs/en/api/fastagency/runtimes/autogen/tools/websurfer/WebSurferAnswer.md delete mode 100644 docs/docs/en/api/fastagency/runtimes/autogen/tools/websurfer/WebSurferTool.md delete mode 100644 docs/docs/en/api/fastagency/runtimes/autogen/tools/whatsapp/WhatsAppTool.md rename fastagency/runtimes/{autogen => ag2}/__init__.py (100%) rename fastagency/runtimes/{autogen => ag2}/agents/__init__.py (100%) rename fastagency/runtimes/{autogen => ag2}/agents/websurfer.py (100%) rename fastagency/runtimes/{autogen => ag2}/agents/whatsapp.py (100%) rename fastagency/runtimes/{autogen => ag2}/autogen.py (100%) rename fastagency/runtimes/{autogen => ag2}/tools/__init__.py (100%) rename fastagency/runtimes/{autogen => ag2}/tools/websurfer.py (100%) rename fastagency/runtimes/{autogen => ag2}/tools/whatsapp.py (96%) rename tests/runtime/autogen/__init__.py => scripts/code_injection.ipynb (100%) rename tests/runtime/{autogen/tools => ag2}/__init__.py (100%) rename tests/runtime/{autogen => ag2}/test_autogen.py (98%) create mode 100644 tests/runtime/ag2/tools/__init__.py rename tests/runtime/{autogen => ag2}/tools/test_web_surfer.py (97%) rename tests/runtime/{autogen => ag2}/tools/test_whatsapp.py (91%) diff --git a/docs/docs/SUMMARY.md b/docs/docs/SUMMARY.md index 16b2c2f3..f27a370f 100644 --- a/docs/docs/SUMMARY.md +++ b/docs/docs/SUMMARY.md @@ -156,27 +156,27 @@ search: - [WorkflowCompleted](api/fastagency/messages/WorkflowCompleted.md) - [WorkflowStarted](api/fastagency/messages/WorkflowStarted.md) - runtimes - - autogen - - [AutoGenWorkflows](api/fastagency/runtimes/autogen/AutoGenWorkflows.md) - - [IOStreamAdapter](api/fastagency/runtimes/autogen/IOStreamAdapter.md) + - ag2 + - [AutoGenWorkflows](api/fastagency/runtimes/ag2/AutoGenWorkflows.md) + - [IOStreamAdapter](api/fastagency/runtimes/ag2/IOStreamAdapter.md) - agents - websurfer - - [WebSurferAgent](api/fastagency/runtimes/autogen/agents/websurfer/WebSurferAgent.md) + - [WebSurferAgent](api/fastagency/runtimes/ag2/agents/websurfer/WebSurferAgent.md) - whatsapp - - [WhatsAppAgent](api/fastagency/runtimes/autogen/agents/whatsapp/WhatsAppAgent.md) + - [WhatsAppAgent](api/fastagency/runtimes/ag2/agents/whatsapp/WhatsAppAgent.md) - autogen - - [AutoGenWorkflows](api/fastagency/runtimes/autogen/autogen/AutoGenWorkflows.md) - - [CurrentMessage](api/fastagency/runtimes/autogen/autogen/CurrentMessage.md) - - [IOStreamAdapter](api/fastagency/runtimes/autogen/autogen/IOStreamAdapter.md) - - [Toolable](api/fastagency/runtimes/autogen/autogen/Toolable.md) + - [AutoGenWorkflows](api/fastagency/runtimes/ag2/autogen/AutoGenWorkflows.md) + - [CurrentMessage](api/fastagency/runtimes/ag2/autogen/CurrentMessage.md) + - [IOStreamAdapter](api/fastagency/runtimes/ag2/autogen/IOStreamAdapter.md) + - [Toolable](api/fastagency/runtimes/ag2/autogen/Toolable.md) - tools - - [WebSurferTool](api/fastagency/runtimes/autogen/tools/WebSurferTool.md) - - [WhatsAppTool](api/fastagency/runtimes/autogen/tools/WhatsAppTool.md) + - [WebSurferTool](api/fastagency/runtimes/ag2/tools/WebSurferTool.md) + - [WhatsAppTool](api/fastagency/runtimes/ag2/tools/WhatsAppTool.md) - websurfer - - [WebSurferAnswer](api/fastagency/runtimes/autogen/tools/websurfer/WebSurferAnswer.md) - - [WebSurferTool](api/fastagency/runtimes/autogen/tools/websurfer/WebSurferTool.md) + - [WebSurferAnswer](api/fastagency/runtimes/ag2/tools/websurfer/WebSurferAnswer.md) + - [WebSurferTool](api/fastagency/runtimes/ag2/tools/websurfer/WebSurferTool.md) - whatsapp - - [WhatsAppTool](api/fastagency/runtimes/autogen/tools/whatsapp/WhatsAppTool.md) + - [WhatsAppTool](api/fastagency/runtimes/ag2/tools/whatsapp/WhatsAppTool.md) - ui - console - [ConsoleUI](api/fastagency/ui/console/ConsoleUI.md) diff --git a/docs/docs/en/api/fastagency/runtimes/autogen/AutoGenWorkflows.md b/docs/docs/en/api/fastagency/runtimes/ag2/AutoGenWorkflows.md similarity index 69% rename from docs/docs/en/api/fastagency/runtimes/autogen/AutoGenWorkflows.md rename to docs/docs/en/api/fastagency/runtimes/ag2/AutoGenWorkflows.md index 01c0b718..27de6086 100644 --- a/docs/docs/en/api/fastagency/runtimes/autogen/AutoGenWorkflows.md +++ b/docs/docs/en/api/fastagency/runtimes/ag2/AutoGenWorkflows.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: fastagency.runtimes.autogen.AutoGenWorkflows +::: fastagency.runtimes.ag2.AutoGenWorkflows diff --git a/docs/docs/en/api/fastagency/runtimes/autogen/IOStreamAdapter.md b/docs/docs/en/api/fastagency/runtimes/ag2/IOStreamAdapter.md similarity index 69% rename from docs/docs/en/api/fastagency/runtimes/autogen/IOStreamAdapter.md rename to docs/docs/en/api/fastagency/runtimes/ag2/IOStreamAdapter.md index a8ee8e0e..62ef663b 100644 --- a/docs/docs/en/api/fastagency/runtimes/autogen/IOStreamAdapter.md +++ b/docs/docs/en/api/fastagency/runtimes/ag2/IOStreamAdapter.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: fastagency.runtimes.autogen.IOStreamAdapter +::: fastagency.runtimes.ag2.IOStreamAdapter diff --git a/docs/docs/en/api/fastagency/runtimes/ag2/agents/websurfer/WebSurferAgent.md b/docs/docs/en/api/fastagency/runtimes/ag2/agents/websurfer/WebSurferAgent.md new file mode 100644 index 00000000..d921a660 --- /dev/null +++ b/docs/docs/en/api/fastagency/runtimes/ag2/agents/websurfer/WebSurferAgent.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: fastagency.runtimes.ag2.agents.websurfer.WebSurferAgent diff --git a/docs/docs/en/api/fastagency/runtimes/autogen/autogen/AutoGenWorkflows.md b/docs/docs/en/api/fastagency/runtimes/ag2/agents/whatsapp/WhatsAppAgent.md similarity index 65% rename from docs/docs/en/api/fastagency/runtimes/autogen/autogen/AutoGenWorkflows.md rename to docs/docs/en/api/fastagency/runtimes/ag2/agents/whatsapp/WhatsAppAgent.md index b1f2179a..91eea8ae 100644 --- a/docs/docs/en/api/fastagency/runtimes/autogen/autogen/AutoGenWorkflows.md +++ b/docs/docs/en/api/fastagency/runtimes/ag2/agents/whatsapp/WhatsAppAgent.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: fastagency.runtimes.autogen.autogen.AutoGenWorkflows +::: fastagency.runtimes.ag2.agents.whatsapp.WhatsAppAgent diff --git a/docs/docs/en/api/fastagency/runtimes/ag2/autogen/AutoGenWorkflows.md b/docs/docs/en/api/fastagency/runtimes/ag2/autogen/AutoGenWorkflows.md new file mode 100644 index 00000000..96d75e09 --- /dev/null +++ b/docs/docs/en/api/fastagency/runtimes/ag2/autogen/AutoGenWorkflows.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: fastagency.runtimes.ag2.autogen.AutoGenWorkflows diff --git a/docs/docs/en/api/fastagency/runtimes/ag2/autogen/CurrentMessage.md b/docs/docs/en/api/fastagency/runtimes/ag2/autogen/CurrentMessage.md new file mode 100644 index 00000000..d36debe3 --- /dev/null +++ b/docs/docs/en/api/fastagency/runtimes/ag2/autogen/CurrentMessage.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: fastagency.runtimes.ag2.autogen.CurrentMessage diff --git a/docs/docs/en/api/fastagency/runtimes/autogen/tools/WebSurferTool.md b/docs/docs/en/api/fastagency/runtimes/ag2/autogen/IOStreamAdapter.md similarity index 67% rename from docs/docs/en/api/fastagency/runtimes/autogen/tools/WebSurferTool.md rename to docs/docs/en/api/fastagency/runtimes/ag2/autogen/IOStreamAdapter.md index b76ae40d..3654fa22 100644 --- a/docs/docs/en/api/fastagency/runtimes/autogen/tools/WebSurferTool.md +++ b/docs/docs/en/api/fastagency/runtimes/ag2/autogen/IOStreamAdapter.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: fastagency.runtimes.autogen.tools.WebSurferTool +::: fastagency.runtimes.ag2.autogen.IOStreamAdapter diff --git a/docs/docs/en/api/fastagency/runtimes/autogen/autogen/Toolable.md b/docs/docs/en/api/fastagency/runtimes/ag2/autogen/Toolable.md similarity index 69% rename from docs/docs/en/api/fastagency/runtimes/autogen/autogen/Toolable.md rename to docs/docs/en/api/fastagency/runtimes/ag2/autogen/Toolable.md index 83204ca5..c8cafbaa 100644 --- a/docs/docs/en/api/fastagency/runtimes/autogen/autogen/Toolable.md +++ b/docs/docs/en/api/fastagency/runtimes/ag2/autogen/Toolable.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: fastagency.runtimes.autogen.autogen.Toolable +::: fastagency.runtimes.ag2.autogen.Toolable diff --git a/docs/docs/en/api/fastagency/runtimes/ag2/tools/WebSurferTool.md b/docs/docs/en/api/fastagency/runtimes/ag2/tools/WebSurferTool.md new file mode 100644 index 00000000..818c56c3 --- /dev/null +++ b/docs/docs/en/api/fastagency/runtimes/ag2/tools/WebSurferTool.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: fastagency.runtimes.ag2.tools.WebSurferTool diff --git a/docs/docs/en/api/fastagency/runtimes/autogen/tools/WhatsAppTool.md b/docs/docs/en/api/fastagency/runtimes/ag2/tools/WhatsAppTool.md similarity index 68% rename from docs/docs/en/api/fastagency/runtimes/autogen/tools/WhatsAppTool.md rename to docs/docs/en/api/fastagency/runtimes/ag2/tools/WhatsAppTool.md index c0e1bae0..44855cb4 100644 --- a/docs/docs/en/api/fastagency/runtimes/autogen/tools/WhatsAppTool.md +++ b/docs/docs/en/api/fastagency/runtimes/ag2/tools/WhatsAppTool.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: fastagency.runtimes.autogen.tools.WhatsAppTool +::: fastagency.runtimes.ag2.tools.WhatsAppTool diff --git a/docs/docs/en/api/fastagency/runtimes/ag2/tools/websurfer/WebSurferAnswer.md b/docs/docs/en/api/fastagency/runtimes/ag2/tools/websurfer/WebSurferAnswer.md new file mode 100644 index 00000000..92280c0f --- /dev/null +++ b/docs/docs/en/api/fastagency/runtimes/ag2/tools/websurfer/WebSurferAnswer.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: fastagency.runtimes.ag2.tools.websurfer.WebSurferAnswer diff --git a/docs/docs/en/api/fastagency/runtimes/autogen/autogen/CurrentMessage.md b/docs/docs/en/api/fastagency/runtimes/ag2/tools/websurfer/WebSurferTool.md similarity index 65% rename from docs/docs/en/api/fastagency/runtimes/autogen/autogen/CurrentMessage.md rename to docs/docs/en/api/fastagency/runtimes/ag2/tools/websurfer/WebSurferTool.md index bd3b8136..f17bfc4a 100644 --- a/docs/docs/en/api/fastagency/runtimes/autogen/autogen/CurrentMessage.md +++ b/docs/docs/en/api/fastagency/runtimes/ag2/tools/websurfer/WebSurferTool.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: fastagency.runtimes.autogen.autogen.CurrentMessage +::: fastagency.runtimes.ag2.tools.websurfer.WebSurferTool diff --git a/docs/docs/en/api/fastagency/runtimes/autogen/autogen/IOStreamAdapter.md b/docs/docs/en/api/fastagency/runtimes/ag2/tools/whatsapp/WhatsAppTool.md similarity index 66% rename from docs/docs/en/api/fastagency/runtimes/autogen/autogen/IOStreamAdapter.md rename to docs/docs/en/api/fastagency/runtimes/ag2/tools/whatsapp/WhatsAppTool.md index 3701640f..8f804725 100644 --- a/docs/docs/en/api/fastagency/runtimes/autogen/autogen/IOStreamAdapter.md +++ b/docs/docs/en/api/fastagency/runtimes/ag2/tools/whatsapp/WhatsAppTool.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: fastagency.runtimes.autogen.autogen.IOStreamAdapter +::: fastagency.runtimes.ag2.tools.whatsapp.WhatsAppTool diff --git a/docs/docs/en/api/fastagency/runtimes/autogen/agents/websurfer/WebSurferAgent.md b/docs/docs/en/api/fastagency/runtimes/autogen/agents/websurfer/WebSurferAgent.md deleted file mode 100644 index 4b6b4a8a..00000000 --- a/docs/docs/en/api/fastagency/runtimes/autogen/agents/websurfer/WebSurferAgent.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: fastagency.runtimes.autogen.agents.websurfer.WebSurferAgent diff --git a/docs/docs/en/api/fastagency/runtimes/autogen/agents/whatsapp/WhatsAppAgent.md b/docs/docs/en/api/fastagency/runtimes/autogen/agents/whatsapp/WhatsAppAgent.md deleted file mode 100644 index 540355d1..00000000 --- a/docs/docs/en/api/fastagency/runtimes/autogen/agents/whatsapp/WhatsAppAgent.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: fastagency.runtimes.autogen.agents.whatsapp.WhatsAppAgent diff --git a/docs/docs/en/api/fastagency/runtimes/autogen/tools/websurfer/WebSurferAnswer.md b/docs/docs/en/api/fastagency/runtimes/autogen/tools/websurfer/WebSurferAnswer.md deleted file mode 100644 index 462c2d67..00000000 --- a/docs/docs/en/api/fastagency/runtimes/autogen/tools/websurfer/WebSurferAnswer.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: fastagency.runtimes.autogen.tools.websurfer.WebSurferAnswer diff --git a/docs/docs/en/api/fastagency/runtimes/autogen/tools/websurfer/WebSurferTool.md b/docs/docs/en/api/fastagency/runtimes/autogen/tools/websurfer/WebSurferTool.md deleted file mode 100644 index 03356260..00000000 --- a/docs/docs/en/api/fastagency/runtimes/autogen/tools/websurfer/WebSurferTool.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: fastagency.runtimes.autogen.tools.websurfer.WebSurferTool diff --git a/docs/docs/en/api/fastagency/runtimes/autogen/tools/whatsapp/WhatsAppTool.md b/docs/docs/en/api/fastagency/runtimes/autogen/tools/whatsapp/WhatsAppTool.md deleted file mode 100644 index 7828928c..00000000 --- a/docs/docs/en/api/fastagency/runtimes/autogen/tools/whatsapp/WhatsAppTool.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: fastagency.runtimes.autogen.tools.whatsapp.WhatsAppTool diff --git a/docs/docs_src/getting_started/basic_auth/fastapi/my_fastagency_app/my_fastagency_app/workflow.py b/docs/docs_src/getting_started/basic_auth/fastapi/my_fastagency_app/my_fastagency_app/workflow.py index bb6a5f34..ece47ddc 100644 --- a/docs/docs_src/getting_started/basic_auth/fastapi/my_fastagency_app/my_fastagency_app/workflow.py +++ b/docs/docs_src/getting_started/basic_auth/fastapi/my_fastagency_app/my_fastagency_app/workflow.py @@ -3,7 +3,7 @@ from autogen.agentchat import ConversableAgent from fastagency import UI -from fastagency.runtimes.autogen import AutoGenWorkflows +from fastagency.runtimes.ag2 import AutoGenWorkflows llm_config = { "config_list": [ diff --git a/docs/docs_src/getting_started/basic_auth/fastapi/my_fastagency_app/pyproject.toml b/docs/docs_src/getting_started/basic_auth/fastapi/my_fastagency_app/pyproject.toml index 62bf8d40..921372f9 100644 --- a/docs/docs_src/getting_started/basic_auth/fastapi/my_fastagency_app/pyproject.toml +++ b/docs/docs_src/getting_started/basic_auth/fastapi/my_fastagency_app/pyproject.toml @@ -8,7 +8,7 @@ version = "0.1.0" name = "my_fastagency_app" dependencies = [ - "fastagency[autogen,mesop,server,fastapi,basic_auth]>=0.3.0", + "fastagency[ag2,mesop,server,fastapi,basic_auth]==0.4.0-dev0", ] [project.optional-dependencies] diff --git a/docs/docs_src/getting_started/basic_auth/mesop/my_fastagency_app/my_fastagency_app/workflow.py b/docs/docs_src/getting_started/basic_auth/mesop/my_fastagency_app/my_fastagency_app/workflow.py index bb6a5f34..ece47ddc 100644 --- a/docs/docs_src/getting_started/basic_auth/mesop/my_fastagency_app/my_fastagency_app/workflow.py +++ b/docs/docs_src/getting_started/basic_auth/mesop/my_fastagency_app/my_fastagency_app/workflow.py @@ -3,7 +3,7 @@ from autogen.agentchat import ConversableAgent from fastagency import UI -from fastagency.runtimes.autogen import AutoGenWorkflows +from fastagency.runtimes.ag2 import AutoGenWorkflows llm_config = { "config_list": [ diff --git a/docs/docs_src/getting_started/basic_auth/mesop/my_fastagency_app/pyproject.toml b/docs/docs_src/getting_started/basic_auth/mesop/my_fastagency_app/pyproject.toml index 670d2cd0..0039a2f3 100644 --- a/docs/docs_src/getting_started/basic_auth/mesop/my_fastagency_app/pyproject.toml +++ b/docs/docs_src/getting_started/basic_auth/mesop/my_fastagency_app/pyproject.toml @@ -8,7 +8,7 @@ version = "0.1.0" name = "my_fastagency_app" dependencies = [ - "fastagency[autogen,mesop,server,basic_auth]>=0.3.0", + "fastagency[ag2,mesop,server,basic_auth]==0.4.0-dev0", ] [project.optional-dependencies] diff --git a/docs/docs_src/getting_started/basic_auth/nats_n_fastapi/my_fastagency_app/my_fastagency_app/workflow.py b/docs/docs_src/getting_started/basic_auth/nats_n_fastapi/my_fastagency_app/my_fastagency_app/workflow.py index bb6a5f34..ece47ddc 100644 --- a/docs/docs_src/getting_started/basic_auth/nats_n_fastapi/my_fastagency_app/my_fastagency_app/workflow.py +++ b/docs/docs_src/getting_started/basic_auth/nats_n_fastapi/my_fastagency_app/my_fastagency_app/workflow.py @@ -3,7 +3,7 @@ from autogen.agentchat import ConversableAgent from fastagency import UI -from fastagency.runtimes.autogen import AutoGenWorkflows +from fastagency.runtimes.ag2 import AutoGenWorkflows llm_config = { "config_list": [ diff --git a/docs/docs_src/getting_started/basic_auth/nats_n_fastapi/my_fastagency_app/pyproject.toml b/docs/docs_src/getting_started/basic_auth/nats_n_fastapi/my_fastagency_app/pyproject.toml index baf3a5fa..15bc65ef 100644 --- a/docs/docs_src/getting_started/basic_auth/nats_n_fastapi/my_fastagency_app/pyproject.toml +++ b/docs/docs_src/getting_started/basic_auth/nats_n_fastapi/my_fastagency_app/pyproject.toml @@ -8,7 +8,7 @@ version = "0.1.0" name = "my_fastagency_app" dependencies = [ - "fastagency[autogen,mesop,server,fastapi,nats,basic_auth]>=0.3.0", + "fastagency[ag2,mesop,server,fastapi,nats,basic_auth]==0.4.0-dev0", ] [project.optional-dependencies] diff --git a/docs/docs_src/getting_started/no_auth/fastapi/main_fastapi_custom_client.py b/docs/docs_src/getting_started/no_auth/fastapi/main_fastapi_custom_client.py index 98147fb2..5be1a06e 100644 --- a/docs/docs_src/getting_started/no_auth/fastapi/main_fastapi_custom_client.py +++ b/docs/docs_src/getting_started/no_auth/fastapi/main_fastapi_custom_client.py @@ -7,7 +7,7 @@ from fastagency import UI from fastagency.adapters.fastapi import FastAPIAdapter -from fastagency.runtimes.autogen import AutoGenWorkflows +from fastagency.runtimes.ag2 import AutoGenWorkflows html = """ diff --git a/docs/docs_src/getting_started/no_auth/fastapi/my_fastagency_app/my_fastagency_app/workflow.py b/docs/docs_src/getting_started/no_auth/fastapi/my_fastagency_app/my_fastagency_app/workflow.py index bb6a5f34..ece47ddc 100644 --- a/docs/docs_src/getting_started/no_auth/fastapi/my_fastagency_app/my_fastagency_app/workflow.py +++ b/docs/docs_src/getting_started/no_auth/fastapi/my_fastagency_app/my_fastagency_app/workflow.py @@ -3,7 +3,7 @@ from autogen.agentchat import ConversableAgent from fastagency import UI -from fastagency.runtimes.autogen import AutoGenWorkflows +from fastagency.runtimes.ag2 import AutoGenWorkflows llm_config = { "config_list": [ diff --git a/docs/docs_src/getting_started/no_auth/fastapi/my_fastagency_app/pyproject.toml b/docs/docs_src/getting_started/no_auth/fastapi/my_fastagency_app/pyproject.toml index f08787cc..76648fc7 100644 --- a/docs/docs_src/getting_started/no_auth/fastapi/my_fastagency_app/pyproject.toml +++ b/docs/docs_src/getting_started/no_auth/fastapi/my_fastagency_app/pyproject.toml @@ -8,7 +8,7 @@ version = "0.1.0" name = "my_fastagency_app" dependencies = [ - "fastagency[autogen,mesop,server,fastapi]>=0.3.0", + "fastagency[ag2,mesop,server,fastapi]==0.4.0-dev0", ] [project.optional-dependencies] diff --git a/docs/docs_src/getting_started/no_auth/mesop/my_fastagency_app/my_fastagency_app/workflow.py b/docs/docs_src/getting_started/no_auth/mesop/my_fastagency_app/my_fastagency_app/workflow.py index bb6a5f34..ece47ddc 100644 --- a/docs/docs_src/getting_started/no_auth/mesop/my_fastagency_app/my_fastagency_app/workflow.py +++ b/docs/docs_src/getting_started/no_auth/mesop/my_fastagency_app/my_fastagency_app/workflow.py @@ -3,7 +3,7 @@ from autogen.agentchat import ConversableAgent from fastagency import UI -from fastagency.runtimes.autogen import AutoGenWorkflows +from fastagency.runtimes.ag2 import AutoGenWorkflows llm_config = { "config_list": [ diff --git a/docs/docs_src/getting_started/no_auth/mesop/my_fastagency_app/pyproject.toml b/docs/docs_src/getting_started/no_auth/mesop/my_fastagency_app/pyproject.toml index b273485d..4f0604e8 100644 --- a/docs/docs_src/getting_started/no_auth/mesop/my_fastagency_app/pyproject.toml +++ b/docs/docs_src/getting_started/no_auth/mesop/my_fastagency_app/pyproject.toml @@ -8,7 +8,7 @@ version = "0.1.0" name = "my_fastagency_app" dependencies = [ - "fastagency[autogen,mesop,server]>=0.3.0", + "fastagency[ag2,mesop,server]==0.4.0-dev0", ] [project.optional-dependencies] diff --git a/docs/docs_src/getting_started/no_auth/nats_n_fastapi/my_fastagency_app/my_fastagency_app/workflow.py b/docs/docs_src/getting_started/no_auth/nats_n_fastapi/my_fastagency_app/my_fastagency_app/workflow.py index bb6a5f34..ece47ddc 100644 --- a/docs/docs_src/getting_started/no_auth/nats_n_fastapi/my_fastagency_app/my_fastagency_app/workflow.py +++ b/docs/docs_src/getting_started/no_auth/nats_n_fastapi/my_fastagency_app/my_fastagency_app/workflow.py @@ -3,7 +3,7 @@ from autogen.agentchat import ConversableAgent from fastagency import UI -from fastagency.runtimes.autogen import AutoGenWorkflows +from fastagency.runtimes.ag2 import AutoGenWorkflows llm_config = { "config_list": [ diff --git a/docs/docs_src/getting_started/no_auth/nats_n_fastapi/my_fastagency_app/pyproject.toml b/docs/docs_src/getting_started/no_auth/nats_n_fastapi/my_fastagency_app/pyproject.toml index 8f8ffc5c..cb7cc802 100644 --- a/docs/docs_src/getting_started/no_auth/nats_n_fastapi/my_fastagency_app/pyproject.toml +++ b/docs/docs_src/getting_started/no_auth/nats_n_fastapi/my_fastagency_app/pyproject.toml @@ -8,7 +8,7 @@ version = "0.1.0" name = "my_fastagency_app" dependencies = [ - "fastagency[autogen,mesop,server,fastapi,nats]>=0.3.0", + "fastagency[ag2,mesop,server,fastapi,nats]==0.4.0-dev0", ] [project.optional-dependencies] diff --git a/docs/docs_src/tutorials/giphy/main.py b/docs/docs_src/tutorials/giphy/main.py index c9a43327..5253c78c 100644 --- a/docs/docs_src/tutorials/giphy/main.py +++ b/docs/docs_src/tutorials/giphy/main.py @@ -7,8 +7,8 @@ from fastagency import UI from fastagency.api.openapi.client import OpenAPI from fastagency.api.openapi.security import APIKeyQuery -from fastagency.runtimes.autogen.agents.websurfer import WebSurferAgent -from fastagency.runtimes.autogen import AutoGenWorkflows +from fastagency.runtimes.ag2.agents.websurfer import WebSurferAgent +from fastagency.runtimes.ag2 import AutoGenWorkflows llm_config = { "config_list": [ diff --git a/docs/docs_src/tutorials/giphy/simple_main.py b/docs/docs_src/tutorials/giphy/simple_main.py index 6acbf07e..d242dc31 100644 --- a/docs/docs_src/tutorials/giphy/simple_main.py +++ b/docs/docs_src/tutorials/giphy/simple_main.py @@ -6,7 +6,7 @@ from fastagency import UI, FastAgency from fastagency.api.openapi.client import OpenAPI from fastagency.api.openapi.security import APIKeyQuery -from fastagency.runtimes.autogen import AutoGenWorkflows +from fastagency.runtimes.ag2 import AutoGenWorkflows from fastagency.ui.mesop import MesopUI open_api_key = os.getenv("OPENAI_API_KEY") diff --git a/docs/docs_src/tutorials/whatsapp/main.py b/docs/docs_src/tutorials/whatsapp/main.py index 53134a91..9c4509a7 100644 --- a/docs/docs_src/tutorials/whatsapp/main.py +++ b/docs/docs_src/tutorials/whatsapp/main.py @@ -7,8 +7,8 @@ from fastagency import UI from fastagency.api.openapi.client import OpenAPI from fastagency.api.openapi.security import APIKeyHeader -from fastagency.runtimes.autogen import AutoGenWorkflows -from fastagency.runtimes.autogen.agents.websurfer import WebSurferAgent +from fastagency.runtimes.ag2 import AutoGenWorkflows +from fastagency.runtimes.ag2.agents.websurfer import WebSurferAgent llm_config = { "config_list": [ diff --git a/docs/docs_src/user_guide/adapters/fastapi/security/workflows.py b/docs/docs_src/user_guide/adapters/fastapi/security/workflows.py index b039d46e..a43e6b46 100644 --- a/docs/docs_src/user_guide/adapters/fastapi/security/workflows.py +++ b/docs/docs_src/user_guide/adapters/fastapi/security/workflows.py @@ -4,7 +4,7 @@ from autogen.agentchat import ConversableAgent from fastagency import UI -from fastagency.runtimes.autogen import AutoGenWorkflows +from fastagency.runtimes.ag2 import AutoGenWorkflows __init__ = ["wf"] diff --git a/docs/docs_src/user_guide/custom_user_interactions/main.py b/docs/docs_src/user_guide/custom_user_interactions/main.py index 7f3b2caf..cf5b659b 100644 --- a/docs/docs_src/user_guide/custom_user_interactions/main.py +++ b/docs/docs_src/user_guide/custom_user_interactions/main.py @@ -6,7 +6,7 @@ from fastagency import UI, FastAgency from fastagency.messages import MultipleChoice, SystemMessage, TextInput -from fastagency.runtimes.autogen import AutoGenWorkflows +from fastagency.runtimes.ag2 import AutoGenWorkflows from fastagency.ui.console import ConsoleUI llm_config = { diff --git a/docs/docs_src/user_guide/external_rest_apis/main.py b/docs/docs_src/user_guide/external_rest_apis/main.py index eb7cb03b..b31ecd7e 100644 --- a/docs/docs_src/user_guide/external_rest_apis/main.py +++ b/docs/docs_src/user_guide/external_rest_apis/main.py @@ -5,7 +5,7 @@ from fastagency import UI, FastAgency from fastagency.api.openapi import OpenAPI -from fastagency.runtimes.autogen import AutoGenWorkflows +from fastagency.runtimes.ag2 import AutoGenWorkflows from fastagency.ui.console import ConsoleUI llm_config = { diff --git a/docs/docs_src/user_guide/external_rest_apis/security.py b/docs/docs_src/user_guide/external_rest_apis/security.py index 304b295f..94c5353f 100644 --- a/docs/docs_src/user_guide/external_rest_apis/security.py +++ b/docs/docs_src/user_guide/external_rest_apis/security.py @@ -6,7 +6,7 @@ from fastagency import UI, FastAgency from fastagency.api.openapi.client import OpenAPI from fastagency.api.openapi.security import APIKeyHeader -from fastagency.runtimes.autogen import AutoGenWorkflows +from fastagency.runtimes.ag2 import AutoGenWorkflows from fastagency.ui.console import ConsoleUI llm_config = { diff --git a/docs/docs_src/user_guide/runtimes/autogen/mesop/main.py b/docs/docs_src/user_guide/runtimes/autogen/mesop/main.py index f32efcf3..88d5ef10 100644 --- a/docs/docs_src/user_guide/runtimes/autogen/mesop/main.py +++ b/docs/docs_src/user_guide/runtimes/autogen/mesop/main.py @@ -6,7 +6,7 @@ from fastagency import UI, FastAgency from fastagency.api.openapi import OpenAPI -from fastagency.runtimes.autogen import AutoGenWorkflows +from fastagency.runtimes.ag2 import AutoGenWorkflows from fastagency.ui.mesop import MesopUI llm_config = { diff --git a/docs/docs_src/user_guide/runtimes/autogen/mesop/using_non_openai_models.py b/docs/docs_src/user_guide/runtimes/autogen/mesop/using_non_openai_models.py index f60f6574..936e2087 100644 --- a/docs/docs_src/user_guide/runtimes/autogen/mesop/using_non_openai_models.py +++ b/docs/docs_src/user_guide/runtimes/autogen/mesop/using_non_openai_models.py @@ -6,7 +6,7 @@ from fastagency import UI, FastAgency from fastagency.api.openapi import OpenAPI -from fastagency.runtimes.autogen import AutoGenWorkflows +from fastagency.runtimes.ag2 import AutoGenWorkflows from fastagency.ui.mesop import MesopUI llm_config = { diff --git a/docs/docs_src/user_guide/runtimes/autogen/websurfer.py b/docs/docs_src/user_guide/runtimes/autogen/websurfer.py index f498fa40..d3f24340 100644 --- a/docs/docs_src/user_guide/runtimes/autogen/websurfer.py +++ b/docs/docs_src/user_guide/runtimes/autogen/websurfer.py @@ -4,8 +4,8 @@ from autogen import UserProxyAgent from fastagency import UI, FastAgency -from fastagency.runtimes.autogen import AutoGenWorkflows -from fastagency.runtimes.autogen.agents.websurfer import WebSurferAgent +from fastagency.runtimes.ag2 import AutoGenWorkflows +from fastagency.runtimes.ag2.agents.websurfer import WebSurferAgent from fastagency.ui.console import ConsoleUI llm_config = { diff --git a/docs/docs_src/user_guide/runtimes/autogen/websurfer_tool.py b/docs/docs_src/user_guide/runtimes/autogen/websurfer_tool.py index 0d325eb7..88b19e43 100644 --- a/docs/docs_src/user_guide/runtimes/autogen/websurfer_tool.py +++ b/docs/docs_src/user_guide/runtimes/autogen/websurfer_tool.py @@ -5,8 +5,8 @@ from autogen.agentchat import ConversableAgent from fastagency import UI, FastAgency -from fastagency.runtimes.autogen import AutoGenWorkflows -from fastagency.runtimes.autogen.tools import WebSurferTool +from fastagency.runtimes.ag2 import AutoGenWorkflows +from fastagency.runtimes.ag2.tools import WebSurferTool from fastagency.ui.console import ConsoleUI llm_config = { diff --git a/docs/docs_src/user_guide/runtimes/autogen/whatsapp.py b/docs/docs_src/user_guide/runtimes/autogen/whatsapp.py index 1ccf6561..a3a154b7 100644 --- a/docs/docs_src/user_guide/runtimes/autogen/whatsapp.py +++ b/docs/docs_src/user_guide/runtimes/autogen/whatsapp.py @@ -4,8 +4,8 @@ from autogen import UserProxyAgent from fastagency import UI, FastAgency -from fastagency.runtimes.autogen import AutoGenWorkflows -from fastagency.runtimes.autogen.agents.whatsapp import WhatsAppAgent +from fastagency.runtimes.ag2 import AutoGenWorkflows +from fastagency.runtimes.ag2.agents.whatsapp import WhatsAppAgent from fastagency.ui.console import ConsoleUI llm_config = { diff --git a/docs/docs_src/user_guide/runtimes/autogen/whatsapp_tool.py b/docs/docs_src/user_guide/runtimes/autogen/whatsapp_tool.py index 20f1b7df..6919ea35 100644 --- a/docs/docs_src/user_guide/runtimes/autogen/whatsapp_tool.py +++ b/docs/docs_src/user_guide/runtimes/autogen/whatsapp_tool.py @@ -5,8 +5,8 @@ from autogen.agentchat import ConversableAgent from fastagency import UI, FastAgency -from fastagency.runtimes.autogen import AutoGenWorkflows -from fastagency.runtimes.autogen.tools import WhatsAppTool +from fastagency.runtimes.ag2 import AutoGenWorkflows +from fastagency.runtimes.ag2.tools import WhatsAppTool from fastagency.ui.console import ConsoleUI llm_config = { diff --git a/docs/docs_src/user_guide/ui/mesop/main_mesop.py b/docs/docs_src/user_guide/ui/mesop/main_mesop.py index d65748d5..38884038 100644 --- a/docs/docs_src/user_guide/ui/mesop/main_mesop.py +++ b/docs/docs_src/user_guide/ui/mesop/main_mesop.py @@ -5,7 +5,7 @@ from autogen.agentchat import ConversableAgent from fastagency import UI, FastAgency -from fastagency.runtimes.autogen import AutoGenWorkflows +from fastagency.runtimes.ag2 import AutoGenWorkflows from fastagency.ui.mesop import MesopUI from fastagency.ui.mesop.styles import ( MesopHomePageStyles, diff --git a/docs/docs_src/user_guide/ui/mesop/main_mesop_basic_auth.py b/docs/docs_src/user_guide/ui/mesop/main_mesop_basic_auth.py index eeb90de5..019c8fb3 100644 --- a/docs/docs_src/user_guide/ui/mesop/main_mesop_basic_auth.py +++ b/docs/docs_src/user_guide/ui/mesop/main_mesop_basic_auth.py @@ -5,7 +5,7 @@ from autogen.agentchat import ConversableAgent from fastagency import UI, FastAgency -from fastagency.runtimes.autogen import AutoGenWorkflows +from fastagency.runtimes.ag2 import AutoGenWorkflows from fastagency.ui.mesop import MesopUI from fastagency.ui.mesop.auth.basic_auth import BasicAuth from fastagency.ui.mesop.styles import ( diff --git a/docs/docs_src/user_guide/ui/mesop/main_mesop_firebase_auth.py b/docs/docs_src/user_guide/ui/mesop/main_mesop_firebase_auth.py index 6ca4527f..67f4fa44 100644 --- a/docs/docs_src/user_guide/ui/mesop/main_mesop_firebase_auth.py +++ b/docs/docs_src/user_guide/ui/mesop/main_mesop_firebase_auth.py @@ -5,7 +5,7 @@ from autogen.agentchat import ConversableAgent from fastagency import UI, FastAgency -from fastagency.runtimes.autogen import AutoGenWorkflows +from fastagency.runtimes.ag2 import AutoGenWorkflows from fastagency.ui.mesop import MesopUI from fastagency.ui.mesop.auth.firebase import FirebaseAuth, FirebaseConfig from fastagency.ui.mesop.styles import ( diff --git a/e2e/llm-sans/main.py b/e2e/llm-sans/main.py index 83cb9985..ef452ac9 100644 --- a/e2e/llm-sans/main.py +++ b/e2e/llm-sans/main.py @@ -5,7 +5,7 @@ from autogen.agentchat import ConversableAgent from fastagency import UI, FastAgency -from fastagency.runtimes.autogen import AutoGenWorkflows +from fastagency.runtimes.ag2 import AutoGenWorkflows from fastagency.ui.mesop import MesopUI wf = AutoGenWorkflows() diff --git a/e2e/llm/main.py b/e2e/llm/main.py index 07a341fc..1364c824 100644 --- a/e2e/llm/main.py +++ b/e2e/llm/main.py @@ -5,7 +5,7 @@ from autogen.agentchat import ConversableAgent from fastagency import UI, FastAgency -from fastagency.runtimes.autogen import AutoGenWorkflows +from fastagency.runtimes.ag2 import AutoGenWorkflows from fastagency.ui.mesop import MesopUI llm_config = { diff --git a/examples/cli/main_console.py b/examples/cli/main_console.py index 7716433a..e217b319 100644 --- a/examples/cli/main_console.py +++ b/examples/cli/main_console.py @@ -4,7 +4,7 @@ from autogen.agentchat import ConversableAgent from fastagency import UI, FastAgency -from fastagency.runtimes.autogen import AutoGenWorkflows +from fastagency.runtimes.ag2 import AutoGenWorkflows from fastagency.ui.console import ConsoleUI llm_config = { diff --git a/examples/cli/main_mesop.py b/examples/cli/main_mesop.py index 9257a573..b8f3bef1 100644 --- a/examples/cli/main_mesop.py +++ b/examples/cli/main_mesop.py @@ -4,7 +4,7 @@ from autogen.agentchat import ConversableAgent from fastagency import UI, FastAgency -from fastagency.runtimes.autogen import AutoGenWorkflows +from fastagency.runtimes.ag2 import AutoGenWorkflows from fastagency.ui.mesop import MesopUI llm_config = { diff --git a/examples/cli/main_user_proxy.py b/examples/cli/main_user_proxy.py index 38a395c5..35839f66 100644 --- a/examples/cli/main_user_proxy.py +++ b/examples/cli/main_user_proxy.py @@ -6,7 +6,7 @@ from fastagency import UI, FastAgency from fastagency.api.openapi.client import OpenAPI from fastagency.api.openapi.security import APIKeyHeader -from fastagency.runtimes.autogen import AutoGenWorkflows +from fastagency.runtimes.ag2 import AutoGenWorkflows from fastagency.ui.console import ConsoleUI llm_config = { diff --git a/fastagency/runtimes/autogen/__init__.py b/fastagency/runtimes/ag2/__init__.py similarity index 100% rename from fastagency/runtimes/autogen/__init__.py rename to fastagency/runtimes/ag2/__init__.py diff --git a/fastagency/runtimes/autogen/agents/__init__.py b/fastagency/runtimes/ag2/agents/__init__.py similarity index 100% rename from fastagency/runtimes/autogen/agents/__init__.py rename to fastagency/runtimes/ag2/agents/__init__.py diff --git a/fastagency/runtimes/autogen/agents/websurfer.py b/fastagency/runtimes/ag2/agents/websurfer.py similarity index 100% rename from fastagency/runtimes/autogen/agents/websurfer.py rename to fastagency/runtimes/ag2/agents/websurfer.py diff --git a/fastagency/runtimes/autogen/agents/whatsapp.py b/fastagency/runtimes/ag2/agents/whatsapp.py similarity index 100% rename from fastagency/runtimes/autogen/agents/whatsapp.py rename to fastagency/runtimes/ag2/agents/whatsapp.py diff --git a/fastagency/runtimes/autogen/autogen.py b/fastagency/runtimes/ag2/autogen.py similarity index 100% rename from fastagency/runtimes/autogen/autogen.py rename to fastagency/runtimes/ag2/autogen.py diff --git a/fastagency/runtimes/autogen/tools/__init__.py b/fastagency/runtimes/ag2/tools/__init__.py similarity index 100% rename from fastagency/runtimes/autogen/tools/__init__.py rename to fastagency/runtimes/ag2/tools/__init__.py diff --git a/fastagency/runtimes/autogen/tools/websurfer.py b/fastagency/runtimes/ag2/tools/websurfer.py similarity index 100% rename from fastagency/runtimes/autogen/tools/websurfer.py rename to fastagency/runtimes/ag2/tools/websurfer.py diff --git a/fastagency/runtimes/autogen/tools/whatsapp.py b/fastagency/runtimes/ag2/tools/whatsapp.py similarity index 96% rename from fastagency/runtimes/autogen/tools/whatsapp.py rename to fastagency/runtimes/ag2/tools/whatsapp.py index 6363e00c..c3bd16cd 100644 --- a/fastagency/runtimes/autogen/tools/whatsapp.py +++ b/fastagency/runtimes/ag2/tools/whatsapp.py @@ -4,7 +4,7 @@ from fastagency.api.openapi.client import OpenAPI from fastagency.api.openapi.security import APIKeyHeader -from fastagency.runtimes.autogen.autogen import Toolable +from fastagency.runtimes.ag2.autogen import Toolable WHATSAPP_OPENAPI_URL = "https://dev.infobip.com/openapi/products/whatsapp.json" WHATSAPP_API_SERVER = "https://api.infobip.com" diff --git a/scripts/build-docs.sh b/scripts/build-docs.sh index 4ee11c0d..f2851574 100755 --- a/scripts/build-docs.sh +++ b/scripts/build-docs.sh @@ -8,22 +8,22 @@ set -x # build docs/docs_src/getting_started cd docs/docs_src/getting_started/no_auth/ && \ rm -rf fastapi/my_fastagency_app/ mesop/my_fastagency_app/ nats_n_fastapi/my_fastagency_app/; \ - cookiecutter -f -o mesop --no-input https://github.com/airtai/cookiecutter-fastagency.git app_type=mesop authentication=none && \ + cookiecutter -f -o mesop --no-input https://github.com/airtai/cookiecutter-fastagency.git --checkout 0.4-dev app_type=mesop authentication=none && \ cd mesop && tree --noreport --dirsfirst my_fastagency_app > folder_structure.txt && cd .. && \ - cookiecutter -f -o fastapi --no-input https://github.com/airtai/cookiecutter-fastagency.git app_type=fastapi+mesop authentication=none && \ + cookiecutter -f -o fastapi --no-input https://github.com/airtai/cookiecutter-fastagency.git --checkout 0.4-dev app_type=fastapi+mesop authentication=none && \ cd fastapi && tree --noreport --dirsfirst my_fastagency_app > folder_structure.txt && cd .. && \ - cookiecutter -f -o nats_n_fastapi --no-input https://github.com/airtai/cookiecutter-fastagency.git app_type=nats+fastapi+mesop authentication=none && \ + cookiecutter -f -o nats_n_fastapi --no-input https://github.com/airtai/cookiecutter-fastagency.git --checkout 0.4-dev app_type=nats+fastapi+mesop authentication=none && \ cd nats_n_fastapi && tree --noreport --dirsfirst my_fastagency_app > folder_structure.txt && cd .. && \ cd ../../../.. cd docs/docs_src/getting_started/basic_auth/ && \ rm -rf fastapi/my_fastagency_app/ mesop/my_fastagency_app/ nats_n_fastapi/my_fastagency_app/; \ - cookiecutter -f -o mesop --no-input https://github.com/airtai/cookiecutter-fastagency.git app_type=mesop authentication=basic && \ + cookiecutter -f -o mesop --no-input https://github.com/airtai/cookiecutter-fastagency.git --checkout 0.4-dev app_type=mesop authentication=basic && \ cd mesop && tree --noreport --dirsfirst my_fastagency_app > folder_structure.txt && cd .. && \ - cookiecutter -f -o fastapi --no-input https://github.com/airtai/cookiecutter-fastagency.git app_type=fastapi+mesop authentication=basic && \ + cookiecutter -f -o fastapi --no-input https://github.com/airtai/cookiecutter-fastagency.git --checkout 0.4-dev app_type=fastapi+mesop authentication=basic && \ cd fastapi && tree --noreport --dirsfirst my_fastagency_app > folder_structure.txt && cd .. && \ - cookiecutter -f -o nats_n_fastapi --no-input https://github.com/airtai/cookiecutter-fastagency.git app_type=nats+fastapi+mesop authentication=basic && \ + cookiecutter -f -o nats_n_fastapi --no-input https://github.com/airtai/cookiecutter-fastagency.git --checkout 0.4-dev app_type=nats+fastapi+mesop authentication=basic && \ cd nats_n_fastapi && tree --noreport --dirsfirst my_fastagency_app > folder_structure.txt && cd .. && \ cd ../../../.. diff --git a/tests/runtime/autogen/__init__.py b/scripts/code_injection.ipynb similarity index 100% rename from tests/runtime/autogen/__init__.py rename to scripts/code_injection.ipynb diff --git a/tests/runtime/autogen/tools/__init__.py b/tests/runtime/ag2/__init__.py similarity index 100% rename from tests/runtime/autogen/tools/__init__.py rename to tests/runtime/ag2/__init__.py diff --git a/tests/runtime/autogen/test_autogen.py b/tests/runtime/ag2/test_autogen.py similarity index 98% rename from tests/runtime/autogen/test_autogen.py rename to tests/runtime/ag2/test_autogen.py index e39d7552..d930b0c5 100644 --- a/tests/runtime/autogen/test_autogen.py +++ b/tests/runtime/ag2/test_autogen.py @@ -9,8 +9,8 @@ from fastagency.api.openapi import OpenAPI from fastagency.base import UI -from fastagency.runtimes.autogen import AutoGenWorkflows -from fastagency.runtimes.autogen.autogen import _findall, _match +from fastagency.runtimes.ag2 import AutoGenWorkflows +from fastagency.runtimes.ag2.autogen import _findall, _match from fastagency.ui.console import ConsoleUI from tests.conftest import InputMock diff --git a/tests/runtime/ag2/tools/__init__.py b/tests/runtime/ag2/tools/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/runtime/autogen/tools/test_web_surfer.py b/tests/runtime/ag2/tools/test_web_surfer.py similarity index 97% rename from tests/runtime/autogen/tools/test_web_surfer.py rename to tests/runtime/ag2/tools/test_web_surfer.py index 4a36fb53..19f84db0 100644 --- a/tests/runtime/autogen/tools/test_web_surfer.py +++ b/tests/runtime/ag2/tools/test_web_surfer.py @@ -3,8 +3,8 @@ import pytest from autogen import ConversableAgent, UserProxyAgent -from fastagency.runtimes.autogen.autogen import Toolable -from fastagency.runtimes.autogen.tools import WebSurferTool +from fastagency.runtimes.ag2.autogen import Toolable +from fastagency.runtimes.ag2.tools import WebSurferTool class TestWebSurferTool: diff --git a/tests/runtime/autogen/tools/test_whatsapp.py b/tests/runtime/ag2/tools/test_whatsapp.py similarity index 91% rename from tests/runtime/autogen/tools/test_whatsapp.py rename to tests/runtime/ag2/tools/test_whatsapp.py index 3b3922cc..85aca198 100644 --- a/tests/runtime/autogen/tools/test_whatsapp.py +++ b/tests/runtime/ag2/tools/test_whatsapp.py @@ -3,9 +3,9 @@ import pytest from autogen import ConversableAgent, UserProxyAgent -from fastagency.runtimes.autogen.agents.whatsapp import WhatsAppAgent -from fastagency.runtimes.autogen.autogen import Toolable -from fastagency.runtimes.autogen.tools import WhatsAppTool +from fastagency.runtimes.ag2.agents.whatsapp import WhatsAppAgent +from fastagency.runtimes.ag2.autogen import Toolable +from fastagency.runtimes.ag2.tools import WhatsAppTool class TestWhatsApp: diff --git a/tests/ui/console/test_base.py b/tests/ui/console/test_base.py index d24970ce..8988bb92 100644 --- a/tests/ui/console/test_base.py +++ b/tests/ui/console/test_base.py @@ -5,7 +5,7 @@ from fastagency.app import FastAgency from fastagency.base import UI -from fastagency.runtimes.autogen import AutoGenWorkflows +from fastagency.runtimes.ag2 import AutoGenWorkflows from fastagency.ui.console import ConsoleUI diff --git a/tests/ui/mesop/test_base.py b/tests/ui/mesop/test_base.py index baaf4734..637889a4 100644 --- a/tests/ui/mesop/test_base.py +++ b/tests/ui/mesop/test_base.py @@ -5,7 +5,7 @@ from fastagency.app import FastAgency from fastagency.messages import TextMessage -from fastagency.runtimes.autogen import AutoGenWorkflows +from fastagency.runtimes.ag2 import AutoGenWorkflows if sys.version_info >= (3, 10): from fastagency.ui.mesop.mesop import MesopUI From fcc375f36fa5af4344c227c6086cb73874db2abd Mon Sep 17 00:00:00 2001 From: rjambrecic <32619626+rjambrecic@users.noreply.github.com> Date: Wed, 27 Nov 2024 12:03:53 +0100 Subject: [PATCH 3/5] Filter one pytest warning (#607) --- pyproject.toml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index 32634487..a84f9fba 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -277,6 +277,9 @@ markers = [ "flaky: mark test as flaky", ] +# Add filterwarnings to suppress the specific UserWarning +filterwarnings = "ignore:.*custom validator is returning a value other than `self`.*:UserWarning" + [tool.coverage.run] parallel = true branch = true From e0ce500724de4e3cbbdb6b416cbc3a590d8a90c2 Mon Sep 17 00:00:00 2001 From: rjambrecic <32619626+rjambrecic@users.noreply.github.com> Date: Fri, 29 Nov 2024 11:29:52 +0100 Subject: [PATCH 4/5] Add dependancy injection (#609) * refactoring * wip * Fix typing and update test * Initial example wit code injection implemented * Skip docs_src.user_guide.code_injection in test_import * Rename the main.py to mesop_main.py * wip: code injection docs * wip: code injection docs * Update code injectionn user guide * Update code injectionn user guide * Update code injection docs * Update tests * Update tests * Update code injection docs to use cookiecutter * Update tests * Update code injection docs * Rename Code Injection to Dependency Injection * Generate cookiecutter my_bank_app in build_docs * Update docs * Update docs --------- Co-authored-by: Davor Runje --- docs/docs/SUMMARY.md | 9 +- .../api/dependency_injection/inject_params.md | 11 ++ .../openapi/{client => openapi}/OpenAPI.md | 2 +- .../{client => openapi}/add_to_globals.md | 2 +- .../dependency_injection/images/result.png | 3 + .../images/user_input.png | 3 + .../api/dependency_injection/index.md | 141 ++++++++++++++++++ docs/docs/en/user-guide/api/index.md | 10 +- docs/docs/navigation_template.txt | 1 + docs/docs_src/tutorials/giphy/main.py | 2 +- docs/docs_src/tutorials/giphy/simple_main.py | 2 +- docs/docs_src/tutorials/whatsapp/main.py | 2 +- .../dependency_injection/__init__.py | 0 .../mesop/folder_structure.txt | 35 +++++ .../my_bank_app/.codespell-whitelist.txt | 0 .../.devcontainer/devcontainer.env | 7 + .../.devcontainer/devcontainer.json | 66 ++++++++ .../.devcontainer/docker-compose.yml | 21 +++ .../mesop/my_bank_app/.devcontainer/setup.sh | 20 +++ .../mesop/my_bank_app/.dockerignore | 0 .../mesop/my_bank_app/.github/dependabot.yml | 17 +++ .../.github/workflows/deploy_to_fly_io.yml | 22 +++ .../my_bank_app/.github/workflows/test.yml | 49 ++++++ .../mesop/my_bank_app/.gitignore | 18 +++ .../mesop/my_bank_app/.pre-commit-config.yaml | 47 ++++++ .../mesop/my_bank_app/.secrets.baseline | 127 ++++++++++++++++ .../mesop/my_bank_app/README.md | 91 +++++++++++ .../mesop/my_bank_app/docker/Dockerfile | 41 +++++ .../docker/content/nginx.conf.template | 72 +++++++++ .../docker/content/run_fastagency.sh | 54 +++++++ .../mesop/my_bank_app/fly.toml | 37 +++++ .../mesop/my_bank_app/my_bank_app/__init__.py | 0 .../my_bank_app/deployment/__init__.py | 0 .../my_bank_app/deployment/main.py | 16 ++ .../my_bank_app/my_bank_app/local/__init__.py | 0 .../my_bank_app/local/main_console.py | 10 ++ .../my_bank_app/local/main_mesop.py | 13 ++ .../mesop/my_bank_app/my_bank_app/workflow.py | 84 +++++++++++ .../mesop/my_bank_app/pyproject.toml | 130 ++++++++++++++++ .../mesop/my_bank_app/scripts/build_docker.sh | 5 + .../check-registered-app-pre-commit.sh | 13 ++ .../scripts/check-registered-app.sh | 8 + .../my_bank_app/scripts/deploy_to_fly_io.sh | 23 +++ .../my_bank_app/scripts/lint-pre-commit.sh | 21 +++ .../mesop/my_bank_app/scripts/lint.sh | 13 ++ .../my_bank_app/scripts/register_to_fly_io.sh | 32 ++++ .../mesop/my_bank_app/scripts/run_docker.sh | 3 + .../my_bank_app/scripts/run_mesop_locally.sh | 1 + .../my_bank_app/scripts/static-analysis.sh | 11 ++ .../my_bank_app/scripts/static-pre-commit.sh | 21 +++ .../mesop/my_bank_app/tests/__init__.py | 0 .../mesop/my_bank_app/tests/conftest.py | 13 ++ .../mesop/my_bank_app/tests/test_workflow.py | 18 +++ .../dependency_injection/workflow.py | 84 +++++++++++ .../user_guide/external_rest_apis/security.py | 2 +- examples/cli/main_user_proxy.py | 2 +- fastagency/api/dependency_injection.py | 25 ++++ fastagency/api/openapi/__init__.py | 2 +- .../api/openapi/{client.py => openapi.py} | 71 ++++++--- fastagency/runtimes/autogen/tools/whatsapp.py | 2 +- scripts/build-docs.sh | 8 + tests/api/openapi/security/test_security.py | 2 +- .../security/test_unsupported_security.py | 2 +- .../test_fastapi_codegen_template.py | 2 +- tests/api/openapi/test_client.py | 34 ++--- tests/api/openapi/test_end2end.py | 30 +++- tests/api/openapi/test_endpoint_with_body.py | 2 +- .../test_uppercase_endpoint_parameters.py | 4 +- tests/api/openapi/test_whatsapp_api.py | 4 +- tests/api/test_code_injection.py | 19 +++ tests/docs_src/test_import.py | 1 + tests/runtime/autogen/test_autogen.py | 2 +- 72 files changed, 1581 insertions(+), 64 deletions(-) create mode 100644 docs/docs/en/api/fastagency/api/dependency_injection/inject_params.md rename docs/docs/en/api/fastagency/api/openapi/{client => openapi}/OpenAPI.md (71%) rename docs/docs/en/api/fastagency/api/openapi/{client => openapi}/add_to_globals.md (68%) create mode 100644 docs/docs/en/user-guide/api/dependency_injection/images/result.png create mode 100644 docs/docs/en/user-guide/api/dependency_injection/images/user_input.png create mode 100644 docs/docs/en/user-guide/api/dependency_injection/index.md create mode 100644 docs/docs_src/user_guide/dependency_injection/__init__.py create mode 100644 docs/docs_src/user_guide/dependency_injection/mesop/folder_structure.txt create mode 100644 docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/.codespell-whitelist.txt create mode 100644 docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/.devcontainer/devcontainer.env create mode 100644 docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/.devcontainer/devcontainer.json create mode 100644 docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/.devcontainer/docker-compose.yml create mode 100644 docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/.devcontainer/setup.sh create mode 100644 docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/.dockerignore create mode 100644 docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/.github/dependabot.yml create mode 100644 docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/.github/workflows/deploy_to_fly_io.yml create mode 100644 docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/.github/workflows/test.yml create mode 100644 docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/.gitignore create mode 100644 docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/.pre-commit-config.yaml create mode 100644 docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/.secrets.baseline create mode 100644 docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/README.md create mode 100644 docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/docker/Dockerfile create mode 100644 docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/docker/content/nginx.conf.template create mode 100755 docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/docker/content/run_fastagency.sh create mode 100644 docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/fly.toml create mode 100644 docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/my_bank_app/__init__.py create mode 100644 docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/my_bank_app/deployment/__init__.py create mode 100644 docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/my_bank_app/deployment/main.py create mode 100644 docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/my_bank_app/local/__init__.py create mode 100644 docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/my_bank_app/local/main_console.py create mode 100644 docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/my_bank_app/local/main_mesop.py create mode 100644 docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/my_bank_app/workflow.py create mode 100644 docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/pyproject.toml create mode 100755 docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/scripts/build_docker.sh create mode 100755 docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/scripts/check-registered-app-pre-commit.sh create mode 100755 docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/scripts/check-registered-app.sh create mode 100755 docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/scripts/deploy_to_fly_io.sh create mode 100755 docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/scripts/lint-pre-commit.sh create mode 100755 docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/scripts/lint.sh create mode 100755 docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/scripts/register_to_fly_io.sh create mode 100755 docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/scripts/run_docker.sh create mode 100755 docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/scripts/run_mesop_locally.sh create mode 100755 docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/scripts/static-analysis.sh create mode 100755 docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/scripts/static-pre-commit.sh create mode 100644 docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/tests/__init__.py create mode 100644 docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/tests/conftest.py create mode 100644 docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/tests/test_workflow.py create mode 100644 docs/docs_src/user_guide/dependency_injection/workflow.py create mode 100644 fastagency/api/dependency_injection.py rename fastagency/api/openapi/{client.py => openapi.py} (88%) create mode 100644 tests/api/test_code_injection.py diff --git a/docs/docs/SUMMARY.md b/docs/docs/SUMMARY.md index 16b2c2f3..4f1ea61a 100644 --- a/docs/docs/SUMMARY.md +++ b/docs/docs/SUMMARY.md @@ -23,6 +23,7 @@ search: - [FastAPI + Nats.io](user-guide/adapters/fastapi_nats/index.md) - [FastAPI Security](user-guide/adapters/fastapi/security.md) - [API-s](user-guide/api/index.md) + - [Dependency Injection](user-guide/api/dependency_injection/index.md) - [OpenAPI](user-guide/api/openapi/index.md) - [Security](user-guide/api/security.md) - [Testing](user-guide/testing/index.md) @@ -59,14 +60,16 @@ search: - [NatsAdapter](api/fastagency/adapters/nats/base/NatsAdapter.md) - [NatsProvider](api/fastagency/adapters/nats/base/NatsProvider.md) - api + - dependency_injection + - [inject_params](api/fastagency/api/dependency_injection/inject_params.md) - openapi - [OpenAPI](api/fastagency/api/openapi/OpenAPI.md) - - client - - [OpenAPI](api/fastagency/api/openapi/client/OpenAPI.md) - - [add_to_globals](api/fastagency/api/openapi/client/add_to_globals.md) - fastapi_code_generator_helpers - [ArgumentWithDescription](api/fastagency/api/openapi/fastapi_code_generator_helpers/ArgumentWithDescription.md) - [patch_get_parameter_type](api/fastagency/api/openapi/fastapi_code_generator_helpers/patch_get_parameter_type.md) + - openapi + - [OpenAPI](api/fastagency/api/openapi/openapi/OpenAPI.md) + - [add_to_globals](api/fastagency/api/openapi/openapi/add_to_globals.md) - patch_datamodel_code_generator - [patch_apply_discriminator_type](api/fastagency/api/openapi/patch_datamodel_code_generator/patch_apply_discriminator_type.md) - patch_fastapi_code_generator diff --git a/docs/docs/en/api/fastagency/api/dependency_injection/inject_params.md b/docs/docs/en/api/fastagency/api/dependency_injection/inject_params.md new file mode 100644 index 00000000..38df7a0a --- /dev/null +++ b/docs/docs/en/api/fastagency/api/dependency_injection/inject_params.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: fastagency.api.dependency_injection.inject_params diff --git a/docs/docs/en/api/fastagency/api/openapi/client/OpenAPI.md b/docs/docs/en/api/fastagency/api/openapi/openapi/OpenAPI.md similarity index 71% rename from docs/docs/en/api/fastagency/api/openapi/client/OpenAPI.md rename to docs/docs/en/api/fastagency/api/openapi/openapi/OpenAPI.md index 95cad190..da0b6f25 100644 --- a/docs/docs/en/api/fastagency/api/openapi/client/OpenAPI.md +++ b/docs/docs/en/api/fastagency/api/openapi/openapi/OpenAPI.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: fastagency.api.openapi.client.OpenAPI +::: fastagency.api.openapi.openapi.OpenAPI diff --git a/docs/docs/en/api/fastagency/api/openapi/client/add_to_globals.md b/docs/docs/en/api/fastagency/api/openapi/openapi/add_to_globals.md similarity index 68% rename from docs/docs/en/api/fastagency/api/openapi/client/add_to_globals.md rename to docs/docs/en/api/fastagency/api/openapi/openapi/add_to_globals.md index b9f103a6..c22ed853 100644 --- a/docs/docs/en/api/fastagency/api/openapi/client/add_to_globals.md +++ b/docs/docs/en/api/fastagency/api/openapi/openapi/add_to_globals.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: fastagency.api.openapi.client.add_to_globals +::: fastagency.api.openapi.openapi.add_to_globals diff --git a/docs/docs/en/user-guide/api/dependency_injection/images/result.png b/docs/docs/en/user-guide/api/dependency_injection/images/result.png new file mode 100644 index 00000000..6454bfc5 --- /dev/null +++ b/docs/docs/en/user-guide/api/dependency_injection/images/result.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e50fbd69cfb2b9750d6fb8f24afc439ce5f401156d07e0accdfaad014df14efc +size 265705 diff --git a/docs/docs/en/user-guide/api/dependency_injection/images/user_input.png b/docs/docs/en/user-guide/api/dependency_injection/images/user_input.png new file mode 100644 index 00000000..eed5e619 --- /dev/null +++ b/docs/docs/en/user-guide/api/dependency_injection/images/user_input.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:553d271513abd98e07c8384f31751fc7e37daa71f472db29a9153343e06ded31 +size 225443 diff --git a/docs/docs/en/user-guide/api/dependency_injection/index.md b/docs/docs/en/user-guide/api/dependency_injection/index.md new file mode 100644 index 00000000..abd56de6 --- /dev/null +++ b/docs/docs/en/user-guide/api/dependency_injection/index.md @@ -0,0 +1,141 @@ +# Dependency Injection + +[Dependency Injection](https://en.wikipedia.org/wiki/Dependency_injection){target="_blank"} is a secure way to connect external functions to agents in `AutoGen` without exposing sensitive data such as passwords, tokens, or personal information. This approach ensures that sensitive information remains protected while still allowing agents to perform their tasks effectively, even when working with large language models (LLMs). + +In this guide, we’ll explore how to use `FastAgency` to build secure workflows that handle sensitive data safely. + +As an example, we’ll create a banking agent that retrieves a user's account balance. The best part is that sensitive data like username and password are never shared with the language model. Instead, it’s securely injected directly into the function at runtime, keeping it safe while maintaining seamless functionality. + +Let’s get started! + + +## Why Use Dependency Injection? + +When working with large language models (LLMs), **security is paramount**. There are several types of sensitive information that we want to keep out of the LLM’s reach: + +- **Passwords or tokens**: These could be exposed through [prompt injection attacks](https://en.wikipedia.org/wiki/Prompt_injection){target="_blank"}. +- **Personal information**: Access to this data might fall under strict regulations, such as the [EU AI Act](https://www.europarl.europa.eu/topics/en/article/20230601STO93804/eu-ai-act-first-regulation-on-artificial-intelligence){target="_blank"}. + +Dependency injection offers a robust solution by isolating sensitive data while enabling your agents to function effectively. + +## Why Dependency Injection Is Essential + +Here’s why dependency injection is a game-changer for secure LLM workflows: + +- **Enhanced Security**: Your sensitive data is never directly exposed to the LLM. +- **Simplified Development**: Secure data can be seamlessly accessed by functions without requiring complex configurations. +- **Unmatched Flexibility**: It supports safe integration of diverse workflows, allowing you to scale and adapt with ease. + +In this guide, we’ll explore how to set up dependency injection, build secure workflows, and create a protected application step-by-step. Let’s dive in! + +--- + +## Install + +We will use [**Cookiecutter**](../../../user-guide/cookiecutter/index.md) for setting up the project. Cookiecutter creates the project folder structure, default workflow, automatically installs all the necessary requirements, and creates a [devcontainer](https://code.visualstudio.com/docs/devcontainers/containers){target="_blank"} that can be used with [Visual Studio Code](https://code.visualstudio.com/){target="_blank"}. + +You can setup the project using Cookiecutter by following the [**project setup guide**](../../../user-guide/cookiecutter/index.md). + +In this example, we’ll create a **Mesop** application **without authentication**. The generated project will have the following files: + +```console +{! docs_src/user_guide/dependency_injection/mesop/folder_structure.txt !} +``` + +## Complete Workflow Code +The only file you need to modify to run the application is `my_bank_app/my_bank_app/workflow.py`. Simply copy and paste the following content into the file: + +
+workflow.py +```python +{! docs_src/user_guide/dependency_injection/workflow.py !} +``` +
+ +## Step-by-Step Guide + +### Imports +These imports are similar to the imports section we have already covered, with the only difference being the additional imports of the [**`inject_params`**](../../../api/fastagency/api/dependency_injection/inject_params.md) function: + +```python hl_lines="7" +{! docs_src/user_guide/dependency_injection/workflow.py [ln:1-8] !} +``` + +### Define the Bank Savings Function + +The `get_balance` function is central to this workflow. It retrieves the user's balance based on the provided **username** and **password**. + +The key consideration here is that both username and password should **NEVER** be exposed to the LLM. Instead, they will be securely injected into the `get_balance` function later in the workflow using the [**`inject_params`**](../../../api/fastagency/api/dependency_injection/inject_params.md) mechanism, ensuring that sensitive information remains confidential while still allowing the function to access the required data. + +```python +{! docs_src/user_guide/dependency_injection/workflow.py [ln:10-23] !} +``` + + +### Configure the Language Model (LLM) +Here, the large language model is configured to use the `gpt-4o-mini` model, and the API key is retrieved from the environment. This setup ensures that both the user and weather agents can interact effectively. + +```python +{! docs_src/user_guide/dependency_injection/workflow.py [ln:26-34] !} +``` + +### Define the Workflow and Agents + +The `bank_workflow` handles user interaction and integrates agents to retrieve balance securely. + + +1. **User Input Collection**: + - At the beginning of the workflow, the user is prompted to provide: + - **Username**: The workflow asks, *"Enter your username:"*. + - **Password**: The workflow then asks, *"Enter your password:"*. + +2. **Agent Setup**: + - Two agents are created to handle the workflow: + - **UserProxyAgent**: Simulates the user's perspective, facilitating secure communication. + - **ConversableAgent**: Acts as the banker agent, retrieving the user's balance. + +```python +{! docs_src/user_guide/dependency_injection/workflow.py [ln:36-63] !} +``` + +### Dependency Injection +Username and password provided by the user are stored securely in a **context dictionary (`ctx`)**. +These parameters are **never shared with the LLM** and they are only used internally within the workflow. + +Using [**`inject_params`**](../../../api/fastagency/api/dependency_injection/inject_params.md), the sensitive parameters from the `ctx` dictionary are injected into the `get_balance` function. + +```python +{! docs_src/user_guide/dependency_injection/workflow.py [ln:65-69] !} +``` + +### Register Function with the Agents +In this step, we register the `get_balance_with_params` +```python +{! docs_src/user_guide/dependency_injection/workflow.py [ln:70-75] !} +``` + +### Enable Agent Interaction and Chat +Here, the user agent initiates a chat with the banker agent, which retrieves the user's balance. The conversation is summarized using a method provided by the LLM. + +```python +{! docs_src/user_guide/dependency_injection/workflow.py [ln:77-84] !} +``` + +## Run Application + +You can run this chapter's FastAgency application using the following command: + +```console +gunicorn my_bank_app.deployment.main:app +``` + +## Output +At the beginning, the user is asked to provide the **username** and **password**. + +![User Input](./images/user_input.png) + +Once the user provide them, the agent executes the `get_balance` function with both parameters securely injected into the function using the [**`inject_params`**](../../../api/fastagency/api/dependency_injection/inject_params.md) mechanism, ensuring these parameters are not exposed to the LLM. + +The agent processes the request, retrieves the user's balance, and provides a summary of the results without compromising sensitive data. + +![Result](./images/result.png) diff --git a/docs/docs/en/user-guide/api/index.md b/docs/docs/en/user-guide/api/index.md index 98855afc..c5e00edb 100644 --- a/docs/docs/en/user-guide/api/index.md +++ b/docs/docs/en/user-guide/api/index.md @@ -6,12 +6,18 @@ Currently, FastAgency supports importing API functionality from [**OpenAPI**](ht ## API Features in FastAgency -### 1. **[OpenAPI Import](./openapi/index.md)** +### 1. **[Dependency Injection](./dependency_injection/index.md)** +FastAgency offers a secure way to manage sensitive data using dependency injection. With the [**`inject_params`**](../../api/fastagency/api/dependency_injection/inject_params.md) function, sensitive information, such as tokens, is injected directly into functions without being exposed to the LLM. This ensures that sensitive data remains private while allowing agents to perform the required tasks. The process helps maintain data security and confidentiality while still enabling the proper execution of functions within the workflow. + +[Learn more about Dependency Injection →](./dependency_injection/index.md) + + +### 2. **[OpenAPI Import](./openapi/index.md)** FastAgency can automatically generate API functions from OpenAPI specifications, streamlining the process of connecting agents to external services. With just a few lines of code, you can import an API specification, and FastAgency will handle the function generation and LLM integration, making it simple for agents to call external APIs. [Learn more about OpenAPI Import →](./openapi/index.md) -### 2. **[API Security](./security.md)** +### 3. **[API Security](./security.md)** FastAgency supports different types of security for REST APIs, including OAuth, API keys, and more. This ensures that your API integrations are secure and can handle sensitive data. Our API security mechanisms are flexible, allowing you to configure and manage secure communication between your agents and external APIs. [Learn more about API Security →](./security.md) diff --git a/docs/docs/navigation_template.txt b/docs/docs/navigation_template.txt index 52ed10b3..1c94fe19 100644 --- a/docs/docs/navigation_template.txt +++ b/docs/docs/navigation_template.txt @@ -23,6 +23,7 @@ search: - [FastAPI + Nats.io](user-guide/adapters/fastapi_nats/index.md) - [FastAPI Security](user-guide/adapters/fastapi/security.md) - [API-s](user-guide/api/index.md) + - [Dependency Injection](user-guide/api/dependency_injection/index.md) - [OpenAPI](user-guide/api/openapi/index.md) - [Security](user-guide/api/security.md) - [Testing](user-guide/testing/index.md) diff --git a/docs/docs_src/tutorials/giphy/main.py b/docs/docs_src/tutorials/giphy/main.py index c9a43327..09f69a0a 100644 --- a/docs/docs_src/tutorials/giphy/main.py +++ b/docs/docs_src/tutorials/giphy/main.py @@ -5,7 +5,7 @@ from autogen.agentchat import ConversableAgent from fastagency import UI -from fastagency.api.openapi.client import OpenAPI +from fastagency.api.openapi import OpenAPI from fastagency.api.openapi.security import APIKeyQuery from fastagency.runtimes.autogen.agents.websurfer import WebSurferAgent from fastagency.runtimes.autogen import AutoGenWorkflows diff --git a/docs/docs_src/tutorials/giphy/simple_main.py b/docs/docs_src/tutorials/giphy/simple_main.py index 6acbf07e..c10d1430 100644 --- a/docs/docs_src/tutorials/giphy/simple_main.py +++ b/docs/docs_src/tutorials/giphy/simple_main.py @@ -4,7 +4,7 @@ from autogen import ConversableAgent, UserProxyAgent from fastagency import UI, FastAgency -from fastagency.api.openapi.client import OpenAPI +from fastagency.api.openapi import OpenAPI from fastagency.api.openapi.security import APIKeyQuery from fastagency.runtimes.autogen import AutoGenWorkflows from fastagency.ui.mesop import MesopUI diff --git a/docs/docs_src/tutorials/whatsapp/main.py b/docs/docs_src/tutorials/whatsapp/main.py index 53134a91..a89869ab 100644 --- a/docs/docs_src/tutorials/whatsapp/main.py +++ b/docs/docs_src/tutorials/whatsapp/main.py @@ -5,7 +5,7 @@ from autogen.agentchat import ConversableAgent from fastagency import UI -from fastagency.api.openapi.client import OpenAPI +from fastagency.api.openapi import OpenAPI from fastagency.api.openapi.security import APIKeyHeader from fastagency.runtimes.autogen import AutoGenWorkflows from fastagency.runtimes.autogen.agents.websurfer import WebSurferAgent diff --git a/docs/docs_src/user_guide/dependency_injection/__init__.py b/docs/docs_src/user_guide/dependency_injection/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/docs/docs_src/user_guide/dependency_injection/mesop/folder_structure.txt b/docs/docs_src/user_guide/dependency_injection/mesop/folder_structure.txt new file mode 100644 index 00000000..592731cc --- /dev/null +++ b/docs/docs_src/user_guide/dependency_injection/mesop/folder_structure.txt @@ -0,0 +1,35 @@ +my_bank_app +├── docker +│   ├── content +│   │   ├── nginx.conf.template +│   │   └── run_fastagency.sh +│   └── Dockerfile +├── my_bank_app +│   ├── deployment +│   │   ├── __init__.py +│   │   └── main.py +│   ├── local +│   │   ├── __init__.py +│   │   ├── main_console.py +│   │   └── main_mesop.py +│   ├── __init__.py +│   └── workflow.py +├── scripts +│   ├── build_docker.sh +│   ├── check-registered-app-pre-commit.sh +│   ├── check-registered-app.sh +│   ├── deploy_to_fly_io.sh +│   ├── lint-pre-commit.sh +│   ├── lint.sh +│   ├── register_to_fly_io.sh +│   ├── run_docker.sh +│   ├── run_mesop_locally.sh +│   ├── static-analysis.sh +│   └── static-pre-commit.sh +├── tests +│   ├── __init__.py +│   ├── conftest.py +│   └── test_workflow.py +├── README.md +├── fly.toml +└── pyproject.toml diff --git a/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/.codespell-whitelist.txt b/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/.codespell-whitelist.txt new file mode 100644 index 00000000..e69de29b diff --git a/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/.devcontainer/devcontainer.env b/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/.devcontainer/devcontainer.env new file mode 100644 index 00000000..68a70143 --- /dev/null +++ b/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/.devcontainer/devcontainer.env @@ -0,0 +1,7 @@ +CONTAINER_PREFIX=${USER} + +# LLM keys +# Set atleast one of the following keys +OPENAI_API_KEY=${OPENAI_API_KEY} +TOGETHER_API_KEY=${TOGETHER_API_KEY} +ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY} diff --git a/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/.devcontainer/devcontainer.json b/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/.devcontainer/devcontainer.json new file mode 100644 index 00000000..5e335b8d --- /dev/null +++ b/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/.devcontainer/devcontainer.json @@ -0,0 +1,66 @@ +{ + "name": "python-3.12", + "dockerComposeFile": [ + "./docker-compose.yml" + ], + "service": "python-3.12-my_bank_app", + + "secrets": { + "OPENAI_API_KEY": { + "description": "This key is optional and only needed if you are working on OpenAI-related code. Leave it blank if not required. You can always set it later as an environment variable in the codespace terminal." + }, + "TOGETHER_API_KEY": { + "description": "This key is optional and only needed if you are working with Together API-related code. Leave it blank if not required. You can always set it later as an environment variable in the codespace terminal." + }, + "ANTHROPIC_API_KEY": { + "description": "This key is optional and only needed if you are working with Anthropic API-related code. Leave it blank if not required. You can always set it later as an environment variable in the codespace terminal." + } + }, + "shutdownAction": "stopCompose", + "workspaceFolder": "/workspaces/my_bank_app", + // "runArgs": [], + "remoteEnv": {}, + "features": { + "ghcr.io/devcontainers/features/common-utils:2": { + "installZsh": true, + "installOhMyZsh": true, + "configureZshAsDefaultShell": true, + "username": "vscode", + "userUid": "1000", + "userGid": "1000" + // "upgradePackages": "true" + }, + "ghcr.io/devcontainers/features/git:1": {}, + "ghcr.io/devcontainers/features/git-lfs:1": {}, + "ghcr.io/devcontainers/features/docker-in-docker:2": {} + }, + "updateContentCommand": "bash .devcontainer/setup.sh", + "postCreateCommand": [], + "customizations": { + "vscode": { + "settings": { + "python.linting.enabled": true, + "python.testing.pytestEnabled": true, + "editor.formatOnSave": true, + "editor.codeActionsOnSave": { + "source.organizeImports": "always" + }, + "[python]": { + "editor.defaultFormatter": "ms-python.vscode-pylance" + }, + "editor.rulers": [ + 80 + ] + }, + "extensions": [ + "ms-python.python", + "ms-toolsai.jupyter", + "ms-toolsai.vscode-jupyter-cell-tags", + "ms-toolsai.jupyter-keymap", + "ms-toolsai.jupyter-renderers", + "ms-toolsai.vscode-jupyter-slideshow", + "ms-python.vscode-pylance" + ] + } + } +} diff --git a/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/.devcontainer/docker-compose.yml b/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/.devcontainer/docker-compose.yml new file mode 100644 index 00000000..1aa124bc --- /dev/null +++ b/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/.devcontainer/docker-compose.yml @@ -0,0 +1,21 @@ +version: '3' + +services: + # nosemgrep: yaml.docker-compose.security.writable-filesystem-service.writable-filesystem-service + python-3.12-my_bank_app: + image: mcr.microsoft.com/devcontainers/python:3.12 + container_name: my_bank_app-${USER}-python-3.12 + volumes: + - ../:/workspaces/my_bank_app:cached + command: sleep infinity + + env_file: + - ./devcontainer.env + security_opt: + - no-new-privileges:true + networks: + - my_bank_app-network + +networks: + my_bank_app-network: + name: my_bank_app-${USER}-network diff --git a/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/.devcontainer/setup.sh b/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/.devcontainer/setup.sh new file mode 100644 index 00000000..872323dd --- /dev/null +++ b/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/.devcontainer/setup.sh @@ -0,0 +1,20 @@ +# update pip +pip install --upgrade pip + +# install dev packages +pip install -e ".[dev]" + +# install pre-commit hooks +pre-commit install + +# install fly.io CLI and set fly.io CLI PATH in bashrc and zshrc +curl -L https://fly.io/install.sh | sh +echo 'export FLYCTL_INSTALL="/home/vscode/.fly"' | tee -a ~/.bashrc ~/.zshrc +echo 'export PATH="$FLYCTL_INSTALL/bin:$PATH"' | tee -a ~/.bashrc ~/.zshrc + +# check OPENAI_API_KEY environment variable is set +if [ -z "$OPENAI_API_KEY" ]; then + echo + echo -e "\033[33mWarning: OPENAI_API_KEY environment variable is not set.\033[0m" + echo +fi diff --git a/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/.dockerignore b/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/.dockerignore new file mode 100644 index 00000000..e69de29b diff --git a/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/.github/dependabot.yml b/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/.github/dependabot.yml new file mode 100644 index 00000000..a72abdca --- /dev/null +++ b/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/.github/dependabot.yml @@ -0,0 +1,17 @@ +# To get started with Dependabot version updates, you'll need to specify which +# package ecosystems to update and where the package manifests are located. +# Please see the documentation for all configuration options: +# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates + +version: 2 +updates: + # GitHub Actions + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" + # Python + - package-ecosystem: "pip" # See documentation for possible values + directory: "/" # Location of package manifests + schedule: + interval: "weekly" diff --git a/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/.github/workflows/deploy_to_fly_io.yml b/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/.github/workflows/deploy_to_fly_io.yml new file mode 100644 index 00000000..8c69f77c --- /dev/null +++ b/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/.github/workflows/deploy_to_fly_io.yml @@ -0,0 +1,22 @@ + +name: Fly Deploy + +on: + push: + branches: + - main + workflow_dispatch: + +env: + FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }} + OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} + +jobs: + deploy: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: superfly/flyctl-actions/setup-flyctl@master + + - name: Check if the app name is registered in fly.io and deploy + run: ./scripts/deploy_to_fly_io.sh diff --git a/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/.github/workflows/test.yml b/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/.github/workflows/test.yml new file mode 100644 index 00000000..81129fd1 --- /dev/null +++ b/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/.github/workflows/test.yml @@ -0,0 +1,49 @@ + +name: Test + +on: + push: + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +jobs: + test: + strategy: + matrix: + python-version: ["3.12"] + fail-fast: false + runs-on: ubuntu-latest + timeout-minutes: 15 + + steps: + - uses: actions/checkout@v4 + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + cache: "pip" + cache-dependency-path: pyproject.toml + - uses: actions/cache@v4 + id: cache + with: + path: ${{ env.pythonLocation }} + key: ${{ runner.os }}-python-${{ env.pythonLocation }}-${{ hashFiles('pyproject.toml') }}-test-v03 + - name: Install Dependencies + if: steps.cache.outputs.cache-hit != 'true' + run: pip install .[testing] + - name: Check for OPENAI_API_KEY + run: | + if [ -z "${{ secrets.OPENAI_API_KEY }}" ]; then + echo "Error: OPENAI_API_KEY is not set in GitHub secrets." + echo "Please set the OPENAI_API_KEY secret in your repository settings." + echo "Follow the instructions here:" + echo "https://docs.github.com/en/actions/security-for-github-actions/security-guides/using-secrets-in-github-actions#creating-secrets-for-a-repository" + exit 1 + fi + - name: Run tests + run: pytest + env: + CONTEXT: ${{ runner.os }}-py${{ matrix.python-version }} diff --git a/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/.gitignore b/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/.gitignore new file mode 100644 index 00000000..9e5161e9 --- /dev/null +++ b/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/.gitignore @@ -0,0 +1,18 @@ +__pycache__ +dist +.idea +venv* +.venv* +.env +.env* +*.lock +.vscode +.pypirc +.pytest_cache +.ruff_cache +.mypy_cache +.coverage* +.cache +htmlcov +token +.DS_Store diff --git a/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/.pre-commit-config.yaml b/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/.pre-commit-config.yaml new file mode 100644 index 00000000..68af06e1 --- /dev/null +++ b/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/.pre-commit-config.yaml @@ -0,0 +1,47 @@ +# See https://pre-commit.com for more information +# See https://pre-commit.com/hooks.html for more hooks +repos: + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v5.0.0 + hooks: + - id: trailing-whitespace + - id: end-of-file-fixer + - id: check-yaml + - id: check-added-large-files + + - repo: local + hooks: + - id: lint + name: Linter + entry: "scripts/lint-pre-commit.sh" + language: python + # language_version: python3.12 + types: [python] + require_serial: true + verbose: true + + - repo: local + hooks: + - id: static-analysis + name: Static analysis + entry: "scripts/static-pre-commit.sh" + language: python + # language_version: python3.12 + types: [python] + require_serial: true + verbose: true + + - repo: https://github.com/Yelp/detect-secrets + rev: v1.5.0 + hooks: + - id: detect-secrets + args: ["--baseline", ".secrets.baseline"] + + - repo: local + hooks: + - id: check-registered-app + name: Check if the app name is registered in fly.io + entry: "scripts/check-registered-app-pre-commit.sh" + language: python + require_serial: true + verbose: true diff --git a/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/.secrets.baseline b/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/.secrets.baseline new file mode 100644 index 00000000..5d482210 --- /dev/null +++ b/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/.secrets.baseline @@ -0,0 +1,127 @@ +{ + "version": "1.5.0", + "plugins_used": [ + { + "name": "ArtifactoryDetector" + }, + { + "name": "AWSKeyDetector" + }, + { + "name": "AzureStorageKeyDetector" + }, + { + "name": "Base64HighEntropyString", + "limit": 4.5 + }, + { + "name": "BasicAuthDetector" + }, + { + "name": "CloudantDetector" + }, + { + "name": "DiscordBotTokenDetector" + }, + { + "name": "GitHubTokenDetector" + }, + { + "name": "GitLabTokenDetector" + }, + { + "name": "HexHighEntropyString", + "limit": 3.0 + }, + { + "name": "IbmCloudIamDetector" + }, + { + "name": "IbmCosHmacDetector" + }, + { + "name": "IPPublicDetector" + }, + { + "name": "JwtTokenDetector" + }, + { + "name": "KeywordDetector", + "keyword_exclude": "" + }, + { + "name": "MailchimpDetector" + }, + { + "name": "NpmDetector" + }, + { + "name": "OpenAIDetector" + }, + { + "name": "PrivateKeyDetector" + }, + { + "name": "PypiTokenDetector" + }, + { + "name": "SendGridDetector" + }, + { + "name": "SlackDetector" + }, + { + "name": "SoftlayerDetector" + }, + { + "name": "SquareOAuthDetector" + }, + { + "name": "StripeDetector" + }, + { + "name": "TelegramBotTokenDetector" + }, + { + "name": "TwilioKeyDetector" + } + ], + "filters_used": [ + { + "path": "detect_secrets.filters.allowlist.is_line_allowlisted" + }, + { + "path": "detect_secrets.filters.common.is_ignored_due_to_verification_policies", + "min_level": 2 + }, + { + "path": "detect_secrets.filters.heuristic.is_indirect_reference" + }, + { + "path": "detect_secrets.filters.heuristic.is_likely_id_string" + }, + { + "path": "detect_secrets.filters.heuristic.is_lock_file" + }, + { + "path": "detect_secrets.filters.heuristic.is_not_alphanumeric_string" + }, + { + "path": "detect_secrets.filters.heuristic.is_potential_uuid" + }, + { + "path": "detect_secrets.filters.heuristic.is_prefixed_with_dollar_sign" + }, + { + "path": "detect_secrets.filters.heuristic.is_sequential_string" + }, + { + "path": "detect_secrets.filters.heuristic.is_swagger_file" + }, + { + "path": "detect_secrets.filters.heuristic.is_templated_secret" + } + ], + "results": {}, + "generated_at": "2024-11-07T10:08:12Z" +} diff --git a/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/README.md b/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/README.md new file mode 100644 index 00000000..ec6bb299 --- /dev/null +++ b/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/README.md @@ -0,0 +1,91 @@ +# My Bank App + +This repository contains a [`FastAgency`](https://github.com/airtai/fastagency) application which uses [Mesop](https://google.github.io/mesop/). Below, you'll find a guide on how to run the application. + +## Running FastAgency Application + +To run this [`FastAgency`](https://github.com/airtai/fastagency) application, follow these steps: + +1. To run the `FastAgency` application, you need an API key for any LLM. The most commonly used LLM is [OpenAI](https://platform.openai.com/docs/models). To use it, create an [OpenAI API Key](https://openai.com/index/openai-api/) and set it as an environment variable in the terminal using the following command: + + ```bash + export OPENAI_API_KEY=paste_openai_api_key_here + ``` + + If you want to use a different LLM provider, follow [this guide](https://fastagency.ai/latest/user-guide/runtimes/autogen/using_non_openai_models/). + + Alternatively, you can skip this step and set the LLM API key as an environment variable later in the devcontainer's terminal. If you open the project in `VSCode` using GUI, you will need to manually set the environment variable in the devcontainer's terminal. + + For [GitHub Codespaces](https://github.com/features/codespaces), you can set the LLM API key as a secret by following [this guide](https://docs.github.com/en/codespaces/setting-up-your-project-for-codespaces/configuring-dev-containers/specifying-recommended-secrets-for-a-repository), Or directly as an environment variable in the Codespaces' terminal. + +2. Open this folder in [VSCode](https://code.visualstudio.com/) using the following command: + + ```bash + code . + ``` + + If you are using GUI to open the project in `VSCode`, you will need to manually set the environment variable in the devcontainer's terminal. + + Alternatively, you can open this repository in [GitHub Codespaces](https://github.com/features/codespaces). + +3. Press `Ctrl+Shift+P`(for windows/linux) or `Cmd+Shift+P`(for mac) and select the option `Dev Containers: Rebuild and Reopen in Container`. This will open the current repository in a [devcontainer](https://code.visualstudio.com/docs/devcontainers/containers) using Docker and will install all the requirements to run the example application. + +4. The `workflow.py` file defines the autogen workflows. It is imported and used in the files that define the `UI`. + +5. The `main.py` file defines the `MesopUI`. You can use any Python WSGI HTTP server like [gunicorn](https://gunicorn.org/) which is the preferred way to run the Mesop application. In a devcontainer terminal, run the following command: + + ```bash + gunicorn my_bank_app.deployment.main:app + ``` + +6. Open the Mesop UI URL [http://localhost:8888](http://localhost:8888) in your browser. You can now use the graphical user interface to start and run the autogen workflow. + +## Running tests + +This `FastAgency` project includes tests to test the autogen workflow. Run these tests with the following command: + +```bash +pytest -s +``` + +## Docker + +This `FastAgency` project includes a Dockerfile for building and running a Docker image. You can build and test-run the Docker image within the devcontainer, as docker-in-docker support is enabled. Follow these steps: + +1. In the devcontainer terminal, run the following command to build the Docker image: + + ```bash + docker build -t deploy_fastagency -f docker/Dockerfile . + ``` + +2. Once the Docker image is built, you can run it using the following command: + + ```bash + docker run --rm -d --name deploy_fastagency -e OPENAI_API_KEY=$OPENAI_API_KEY -p 8888:8888 deploy_fastagency + ``` + +## Deploying with Docker + +This `FastAgency` project includes a `fly.toml` file for deployment to [fly.io](https://fly.io/), allowing you to share this project with others using a single URL. If you prefer deploying to another hosting provider, you can use the provided Dockerfile. To deplooy to fly.io, follow these steps: + +1. Login into fly.io: + + ```bash + flyctl auth login + ``` + +2. Launch the fly.io app: + + ```bash + flyctl launch --config fly.toml --copy-config --yes + ``` + +3. Set necessary LLM API key(for example, OPENAI_API_KEY) as a secret: + + ```bash + flyctl secrets set OPENAI_API_KEY=paste_openai_api_key_here + ``` + +## What's Next? + +Once you’ve experimented with the default workflow in the `workflow.py` file, modify the autogen workflow to define your own workflows and try them out. diff --git a/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/docker/Dockerfile b/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/docker/Dockerfile new file mode 100644 index 00000000..19a5479e --- /dev/null +++ b/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/docker/Dockerfile @@ -0,0 +1,41 @@ +FROM python:3.12 + +WORKDIR /app + +# Install nginx +RUN apt-get update && apt-get install -y --no-install-recommends nginx gettext \ + && rm -rf /var/lib/apt/lists/* + +COPY my_bank_app /app/my_bank_app + +COPY pyproject.toml README.md /app/ +COPY docker/content/* /app/ + + +RUN pip install --upgrade pip && pip install --no-cache-dir -e "." + +# Add user appuser with root permissions +RUN adduser --disabled-password --gecos '' appuser \ + && chown -R appuser /app \ + && chown -R appuser:appuser /etc/nginx/conf.d /var/log/nginx /var/lib/nginx \ + && touch /run/nginx.pid && chown -R appuser:appuser /run/nginx.pid \ + # Allow binding to ports > 1024 without root + && sed -i 's/listen 80/listen 9999/g' /etc/nginx/sites-available/default \ + && sed -i 's/listen \[::\]:80/listen \[::\]:9999/g' /etc/nginx/sites-available/default \ + # Create required directories with correct permissions + && mkdir -p /var/cache/nginx /var/run \ + && chown -R appuser:appuser /var/cache/nginx /var/run + +USER appuser + +# ToDo: Fix exposing ports +# EXPOSE 8000 8008 8888 + +CMD ["/app/run_fastagency.sh"] + +# Run the build command from root of fastagency repo +# docker build -t deploy_fastagency -f docker/Dockerfile . + +# Run the container + +# docker run --rm -d --name deploy_fastagency -e OPENAI_API_KEY=$OPENAI_API_KEY -p 8888:8888 deploy_fastagency diff --git a/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/docker/content/nginx.conf.template b/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/docker/content/nginx.conf.template new file mode 100644 index 00000000..626bce1c --- /dev/null +++ b/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/docker/content/nginx.conf.template @@ -0,0 +1,72 @@ +upstream nats_fastapi_backend { + # Enable sticky sessions with IP hash + ip_hash; + + +} + +upstream fastapi_backend { + # Enable sticky sessions with IP hash + ip_hash; + + +} + +upstream mesop_backend { + # Enable sticky sessions with IP hash + ip_hash; + + +} + +# Extract fly-machine-id cookie value +map $http_cookie $fly_machine_id { + "~*fly-machine-id=([^;]+)" $1; + default ""; +} + +# Determine action based on cookie value +map $fly_machine_id $sticky_action { + "" "set_cookie"; # Empty cookie - need to set it + $FLY_MACHINE_ID "proceed"; # Cookie matches current instance + default "replay"; # Cookie exists but doesn't match - need to replay +} + +# Mesop server block +server { + listen $MESOP_PORT; + server_name localhost; + + # Security headers + add_header X-Frame-Options "SAMEORIGIN"; + add_header X-Content-Type-Options "nosniff"; + add_header X-XSS-Protection "1; mode=block"; + + location / { + # Handle cookie setting + if ($sticky_action = "set_cookie") { + add_header Set-Cookie "fly-machine-id=$FLY_MACHINE_ID; Max-Age=518400; Path=/"; + } + + # Handle replay + if ($sticky_action = "replay") { + add_header Fly-Replay "instance=$fly_machine_id"; + return 307; + } + + proxy_pass http://mesop_backend; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_redirect off; + proxy_buffering off; + + # WSGI support + proxy_set_header X-Forwarded-Host $server_name; + + # WebSocket support + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + } +} diff --git a/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/docker/content/run_fastagency.sh b/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/docker/content/run_fastagency.sh new file mode 100755 index 00000000..2f26452b --- /dev/null +++ b/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/docker/content/run_fastagency.sh @@ -0,0 +1,54 @@ +#!/bin/bash + +# Accept env variable for PORT +export NATS_FASTAPI_PORT=${NATS_FASTAPI_PORT:-8000} +export FASTAPI_PORT=${FASTAPI_PORT:-8008} +export MESOP_PORT=${MESOP_PORT:-8888} + +# Default number of workers if not set +WORKERS=${WORKERS:-1} +echo "Number of workers: $WORKERS" + +# Check FLY_MACHINE_ID is set, if not set, set it to dummy value +export FLY_MACHINE_ID=${FLY_MACHINE_ID:-dummy_fly_machine_id_value} +echo "Fly machine ID: $FLY_MACHINE_ID" + +# Generate nginx config +for ((i=1; i<$WORKERS+1; i++)) +do + PORT=$((MESOP_PORT + i)) + sed -i "19i\ server 127.0.0.1:$PORT;" nginx.conf.template +done + +for ((i=1; i<$WORKERS+1; i++)) +do + PORT=$((FASTAPI_PORT + i)) + sed -i "12i\ server 127.0.0.1:$PORT;" nginx.conf.template +done + +for ((i=1; i<$WORKERS+1; i++)) +do + PORT=$((NATS_FASTAPI_PORT + i)) + sed -i "5i\ server 127.0.0.1:$PORT;" nginx.conf.template +done + +envsubst '${NATS_FASTAPI_PORT},${FASTAPI_PORT},${MESOP_PORT},${FLY_MACHINE_ID}' < nginx.conf.template >/etc/nginx/conf.d/default.conf +echo "Nginx config:" +cat /etc/nginx/conf.d/default.conf + +# Start nginx +nginx -g "daemon off;" & + + + +# Run gunicorn server +# Start multiple single-worker gunicorn instances on consecutive ports +for ((i=1; i<$WORKERS+1; i++)) +do + PORT=$((MESOP_PORT + i)) + echo "Starting gunicorn on port $PORT" + gunicorn --workers=1 my_bank_app.deployment.main:app --bind 0.0.0.0:$PORT > /dev/stdout 2>&1 & +done + +# Wait for all background processes +wait diff --git a/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/fly.toml b/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/fly.toml new file mode 100644 index 00000000..8547e4ff --- /dev/null +++ b/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/fly.toml @@ -0,0 +1,37 @@ +# fly.toml app configuration file generated for my_bank_app +# +# See https://fly.io/docs/reference/configuration/ for information about how to use this file. +# + +app = 'my-bank-app' +primary_region = 'ams' + +[build] + dockerfile = 'docker/Dockerfile' + +[http_service] + internal_port = 8888 + force_https = true + auto_stop_machines = 'stop' + auto_start_machines = true + min_machines_running = 0 + processes = ['app'] + +[[vm]] + memory = '1gb' + cpu_kind = 'shared' + cpus = 1 + +[[services]] + http_checks = [] + internal_port = 8888 + processes = ["app"] + protocol = "tcp" + script_checks = [] + + [services.concurrency] + type = "connections" + + [[services.ports]] + handlers = ["tls", "http"] + port = 8888 diff --git a/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/my_bank_app/__init__.py b/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/my_bank_app/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/my_bank_app/deployment/__init__.py b/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/my_bank_app/deployment/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/my_bank_app/deployment/main.py b/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/my_bank_app/deployment/main.py new file mode 100644 index 00000000..5259b4c4 --- /dev/null +++ b/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/my_bank_app/deployment/main.py @@ -0,0 +1,16 @@ +from fastagency import FastAgency +from fastagency.ui.mesop import MesopUI + +from ..workflow import wf + +ui = MesopUI() + + +app = FastAgency( + provider=wf, + ui=ui, + title="My Bank App", +) + +# start the fastagency app with the following command +# gunicorn my_bank_app.deployment.main:app diff --git a/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/my_bank_app/local/__init__.py b/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/my_bank_app/local/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/my_bank_app/local/main_console.py b/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/my_bank_app/local/main_console.py new file mode 100644 index 00000000..7b2df8cd --- /dev/null +++ b/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/my_bank_app/local/main_console.py @@ -0,0 +1,10 @@ +from fastagency import FastAgency +from fastagency.ui.console import ConsoleUI + +from ..workflow import wf + +app = FastAgency( + provider=wf, + ui=ConsoleUI(), + title="My Bank App", +) diff --git a/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/my_bank_app/local/main_mesop.py b/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/my_bank_app/local/main_mesop.py new file mode 100644 index 00000000..7bfcab33 --- /dev/null +++ b/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/my_bank_app/local/main_mesop.py @@ -0,0 +1,13 @@ +from fastagency import FastAgency +from fastagency.ui.mesop import MesopUI + +from ..workflow import wf + +app = FastAgency( + provider=wf, + ui=MesopUI(), + title="My Bank App", +) + +# start the fastagency app with the following command +# gunicorn my_bank_app.local.main_mesop:app diff --git a/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/my_bank_app/workflow.py b/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/my_bank_app/workflow.py new file mode 100644 index 00000000..d3fa0005 --- /dev/null +++ b/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/my_bank_app/workflow.py @@ -0,0 +1,84 @@ +import os +from typing import Annotated, Any + +from autogen import UserProxyAgent, register_function +from autogen.agentchat import ConversableAgent +from fastagency import UI +from fastagency.api.dependency_injection import inject_params +from fastagency.runtimes.autogen import AutoGenWorkflows + +account_ballace_dict = { + ("alice", "password123"): 100, + ("bob", "password456"): 200, + ("charlie", "password789"): 300, +} + + +def get_balance( + username: Annotated[str, "Username"], + password: Annotated[str, "Password"], +) -> str: + if (username, password) not in account_ballace_dict: + return "Invalid username or password" + return f"Your balance is {account_ballace_dict[(username, password)]}$" + + +llm_config = { + "config_list": [ + { + "model": "gpt-4o-mini", + "api_key": os.getenv("OPENAI_API_KEY"), + } + ], + "temperature": 0.8, +} + +wf = AutoGenWorkflows() + + +@wf.register(name="bank_chat", description="Bank chat") # type: ignore[misc] +def bank_workflow(ui: UI, params: dict[str, str]) -> str: + username = ui.text_input( + sender="Workflow", + recipient="User", + prompt="Enter your username:", + ) + password = ui.text_input( + sender="Workflow", + recipient="User", + prompt="Enter your password:", + ) + + user_agent = UserProxyAgent( + name="User_Agent", + system_message="You are a user agent", + llm_config=llm_config, + human_input_mode="NEVER", + ) + banker_agent = ConversableAgent( + name="Banker_Agent", + system_message="You are a banker agent", + llm_config=llm_config, + human_input_mode="NEVER", + ) + + ctx: dict[str, Any] = { + "username": username, + "password": password, + } + get_balance_with_params = inject_params(get_balance, ctx) + register_function( + f=get_balance_with_params, + caller=banker_agent, + executor=user_agent, + description="Get balance", + ) + + chat_result = user_agent.initiate_chat( + banker_agent, + message="We need to get user's balance.", + summary_method="reflection_with_llm", + max_turns=3, + ) + + return chat_result.summary # type: ignore[no-any-return] diff --git a/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/pyproject.toml b/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/pyproject.toml new file mode 100644 index 00000000..fcf985d9 --- /dev/null +++ b/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/pyproject.toml @@ -0,0 +1,130 @@ +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + +[project] + +version = "0.1.0" +name = "my_bank_app" + +dependencies = [ + "fastagency[autogen,mesop,server]>=0.3.0", +] + +[project.optional-dependencies] +testing = [ + "pytest==8.3.3", + "pytest-asyncio==0.24.0", +] + +# dev dependencies +lint = [ + "types-PyYAML", + "types-setuptools", + "types-ujson", + "types-Pygments", + "types-docutils", + "mypy==1.12.1", + "ruff==0.7.2", + "pyupgrade-directories==0.3.0", + "bandit==1.7.10", + "semgrep==1.95.0", + "codespell==2.3.0", + "pytest-mypy-plugins==3.1.2", +] + +dev = [ + "my_bank_app[testing,lint]", + "pre-commit==4.0.1", + "detect-secrets==1.5.0", +] + +[tool.hatch.build.targets.wheel] +only-include = ["my_bank_app"] + +[tool.pytest.ini_options] +filterwarnings =["ignore::DeprecationWarning"] +asyncio_default_fixture_loop_scope = "function" +testpaths = [ + "tests", +] + +[tool.mypy] + +files = ["my_bank_app", "tests"] + +strict = true +python_version = "3.12" +ignore_missing_imports = true +install_types = true +non_interactive = true +plugins = [ + "pydantic.mypy", +] + +# from https://blog.wolt.com/engineering/2021/09/30/professional-grade-mypy-configuration/ +disallow_untyped_defs = true +no_implicit_optional = true +check_untyped_defs = true +warn_return_any = true +show_error_codes = true +warn_unused_ignores = false + +disallow_incomplete_defs = true +disallow_untyped_decorators = true +disallow_any_unimported = false + +[tool.ruff] +fix = true +line-length = 88 +include = ["my_bank_app/**/*.py", "my_bank_app/**/*.pyi", "pyproject.toml"] +exclude = [] + +[tool.ruff.lint] +select = [ + "E", # pycodestyle errors https://docs.astral.sh/ruff/rules/#error-e + "W", # pycodestyle warnings https://docs.astral.sh/ruff/rules/#warning-w + "C90", # mccabe https://docs.astral.sh/ruff/rules/#mccabe-c90 + "N", # pep8-naming https://docs.astral.sh/ruff/rules/#pep8-naming-n + "D", # pydocstyle https://docs.astral.sh/ruff/rules/#pydocstyle-d + "I", # isort https://docs.astral.sh/ruff/rules/#isort-i + "F", # pyflakes https://docs.astral.sh/ruff/rules/#pyflakes-f + "ASYNC", # flake8-async https://docs.astral.sh/ruff/rules/#flake8-async-async + "C4", # flake8-comprehensions https://docs.astral.sh/ruff/rules/#flake8-comprehensions-c4 + "B", # flake8-bugbear https://docs.astral.sh/ruff/rules/#flake8-bugbear-b + "Q", # flake8-quotes https://docs.astral.sh/ruff/rules/#flake8-quotes-q + "T20", # flake8-print https://docs.astral.sh/ruff/rules/#flake8-print-t20 + "SIM", # flake8-simplify https://docs.astral.sh/ruff/rules/#flake8-simplify-sim + "PT", # flake8-pytest-style https://docs.astral.sh/ruff/rules/#flake8-pytest-style-pt + "PTH", # flake8-use-pathlib https://docs.astral.sh/ruff/rules/#flake8-use-pathlib-pth + "TCH", # flake8-type-checking https://docs.astral.sh/ruff/rules/#flake8-type-checking-tch + "RUF", # Ruff-specific rules https://docs.astral.sh/ruff/rules/#ruff-specific-rules-ruf + "PERF", # Perflint https://docs.astral.sh/ruff/rules/#perflint-perf +] + +ignore = [ + "E501", # line too long, handled by formatter later + "D100", "D101", "D102", "D103", "D104", +# "C901", # too complex +] + +[tool.ruff.lint.isort] +case-sensitive = true + +[tool.ruff.format] +docstring-code-format = true + +[tool.ruff.lint.pydocstyle] +convention = "google" + +[tool.ruff.lint.flake8-bugbear] + +[tool.bandit] + +[tool.black] + +line-length = 88 + +[tool.codespell] +skip = "./venv*" +ignore-words = ".codespell-whitelist.txt" diff --git a/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/scripts/build_docker.sh b/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/scripts/build_docker.sh new file mode 100755 index 00000000..47a834bc --- /dev/null +++ b/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/scripts/build_docker.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +echo -e "\033[0;32mBuilding fastagency docker image\033[0m" +docker build -t deploy_fastagency -f docker/Dockerfile --progress plain . && \ +echo -e "\033[0;32mSuccessfully built fastagency docker image\033[0m" diff --git a/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/scripts/check-registered-app-pre-commit.sh b/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/scripts/check-registered-app-pre-commit.sh new file mode 100755 index 00000000..5f2aef85 --- /dev/null +++ b/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/scripts/check-registered-app-pre-commit.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash + +# taken from: https://jaredkhan.com/blog/mypy-pre-commit + +# A script for running mypy, +# with all its dependencies installed. + +set -o errexit + +# Change directory to the project root directory. +cd "$(dirname "$0")"/.. + +./scripts/check-registered-app.sh diff --git a/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/scripts/check-registered-app.sh b/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/scripts/check-registered-app.sh new file mode 100755 index 00000000..62a816ee --- /dev/null +++ b/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/scripts/check-registered-app.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +# Check file registered_app_domain.txt exists. If it does not exists, echo and exit. +if [ ! -f registered_app_domain.txt ]; then + echo -e "\033[0;33mWarning: App name is not registered.\033[0m" + echo -e "\033[0;33mGithub Actions may fail if you push without registering.\033[0m" + echo -e "\033[0;33mRegister your app name by running the script 'scripts/register_to_fly_io.sh'.\033[0m" +fi diff --git a/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/scripts/deploy_to_fly_io.sh b/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/scripts/deploy_to_fly_io.sh new file mode 100755 index 00000000..42e47b16 --- /dev/null +++ b/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/scripts/deploy_to_fly_io.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +# Check file registered_app_domain.txt exists. If it does not exists, echo and exit. +if [ ! -f registered_app_domain.txt ]; then + echo -e "\033[0;31mError: App name is not registered.\033[0m" + echo -e "\033[0;31mRegister your app name by running the script 'scripts/register_to_fly_io.sh'.\033[0m" + echo -e "\033[0;31mExiting.\033[0m" + exit 1 +fi + +echo -e "\033[0;32mChecking if already logged into fly.io\033[0m" +if ! flyctl auth whoami > /dev/null 2>&1; then + echo -e "\033[0;32mLogging into fly.io\033[0m" + flyctl auth login +else + echo -e "\033[0;32mAlready logged into fly.io\033[0m" +fi + +echo -e "\033[0;32mDeploying to fly.io\033[0m" +flyctl deploy --config fly.toml --yes + +echo -e "\033[0;32mSetting secrets\033[0m" +flyctl secrets set OPENAI_API_KEY=$OPENAI_API_KEY diff --git a/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/scripts/lint-pre-commit.sh b/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/scripts/lint-pre-commit.sh new file mode 100755 index 00000000..f78094cb --- /dev/null +++ b/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/scripts/lint-pre-commit.sh @@ -0,0 +1,21 @@ +#!/usr/bin/env bash + +# taken from: https://jaredkhan.com/blog/mypy-pre-commit + +# A script for running linting checks on a Python project, +# with all its dependencies installed. + +set -o errexit + +# Change directory to the project root directory. +cd "$(dirname "$0")"/.. + +# Install the dependencies. +# Note that this can take seconds to run. +pip install --editable ".[dev]" \ + --retries 1 \ + --no-input \ + --quiet + +# Run linting checks. +./scripts/lint.sh diff --git a/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/scripts/lint.sh b/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/scripts/lint.sh new file mode 100755 index 00000000..ed1abf0b --- /dev/null +++ b/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/scripts/lint.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash + +echo "Running pyup_dirs..." +pyup_dirs --py39-plus --recursive my_bank_app tests + +echo "Running ruff linter (isort, flake, pyupgrade, etc. replacement)..." +ruff check + +echo "Running ruff formatter (black replacement)..." +ruff format + +echo "Running codespell to find typos..." +codespell --skip="./playwright-report" diff --git a/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/scripts/register_to_fly_io.sh b/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/scripts/register_to_fly_io.sh new file mode 100755 index 00000000..bfd9711a --- /dev/null +++ b/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/scripts/register_to_fly_io.sh @@ -0,0 +1,32 @@ +#!/bin/bash + + +# Check file registered_app_domain.txt exists. If it does, echo and exit. +if [ -f registered_app_domain.txt ]; then + echo -e "\033[1;33mWarning: App name is already registered.\033[0m" + echo -e "\033[0;32mRegistered app name is:\033[0m" + cat registered_app_domain.txt + exit 1 +fi + +echo -e "\033[0;32mChecking if already logged into fly.io\033[0m" +if ! flyctl auth whoami > /dev/null 2>&1; then + echo -e "\033[0;32mLogging into fly.io\033[0m" + flyctl auth login +else + echo -e "\033[0;32mAlready logged into fly.io\033[0m" +fi + +export FLY_APP_NAME=$(grep "^app = " fly.toml | awk -F"'" '{print $2}') + +echo -e "\033[0;32mRegistering app name in fly.io\033[0m" +if flyctl apps create $FLY_APP_NAME; then + echo "$FLY_APP_NAME.fly.dev" > registered_app_domain.txt + echo -e "\033[0;32mApp name registered successfully\033[0m" + echo -e "\033[0;32mRegistered app name is:\033[0m" + cat registered_app_domain.txt +else + echo -e "\033[1;31mError: App name is not available.\033[0m" + echo -e "\033[1;31mPlease change the app name in fly.toml and run this script again.\033[0m" + exit 1 +fi diff --git a/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/scripts/run_docker.sh b/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/scripts/run_docker.sh new file mode 100755 index 00000000..ab261872 --- /dev/null +++ b/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/scripts/run_docker.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +docker run -it -e OPENAI_API_KEY=$OPENAI_API_KEY -p 8888:8888 deploy_fastagency diff --git a/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/scripts/run_mesop_locally.sh b/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/scripts/run_mesop_locally.sh new file mode 100755 index 00000000..bfa1830f --- /dev/null +++ b/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/scripts/run_mesop_locally.sh @@ -0,0 +1 @@ +gunicorn my_bank_app.local.main_mesop:app diff --git a/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/scripts/static-analysis.sh b/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/scripts/static-analysis.sh new file mode 100755 index 00000000..a55dc01f --- /dev/null +++ b/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/scripts/static-analysis.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env bash +set -e + +echo "Running mypy..." +mypy + +echo "Running bandit..." +bandit -c pyproject.toml -r my_bank_app + +echo "Running semgrep..." +semgrep scan --config auto --error diff --git a/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/scripts/static-pre-commit.sh b/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/scripts/static-pre-commit.sh new file mode 100755 index 00000000..43792b80 --- /dev/null +++ b/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/scripts/static-pre-commit.sh @@ -0,0 +1,21 @@ +#!/usr/bin/env bash + +# taken from: https://jaredkhan.com/blog/mypy-pre-commit + +# A script for running static analysis checks on a Python project, +# with all its dependencies installed. + +set -o errexit + +# Change directory to the project root directory. +cd "$(dirname "$0")"/.. + +# Install the dependencies. +# Note that this can take seconds to run. +pip install --editable ".[dev]" \ + --retries 1 \ + --no-input \ + --quiet + +# Run static analysis checks. +./scripts/static-analysis.sh diff --git a/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/tests/__init__.py b/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/tests/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/tests/conftest.py b/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/tests/conftest.py new file mode 100644 index 00000000..0452b46a --- /dev/null +++ b/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/tests/conftest.py @@ -0,0 +1,13 @@ +from typing import Any +from unittest.mock import MagicMock + + +class InputMock: + def __init__(self, responses: list[str]) -> None: + """Initialize the InputMock.""" + self.responses = responses + self.mock = MagicMock() + + def __call__(self, *args: Any, **kwargs: Any) -> str: + self.mock(*args, **kwargs) + return self.responses.pop(0) diff --git a/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/tests/test_workflow.py b/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/tests/test_workflow.py new file mode 100644 index 00000000..2d3eb032 --- /dev/null +++ b/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/tests/test_workflow.py @@ -0,0 +1,18 @@ +from uuid import uuid4 + +import pytest +from fastagency.ui.console import ConsoleUI + +from my_bank_app.workflow import wf +from tests.conftest import InputMock + + +def test_workflow(monkeypatch: pytest.MonkeyPatch) -> None: + monkeypatch.setattr("builtins.input", InputMock([""] * 5)) + + result = wf.run( + name="simple_learning", + ui=ConsoleUI().create_workflow_ui(workflow_uuid=uuid4().hex), + ) + + assert result is not None diff --git a/docs/docs_src/user_guide/dependency_injection/workflow.py b/docs/docs_src/user_guide/dependency_injection/workflow.py new file mode 100644 index 00000000..d3fa0005 --- /dev/null +++ b/docs/docs_src/user_guide/dependency_injection/workflow.py @@ -0,0 +1,84 @@ +import os +from typing import Annotated, Any + +from autogen import UserProxyAgent, register_function +from autogen.agentchat import ConversableAgent +from fastagency import UI +from fastagency.api.dependency_injection import inject_params +from fastagency.runtimes.autogen import AutoGenWorkflows + +account_ballace_dict = { + ("alice", "password123"): 100, + ("bob", "password456"): 200, + ("charlie", "password789"): 300, +} + + +def get_balance( + username: Annotated[str, "Username"], + password: Annotated[str, "Password"], +) -> str: + if (username, password) not in account_ballace_dict: + return "Invalid username or password" + return f"Your balance is {account_ballace_dict[(username, password)]}$" + + +llm_config = { + "config_list": [ + { + "model": "gpt-4o-mini", + "api_key": os.getenv("OPENAI_API_KEY"), + } + ], + "temperature": 0.8, +} + +wf = AutoGenWorkflows() + + +@wf.register(name="bank_chat", description="Bank chat") # type: ignore[misc] +def bank_workflow(ui: UI, params: dict[str, str]) -> str: + username = ui.text_input( + sender="Workflow", + recipient="User", + prompt="Enter your username:", + ) + password = ui.text_input( + sender="Workflow", + recipient="User", + prompt="Enter your password:", + ) + + user_agent = UserProxyAgent( + name="User_Agent", + system_message="You are a user agent", + llm_config=llm_config, + human_input_mode="NEVER", + ) + banker_agent = ConversableAgent( + name="Banker_Agent", + system_message="You are a banker agent", + llm_config=llm_config, + human_input_mode="NEVER", + ) + + ctx: dict[str, Any] = { + "username": username, + "password": password, + } + get_balance_with_params = inject_params(get_balance, ctx) + register_function( + f=get_balance_with_params, + caller=banker_agent, + executor=user_agent, + description="Get balance", + ) + + chat_result = user_agent.initiate_chat( + banker_agent, + message="We need to get user's balance.", + summary_method="reflection_with_llm", + max_turns=3, + ) + + return chat_result.summary # type: ignore[no-any-return] diff --git a/docs/docs_src/user_guide/external_rest_apis/security.py b/docs/docs_src/user_guide/external_rest_apis/security.py index 304b295f..4db6c004 100644 --- a/docs/docs_src/user_guide/external_rest_apis/security.py +++ b/docs/docs_src/user_guide/external_rest_apis/security.py @@ -4,7 +4,7 @@ from autogen.agentchat import ConversableAgent from fastagency import UI, FastAgency -from fastagency.api.openapi.client import OpenAPI +from fastagency.api.openapi import OpenAPI from fastagency.api.openapi.security import APIKeyHeader from fastagency.runtimes.autogen import AutoGenWorkflows from fastagency.ui.console import ConsoleUI diff --git a/examples/cli/main_user_proxy.py b/examples/cli/main_user_proxy.py index 38a395c5..6b10651e 100644 --- a/examples/cli/main_user_proxy.py +++ b/examples/cli/main_user_proxy.py @@ -4,7 +4,7 @@ from autogen.agentchat import ConversableAgent, UserProxyAgent from fastagency import UI, FastAgency -from fastagency.api.openapi.client import OpenAPI +from fastagency.api.openapi import OpenAPI from fastagency.api.openapi.security import APIKeyHeader from fastagency.runtimes.autogen import AutoGenWorkflows from fastagency.ui.console import ConsoleUI diff --git a/fastagency/api/dependency_injection.py b/fastagency/api/dependency_injection.py new file mode 100644 index 00000000..eb943324 --- /dev/null +++ b/fastagency/api/dependency_injection.py @@ -0,0 +1,25 @@ +from functools import wraps +from inspect import signature +from typing import Any, Callable + + +def inject_params(f: Callable[..., Any], ctx: dict[str, Any]) -> Callable[..., Any]: + keys_used = set(signature(f).parameters.keys()) & set(ctx.keys()) + + @wraps(f) + def wrapper(*args: Any, **kwargs: dict[str, Any]) -> Any: + # check if all required parameters are present + if not keys_used.issubset(ctx.keys()): + raise ValueError(f"Missing required parameters: {keys_used - ctx.keys()}") + + params = {k: ctx[k] for k in keys_used} + return f(**params, **kwargs) + + # Update the signature of wrapper to remove parameters passed in kwargs + sig = signature(f) + new_params = [ + param for name, param in sig.parameters.items() if name not in keys_used + ] + wrapper.__signature__ = sig.replace(parameters=new_params) # type: ignore[attr-defined] + + return wrapper diff --git a/fastagency/api/openapi/__init__.py b/fastagency/api/openapi/__init__.py index 281eebbc..8eddd088 100644 --- a/fastagency/api/openapi/__init__.py +++ b/fastagency/api/openapi/__init__.py @@ -14,6 +14,6 @@ patch_generate_code() patch_apply_discriminator_type() -from .client import OpenAPI # noqa: E402 +from .openapi import OpenAPI # noqa: E402 __all__ = ["OpenAPI"] diff --git a/fastagency/api/openapi/client.py b/fastagency/api/openapi/openapi.py similarity index 88% rename from fastagency/api/openapi/client.py rename to fastagency/api/openapi/openapi.py index 41f42e34..dff10e9a 100644 --- a/fastagency/api/openapi/client.py +++ b/fastagency/api/openapi/openapi.py @@ -47,14 +47,14 @@ def __init__( self, servers: list[dict[str, Any]], title: Optional[str] = None, **kwargs: Any ) -> None: """Proxy class to generate client from OpenAPI schema.""" - self.servers = servers - self.title = title - self.kwargs = kwargs - self.registered_funcs: list[Callable[..., Any]] = [] - self.globals: dict[str, Any] = {} + self._servers = servers + self._title = title + self._kwargs = kwargs + self._registered_funcs: list[Callable[..., Any]] = [] + self._globals: dict[str, Any] = {} - self.security: dict[str, list[BaseSecurity]] = {} - self.security_params: dict[Optional[str], BaseSecurityParameters] = {} + self._security: dict[str, list[BaseSecurity]] = {} + self._security_params: dict[Optional[str], BaseSecurityParameters] = {} @staticmethod def _convert_camel_case_within_braces_to_snake(text: str) -> str: @@ -97,7 +97,7 @@ def _process_params( expanded_path = path.format(**{p: kwargs[p] for p in path_params}) - url = self.servers[0]["url"] + expanded_path + url = self._servers[0]["url"] + expanded_path body_dict = {} if body and body in kwargs: @@ -122,7 +122,7 @@ def set_security_params( self, security_params: BaseSecurityParameters, name: Optional[str] = None ) -> None: if name is not None: - security = self.security.get(name) + security = self._security.get(name) if security is None: raise ValueError(f"Security is not set for '{name}'") @@ -134,7 +134,7 @@ def set_security_params( f"Security parameters {security_params} do not match security {security}" ) - self.security_params[name] = security_params + self._security_params[name] = security_params def _get_matching_security( self, security: list[BaseSecurity], security_params: BaseSecurityParameters @@ -151,14 +151,14 @@ def _get_security_params( self, name: str ) -> tuple[Optional[BaseSecurityParameters], Optional[BaseSecurity]]: # check if security is set for the method - security = self.security.get(name) + security = self._security.get(name) if not security: return None, None - security_params = self.security_params.get(name) + security_params = self._security_params.get(name) if security_params is None: # check if default security parameters are set - security_params = self.security_params.get(None) + security_params = self._security_params.get(None) if security_params is None: raise ValueError( f"Security parameters are not set for {name} and there are no default security parameters" @@ -180,13 +180,13 @@ def decorator(func: Callable[..., Any]) -> Callable[..., dict[str, Any]]: name = func.__name__ if security is not None: - self.security[name] = security + self._security[name] = security @wraps(func) def wrapper(*args: Any, **kwargs: Any) -> dict[str, Any]: url, params, body_dict = self._process_params(path, func, **kwargs) - security = self.security.get(name) + security = self._security.get(name) if security is not None: security_params, matched_security = self._get_security_params(name) if security_params is None: @@ -205,7 +205,7 @@ def wrapper(*args: Any, **kwargs: Any) -> dict[str, Any]: else None ) - self.registered_funcs.append(wrapper) + self._registered_funcs.append(wrapper) return wrapper @@ -283,7 +283,7 @@ def generate_code( def set_globals(self, main: ModuleType, suffix: str) -> None: xs = {k: v for k, v in main.__dict__.items() if not k.startswith("__")} - self.globals = { + self._globals = { k: v for k, v in xs.items() if hasattr(v, "__module__") @@ -293,6 +293,7 @@ def set_globals(self, main: ModuleType, suffix: str) -> None: @classmethod def create( cls, + *, openapi_json: Optional[str] = None, openapi_url: Optional[str] = None, client_source_path: Optional[str] = None, @@ -338,7 +339,7 @@ def _get_functions_to_register( ) -> dict[Callable[..., Any], dict[str, Union[str, None]]]: if functions is None: return { - f: {"name": None, "description": None} for f in self.registered_funcs + f: {"name": None, "description": None} for f in self._registered_funcs } functions_with_name_desc: dict[str, dict[str, Union[str, None]]] = {} @@ -361,7 +362,7 @@ def _get_functions_to_register( funcs_to_register: dict[Callable[..., Any], dict[str, Union[str, None]]] = { f: functions_with_name_desc[f.__name__] - for f in self.registered_funcs + for f in self._registered_funcs if f.__name__ in functions_with_name_desc } missing_functions = set(functions_with_name_desc.keys()) - { @@ -415,7 +416,7 @@ def _register_for_llm( ) -> None: funcs_to_register = self._get_functions_to_register(functions) - with add_to_globals(self.globals): + with add_to_globals(self._globals): for f, v in funcs_to_register.items(): agent.register_for_llm(name=v["name"], description=v["description"])(f) @@ -436,4 +437,32 @@ def _register_for_execution( agent.register_for_execution(name=v["name"])(f) def get_functions(self) -> list[str]: - return [f.__name__ for f in self.registered_funcs] + raise DeprecationWarning( + "Use function_names property instead of get_functions method" + ) + + @property + def function_names(self) -> list[str]: + return [f.__name__ for f in self._registered_funcs] + + def get_function(self, name: str) -> Callable[..., dict[str, Any]]: + for f in self._registered_funcs: + if f.__name__ == name: + return f + raise ValueError(f"Function {name} not found") + + def set_function(self, name: str, func: Callable[..., dict[str, Any]]) -> None: + for i, f in enumerate(self._registered_funcs): + if f.__name__ == name: + self._registered_funcs[i] = func + return + + raise ValueError(f"Function {name} not found") + + def inject_parameters(self, name: str, **kwargs: Any) -> None: + raise NotImplementedError("Injecting parameters is not implemented yet") + # for f in self._registered_funcs: + # if f.__name__ == name: + # return + + # raise ValueError(f"Function {name} not found") diff --git a/fastagency/runtimes/autogen/tools/whatsapp.py b/fastagency/runtimes/autogen/tools/whatsapp.py index 6363e00c..85727e65 100644 --- a/fastagency/runtimes/autogen/tools/whatsapp.py +++ b/fastagency/runtimes/autogen/tools/whatsapp.py @@ -2,7 +2,7 @@ from autogen import ConversableAgent -from fastagency.api.openapi.client import OpenAPI +from fastagency.api.openapi import OpenAPI from fastagency.api.openapi.security import APIKeyHeader from fastagency.runtimes.autogen.autogen import Toolable diff --git a/scripts/build-docs.sh b/scripts/build-docs.sh index 4ee11c0d..f74e3bc0 100755 --- a/scripts/build-docs.sh +++ b/scripts/build-docs.sh @@ -27,6 +27,14 @@ cd docs/docs_src/getting_started/basic_auth/ && \ cd nats_n_fastapi && tree --noreport --dirsfirst my_fastagency_app > folder_structure.txt && cd .. && \ cd ../../../.. +# build docs/docs_src/user_guide/dependency_injection +cd docs/docs_src/user_guide/dependency_injection && \ + rm -rf mesop/my_bank_app/; \ + cookiecutter -f -o mesop --no-input https://github.com/airtai/cookiecutter-fastagency.git project_name="My Bank App" app_type=mesop authentication=none && \ + cd mesop && tree --noreport --dirsfirst my_bank_app > folder_structure.txt && cd .. && \ + cp workflow.py mesop/my_bank_app/my_bank_app + cd ../../../.. + # build docs rm -rf docs/docs/en/api docs/docs/en/cli cd docs; python docs.py build diff --git a/tests/api/openapi/security/test_security.py b/tests/api/openapi/security/test_security.py index 31a32f20..1857da86 100644 --- a/tests/api/openapi/security/test_security.py +++ b/tests/api/openapi/security/test_security.py @@ -80,7 +80,7 @@ def test_import_and_call_generate_client(secure_fastapi_url: str) -> None: from main_gen import app as generated_client_app from main_gen import read_items_items__get - assert generated_client_app.security != {}, generated_client_app.security + assert generated_client_app._security != {}, generated_client_app._security api_key = "super secret key" # pragma: allowlist secret diff --git a/tests/api/openapi/security/test_unsupported_security.py b/tests/api/openapi/security/test_unsupported_security.py index d3d98978..8f64ebc1 100644 --- a/tests/api/openapi/security/test_unsupported_security.py +++ b/tests/api/openapi/security/test_unsupported_security.py @@ -2,7 +2,7 @@ import pytest -from fastagency.api.openapi.client import OpenAPI +from fastagency.api.openapi import OpenAPI from fastagency.api.openapi.security import HTTPBearer, UnsuportedSecurityStub from .test_http_bearer_client import create_http_bearer_fastapi_app diff --git a/tests/api/openapi/templates/test_fastapi_codegen_template.py b/tests/api/openapi/templates/test_fastapi_codegen_template.py index d24aa180..4bfd405c 100644 --- a/tests/api/openapi/templates/test_fastapi_codegen_template.py +++ b/tests/api/openapi/templates/test_fastapi_codegen_template.py @@ -62,7 +62,7 @@ def test_fastapi_codegen_template(openapi_file_path: Path) -> None: sys.path = original_sys_path app = main.app - assert app.title == openapi_file_path.stem + assert app._title == openapi_file_path.stem @pytest.mark.parametrize("openapi_file_path", OPENAPI_FILE_PATHS) diff --git a/tests/api/openapi/test_client.py b/tests/api/openapi/test_client.py index 6322a865..cc02cdaa 100644 --- a/tests/api/openapi/test_client.py +++ b/tests/api/openapi/test_client.py @@ -13,22 +13,22 @@ def test_simple_create_client(self) -> None: assert json_path.exists(), json_path.resolve() openapi_json = json_path.read_text() - client = OpenAPI.create(openapi_json) + client = OpenAPI.create(openapi_json=openapi_json) assert client is not None assert isinstance(client, OpenAPI) - assert client.servers == [ + assert client._servers == [ {"url": "http://localhost:8080", "description": "Local environment"} ] - assert len(client.registered_funcs) == 1, client.registered_funcs + assert len(client._registered_funcs) == 1, client._registered_funcs assert ( - client.registered_funcs[0].__name__ + client._registered_funcs[0].__name__ == "update_item_items__item_id__ships__ship__put" ) assert ( - client.registered_funcs[0].__doc__ + client._registered_funcs[0].__doc__ == """ Update Item """ @@ -38,14 +38,14 @@ def test_simple_create_client(self) -> None: assert json2_path.exists(), json2_path.resolve() openapi2_json = json2_path.read_text() - client2 = OpenAPI.create(openapi2_json) + client2 = OpenAPI.create(openapi_json=openapi2_json) assert client2 is not None assert isinstance(client2, OpenAPI) - assert len(client2.registered_funcs) == 3, client2.registered_funcs + assert len(client2._registered_funcs) == 3, client2._registered_funcs - actual = [x.__name__ for x in client2.registered_funcs] + actual = [x.__name__ for x in client2._registered_funcs] expected = [ "list_pets", "create_pets", @@ -64,29 +64,29 @@ def test_create_client_with_servers(self) -> None: openapi_json = json_path.read_text() client = OpenAPI.create(openapi_json=openapi_json, servers=servers) - assert client.servers == servers + assert client._servers == servers def test_get_functions(self) -> None: json_path = Path(__file__).parent / "templates" / "openapi.json" openapi_json = json_path.read_text() - client = OpenAPI.create(openapi_json) + client = OpenAPI.create(openapi_json=openapi_json) - functions = client.get_functions() + function_names = client.function_names expected = ["update_item_items__item_id__ships__ship__put"] - assert functions == expected, functions + assert function_names == expected, function_names json2_path = Path(__file__).parent / "templates" / "openapi2.json" openapi2_json = json2_path.read_text() - client2 = OpenAPI.create(openapi2_json) + client2 = OpenAPI.create(openapi_json=openapi2_json) - functions2 = client2.get_functions() + function_names2 = client2.function_names expected2 = ["list_pets", "create_pets", "show_pet_by_id"] - assert functions2 == expected2, functions2 + assert function_names2 == expected2, function_names2 def test_get_functions_to_register(self) -> None: json_path = Path(__file__).parent / "templates" / "openapi.json" openapi_json = json_path.read_text() - client = OpenAPI.create(openapi_json) + client = OpenAPI.create(openapi_json=openapi_json) functions = client._get_functions_to_register( ["update_item_items__item_id__ships__ship__put"] @@ -102,7 +102,7 @@ def test_get_functions_to_register(self) -> None: json2_path = Path(__file__).parent / "templates" / "openapi2.json" openapi2_json = json2_path.read_text() - client2 = OpenAPI.create(openapi2_json) + client2 = OpenAPI.create(openapi_json=openapi2_json) functions2 = client2._get_functions_to_register(["list_pets"]) expected2 = ["list_pets"] diff --git a/tests/api/openapi/test_end2end.py b/tests/api/openapi/test_end2end.py index 79d28d81..c4dbfcc5 100644 --- a/tests/api/openapi/test_end2end.py +++ b/tests/api/openapi/test_end2end.py @@ -701,14 +701,14 @@ class HTTPValidationError(BaseModel): @pytest.fixture def client(self, openapi_schema: dict[str, Any]) -> OpenAPI: - client = OpenAPI.create(json.dumps(openapi_schema)) + client = OpenAPI.create(openapi_json=json.dumps(openapi_schema)) return client def test_client(self, client: OpenAPI) -> None: assert client is not None assert isinstance(client, OpenAPI) - assert len(client.registered_funcs) == 4, client.registered_funcs + assert len(client._registered_funcs) == 4, client._registered_funcs expected_func_desc = { "create_item_items__post": "Create Item", @@ -718,7 +718,7 @@ def test_client(self, client: OpenAPI) -> None: } func_desc = { func.__name__: func._description # type: ignore[attr-defined] - for func in client.registered_funcs + for func in client._registered_funcs } assert func_desc == expected_func_desc @@ -880,6 +880,30 @@ def default(self, o: Any) -> Any: expected_tools, cls=JSONEncoder ) + def test_client_get_function(self, client: OpenAPI) -> None: + f = client.get_function("create_item_items__post") + assert f is not None + + def test_client_get_function_not_found(self, client: OpenAPI) -> None: + function_name = "create_item_items__post__not_found" + with pytest.raises( + expected_exception=ValueError, match=f"Function {function_name} not found" + ): + client.get_function(function_name) + + def test_set_function(self, client: OpenAPI) -> None: + def create_item_items__post() -> dict[str, Any]: + return {"item_id": 1} + + client.set_function(create_item_items__post.__name__, create_item_items__post) + + def test_get_functions(self, client: OpenAPI) -> None: + with pytest.raises( + expected_exception=DeprecationWarning, + match="Use function_names property instead of get_functions method", + ): + client.get_functions() + def test_register_for_execution( self, client: OpenAPI, azure_gpt35_turbo_16k_llm_config: dict[str, Any] ) -> None: diff --git a/tests/api/openapi/test_endpoint_with_body.py b/tests/api/openapi/test_endpoint_with_body.py index 930ba6e0..040ff121 100644 --- a/tests/api/openapi/test_endpoint_with_body.py +++ b/tests/api/openapi/test_endpoint_with_body.py @@ -5,7 +5,7 @@ from fastapi import FastAPI from pydantic import BaseModel -from fastagency.api.openapi.client import OpenAPI +from fastagency.api.openapi import OpenAPI def create_fastapi_app_with_body(host: str, port: int) -> FastAPI: diff --git a/tests/api/openapi/test_uppercase_endpoint_parameters.py b/tests/api/openapi/test_uppercase_endpoint_parameters.py index bfbe3eea..01593b7c 100644 --- a/tests/api/openapi/test_uppercase_endpoint_parameters.py +++ b/tests/api/openapi/test_uppercase_endpoint_parameters.py @@ -4,7 +4,7 @@ import pytest from autogen import ConversableAgent, UserProxyAgent -from fastagency.api.openapi.client import OpenAPI +from fastagency.api.openapi import OpenAPI from ...conftest import create_gify_fastapi_app @@ -150,7 +150,7 @@ def test_openapi_schema(openapi_schema: dict[str, Any]) -> None: @pytest.fixture def api(openapi_schema: dict[str, Any]) -> OpenAPI: # print(f"{openapi_schema=}") - client = OpenAPI.create(json.dumps(openapi_schema)) + client = OpenAPI.create(openapi_json=json.dumps(openapi_schema)) return client diff --git a/tests/api/openapi/test_whatsapp_api.py b/tests/api/openapi/test_whatsapp_api.py index 9d6d92c7..51812fb2 100644 --- a/tests/api/openapi/test_whatsapp_api.py +++ b/tests/api/openapi/test_whatsapp_api.py @@ -2,11 +2,11 @@ from autogen import UserProxyAgent -from fastagency.api.openapi.client import OpenAPI +from fastagency.api.openapi import OpenAPI from fastagency.api.openapi.security import APIKeyHeader -@patch("fastagency.api.openapi.client.requests.post") +@patch("fastagency.api.openapi.openapi.requests.post") def test_real_whatsapp_end2end( mock_post: MagicMock, ) -> None: diff --git a/tests/api/test_code_injection.py b/tests/api/test_code_injection.py new file mode 100644 index 00000000..f3925e43 --- /dev/null +++ b/tests/api/test_code_injection.py @@ -0,0 +1,19 @@ +from inspect import signature +from typing import Annotated, Any + +from fastagency.api.dependency_injection import inject_params + + +def test_dependency_injection() -> None: + def f( + city: Annotated[str, "City name"], + date: Annotated[str, "Date"], + user_id: Annotated[int, "User ID"], + ) -> Annotated[str, "Weather"]: + return f"User {user_id}: {city} {date}" + + ctx: dict[str, Any] = {"user_id": 123} + g = inject_params(f, ctx) + assert list(signature(g).parameters.keys()) == ["city", "date"] + kwargs: dict[str, Any] = {"city": "Zagreb", "date": "2021-01-01"} + assert g(**kwargs) == "User 123: Zagreb 2021-01-01" diff --git a/tests/docs_src/test_import.py b/tests/docs_src/test_import.py index b20cb687..3683df98 100644 --- a/tests/docs_src/test_import.py +++ b/tests/docs_src/test_import.py @@ -25,6 +25,7 @@ "docs_src.tutorials.giphy", "docs_src.tutorials.whatsapp", "docs_src.user_guide.runtimes.autogen.mesop", + "docs_src.user_guide.dependency_injection", } # Mock Environment variables for Mesop Auth testing diff --git a/tests/runtime/autogen/test_autogen.py b/tests/runtime/autogen/test_autogen.py index e39d7552..83af5afb 100644 --- a/tests/runtime/autogen/test_autogen.py +++ b/tests/runtime/autogen/test_autogen.py @@ -205,7 +205,7 @@ def test_register_api(openai_gpt4o_mini_llm_config: dict[str, Any]) -> None: ) assert json_path.exists() openapi_json = json_path.read_text() - client = OpenAPI.create(openapi_json) + client = OpenAPI.create(openapi_json=openapi_json) wf = AutoGenWorkflows() function_to_register = "update_item_items__item_id__ships__ship__put" From 76c0a0eb33d696ed8e8f63c9279700c4d72501ab Mon Sep 17 00:00:00 2001 From: Davor Runje Date: Mon, 2 Dec 2024 09:04:22 +0000 Subject: [PATCH 5/5] ag2 and agentchat runtimes added --- README.md | 2 +- docs/docs/en/example.md | 2 +- .../user-guide/runtimes/autogen/websurfer.md | 4 +- .../user-guide/runtimes/autogen/whatsapp.md | 8 +- .../docker/content/nginx.conf.template | 56 +---------- .../docker/content/run_fastagency.sh | 35 ++----- .../fastapi/my_fastagency_app/fly.toml | 27 ------ .../scripts/register_to_fly_io.sh | 4 +- .../docker/content/nginx.conf.template | 18 +--- .../docker/content/run_fastagency.sh | 28 ++---- .../mesop/my_fastagency_app/fly.toml | 14 --- .../scripts/register_to_fly_io.sh | 4 +- .../docker/content/nginx.conf.template | 94 +------------------ .../docker/content/run_fastagency.sh | 45 +++------ .../nats_n_fastapi/my_fastagency_app/fly.toml | 40 -------- .../scripts/register_to_fly_io.sh | 4 +- .../docker/content/nginx.conf.template | 56 +---------- .../docker/content/run_fastagency.sh | 35 ++----- .../fastapi/my_fastagency_app/fly.toml | 27 ------ .../scripts/register_to_fly_io.sh | 4 +- .../docker/content/nginx.conf.template | 18 +--- .../docker/content/run_fastagency.sh | 28 ++---- .../no_auth/mesop/my_fastagency_app/fly.toml | 14 --- .../scripts/register_to_fly_io.sh | 4 +- .../docker/content/nginx.conf.template | 94 +------------------ .../docker/content/run_fastagency.sh | 45 +++------ .../nats_n_fastapi/my_fastagency_app/fly.toml | 40 -------- .../scripts/register_to_fly_io.sh | 4 +- .../mesop/my_bank_app/my_bank_app/workflow.py | 2 +- .../dependency_injection/workflow.py | 2 +- fastagency/runtimes/ag2/__init__.py | 2 +- fastagency/runtimes/agentchat/__init__.py | 3 + tests/cli/test_discover.py | 2 +- tests/cli/test_mesop.py | 2 +- tests/docs_src/test_import.py | 2 +- tests/runtime/agentchat/__init__.py | 0 tests/runtime/agentchat/test_agentchat.py | 0 37 files changed, 107 insertions(+), 662 deletions(-) create mode 100644 fastagency/runtimes/agentchat/__init__.py create mode 100644 tests/runtime/agentchat/__init__.py create mode 100644 tests/runtime/agentchat/test_agentchat.py diff --git a/README.md b/README.md index f75c4c6d..b5950a8a 100644 --- a/README.md +++ b/README.md @@ -190,7 +190,7 @@ from typing import Any from autogen.agentchat import ConversableAgent from fastagency import UI -from fastagency.runtimes.autogen import AutoGenWorkflows +from fastagency.runtimes.ag2 import AutoGenWorkflows llm_config = { "config_list": [ diff --git a/docs/docs/en/example.md b/docs/docs/en/example.md index e2c92ebf..7ac8cf1e 100644 --- a/docs/docs/en/example.md +++ b/docs/docs/en/example.md @@ -83,7 +83,7 @@ from typing import Any from autogen.agentchat import ConversableAgent from fastagency import UI -from fastagency.runtimes.autogen import AutoGenWorkflows +from fastagency.runtimes.ag2 import AutoGenWorkflows llm_config = { "config_list": [ diff --git a/docs/docs/en/user-guide/runtimes/autogen/websurfer.md b/docs/docs/en/user-guide/runtimes/autogen/websurfer.md index a88e4417..cefa38e9 100644 --- a/docs/docs/en/user-guide/runtimes/autogen/websurfer.md +++ b/docs/docs/en/user-guide/runtimes/autogen/websurfer.md @@ -191,7 +191,7 @@ Once you run it, FastAgency automatically detects the appropriate app to execute ╰─────────────────────────╯ [INFO] Importing autogen.base.py - [INFO] Initializing FastAgency with workflows: and UI: + [INFO] Initializing FastAgency with workflows: and UI: [INFO] Initialized FastAgency: ╭──── Importable FastAgency app ────╮ @@ -226,7 +226,7 @@ Once you run it, FastAgency automatically detects the appropriate app to execute ╰────────────────────────╯ [INFO] Importing autogen.base.py - [INFO] Initializing FastAgency with workflows: and UI: + [INFO] Initializing FastAgency with workflows: and UI: [INFO] Initialized FastAgency: ╭─── Importable FastAgency app ────╮ diff --git a/docs/docs/en/user-guide/runtimes/autogen/whatsapp.md b/docs/docs/en/user-guide/runtimes/autogen/whatsapp.md index 505b5e9d..ace4dada 100644 --- a/docs/docs/en/user-guide/runtimes/autogen/whatsapp.md +++ b/docs/docs/en/user-guide/runtimes/autogen/whatsapp.md @@ -205,12 +205,12 @@ Once you run it, FastAgency automatically detects the appropriate app to execute 2024-11-06 12:05:31,512 [INFO] Patched Operation.function_name 2024-11-06 12:05:31,512 [INFO] Patched fastapi_code_generator.__main__.generate_code 2024-11-06 12:05:31,512 [INFO] Patched Parser.__apply_discriminator_type, - 2024-11-06 12:05:31,712 [INFO] Initializing FastAgency with workflows: and UI: + 2024-11-06 12:05:31,712 [INFO] Initializing FastAgency with workflows: and UI: 2024-11-06 12:05:31,712 [INFO] Initialized FastAgency: ╭───────────────────── Importable FastAgency app ──────────────────────╮ │ │ - │ from docs.docs_src.user_guide.runtimes.autogen.whatsapp import app │ + │ from docs.docs_src.user_guide.runtimes.ag2.whatsapp import app │ │ │ ╰──────────────────────────────────────────────────────────────────────╯ @@ -258,12 +258,12 @@ Once you run it, FastAgency automatically detects the appropriate app to execute 2024-11-06 12:01:56,374 [INFO] Patched Operation.function_name 2024-11-06 12:01:56,374 [INFO] Patched fastapi_code_generator.__main__.generate_code 2024-11-06 12:01:56,374 [INFO] Patched Parser.__apply_discriminator_type, - 2024-11-06 12:01:56,611 [INFO] Initializing FastAgency with workflows: and UI: + 2024-11-06 12:01:56,611 [INFO] Initializing FastAgency with workflows: and UI: 2024-11-06 12:01:56,611 [INFO] Initialized FastAgency: ╭──────────────────────── Importable FastAgency app ────────────────────────╮ │ │ - │ from docs.docs_src.user_guide.runtimes.autogen.whatsapp_tool import app │ + │ from docs.docs_src.user_guide.runtimes.ag2.whatsapp_tool import app │ │ │ ╰───────────────────────────────────────────────────────────────────────────╯ diff --git a/docs/docs_src/getting_started/basic_auth/fastapi/my_fastagency_app/docker/content/nginx.conf.template b/docs/docs_src/getting_started/basic_auth/fastapi/my_fastagency_app/docker/content/nginx.conf.template index 24a2cd5f..52347c6e 100644 --- a/docs/docs_src/getting_started/basic_auth/fastapi/my_fastagency_app/docker/content/nginx.conf.template +++ b/docs/docs_src/getting_started/basic_auth/fastapi/my_fastagency_app/docker/content/nginx.conf.template @@ -1,17 +1,3 @@ -upstream nats_fastapi_backend { - # Enable sticky sessions with IP hash - ip_hash; - - -} - -upstream fastapi_backend { - # Enable sticky sessions with IP hash - ip_hash; - - -} - upstream mesop_backend { # Enable sticky sessions with IP hash ip_hash; @@ -32,47 +18,9 @@ map $fly_machine_id $sticky_action { default "replay"; # Cookie exists but doesn't match - need to replay } -# Fastapi server block -server { - listen $FASTAPI_PORT; - server_name localhost; - - # Security headers - add_header X-Frame-Options "SAMEORIGIN"; - add_header X-Content-Type-Options "nosniff"; - add_header X-XSS-Protection "1; mode=block"; - - location / { - # Handle cookie setting - if ($sticky_action = "set_cookie") { - add_header Set-Cookie "fly-machine-id=$FLY_MACHINE_ID; Max-Age=518400; Path=/"; - } - - # Handle replay - if ($sticky_action = "replay") { - add_header Fly-Replay "instance=$fly_machine_id"; - return 307; - } - - proxy_pass http://fastapi_backend; - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_redirect off; - proxy_buffering off; - - # WSGI support - proxy_set_header X-Forwarded-Host $server_name; - - # WebSocket support - proxy_http_version 1.1; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - } -} -# Mesop server block +# Main server block server { - listen $MESOP_PORT; + listen $SERVICE_PORT; server_name localhost; # Security headers diff --git a/docs/docs_src/getting_started/basic_auth/fastapi/my_fastagency_app/docker/content/run_fastagency.sh b/docs/docs_src/getting_started/basic_auth/fastapi/my_fastagency_app/docker/content/run_fastagency.sh index 77d9d2a9..548457f6 100755 --- a/docs/docs_src/getting_started/basic_auth/fastapi/my_fastagency_app/docker/content/run_fastagency.sh +++ b/docs/docs_src/getting_started/basic_auth/fastapi/my_fastagency_app/docker/content/run_fastagency.sh @@ -1,9 +1,13 @@ #!/bin/bash # Accept env variable for PORT -export NATS_FASTAPI_PORT=${NATS_FASTAPI_PORT:-8000} -export FASTAPI_PORT=${FASTAPI_PORT:-8008} + + +FASTAPI_PORT=${FASTAPI_PORT:-8008} + + export MESOP_PORT=${MESOP_PORT:-8888} +export SERVICE_PORT=$MESOP_PORT # Default number of workers if not set WORKERS=${WORKERS:-1} @@ -16,23 +20,10 @@ echo "Fly machine ID: $FLY_MACHINE_ID" # Generate nginx config for ((i=1; i<$WORKERS+1; i++)) do - PORT=$((MESOP_PORT + i)) - sed -i "19i\ server 127.0.0.1:$PORT;" nginx.conf.template -done - -for ((i=1; i<$WORKERS+1; i++)) -do - PORT=$((FASTAPI_PORT + i)) - sed -i "12i\ server 127.0.0.1:$PORT;" nginx.conf.template -done - -for ((i=1; i<$WORKERS+1; i++)) -do - PORT=$((NATS_FASTAPI_PORT + i)) + PORT=$((SERVICE_PORT + i)) sed -i "5i\ server 127.0.0.1:$PORT;" nginx.conf.template done - -envsubst '${NATS_FASTAPI_PORT},${FASTAPI_PORT},${MESOP_PORT},${FLY_MACHINE_ID}' < nginx.conf.template >/etc/nginx/conf.d/default.conf +envsubst '${SERVICE_PORT},${FLY_MACHINE_ID}' < nginx.conf.template >/etc/nginx/conf.d/default.conf echo "Nginx config:" cat /etc/nginx/conf.d/default.conf @@ -41,20 +32,14 @@ nginx -g "daemon off;" & # Run uvicorn server -# Start multiple single-worker uvicorn instances on consecutive ports -for ((i=1; i<$WORKERS+1; i++)) -do - PORT=$((FASTAPI_PORT + i)) - echo "Starting fastapi uvicorn on port $PORT" - uvicorn my_fastagency_app.deployment.main_1_fastapi:app --workers=1 --host 0.0.0.0 --port $PORT > /dev/stdout 2>&1 & -done +uvicorn my_fastagency_app.deployment.main_1_fastapi:app --host 0.0.0.0 --port $FASTAPI_PORT > /dev/stdout 2>&1 & # Run gunicorn server # Start multiple single-worker gunicorn instances on consecutive ports for ((i=1; i<$WORKERS+1; i++)) do - PORT=$((MESOP_PORT + i)) + PORT=$((SERVICE_PORT + i)) echo "Starting gunicorn on port $PORT" gunicorn --workers=1 my_fastagency_app.deployment.main_2_mesop:app --bind 0.0.0.0:$PORT > /dev/stdout 2>&1 & done diff --git a/docs/docs_src/getting_started/basic_auth/fastapi/my_fastagency_app/fly.toml b/docs/docs_src/getting_started/basic_auth/fastapi/my_fastagency_app/fly.toml index d19237b6..742cfd80 100644 --- a/docs/docs_src/getting_started/basic_auth/fastapi/my_fastagency_app/fly.toml +++ b/docs/docs_src/getting_started/basic_auth/fastapi/my_fastagency_app/fly.toml @@ -21,30 +21,3 @@ primary_region = 'ams' memory = '1gb' cpu_kind = 'shared' cpus = 1 - -[[services]] - http_checks = [] - internal_port = 8008 - processes = ["app"] - protocol = "tcp" - script_checks = [] - - [services.concurrency] - type = "connections" - - [[services.ports]] - handlers = ["tls", "http"] - port = 8008 -[[services]] - http_checks = [] - internal_port = 8888 - processes = ["app"] - protocol = "tcp" - script_checks = [] - - [services.concurrency] - type = "connections" - - [[services.ports]] - handlers = ["tls", "http"] - port = 8888 diff --git a/docs/docs_src/getting_started/basic_auth/fastapi/my_fastagency_app/scripts/register_to_fly_io.sh b/docs/docs_src/getting_started/basic_auth/fastapi/my_fastagency_app/scripts/register_to_fly_io.sh index bfd9711a..a49aac06 100755 --- a/docs/docs_src/getting_started/basic_auth/fastapi/my_fastagency_app/scripts/register_to_fly_io.sh +++ b/docs/docs_src/getting_started/basic_auth/fastapi/my_fastagency_app/scripts/register_to_fly_io.sh @@ -17,7 +17,7 @@ else echo -e "\033[0;32mAlready logged into fly.io\033[0m" fi -export FLY_APP_NAME=$(grep "^app = " fly.toml | awk -F"'" '{print $2}') +export FLY_APP_NAME=my-fastagency-app echo -e "\033[0;32mRegistering app name in fly.io\033[0m" if flyctl apps create $FLY_APP_NAME; then @@ -27,6 +27,6 @@ if flyctl apps create $FLY_APP_NAME; then cat registered_app_domain.txt else echo -e "\033[1;31mError: App name is not available.\033[0m" - echo -e "\033[1;31mPlease change the app name in fly.toml and run this script again.\033[0m" + echo -e "\033[1;31mPlease change the app name in fly.toml and scripts/register_to_fly_io.sh and run this script again.\033[0m" exit 1 fi diff --git a/docs/docs_src/getting_started/basic_auth/mesop/my_fastagency_app/docker/content/nginx.conf.template b/docs/docs_src/getting_started/basic_auth/mesop/my_fastagency_app/docker/content/nginx.conf.template index 626bce1c..52347c6e 100644 --- a/docs/docs_src/getting_started/basic_auth/mesop/my_fastagency_app/docker/content/nginx.conf.template +++ b/docs/docs_src/getting_started/basic_auth/mesop/my_fastagency_app/docker/content/nginx.conf.template @@ -1,17 +1,3 @@ -upstream nats_fastapi_backend { - # Enable sticky sessions with IP hash - ip_hash; - - -} - -upstream fastapi_backend { - # Enable sticky sessions with IP hash - ip_hash; - - -} - upstream mesop_backend { # Enable sticky sessions with IP hash ip_hash; @@ -32,9 +18,9 @@ map $fly_machine_id $sticky_action { default "replay"; # Cookie exists but doesn't match - need to replay } -# Mesop server block +# Main server block server { - listen $MESOP_PORT; + listen $SERVICE_PORT; server_name localhost; # Security headers diff --git a/docs/docs_src/getting_started/basic_auth/mesop/my_fastagency_app/docker/content/run_fastagency.sh b/docs/docs_src/getting_started/basic_auth/mesop/my_fastagency_app/docker/content/run_fastagency.sh index a6cb4cf0..55aa17d3 100755 --- a/docs/docs_src/getting_started/basic_auth/mesop/my_fastagency_app/docker/content/run_fastagency.sh +++ b/docs/docs_src/getting_started/basic_auth/mesop/my_fastagency_app/docker/content/run_fastagency.sh @@ -1,9 +1,11 @@ #!/bin/bash # Accept env variable for PORT -export NATS_FASTAPI_PORT=${NATS_FASTAPI_PORT:-8000} -export FASTAPI_PORT=${FASTAPI_PORT:-8008} + + + export MESOP_PORT=${MESOP_PORT:-8888} +export SERVICE_PORT=$MESOP_PORT # Default number of workers if not set WORKERS=${WORKERS:-1} @@ -16,23 +18,10 @@ echo "Fly machine ID: $FLY_MACHINE_ID" # Generate nginx config for ((i=1; i<$WORKERS+1; i++)) do - PORT=$((MESOP_PORT + i)) - sed -i "19i\ server 127.0.0.1:$PORT;" nginx.conf.template -done - -for ((i=1; i<$WORKERS+1; i++)) -do - PORT=$((FASTAPI_PORT + i)) - sed -i "12i\ server 127.0.0.1:$PORT;" nginx.conf.template -done - -for ((i=1; i<$WORKERS+1; i++)) -do - PORT=$((NATS_FASTAPI_PORT + i)) + PORT=$((SERVICE_PORT + i)) sed -i "5i\ server 127.0.0.1:$PORT;" nginx.conf.template done - -envsubst '${NATS_FASTAPI_PORT},${FASTAPI_PORT},${MESOP_PORT},${FLY_MACHINE_ID}' < nginx.conf.template >/etc/nginx/conf.d/default.conf +envsubst '${SERVICE_PORT},${FLY_MACHINE_ID}' < nginx.conf.template >/etc/nginx/conf.d/default.conf echo "Nginx config:" cat /etc/nginx/conf.d/default.conf @@ -40,12 +29,15 @@ cat /etc/nginx/conf.d/default.conf nginx -g "daemon off;" & +# Run uvicorn server +uvicorn my_fastagency_app.deployment.main_:app --host 0.0.0.0 --port $FASTAPI_PORT > /dev/stdout 2>&1 & + # Run gunicorn server # Start multiple single-worker gunicorn instances on consecutive ports for ((i=1; i<$WORKERS+1; i++)) do - PORT=$((MESOP_PORT + i)) + PORT=$((SERVICE_PORT + i)) echo "Starting gunicorn on port $PORT" gunicorn --workers=1 my_fastagency_app.deployment.main:app --bind 0.0.0.0:$PORT > /dev/stdout 2>&1 & done diff --git a/docs/docs_src/getting_started/basic_auth/mesop/my_fastagency_app/fly.toml b/docs/docs_src/getting_started/basic_auth/mesop/my_fastagency_app/fly.toml index ed002a65..742cfd80 100644 --- a/docs/docs_src/getting_started/basic_auth/mesop/my_fastagency_app/fly.toml +++ b/docs/docs_src/getting_started/basic_auth/mesop/my_fastagency_app/fly.toml @@ -21,17 +21,3 @@ primary_region = 'ams' memory = '1gb' cpu_kind = 'shared' cpus = 1 - -[[services]] - http_checks = [] - internal_port = 8888 - processes = ["app"] - protocol = "tcp" - script_checks = [] - - [services.concurrency] - type = "connections" - - [[services.ports]] - handlers = ["tls", "http"] - port = 8888 diff --git a/docs/docs_src/getting_started/basic_auth/mesop/my_fastagency_app/scripts/register_to_fly_io.sh b/docs/docs_src/getting_started/basic_auth/mesop/my_fastagency_app/scripts/register_to_fly_io.sh index bfd9711a..a49aac06 100755 --- a/docs/docs_src/getting_started/basic_auth/mesop/my_fastagency_app/scripts/register_to_fly_io.sh +++ b/docs/docs_src/getting_started/basic_auth/mesop/my_fastagency_app/scripts/register_to_fly_io.sh @@ -17,7 +17,7 @@ else echo -e "\033[0;32mAlready logged into fly.io\033[0m" fi -export FLY_APP_NAME=$(grep "^app = " fly.toml | awk -F"'" '{print $2}') +export FLY_APP_NAME=my-fastagency-app echo -e "\033[0;32mRegistering app name in fly.io\033[0m" if flyctl apps create $FLY_APP_NAME; then @@ -27,6 +27,6 @@ if flyctl apps create $FLY_APP_NAME; then cat registered_app_domain.txt else echo -e "\033[1;31mError: App name is not available.\033[0m" - echo -e "\033[1;31mPlease change the app name in fly.toml and run this script again.\033[0m" + echo -e "\033[1;31mPlease change the app name in fly.toml and scripts/register_to_fly_io.sh and run this script again.\033[0m" exit 1 fi diff --git a/docs/docs_src/getting_started/basic_auth/nats_n_fastapi/my_fastagency_app/docker/content/nginx.conf.template b/docs/docs_src/getting_started/basic_auth/nats_n_fastapi/my_fastagency_app/docker/content/nginx.conf.template index 3e295c7b..52347c6e 100644 --- a/docs/docs_src/getting_started/basic_auth/nats_n_fastapi/my_fastagency_app/docker/content/nginx.conf.template +++ b/docs/docs_src/getting_started/basic_auth/nats_n_fastapi/my_fastagency_app/docker/content/nginx.conf.template @@ -1,17 +1,3 @@ -upstream nats_fastapi_backend { - # Enable sticky sessions with IP hash - ip_hash; - - -} - -upstream fastapi_backend { - # Enable sticky sessions with IP hash - ip_hash; - - -} - upstream mesop_backend { # Enable sticky sessions with IP hash ip_hash; @@ -32,85 +18,9 @@ map $fly_machine_id $sticky_action { default "replay"; # Cookie exists but doesn't match - need to replay } -# Nats fastapi server block -server { - listen $NATS_FASTAPI_PORT; - server_name localhost; - - # Security headers - add_header X-Frame-Options "SAMEORIGIN"; - add_header X-Content-Type-Options "nosniff"; - add_header X-XSS-Protection "1; mode=block"; - - location / { - # Handle cookie setting - if ($sticky_action = "set_cookie") { - add_header Set-Cookie "fly-machine-id=$FLY_MACHINE_ID; Max-Age=518400; Path=/"; - } - - # Handle replay - if ($sticky_action = "replay") { - add_header Fly-Replay "instance=$fly_machine_id"; - return 307; - } - - proxy_pass http://nats_fastapi_backend; - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_redirect off; - proxy_buffering off; - - # WSGI support - proxy_set_header X-Forwarded-Host $server_name; - - # WebSocket support - proxy_http_version 1.1; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - } -} -# Fastapi server block -server { - listen $FASTAPI_PORT; - server_name localhost; - - # Security headers - add_header X-Frame-Options "SAMEORIGIN"; - add_header X-Content-Type-Options "nosniff"; - add_header X-XSS-Protection "1; mode=block"; - - location / { - # Handle cookie setting - if ($sticky_action = "set_cookie") { - add_header Set-Cookie "fly-machine-id=$FLY_MACHINE_ID; Max-Age=518400; Path=/"; - } - - # Handle replay - if ($sticky_action = "replay") { - add_header Fly-Replay "instance=$fly_machine_id"; - return 307; - } - - proxy_pass http://fastapi_backend; - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_redirect off; - proxy_buffering off; - - # WSGI support - proxy_set_header X-Forwarded-Host $server_name; - - # WebSocket support - proxy_http_version 1.1; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - } -} -# Mesop server block +# Main server block server { - listen $MESOP_PORT; + listen $SERVICE_PORT; server_name localhost; # Security headers diff --git a/docs/docs_src/getting_started/basic_auth/nats_n_fastapi/my_fastagency_app/docker/content/run_fastagency.sh b/docs/docs_src/getting_started/basic_auth/nats_n_fastapi/my_fastagency_app/docker/content/run_fastagency.sh index 0ba28573..1db12dbb 100755 --- a/docs/docs_src/getting_started/basic_auth/nats_n_fastapi/my_fastagency_app/docker/content/run_fastagency.sh +++ b/docs/docs_src/getting_started/basic_auth/nats_n_fastapi/my_fastagency_app/docker/content/run_fastagency.sh @@ -1,9 +1,15 @@ #!/bin/bash # Accept env variable for PORT -export NATS_FASTAPI_PORT=${NATS_FASTAPI_PORT:-8000} -export FASTAPI_PORT=${FASTAPI_PORT:-8008} + +NATS_FASTAPI_PORT=${NATS_FASTAPI_PORT:-8000} + + +FASTAPI_PORT=${FASTAPI_PORT:-8008} + + export MESOP_PORT=${MESOP_PORT:-8888} +export SERVICE_PORT=$MESOP_PORT # Default number of workers if not set WORKERS=${WORKERS:-1} @@ -16,23 +22,10 @@ echo "Fly machine ID: $FLY_MACHINE_ID" # Generate nginx config for ((i=1; i<$WORKERS+1; i++)) do - PORT=$((MESOP_PORT + i)) - sed -i "19i\ server 127.0.0.1:$PORT;" nginx.conf.template -done - -for ((i=1; i<$WORKERS+1; i++)) -do - PORT=$((FASTAPI_PORT + i)) - sed -i "12i\ server 127.0.0.1:$PORT;" nginx.conf.template -done - -for ((i=1; i<$WORKERS+1; i++)) -do - PORT=$((NATS_FASTAPI_PORT + i)) + PORT=$((SERVICE_PORT + i)) sed -i "5i\ server 127.0.0.1:$PORT;" nginx.conf.template done - -envsubst '${NATS_FASTAPI_PORT},${FASTAPI_PORT},${MESOP_PORT},${FLY_MACHINE_ID}' < nginx.conf.template >/etc/nginx/conf.d/default.conf +envsubst '${SERVICE_PORT},${FLY_MACHINE_ID}' < nginx.conf.template >/etc/nginx/conf.d/default.conf echo "Nginx config:" cat /etc/nginx/conf.d/default.conf @@ -40,30 +33,18 @@ cat /etc/nginx/conf.d/default.conf nginx -g "daemon off;" & # Run nats uvicorn server -# Start multiple single-worker uvicorn instances on consecutive ports -for ((i=1; i<$WORKERS+1; i++)) -do - PORT=$((NATS_FASTAPI_PORT + i)) - echo "Starting nats fastapi uvicorn on port $PORT" - uvicorn my_fastagency_app.deployment.main_1_nats:app --workers=1 --host 0.0.0.0 --port $PORT > /dev/stdout 2>&1 & -done +uvicorn my_fastagency_app.deployment.main_1_nats:app --host 0.0.0.0 --port $NATS_FASTAPI_PORT > /dev/stdout 2>&1 & # Run uvicorn server -# Start multiple single-worker uvicorn instances on consecutive ports -for ((i=1; i<$WORKERS+1; i++)) -do - PORT=$((FASTAPI_PORT + i)) - echo "Starting fastapi uvicorn on port $PORT" - uvicorn my_fastagency_app.deployment.main_2_fastapi:app --workers=1 --host 0.0.0.0 --port $PORT > /dev/stdout 2>&1 & -done +uvicorn my_fastagency_app.deployment.main_2_fastapi:app --host 0.0.0.0 --port $FASTAPI_PORT > /dev/stdout 2>&1 & # Run gunicorn server # Start multiple single-worker gunicorn instances on consecutive ports for ((i=1; i<$WORKERS+1; i++)) do - PORT=$((MESOP_PORT + i)) + PORT=$((SERVICE_PORT + i)) echo "Starting gunicorn on port $PORT" gunicorn --workers=1 my_fastagency_app.deployment.main_3_mesop:app --bind 0.0.0.0:$PORT > /dev/stdout 2>&1 & done diff --git a/docs/docs_src/getting_started/basic_auth/nats_n_fastapi/my_fastagency_app/fly.toml b/docs/docs_src/getting_started/basic_auth/nats_n_fastapi/my_fastagency_app/fly.toml index ef085a35..742cfd80 100644 --- a/docs/docs_src/getting_started/basic_auth/nats_n_fastapi/my_fastagency_app/fly.toml +++ b/docs/docs_src/getting_started/basic_auth/nats_n_fastapi/my_fastagency_app/fly.toml @@ -21,43 +21,3 @@ primary_region = 'ams' memory = '1gb' cpu_kind = 'shared' cpus = 1 - -[[services]] - http_checks = [] - internal_port = 8000 - processes = ["app"] - protocol = "tcp" - script_checks = [] - - [services.concurrency] - type = "connections" - - [[services.ports]] - handlers = ["tls", "http"] - port = 8000 -[[services]] - http_checks = [] - internal_port = 8008 - processes = ["app"] - protocol = "tcp" - script_checks = [] - - [services.concurrency] - type = "connections" - - [[services.ports]] - handlers = ["tls", "http"] - port = 8008 -[[services]] - http_checks = [] - internal_port = 8888 - processes = ["app"] - protocol = "tcp" - script_checks = [] - - [services.concurrency] - type = "connections" - - [[services.ports]] - handlers = ["tls", "http"] - port = 8888 diff --git a/docs/docs_src/getting_started/basic_auth/nats_n_fastapi/my_fastagency_app/scripts/register_to_fly_io.sh b/docs/docs_src/getting_started/basic_auth/nats_n_fastapi/my_fastagency_app/scripts/register_to_fly_io.sh index bfd9711a..a49aac06 100755 --- a/docs/docs_src/getting_started/basic_auth/nats_n_fastapi/my_fastagency_app/scripts/register_to_fly_io.sh +++ b/docs/docs_src/getting_started/basic_auth/nats_n_fastapi/my_fastagency_app/scripts/register_to_fly_io.sh @@ -17,7 +17,7 @@ else echo -e "\033[0;32mAlready logged into fly.io\033[0m" fi -export FLY_APP_NAME=$(grep "^app = " fly.toml | awk -F"'" '{print $2}') +export FLY_APP_NAME=my-fastagency-app echo -e "\033[0;32mRegistering app name in fly.io\033[0m" if flyctl apps create $FLY_APP_NAME; then @@ -27,6 +27,6 @@ if flyctl apps create $FLY_APP_NAME; then cat registered_app_domain.txt else echo -e "\033[1;31mError: App name is not available.\033[0m" - echo -e "\033[1;31mPlease change the app name in fly.toml and run this script again.\033[0m" + echo -e "\033[1;31mPlease change the app name in fly.toml and scripts/register_to_fly_io.sh and run this script again.\033[0m" exit 1 fi diff --git a/docs/docs_src/getting_started/no_auth/fastapi/my_fastagency_app/docker/content/nginx.conf.template b/docs/docs_src/getting_started/no_auth/fastapi/my_fastagency_app/docker/content/nginx.conf.template index 24a2cd5f..52347c6e 100644 --- a/docs/docs_src/getting_started/no_auth/fastapi/my_fastagency_app/docker/content/nginx.conf.template +++ b/docs/docs_src/getting_started/no_auth/fastapi/my_fastagency_app/docker/content/nginx.conf.template @@ -1,17 +1,3 @@ -upstream nats_fastapi_backend { - # Enable sticky sessions with IP hash - ip_hash; - - -} - -upstream fastapi_backend { - # Enable sticky sessions with IP hash - ip_hash; - - -} - upstream mesop_backend { # Enable sticky sessions with IP hash ip_hash; @@ -32,47 +18,9 @@ map $fly_machine_id $sticky_action { default "replay"; # Cookie exists but doesn't match - need to replay } -# Fastapi server block -server { - listen $FASTAPI_PORT; - server_name localhost; - - # Security headers - add_header X-Frame-Options "SAMEORIGIN"; - add_header X-Content-Type-Options "nosniff"; - add_header X-XSS-Protection "1; mode=block"; - - location / { - # Handle cookie setting - if ($sticky_action = "set_cookie") { - add_header Set-Cookie "fly-machine-id=$FLY_MACHINE_ID; Max-Age=518400; Path=/"; - } - - # Handle replay - if ($sticky_action = "replay") { - add_header Fly-Replay "instance=$fly_machine_id"; - return 307; - } - - proxy_pass http://fastapi_backend; - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_redirect off; - proxy_buffering off; - - # WSGI support - proxy_set_header X-Forwarded-Host $server_name; - - # WebSocket support - proxy_http_version 1.1; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - } -} -# Mesop server block +# Main server block server { - listen $MESOP_PORT; + listen $SERVICE_PORT; server_name localhost; # Security headers diff --git a/docs/docs_src/getting_started/no_auth/fastapi/my_fastagency_app/docker/content/run_fastagency.sh b/docs/docs_src/getting_started/no_auth/fastapi/my_fastagency_app/docker/content/run_fastagency.sh index 77d9d2a9..548457f6 100755 --- a/docs/docs_src/getting_started/no_auth/fastapi/my_fastagency_app/docker/content/run_fastagency.sh +++ b/docs/docs_src/getting_started/no_auth/fastapi/my_fastagency_app/docker/content/run_fastagency.sh @@ -1,9 +1,13 @@ #!/bin/bash # Accept env variable for PORT -export NATS_FASTAPI_PORT=${NATS_FASTAPI_PORT:-8000} -export FASTAPI_PORT=${FASTAPI_PORT:-8008} + + +FASTAPI_PORT=${FASTAPI_PORT:-8008} + + export MESOP_PORT=${MESOP_PORT:-8888} +export SERVICE_PORT=$MESOP_PORT # Default number of workers if not set WORKERS=${WORKERS:-1} @@ -16,23 +20,10 @@ echo "Fly machine ID: $FLY_MACHINE_ID" # Generate nginx config for ((i=1; i<$WORKERS+1; i++)) do - PORT=$((MESOP_PORT + i)) - sed -i "19i\ server 127.0.0.1:$PORT;" nginx.conf.template -done - -for ((i=1; i<$WORKERS+1; i++)) -do - PORT=$((FASTAPI_PORT + i)) - sed -i "12i\ server 127.0.0.1:$PORT;" nginx.conf.template -done - -for ((i=1; i<$WORKERS+1; i++)) -do - PORT=$((NATS_FASTAPI_PORT + i)) + PORT=$((SERVICE_PORT + i)) sed -i "5i\ server 127.0.0.1:$PORT;" nginx.conf.template done - -envsubst '${NATS_FASTAPI_PORT},${FASTAPI_PORT},${MESOP_PORT},${FLY_MACHINE_ID}' < nginx.conf.template >/etc/nginx/conf.d/default.conf +envsubst '${SERVICE_PORT},${FLY_MACHINE_ID}' < nginx.conf.template >/etc/nginx/conf.d/default.conf echo "Nginx config:" cat /etc/nginx/conf.d/default.conf @@ -41,20 +32,14 @@ nginx -g "daemon off;" & # Run uvicorn server -# Start multiple single-worker uvicorn instances on consecutive ports -for ((i=1; i<$WORKERS+1; i++)) -do - PORT=$((FASTAPI_PORT + i)) - echo "Starting fastapi uvicorn on port $PORT" - uvicorn my_fastagency_app.deployment.main_1_fastapi:app --workers=1 --host 0.0.0.0 --port $PORT > /dev/stdout 2>&1 & -done +uvicorn my_fastagency_app.deployment.main_1_fastapi:app --host 0.0.0.0 --port $FASTAPI_PORT > /dev/stdout 2>&1 & # Run gunicorn server # Start multiple single-worker gunicorn instances on consecutive ports for ((i=1; i<$WORKERS+1; i++)) do - PORT=$((MESOP_PORT + i)) + PORT=$((SERVICE_PORT + i)) echo "Starting gunicorn on port $PORT" gunicorn --workers=1 my_fastagency_app.deployment.main_2_mesop:app --bind 0.0.0.0:$PORT > /dev/stdout 2>&1 & done diff --git a/docs/docs_src/getting_started/no_auth/fastapi/my_fastagency_app/fly.toml b/docs/docs_src/getting_started/no_auth/fastapi/my_fastagency_app/fly.toml index d19237b6..742cfd80 100644 --- a/docs/docs_src/getting_started/no_auth/fastapi/my_fastagency_app/fly.toml +++ b/docs/docs_src/getting_started/no_auth/fastapi/my_fastagency_app/fly.toml @@ -21,30 +21,3 @@ primary_region = 'ams' memory = '1gb' cpu_kind = 'shared' cpus = 1 - -[[services]] - http_checks = [] - internal_port = 8008 - processes = ["app"] - protocol = "tcp" - script_checks = [] - - [services.concurrency] - type = "connections" - - [[services.ports]] - handlers = ["tls", "http"] - port = 8008 -[[services]] - http_checks = [] - internal_port = 8888 - processes = ["app"] - protocol = "tcp" - script_checks = [] - - [services.concurrency] - type = "connections" - - [[services.ports]] - handlers = ["tls", "http"] - port = 8888 diff --git a/docs/docs_src/getting_started/no_auth/fastapi/my_fastagency_app/scripts/register_to_fly_io.sh b/docs/docs_src/getting_started/no_auth/fastapi/my_fastagency_app/scripts/register_to_fly_io.sh index bfd9711a..a49aac06 100755 --- a/docs/docs_src/getting_started/no_auth/fastapi/my_fastagency_app/scripts/register_to_fly_io.sh +++ b/docs/docs_src/getting_started/no_auth/fastapi/my_fastagency_app/scripts/register_to_fly_io.sh @@ -17,7 +17,7 @@ else echo -e "\033[0;32mAlready logged into fly.io\033[0m" fi -export FLY_APP_NAME=$(grep "^app = " fly.toml | awk -F"'" '{print $2}') +export FLY_APP_NAME=my-fastagency-app echo -e "\033[0;32mRegistering app name in fly.io\033[0m" if flyctl apps create $FLY_APP_NAME; then @@ -27,6 +27,6 @@ if flyctl apps create $FLY_APP_NAME; then cat registered_app_domain.txt else echo -e "\033[1;31mError: App name is not available.\033[0m" - echo -e "\033[1;31mPlease change the app name in fly.toml and run this script again.\033[0m" + echo -e "\033[1;31mPlease change the app name in fly.toml and scripts/register_to_fly_io.sh and run this script again.\033[0m" exit 1 fi diff --git a/docs/docs_src/getting_started/no_auth/mesop/my_fastagency_app/docker/content/nginx.conf.template b/docs/docs_src/getting_started/no_auth/mesop/my_fastagency_app/docker/content/nginx.conf.template index 626bce1c..52347c6e 100644 --- a/docs/docs_src/getting_started/no_auth/mesop/my_fastagency_app/docker/content/nginx.conf.template +++ b/docs/docs_src/getting_started/no_auth/mesop/my_fastagency_app/docker/content/nginx.conf.template @@ -1,17 +1,3 @@ -upstream nats_fastapi_backend { - # Enable sticky sessions with IP hash - ip_hash; - - -} - -upstream fastapi_backend { - # Enable sticky sessions with IP hash - ip_hash; - - -} - upstream mesop_backend { # Enable sticky sessions with IP hash ip_hash; @@ -32,9 +18,9 @@ map $fly_machine_id $sticky_action { default "replay"; # Cookie exists but doesn't match - need to replay } -# Mesop server block +# Main server block server { - listen $MESOP_PORT; + listen $SERVICE_PORT; server_name localhost; # Security headers diff --git a/docs/docs_src/getting_started/no_auth/mesop/my_fastagency_app/docker/content/run_fastagency.sh b/docs/docs_src/getting_started/no_auth/mesop/my_fastagency_app/docker/content/run_fastagency.sh index a6cb4cf0..55aa17d3 100755 --- a/docs/docs_src/getting_started/no_auth/mesop/my_fastagency_app/docker/content/run_fastagency.sh +++ b/docs/docs_src/getting_started/no_auth/mesop/my_fastagency_app/docker/content/run_fastagency.sh @@ -1,9 +1,11 @@ #!/bin/bash # Accept env variable for PORT -export NATS_FASTAPI_PORT=${NATS_FASTAPI_PORT:-8000} -export FASTAPI_PORT=${FASTAPI_PORT:-8008} + + + export MESOP_PORT=${MESOP_PORT:-8888} +export SERVICE_PORT=$MESOP_PORT # Default number of workers if not set WORKERS=${WORKERS:-1} @@ -16,23 +18,10 @@ echo "Fly machine ID: $FLY_MACHINE_ID" # Generate nginx config for ((i=1; i<$WORKERS+1; i++)) do - PORT=$((MESOP_PORT + i)) - sed -i "19i\ server 127.0.0.1:$PORT;" nginx.conf.template -done - -for ((i=1; i<$WORKERS+1; i++)) -do - PORT=$((FASTAPI_PORT + i)) - sed -i "12i\ server 127.0.0.1:$PORT;" nginx.conf.template -done - -for ((i=1; i<$WORKERS+1; i++)) -do - PORT=$((NATS_FASTAPI_PORT + i)) + PORT=$((SERVICE_PORT + i)) sed -i "5i\ server 127.0.0.1:$PORT;" nginx.conf.template done - -envsubst '${NATS_FASTAPI_PORT},${FASTAPI_PORT},${MESOP_PORT},${FLY_MACHINE_ID}' < nginx.conf.template >/etc/nginx/conf.d/default.conf +envsubst '${SERVICE_PORT},${FLY_MACHINE_ID}' < nginx.conf.template >/etc/nginx/conf.d/default.conf echo "Nginx config:" cat /etc/nginx/conf.d/default.conf @@ -40,12 +29,15 @@ cat /etc/nginx/conf.d/default.conf nginx -g "daemon off;" & +# Run uvicorn server +uvicorn my_fastagency_app.deployment.main_:app --host 0.0.0.0 --port $FASTAPI_PORT > /dev/stdout 2>&1 & + # Run gunicorn server # Start multiple single-worker gunicorn instances on consecutive ports for ((i=1; i<$WORKERS+1; i++)) do - PORT=$((MESOP_PORT + i)) + PORT=$((SERVICE_PORT + i)) echo "Starting gunicorn on port $PORT" gunicorn --workers=1 my_fastagency_app.deployment.main:app --bind 0.0.0.0:$PORT > /dev/stdout 2>&1 & done diff --git a/docs/docs_src/getting_started/no_auth/mesop/my_fastagency_app/fly.toml b/docs/docs_src/getting_started/no_auth/mesop/my_fastagency_app/fly.toml index ed002a65..742cfd80 100644 --- a/docs/docs_src/getting_started/no_auth/mesop/my_fastagency_app/fly.toml +++ b/docs/docs_src/getting_started/no_auth/mesop/my_fastagency_app/fly.toml @@ -21,17 +21,3 @@ primary_region = 'ams' memory = '1gb' cpu_kind = 'shared' cpus = 1 - -[[services]] - http_checks = [] - internal_port = 8888 - processes = ["app"] - protocol = "tcp" - script_checks = [] - - [services.concurrency] - type = "connections" - - [[services.ports]] - handlers = ["tls", "http"] - port = 8888 diff --git a/docs/docs_src/getting_started/no_auth/mesop/my_fastagency_app/scripts/register_to_fly_io.sh b/docs/docs_src/getting_started/no_auth/mesop/my_fastagency_app/scripts/register_to_fly_io.sh index bfd9711a..a49aac06 100755 --- a/docs/docs_src/getting_started/no_auth/mesop/my_fastagency_app/scripts/register_to_fly_io.sh +++ b/docs/docs_src/getting_started/no_auth/mesop/my_fastagency_app/scripts/register_to_fly_io.sh @@ -17,7 +17,7 @@ else echo -e "\033[0;32mAlready logged into fly.io\033[0m" fi -export FLY_APP_NAME=$(grep "^app = " fly.toml | awk -F"'" '{print $2}') +export FLY_APP_NAME=my-fastagency-app echo -e "\033[0;32mRegistering app name in fly.io\033[0m" if flyctl apps create $FLY_APP_NAME; then @@ -27,6 +27,6 @@ if flyctl apps create $FLY_APP_NAME; then cat registered_app_domain.txt else echo -e "\033[1;31mError: App name is not available.\033[0m" - echo -e "\033[1;31mPlease change the app name in fly.toml and run this script again.\033[0m" + echo -e "\033[1;31mPlease change the app name in fly.toml and scripts/register_to_fly_io.sh and run this script again.\033[0m" exit 1 fi diff --git a/docs/docs_src/getting_started/no_auth/nats_n_fastapi/my_fastagency_app/docker/content/nginx.conf.template b/docs/docs_src/getting_started/no_auth/nats_n_fastapi/my_fastagency_app/docker/content/nginx.conf.template index 3e295c7b..52347c6e 100644 --- a/docs/docs_src/getting_started/no_auth/nats_n_fastapi/my_fastagency_app/docker/content/nginx.conf.template +++ b/docs/docs_src/getting_started/no_auth/nats_n_fastapi/my_fastagency_app/docker/content/nginx.conf.template @@ -1,17 +1,3 @@ -upstream nats_fastapi_backend { - # Enable sticky sessions with IP hash - ip_hash; - - -} - -upstream fastapi_backend { - # Enable sticky sessions with IP hash - ip_hash; - - -} - upstream mesop_backend { # Enable sticky sessions with IP hash ip_hash; @@ -32,85 +18,9 @@ map $fly_machine_id $sticky_action { default "replay"; # Cookie exists but doesn't match - need to replay } -# Nats fastapi server block -server { - listen $NATS_FASTAPI_PORT; - server_name localhost; - - # Security headers - add_header X-Frame-Options "SAMEORIGIN"; - add_header X-Content-Type-Options "nosniff"; - add_header X-XSS-Protection "1; mode=block"; - - location / { - # Handle cookie setting - if ($sticky_action = "set_cookie") { - add_header Set-Cookie "fly-machine-id=$FLY_MACHINE_ID; Max-Age=518400; Path=/"; - } - - # Handle replay - if ($sticky_action = "replay") { - add_header Fly-Replay "instance=$fly_machine_id"; - return 307; - } - - proxy_pass http://nats_fastapi_backend; - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_redirect off; - proxy_buffering off; - - # WSGI support - proxy_set_header X-Forwarded-Host $server_name; - - # WebSocket support - proxy_http_version 1.1; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - } -} -# Fastapi server block -server { - listen $FASTAPI_PORT; - server_name localhost; - - # Security headers - add_header X-Frame-Options "SAMEORIGIN"; - add_header X-Content-Type-Options "nosniff"; - add_header X-XSS-Protection "1; mode=block"; - - location / { - # Handle cookie setting - if ($sticky_action = "set_cookie") { - add_header Set-Cookie "fly-machine-id=$FLY_MACHINE_ID; Max-Age=518400; Path=/"; - } - - # Handle replay - if ($sticky_action = "replay") { - add_header Fly-Replay "instance=$fly_machine_id"; - return 307; - } - - proxy_pass http://fastapi_backend; - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_redirect off; - proxy_buffering off; - - # WSGI support - proxy_set_header X-Forwarded-Host $server_name; - - # WebSocket support - proxy_http_version 1.1; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - } -} -# Mesop server block +# Main server block server { - listen $MESOP_PORT; + listen $SERVICE_PORT; server_name localhost; # Security headers diff --git a/docs/docs_src/getting_started/no_auth/nats_n_fastapi/my_fastagency_app/docker/content/run_fastagency.sh b/docs/docs_src/getting_started/no_auth/nats_n_fastapi/my_fastagency_app/docker/content/run_fastagency.sh index 0ba28573..1db12dbb 100755 --- a/docs/docs_src/getting_started/no_auth/nats_n_fastapi/my_fastagency_app/docker/content/run_fastagency.sh +++ b/docs/docs_src/getting_started/no_auth/nats_n_fastapi/my_fastagency_app/docker/content/run_fastagency.sh @@ -1,9 +1,15 @@ #!/bin/bash # Accept env variable for PORT -export NATS_FASTAPI_PORT=${NATS_FASTAPI_PORT:-8000} -export FASTAPI_PORT=${FASTAPI_PORT:-8008} + +NATS_FASTAPI_PORT=${NATS_FASTAPI_PORT:-8000} + + +FASTAPI_PORT=${FASTAPI_PORT:-8008} + + export MESOP_PORT=${MESOP_PORT:-8888} +export SERVICE_PORT=$MESOP_PORT # Default number of workers if not set WORKERS=${WORKERS:-1} @@ -16,23 +22,10 @@ echo "Fly machine ID: $FLY_MACHINE_ID" # Generate nginx config for ((i=1; i<$WORKERS+1; i++)) do - PORT=$((MESOP_PORT + i)) - sed -i "19i\ server 127.0.0.1:$PORT;" nginx.conf.template -done - -for ((i=1; i<$WORKERS+1; i++)) -do - PORT=$((FASTAPI_PORT + i)) - sed -i "12i\ server 127.0.0.1:$PORT;" nginx.conf.template -done - -for ((i=1; i<$WORKERS+1; i++)) -do - PORT=$((NATS_FASTAPI_PORT + i)) + PORT=$((SERVICE_PORT + i)) sed -i "5i\ server 127.0.0.1:$PORT;" nginx.conf.template done - -envsubst '${NATS_FASTAPI_PORT},${FASTAPI_PORT},${MESOP_PORT},${FLY_MACHINE_ID}' < nginx.conf.template >/etc/nginx/conf.d/default.conf +envsubst '${SERVICE_PORT},${FLY_MACHINE_ID}' < nginx.conf.template >/etc/nginx/conf.d/default.conf echo "Nginx config:" cat /etc/nginx/conf.d/default.conf @@ -40,30 +33,18 @@ cat /etc/nginx/conf.d/default.conf nginx -g "daemon off;" & # Run nats uvicorn server -# Start multiple single-worker uvicorn instances on consecutive ports -for ((i=1; i<$WORKERS+1; i++)) -do - PORT=$((NATS_FASTAPI_PORT + i)) - echo "Starting nats fastapi uvicorn on port $PORT" - uvicorn my_fastagency_app.deployment.main_1_nats:app --workers=1 --host 0.0.0.0 --port $PORT > /dev/stdout 2>&1 & -done +uvicorn my_fastagency_app.deployment.main_1_nats:app --host 0.0.0.0 --port $NATS_FASTAPI_PORT > /dev/stdout 2>&1 & # Run uvicorn server -# Start multiple single-worker uvicorn instances on consecutive ports -for ((i=1; i<$WORKERS+1; i++)) -do - PORT=$((FASTAPI_PORT + i)) - echo "Starting fastapi uvicorn on port $PORT" - uvicorn my_fastagency_app.deployment.main_2_fastapi:app --workers=1 --host 0.0.0.0 --port $PORT > /dev/stdout 2>&1 & -done +uvicorn my_fastagency_app.deployment.main_2_fastapi:app --host 0.0.0.0 --port $FASTAPI_PORT > /dev/stdout 2>&1 & # Run gunicorn server # Start multiple single-worker gunicorn instances on consecutive ports for ((i=1; i<$WORKERS+1; i++)) do - PORT=$((MESOP_PORT + i)) + PORT=$((SERVICE_PORT + i)) echo "Starting gunicorn on port $PORT" gunicorn --workers=1 my_fastagency_app.deployment.main_3_mesop:app --bind 0.0.0.0:$PORT > /dev/stdout 2>&1 & done diff --git a/docs/docs_src/getting_started/no_auth/nats_n_fastapi/my_fastagency_app/fly.toml b/docs/docs_src/getting_started/no_auth/nats_n_fastapi/my_fastagency_app/fly.toml index ef085a35..742cfd80 100644 --- a/docs/docs_src/getting_started/no_auth/nats_n_fastapi/my_fastagency_app/fly.toml +++ b/docs/docs_src/getting_started/no_auth/nats_n_fastapi/my_fastagency_app/fly.toml @@ -21,43 +21,3 @@ primary_region = 'ams' memory = '1gb' cpu_kind = 'shared' cpus = 1 - -[[services]] - http_checks = [] - internal_port = 8000 - processes = ["app"] - protocol = "tcp" - script_checks = [] - - [services.concurrency] - type = "connections" - - [[services.ports]] - handlers = ["tls", "http"] - port = 8000 -[[services]] - http_checks = [] - internal_port = 8008 - processes = ["app"] - protocol = "tcp" - script_checks = [] - - [services.concurrency] - type = "connections" - - [[services.ports]] - handlers = ["tls", "http"] - port = 8008 -[[services]] - http_checks = [] - internal_port = 8888 - processes = ["app"] - protocol = "tcp" - script_checks = [] - - [services.concurrency] - type = "connections" - - [[services.ports]] - handlers = ["tls", "http"] - port = 8888 diff --git a/docs/docs_src/getting_started/no_auth/nats_n_fastapi/my_fastagency_app/scripts/register_to_fly_io.sh b/docs/docs_src/getting_started/no_auth/nats_n_fastapi/my_fastagency_app/scripts/register_to_fly_io.sh index bfd9711a..a49aac06 100755 --- a/docs/docs_src/getting_started/no_auth/nats_n_fastapi/my_fastagency_app/scripts/register_to_fly_io.sh +++ b/docs/docs_src/getting_started/no_auth/nats_n_fastapi/my_fastagency_app/scripts/register_to_fly_io.sh @@ -17,7 +17,7 @@ else echo -e "\033[0;32mAlready logged into fly.io\033[0m" fi -export FLY_APP_NAME=$(grep "^app = " fly.toml | awk -F"'" '{print $2}') +export FLY_APP_NAME=my-fastagency-app echo -e "\033[0;32mRegistering app name in fly.io\033[0m" if flyctl apps create $FLY_APP_NAME; then @@ -27,6 +27,6 @@ if flyctl apps create $FLY_APP_NAME; then cat registered_app_domain.txt else echo -e "\033[1;31mError: App name is not available.\033[0m" - echo -e "\033[1;31mPlease change the app name in fly.toml and run this script again.\033[0m" + echo -e "\033[1;31mPlease change the app name in fly.toml and scripts/register_to_fly_io.sh and run this script again.\033[0m" exit 1 fi diff --git a/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/my_bank_app/workflow.py b/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/my_bank_app/workflow.py index d3fa0005..b7eda053 100644 --- a/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/my_bank_app/workflow.py +++ b/docs/docs_src/user_guide/dependency_injection/mesop/my_bank_app/my_bank_app/workflow.py @@ -5,7 +5,7 @@ from autogen.agentchat import ConversableAgent from fastagency import UI from fastagency.api.dependency_injection import inject_params -from fastagency.runtimes.autogen import AutoGenWorkflows +from fastagency.runtimes.ag2 import AutoGenWorkflows account_ballace_dict = { ("alice", "password123"): 100, diff --git a/docs/docs_src/user_guide/dependency_injection/workflow.py b/docs/docs_src/user_guide/dependency_injection/workflow.py index d3fa0005..b7eda053 100644 --- a/docs/docs_src/user_guide/dependency_injection/workflow.py +++ b/docs/docs_src/user_guide/dependency_injection/workflow.py @@ -5,7 +5,7 @@ from autogen.agentchat import ConversableAgent from fastagency import UI from fastagency.api.dependency_injection import inject_params -from fastagency.runtimes.autogen import AutoGenWorkflows +from fastagency.runtimes.ag2 import AutoGenWorkflows account_ballace_dict = { ("alice", "password123"): 100, diff --git a/fastagency/runtimes/ag2/__init__.py b/fastagency/runtimes/ag2/__init__.py index a4dc920b..29392e27 100644 --- a/fastagency/runtimes/ag2/__init__.py +++ b/fastagency/runtimes/ag2/__init__.py @@ -1,6 +1,6 @@ from ...helpers import check_imports -check_imports(["autogen"], "autogen") +check_imports(["autogen"], "ag2") from .autogen import AutoGenWorkflows, IOStreamAdapter # noqa: E402 diff --git a/fastagency/runtimes/agentchat/__init__.py b/fastagency/runtimes/agentchat/__init__.py new file mode 100644 index 00000000..5e64786c --- /dev/null +++ b/fastagency/runtimes/agentchat/__init__.py @@ -0,0 +1,3 @@ +from ...helpers import check_imports + +check_imports(["autogen"], "autogen-agentchat") diff --git a/tests/cli/test_discover.py b/tests/cli/test_discover.py index 947738df..e3ba7bb3 100644 --- a/tests/cli/test_discover.py +++ b/tests/cli/test_discover.py @@ -32,7 +32,7 @@ def _import_fixture( main_content = f""" from unittest.mock import MagicMock from fastagency.ui.console import ConsoleUI -from fastagency.runtimes.autogen import AutoGenWorkflows +from fastagency.runtimes.ag2 import AutoGenWorkflows {'frim' if syntax_error else 'from'} fastagency import FastAgency diff --git a/tests/cli/test_mesop.py b/tests/cli/test_mesop.py index 10f8b03c..56270a10 100644 --- a/tests/cli/test_mesop.py +++ b/tests/cli/test_mesop.py @@ -14,7 +14,7 @@ from autogen.agentchat import ConversableAgent from fastagency import UI, FastAgency, WorkflowsProtocol -from fastagency.runtimes.autogen import AutoGenWorkflows +from fastagency.runtimes.ag2 import AutoGenWorkflows from fastagency.ui.mesop import MesopUI llm_config = { diff --git a/tests/docs_src/test_import.py b/tests/docs_src/test_import.py index 3683df98..4d895c40 100644 --- a/tests/docs_src/test_import.py +++ b/tests/docs_src/test_import.py @@ -24,7 +24,7 @@ MESOP_EXCLUDED_MODULES = { "docs_src.tutorials.giphy", "docs_src.tutorials.whatsapp", - "docs_src.user_guide.runtimes.autogen.mesop", + "docs_src.user_guide.runtimes.ag2.mesop", "docs_src.user_guide.dependency_injection", } diff --git a/tests/runtime/agentchat/__init__.py b/tests/runtime/agentchat/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/runtime/agentchat/test_agentchat.py b/tests/runtime/agentchat/test_agentchat.py new file mode 100644 index 00000000..e69de29b