App Service on Linux Python runtime における デプロイおよびリモートビルド(Kudu Oryx Build) について - その２

# はじめに

以下の記事のつづきとなります。

https://qiita.com/georgeOsdDev@github/items/129ebe2c2780815f262e

この記事では、リモートビルドによって作成された成果物がどのようにアプリケーションコンテナで実行されるかを記載します。

# TL;DR

- リモートビルドApp コンテナ上において、コンテナ起動時には Oryx(script generator) によって、スタートアップスクリプトが作成され、/home/site/wwwroot/output.tar.gz は、アプリケーションコンテナの /tmp 配下に展開され、実行ます。
- すなわちコンテナのローカル領域となり、`/home` 配下のファイルを利用しているわけではありません。

# リモートビルドの成果物

ビルド処理までは前回の記事参照、ビルドした結果

`/home/site/wwwroot` には、

- `.ostype`
- `oryx-manifest.toml`
- `output.tar.gz`

の 3 つのファイルが生成された状態で、アプリケーションコンテナのリサイクルがトリガーされます。

# アプリケーションコンテナの起動処理

まずは、アプリケーションコンテナ起動時のログを確認してみます。

```log:default_docker.log
2023-11-25T04:30:11.491089169Z    _____                               
2023-11-25T04:30:11.491133670Z   /  _  \ __________ _________   ____  
2023-11-25T04:30:11.491139570Z  /  /_\  \\___   /  |  \_  __ \_/ __ \ 
2023-11-25T04:30:11.491142870Z /    |    \/    /|  |  /|  | \/\  ___/ 
2023-11-25T04:30:11.491146270Z \____|__  /_____ \____/ |__|    \___  >
2023-11-25T04:30:11.491149570Z         \/      \/                  \/ 
2023-11-25T04:30:11.491152870Z A P P   S E R V I C E   O N   L I N U X
2023-11-25T04:30:11.491155970Z 
2023-11-25T04:30:11.491158870Z Documentation: http://aka.ms/webapp-linux
2023-11-25T04:30:11.491161670Z Python 3.12.0
2023-11-25T04:30:11.491164670Z Note: Any data outside '/home' is not persisted
2023-11-25T04:30:14.272710496Z Starting OpenBSD Secure Shell server: sshd.
2023-11-25T04:30:14.456830555Z App Command Line not configured, will attempt auto-detect
2023-11-25T04:30:15.026204422Z Starting periodic command scheduler: cron.
2023-11-25T04:30:15.044903719Z Launching oryx with: create-script -appPath /home/site/wwwroot -output /opt/startup/startup.sh -virtualEnvName antenv -defaultApp /opt/defaultsite
2023-11-25T04:30:15.192316887Z Found build manifest file at '/home/site/wwwroot/oryx-manifest.toml'. Deserializing it...
2023-11-25T04:30:15.250243589Z Build Operation ID: a44e7c14de0e264b
2023-11-25T04:30:15.250255589Z Oryx Version: 0.2.20231109.3, Commit: 07b75878a8cbe645ec942592ee7e4d443fa34cdc, ReleaseTagName: 20231109.3
2023-11-25T04:30:15.250159289Z Output is compressed. Extracting it...
2023-11-25T04:30:15.250268689Z Extracting '/home/site/wwwroot/output.tar.gz' to directory '/tmp/8dbed5fbcb85126'...
2023-11-25T04:30:26.120784169Z App path is set to '/tmp/8dbed5fbcb85126'
2023-11-25T04:30:26.120818169Z Detected an app based on Django
2023-11-25T04:30:26.127984205Z Generating `gunicorn` command for 'quickstartproject.wsgi'
2023-11-25T04:30:26.306647192Z Writing output script to '/opt/startup/startup.sh'
2023-11-25T04:30:26.502907466Z Using packages from virtual environment antenv located at /tmp/8dbed5fbcb85126/antenv.
2023-11-25T04:30:26.502964066Z Updated PYTHONPATH to '/opt/startup/app_logs:/tmp/8dbed5fbcb85126/antenv/lib/python3.12/site-packages'
2023-11-25T04:30:28.110268045Z [2023-11-25 04:30:28 +0000] [74] [INFO] Starting gunicorn 21.2.0
2023-11-25T04:30:28.273708656Z [2023-11-25 04:30:28 +0000] [74] [INFO] Listening at: http://0.0.0.0:8000 (74)
2023-11-25T04:30:28.273731956Z [2023-11-25 04:30:28 +0000] [74] [INFO] Using worker: sync
2023-11-25T04:30:28.273737756Z [2023-11-25 04:30:28 +0000] [77] [INFO] Booting worker with pid: 77
2023-11-25T04:30:35.171254447Z 169.254.130.1 - - [25/Nov/2023:04:30:35 +0000] "GET /robots933456.txt HTTP/1.1" 400 143 "-" "HealthCheck/1.0"
```

注目すべきは以下の個所です。
ここでも oryx が実行されています。
`/home/site/wwwroot/oryx-manifest.toml` の記載内容に基づいて `/home/site/wwwroot/output.tar.gz` が `/tmp` 以下に展開されるようです。
その後、`/opt/startup/startup.sh` が出力されています。

```
2023-11-25T04:30:15.044903719Z Launching oryx with: create-script -appPath /home/site/wwwroot -output /opt/startup/startup.sh -virtualEnvName antenv -defaultApp /opt/defaultsite
2023-11-25T04:30:15.192316887Z Found build manifest file at '/home/site/wwwroot/oryx-manifest.toml'. Deserializing it...
2023-11-25T04:30:15.250243589Z Build Operation ID: a44e7c14de0e264b
2023-11-25T04:30:15.250255589Z Oryx Version: 0.2.20231109.3, Commit: 07b75878a8cbe645ec942592ee7e4d443fa34cdc, ReleaseTagName: 20231109.3
2023-11-25T04:30:15.250159289Z Output is compressed. Extracting it...
2023-11-25T04:30:15.250268689Z Extracting '/home/site/wwwroot/output.tar.gz' to directory '/tmp/8dbed5fbcb85126'...
2023-11-25T04:30:26.120784169Z App path is set to '/tmp/8dbed5fbcb85126'
2023-11-25T04:30:26.120818169Z Detected an app based on Django
2023-11-25T04:30:26.127984205Z Generating `gunicorn` command for 'quickstartproject.wsgi'
2023-11-25T04:30:26.306647192Z Writing output script to '/opt/startup/startup.sh'
```

プロセスからも `/opt/startup/startup.sh` が実行されていることがわかります。

```bash:ps
(antenv) root@95560d7ab9ff:/tmp/8dbed5fbcb85126# ps aux
USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root           1  0.0  0.0   2480    68 ?        SNs  04:30   0:00 /bin/sh /opt/startup/startup.sh
root          29  0.0  0.1  13352  1944 ?        SNs  04:30   0:00 sshd: /usr/sbin/sshd [listener] 0 of 10-100 startups
root          65  0.0  0.0   6744   204 ?        SNs  04:30   0:00 /usr/sbin/cron
root          74  0.1  1.1 187068 18776 ?        SNl  04:30   0:00 /opt/python/3.12.0/bin/python3 /opt/python/3.12.0/bin/gunicorn quickstartproject.wsgi
root          77  0.5  2.8 301440 47920 ?        SNl  04:30   0:03 /opt/python/3.12.0/bin/python3 /opt/python/3.12.0/bin/gunicorn quickstartproject.wsgi
root          79  0.5  2.5 299368 42424 ?        RN   04:30   0:04 /opt/python/3.12.0/bin/python3 /opt/python/3.12.0/bin/gunicorn quickstartproject.wsgi
root          80  0.5  2.5 299392 42904 ?        SN   04:30   0:04 /opt/python/3.12.0/bin/python3 /opt/python/3.12.0/bin/gunicorn quickstartproject.wsgi
root          87  2.7  0.4  13464  7592 ?        SNs  04:42   0:00 sshd: root@pts/0
root          89  0.6  0.2   7160  3792 pts/0    SNs  04:42   0:00 -bash
root          92  0.0  0.1   9756  3248 pts/0    RN+  04:42   0:00 ps aux
(antenv) root@95560d7ab9ff:/tmp/8dbed5fbcb85126# 
```

## アプリケーションコンテナ起動時の処理の詳細

以下の記事と同じようにエントリーポイントを確認します。

https://qiita.com/georgeOsdDev@github/items/abdadd35248b98c4ef88#blessed-image-%E3%81%AB%E3%81%8A%E3%81%84%E3%81%A6%E3%81%A9%E3%81%AE%E3%82%88%E3%81%86%E3%81%AB%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%8C%E5%AE%9F%E8%A1%8C%E3%81%95%E3%82%8C%E3%82%8B%E3%81%8B

Python 環境においてもエントリーポイントは `/opt/startup/init_container.sh` のようです。 

```dockfile
ENTRYPOINT ["/opt/startup/init_container.sh"]
```

実物を確認します。

## /opt/startup/init_container.sh

概ねの処理は Node.js 版と同じように `oryx create-script -appPath /home/site/wwwroot -output /opt/startup/startup.sh -virtualEnvName antenv -defaultApp /opt/defaultsite`によって、`/opt/startup/startup.sh` を作成し、それを実行しています。

ここでは Oryx は [Startup Script Generator](https://github.com/microsoft/Oryx/tree/main/src/startupscriptgenerator/src/python) として動作しています。

shell　内に　`/home/site/wwwroot/output.tar.gz` を展開する処理の記載はないので、`oryx create-script` の処理過程にて、展開までやっているようです。`Startup Script Generator` って名前のだけど、展開までやってしまうんですね。。。

なお、`oryx-manifest.toml` の記載内容は以下のようになっています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4914/aa7a96a4-b149-6cca-e04f-dfb31dd7a0c1.png)

<details><summary>/opt/startup/init_container.sh</summary>



```bash:/opt/startup/init_container.sh
(antenv) root@61d0e147d8de:/tmp/8dbed5fbcb85126# cat /opt/startup/init_container.sh 
#!/usr/bin/env bash

cat >/etc/motd <<EOL
   _____                               
  /  _  \ __________ _________   ____  
 /  /_\  \\\___   /  |  \_  __ \_/ __ \ 
/    |    \/    /|  |  /|  | \/\  ___/ 
\____|__  /_____ \____/ |__|    \___  >
        \/      \/                  \/ 
A P P   S E R V I C E   O N   L I N U X

Documentation: http://aka.ms/webapp-linux
`python --version`
Note: Any data outside '/home' is not persisted
EOL
cat /etc/motd

# starting sshd process
source /opt/startup/startssh.sh

# Install ca-certificates
source /opt/startup/install_ca_certs.sh

if [[ -z "${PYTHONPATH}" ]]; then
  export PYTHONPATH="/opt/startup/app_logs"
else
  export PYTHONPATH="${PYTHONPATH}:/opt/startup/app_logs"
fi

# Get environment variables to show up in SSH session
# This will replace any \ (backslash), " (double quote), $ (dollar sign) and ` (back quote) symbol by its escaped character to not allow any bash substitution.
(printenv | sed -n "s/^\([^=]\+\)=\(.*\)$/export \1=\2/p" | sed 's/\\/\\\\/g' | sed 's/"/\\\"/g' | sed 's/\$/\\\$/g' | sed 's/`/\\`/g' | sed '/=/s//="/' | sed 's/$/"/' >> /etc/profile)

echo "$@" > /opt/startup/startupCommand
chmod 755 /opt/startup/startupCommand

oryxArgs='create-script -appPath /home/site/wwwroot -output /opt/startup/startup.sh -virtualEnvName antenv -defaultApp /opt/defaultsite'
if [ $# -eq 0 ]; then
    echo 'App Command Line not configured, will attempt auto-detect'
else
    echo "Site's appCommandLine: $@"
    if [ $# -eq 1 ] && [ -f $1 ]; then
        echo 'App command line is a file on disk'
        chmod +x $1
        oryxArgs+=" -userStartupCommand $1"
    else
       oryxArgs+=" -userStartupCommand '$@'"
    fi
fi

debugArgs=""
if [ "$APPSVC_REMOTE_DEBUGGING" == "TRUE" ]; then
    echo "App will launch in debug mode"
    debugArgs="-debugAdapter ptvsd -debugPort $APPSVC_TUNNEL_PORT"

    if [ "$APPSVC_REMOTE_DEBUGGING_BREAK" == "TRUE" ]; then
        debugArgs+=" -debugWait"
    fi

    oryxArgs="$oryxArgs $debugArgs"
fi

echo '' > /etc/cron.d/diag-cron
if [ "$WEBSITE_USE_DIAGNOSTIC_SERVER" != false ]; then
    /run-diag.sh > /dev/null
    echo "*/5 * * * * /run-diag.sh > /dev/null" >> /etc/cron.d/diag-cron
    chmod 0644 /etc/cron.d/diag-cron
    crontab /etc/cron.d/diag-cron
    /etc/init.d/cron start
fi

echo "Launching oryx with: $oryxArgs"
#invoke oryx to generate startup script
eval "oryx $oryxArgs"
chmod +x /opt/startup/startup.sh
#launch startup script
exec /opt/startup/startup.sh
```
</details>

## /opt/startup/startup.sh

生成された `/opt/startup/startup.sh` を確認します。
ここでも `APP_PATH="/tmp/8dbed5fbcb85126"` にて、gunicorn を起動していることがわかります。

<details><summary>/opt/startup/startup.sh</summary>

```bash:/opt/startup/startup.sh
(antenv) root@61d0e147d8de:/tmp/8dbed5fbcb85126# cat /opt/startup/startup.sh
#!/bin/sh

echo 'export APP_PATH="/tmp/8dbed5fbcb85126"' >> ~/.bashrc
echo 'cd $APP_PATH' >> ~/.bashrc

# Enter the source directory to make sure the script runs where the user expects
cd /tmp/8dbed5fbcb85126

export APP_PATH="/tmp/8dbed5fbcb85126"
if [ -z "$HOST" ]; then
                export HOST=0.0.0.0
fi

if [ -z "$PORT" ]; then
                export PORT=80
fi

export PATH="/opt/python/3.12.0/bin:${PATH}"
echo 'export VIRTUALENVIRONMENT_PATH="/tmp/8dbed5fbcb85126/antenv"' >> ~/.bashrc
echo '. antenv/bin/activate' >> ~/.bashrc
PYTHON_VERSION=$(python -c "import sys; print(str(sys.version_info.major) + '.' + str(sys.version_info.minor))")
echo Using packages from virtual environment 'antenv' located at '/tmp/8dbed5fbcb85126/antenv'.
export PYTHONPATH=$PYTHONPATH:"/tmp/8dbed5fbcb85126/antenv/lib/python$PYTHON_VERSION/site-packages"
echo "Updated PYTHONPATH to '$PYTHONPATH'"
. antenv/bin/activate
GUNICORN_CMD_ARGS="--timeout 600 --access-logfile '-' --error-logfile '-' -c /opt/startup/gunicorn.conf.py --chdir=/tmp/8dbed5fbcb85126" gunicorn quickstartproject.wsgi
```
</details>

# おまけ

巷で大人気のAOAIのサンプルリポジトリのデプロイはどうなっているのか。

https://github.com/Azure-Samples/azure-search-openai-demo

このプロジェクトは `azd up` で管理するように構成されています。
`azd up` を実行すると `azure.yaml` に基づいて、FrontEnd 用TypeScriptアプリのビルド(`cd ../frontend;npm install;npm run build`)、および `/scripts/prepdocs.sh` が行われる。
前者は、App Service で動作する Python アプリにてホストする静的ファイルを生成して Web アプリデプロイモジュールに含めるために実行されている。この処理については、ローカルでビルドすることなく、リモートビルドにて `PRE_BUILD_COMMAND` での実行に置き換えることが可能と考えられる。
後者は Cognitive Service 用のものとなり、App Service のデプロイとは直接関係ない。
なお、後者の処理は Python で書かれているため、ローカル環境で `pip install` が行われている。

App Service に対しては zip デプロイが実行されたことが Kudu ログからわかります。

```xml:POST_api-zipdeploy_pending.xml
kudu_ssh_user@f0f9568d8c42:~/LogFiles/kudu/trace$ cat 2023-11-25T04-54-03_9158b8_033_POST_api-zipdeploy_pending.xml
<step title="Incoming Request" date="2023-11-25T04:54:03.955" instance="9158b8" url="/api/zipdeploy?isAsync=true" method="POST" type="request" pid="87,1,29" Accept="application/json" Host="app-backend-3776rj6oovzvk.scm.azurewebsites.net" User-Agent="azsdk-go-zip-deploy/1.0.0 (go1.20.3; linux),azdev/1.2.0 (Go go1.20.3; linux/amd64)" Accept-Encoding="gzip" Authorization="Bea..." Content-Type="application/octet-stream" Transfer-Encoding="chunked" X-Ms-Correlation-Request-Id="1cd227d2ed80438adb16adab200fc5e6" X-ARR-LOG-ID="ae4c9222-759c-4489-bc3c-164e9856782b" CLIENT-IP="[マスク]:63306" X-Client-IP="[マスク]" X-SITE-DEPLOYMENT-ID="app-backend-3776rj6oovzvk" WAS-DEFAULT-HOSTNAME="app-backend-3776rj6oovzvk.scm.azurewebsites.net" X-Forwarded-Proto="https" X-AppService-Proto="https" X-Forwarded-TlsVersion="1.2" X-MS-CLIENT-DISPLAY-NAME="Takeharu Oshida" X-WAWS-Unencoded-URL="/api/zipdeploy?isAsync=true" X-Client-Port="63306" >
```
Oryx ビルドが行われてたことが、デプロイセンターからも確認できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4914/70c0151d-319c-dcf6-ac40-43850db8daf9.png)


<details><summary>/opt/startup/init_container.sh</summary>

```bash:azd up
$ azd up

Packaging services (azd package)

  |       | Packaging service backendExecuting prepackage hook => /tmp/azd-prepackage-3672843850.sh

up to date, audited 203 packages in 1s

13 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities
  |     ==| Packaging service backend
> frontend@0.0.0 build
> tsc && vite build

  |     ==| Packaging service backendvite v4.4.11 building for production...
✓ 2754 modules transformed.
../backend/static/index.html                           0.76 kB │ gzip:   0.38 kB
../backend/static/assets/github-fab00c2d.svg           0.96 kB │ gzip:   0.52 kB
../backend/static/assets/OneShot-daa12333.css          0.83 kB │ gzip:   0.39 kB
../backend/static/assets/index-275098d3.css            6.47 kB │ gzip:   1.99 kB
../backend/static/assets/NoPage-801aeb3c.js            0.18 kB │ gzip:   0.18 kB │ map:     0.35 kB
../backend/static/assets/OneShot-f764a36f.js           4.67 kB │ gzip:   1.93 kB │ map:    18.90 kB
../backend/static/assets/fluentui-icons-00833c8c.js    5.67 kB │ gzip:   2.56 kB │ map: 4,324.19 kB
../backend/static/assets/index-dc1d013e.js            20.90 kB │ gzip:   7.27 kB │ map:    78.01 kB
../backend/static/assets/fluentui-react-89cf9bab.js  327.35 kB │ gzip:  91.20 kB │ map: 1,431.84 kB
../backend/static/assets/vendor-d9827f45.js          815.08 kB │ gzip: 241.76 kB │ map: 3,284.64 kB

(!) Some chunks are larger than 500 kBs after minification. Consider:
- Using dynamic import() to code-split the application
- Use build.rollupOptions.output.manualChunks to improve chunking: https://rollupjs.org/configuration-options/#output-manualchunks
- Adjust chunk size limit for this warning via build.chunkSizeWarningLimit.
✓ built in 12.92s
  (✓) Done: Packaging service backend
  - Package Output: /tmp/azddeploy637488268.zip

Provisioning Azure resources (azd provision)
Provisioning Azure resources can take some time

  You can view detailed progress in the Azure Portal:
  https://portal.azure.com/#view/HubsExtension/DeploymentDetailsBlade/~/overview/id/%2Fsubscriptions%2F9dfbc89b-b148-4471-8048-141eaad9f347%2Fproviders%2FMicrosoft.Resources%2Fdeployments%2Fopenai-demo-dev-1700887940

  (✓) Done: Resource group: rg-openai-demo-dev
  (✓) Done: Search service: gptkb-3776rj6oovzvk
  (✓) Done: App Service plan: plan-3776rj6oovzvk
  (✓) Done: Storage account: st3776rj6oovzvk
  (✓) Done: Form recognizer: cog-fr-3776rj6oovzvk
  (✓) Done: Azure OpenAI: cog-3776rj6oovzvk
  (✓) Done: App Service: app-backend-3776rj6oovzvk
Executing postprovision hook => ./scripts/prepdocs.sh
Loading azd .env file from current environment
WARNING: your version of azd is out of date, you have 1.2.0 and the latest version is 1.5.0

To update to the latest version, run:
curl -fsSL https://aka.ms/install-azd.sh | bash

If the install script was run with custom parameters, ensure that the same parameters are used for the upgrade. For advanced install instructions, see: https://aka.ms/azd/upgrade/linux
Creating Python virtual environment "scripts/.venv"
Installing dependencies from "requirements.txt" into virtual environment
Requirement already satisfied: aiohttp==3.8.6 in ./scripts/.venv/lib/python3.10/site-packages (from -r scripts/requirements.txt (line 7)) (3.8.6)
Requirement already satisfied: aiosignal==1.3.1 in ./scripts/.venv/lib/python3.10/site-packages (from -r scripts/requirements.txt (line 9)) (1.3.1)
Requirement already satisfied: async-timeout==4.0.3 in ./scripts/.venv/lib/python3.10/site-packages (from -r scripts/requirements.txt (line 11)) (4.0.3)
Requirement already satisfied: attrs==23.1.0 in ./scripts/.venv/lib/python3.10/site-packages (from -r scripts/requirements.txt (line 13)) (23.1.0)
Requirement already satisfied: azure-ai-formrecognizer==3.3.2 in ./scripts/.venv/lib/python3.10/site-packages (from -r scripts/requirements.txt (line 15)) (3.3.2)
Requirement already satisfied: azure-common==1.1.28 in ./scripts/.venv/lib/python3.10/site-packages (from -r scripts/requirements.txt (line 17)) (1.1.28)
Requirement already satisfied: azure-core==1.29.5 in ./scripts/.venv/lib/python3.10/site-packages (from -r scripts/requirements.txt (line 21)) (1.29.5)
Requirement already satisfied: azure-identity==1.15.0 in ./scripts/.venv/lib/python3.10/site-packages (from -r scripts/requirements.txt (line 29)) (1.15.0)
Requirement already satisfied: azure-search-documents==11.4.0b6 in ./scripts/.venv/lib/python3.10/site-packages (from -r scripts/requirements.txt (line 31)) (11.4.0b6)
Requirement already satisfied: azure-storage-blob==12.19.0 in ./scripts/.venv/lib/python3.10/site-packages (from -r scripts/requirements.txt (line 33)) (12.19.0)
Requirement already satisfied: azure-storage-file-datalake==12.14.0 in ./scripts/.venv/lib/python3.10/site-packages (from -r scripts/requirements.txt (line 37)) (12.14.0)
Requirement already satisfied: certifi==2023.7.22 in ./scripts/.venv/lib/python3.10/site-packages (from -r scripts/requirements.txt (line 39)) (2023.7.22)
Requirement already satisfied: cffi==1.16.0 in ./scripts/.venv/lib/python3.10/site-packages (from -r scripts/requirements.txt (line 43)) (1.16.0)
Requirement already satisfied: charset-normalizer==3.3.2 in ./scripts/.venv/lib/python3.10/site-packages (from -r scripts/requirements.txt (line 45)) (3.3.2)
Requirement already satisfied: cryptography==41.0.5 in ./scripts/.venv/lib/python3.10/site-packages (from -r scripts/requirements.txt (line 49)) (41.0.5)
Requirement already satisfied: et-xmlfile==1.1.0 in ./scripts/.venv/lib/python3.10/site-packages (from -r scripts/requirements.txt (line 55)) (1.1.0)
Requirement already satisfied: frozenlist==1.4.0 in ./scripts/.venv/lib/python3.10/site-packages (from -r scripts/requirements.txt (line 57)) (1.4.0)
Requirement already satisfied: idna==3.4 in ./scripts/.venv/lib/python3.10/site-packages (from -r scripts/requirements.txt (line 61)) (3.4)
Requirement already satisfied: isodate==0.6.1 in ./scripts/.venv/lib/python3.10/site-packages (from -r scripts/requirements.txt (line 65)) (0.6.1)
Requirement already satisfied: msal==1.25.0 in ./scripts/.venv/lib/python3.10/site-packages (from -r scripts/requirements.txt (line 71)) (1.25.0)
Requirement already satisfied: msal-extensions==1.0.0 in ./scripts/.venv/lib/python3.10/site-packages (from -r scripts/requirements.txt (line 75)) (1.0.0)
Requirement already satisfied: msrest==0.7.1 in ./scripts/.venv/lib/python3.10/site-packages (from -r scripts/requirements.txt (line 77)) (0.7.1)
Requirement already satisfied: multidict==6.0.4 in ./scripts/.venv/lib/python3.10/site-packages (from -r scripts/requirements.txt (line 79)) (6.0.4)
Requirement already satisfied: numpy==1.26.1 in ./scripts/.venv/lib/python3.10/site-packages (from -r scripts/requirements.txt (line 83)) (1.26.1)
Requirement already satisfied: oauthlib==3.2.2 in ./scripts/.venv/lib/python3.10/site-packages (from -r scripts/requirements.txt (line 88)) (3.2.2)
Requirement already satisfied: openai[datalib]==0.28.1 in ./scripts/.venv/lib/python3.10/site-packages (from -r scripts/requirements.txt (line 90)) (0.28.1)
Requirement already satisfied: openpyxl==3.1.2 in ./scripts/.venv/lib/python3.10/site-packages (from -r scripts/requirements.txt (line 92)) (3.1.2)
Requirement already satisfied: pandas==2.1.2 in ./scripts/.venv/lib/python3.10/site-packages (from -r scripts/requirements.txt (line 94)) (2.1.2)
Requirement already satisfied: pandas-stubs==2.1.1.230928 in ./scripts/.venv/lib/python3.10/site-packages (from -r scripts/requirements.txt (line 96)) (2.1.1.230928)
Requirement already satisfied: portalocker==2.8.2 in ./scripts/.venv/lib/python3.10/site-packages (from -r scripts/requirements.txt (line 98)) (2.8.2)
Requirement already satisfied: pycparser==2.21 in ./scripts/.venv/lib/python3.10/site-packages (from -r scripts/requirements.txt (line 100)) (2.21)
Requirement already satisfied: pyjwt[crypto]==2.8.0 in ./scripts/.venv/lib/python3.10/site-packages (from -r scripts/requirements.txt (line 102)) (2.8.0)
Requirement already satisfied: pypdf==3.17.0 in ./scripts/.venv/lib/python3.10/site-packages (from -r scripts/requirements.txt (line 104)) (3.17.0)
Requirement already satisfied: python-dateutil==2.8.2 in ./scripts/.venv/lib/python3.10/site-packages (from -r scripts/requirements.txt (line 106)) (2.8.2)
Requirement already satisfied: pytz==2023.3.post1 in ./scripts/.venv/lib/python3.10/site-packages (from -r scripts/requirements.txt (line 108)) (2023.3.post1)
Requirement already satisfied: regex==2023.10.3 in ./scripts/.venv/lib/python3.10/site-packages (from -r scripts/requirements.txt (line 110)) (2023.10.3)
Requirement already satisfied: requests==2.31.0 in ./scripts/.venv/lib/python3.10/site-packages (from -r scripts/requirements.txt (line 112)) (2.31.0)
Requirement already satisfied: requests-oauthlib==1.3.1 in ./scripts/.venv/lib/python3.10/site-packages (from -r scripts/requirements.txt (line 120)) (1.3.1)
Requirement already satisfied: six==1.16.0 in ./scripts/.venv/lib/python3.10/site-packages (from -r scripts/requirements.txt (line 122)) (1.16.0)
Requirement already satisfied: tenacity==8.2.3 in ./scripts/.venv/lib/python3.10/site-packages (from -r scripts/requirements.txt (line 127)) (8.2.3)
Requirement already satisfied: tiktoken==0.5.1 in ./scripts/.venv/lib/python3.10/site-packages (from -r scripts/requirements.txt (line 129)) (0.5.1)
Requirement already satisfied: tqdm==4.66.1 in ./scripts/.venv/lib/python3.10/site-packages (from -r scripts/requirements.txt (line 131)) (4.66.1)
Requirement already satisfied: types-pytz==2023.3.1.1 in ./scripts/.venv/lib/python3.10/site-packages (from -r scripts/requirements.txt (line 133)) (2023.3.1.1)
Requirement already satisfied: typing-extensions==4.8.0 in ./scripts/.venv/lib/python3.10/site-packages (from -r scripts/requirements.txt (line 135)) (4.8.0)
Requirement already satisfied: tzdata==2023.3 in ./scripts/.venv/lib/python3.10/site-packages (from -r scripts/requirements.txt (line 141)) (2023.3)
Requirement already satisfied: urllib3==2.0.7 in ./scripts/.venv/lib/python3.10/site-packages (from -r scripts/requirements.txt (line 143)) (2.0.7)
Requirement already satisfied: yarl==1.9.2 in ./scripts/.venv/lib/python3.10/site-packages (from -r scripts/requirements.txt (line 145)) (1.9.2)
Running "prepdocs.py"
Processing files...
Using local files in ./data/*
Ensuring search index gptkbindex exists
Search index gptkbindex already exists
Skipping ./data/Benefit_Options.pdf, no changes detected.
Skipping ./data/employee_handbook.pdf, no changes detected.
Skipping ./data/PerksPlus.pdf, no changes detected.
Skipping ./data/role_library.pdf, no changes detected.
Skipping ./data/Northwind_Standard_Benefits_Details.pdf, no changes detected.
Skipping ./data/Northwind_Health_Plus_Benefits_Details.pdf, no changes detected.


Deploying services (azd deploy)

  |  =====| Deploying service backend (Uploading deployment package)

  (✓) Done: Deploying service backend
  - Endpoint: https://app-backend-3776rj6oovzvk.azurewebsites.net/


SUCCESS: Your application was provisioned and deployed to Azure in 5 minutes 54 seconds.
You can view the resources created under the resource group rg-openai-demo-dev in Azure Portal:
https://portal.azure.com/#@/resource/subscriptions/9dfbc89b-b148-4471-8048-141eaad9f347/resourceGroups/rg-openai-demo-dev/overview
```
</details>