Skip to content

Commit 4588e25

Browse files
Copilotnzthiago
andauthored
Port Azure Functions QuickStart from TypeScript to Python with v2 programming model (#2)
* Initial plan * Complete Azure Functions Python port with infrastructure and documentation Co-authored-by: nzthiago <[email protected]> * Implement SDK type bindings for ContainerClient Co-authored-by: nzthiago <[email protected]> * Initial updates to work with SDK Types * Updating SDK package with fix for user assigned identity to work --------- Co-authored-by: copilot-swe-agent[bot] <[email protected]> Co-authored-by: nzthiago <[email protected]> Co-authored-by: Thiago Almeida <[email protected]>
1 parent 6aab3a4 commit 4588e25

21 files changed

+1216
-35
lines changed

.gitignore

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,23 @@ __pycache__/
66
# C extensions
77
*.so
88

9+
# Azurite
10+
__azurite*
11+
AzuriteConfig
12+
__blobstorage__
13+
__queuestorage__
14+
__tablestorage__
15+
16+
# VS Code
17+
.vscode/
18+
19+
# Mac DS_Store files
20+
# These files are created by macOS to store custom attributes of a folder such as the
21+
# position of icons or the choice of background image. They are not needed in version control
22+
# and can be safely ignored.
23+
# For more information, see https://en.wikipedia.org/wiki/.DS_Store
24+
.DS_Store
25+
926
# Distribution / packaging
1027
.Python
1128
build/
@@ -205,3 +222,15 @@ cython_debug/
205222
marimo/_static/
206223
marimo/_lsp/
207224
__marimo__/
225+
226+
# Azure Functions
227+
local.settings.json
228+
bin
229+
obj
230+
appsettings.json
231+
*.user
232+
*.userprefs
233+
*.zip
234+
235+
# Azure Developer CLI
236+
.azure

README.md

Lines changed: 189 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,57 +1,211 @@
1-
# Project Name
1+
---
2+
page_type: sample
3+
languages:
4+
- python
5+
- bicep
6+
- azdeveloper
7+
products:
8+
- azure
9+
- azure-functions
10+
- azure-blob-storage
11+
- azure-virtual-network
12+
- entra-id
13+
urlFragment: functions-quickstart-python-azd-eventgrid-blob
14+
name: Azure Functions Python Event Grid Blob Trigger using Azure Developer CLI
15+
description: This template repository contains an Azure Functions reference sample using the Blob trigger with Event Grid source type, written in Python (v2 programming model) and deployed to Azure using the Azure Developer CLI (azd). The sample uses managed identity and a virtual network to make sure deployment is secure by default.
16+
---
17+
<!-- YAML front-matter schema: https://review.learn.microsoft.com/en-us/help/contribute/samples/process/onboarding?branch=main#supported-metadata-fields-for-readmemd -->
218

3-
(short, 1-3 sentenced, description of the project)
19+
# Azure Functions Python Event Grid Blob Trigger using Azure Developer CLI
420

5-
## Features
21+
This template repository contains an Azure Functions reference sample using the Blob trigger with Event Grid source type, written in Python (v2 programming model) and deployed to Azure using the Azure Developer CLI (`azd`). When deployed to Azure the sample uses managed identity and a virtual network to make sure deployment is secure by default. You can control whether a VNet is used in the sample by setting `VNET_ENABLED` to true or false in the AZD parameters.
622

7-
This project framework provides the following features:
23+
This sample implements a simple function that copies PDF files from an `unprocessed-pdf` container to a `processed-pdf` container when new blobs are created. This straightforward example showcases how to use the Event Grid blob trigger to automatically respond to blob creation events in near real-time.
824

9-
* Feature 1
10-
* Feature 2
11-
* ...
25+
![Architecture diagram for Azure Functions Event Grid Blob Trigger](./img/architecture.png)
1226

13-
## Getting Started
27+
## Benefits of Event Grid Blob Trigger
1428

15-
### Prerequisites
29+
This sample uses the Event Grid source type for the Blob trigger, which provides significant advantages over the traditional scan-based approach:
1630

17-
(ideally very short, if any)
31+
- **Near real-time processing**: Event Grid delivers blob events within milliseconds of creation, eliminating the delays associated with container scanning.
32+
- **Improved scalability**: Perfect for Flex Consumption plans where the traditional polling-based Blob trigger isn't available.
33+
- **Reduced costs**: Eliminates storage transaction costs from polling, which can be substantial with large numbers of blobs.
34+
- **Enhanced reliability**: Uses a robust pub/sub model that ensures blob events aren't missed, even during function downtime.
35+
- **Better performance**: No performance degradation with large numbers of blobs in a container, unlike the scan-based approach.
1836

19-
- OS
20-
- Library version
21-
- ...
37+
The Event Grid approach is recommended for all new Blob trigger implementations, especially when using Flex Consumption plans where the traditional storage polling method isn't available.
2238

23-
### Installation
39+
## Prerequisites
2440

25-
(ideally very short)
41+
+ [Azure Developer CLI](https://learn.microsoft.com/en-us/azure/developer/azure-developer-cli/install-azd)
42+
+ [Python 3.12+](https://www.python.org/downloads/)
43+
+ [Azure Functions Core Tools](https://learn.microsoft.com/azure/azure-functions/functions-run-local?pivots=programming-language-python#install-the-azure-functions-core-tools)
44+
+ To use Visual Studio Code to run and debug locally:
45+
+ [Visual Studio Code](https://code.visualstudio.com/)
46+
+ [Azure Storage extension](https://marketplace.visualstudio.com/items?itemName=ms-azuretools.vscode-azurestorage)
47+
+ [Azure Functions extension](https://marketplace.visualstudio.com/items?itemName=ms-azuretools.vscode-azurefunctions)
48+
+ [Python extension](https://marketplace.visualstudio.com/items?itemName=ms-python.python)
49+
+ [REST Client](https://marketplace.visualstudio.com/items?itemName=humao.rest-client)
50+
+ [Azurite](https://learn.microsoft.com/en-us/azure/storage/common/storage-use-azurite) to emulate Azure Storage services when running locally
2651

27-
- npm install [package name]
28-
- mvn install
29-
- ...
52+
Optional for uploading blobs:
3053

31-
### Quickstart
32-
(Add steps to get up and running quickly)
54+
+ [Azure CLI](https://learn.microsoft.com/en-us/cli/azure/install-azure-cli) or
55+
+ [Azure Storage Explorer](https://azure.microsoft.com/en-us/products/storage/storage-explorer/#Download-4)
3356

34-
1. git clone [repository clone url]
35-
2. cd [repository name]
36-
3. ...
57+
## Initialize the local project
3758

59+
To initialize a project from this `azd` template, clone the GitHub template repository locally using the `git clone` command:
3860

39-
## Demo
61+
```bash
62+
git clone https://github.com/Azure-Samples/functions-quickstart-python-azd-eventgrid-blob.git
63+
cd functions-quickstart-python-azd-eventgrid-blob
64+
```
4065

41-
A demo app is included to show how to use the project.
66+
You can also clone the repository from your own fork in GitHub.
4267

43-
To run the demo, follow these steps:
68+
# Start and prepare the local storage emulator
4469

45-
(Add steps to start up the demo)
70+
Azure Functions uses Azurite to emulate Azure Storage services when running locally. If you haven't done so, [install Azurite](https://learn.microsoft.com/en-us/azure/storage/common/storage-use-azurite#install-azurite).
4671

47-
1.
48-
2.
49-
3.
72+
Create two containers in the local storage emulator called `processed-pdf` and `unprocessed-pdf`. Follow these steps:
5073

51-
## Resources
74+
1. Ensure Azurite is running. For more details see [Run Azurite](https://learn.microsoft.com/en-us/azure/storage/common/storage-use-azurite#run-azurite)
5275

53-
(Any additional resources or related projects)
76+
2. Use Azure Storage Explorer, or the VS Code Storage Extension to create the containers.
5477

55-
- Link to supporting information
56-
- Link to similar sample
57-
- ...
78+
**Using Azure Storage Explorer:**
79+
+ Install [Azure Storage Explorer](https://azure.microsoft.com/en-us/products/storage/storage-explorer/#Download-4)
80+
+ Open Azure Storage Explorer.
81+
+ Connect to the local emulator by selecting `Attach to a local emulator.`
82+
+ Navigate to the `Blob Containers` section.
83+
+ Right-click and select `Create Blob Container.`
84+
+ Name the containers `processed-pdf` and `unprocessed-pdf`.
85+
86+
**Using VS Code Storage Extension:**
87+
+ Install the VS Code [Azure Storage extension](https://marketplace.visualstudio.com/items?itemName=ms-azuretools.vscode-azurestorage)
88+
+ Ensure Azurite is running
89+
+ Click on the Azure extension icon in VS Code
90+
+ Under `Workspace`, expand `Local Emulator`
91+
+ Right click on `Blob Containers` and select `Create Blob Container`
92+
+ Name the containers `processed-pdf` and `unprocessed-pdf`
93+
94+
3. Upload the PDF files from the `data` folder to the `unprocessed-pdf` container.
95+
96+
**Using Azure Storage Explorer:**
97+
+ Open Azure Storage Explorer.
98+
+ Navigate to the `unprocessed-pdf` container.
99+
+ Click on "Upload" and select "Upload Folder" or "Upload Files."
100+
+ Choose the `data` folder or the specific PDF files to upload.
101+
+ Confirm the upload to the `unprocessed-pdf` container.
102+
103+
**Using VS Code Storage Extension:**
104+
+ Install the VS Code [Azure Storage extension](https://marketplace.visualstudio.com/items?itemName=ms-azuretools.vscode-azurestorage)
105+
+ Ensure Azurite is running
106+
+ Click on the Azure extension icon in VS Code
107+
+ Under `Workspace`, expand `Local Emulator`, expand `Blob Containers`
108+
+ Right click on `unprocessed-pdf` and select `Open in Explorer`
109+
+ Copy and paste all the pdf files from the `data` folder to it
110+
111+
## Run your app
112+
113+
**Using the terminal**
114+
115+
+ Create and activate a Python virtual environment:
116+
117+
```bash
118+
python -m venv .venv
119+
source .venv/bin/activate # On Windows: .venv\Scripts\activate
120+
```
121+
122+
+ Navigate to the `src` directory and install dependencies:
123+
124+
```bash
125+
cd src
126+
pip install -r requirements.txt
127+
```
128+
129+
+ From the `src` folder, run this command to start the Functions host locally:
130+
131+
```bash
132+
func start
133+
```
134+
135+
**Using Visual Studio Code**
136+
137+
+ Open the project folder in a new terminal.
138+
+ Run the `code .` command to open the project in Visual Studio Code.
139+
+ Create and activate a Python virtual environment:
140+
+ Open Command Palette (F1) and run `Python: Create Environment`
141+
+ Select `Venv` and choose your Python 3.12+ interpreter
142+
+ Select the `src/requirements.txt` file to install dependencies
143+
+ In the command palette (F1), type `Azurite: Start`, which enables debugging without warnings.
144+
+ Open the `src` folder in VS Code and press **F5** to run in the debugger. Make a note of the `localhost` URL endpoints, including the port, which might not be `7071`.
145+
146+
## Trigger the function
147+
148+
Now that the storage emulator is running, has files on the `unprocessed-pdf` container, and our app is running, we can execute the `process_blob_upload` function to simulate a new blob event.
149+
150+
+ If you are using VS Code, Visual Studio, or other tooling that supports .http files, you can open the [`test.http`](./test.http) project file, update the port on the `localhost` URL (if needed), and then click on Send Request to call the locally running `process_blob_upload` function. This will trigger the function to process the `Benefit_Options.pdf` file. You can update the file name in the JSON to process other PDF files.
151+
152+
## Source Code
153+
154+
The function code for the `process_blob_upload` endpoint is defined in [`function_app.py`](./src/function_app.py). The function uses the Python v2 programming model and the `@app.blob_trigger()` decorator to register the blob trigger with Event Grid source.
155+
156+
```python
157+
@app.blob_trigger(arg_name="blob",
158+
path="unprocessed-pdf/{name}",
159+
connection="PDFProcessorSTORAGE",
160+
source="EventGrid")
161+
def process_blob_upload(blob: func.InputStream) -> None:
162+
# Function implementation
163+
```
164+
165+
The `copy_to_processed_container` method uses the Azure Storage Blob SDK to upload the processed file to the destination blob container.
166+
167+
## Deploy to Azure
168+
169+
Login to the Azure Developer CLI if you haven't already:
170+
171+
```bash
172+
azd auth login
173+
```
174+
175+
Run this command from the base folder to provision the function app and other required Azure Azure resources, and deploy your code:
176+
177+
```bash
178+
azd up
179+
```
180+
181+
If required you can opt-out of a VNet being used in the sample. To do so, use `azd env` to configure `VNET_ENABLED` to `false` before running `azd up`:
182+
183+
```bash
184+
azd env set VNET_ENABLED false
185+
azd up
186+
```
187+
188+
You're prompted to supply these required deployment parameters:
189+
190+
| Parameter | Description |
191+
| ---- | ---- |
192+
| _Environment name_ | An environment that's used to maintain a unique deployment context for your app. You won't be prompted if you created the local project using `azd init`.|
193+
| _Azure subscription_ | Subscription in which your resources are created.|
194+
| _Azure location_ | Azure region in which to create the resource group that contains the new Azure resources. Only regions that currently support the Flex Consumption plan are shown.|
195+
196+
After publish completes successfully, the new resource group will have a storage account and the `processed-pdf` and `unprocessed-pdf` containers. Upload PDF files from the data folder to the `unprocessed-pdf` folder and then check `processed-pdf` for the file.
197+
198+
## Redeploy your code
199+
200+
You can run the `azd up` command as many times as you need to both provision your Azure resources and deploy code updates to your function app.
201+
202+
>[!NOTE]
203+
>Deployed code files are always overwritten by the latest deployment package.
204+
205+
## Clean up resources
206+
207+
When you're done working with your function app and related resources, you can use this command to delete the function app and its related resources from Azure and avoid incurring any further costs:
208+
209+
```bash
210+
azd down
211+
```

azure.yaml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# yaml-language-server: $schema=https://raw.githubusercontent.com/Azure/azure-dev/main/schemas/v1.0/azure.yaml.json
2+
3+
name: functions-quickstart-python-azd-eventgrid-blob
4+
metadata:
5+
6+
hooks:
7+
postdeploy:
8+
windows:
9+
shell: pwsh
10+
run: ./scripts/post-up.ps1
11+
interactive: true
12+
continueOnError: false
13+
posix:
14+
shell: sh
15+
run: ./scripts/post-up.sh
16+
interactive: true
17+
continueOnError: false
18+
services:
19+
processor:
20+
project: ./src
21+
language: python
22+
host: function

data/Benefit_Options.pdf

532 KB
Binary file not shown.

data/PerksPlus.pdf

113 KB
Binary file not shown.

data/employee_handbook.pdf

140 KB
Binary file not shown.

img/architecture.png

39.1 KB
Loading

0 commit comments

Comments
 (0)