For those of you who have experience with Strava API - I used the documentation on their developer site: https://developers.strava.com/docs/reference/#api-Activities-getLoggedInAthleteActivities
However, copying their code over I get an attribute error-
AttributeError: 'ActivitiesApi' object has no attribute 'getActivityById'
AttributeError: 'ActivitiesApi' object has no attribute 'getLoggedInAthleteActivities'
Any idea why? Obviously inputted my ID/secret/token as from their website. Code below:
import time
import swagger_client
from swagger_client.rest import ApiException
from pprint import pprint
STRAVA_CLIENT_ID = MY_CLIENT_ID
STRAVA_CLIENT_SECRET = 'MY_CLIENT_SECRET'
STRAVA_ACCESS_TOKEN = 'MY_ACCESS_TOKEN'
swagger_client.configuration.access_token = STRAVA_ACCESS_TOKEN
api_instance = swagger_client.ActivitiesApi()
def get_activity_data():
activity_id = 3307145226
includeAllEfforts = True # Boolean | To include all segments efforts. (optional)
try:
# Get Activity
api_response = api_instance.getActivityById(id,
includeAllEfforts=includeAllEfforts)
pprint(api_response)
except ApiException as e:
print("Exception when calling ActivitiesApi->getActivityById: %s\n" % e)
return
Looks like you have an error for passing the id to getActivityById. Your activity id variable is activity_id but you're passing in id. Not sure if that will fix your issue or not but it's a start.
Related
Code:
import time
import giphy_client
from giphy_client.rest import ApiException
from pprint import pprint
def giphyapi():
api_instance = giphy_client.DefaultApi()
api_key = '################################'
tag = 'test'
rating = 'pg-13'
fmt = 'json'
try:
# Search Endpoint
api_response = api_instance.gifs_random_get(api_key, tag = tag, rating = rating, fmt = fmt)
## here’s where I want to do stuff with the data
except ApiException as exc:
print("Exception when calling DefaultApi->gifs_random_get: %s\n" % exc)
return None
giphyapi()
Hi! How do I convert api_instance into something manipulatable, such as a dict?
This is the same problem as this, but the solution that the question author found sadly did not work for me.
I have tried print(api_response.data[0].images.type), but that threw this error:
TypeError: 'RandomGif' object is not subscriptable
I also tried this:
for block in api_response["data"]:
giftype = block["type"]
But that threw this error:
TypeError: 'InlineResponse2002' object is not subscriptable
I’m using Python 3.8.1, and I’m also using giphy-python-client. Here is a list of RandomGif models. The one I’m trying to fetch in the two examples of what I tried above is type.
Any help is greatly appreciated! 🙂
I solved it thanks to shoot2thr1ll284 on Reddit.
You just use api_response.data.type and replace type with the property that you want to fetch.
#pytest.fixture
def settings():
with open('../config.yaml') as yaml_stream:
return yaml.load(stream=yaml_stream)
#pytest.fixture
def viewers(settings):
try:
data = requests.get(settings['endpoints']['viewers']).json()
return data[0]['viewers']
except Exception:
print('ERROR retrieving viewers')
raise(SystemExit)
#pytest.fixture
def viewers_buffer_health(viewers):
print(viewers)
viewers_with_buffer_health = {}
for viewer in viewers:
try:
data = requests.get(settings['endpoints']['node_buffer_health']).replace('<NODE_ID>', viewer)
except Exception as e:
print('ERROR retrieving buffer_health for {}'.format(viewer))
raise(SystemExit)
viewers_with_buffer_health[viewer] = data[0]['avg_buffer_health']
return viewers_with_buffer_health
The fixture viewers_buffer_health is failing all the time on the requests because 'function' object is not subscriptable
Other times I have seen such error it has been because I was calling a variable and a function by the same name, but it's not the case (or I'm blind at all).
Although it shouldn't matter, the output of viewers is a list like ['a4a6b1c0-e98a-42c8-abe9-f4289360c220', '152bff1c-e82e-49e1-92b6-f652c58d3145', '55a06a01-9956-4d7c-bfd0-5a2e6a27b62b']
Since viewers_buffer_health() doesn't have a local definition for settings it is using the function defined previously. If it is meant to work in the same manner as viewers() then you will need to add a settings argument to its current set of arguments.
settings is a function.
data = requests.get(settings()['endpoints']['node_buffer_health']).replace('<NODE_ID>', viewer)
I'm trying to create a bot that will retweet and promote some of my other accounts. But i receive the below error
AttributeError: 'Twython' object has no attribute 'getUserTimeline'
my code is:
search_results = twitter.getUserTimeline(sreen_name="SCREENNAME", count = 2,)
try:
for tweet in search_results["statuses"]:
twitter.retweet(id = tweet["id_str"])
except TwythonError as e:
print e
Can anyone help?
According to the twithon documentation there is no getUserTimeline function there is however a get_user_timeline function.
You should change the following call:
twitter.getUserTimeline
to be:
twitter.get_user_timeline
What is the best way to check if a CloudFormation stack exists and is not in a broken state using Boto? By broken I mean failed and rollback states.
I don't want to use a try/except solution, because boto logs it as an error, and in my scenario it's going to send the exception log to an alarm system.
At the moment I have the following solutions:
1) Use boto.cloudformation.connection.CloudFormationConnection.describe_stacks()
valid_states = '''\
CREATE_IN_PROGRESS
CREATE_COMPLETE
UPDATE_IN_PROGRESS
UPDATE_COMPLETE_CLEANUP_IN_PROGRESS
UPDATE_COMPLETE'''.splitlines()
def describe_stacks():
result = []
resp = cf_conn.describe_stacks()
result.extend(resp)
while resp.next_token:
resp = cf_conn.describe_stacks(next_token=resp.next_token)
result.extend(resp)
return result
stacks = [stack for stack in describe_stacks() if stack.stack_name == STACK_NAME and stack.stack_status in valid_states]
exists = len(stacks) >= 1
This is slow because I have lots of stacks.
2) Use boto.cloudformation.connection.CloudFormationConnection.list_stacks()
def list_stacks(filters):
result = []
resp = cf_conn.list_stacks(filters)
result.extend(resp)
while resp.next_token:
resp = cf_conn.list_stacks(filters, next_token=resp.next_token)
result.extend(resp)
return result
stacks = [stack for stack in list_stacks(valid_states) if stack.stack_name == STACK_NAME]
exists = len(stacks) >= 1
This takes forever, because summaries are kept for 90 days and I have lots of stacks.
Question: What is the ideal solution to check if a given stack exists and is not in a failure or rollback state?
I implemented the following which works:
import boto3
from botocore.exceptions import ClientError
client = boto3.client('cloudformation')
def stack_exists(name, required_status = 'CREATE_COMPLETE'):
try:
data = client.describe_stacks(StackName = name)
except ClientError:
return False
return data['Stacks'][0]['StackStatus'] == required_status
I didn't find any of the previous solutions complete, nor is there any quick way of doing it with boto3 so I created the above.
From the boto docs:
describe_stacks(stack_name_or_id=None, next_token=None)
Returns the description for the specified stack; if no stack name was specified, then it returns the description for all the stacks created.
Parameters: stack_name_or_id (string) – The name or the unique identifier associated with the stack.
Since you know the stack name, you can use describe_stacks(stack_name_or_id=STACK_NAME). That should speed things up for you.
I know this is old, but someone asked if there was a solution to it just a couple of weeks ago, so here goes...
If you read the boto3 docs, it mentions deleted stacks quite frequently. In order to do this, you have to use the full stack ID. You can't use the stack name. This is because the only thing truly unique about the stack is the ID.
Example:
resource = boto3.resource('cloudformation')
status = resource.Stack('id:of:stack').stack_status
The only time this will return an exception is if that stack ID doesn't exist.
Cheers!
I would check via the paginator combined with ListStacks API call because it might be possible my lambda or I doesn't have permissions for cloudformation if that happens, I should return relevant information instead of saying stack doesn't exist.
import boto3
from botocore.exceptions import ClientError
cfn = boto3.client('cloudformation')
def stack_exists(stack_name: str, stack_status: str) -> bool:
try:
paginator = cfn.get_paginator('list_stacks')
response_iterator = paginator.paginate()
for page in response_iterator:
for stack in page['StackSummaries']:
if stack_name == stack.get('StackName') and stack.get('StackStatus') != stack_status:
return True
except ClientError as e:
logger.exception(f'Client error while checking stack : {e}')
raise
except Exception:
logger.exception('Error while checking stack')
raise
return False
Or if we don't want to iterate over all the stacks:
import boto3
from botocore.exceptions import ClientError
cfn = boto3.client('cloudformation')
def stack_exists(stack_name: str, required_status='DELETE_COMPLETE'):
try:
stacks_summary = cfn.describe_stacks(StackName=stack_name)
stack_info = stacks_summary.get('Stacks')[0]
return stack_name == stack_info.get('StackName') and stack_info.get('StackStatus') != required_status
except ClientError as e:
stack_not_found_error = f'Stack with id {stack_name} does not exist'
error_received = e.response('Error')
error_code_received = error_received.get('Code')
error_message_received = error_received.get('Message')
if error_code_received == 'ValidationError' and error_message_received == stack_not_found_error:
return True
logger.exception(f'Client error while describing stacks: {e}')
raise
except Exception:
logger.exception('Error while checking stack')
raise
The best way to do this will be to split this into two separate problems:
Find out which stacks don't exist.
Find out which stacks are in an error state.
Might look something like this:
failure_states = ['CREATE_FAILED', ... ]
stack_names = ['prod', 'dev', 'test']
c = boto.cloudformation.connect_to_region(region)
existing_stacks = [s.stack_name for s in c.describe_stacks()]
nonexistent_stacks = set(stack_names) - set(existing_stacks)
error_stacks = c.list_stacks(stack_status_filters=failure_states)
You may have many more stacks then I do so maybe you need to use next_token to paginate, which would be a bit of a hassle. However, you can see that both operations can be done with a single request each and will not throw an exception.
You can silence the Boto logger by setting its level above ERROR. This will let you capture the exception without the logging alarm:
import boto3
import botocore.exceptions
import logging
cf = boto3.resource('cloudformation')
logging.Logger.manager.loggerDict['boto3'].setLevel(logging.CRITICAL)
logging.Logger.manager.loggerDict['botocore'].setLevel(logging.CRITICAL)
try:
stack.Stack('foo').stack_status
except botocore.exceptions.ClientError:
logging.info('stack doesnt exist')
logging.Logger.manager.loggerDict['boto3'].setLevel(logging.WARNING)
logging.Logger.manager.loggerDict['botocore'].setLevel(logging.WARNING)
I am utterly lost at what should be an easy task.
I am trying to use Python with SUDS to grab a WSDL URL, create client objects, modify some information, and then post back up the WSDL (Or where ever it tell me to post it).
I get the following error message:
Traceback (most recent call last):
File "./test.py", line 47, in <module>
email_sent = client.service.sendEmail(From, SenderContext, Email)
NameError: name 'client' is not defined
If I remove the "Try:" section in the code and insert come print code to print the objects, everything works just fine. It does grab the information and do the changes I want.
What I don't understand is that the client object is created and I am trying to post the information back up, but can't. Any one have any experience with XML and Python?
import sys
import logging
import traceback as tb
import suds.metrics as metrics
import unittest
from suds import null, WebFault
from suds.client import Client
def sendTestMail():
url = 'wsdl url at my company'
client = Client(url)
SenderContext = client.factory.create('senderContext')
SenderContext.registeredSenderId = 'Endurance'
SenderContext.mailType = 'TRANSACTIONAL_OTHER'
SenderContext.subSenderId = 12345
From = client.factory.create('emailAddressBean')
From.address = 'me#somecompany.com'
From.valid = 'TRUE'
Email = client.factory.create('email')
Email.recipients = 'me#somecompany.com'
Email.ccRecipients = ''
Email.bccRecipients = ''
Email.agencyId = ''
Email.content = 'This is a test of sending'
Email.contentType = 'text/plain'
Email.description = ''
#Email.from = From
Email.fromName = 'An Employee'
Email.subject = 'This is a test'
Email.mrrId = ''
Email.templateId = ''
try:
email_sent = client.service.sendEmail(From, SenderContext, Email)
except WebFault, e:
print e
if __name__ == '__main__':
errors = 0
sendTestMail()
print '\nFinished: errors=%d' % errors
You define client in the sendTestMail() class, but then use a lower-level indentation in your try/except statement. Therefore, client is not within scope at this point. Either indent your try/except block to be within the sendTestMail() scope or declare client globally.