Sql bind in Azure Function - python

I'm trying to use Sql output binding functionalities for Azure function.
Below is my current configuration. I'm using Visual Studio Code as IDE
Found Python version 3.9.0 (py).
Core Tools Version: 4.0.4736 Commit hash: N/A (64-bit)
Function Runtime Version: 4.8.1.18957
Extension bundle version: "[4.*, 5.0.0)"
functions.json :
{
"scriptFile": "__init__.py",
"bindings": [
{
"authLevel": "anonymous",
"type": "httpTrigger",
"direction": "in",
"name": "req",
"methods": [
"post"
]
},
{
"type": "http",
"direction": "out",
"name": "$return"
},
{
"name": "transactions",
"type": "sql",
"direction": "out",
"commandText": "dbo.[table]",
"connectionStringSetting": "Driver={ODBC Driver 13 for SQL Server} etcetc."
}
]
}
init.py
import logging
import json
import azure.functions as func
def main(
req: func.HttpRequest, transactions: func.Out[func.SqlRow]
) -> func.HttpResponse:
logging.info("Python HTTP trigger function processed a request.")
# i'm using Vue JSON.Stringify({}) in the POST method...on client side
body = json.loads(req.get_body())
row = func.SqlRow.from_dict(body)
transactions.set(row)
return func.HttpResponse(
body=json.dumps(body), status_code=201, mimetype="application/json"
)
Error :
[2022-09-12T17:49:13.731Z] Executed 'Functions.RegisterNewBatch' (Failed, Id=..., Duration=9ms)
[2022-09-12T17:49:13.732Z] System.Private.CoreLib: Exception while executing function:
Functions.RegisterNewBatch. Microsoft.Azure.WebJobs.Host:
Error while handling parameter _binder after function returned:
Microsoft.Data.SqlClient: The ConnectionString property has not been initialized.
Can you please help on that.

Value for ConnectionString must be included in local.settings.json (not env variable).

Check your binding declaration in function.json and the ConnectionString in your local.settings.json
Here is a full sample for input and output bindings:
https://github.com/DFMERA/azure-functions-sql-binding
Blog Post:
https://acelera.tech/2023/02/10/azure-functions-sql-binding-con-python/

Related

Azure Functions Python App - enable IdentityModelEventSource.ShowPII Property

I'm having some issues with the AAD authentication of my Python API which is hosted in Azure Functions.
The official documentation suggests to "enable PII to see the values removed from the message" in order to be able to check the Issuer & ValidIssuer. The documentation only references the .NET extension however. The search on learn.microsoft.com also only shows hits for .NET developers. How can I activate it for my Python API application?
The error code / return JSON I am stuck on:
{
"code": 401,
"message": "IDX10205: Issuer validation failed. Issuer: '[PII of type 'System.String' is hidden.
For more details, see https://aka.ms/IdentityModel/PII.]'.
Did not match: validationParameters.ValidIssuer:
'[PII of type 'System.String' is hidden. For more details, see https://aka.ms/IdentityModel/PII.]'
or validationParameters.ValidIssuers: '[PII of type 'System.String'
is hidden. For more details, see https://aka.ms/IdentityModel/PII.]'.
For more details, see https://aka.ms/IdentityModel/issuer-validation. "
}
host.json file:
{
"version": "2.0",
"extensions": {
"http": {
"routePrefix": ""
}
}
}
local.settings.json file:
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "",
"FUNCTIONS_WORKER_RUNTIME": "python"
}
}
MyApp/function.json file:
{
"scriptFile": "__init__.py", # see below for contents
"disabled": false,
"bindings": [
{
"authLevel": "anonymous",
"type": "httpTrigger",
"direction": "in",
"name": "req",
"methods": [
"get",
"post"
],
"route": "{*route}"
},
{
"type": "http",
"direction": "out",
"name": "$return"
}
]
}
MyApp/__ init __.py file:
from ..FastAPIApp import app # see below for contents
nest_asyncio.apply()
logger = logging.getLogger()
#app.get("/status")
async def index() -> Dict:
return {
"info": "API is working normally.",
}
FastAPIApp/__ init __.py file:
import fastapi
app = fastapi.FastAPI()

Error: Could not load file or assembly 'Microsoft.Azure.WebJobs.Script.Abstractions

I'm trying to run an Azure Function locally following the Microsoft guide:
https://learn.microsoft.com/nl-nl/azure/azure-functions/create-first-function-cli-python?tabs=azure-cli%2Cbash%2Cbrowser#create-venv
Whatever I try I get the same error over and over again when i try to start the function using "func start":
Found Python version 3.8.0 (py).
Azure Functions Core Tools
Core Tools Version: 4.0.4544 Commit hash: N/A (64-bit)
Function Runtime Version: 4.3.2.18186
Could not load file or assembly 'Microsoft.Azure.WebJobs.Script.Abstractions,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=3c5b9424214e8f8c'. The system cannot find
the file specified.
My files are set up as follows
Host.json
{
"version": "2.0",
"logging": {
"applicationInsights": {
"samplingSettings": {
"isEnabled": true,
"excludedTypes": "Request"
}
}
},
"extensionBundle": {
"id": "Microsoft.Azure.Functions.ExtensionBundle",
"version": "[2.*, 3.0.0)"
}
}
local.setting.json
{
"IsEncrypted": false,
"Values": {
"FUNCTIONS_WORKER_RUNTIME": "python",
"AzureWebJobsStorage": "UseDevelopmentStorage=true"
}
}
requirements.txt
azure-functions
function.json
{
"scriptFile": "__init__.py",
"bindings": [
{
"authLevel": "Anonymous",
"type": "httpTrigger",
"direction": "in",
"name": "req",
"methods": [
"get",
"post"
]
},
{
"type": "http",
"direction": "out",
"name": "$return"
}
]
}
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
)
Any help would be appreciated!
I came across this too. Not sure what caused it.
But what fixed it for me was to download, uninstall, and reinstall the Azure Functions Core Tools
(using 'repair' just returned a generic "Failed due to error", and I had to kill PowerToys)
Not sure if it's necessary, but I also cleared my nuget cache
dotnet nuget locals all -c
dotnet restore # in your sln folder
And reinstalled my vscode Azure plugins
I ran into exactly the same problem while running the Azure Function v4 using the Azure CLI:
"azure-cli": "2.37.0",
"azure-cli-core": "2.37.0",
"azure-cli-telemetry": "1.0.6",
"extensions": {}
I fixed it by just reinstalling Azure Functions Core Tools (part of the answer by Lightfire) All the other actions had no effect for me.
Link to Install Azure Functions Core Tools

Delete CosmosDB Container Items

I am trying to create an Azure Function (implemented in Python) to delete an item in a CosmosDB container. Using Azure Cosmos DB Input & Output bindings, I was able to add, query and update items but I was not able to find a method that could delete one. Is it possible to delete an item using the binding methods?
The following code is what I am currently using to do a simple update.
_init_.py file
import logging
import azure.functions as func
def main(req: func.HttpRequest, doc: func.Out[func.Document]) -> func.HttpResponse:
logging.info('Python HTTP trigger function processed a request.')
departure_time = ""
arrival_time = ""
try:
req_body = req.get_json()
except ValueError:
pass
else:
bc_id_no = req_body.get('bc_id_no')
trip_id = req_body.get('trip_id')
departure_time = req_body.get('departure_time')
arrival_time = req_body.get('arrival_time')
if bc_id_no and trip_id:
newdocs = func.DocumentList()
input_dict = {
"bc_id_no": bc_id_no,
"id": trip_id,
"departure_time": departure_time,
"arrival_time": arrival_time
}
newdocs.append(func.Document.from_dict(input_dict))
doc.set(newdocs)
return func.HttpResponse(f"This HTTP triggered function executed successfully.")
else:
return func.HttpResponse(
"bc_id_no or trip_id not available",
status_code=200
)
function.json
{
"scriptFile": "__init__.py",
"bindings": [
{
"authLevel": "anonymous",
"type": "httpTrigger",
"direction": "in",
"name": "req",
"methods": [
"get",
"post"
],
"route": "update_rec"
},
{
"type": "cosmosDB",
"direction": "out",
"name": "doc",
"databaseName": "mockDB",
"collectionName": "mockCollection",
"connectionStringSetting": "AzureCosmosDBConnectionString"
},
{
"type": "http",
"direction": "out",
"name": "$return"
}
]
}
Understand that it may be possible to use the sqlQuery configuration properties for the input binding to specify a delete statement (not too sure if this is a good practice even..) but just wondering if another method for deletion is available.
The bindings only support querying, reading (Input binding), or adding (Output binding), there is no Delete support.
There is no configuration you can pass that would make the binding execute a Delete, it's just not there in the code: https://github.com/Azure/azure-webjobs-sdk-extensions/tree/cosmos/v3.x/src/WebJobs.Extensions.CosmosDB
The only alternative I can think of is if you used the Python SDK directly inside the Function to perform the delete: https://learn.microsoft.com/azure/cosmos-db/sql-api-sdk-python
Just make sure that the instance is created and maintained outside of the execution scope: https://learn.microsoft.com/azure/azure-functions/manage-connections#static-clients

upload hyperlink data to azure binding

I am trying to stream data from hyperlink destination to azure storage. I have to do this via binding since I want to run this from azure function App.
file -- function.json:
{
"scriptFile": "__init__.py",
"bindings": [
{
"authLevel": "anonymous",
"type": "httpTrigger",
"direction": "in",
"name": "req",
"methods": [
"get",
"post"
]
},
{
"type": "http",
"direction": "out",
"name": "$return"
},
{
"type": "blob",
"direction": "out",
"name": "outputBlob",
"path": "samples-workitems/{rand-guid}",
"connection": ""
}
]
}
file -- init.py:
import logging
import cdsapi
import azure.functions as func
from azure.storage.blob import BlobServiceClient, BlobClient, ContainerClient
def main(req: func.HttpRequest, outputBlob:func.Out[func.InputStream]) -> func.HttpResponse:
logging.info('Python HTTP trigger function is about to process request.')
try:
source_blob="http://www.africau.edu/images/default/sample.pdf"
with open(source_blob, "rb") as data:
print(data)
outputBlob.set(data)
except Exception as ex:
logging.info(" error!", ex, "occurred.")
return func.HttpResponse(
"This HTTP triggered function executed successfully.",
status_code=200
)
I have tested binding and it works. When I simply do outputBlob.set("sample string") data is streamed as it should be.
I am stuck with converting data from hyperlink to bytes(or blob). While running code above, i get error Exception: TypeError: not all arguments converted during string formatting. Any help in converting this and uploading to azure storage is appreciated.
Problem is you were trying to read the File from URL with open(source_blob, "rb") as data: which of course won't work since open is for local files only. I have changed your code as below using requests module to get the remote URL response and set the content to blob.
import requests
source_url="http://www.africau.edu/images/default/sample.pdf"
with requests.get(source_url, stream=True) as r:
r.raise_for_status()
outputBlob.set(r.content)

I'm getting Value 'func.Out' is unsubscriptable trying to write in an azure blob storage using a python function

I want to write in an azure blob storage using Azure Functions in Python.
I'm using the output blob storage bindings for Azure Functions.
My function.json:
{
"scriptFile": "__init__.py",
"bindings": [
{
"authLevel": "anonymous",
"type": "httpTrigger",
"direction": "in",
"name": "req",
"methods": [
"get",
"post"
]
},
{
"name": "inputblob",
"type": "blob",
"path": "{containerName}/{blobName}.json",
"connection": "MyStorageConnectionAppSetting",
"direction": "in"
},
{
"name": "outputblob",
"type": "blob",
"path": "{containerName}/{blobName}.json",
"connection": "MyStorageConnectionAppSetting",
"direction": "out"
},
{
"type": "http",
"direction": "out",
"name": "$return"
}
]
}
And my Python code looks like this:
import logging
import azure.functions as func
import azure.storage.blob
from azure.storage.blob import BlobServiceClient, BlobClient, ContainerClient
import json, os
def main(req: func.HttpRequest, inputblob: func.InputStream, outputblob: func.Out[func.InputStream]) -> func.HttpResponse:
logging.info('Python HTTP trigger function processed a request.')
# Initialize variable for tracking any changes
anyChanges= False
# Read JSON file
jsonData= json.loads(inputblob.read())
# Make changes to jsonData (omitted for simplicity) and update anyChanges
# Upload new JSON file
if anyChanges:
outputblob.set(jsonData)
return func.HttpResponse(f"Input data: {jsonData}. Any changes: {anyChanges}.")
However, this isn't working at all, with the following error being thrown:
Value 'func.Out' is unsubscriptable
Another guy in December already asked for a resolution to the same issue, but the answer does not solve the issue
Same issue using 3.7.0 switched to 3.6.8 to solve it
I've had the same issue, and I actually found out that's the problem is resolved by removing pylint library:
pip uninstall pylint
I am not sure if that is a problem in pylint or if Azure Functions cannot coexist with pylint in Python 3.7, but removing it did the trick for me.
Instead of uninstalling pylint, you can simply disable that specific warning:
# pylint: disable=unsubscriptable-object
def main(req: func.HttpRequest, inputblob: func.InputStream, outputblob: func.Out[func.InputStream]) -> func.HttpResponse:
# your code

Categories