Build Python apps in Azure Pipelines

Azure Pipelines

This guidance explains how to use Azure Pipelines to automatically build, test, and deploy Python apps or scripts with CI/CD pipelines.


For a working example of how to build a Python app with Django, import (into Azure Repos or TFS) or fork (into GitHub) this repo:

The sample code includes an azure-pipelines.yml file at the root of the repository. You can use this file to build the project.

Follow all the instructions in Create your first pipeline to create a build pipeline for the sample project.

Build environment

You can use Azure Pipelines to build your Python projects without needing to set up any infrastructure of your own. Python is preinstalled on Microsoft-hosted agents in Azure Pipelines. You can use Linux, macOS, or Windows agents to run your builds.

For the exact versions of Python that are preinstalled, refer to Microsoft-hosted agents. To install a specific version of Python on Microsoft hosted agents, add the Use Python Version task to the beginning of your pipeline.

Use a specific Python version

Add the Use Python Version task to set the version of Python used in your pipeline. This snippet sets subsequent pipeline tasks to use Python 3.6.

  vmImage: 'ubuntu-16.04' # other options: 'macOS-10.13', 'vs2017-win2016'

- task: UsePythonVersion@0
    versionSpec: '3.6'
    architecture: 'x64'

Use multiple Python versions

To run a pipeline with multiple Python versions, such as to test your project using different versions, define a job with a matrix of Python version values. Then set the Use Python Version task to reference the matrix variable for its Python version. Increase the parallel value to simultaneously run the job for all versions in the matrix, depending on how many parallel jobs are available.

- job: 'Test'
    vmImage: 'ubuntu-16.04' # other options: 'macOS-10.13', 'vs2017-win2016'
        python.version: '2.7'
        python.version: '3.5'
        python.version: '3.6'
    maxParallel: 3

  - task: UsePythonVersion@0
      versionSpec: '$(python.version)'
      architecture: 'x64'

  # Add additional tasks to run using each Python version in the matrix above

Create and activate an Anaconda environment

See Run pipelines with Anaconda environments.

Run a Python script

If you have a Python script checked into the repo, you can run it using script. Add the following YAML to run a Python file named

- script: python src/

If you want to write a Python script inline in the YAML file, use the Python Script task. Set the targetType to inline and put your code in the script section.

- task: PythonScript@0
    targetType: 'inline'
    script: |
      print('Hello world 1')
      print('Hello world 2')

Install dependencies

Install specific PyPI packages with pip

Add the following YAML to install or upgrade pip and two specific packages: setuptools and wheel.

- script: python -m pip install --upgrade pip setuptools wheel
  displayName: 'Install tools'

Install requirements with pip

After updating pip and friends, a typical next step is to install from requirements.txt.

- script: pip install -r requirements.txt
  displayName: 'Install requirements'

Install Anaconda packages with conda

See Run pipelines with Anaconda environments.


Run lint tests with Flake8

Add the following YAML to install or upgrade flake8 and use it to run lint tests.

- script: |
    python -m pip install flake8
    flake8 .
  displayName: 'Run lint tests'

Test with pytest and collect coverage metrics with pytest-cov

Add the following YAML to install pytest and pytest-cov, run tests, output test results in JUnit format, and output code coverage results in Cobertura XML format.

- script: |
    pip install pytest
    pip install pytest-cov
    pytest tests --doctest-modules --junitxml=junit/test-results.xml --cov=com --cov-report=xml --cov-report=html
  displayName: 'Test with pytest'

Publish test results

Add the Publish Test Results task to publish JUnit or xUnit test results to the server.

- task: PublishTestResults@2
  condition: succeededOrFailed()
    testResultsFiles: '**/test-*.xml'
    testRunTitle: 'Publish test results for Python $(python.version)'

Publish code coverage results

Add the Publish Code Coverage Results task to publish code coverage results to the server. When you do this, coverage metrics can be seen in the build summary and HTML reports can be downloaded for further analysis.

- task: PublishCodeCoverageResults@1
    codeCoverageTool: Cobertura
    summaryFileLocation: '$(System.DefaultWorkingDirectory)/**/coverage.xml'
    reportDirectory: '$(System.DefaultWorkingDirectory)/**/htmlcov'

Package and deliver your code

Authenticate with twine

The Twine Authenticate task stores authentication credentials for twine in the PYPIRC_PATH environment variable.

- task: TwineAuthenticate@0
    artifactFeeds: 'feed_name1, feed_name2'
    externalFeeds: 'feed_name1, feed_name2'

Publish with twine

Then, add a custom script task to use twine to publish your packages.

- script: 'twine -r {feedName/EndpointName} --config-file $(PYPIRC_PATH) {package path to publish}'

Build a container image

You can also build and publish a Docker container image for your app. For more information, see Docker.