Azure / Azure/azure-functions-core-tools

Better Monorepo Support for Python Function Apps

Open
#4,737 3 comments 6 reactions 0 assignees View on GitHub
enhancement
Dominant language
C#
Stars
1.5k
Forks
498
Avg merge
4d 20h
Merged PRs (30d)
14

Description

### 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** ❌
```bash
export PIP_FIND_LINKS=".python_packages/wheels"
func azure functionapp publish ...
```
**Result**: Variable not passed to Azure remote build environment

2. App Setting with Relative Path** ❌
```bash
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.
```

3. App Setting with Absolute Path + file:// Scheme** ❌
```bash
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:**
```toml
# 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:**
```json
// .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:**
```python
# 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:
- https://learn.microsoft.com/en-us/azure/azure-functions/functions-reference-python
- https://learn.microsoft.com/en-us/azure/azure-functions/functions-how-to-use-azure-function-app-settings

---

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

Contributor guide

Open the contributing guide

Research direction

Start at the `func azure functionapp publish` remote-build path and trace how `requirements.txt`, `pyproject.toml`, and local package paths are handled. First resolve which of the four proposed approaches is preferred; done should mean a documented or implemented monorepo workflow succeeds during remote Oryx builds without copying shared packages into the function app.

Written by the indexing model from the issue text.

Assessment

Tech stack
azure, csharp, python
Domain
build-system, cli, cloud
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.