You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
log.LogInformation(sprintf "F# function executed at %s!" now)
116
117
```
117
118
119
+
### Java example
120
+
121
+
The following example function triggers and executes every five minutes. The `@TimerTrigger` annotation on the function defines the schedule using the same string format as [CRON expressions](https://en.wikipedia.org/wiki/Cron#CRON_expression).
// timeInfo is a JSON string, you can deserialize it to an object using your favorite JSON library
130
+
context.getLogger().info("Timer is triggered: "+ timerInfo);
131
+
}
132
+
```
133
+
118
134
### JavaScript example
119
135
120
136
The following example shows a timer trigger binding in a *function.json* file and a [JavaScript function](functions-reference-node.md) that uses the binding. The function writes a log indicating whether this function invocation is due to a missed schedule occurrence. A [timer object](#usage) is passed into the function.
@@ -146,21 +162,39 @@ module.exports = function (context, myTimer) {
146
162
};
147
163
```
148
164
149
-
### Java example
165
+
### Python example
150
166
151
-
The following example function triggers and executes every five minutes. The `@TimerTrigger` annotation on the function defines the schedule using the same string format as [CRON expressions](https://en.wikipedia.org/wiki/Cron#CRON_expression).
167
+
The following example uses a timer trigger binding whose configuration is described in the *function.json* file. The actual [Python function](functions-reference-python.md) that uses the binding is described in the *__init__.py* file. The object passed into the function is of type [azure.functions.TimerRequest object](/python/api/azure-functions/azure.functions.timerrequest). The function logic writes to the logs indicating whether the current invocation is due to a missed schedule occurrence.
logging.info('Python timer trigger function ran at %s', utc_timestamp)
196
+
```
197
+
164
198
## Attributes
165
199
166
200
In [C# class libraries](functions-dotnet-class-library.md), use the [TimerTriggerAttribute](https://github.com/Azure/azure-webjobs-sdk-extensions/blob/master/src/WebJobs.Extensions/Extensions/Timers/TimerTriggerAttribute.cs).
Copy file name to clipboardExpand all lines: articles/azure-functions/functions-reference-python.md
+94-96Lines changed: 94 additions & 96 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -25,7 +25,7 @@ This article is an introduction to developing Azure Functions using Python. The
25
25
26
26
An Azure Function should be a stateless method in your Python script that processes input and produces output. By default, the runtime expects the method to be implemented as a global method called `main()` in the `__init__.py` file.
27
27
28
-
You can change the default configuration by specifying the `scriptFile` and `entryPoint` properties in the `function.json` file. For example, the _function.json_ below tells the runtime to use the _customentry()_ method in the _main.py_ file, as the entry point for your Azure Function.
28
+
You can change the default configuration by specifying the `scriptFile` and `entryPoint` properties in the *function.json* file. For example, the _function.json_ below tells the runtime to use the `customentry()` method in the _main.py_ file, as the entry point for your Azure Function.
29
29
30
30
```json
31
31
{
@@ -35,7 +35,7 @@ You can change the default configuration by specifying the `scriptFile` and `en
35
35
}
36
36
```
37
37
38
-
Data from triggers and bindings is bound to the function via method attributes using the `name` property defined in the `function.json` configuration file. For example, the _function.json_ below describes a simple function triggered by an HTTP request named `req`:
38
+
Data from triggers and bindings is bound to the function via method attributes using the `name` property defined in the *function.json* file. For example, the _function.json_ below describes a simple function triggered by an HTTP request named `req`:
39
39
40
40
```json
41
41
{
@@ -63,7 +63,7 @@ def main(req):
63
63
returnf'Hello, {user}!'
64
64
```
65
65
66
-
Optionally, you can also declare the parameter types and return type in the function using Python type annotations. For example, the same function can be written using annotations, as follows:
66
+
Optionally, to leverage the intellisense and auto-complete features provided by your code editor, you can also declare the attribute types and return type in the function using Python type annotations.
Use the Python annotations included in the [azure.functions.*](/python/api/azure-functions/azure.functions?view=azure-python) package to bind input and outputs to your methods.
76
+
Use the Python annotations included in the [azure.functions.*](/python/api/azure-functions/azure.functions?view=azure-python) package to bind input and outputs to your methods.
77
77
78
78
## Folder structure
79
79
@@ -92,25 +92,23 @@ The folder structure for a Python Functions project looks like the following:
92
92
| | - mySecondHelperFunction.py
93
93
| - host.json
94
94
| - requirements.txt
95
-
| - extensions.csproj
96
-
| - bin
97
95
```
98
96
99
97
There's a shared [host.json](functions-host-json.md) file that can be used to configure the function app. Each function has its own code file and binding configuration file (function.json).
100
98
101
99
Shared code should be kept in a separate folder. To reference modules in the SharedCode folder, you can use the following syntax:
102
100
103
101
```
104
-
from ..SharedCode import myFirstHelperFunction
102
+
from __app__.SharedCode import myFirstHelperFunction
105
103
```
106
104
107
-
Binding extensions used by the Functions runtime are defined in the `extensions.csproj` file, with the actual library files in the `bin` folder. When developing locally, you must [register binding extensions](./functions-bindings-register.md#local-development-with-azure-functions-core-tools-and-extension-bundles) using Azure Functions Core Tools.
108
-
109
-
When deploying a Functions project to your function app in Azure, the entire content of the FunctionApp folder should be included in the package, but not the folder itself.
105
+
When deploying a Function project to your function app in Azure, the entire content of the *FunctionApp* folder should be included in the package, but not the folder itself.
110
106
111
107
## Triggers and Inputs
112
108
113
-
Inputs are divided into two categories in Azure Functions: trigger input and additional input. Although they are different in `function.json`, the usage is identical in Python code. Connection strings for trigger and input sources should map to values in the `local.settings.json` file locally, and the application settings when running in Azure. Let's take the following code snippet as an example:
109
+
Inputs are divided into two categories in Azure Functions: trigger input and additional input. Although they are different in the `function.json` file, usage is identical in Python code. Connection strings or secrets for trigger and input sources map to values in the `local.settings.json` file when running locally, and the application settings when running in Azure.
110
+
111
+
For example, the following code demonstrates the difference between the two:
114
112
115
113
```json
116
114
// function.json
@@ -228,30 +226,17 @@ Additional logging methods are available that let you write to the console at di
228
226
| logging.**info(_message_)**| Writes a message with level INFO on the root logger. |
229
227
| logging.**debug(_message_)**| Writes a message with level DEBUG on the root logger. |
230
228
231
-
## Importing shared code into a function module
232
-
233
-
Python modules published alongside function modules must be imported using the relative import syntax:
234
-
235
-
```python
236
-
from . import helpers # Use more dots to navigate up the folder structure.
237
-
defmain(req: func.HttpRequest):
238
-
helpers.process_http_request(req)
239
-
```
240
-
241
-
Alternatively, put shared code into a standalone package, publish it to a public or a private
242
-
PyPI instance, and specify it as a regular dependency.
243
-
244
229
## Async
245
230
246
-
Since only a single Python process can exist per function app, it is recommended to implement your Azure Function as an asynchronous coroutine using the `async def` statement.
231
+
We recommend that you write your Azure Function as an asynchronous coroutine using the `async def` statement.
247
232
248
233
```python
249
234
# Will be run with asyncio directly
250
235
asyncdefmain():
251
236
await some_nonblocking_socket_io_op()
252
237
```
253
238
254
-
If the main() function is synchronous (no `async` qualifier) we automatically run it in an `asyncio` thread-pool.
239
+
If the main() function is synchronous (no `async` qualifier) we automatically run the function in an `asyncio` thread-pool.
255
240
256
241
```python
257
242
# Would be run in an asyncio thread-pool
@@ -284,6 +269,21 @@ Name of the function.
284
269
`invocation_id`
285
270
ID of the current function invocation.
286
271
272
+
## Global variables
273
+
274
+
It is not guaranteed that the state of your app will be preserved for future executions. However, the Azure Functions runtime often reuses the same process for multiple executions of the same app. In order to cache the results of an expensive computation, declare it as a global variable.
275
+
276
+
```python
277
+
CACHED_DATA=None
278
+
279
+
defmain(req):
280
+
globalCACHED_DATA
281
+
ifCACHED_DATAisNone:
282
+
CACHED_DATA= load_json()
283
+
284
+
# ... use CACHED_DATA in code
285
+
```
286
+
287
287
## Python version and package management
288
288
289
289
Currently, Azure Functions only supports Python 3.6.x (official CPython distribution).
@@ -292,10 +292,6 @@ When developing locally using the Azure Functions Core Tools or Visual Studio Co
292
292
293
293
For example, the following requirements file and pip command can be used to install the `requests` package from PyPI.
294
294
295
-
```bash
296
-
pip install requests
297
-
```
298
-
299
295
```txt
300
296
requests==2.19.1
301
297
```
@@ -304,20 +300,9 @@ requests==2.19.1
304
300
pip install -r requirements.txt
305
301
```
306
302
307
-
When you're ready for publishing, make sure that all your dependencies are listed in the `requirements.txt` file, located at the root of your project directory. To successfully execute your Azure Functions, the requirements file should contain a minimum of the following packages:
308
-
309
-
```txt
310
-
azure-functions
311
-
azure-functions-worker
312
-
grpcio==1.14.1
313
-
grpcio-tools==1.14.1
314
-
protobuf==3.6.1
315
-
six==1.11.0
316
-
```
317
-
318
303
## Publishing to Azure
319
304
320
-
If you're using a package that requires a compiler and does not support the installation of manylinux-compatible wheels from PyPI, publishing to Azure will fail with the following error:
305
+
When you're ready to publish, make sure that all your dependencies are listed in the *requirements.txt* file, which is located at the root of your project directory. If you're using a package that requires a compiler and does not support the installation of manylinux-compatible wheels from PyPI, publishing to Azure will fail with the following error:
321
306
322
307
```
323
308
There was an error restoring dependencies.ERROR: cannot install <package name - version> dependency: binary dependencies without wheels are not supported.
Underneath the covers, Core Tools will use docker to run the [mcr.microsoft.com/azure-functions/python](https://hub.docker.com/r/microsoft/azure-functions/) image as a container on your local machine. Using this environment, it'll then build and install the required modules from source distribution, before packaging them up for final deployment to Azure.
334
319
335
-
> [!NOTE]
336
-
> Core Tools (func) uses the PyInstaller program to freeze the user's code and dependencies into a single stand-alone executable to run in Azure. This functionality is currently in preview and may not extend to all types of Python packages. If you're unable to import your modules, try publishing again using the `--no-bundler` option.
> If you continue to experience issues, please let us know by [opening an issue](https://github.com/Azure/azure-functions-core-tools/issues/new) and including a description of the problem.
341
-
342
-
343
-
To build your dependencies and publish using a continuous integration (CI) and continuous delivery (CD) system, you can use an [Azure Pipeline](https://docs.microsoft.com/azure/devops/pipelines/get-started-yaml?view=vsts) or [Travis CI custom script](https://docs.travis-ci.com/user/deployment/script/).
344
-
345
-
Following is an example `azure-pipelines.yml` script for the build and publishing process.
346
-
```yml
347
-
pool:
348
-
vmImage: 'Ubuntu 16.04'
349
-
350
-
steps:
351
-
- task: NodeTool@0
352
-
inputs:
353
-
versionSpec: '8.x'
354
-
355
-
- script: |
356
-
set -e
357
-
echo "deb [arch=amd64] https://packages.microsoft.com/repos/azure-cli/ wheezy main" | sudo tee /etc/apt/sources.list.d/azure-cli.list
To build your dependencies and publish using a continuous delivery (CD) system, [use Azure DevOps Pipelines](https://docs.microsoft.com/azure/azure-functions/functions-how-to-azure-devops).
372
321
373
-
Following is an example `.travis.yaml` script for the build and publishing process.
322
+
## Unit Testing
374
323
375
-
```yml
376
-
sudo: required
324
+
Functions written in Python can be tested like other Python code using standard testing frameworks. For most bindings, it's possible to create a mock input object by creating an instance of an appropriate class from the `azure.functions` package.
377
325
378
-
language: node_js
326
+
For example, following is a mock test of an HTTP triggered function:
Here is another example, with a queue triggered function:
366
+
367
+
```python
368
+
# myapp/__init__.py
369
+
import azure.functions as func
397
370
371
+
defmy_function(msg: func.QueueMessage) -> str:
372
+
returnf'msg body: {msg.get_body().decode()}'
398
373
```
399
374
375
+
```python
376
+
# myapp/test_func.py
377
+
import unittest
378
+
379
+
import azure.functions as func
380
+
from . import my_function
381
+
382
+
classTestFunction(unittest.TestCase):
383
+
deftest_my_function(self):
384
+
# Construct a mock Queue message.
385
+
req = func.QueueMessage(
386
+
body=b'test')
387
+
388
+
# Call the function.
389
+
resp = my_function(req)
390
+
391
+
# Check the output.
392
+
self.assertEqual(
393
+
resp,
394
+
'msg body: test',
395
+
)
396
+
```
397
+
400
398
## Known issues and FAQ
401
399
402
400
All known issues and feature requests are tracked using [GitHub issues](https://github.com/Azure/azure-functions-python-worker/issues) list. If you run into a problem and can't find the issue in GitHub, open a new issue and include a detailed description of the problem.
0 commit comments