Python-web- en -werkrollen met Python-tools voor Visual Studio

Belangrijk

Cloud Services (klassiek) is nu afgeschaft voor nieuwe klanten en wordt op 31 augustus 2024 buiten gebruik gesteld voor alle klanten. Nieuwe implementaties moeten gebruikmaken van het nieuwe implementatiemodel op basis van Azure Resource Manager Azure Cloud Services (uitgebreide ondersteuning).

Dit artikel biedt een overzicht van het gebruik van Python-web- en -werkrollen met Python Tools for Visual Studio. U kunt hier lezen hoe u met Visual Studio een eenvoudige cloudservice maakt en implementeert die gebruikmaakt van Python.

Vereisten

Notitie

U hebt een Azure-account nodig om deze zelfstudie te voltooien. U kunt uw voordelen als Visual Studio-abonnee activeren of u aanmelden voor een gratis proefversie.

Wat zijn Python-web- en -werkrollen?

Azure biedt drie rekenmodellen voor het uitvoeren van toepassingen: web-appsfunctie in Azure App Service, Azure Virtual Machines en Azure Cloud Services. Alle drie modellen ondersteunen Python. Cloud Services, die web- en werkrollen bevatten, bieden Platform as a Service (PaaS). Binnen een cloudservice biedt een webrol een speciale IIS-webserver (Internet Information Services) voor het hosten van front-end webtoepassingen. Een werkrol kan asynchrone langlopende of permanente taken uitvoeren onafhankelijk van de interactie of invoer van de gebruiker.

Zie Wat is een cloudservice? voor meer informatie.

Notitie

Wilt u een eenvoudige website bouwen? Als uw scenario slechts een ongecompliceerde website-front-end omvat, kunt u overwegen de eenvoudige functie Web Apps in Azure App Service te gebruiken. U kunt vervolgens gemakkelijk upgraden naar een cloudservice naarmate uw website groeit en de vereisten veranderen. Zie het Python Developer Center voor artikelen over ontwikkeling met de functie Web Apps in Azure App Service.

Een project maken

In Visual Studio kunt u Azure Cloud Service selecteren in het dialoogvenster Nieuw project onder Python.

Dialoogvenster Nieuw project

U kunt nieuwe web- en werkrollen maken in de Azure Cloud Service-wizard.

Het dialoogvenster Azure Cloud Service

De werkrolsjabloon wordt geleverd met standaardcode om verbinding maken met een Azure-opslagaccount of Azure Service Bus.

Cloudserviceoplossing

U kunt op elk gewenst moment web- of werkrollen toevoegen aan een bestaande cloudservice. U kunt bestaande projecten aan uw oplossing toevoegen of nieuwe maken.

De opdracht Rol toevoegen

Uw cloudservice kan rollen bevatten die zijn geïmplementeerd in verschillende talen. U kunt bijvoorbeeld een Python-webrol hebben die is geïmplementeerd met Django, met Python of met C#-werkrollen. U kunt eenvoudig communiceren tussen uw rollen met behulp van de Service Bus-wachtrijen of opslagwachtrijen.

Python installeren op de cloudservice

Waarschuwing

De installatiescripts die met Visual Studio zijn geïnstalleerd, werken niet (op het moment dat dit artikel voor het laatst werd bijgewerkt). Deze sectie beschrijft een tijdelijke oplossing.

Het belangrijkste probleem met de installatiescripts is dat Python hiermee niet wordt geïnstalleerd. Eerst definieert u twee opstarttaken in het bestand ServiceDefinition.csdef. De eerste taak (PrepPython.ps1) downloadt en installeert de Python-runtime. De tweede taak (PipInstaller.ps1) voert pip uit om alle afhankelijkheden die u mogelijk hebt, te installeren.

De volgende scripts zijn geschreven voor Python 3.8. Als u versie 2.x van Python wilt gebruiken, stelt u de variabele PYTHON2 in het bestand in op on (aan) voor de twee opstarttaken en de runtimetaak: <Variable name="PYTHON2" value="<mark>on</mark>" />.

<Startup>

  <Task executionContext="elevated" taskType="simple" commandLine="bin\ps.cmd PrepPython.ps1">
    <Environment>
      <Variable name="EMULATED">
        <RoleInstanceValue xpath="/RoleEnvironment/Deployment/@emulated" />
      </Variable>
      <Variable name="PYTHON2" value="off" />
    </Environment>
  </Task>

  <Task executionContext="elevated" taskType="simple" commandLine="bin\ps.cmd PipInstaller.ps1">
    <Environment>
      <Variable name="EMULATED">
        <RoleInstanceValue xpath="/RoleEnvironment/Deployment/@emulated" />
      </Variable>
      <Variable name="PYTHON2" value="off" />
    </Environment>

  </Task>

</Startup>

De variabelen PYTHON2 en PYPATH moeten aan de opstarttaak van de werkrol worden toegevoegd. De variabele PYPATH wordt alleen gebruikt als de variabele PYTHON2 is ingesteld op on (aan).

<Runtime>
  <Environment>
    <Variable name="EMULATED">
      <RoleInstanceValue xpath="/RoleEnvironment/Deployment/@emulated" />
    </Variable>
    <Variable name="PYTHON2" value="off" />
    <Variable name="PYPATH" value="%SystemDrive%\Python27" />
  </Environment>
  <EntryPoint>
    <ProgramEntryPoint commandLine="bin\ps.cmd LaunchWorker.ps1" setReadyOnProcessStart="true" />
  </EntryPoint>
</Runtime>

Voorbeeld van ServiceDefinition.csdef

<?xml version="1.0" encoding="utf-8"?>
<ServiceDefinition name="AzureCloudServicePython" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition" schemaVersion="2015-04.2.6">
  <WorkerRole name="WorkerRole1" vmsize="Small">
    <ConfigurationSettings>
      <Setting name="Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString" />
      <Setting name="Python2" />
    </ConfigurationSettings>
    <Startup>
      <Task executionContext="elevated" taskType="simple" commandLine="bin\ps.cmd PrepPython.ps1">
        <Environment>
          <Variable name="EMULATED">
            <RoleInstanceValue xpath="/RoleEnvironment/Deployment/@emulated" />
          </Variable>
          <Variable name="PYTHON2" value="off" />
        </Environment>
      </Task>
      <Task executionContext="elevated" taskType="simple" commandLine="bin\ps.cmd PipInstaller.ps1">
        <Environment>
          <Variable name="EMULATED">
            <RoleInstanceValue xpath="/RoleEnvironment/Deployment/@emulated" />
          </Variable>
          <Variable name="PYTHON2" value="off" />
        </Environment>
      </Task>
    </Startup>
    <Runtime>
      <Environment>
        <Variable name="EMULATED">
          <RoleInstanceValue xpath="/RoleEnvironment/Deployment/@emulated" />
        </Variable>
        <Variable name="PYTHON2" value="off" />
        <Variable name="PYPATH" value="%SystemDrive%\Python27" />
      </Environment>
      <EntryPoint>
        <ProgramEntryPoint commandLine="bin\ps.cmd LaunchWorker.ps1" setReadyOnProcessStart="true" />
      </EntryPoint>
    </Runtime>
    <Imports>
      <Import moduleName="RemoteAccess" />
      <Import moduleName="RemoteForwarder" />
    </Imports>
  </WorkerRole>
</ServiceDefinition>

Maak vervolgens de bestanden PrepPython.ps1 en PipInstaller.ps1 in de map ./bin van uw rol.

PrepPython.ps1

Dit script installeert Python. Als de omgevingsvariabele PYTHON2 is ingesteld op Aan, wordt Python 2.7 geïnstalleerd, anders wordt Python 3.8 geïnstalleerd.

[Net.ServicePointManager]::SecurityProtocol = "tls12, tls11, tls"
$is_emulated = $env:EMULATED -eq "true"
$is_python2 = $env:PYTHON2 -eq "on"
$nl = [Environment]::NewLine

if (-not $is_emulated){
    Write-Output "Checking if Python is installed...$nl"
    if ($is_python2) {
        & "${env:SystemDrive}\Python27\python.exe"  -V | Out-Null
    }
    else {
        py -V | Out-Null
    }

    if (-not $?) {

        $url = "https://www.python.org/ftp/python/3.8.8/python-3.8.8-amd64.exe"
        $outFile = "${env:TEMP}\python-3.8.8-amd64.exe"

        if ($is_python2) {
            $url = "https://www.python.org/ftp/python/2.7.18/python-2.7.18.amd64.msi"
            $outFile = "${env:TEMP}\python-2.7.18.amd64.msi"
        }

        Write-Output "Not found, downloading $url to $outFile$nl"
        Invoke-WebRequest $url -OutFile $outFile
        Write-Output "Installing$nl"

        if ($is_python2) {
            Start-Process msiexec.exe -ArgumentList "/q", "/i", "$outFile", "ALLUSERS=1" -Wait
        }
        else {
            Start-Process "$outFile" -ArgumentList "/quiet", "InstallAllUsers=1" -Wait
        }

        Write-Output "Done$nl"
    }
    else {
        Write-Output "Already installed"
    }
}

PipInstaller.ps1

Met dit script wordt pip aangeroepen en worden alle afhankelijkheden in het bestand requirements.txt geïnstalleerd. Als de omgevingsvariabele PYTHON2 is ingesteld op Aan, wordt Python 2.7 gebruikt, anders wordt Python 3.8 gebruikt.

$is_emulated = $env:EMULATED -eq "true"
$is_python2 = $env:PYTHON2 -eq "on"
$nl = [Environment]::NewLine

if (-not $is_emulated){
    Write-Output "Checking if requirements.txt exists$nl"
    if (Test-Path ..\requirements.txt) {
        Write-Output "Found. Processing pip$nl"

        if ($is_python2) {
            & "${env:SystemDrive}\Python27\python.exe" -m pip install -r ..\requirements.txt
        }
        else {
            py -m pip install -r ..\requirements.txt
        }

        Write-Output "Done$nl"
    }
    else {
        Write-Output "Not found$nl"
    }
}

LaunchWorker.ps1 wijzigen

Notitie

In het geval van een project met een werkrol is het bestand LauncherWorker.ps1 vereist om het opstartbestand uit te voeren. Bij een project met een webrol wordt het opstartbestand in plaats daarvan gedefinieerd in de projecteigenschappen.

Het bestand bin\LaunchWorker.ps1 is oorspronkelijk gemaakt om heel wat voorbereidende taken te verrichten, maar werkt niet echt. Vervang de inhoud van dat bestand door het volgende script.

Met dit script wordt het worker.py-bestand vanuit uw Python-project aangeroepen. Als de omgevingsvariabele PYTHON2 is ingesteld op Aan, wordt Python 2.7 gebruikt, anders wordt Python 3.8 gebruikt.

$is_emulated = $env:EMULATED -eq "true"
$is_python2 = $env:PYTHON2 -eq "on"
$nl = [Environment]::NewLine

if (-not $is_emulated)
{
    Write-Output "Running worker.py$nl"

    if ($is_python2) {
        cd..
        iex "$env:PYPATH\python.exe worker.py"
    }
    else {
        cd..
        iex "py worker.py"
    }
}
else
{
    Write-Output "Running (EMULATED) worker.py$nl"

    # Customize to your local dev environment

    if ($is_python2) {
        cd..
        iex "$env:PYPATH\python.exe worker.py"
    }
    else {
        cd..
        iex "py worker.py"
    }
}

ps.cmd

De Visual Studio-sjablonen zouden in de map ./bin een bestand ps.cmd moeten hebben gemaakt. Dit shellscript roept de bovenstaande PowerShell-wrapperscripts aan en biedt logboekregistratie op basis van de naam van de aangeroepen PowerShell-wrapper. Als dit bestand niet is gemaakt, ziet u hieronder wat het moet bevatten.

@echo off

cd /D %~dp0

if not exist "%DiagnosticStore%\LogFiles" mkdir "%DiagnosticStore%\LogFiles"
%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe -ExecutionPolicy Unrestricted -File %* >> "%DiagnosticStore%\LogFiles\%~n1.txt" 2>> "%DiagnosticStore%\LogFiles\%~n1.err.txt"

Lokaal uitvoeren

Als u uw cloudserviceproject instelt als opstartproject en op F5 drukt, wordt de cloudservice in de lokale Azure-emulator uitgevoerd.

Hoewel PTVS opstarten in de emulator ondersteunt, werkt foutopsporing (bijvoorbeeld onderbrekingspunten) niet.

Voor foutopsporing in uw web- en werkrollen kunt u het rolproject instellen als opstartproject en daarop foutopsporing uitvoeren. U kunt ook meerdere opstartprojecten instellen. Klik met de rechtermuisknop op de oplossing en selecteer vervolgens Opstartprojecten instellen.

Eigenschappen van opstartprojecten in de oplossing

Publiceren naar Azure

Om te publiceren, klikt u met de rechtermuisknop op het cloudserviceproject in de oplossing en selecteert u vervolgens Publiceren.

Aanmelden voor publiceren in Microsoft Azure

Volg de wizard. Schakel Extern bureaublad in, als dat nodig is. Extern bureaublad is handig wanneer u ergens fouten in moet opsporen.

Klik op Publiceren wanneer u klaar bent met het configureren van instellingen.

De voortgang wordt gedeeltelijk weergegeven in het uitvoervenster. Vervolgens ziet u het venster Activiteitenlogboek van Microsoft Azure.

Het venster Activiteitenlogboek van Microsoft Azure

De implementatie duurt enkele minuten. Daarna worden uw web- en/of werkrollen uitgevoerd in Azure.

Logboeken onderzoeken

Nadat de virtuele machine van de cloudservice wordt gestart en Python installeert, kunt u de logboeken controleren op foutberichten. Deze logboeken bevinden zich in de map C:\Resources\Directory\{role}\LogFiles . PrepPython.err.txt bevat ten minste één fout doordat het script probeert te detecteren of Python is geïnstalleerd. Mogelijk geeft PipInstaller.err.txt ook aan dat de versie van pip is verouderd.

Volgende stappen

Zie de documentatie bij PTVS voor meer informatie over het werken met web- en werkrollen in Python-tools voor Visual Studio:

Zie de volgende artikelen voor meer informatie over het gebruik van Azure-services via uw web- en werkrollen, zoals het gebruik van Azure Storage of Service Bus: