I'm deploying some lambda functions and at the end, I need to print the complete URL of the latest CloudWatch log stream. So that other users can view the log directly by clicking the URL.
I've tried the below, but I need to print the complete URL.
print("CloudWatch log stream name:", context.log_stream_name)
I believe this can be done by using describe_log_streams along with some tweaks. But I'm helpless where to start.
I tried the below code and its working as expected, please comment for any improvement.
def multiple_replace(text, adict):
rx = re.compile('|'.join(map(re.escape, adict)))
def one_xlat(match):
return adict[match.group(0)]
return rx.sub(one_xlat, text)
def main(event, context):
region = context.invoked_function_arn.split(':')[3]
replace_map = {}
replace_map['/']='$252F'
replace_map['[']='$255B'
replace_map['$']='$2524'
replace_map[']']='$255D'
cw_logs = 'https://' + region + '.console.aws.amazon.com/cloudwatch/home?region=' + region + '#logsV2:log-groups/log-group/' + context.log_group_name.replace('/', '%252F') + '/log-events/' + multiple_replace(context.log_stream_name,replace_map)
Related
I'm working on a script to programmatically create a bunch of intents. I want to set the input context for these intents to a specific value. I have working code that creates the full intent - but I can't get the parameter for input context to work.
This works (in python), but does not create an input context:
intents_client = dialogflow_v2beta1.IntentsClient.from_service_account_json(PROJECT_JSON)
parent = intents_client.project_agent_path(PROJECT_ID)
training_phrases = []
part1 = dialogflow_v2beta1.types.Intent.TrainingPhrase.Part(text="hello ")
parts = []
parts.append(part1)
training_phrase = dialogflow_v2beta1.types.Intent.TrainingPhrase(parts=parts)
training_phrases.append(training_phrase)
text = dialogflow_v2beta1.types.Intent.Message.Text(text=["say hello"])
message = dialogflow_v2beta1.types.Intent.Message(text=text)
messages = []
messages.append(message)
intent = dialogflow_v2beta1.types.Intent(
display_name='Mike_Hello',
training_phrases=training_phrases,
messages=messages)
response = intents_client.create_intent(parent, intent, language_code=LANGUAGE)
But, when I add the following to my Intent definition:
intent = dialogflow_v2beta1.types.Intent(
display_name='Mike_Hello',
input_context_names=['5000'],
training_phrases=training_phrases,
messages=messages)
(ie - adding the input_context_names parameter)
The intent creation fails with an error:
Resource name does not match format 'projects/{project_id}/agent/sessions/{session_id}/contexts/{context_id}'
I tried creating a context with a context client and create_context, but it fails with the same error. The create_context API seems to me to be more related to creating a context for inputting into detect_intent, as it wants a live SESSION_ID as input.
I can replace ["5000"] in the input_context above with 'projects/PROJECT_ID/agent/sessions/-/contexts/5000', and I get the same error.
Bug? Or am I missing something?
Found the problem.
The entity string:
'projects/' + PROJECT_ID + '/agent/sessions/-/contexts/my_ctx_name'
works great.
The entity string:
'/projects/' + PROJECT_ID + '/agent/sessions/-/contexts/my_ctx_name'
does not work. My problem was the leading '/' before 'projects'.
I am trying to submit a hit using the example provided in mturk example
Here is my question.xml:
<?xml version="1.0" encoding="UTF-8"?>
<ExternalQuestion xmlns="http://mechanicalturk.amazonaws.com/AWSMechanicalTurkDataSchemas/2011-11-11/HTMLQuestion.xsd">
<ExternalURL>https://tictactoe.amazon.com/gamesurvey.cgi?gameid=01523</ExternalURL>
<FrameHeight>750</FrameHeight>
</ExternalQuestion>
and here is my submit_hit.py:
import boto3
from dateutil.parser import *
MTURK_SANDBOX = 'https://mturk-requester-sandbox.us-east-1.amazonaws.com'
mturk = boto3.client('mturk',
aws_access_key_id = "....",
aws_secret_access_key = "....",
region_name='us-east-1',
endpoint_url = MTURK_SANDBOX
)
print "I have $" + mturk.get_account_balance()['AvailableBalance'] + " in my Sandbox account"
question = open(name='question.xml',mode='r').read()
new_hit = mturk.create_hit(
Title = 'Here comes the title',
Description = 'Here comes description'
Keywords = 'game, quick',
Reward = '0.15',
MaxAssignments = 1,
LifetimeInSeconds = 172800,
AssignmentDurationInSeconds = 600,
AutoApprovalDelayInSeconds = 14400,
Question = question,
)
print "A new HIT has been created. You can preview it here:"
print "https://workersandbox.mturk.com/mturk/preview?groupId=" + new_hit['HIT']['HITGroupId']
print "HITID = " + new_hit['HIT']['HITId'] + " (Use to Get Results)"
And here is the error I am receiving:
botocore.exceptions.ClientError: An error occurred (ParameterValidationError) when calling the CreateHIT operation: There was an error parsing the XML question or answer data in your request. Please make sure the data is well-formed and validates against the appropriate schema. Details: cvc-elt.1: Cannot find the declaration of element 'ExternalQuestion'. (1579649552886 s)
I need to use external url(i.e. I can not copy my html file in .xml) since my html content is web-based tool and not a simple questionare.
I am using python 2.7 if that matters.
Any help would be very much appreciated.
Turned out I was using tag <ExternalQuestion>, BUT I was using the http link for <HTMLQuestion>! make sure you're using the right link.
So, instead of this:
<ExternalQuestion
xmlns="http://mechanicalturk.amazonaws.com/AWSMechanicalTurkDataSchemas/2011-11-11/HTMLQuestion.xsd">
it should be this:
<ExternalQuestion xmlns="http://mechanicalturk.amazonaws.com/AWSMechanicalTurkDataSchemas/2006-07-14/ExternalQuestion.xsd">
I've read about the offset parameter in the documentation; however, I can't figure out how to use it. Here's my code so far. Unfortunately only the first 100 songs are retrieved from the playlist. How do I change the index so that I can retrieve more songs from a playlist?
import os, re, shutil
import spotipy
import spotipy.util as util
import time
# Parameters
username = 'REDACTED'
client_id = 'REDACTED'
client_secret = 'REDACTED'
redirect_uri = 'http://localhost/'
scope = 'user-library-read'
playlist = '17gneMykp6L6O5R70wm0gE'
def show_tracks(tracks):
for i, item in enumerate(tracks['items']):
track = item['track']
myName = re.sub('[^A-Za-z0-9\ ]+', '', track['name'])
dirName = "/Users/pschorn/Songs/" + myName + ".app"
if os.path.exists(dirName):
continue
#shutil.rmtree(dirName)
os.mkdir(dirName)
os.mkdir(dirName + "/Contents")
with open(dirName + "/Contents/PkgInfo", "w+") as f:
f.write("APPL????")
os.mkdir(dirName + "/Contents/MacOS")
with open(dirName + "/Contents/MacOS/" + myName, "w+") as f:
f.write("#!/bin/bash\n")
f.write("osascript -e \'tell application \"Spotify\" to play track \"{}\"\'".format(track['uri']))
os.lchmod(dirName + "/Contents/MacOS/" + myName, 0o777)
myName = re.sub('\ ', '\\ ', myName)
# I've installed a third-party command-line utility that
# allows me to set the icon for applications.
# If there's a way to do this from python, let me know.
os.system(
'/usr/local/bin/fileicon set /Users/pschorn/Songs/' + myName + '.app /Users/pschorn/Code/PyCharmSupport/Icon.icns')
token = util.prompt_for_user_token(username, scope, client_id, client_secret, redirect_uri)
if token:
sp = spotipy.Spotify(auth=token)
results = sp.user_playlist(username, playlist, fields="tracks,next")
tracks = results['tracks', offset=100]
show_tracks(tracks)
else:
print("Can't get token for", username)
EDIT: I've since figured out how to return songs starting at a given index and much more than that. You can check out my code here! It retrieves all the songs in all of the user's playlists and makes an application for each one that can be opened to play the song. The purpose of this is so that you can play your Spotify songs directly from spotlight search!
This custom class I wrote that extends functionality offered by the Spotipy library has a wrapper function that handles offsets.
def user_playlist_tracks_full(spotify, user, playlist_id=None, fields=None, market=None):
""" Get full details of the tracks of a playlist owned by a user.
Parameters:
- spotify - spotipy instance
- user - the id of the user
- playlist_id - the id of the playlist
- fields - which fields to return
- market - an ISO 3166-1 alpha-2 country code.
"""
# first run through also retrieves total no of songs in library
response = spotify.user_playlist_tracks(user, playlist_id, fields=fields, limit=100, market=market)
results = response["items"]
# subsequently runs until it hits the user-defined limit or has read all songs in the library
while len(results) < response["total"]:
response = spotify.user_playlist_tracks(
user, playlist_id, fields=fields, limit=100, offset=len(results), market=market
)
results.extend(response["items"])
return results
This code might be enough to illustrate what you have to do, loop over and change the offset each time.
The full class is in a standalone gist that should work, in this example I've just replaced self with spotify.
I have the following code to make a Stream Listener and get tweets from the Twitter API.
class MyStreamListener(tweepy.StreamListener):
#class constructor
def __init__(self,api=None):
super(MyStreamListener,self).__init__()
#creates class variables and instantiates to file and number
self.num_tweets = 0
self.file = open("tweets.txt",'w')
#function to collect tweets and add to file
def on_status (self,status):
tweet = status._json
print("Tweet: " + tweet)
print("STATUS: " + status.text)
self.file.write(json.dumps(tweet)+'\n')
print(status)
self.num_tweets+=1
if self.num_tweets < 100:
return True
else:
return False
self.file.close()
l = MyStreamListener()
stream = tweepy.Stream(auth,l)
stream.filter(track=[])
Although there are no errors with this code, the program does not print anything as is the projected output in the lines
print("Tweet: " + tweet)
print("STATUS: " + status.text)
I have tried to adjust the line
stream.filter(track=[])
to include
stream.filter(track=['trump','clinton'])
but I still did not receive any output.
Help on why this problem is occurring or a possible solution would be appreciated.
EDIT: Future debugging shows that the on_status function is not even running at any time, despite the fact that this is shown in the tweepy docs.
If you want to use Tweepy's StreamListener to filter tweets by just a keyword like trump or clinton, I think you're better off overriding the on_data method instead. You should receive the data like you're expecting then.
I'd double check this but it seems like their docs are down?
Why don't you use the json.loads() function to obtain all the data? That gives a nicer format to work from:
def on_status (self, status):
all_data = json.loads(status)
tweet = all_data['text']
print("Tweet: " + tweet)
print("STATUS: " + all_data + '\n')
self.file.write(tweet) + '\n')
Now you have your status as a dictionary format in all_data that you can access to find the Tweet and all other variables.
It appears the problem was in an incorrect access key, the error code was not printing for some reason. I solved the problem by rewriting the class and creating a new streaming application with a new key.
I am trying to share a blob in a private Azure blob storage container using Python SDK, below is the code:
try:
accss_plcy = AccessPolicy()
accss_plcy.start = '2013-03-12'
accss_plcy.expiry = '2013-03-13'
accss_plcy.permission = 'r'
signed_identifier = 'YWJjZGVmZw=='
sap = SharedAccessPolicy(accss_plcy, signed_identifier)
qry_str = sas.generate_signed_query_string('picture/xxx.jpg','blob', sap)
except Exception as ex:
abort(400, 'Download blob fail %s'%ex)
return sas._convert_query_string(qry_str)
Below is the query string return :
st=2013-03-12&se=2013-03-13&sp=r&resource=blob&sig=FI88prUINf58Seg5Nwo6Uj5RP9FxXGZBBSKi7pybmeQ=&
You may notice that resource=blob, but it should return sr=b.
How should I solve the problem?
It looks like a bug in the SDK. Since the code for Azure SDK is open source, you could possibly download the code and make change to this file: https://github.com/WindowsAzure/azure-sdk-for-python/blob/master/src/azure/storage/sharedaccesssignature.py. Looking at the source code in that file, you would need to change the following line of code (line 129):
convert_str += SIGNED_RESOURCE_TYPE + '=' + query_string[SIGNED_RESOURCE] + '&'
to
convert_str += SIGNED_RESOURCE + '=' + query_string[SIGNED_RESOURCE] + '&'
Also I noticed that you're passing blob as the resource type in your code above:
qry_str = sas.generate_signed_query_string('picture/xxx.jpg','blob', sap)
You would need to pass 'b' instead of 'blob'
qry_str = sas.generate_signed_query_string('picture/xxx.jpg','b', sap)
I think that should do the trick. Also please ensure that you submit a bug on Github so that the team responsible for maintaining the code can fix it.