สร้าง Azure Functions แบบ HTTP trigger ด้วย Python

  1. Create a function app
  2. Triggers
  3. Bindings
  4. Create a function in the Azure portal
  5. Navigate to your function and its files
  6. Test in the Azure portal
  7. Run function manually
  8. Other .Net

Azure Functions allow developers to host business logic that can be executed without managing or provisioning infrastructure.

1. Create a function app

Let’s create a function app in the Azure portal.

  1. Sign in to the Azure portal
  2. Under Azure services, select Create a resource.
  3. In the menu, select Compute, and then select Function App in the Popular products list.
  4. On the Basics tab, enter the following values for each setting.
SettingValue
PublishCode
Runtime stackPython
Version*3.8
Play typeConsumption (Serverless)

*Python มีเวอร์ชันให้เลือกเป็น 3.7 , 3.8 , 3.9

When deployment completes, select Go to resource

2. Triggers

Functions are event driven, which means they run in response to an event. The type of event that starts a function is called a trigger. Each function must be configured with exactly one trigger.

Azure supports triggers for the following services.

ServiceTrigger description
Blob StorageStarts a function when a new or updated blob is detected.
Azure Cosmos DBStart a function when inserts and updates are detected.
Event GridStarts a function when an event is received from Event Grid.
HTTPStarts a function with an HTTP request.
Microsoft Graph EventsStarts a function in response to an incoming webhook from the Microsoft Graph. Each instance of this trigger can react to one Microsoft Graph resource type.
Queue StorageStarts a function when a new item is received on a queue. The queue message is provided as input to the function.
Service BusStarts a function in response to messages from a Service Bus queue.
TimerStarts a function on a schedule.

3. Bindings

A binding is a declarative way to connect data and services to your function. Bindings interact with various data sources, which means you don’t have to write the code in your function to connect to data sources and manage connections. The platform takes care of that complexity for you as part of the binding code.

Each binding has a direction–your code reads data from input bindings, and writes data to output bindings. Each function can have zero or more bindings to manage the input and output data processed by the function.

A trigger is a type of input binding that has the ability to initiate execution of some code.

Azure provides a large number of bindings to connect to different storage and messaging services.

4. Create a function in the Azure portal

When you create your first function in the Azure Create function pane, you can select a predefined trigger for your function. Based on your selections, Azure generates default code and configuration information, such as creating an event log entry when input data is received.

When you create a function from a template, several files are created, including a configuration file, function.json, and a source code file, __init__.py.

When you select a function that you created in your function app, the Function pane opens. By selecting Code + Test from the Function menu, you have access to actions in the command bar to test and run the code, to save or discard changes you make, or to obtain the published URL.

By selecting Test/Run from the command bar, you can run use cases for requests that include query strings and values. The function’s path above the code box displays the name of the file that is open. You can select a specific file from the dropdown to test or edit, for example, function.json.

__init__.py

import logging

import azure.functions as func


def main(req: func.HttpRequest) -> func.HttpResponse:
    logging.info('Python HTTP trigger function processed a request.')

    name = req.params.get('name')
    if not name:
        try:
            req_body = req.get_json()
        except ValueError:
            pass
        else:
            name = req_body.get('name')

    if name:
        return func.HttpResponse(f"Hello, {name}. This HTTP triggered function executed successfully.")
    else:
        return func.HttpResponse(
             "This HTTP triggered function executed successfully. Pass a name in the query string or in the request body for a personalized response.",
             status_code=200
        )

function.json

{
  "bindings": [
    {
      "authLevel": "function",
      "type": "httpTrigger",
      "direction": "in",
      "name": "req",
      "methods": [
        "get",
        "post"
      ]
    },
    {
      "type": "http",
      "direction": "out",
      "name": "$return"
    }
  ]
}

The bindings property is where you configure both triggers and bindings. Each binding shares a few common settings and some settings which are specific to a particular type of binding. Every binding requires the following settings:

PropertyTypesComments
typestringName of binding. For example, queueTrigger.
directionstringIndicates whether the binding is for receiving data into the function or sending data from the function. For example, in or out.
namestringThe name that is used for the bound data in the function. For example, myQueue.

6. Test in the Azure portal

The portal also provides a convenient way to test your functions. As previously described, in the screenshot above. When you select Run in this pane, the results automatically appear in the Output tab, and the Logs pane opens to display the status.

7. Run function manually

You can start a function by manually triggering the configured trigger. For instance, if you’re using an HTTP trigger, you can use a tool, such as Postman or cURL, to initiate an HTTP request to your function endpoint URL, which is available from the function definition (Get function URL).

เช่นตัวอย่างนี้ก็ ต่อท้าย url ด้วย &name=jack

8. Other .Net

.Net 6

run.csx

#r "Newtonsoft.Json"

using System.Net;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Primitives;
using Newtonsoft.Json;

public static async Task<IActionResult> Run(HttpRequest req, ILogger log)
{
    log.LogInformation("C# HTTP trigger function processed a request.");

    string name = req.Query["name"];

    string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
    dynamic data = JsonConvert.DeserializeObject(requestBody);
    name = name ?? data?.name;

    string responseMessage = string.IsNullOrEmpty(name)
        ? "This HTTP triggered function executed successfully. Pass a name in the query string or in the request body for a personalized response."
                : $"Hello, {name}. This HTTP triggered function executed successfully.";

            return new OkObjectResult(responseMessage);
}

function.json

{
  "bindings": [
    {
      "authLevel": "function",
      "name": "req",
      "type": "httpTrigger",
      "direction": "in",
      "methods": [
        "get",
        "post"
      ]
    },
    {
      "name": "$return",
      "type": "http",
      "direction": "out"
    }
  ]
}

Windows Terminal

Windows Terminal requires Windows 10 2004 (build 19041) or later

Install via Microsoft Store [Recommended]

Install the Windows Terminal from the Microsoft Store. This allows you to always be on the latest version when we release new builds with automatic upgrades.

Install via Windows Package Manager CLI (aka winget)

winget users can download and install the latest Terminal release by installing the Microsoft.WindowsTerminal package:

> winget install --id=Microsoft.WindowsTerminal -e
The `msstore` source requires that you view the following agreements before using.
Terms of Transaction: https://aka.ms/microsoft-store-terms-of-transaction
The source requires the current machine's 2-letter geographic region to be sent to the backend service to function properly (ex. "US").

Do you agree to all the source agreements terms?
[Y] Yes  [N] No: y
Found Windows Terminal [Microsoft.WindowsTerminal] Version 1.13.11431.0
This application is licensed to you by its owner.
Microsoft is not responsible for, nor does it grant any licenses to, third-party packages.
Successfully verified installer hash
Starting package install...
  ██████████████████████████████  100%
Successfully installed

base64

3.6 base64: Transform data into printable data

base64 transforms data read from a file, or standard input, into (or from) base64 encoded form. The base64 encoded form uses printable ASCII characters to represent binary data. Synopses:

base64 [option]… [file]
base64 --decode [option]… [file]

Example#1: Encoding text data

$ echo  'linuxhint.com' | base64

Example#2: Decoding text data

$ echo 'bGludXhoaW50LmNvbQo=' | base64 --decode

Example#3: Encoding text file

$ base64 sample.txt
$ base64 sample.txt > encodedData.txt
$ cat encodedData.txt

Example#4: Decoding text file

$ base64 -d encodedData.txt
$ base64 --decode encodedData.txt > originalData.txt
$ cat originalData.txt

md5sum

6.5 md5sum: Print or check MD5 digests

md5sum computes a 128-bit checksum (or fingerprint or message-digest) for each specified file.

Syntax :

md5sum [OPTION]... [FILE]...
$ md5sum index.png
4191736479ed247941e1bf20830618ad  index.png

Command usage examples with options :

Example 1: Store the MD5 checksum in file and then verify it.

$ md5sum /home/mandeep/test/test.cpp > checkmd5.md5

It will store the MD5 checksum for test.cpp in file checkmd5.md5

$ md5sum -c checkmd5.md5

It will verify the contents of file

Output :

/home/mandeep/test/test.cpp: OK

After changing the contents of file checkmd5.md5, the output will be :

/home/mandeep/test/test.cpp: FAILED
md5sum: WARNING: 1 computed checksum did NOT match

Install EPEL On CentOS 7

Extra Packages for Enterprise Linux (or EPEL) is a Fedora Special Interest Group that creates, maintains, and manages a high quality set of additional packages for Enterprise Linux, including, but not limited to, Red Hat Enterprise Linux (RHEL), CentOS, Scientific Linux (SL), Oracle Linux (OL), AlmaLinux (AL) and Rocky Linux (RL).

CentOS 7

# yum install epel-release

ติดตั้งด้วย dnf (Install DNF On CentOS 7)

$ sudo dnf install epel-release

Install DNF On CentOS 7

DNF (short for “DaNdiFied Yum”) is the next upcoming major version of Yum, a package manager for RPM-based Linux distributions, such as RHEL, CentOS, and Fedora. DNF is first introduced in Fedora 18, and it has became the default package manager from Fedora 25 version. This brief tutorial will explain how to install DNF on CentOS 7 and RHEL 7 versions.

Install DNF On CentOS 7

$ sudo yum install dnf
$ dnf help

บางโปรแกรมเช่น neofetch อยู่ใน dnf-plugins-core ต้องติดตั้ง dnf-plugins-core แล้วก็ enable ก่อน ถึงจะติดตั้งได้

$ sudo yum install neofetch
Loaded plugins: fastestmirror, langpacks
Loading mirror speeds from cached hostfile
 * base: mirrors.bfsu.edu.cn
 * epel: mirrors.tuna.tsinghua.edu.cn
 * extras: ftp.sjtu.edu.cn
 * updates: ftp.sjtu.edu.cn
No package neofetch available.
Error: Nothing to do

ติดตั้ง dnf-plugins-core

$ sudo yum install dnf-plugins-core

Enable COPR repository

$ sudo dnf copr enable konimex/neofetch

เสร็จแล้วค่อยติดตั้ง neofetch อีกครั้งก็จะได้ละ

$ sudo dnf install neofetch

Add User to Sudoers in CentOS

The sudo command stands for “Super User DO” and temporarily elevates the privileges of a regular user for administrative tasks.

Step 1: Verify the Wheel Group is Enabled

Your CentOS 7 installation may or may not have the wheel group enabled.

Open the configuration file by entering the command:

# visudo

Scroll through the configuration file until you see the following entry:

## Allows people in group wheel to run all commands
# %wheel        ALL=(ALL)       ALL

If the second line begins with the # sign, it has been disabled and marked as a comment. Just delete the # sign at the beginning of the second line.

Step 2: Add User to Group

To add a user to the wheel group, use the command:

# usermod –aG wheel <username>

Step: 3 Switch to the Sudo User

Switch to the new (or newly-elevated) user account with the su (substitute user) command:

su - <username>

uuid

What is UUID

UUID is a Universally Unique Identifier. You can also call it as GUID, i.e., Globally Unique Identifier.

A UUID is 128 bits long number or ID to uniquely identify the documents, Users, resources or information in computer systems.

  • UUID can guarantee the uniqueness of Identifiers across space and time. when we talk about space and time means when UUID generated according to the standard then the identifier does not duplicate one that has already been created or will be created to identify something else.

Python UUID module implemented as per RFC 4122. RFC 4122 is a standard and Copyright (C) of The Internet Society. RFC 4122 specification includes all the details and algorithms to generate the Unique Identifiers of all the versions. RFC 4122 document specifies three algorithms to generate UUIDs.

Hence using Python UUID module, you can generate versions 1, 3, 4, and 5 UUIDs. UUID generated using this module is immutable.

Python UUID module supports the following versions of UUIDs.

  • UUID1 – Generate UUID using a Host MAC address, sequence number and the current time. This version uses the IEEE 802 MAC addresses.
  • UUID3 and UUID 5 uses cryptographic hashing and application-provided text strings to generate UUID. UUID 3 uses MD5 hashing, and UUID 5 uses SHA-1 hashing.
  • UUID4 uses pseudo-random number generators to generate UUID.

Structure of UUID

As you can see in the output UUID is made up of five components, and each component has a fixed length. A hyphen symbol separates each component. UUID’s presented in the format “8-4-4-4-12”.

UUID 1 to Generate a unique ID using MAC Address

The uuid.uuid1() function is used to generate a UUID from the host ID, sequence number, and the current time. It uses the MAC address of a host as a source of uniqueness.

import uuid

# make a UUID based on the host address and current time
uuidOne = uuid.uuid1()
print(uuidOne)

# f8adce75-04f3-11ed-9cc3-0456e5e23db1

UUID 4 to generate a random UUID

The UUID generated using a uuid4() function is created using a truly Random or Pseudo-Random generator.

import uuid

uuidFour = uuid.uuid4()
print(uuidFour)

UUID 3 and UUID 5 to Create a Name-Based UUID

Version 3 or 5 UUID meant for generating UUIDs from “names.” we can use name and namespace to create a series of unique UUIDs. In simple words version, 3 and  5 UUIDs is nothing but hashing namespace identifier with a name.

The uuid.uuid3(namespace, name) generate a UUID based on the MD5 hash of a namespace identifier (which is a UUID) and a string.

Similarly, the uuid.uuid5(namespace, name) generate a UUID based on the SHA-1 hashing technique of a namespace identifier (which is a UUID) and a name.

The UUID module defines the following namespace identifiers to use with uuid3() or uuid5().

  • UUID.NAMESPACE_DNS means a fully qualified domain name. For example, https://pynative.com.
  • UUID.NAMESPACE_URL When this namespace is specified, It means it is a URL.
  • UUID.NAMESPACE_OID When this namespace is specified, the name string is an ISO OID.
  • UUID.NAMESPACE_X500 When this namespace is specified, the name string is an X.500 DN in DER or a text output format.
import uuid

hostNames = ['pynative.com', 'phaisarn.com']

for host in hostNames:
    print(uuid.uuid3(uuid.NAMESPACE_DNS, host))
    print(uuid.uuid5(uuid.NAMESPACE_DNS, host))
    print()

Extract UUID attributes read-only attributes

The internal representation of a UUID is a specific sequence of bits in memory, as described in RFC4211. It is necessary to convert the bit sequence to a string representation to represent UUID in string format.

UUID module provides the various read-only argument to access the value of each component of the UUID object. You can extract the values from UUID so we can use this value for a different purpose. For example, You want to Extract the time from a UUID version1 in python.

import uuid

UUID = uuid.uuid1()

print("UUID is ", UUID)
print("UUID Type is   ",type(UUID))
print('UUID.bytes    :', UUID.bytes)
print('UUID.bytes_le :', UUID.bytes_le)
print('UUID.hex      :', UUID.hex)
print('UUID.int      :', UUID.int)
print('UUID.urn      :', UUID.urn)
print('UUID.variant  :', UUID.variant)
print('UUID.version  :', UUID.version)
print('UUID.fields   :', UUID.fields)
print("Prining each field seperately")
print('UUID.time_low            : ', UUID.time_low)
print('UUID.time_mid            : ', UUID.time_mid)
print('UUID.time_hi_version     : ', UUID.time_hi_version)
print('UUID.clock_seq_hi_variant: ', UUID.clock_seq_hi_variant)
print('UUID.clock_seq_low       : ', UUID.clock_seq_low)
print('UUID.node                : ', UUID.node)
print('UUID.time                : ', UUID.time)
print('UUID.clock_seq           : ', UUID.clock_seq)
print('UUID.SafeUUID            : ', UUID.is_safe)

UUID to String and String to UUID in Python

When we call a uuid.uuid1 or any other version of UUID you will get an instance of UUID class. When we want UUID in string format for comparison, manipulation or maybe for any reason we can get its string representation using a str class. Let see how do change a UUID to a string.

create string from uuid

import uuid

UUID1 = uuid.uuid1()
print(type(UUID1))
print(UUID1)
print(type(str(UUID1)))
print(str(UUID1))
print(str(UUID1).replace("-", "")) # remove dash

create uuid from string

import uuid

uuid_str = ["{55da37d1-d481-11e8-9013-adaf456d94a0}",
            "018c168c-d509-11e8-b096-ccaf789d94a0",
            "urn:uuid:e5e9394c-daed-498e-b9f3-69228b44fbfa"]

for string in uuid_str:
    # make a UUID from a string of hex digits
    # (braces and hyphens ignored)
    myUUID = uuid.UUID(string)
    print("UUID is", myUUID)
    print("UUID time component is", myUUID.time)
    print()