FlickrApi exception: Photo not found on calling photo.getSizes() - python

I get a flickrapi.exceptions.FlickrError: Error: 1: Photo not found exception in the code below, at this line:
sizes_element = self.flickr.photos_getSizes(k_id = id)
However, according to me the photo_id that I am passing is correct.
import flickrapi
class FlickrDownloader():
def __init__(self,key,secret):
self.api_key = key
self.secret = secret
self.flickr = flickrapi.FlickrAPI(self.api_key,self.secret)
def getUrls(self):
self.photos = self.flickr
self.urlList = []
#get a list of photos
photo_element = self.flickr.photos_search(tags = 'flowers',per_page = '10')
#get and iterator over elements
photo_iter = photo_element.iter('photo')
self.i = 0
for photo in photo_iter:
#get the photo id
id = photo.attrib['id']
print id
#get the different sizes of photo
sizes_element = self.flickr.photos_getSizes(k_id = id)
#get an interator
sizes_iter = sizes_element.iter('size')
#iterate over the sizes
for size in sizes_iter:
#check if its original size
if size.attrib['label'] == 'Original':
self.urlList.append(size.attrib['source'])
return self.urlList

The flickr.photos.getSizes call doesn't take a k_id parameter. Check the Flickr documentation, it shows that you need to pass the photo ID using the photo_id parameter. You need to get the parameter names right, otherwise Flickr doesn't know what to do with them.

Related

Shopify Python - Set inventory quantity

I'm trying to set inventory quantity of a product in shopify using the Shopify Python Api.
As i understand it, i need to set the 'inventory_level' of the 'inventory_item' that belongs to the product, but after a few days of searching and testing i still have no luck.
Where i'm at
I have my products showing up in my store with all the data but the inventory quantity.
I'm not sure how to proceed as there's not a whole lot of documentation.
Here's my code for creating a product
def CreateShopifyProduct(data):
# CREATE PRODUCT
product = shopify.Product()
# Add stuff to product, variant and inventoryItem here
product.title = data['title']
#product.status = ""
#product.tags = data['tags']
product.body_html = data['description']
if 'catagory' in data:
product.product_type = data['category']
if 'vendor' in data:
product.vendor = data['vendor']
if 'image_url' in data:
image_path = data['image_url']
image = shopify.Image()
image.src = image_path
product.images = [image]
else:
try:
image = GetLocalImageFiles(data['id'])
product.images = [image]
except:
print("No local images found")
success = product.save() #returns false if the record is invalid
# CREATE VARIANT
variant = shopify.Variant()
if 'ean' in data:
variant.barcode = data['ean']
variant.price = data['gross_price']
variant.weight = data['weight']
#variant.count = data['inventory']
variant.inventory_management = 'shopify'
product.variants = [variant]
variant.product_id = product.id
s = variant.save()
success = product.save() #returns false if the record is invalid
# CREATE INVENTORYITEM
inventoryItem = shopify.InventoryItem()
#inventoryItem = variant.inventory_item
inventoryItem.tracked = True
inventoryItem.id = product.id
variant.inventory_quantity = data['inventory']
inventoryItem.inventory_quantity = data['inventory']
variant.inventory_item = inventoryItem
s = variant.save()
success = product.save()
#ii = inventoryItem.save() # this returns 406
#inv_level = shopify.InventoryLevel.find(inventory_item_ids=6792364982390, location_ids=61763518582)
#quantity = inv_level[0].__dict__['attributes']['available']
#shopify.InventoryLevel.set(location_id=61763518582, inventory_item_id=variant.inventory_item.id, available=data['inventory'])
#shopify.InventoryLevel.connect(61763518582, variant.inventory_item.id)
if product.errors:
#something went wrong, see new_product.errors.full_messages() for example
print("error")
print(product.errors.full_messages())
If i try to set the InventoryLevel with
shopify.InventoryLevel.set(61527654518, inventoryItem.id, 42)
# or
shopify.InventoryLevel.set(location_id=61527654518, inventory_item_id=inventoryItem.id, available=17)
I recieve a
pyactiveresource.connection.ResourceNotFound: Not Found: https://domain.myshopify.com/admin/api/2022-07/inventory_levels/set.json
You need three things to update an inventory level. One, you need a valid location ID. Two, you need the inventory item ID. Finally, you need the amount to adjust inventory to, that will adjust the inventory there to match your needs.
You should really play at the command-line and ensure you can quickly get the information you need, then try your updates. In other words, ensure you are getting a good location ID, inventory item ID and finally, that you know the amount of inventory already in Shopify. Since you have to calculate a delta change, these are the minimum steps most people take.
Note that once you get good at doing one item, you'll realize Shopify also accepts up to 100 at a time, making your updates a lot faster.

Creating dataframe from a dictionary where arrays with the same length

I am trying to extract some YouTube videos with details, and when I created a dataframe from my dictionary, I faced this error. so can someone help me??
def youtube_search(q, max_results=50,order="relevance", token=None, location=None, location_radius=None):
search_response = youtube.search().list(
q=q,
type="video",
pageToken=token,
order = order,
part="id,snippet", # Part signifies the different types of data you want
maxResults=max_results,
location=location,
locationRadius=location_radius).execute()
title = []
channelId = []
channelTitle = []
categoryId = []
videoId = []
viewCount = []
likeCount = []
dislikeCount = []
commentCount = []
category = []
tags = []
videos = []
for search_result in search_response.get("items", []):
if search_result["id"]["kind"] == "youtube#video":
title.append(search_result['snippet']['title'])
videoId.append(search_result['id']['videoId'])
response = youtube.videos().list(
part='statistics, snippet',
id=search_result['id']['videoId']).execute()
channelId.append(response['items'][0]['snippet']['channelId'])
channelTitle.append(response['items'][0]['snippet']['channelTitle'])
categoryId.append(response['items'][0]['snippet']['categoryId'])
viewCount.append(response['items'][0]['statistics']['viewCount'])
likeCount.append(response['items'][0]['statistics']['likeCount'])
dislikeCount.append(response['items'][0]['statistics']['dislikeCount'])
if 'commentCount' in response['items'][0]['statistics'].keys():
commentCount.append(response['items'][0]['statistics']['commentCount'])
else:
commentCount.append([])
if 'tags' in response['items'][0]['snippet'].keys():
tags.append(response['items'][0]['snippet']['tags'])
else:
tags.append([])
#Not every video has likes/dislikes enabled so they won't appear in JSON response
try:
likeCount.append(response['items'][0]['statistics']['likeCount'])
except:
#Good to be aware of Channels that turn off their Likes
print("Video titled {0}, on Channel {1} Likes Count is not available".format(stats['items'][0]['snippet']['title'],
stats['items'][0]['snippet']['channelTitle']))
print(response['items'][0]['statistics'].keys())
#Appends "Not Available" to keep dictionary values aligned
likeCount.append("Not available")
try:
dislikeCount.append(response['items'][0]['statistics']['dislikeCount'])
except:
#Good to be aware of Channels that turn off their Likes
print("Video titled {0}, on Channel {1} Dislikes Count is not available".format(stats['items'][0]['snippet']['title'],
stats['items'][0]['snippet']['channelTitle']))
print(response['items'][0]['statistics'].keys())
dislikeCount.append("Not available")
#youtube_dict = {'tags':tags,'channelId': channelId,'channelTitle': channelTitle,'categoryId':categoryId,'title':title,'videoId':videoId,'viewCount':viewCount,'likeCount':likeCount,'dislikeCount':dislikeCount,'commentCount':commentCount,'favoriteCount':favoriteCount}
youtube_dict = {'tags':tags,'channelTitle': channelTitle,
'title':title,'videoId':videoId,'viewCount':viewCount,
'likeCount':likeCount, 'dislikeCount':dislikeCount, 'commentCount':commentCount, }
return youtube_dict
q = "covid19 vaccine"
test = youtube_search(q, max_results=100,order="relevance", token=None, location=None, location_radius=None)
import pandas as pd
df = pd.DataFrame(data=test)
df.head()
ValueError: arrays must all be same length. I tried to add
df = pd.DataFrame.from_dict(data=test, orient='index'), but I doesn't work too, I faced an other error
TypeError: init() got an unexpected keyword argument 'orient'
Any help would be much appreciated.

Data output is not the same as inside function

I am currently having an issue where I am trying to store data in a list (using dataclasses). When I print the data inside the list in the function (PullIncursionData()) it responded with a certain amount of numbers (never the same, not possible due to it's nature). When printing it after it being called to store it's return in a Var it somehow prints only the same number.
I cannot share the numbers, as they update with EVE Online's API, so the only way is to run it locally and read the first list yourself.
The repository is Here: https://github.com/AtherActive/EVEAPI-Demo
Heads up! Inside the main.py (the file with issues) (a snippet of code is down below) are more functions. All functions from line 90 and forward are important, the rest can be ignored for this question, as they do not interact with the other functions.
def PullIncursionData():
#Pulls data from URL and converts it into JSON
url = 'https://esi.evetech.net/latest/incursions/?datasource=tranquility'
data = rq.get(url)
jsData = data.json()
#Init var to store incursions
incursions = []
#Set lenght for loop. yay
length = len(jsData)
# Every loop incursion data will be read by __parseIncursionData(). It then gets added to var Incursions.
for i in range(length):
# Add data to var Incursion.
incursions.append(__parseIncursionData(jsData, i))
# If Dev mode, print some debug. Can be toggled in settings.py
if settings.developerMode == 1:
print(incursions[i].constellation_id)
return incursions
# Basically parses the input data in a decent manner. No comments needed really.
def __parseIncursionData(jsData, i):
icstruct = stru.Incursion
icstruct.constellation_id = jsData[i]['constellation_id']
icstruct.constellation_name = 'none'
icstruct.staging = jsData[i]['staging_solar_system_id']
icstruct.region_name = ResolveSystemNames(icstruct.constellation_id, 'con-reg')
icstruct.status = jsData[i]['state']
icstruct.systems_id = jsData[i]['infested_solar_systems']
icstruct.systems_names = ResolveSystemNames(jsData[i]['infested_solar_systems'], 'system')
return icstruct
# Resolves names for systems, regions and constellations. Still WIP.
def ResolveSystemNames(id, mode='constellation'):
#init value
output_name = 'none'
# If constellation, pull data and find region name.
if mode == 'con-reg':
url = 'https://www.fuzzwork.co.uk/api/mapdata.php?constellationid={}&format=json'.format(id)
data = rq.get(url)
jsData = data.json()
output_name = jsData[0]['regionname']
# Pulls system name form Fuzzwork.co.uk.
elif mode == 'system':
#Convert output to a list.
output_name = []
lenght = len(id)
# Pulls system name from Fuzzwork. Not that hard.
for i in range(lenght):
url = 'https://www.fuzzwork.co.uk/api/mapdata.php?solarsystemid={}&format=json'.format(id[i])
data = rq.get(url)
jsData = data.json()
output_name.append(jsData[i]['solarsystemname'])
return output_name
icdata = PullIncursionData()
print('external data check:')
length = len(icdata)
for i in range(length):
print(icdata[i].constellation_id)
structures.py (custom file)
#dataclass
class Incursion:
constellation_id = int
constellation_name = str
staging = int
staging_name = str
systems_id = list
systems_names = list
region_name = str
status = str
def ___init___(self):
self.constellation_id = -1
self.constellation_name = 'undefined'
self.staging = -1
self.staging_name = 'undefined'
self.systems_id = []
self.systems_names = []
self.region_name = 'undefined'
self.status = 'unknown'

AWS - boto3 - how to list of all the ORG IDs(even nested) under organization

I am trying to get a list of all the org ids under organization using boto3. The current structure is like this -
Root
|
|
ou1-----OU2-----OU3
| | |
ou4 ou5 ou6
|
ou7
|
ou8
This structure may change in future more ORG units might get added some of them may be deleted so I would like to make the function dynamic. I was hoping I could provide the Root id after which it should be able to find out all the org id under it. But this seems a little complicated as there is no existing API in boto3 which lists all the ORG ids under root. I would really appreciate if someone could give guidance/suggestion
I have taken a look at -
https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/organizations.html#Organizations.Client.list_children
https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/organizations.html#Organizations.Client.list_parents
but not sure how to interconnect them so it can find all the org ids, below is the code that I wrote but this will only fetch 2nd layer of children, that is till org4,5 and 6
org = session.client("organizations")
response = org.list_roots()
for PolicyTypes in response["Roots"]:
parent_id = PolicyTypes["Id"]
OUlist = []
NextToken = False
while NextToken is not None:
if not NextToken:
response_iterator = org.list_organizational_units_for_parent(ParentId=parent_id, MaxResults=20)
else:
response_iterator = org.list_organizational_units_for_parent(ParentId=parent_id, MaxResults=20,
NextToken=NextToken)
OUlist = get_OUlist(OUlist, response_iterator)
try:
NextToken = response_iterator['NextToken']
except KeyError:
break
get_child_ou(org, OUlist)
def get_child_ou(org, OUlist):
for ou in OUlist:
NextToken = False
while NextToken is not None:
if not NextToken:
response_iterator = org.list_children(ParentId=ou, ChildType='ORGANIZATIONAL_UNIT', MaxResults=20)
else:
response_iterator = org.list_children(ParentId=ou, ChildType='ORGANIZATIONAL_UNIT', NextToken=NextToken,
MaxResults=20)
try:
NextToken = response_iterator['NextToken']
except KeyError:
break
for orgid in response_iterator["Children"]:
OUlist.append(orgid["Id"])
return OUlist
Simple solution
import boto3
session = boto3.Session(profile_name='default')
org = session.client('organizations')
def printout(parent_id, indent):
print(f"{'-' * indent} {parent_id}")
paginator = org.get_paginator('list_children')
iterator = paginator.paginate(
ParentId=parent_id,
ChildType='ORGANIZATIONAL_UNIT'
)
indent += 1
for page in iterator:
for ou in page['Children']:
printout(ou['Id'], indent)
if __name__ == "__main__":
rootid = org.list_roots()["Roots"][0]["Id"]
printout(rootid, 0)
import boto3
def add_ou(ids):
for id in ids:
ou_list.append(id)
child_ids = get_childs(id)
while child_ids:
if len(child_ids) > 1:
add_ou(child_ids)
child_ids = []
else:
ou_list.append(child_ids[0])
child_ids = get_childs(child_ids[0])
def get_childs(id):
childs = org_client.list_children(
ParentId=id,
ChildType='ORGANIZATIONAL_UNIT')
return [child["Id"] for child in childs["Children"]]
if __name__ == "__main__":
org_client = boto3.client('organizations')
root_id = org_client.list_roots()["Roots"][0]["Id"]
childs = get_childs(root_id)
ou_list = []
add_ou(childs)
print(ou_list)
This will loop through all organization units and print organization units Ids
In addition to #Danish's answer:
You can now use the Paginator feature for organizations.list_children (and many other API calls). This drops the need to check for NextToken, saves LOCs and enhances code readability :-)
# Lambda example
import boto3
client = boto3.client('organizations')
def lambda_handler(event, context):
root_id = client.list_roots()['Roots'][0]['Id']
ou_id_list = get_ou_ids(root_id)
print(ou_id_list)
def get_ou_ids(parent_id):
full_result = []
paginator = client.get_paginator('list_children')
iterator = paginator.paginate(
ParentId=parent_id,
ChildType='ORGANIZATIONAL_UNIT'
)
for page in iterator:
for ou in page['Children']:
# 1. Add entry
# 2. Fetch children recursively
full_result.append(ou['Id'])
full_result.extend(get_ou_ids(ou['Id']))
return full_result

Separating "user-owned" from "other" data in Django template

I have an Openstack-powered, Django-modified application that shows the disk images and snapshots available for a user to launch. The user currently sees both snapshots they created and ones they did not. I would like to separate the current table into two based on whether they are owned by the user or not.
My two table definitions are as follows (note I altered row_actions accordingly):
class UserSnapshotsTable(OldSnapshotsTable):
cloud = tables.Column(get_cloud, verbose_name=_("Cloud"))
class Meta:
name = "usersnapshots"
verbose_name = _("User Snapshots")
table_actions = (DeleteSnapshot,)
row_actions = (LaunchSnapshot, LaunchCluster, EditImage, DeleteSnapshot)
pagination_param = "snapshot_marker"
row_class = UpdateRow
status_columns = ["status"]
class OtherSnapshotsTable(OldSnapshotsTable):
cloud = tables.Column(get_cloud, verbose_name=_("Cloud"))
class Meta:
name = "othersnapshots"
verbose_name = _("Other Snapshots")
table_actions = (DeleteSnapshot,)
row_actions = (LaunchSnapshot, LaunchCluster)
pagination_param = "snapshot_marker"
row_class = UpdateRow
status_columns = ["status"]
I have altered the HTML template to pull the "UserSnapshotsTable" and "OtherSnapshotsTable" tables (I copied the original table and renamed both), but both full tables still generate under the respective headings. There are two functions generating the data:
def get_usersnapshots_data(self):
req = self.request
marker = req.GET.get(UserSnapshotsTable._meta.pagination_param, None)
try:
usersnaps, self._more_snapshots = api.snapshot_list_detailed(req,
marker=marker)
except:
usersnaps = []
exceptions.handle(req, _("Unable to retrieve user-owned snapshots."))
return usersnaps
def get_othersnapshots_data(self):
req = self.request
marker = req.GET.get(OtherSnapshotsTable._meta.pagination_param, None)
try:
othersnaps, self._more_snapshots = api.snapshot_list_detailed(req,
marker=marker)
except:
othersnaps = []
exceptions.handle(req, _("Unable to retrieve non-user-owned snapshots."))
return othersnaps
There are also Edit/Delete options defined for images, and imported for snapshots, that seem to have a key comparison. Here's the "Delete" one (line 7):
class DeleteImage(tables.DeleteAction):
data_type_singular = _("Image")
data_type_plural = _("Images")
def allowed(self, request, image=None):
if image:
return image.owner == request.user.tenant_id
# Return True to allow table-level bulk delete action to appear.
return True
def delete(self, request, obj_id):
api.image_delete(request, obj_id)
How can I separate those tables out? This is my first time asking a question here, so please let me know if I can provide further information. Apologies for the length of it.
As far as I see you are using glanceclient. If that so you can use extra_filters parameter of snapshot_list_detailed() to filter only user images like this:
usersnaps, self._more_snapshots = api.snapshot_list_detailed(
req,
marker = marker,
extra_filters = {"owner": "user_name"}
)
Under cover snapshot_list_detailed uses GET images of Openstack Image Service API.

Categories