I am trying to publish a machine learning model on Azure webservice using python. I am able to deploy the code successfully but when i try to call it through the URL, it's throwing me 'Azure' module doesn't exist. The code basically retrieves a TFIDF model from the container (blob) and use it to predict the new value. The error clearly says, Azure package is missing while trying to run on the webservice and I am not sure how to fix it. Here goes the code:
For deployment:
from azureml import services
from azure.storage.blob import BlobService
#services.publish('7c94eb2d9e4c01cbe7ce1063','f78QWNcOXHt9J+Qt1GMzgdEt+m3NXby9JL`npT7XX8ZAGdRZIX/NZ4lL2CkRkGQ==')
#services.types(res=unicode)
#services.returns(str)
def TechBot(res):
from azure.storage.blob import BlobService
from gensim.similarities import SparseMatrixSimilarity, MatrixSimilarity, Similarity
blob_service = BlobService(account_name='tfidf', account_key='RU4R/NIVPsPOoR0bgiJMtosHJMbK1+AVHG0sJCHT6jIdKPRz3cIMYTsrQ5BBD5SELKHUXgBHNmvsIlhEdqUCzw==')
blob_service.get_blob_to_path('techbot',"2014.csv","df")
df=pd.read_csv("df")
doct = res
To access the url I used the python code from
service.azureml.net
import urllib2
import json
import requests
data = {
"Inputs": {
"input1":
[
{
'res': "wifi wnable",
}
],
},
"GlobalParameters": {
}
}
body = str.encode(json.dumps(data))
#proxies = {"http":"http://%s" % proxy}
url = 'http://ussouthcentral.services.azureml.net/workspaces/7c94eb2de26a45399e4c01cbe7ce1063/services/11943e537e0741beb466cd91f738d073/execute?api-version=2.0&format=swagger'
api_key = '8fH9kp67pEt3C6XK9sXDLbyYl5cBNEwYg9VY92xvkxNd+cd2w46sF1ckC3jqrL/m8joV7o3rsTRUydkzRGDYig==' # Replace this with the API key for the web service
headers = {'Content-Type':'application/json', 'Authorization':('Bearer '+ api_key)}
#proxy_support = urllib2.ProxyHandler(proxies)
#opener = urllib2.build_opener(proxy_support, urllib2.HTTPHandler(debuglevel=1))
#urllib2.install_opener(opener)
req = urllib2.Request(url, body, headers)
try:
response = urllib2.urlopen(req, timeout=60)
result = response.read()
print(result)
except urllib2.HTTPError, error:
print("The request failed with status code: " + str(error.code))
# Print the headers - they include the requert ID and the timestamp, which are useful for debugging the failure
print(error.info())
print(json.loads(error.read()))
The string 'res' will be predicted at the end. As I said it runs perfectly fine if I run as it is in python by calling azure module, problem happens when I access the url.
Any help is appreciated, please let me know if you need more information (I only sohwcased half of my code)
I tried to reproduce the issue via POSTMAN, then I got the error information below as you said.
{
"error": {
"code": "ModuleExecutionError",
"message": "Module execution encountered an error.",
"details": [
{
"code": "85",
"target": "Execute Python Script RRS",
"message": "Error 0085: The following error occurred during script evaluation, please view the output log for more information:\r\n---------- Start of error message from Python interpreter ----------\r\nCaught exception while executing function: Traceback (most recent call last):\n File \"\\server\\InvokePy.py\", line 120, in executeScript\n outframe = mod.azureml_main(*inframes)\n File \"\\temp\\1280677032.py\", line 1094, in azureml_main\n File \"<ipython-input-15-bd03d199b8d9>\", line 6, in TechBot_2\nImportError: No module named azure\n\r\n\r\n---------- End of error message from Python interpreter ----------"
}
]
}
}
According to the error code 00085 & the information ImportError: No module named azure, I think the issue was caused by importing python moduleazure-storage. There was a similar SO thread Access Azure blog storage from within an Azure ML experiment which got the same issue, I think you can refer to its answer try to use HTTP protocol instead HTTPS in your code to resolve the issue as the code client = BlobService(STORAGE_ACCOUNT, STORAGE_KEY, protocol="http").
Hope it helps. Any concern & update, please feel free to let me know.
Update: Using HTTP protocol for BlobService
from azureml import services
from azure.storage.blob import BlobService
#services.publish('7c94eb2d9e4c01cbe7ce1063','f78QWNcOXHt9J+Qt1GMzgdEt+m3NXby9JL`npT7XX8ZAGdRZIX/NZ4lL2CkRkGQ==')
#services.types(res=unicode)
#services.returns(str)
def TechBot(res):
from azure.storage.blob import BlobService
from gensim.similarities import SparseMatrixSimilarity, MatrixSimilarity, Similarity
# Begin: Update code
# Using `HTTP` protocol for BlobService
blob_service = BlobService(account_name='tfidf',
account_key='RU4R/NIVPsPOoR0bgiJMtosHJMbK1+AVHG0sJCHT6jIdKPRz3cIMYTsrQ5BBD5SELKHUXgBHNmvsIlhEdqUCzw==',
protocol='http')
# End
blob_service.get_blob_to_path('techbot',"2014.csv","df")
df=pd.read_csv("df")
doct = res
Related
When I run the script as a cloud function it can find the job name but when I run it in cloud run jobs it can't find the job name.
What exactly am I doing wrong?
httpRequest: {1}
insertId: "8vr1cwfi77fef"
jsonPayload: {
#type: "type.googleapis.com/google.cloud.scheduler.logging.AttemptFinished"
jobName: "projects/api-data-pod/locations/us-central1/jobs/mouse-recording"
status: "NOT_FOUND"
targetType: "HTTP"
url: "https://us-central1-run.googleapis.com/apis/run.googleapis.com/v1/namespaces/api-data-pod/jobs/mouseflowrecording:run"
}
logName: "projects/api-data-pod/logs/cloudscheduler.googleapis.com%2Fexecutions"
receiveTimestamp: "2022-08-02T11:54:04.664184360Z"
resource: {
labels: {3}
type: "cloud_scheduler_job"
}
severity: "ERROR"
timestamp: "2022-08-02T11:54:04.664184360Z"
}
import requests
import json
import pandas as pd
import pandas_gbq
from google.cloud import bigquery
from requests.auth import HTTPBasicAuth
#import schedule
#import time
def rec(request):
r = requests.get("https://api-eu.mouseflow.com/websites/e768ed54-c09b-48dc-bf49-beda12697013/recordings",
auth=HTTPBasicAuth("*************", "********************"))
if r.status_code == 200:
parsed = json.loads(r.text)
print(json.dumps(parsed['recordings'], indent=4, sort_keys=True))
df = pd.DataFrame.from_records(parsed['recordings'])
#print(df.dtypes)
#df.to_csv('mousedata3.csv')#
try:
temp_csv_string = df.to_csv(sep=";", index=False)
temp_csv_string_IO = StringIO(temp_csv_string)
# create new dataframe from string variable
new_df = pd.read_csv(temp_csv_string_IO, sep=";")
# this new df can be uploaded to BQ with no issues
new_df.to_gbq('Mouseflow.Mouseflow_Recording', if_exists='replace', project_id='api-data-pod')
return f'Successful'
except Exception as err:
return f'Upload to BigQuery failed: {err}'
else:
return f'API request error occurred: Status code {r.status_code}'
rec(requests.request)```
Hi here is the python code that is causing the problem.
It works with cloud functions perfectly but it can't find the jobname of cloud run jobs for some reason.
The only difference with the cloud function code is that I don;t have an end to function as it is not needed. So this is not at the end of my code rec(requests.request).
I hope this is explains things a bit better.
I'm trying to replace a Google slides shape filled with a placeholder text with an image via API. The image in question is allocated in a team Drive unit. I've read several solutions like this and this, and I have tried to set the permissions in the image as "reader" and "anyone with link", both via API and manually, and nothing works. I get a "Access to the provided image was forbidden" error everytime. However, I can download the image wihout problems via API and without giving extra permissions.
I'm using v3 of the Drive API and v1 for Slides API.
Below is the code I'm using:
def replace_shape_with_image(slides_service, url, presentation_id, contains_text):
requests = [
{
"replaceAllShapesWithImage": {
"imageUrl": url,
"replaceMethod": "CENTER_INSIDE",
"containsText": {
"text": "{{" + contains_text + "}}",
}
}
}]
body = {
'requests': requests
}
response = slides_service.presentations().batchUpdate(presentationId=presentation_id,body=body).execute()
return response
def create_public_permissions(drive_service, file_id):
request = drive_service.permissions().create(
fileId=file_id,
supportsAllDrives=True,
fields='id, type, role',
body={
'role':'reader',
'type':'anyone'
}
)
response = request.execute()
return response
file_id = '123'
presentation_id = '789'
# drive_service = etc
# slides_service = etc
create_public_permissions(drive_service, file_id) # Here I put the actual service object and file ID. Manually verified and it works
url = f'https://drive.google.com/uc?export=download&id={file_id}'
# also tried url = https://drive.google.com/uc?id={file_id}&export=download
replace_shape_with_image(slides_service, url, presentation_id, 'test') # shape in slide has "test" as text
The following error is returned:
googleapiclient.errors.HttpError: <HttpError 400 when requesting
https://slides.googleapis.com/v1/presentations/1cDSov4IKFHSyzaXjFYNYPB7EYlMMtInamYv0AwXiazw:batchUpdate?alt=json
returned "Invalid requests[0].replaceAllShapesWithImage: Access to the
provided image was forbidden.">
For downloading the file I use this code, which works without problem:
import io
from googleapiclient.http import MediaIoBaseDownload
tmp_file_path = r'C:\Users\me\tmp\testimage.png'
fh = io.FileIO(tmp_file_path, 'wb')
downloader = MediaIoBaseDownload(fh, request)
done = False
while done is False:
status, done = downloader.next_chunk()
I know there have been changes in the Drive API recently (over the last year), and most questions about this are old and the solutions are deprecated, and more recent ones doesn't seem to work for me. Any ideas in how to solve this issue, if possible?
Thanks in advance!
It's known issue: https://issuetracker.google.com/issues/150933939
As it was happening with one of our projects, we figured out that error is thrown not for all Google Drive images, but for random ones when using replaceAllShapesWithImage Slides API request.
Only possible workaround is to wrap your requests code in try / catch and use some placeholder image in case replaceAllShapesWithImage requests are keep failing.
Example code (in Google Apps Script):
var slideImageNotFoundPlaceholder = 'https://example.com/../placeholder.png';
try {
Slides.Presentations.batchUpdate({'requests': slidesReqs}, presentationFileId);
}
catch(err)
{
// loop all requests
for (var i = 0; i < slidesReqs.length; i++)
{
// update replaceAllShapesWithImage requests
if (slidesReqs[i].replaceAllShapesWithImage)
{
// replace with image not found placeholder
slidesReqs[i].replaceAllShapesWithImage.imageUrl = slideImageNotFoundPlaceholder;
}
}
Slides.Presentations.batchUpdate({'requests': slidesReqs}, presentationFileId);
}
It is not perfect solution, but all other requests are getting executed, so you won't have your presentations being totally failed.
P.S. hopefully Google will fix Google Drive images being used in Slides API, so "star" the issue linked in the beginning of the answer to make it happen faster.
I have created an Azure Cognitive Services resource following the tutorial 1
Then I have created the environment and run the following code (from tutorial 2):
# Import required modules.
from azure.cognitiveservices.search.websearch import WebSearchAPI
from azure.cognitiveservices.search.websearch.models import SafeSearch
from msrest.authentication import CognitiveServicesCredentials
# Replace with your subscription key.
subscription_key = "YOUR_SUBSCRIPTION_KEY"
# Instantiate the client and replace with your endpoint.
client = WebSearchAPI(CognitiveServicesCredentials(subscription_key), base_url = "YOUR_ENDPOINT")
# Make a request. Replace Yosemite if you'd like.
web_data = client.web.search(query="Yosemite")
print("\r\nSearched for Query# \" Yosemite \"")
However, it seems the generaed Subscription key and endpoint are not correctly read by the script since I get the following error:
File "azu_scrapper.py", line 17, in
web_data = client.web.search(query="Yosemite") File "/home/user/.local/share/virtualenvs/linkedin-CHSAGU1d/lib/python3.7/site-packages/azure/cognitiveservices/search/websearch/operations/web_operations.py",
line 365, in search
raise models.ErrorResponseException(self._deserialize, response) azure.cognitiveservices.search.websearch.models.error_response_py3.ErrorResponseException:
Operation returned an invalid status code 'Resource Not Found'
Any idea why it is not working?
The base_url value should be :
https://<your endpoint>/bing/v7.0
I have tested on my side and it works for me :
I try to follow MS official doc to get the log from my resource in Azure Log Monitor but never success.
My code is like below.
from azure.loganalytics import LogAnalyticsDataClient
from azure.common.client_factory import get_client_from_cli_profile
from azure.loganalytics.models import QueryBody
log_client = get_client_from_cli_profile(LogAnalyticsDataClient)
myWorkSpaceId = '1234567890...'
result = log_client.query(myWorkSpaceId, QueryBody(**{'query': 'Heartbeat| limit 50'}))
And I always get exception like below:
result = log_client.query(myWorkSpaceId, QueryBody(**{'query': 'Heartbeat| limit 50'}))
File ".../lib/python2.7/site-packages/azure/loganalytics/log_analytics_data_client.py", line 121, in query
raise models.ErrorResponseException(self._deserialize, response)
azure.loganalytics.models.error_response.ErrorResponseException: (MissingApiVersionParameter) The api-version query parameter (?api-version=) is required for all requests
I trace code into library in /azure/loganalytics/log_analytics_data_client.py, and dump the url string used for query like below.
print(url, query_parameters, header_parameters, body_content)
request = self._client.post(url, query_parameters)
response = self._client.send(request, header_parameters, body_content, stream=False, **operation_config)
The output of the url and query information is like below and it look like no version information in between and I doubt this is why I get the exception:
('https://management.azure.com/workspaces/1234567890.../query', {}, {'Content-Type': 'application/json; charset=utf-8'}, {'query': 'Heartbeat| limit 50'})
My azure SDK version is 4.0.0, and my azure-loganalytics library version is v0.1.0, running on Ubuntu.
Does anyone run into same issue or know how to fix this?
Thanks.
The code that I included to call a API in AWS lambda is given below. urlilb3 python library is uploaded as a zip folder successfully. But when I try to access the particular intent it shows
When I included the API call in AWS lambda (python 3.6), I got
"The remote endpoint could not be called, or the response it returned was invalid" .
Why is it so? What are the prerequisites to be done before including the API calls in python 3.6. I used urllib3 python library and upload as zip folder.?? Is any other things required to do??
def get_weather(session):
should_end_session = False
speech_output = " "
reprompt_text = ""
api = "some url ...."
http = urllib3.PoolManager()
response = http.request('GET',api)
weather_status = json.loads(response.data.decode('utf-8'))
for weather in weather_status:
final_weather = weather["WeatherText"]
return build_response(session_attributes, build_speechlet_response(speech_output, reprompt_text, should_end_session))
Scenario : To obtain weather using an third party API
import urllib3
def get_weather():
api = "some url ...."
http = urllib3.PoolManager()
response = http.request('GET',api)
weather_status = json.loads(response.data.decode('utf-8'))
for weather in weather_status:
final_weather = weather["WeatherText"] ## The attribute "WeatherText" will varies depending upon the weather API you are using.
return final_weather
get_weather() # simple function call
Try printing response.data so you can see it in the logs. That might give you a clue. I would also try to switch to Python Requests instead of URLLib3. You may also need to set the Content Type depending on the implementation of the API you're calling.
from __future__ import print_function
import json
from botocore.vendored import requests
def lambda_handler(event, context):
print('received request: ' + str(event))
doctor_intent = event['currentIntent']['slots']['doctor']
email_intent = event['currentIntent']['slots']['email']
print(doctor_intent, email_intent)
print(type(doctor_intent), type(email_intent))
utf8string = doctor_intent.encode("utf-8")
utf8string1 = email_intent.encode("utf-8")
print(type(utf8string))
print(type(utf8string1))
car1 = {"business_name": utf8string , "customer_email": utf8string1 }
r = requests.post('https://postgresheroku.herokuapp.com/update',
json=car1)
#print ("JSON : ", r.json())
print(r.json())
data = str(r.json())
print(type(data))
return {
"dialogAction": {
"type": "Close",
"fulfillmentState": "Fulfilled",
"message": {
"contentType": "PlainText",
"content": "Thank you for booking appointment with {doctor}
{response}".format(doctor=doctor_intent,response=data)
}
}
}