Skip to content

Better Monorepo Support for Python Function Apps #4737

@dvasdekis

Description

@dvasdekis

Description

When deploying Python Azure Function Apps from a monorepo with shared internal packages, the current deployment process requires physically copying the code from the monorepo directory into the functionapp directory - I haven't found any other process that works.

Have just spent the afternoon trying to build a wheel from one directory and porting it into the other without luck:

  1. Shell Environment Variable** ❌
export PIP_FIND_LINKS=".python_packages/wheels"
func azure functionapp publish ...

Result: Variable not passed to Azure remote build environment

  1. App Setting with Relative Path** ❌
az functionapp config appsettings set ... --settings "PIP_FIND_LINKS=.python_packages/wheels"

Result:

WARNING: Location '.python_packages/wheels' is ignored: it is either a non-existing path or lacks a specific scheme.
  1. App Setting with Absolute Path + file:// Scheme** ❌
az functionapp config appsettings set ... --settings "PIP_FIND_LINKS=file:///tmp/zipdeploy/extracted/.python_packages/wheels"

Result:

WARNING: Location 'file:///tmp/zipdeploy/extracted/.python_packages/wheels' is ignored: it is neither a file nor a directory.

Any of the below would work for us

Option 1: Support Relative Paths in Remote Build (Simplest)

Allow requirements.txt to contain relative paths that work during remote Oryx build, just like they do locally.

Example:

# requirements.txt
../../../shared/connect_to_database
fastapi==0.115.8

Implementation suggestion:

  • Before running pip install -r requirements.txt, resolve relative paths and install them first
  • Or: Copy referenced local packages into the build context before pip install

Option 2: Support PEP 660 Editable Installs

Support modern Python packaging standards for local dependencies.

Example:

# requirements.txt
-e ../../../shared/connect_to_database
fastapi==0.115.8

Current behavior: Fails during remote build
Desired behavior: Recognize -e paths, copy source into build context, install as editable

Option 3: Support pyproject.toml Workspace Dependencies

Recognize and support workspace-style dependencies in pyproject.toml (similar to Poetry workspaces, PDM, or npm workspaces).

Example:

# pyproject.toml in function app directory
[project]
dependencies = [
    "fastapi==0.115.8",
    "connect-to-database @ file://../../../shared/connect_to_database",
]

Implementation suggestion:

  • Parse pyproject.toml during remote build
  • Resolve file:// paths relative to the project root
  • Include referenced packages in the deployment bundle

Option 4: Explicit Monorepo Configuration

Add a configuration option to specify monorepo layout and shared package locations.

Example:

// .funcappconfig or similar
{
  "monorepo": {
    "root": "../../..",
    "sharedPackages": [
      "shared/connect_to_database"
    ]
  }
}

Then allow normal package references in requirements.txt:

connect-to-database>=1.0.0
fastapi==0.115.8

Real-World Use Case

Repository structure:

platform/
├── azure/
│   ├── global/
│   │   └── python/
│   │       └── connect_to_database/        # Shared package
│   │           ├── setup.py
│   │           └── connect_to_database/
│   └── project1/
│       └── functionapps/
│           └── funcapp1/
│               ├── requirements.txt
│               └── function_app.py
│           └── funcapp2/
│               ├── requirements.txt
│               └── function_app.py
│   └── project2/
│       └── functionapps/
│           └── funcapp3/               # Function app
│               ├── requirements.txt
│               └── function_app.py

What should work but doesn't:

# requirements.txt in pubapi/
../../../global/python/connect_to_database

This works perfectly with pip install -r requirements.txt locally, but fails in Azure remote build.

Impact

This affects any organization using monorepos with Azure Functions, which is increasingly common for:

  • Microservices architectures with shared libraries
  • Multi-tenant applications with shared utilities
  • Data engineering platforms (our use case) with shared database/auth code
  • Enterprise applications with shared business logic

Comparison with Other Platforms

  • AWS Lambda (with SAM/CDK): Supports specifying local package paths in build configuration
  • Google Cloud Functions: Can include local packages via build configuration
  • Vercel/Netlify: Built-in monorepo support with workspace detection
  • Azure Static Web Apps: Supports app-specific configuration in monorepos

Azure Functions should match or exceed these capabilities.

Environment

  • Azure Functions Core Tools: 4.0.5907
  • Python Version: 3.12
  • Operating System: Linux (GitHub Actions runners, local Ubuntu)
  • Deployment Method: func azure functionapp publish with remote build
  • Build System: Oryx 0.2.20251022.1

Workaround Documentation

If this feature can't be implemented soon, please at least document the official recommended approach for monorepos. Currently, the documentation doesn't address this scenario at all.

Suggested documentation locations:


Would you accept a PR for this feature? Our team would be happy to contribute if you can provide guidance on the preferred approach.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions