部署到 Azure Web 应用程序的 FastAPI 无法加载

问题描述 投票:0回答:1

一直在努力让 FastAPI 应用程序在 azure 上运行。以下是所有步骤和发现:

FastAPI 端点:

from fastapi import FastAPI,Request
from fastapi.middleware.cors import CORSMiddleware
from fastapi_azure_auth import SingleTenantAzureAuthorizationCodeBearer
import uvicorn
from fastapi import FastAPI, Security
import os
from typing import Dict

from settings import Settings

from pydantic import AnyHttpUrl,BaseModel

from contextlib import asynccontextmanager
from typing import AsyncGenerator

from fastapi_azure_auth.user import User

settings = Settings()

@asynccontextmanager
async def lifespan(app: FastAPI) -> AsyncGenerator[None, None]:
    """
    Load OpenID config on startup.
    """
    await azure_scheme.openid_config.load_config()
    yield


app = FastAPI(
    swagger_ui_oauth2_redirect_url='/oauth2-redirect',
    swagger_ui_init_oauth={
        'usePkceWithAuthorizationCodeGrant': True,
        'clientId': settings.OPENAPI_CLIENT_ID,
        'scopes': settings.SCOPE_NAME,
    },
)

if settings.BACKEND_CORS_ORIGINS:
    app.add_middleware(
        CORSMiddleware,
        allow_origins=[str(origin) for origin in settings.BACKEND_CORS_ORIGINS],
        allow_credentials=True,
        allow_methods=['*'],
        allow_headers=['*'],
    )

azure_scheme = SingleTenantAzureAuthorizationCodeBearer(
    app_client_id=settings.APP_CLIENT_ID,
    tenant_id=settings.TENANT_ID,
    scopes=settings.SCOPES,
)

class User(BaseModel):
    name: str
    roles: list[str] = []


@app.get("/", dependencies=[Security(azure_scheme)])
async def root():
    print("Yo bro")
    return {"whoIsTheBest": "DNA Team is"}

@app.get("/test", dependencies=[Security(azure_scheme)])
async def root():
    print("Yo test")
    return {"whoIsTheBest": "DNA Team is!"}

@app.get("/me", dependencies=[Security(azure_scheme)])
async def me(request: Request):
    print("Me")
    return User(roles=request.state.user.roles,name=request.state.user.name)

if __name__ == '__main__':
    uvicorn.run('main:app', reload=True) 

设置:

from pydantic import AnyHttpUrl, computed_field
from pydantic_settings import BaseSettings
import os

class Settings(BaseSettings):
    BACKEND_CORS_ORIGINS: list[str | AnyHttpUrl] = ['http://localhost:80']
    OPENAPI_CLIENT_ID: str = os.getenv('OPENAPI_CLIENT_ID')
    APP_CLIENT_ID: str = os.getenv('APP_CLIENT_ID')
    TENANT_ID: str = os.getenv('TENANT_ID')
    SCOPE_DESCRIPTION: str = "user_impersonation"

    @computed_field
    @property
    def SCOPE_NAME(self) -> str:
        return f'api://{self.APP_CLIENT_ID}/{self.SCOPE_DESCRIPTION}'

    @computed_field
    @property
    def SCOPES(self) -> dict:
        return {
            self.SCOPE_NAME: self.SCOPE_DESCRIPTION,
        }

    @computed_field
    @property
    def OPENAPI_TOKEN_URL(self) -> str:
        return f"https://login.microsoftonline.com/{self.TENANT_ID}/oauth2/v2.0/token"

    class Config:
        env_file = '.env'
        env_file_encoding = 'utf-8'
        case_sensitive = True

我在 github 中有以下操作: 名称:构建 Python 应用程序并将其部署到 Azure Web App - fast-api-port

on:
  push:
    branches:
      - main
  workflow_dispatch:

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4

      - name: Set up Python version
        uses: actions/setup-python@v5
        with:
          python-version: '3.12'

      - name: Create and start virtual environment
        run: |
          python -m venv venv
          source venv/bin/activate
      
      - name: Install dependencies
        run: pip install -r requirements.txt
        
      # Optional: Add step to run tests here (PyTest, Django test suites, etc.)

      - name: Zip artifact for deployment
        run: zip release.zip ./* -r

      - name: Upload artifact for deployment jobs
        uses: actions/upload-artifact@v4
        with:
          name: python-app
          path: |
            release.zip
            !venv/

  deploy:
    runs-on: ubuntu-latest
    needs: build
    environment:
      name: 'Production'
      url: ${{ steps.deploy-to-webapp.outputs.webapp-url }}
    permissions:
      id-token: write #This is required for requesting the JWT

    steps:
      - name: Download artifact from build job
        uses: actions/download-artifact@v4
        with:
          name: python-app

      - name: Unzip artifact for deployment
        run: unzip release.zip

      
      - name: Login to Azure
        uses: azure/login@v2
        with:
          client-id: ${{ secrets.AZUREAPPSERVICE_CLIENTID_7C6D249DE594426EBD4725CC0D066145 }}
          tenant-id: ${{ secrets.AZUREAPPSERVICE_TENANTID_6399B578ADAF41E095CA377A465B8BB1 }}
          subscription-id: ${{ secrets.AZUREAPPSERVICE_SUBSCRIPTIONID_527AF2EA4A6A4A8BAC99ECB57B6CE6AB }}

      - name: 'Deploy to Azure Web App'
        uses: azure/webapps-deploy@v3
        id: deploy-to-webapp
        with:
          app-name: 'fast-api-port'
          slot-name: 'Production'

我可以看到文件按预期部署到 Web 应用程序中 wwwroot 文件夹中的 output.tar.gz 文件。

我在网络应用程序的配置中添加了以下内容: enter image description here

当我加载我的应用程序时https://xxx.westeurope-01.azurewebsites.net/docs我收到以下错误: enter image description here

这是我在日志中可以找到的内容: enter image description here

有什么建议会导致这种情况吗?

python azure azure-web-app-service fastapi
1个回答
0
投票

当我使用你的代码并使用 GitHub 将其部署到 Azure 时,我遇到了同样的错误。

如果仔细观察应用程序日志,我们可以看到环境变量 OPENAPI_CLIENT_ID、APP_CLIENT_ID 和 TENANT_ID 的

input_value
设置为
None
。因此,该应用程序无法启动。

为了解决上述问题,我将以下值从

.env
文件添加到 Azure Web App 的
Environment Variables

TENANT_ID=<Tenant_Id>
APP_CLIENT_ID=<App_Client_Id>
OPENAPI_CLIENT_ID=<Openapi_Client_Id>

enter image description here

Azure 输出

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.