How do you pull JSON array from API in Python? - python

I am having issues pulling a JSON array from http://api.divesites.com.
When I manually set the data as a string in Python 3.7, I can see the array.
import json
def main():
hardcode = """{"request":{"str":null,"timestamp":1572865590,"loc":{"lat":"50.442","lng":"-4.08279999999999"},"mode":"sites","dist":"9","api":1},"sites":[{"currents":null,"distance":"7.47","hazards":null,"lat":"50.3378","name":"Fort Bovisand","water":null,"marinelife":null,"description":null,"maxdepth":null,"mindepth":null,"predive":null,"id":"24387","equipment":null,"lng":"-4.1285"},{"currents":null,"distance":"7.93","hazards":null,"lat":"50.3352","name":"Plymouth Breakwater","water":null,"marinelife":null,"description":null,"maxdepth":null,"mindepth":null,"predive":null,"id":"24388","equipment":null,"lng":"-4.1485"}],"version":1,"loc":{"lat":"50.442","lng":"-4.08279999999999"},"result":true}
"""
print("Original Data: ---", get_data(hardcode))
print("Site Data:----", get_data(hardcode)['sites'])
def get_data(data):
return json.loads(data)
if __name__=='__main__':
main()
Output
Original Data: --- {'request': {'str': None, 'timestamp': 1572865590, 'loc': {'lat': '50.442', 'lng': '-4.08279999999999'}, 'mode': 'sites', 'dist': '9', 'api': 1}, 'sites': [{'currents': None, 'distance': '7.47', 'hazards': None, 'lat': '50.3378', 'name': 'Fort Bovisand', 'water': None, 'marinelife': None, 'description': None, 'maxdepth': None, 'mindepth': None, 'predive': None, 'id': '24387', 'equipment': None, 'lng': '-4.1285'}, {'currents': None, 'distance': '7.93', 'hazards': None, 'lat': '50.3352', 'name': 'Plymouth Breakwater', 'water': None, 'marinelife': None, 'description': None, 'maxdepth': None, 'mindepth': None, 'predive': None, 'id': '24388', 'equipment': None, 'lng': '-4.1485'}], 'version': 1, 'loc': {'lat': '50.442', 'lng': '-4.08279999999999'}, 'result': True}
Site Data:---- [{'currents': None, 'distance': '7.47', 'hazards': None, 'lat': '50.3378', 'name': 'Fort Bovisand', 'water': None, 'marinelife': None, 'description': None, 'maxdepth': None, 'mindepth': None, 'predive': None, 'id': '24387', 'equipment': None, 'lng': '-4.1285'}, {'currents': None, 'distance': '7.93', 'hazards': None, 'lat': '50.3352', 'name': 'Plymouth Breakwater', 'water': None, 'marinelife': None, 'description': None, 'maxdepth': None, 'mindepth': None, 'predive': None, 'id': '24388', 'equipment': None, 'lng': '-4.1485'}]
However when I try and perform a GET request (using urllib.request.urlopen()), I only receive the objects.
import urllib.request
import json
def get_jsonparsed_data(url):
response = urllib.request.urlopen(url)
data = response.read().decode("utf-8")
return json.loads(data)
def main():
url = 'http://api.divesites.com/?mode=sites&lat=-50.350874&lng=175.849890&dist=12'
print("Original Data: ---", get_jsonparsed_data(url))
print("Sites: ----", get_jsonparsed_data(url)['sites'])
if __name__=='__main__':
main()
Output
Original Data: --- {'request': {'str': None, 'timestamp': 1572866211, 'loc': {'lat': '-50.350874', 'lng': '175.849890'}, 'mode': 'sites', 'dist': '12', 'api': 1}, 'sites': [], 'version': 1, 'loc': {'lat': '-50.350874', 'lng': '175.849890'}, 'result': True}
Site Data:---- []
Am I doing something wrong, or do I need an extra step?

Solved it. I spent so long focusing on debugging the code I forgot to check the final API call. Turns out I either didn't have enough distance set, or the wrong starting longitude and latitude. This was different to my hard coded JSON.
The URL should have been: http://api.divesites.com/?mode=sites&lat=50.442&lng=-4.08279999999999&dist=9
Stupid mistake. Thanks for helping though. It got me to look.

First, I'd use the requests library instead and then you can find the solution here

Related

mlflow: INVALID_PARAMETER_VALUE Parameters can not be modified after a value is set

I get the following exception raised, help me please
mlflow.exceptions.RestException: INVALID_PARAMETER_VALUE: Response:
{
'Error': {
'Code': 'ValidationError',
'Severity': None,
'Message': 'Parameters can not be modified after a value is set.',
'MessageFormat': None,
'MessageParameters': None,
'ReferenceCode': None,
'DetailsUri': None,
'Target': None,
'Details': [],
'InnerError': None,
'DebugInfo': None,
'AdditionalInfo': None
},
'Correlation': {
'operation': '13b09a7297c0e920a41eeaa728c4cb4e',
'request': 'ae8a75a01a168e65'
},
'Environment': 'westeurope',
'Location': 'westeurope',
'Time': '2022-12-22T23:37:07.4626959+00:00',
'ComponentName': 'mlflow',
'error_code': 'INVALID_PARAMETER_VALUE'
}
my code pretty much looks like this
mlflow.start_run()
mlflow.log_params({'key1':1, 'key2':2})
mlflow.log_param('key3', 3) //Exception raised
PS: the mlflow version i am using is 2.1.0

Iterate on nested json through python

I am having a json data coming through API and i need to print some specific values through it and i am using the code to get the same but its giving me keyerror : results
import json
import requests
headers = {"Content-Type":"application/json","Accept":"application/json"}
r = requests.get('API', headers=headers)
data=r.text
parse_json=json.loads(data)
for result in parse_json['results']:
for cpu in result['cpumfs']:
print(cpu.get('pct_im_utilization'))
Below is the json data :
{'d': {'__count': '0', 'results': [{'ID': '6085', 'Name': 'device1', 'DisplayName': None, 'DisplayDescription': None, 'cpumfs': {'results': [{'ID': '6117', 'Timestamp': '1649157300', 'DeviceItemID': '6085', 'pct_im_Utilization': '4.0'}, {'ID': '6117', 'Timestamp': '1649157600', 'DeviceItemID': '6085', 'pct_im_Utilization': '1.0'}, {'ID': '6117', 'Timestamp': '1649157900', 'DeviceItemID': '6085', 'pct_im_Utilization': '4.0'}, {'ID': '6117', 'Timestamp': '1649158200', 'DeviceItemID': '6085', 'pct_im_Utilization': '1.0'},
I need to get printed Name of the device ,Timestamp,pct_im_utlization

how to scrape product data from website pages that uses graphql

I previously used the code below to scrape the search result for a word search, for example book, on https://www.walmart.com/. They have currently changed their request and response parameters and this code does not get any response again.
params = {
'query': 'book',
'cat_id': 0,
'ps': 24,
'offset': 0,
'prg': 'desktop',
'stores': re.search(r'store/(\d+)', url).group(1)
}
try:
data1 = requests.get(api_url, params=params).json()
except Exception as e:
print("Sleeping for 10 seconds", e)
time.sleep(10)
try:
data1 = requests.get(api_url, params=params).json()
except Exception as e:
print("sleeping for 60 seconds", e)
time.sleep(60)
try:
data1 = requests.get(api_url, params=params).json()
except Exception as e:
print("sleeping for 360 seconds")
time.sleep(360)
data1 = requests.get(api_url, params=params).json()
I want to get the json response for a product page for example the product the in this url
https://www.walmart.com/ip/SKIPPY-Natural-Creamy-Peanut-Butter-Spread-15-oz/37447671
How could i rewrite the code with their current parameters to get the json response?
According to your question, to get the json response, You can follow my working solution as an example. Actually, the hidden api calls json response is here. The interesing matter is that the request method is post but it sends query string parameters & request payload/formdata and the next pages at the same time which type of response I face first time ever and I have to make both types of parameters to get desired json response. I've also made the pagination following json response and you can increase or decrease it according to json response maxpage.
import requests
import json
data= {
"query":"query Browse( $query:String $page:Int $prg:Prg! $facet:String $sort:Sort $catId:String! $max_price:String $min_price:String $module_search:String $affinityOverride:AffinityOverride $ps:Int $ptss:String $beShelfId:String $fitmentFieldParams:JSON ={}$fitmentSearchParams:JSON ={}$rawFacet:String $seoPath:String $trsp:String $fetchMarquee:Boolean! $fetchSkyline:Boolean! $additionalQueryParams:JSON ={}){search( query:$query page:$page prg:$prg facet:$facet sort:$sort cat_id:$catId max_price:$max_price min_price:$min_price module_search:$module_search affinityOverride:$affinityOverride additionalQueryParams:$additionalQueryParams ps:$ps ptss:$ptss trsp:$trsp _be_shelf_id:$beShelfId ){query searchResult{...BrowseResultFragment}}contentLayout( channel:\"WWW\" pageType:\"BrowsePage\" tenant:\"WM_GLASS\" version:\"v1\" searchArgs:{query:$query cat_id:$catId _be_shelf_id:$beShelfId prg:$prg}){modules{...ModuleFragment configs{...on EnricherModuleConfigsV1{zoneV1}__typename...on _TempoWM_GLASSWWWSearchSortFilterModuleConfigs{facetsV1{...FacetFragment}}...on TempoWM_GLASSWWWPillsModuleConfigs{moduleSource pillsV2{...PillsModuleFragment}}...on TempoWM_GLASSWWWSearchFitmentModuleConfigs{fitments( fitmentSearchParams:$fitmentSearchParams fitmentFieldParams:$fitmentFieldParams ){...FitmentFragment sisFitmentResponse{...BrowseResultFragment}}}...on TempoWM_GLASSWWWStoreSelectionHeaderConfigs{fulfillmentMethodLabel storeDislayName}...on TempoWM_GLASSWWWBreadcrumbConfigs{_rawConfigs}...on TempoWM_GLASSWWWSponsoredProductCarouselConfigs{_rawConfigs}...PopularInModuleFragment...CopyBlockModuleFragment...BannerModuleFragment...HeroPOVModuleFragment...InlineSearchModuleFragment...MarqueeDisplayAdConfigsFragment #include(if:$fetchMarquee)...SkylineDisplayAdConfigsFragment #include(if:$fetchSkyline)...HorizontalChipModuleConfigsFragment}}...LayoutFragment pageMetadata{location{postalCode stateOrProvinceCode city storeId}pageContext}}seoBrowseMetaData( id:$catId facets:$rawFacet path:$seoPath facet_query_param:$facet _be_shelf_id:$beShelfId ){metaTitle metaDesc metaCanon h1}}fragment BrowseResultFragment on SearchInterface{title aggregatedCount...BreadCrumbFragment...DebugFragment...ItemStacksFragment...PageMetaDataFragment...PaginationFragment...RequestContextFragment...ErrorResponse modules{facetsV1{...FacetFragment}pills{...PillsModuleFragment}}}fragment ModuleFragment on TempoModule{name version type moduleId schedule{priority}matchedTrigger{zone}}fragment LayoutFragment on ContentLayout{layouts{id layout}}fragment BreadCrumbFragment on SearchInterface{breadCrumb{id name url}}fragment DebugFragment on SearchInterface{debug{sisUrl}}fragment ItemStacksFragment on SearchInterface{itemStacks{displayMessage meta{adsBeacon{adUuid moduleInfo max_ads}query stackId stackType title layoutEnum totalItemCount totalItemCountDisplay viewAllParams{query cat_id sort facet affinityOverride recall_set min_price max_price}}itemsV2{...ItemFragment...InGridMarqueeAdFragment}}}fragment ItemFragment on Product{__typename id usItemId fitmentLabel name checkStoreAvailabilityATC seeShippingEligibility brand type shortDescription imageInfo{...ProductImageInfoFragment}canonicalUrl externalInfo{url}category{path{name url}}badges{flags{...on BaseBadge{key text type id}}tags{...on BaseBadge{key text type}}}classType averageRating numberOfReviews esrb mediaRating salesUnitType sellerId sellerName hasSellerBadge availabilityStatusV2{display value}productLocation{displayValue aisle{zone aisle}}badge{type dynamicDisplayName}fulfillmentSpeed offerId preOrder{...PreorderFragment}priceInfo{...ProductPriceInfoFragment}variantCriteria{...VariantCriteriaFragment}fulfillmentBadge fulfillmentTitle fulfillmentType brand manufacturerName showAtc sponsoredProduct{spQs clickBeacon spTags}showOptions}fragment ProductImageInfoFragment on ProductImageInfo{thumbnailUrl}fragment ProductPriceInfoFragment on ProductPriceInfo{priceRange{minPrice maxPrice}currentPrice{...ProductPriceFragment}wasPrice{...ProductPriceFragment}unitPrice{...ProductPriceFragment}listPrice{...ProductPriceFragment}shipPrice{...ProductPriceFragment}subscriptionPrice{priceString subscriptionString}priceDisplayCodes{priceDisplayCondition finalCostByWeight}}fragment PreorderFragment on PreOrder{isPreOrder preOrderMessage preOrderStreetDateMessage}fragment ProductPriceFragment on ProductPrice{price priceString}fragment VariantCriteriaFragment on VariantCriterion{name type id isVariantTypeSwatch variantList{id images name rank swatchImageUrl availabilityStatus products selectedProduct{canonicalUrl usItemId}}}fragment InGridMarqueeAdFragment on MarqueePlaceholder{__typename type moduleLocation lazy}fragment PageMetaDataFragment on SearchInterface{pageMetadata{storeSelectionHeader{fulfillmentMethodLabel storeDislayName}title canonical description location{addressId}}}fragment PaginationFragment on SearchInterface{paginationV2{maxPage pageProperties}}fragment RequestContextFragment on SearchInterface{requestContext{vertical isFitmentFilterQueryApplied searchMatchType categories{id name}}}fragment ErrorResponse on SearchInterface{errorResponse{correlationId source errors{errorType statusCode statusMsg source}}}fragment PillsModuleFragment on PillsSearchInterface{title url image:imageV1{src alt}baseSeoURL}fragment BannerModuleFragment on TempoWM_GLASSWWWSearchBannerConfigs{moduleType viewConfig{title image imageAlt displayName description url urlAlt appStoreLink appStoreLinkAlt playStoreLink playStoreLinkAlt}}fragment PopularInModuleFragment on TempoWM_GLASSWWWPopularInBrowseConfigs{seoBrowseRelmData(id:$catId){relm{id name url}}}fragment CopyBlockModuleFragment on TempoWM_GLASSWWWCopyBlockConfigs{copyBlock(id:$catId){cwc}}fragment FacetFragment on Facet{name type layout min max selectedMin selectedMax unboundedMax stepSize values{id name description type itemCount isSelected baseSeoURL}}fragment FitmentFragment on Fitments{partTypeIDs result{status formId position quantityTitle extendedAttributes{...FitmentFieldFragment}labels{...LabelFragment}resultSubTitle}labels{...LabelFragment}savedVehicle{vehicleYear{...VehicleFieldFragment}vehicleMake{...VehicleFieldFragment}vehicleModel{...VehicleFieldFragment}additionalAttributes{...VehicleFieldFragment}}fitmentFields{...VehicleFieldFragment}fitmentForms{id fields{...FitmentFieldFragment}title labels{...LabelFragment}}}fragment LabelFragment on FitmentLabels{ctas{...FitmentLabelEntityFragment}messages{...FitmentLabelEntityFragment}links{...FitmentLabelEntityFragment}images{...FitmentLabelEntityFragment}}fragment FitmentLabelEntityFragment on FitmentLabelEntity{id label}fragment VehicleFieldFragment on FitmentVehicleField{id label value}fragment FitmentFieldFragment on FitmentField{id displayName value extended data{value label}dependsOn}fragment HeroPOVModuleFragment on TempoWM_GLASSWWWHeroPovConfigsV1{povCards{card{povStyle image{mobileImage{...TempoCommonImageFragment}desktopImage{...TempoCommonImageFragment}}heading{text textColor textSize}subheading{text textColor}detailsView{backgroundColor isTransparent}ctaButton{button{linkText clickThrough{value}}}logo{...TempoCommonImageFragment}links{link{linkText}}}}}fragment TempoCommonImageFragment on TempoCommonImage{src alt assetId uid clickThrough{value}}fragment InlineSearchModuleFragment on TempoWM_GLASSWWWInlineSearchConfigs{headingText placeholderText}fragment MarqueeDisplayAdConfigsFragment on TempoWM_GLASSWWWMarqueeDisplayAdConfigs{_rawConfigs ad{...DisplayAdFragment}}fragment DisplayAdFragment on Ad{...AdFragment adContent{type data{__typename...AdDataDisplayAdFragment}}}fragment AdFragment on Ad{status moduleType platform pageId pageType storeId stateCode zipCode pageContext moduleConfigs adsContext adRequestComposite}fragment AdDataDisplayAdFragment on AdData{...on DisplayAd{json status}}fragment SkylineDisplayAdConfigsFragment on TempoWM_GLASSWWWSkylineDisplayAdConfigs{_rawConfigs ad{...SkylineDisplayAdFragment}}fragment SkylineDisplayAdFragment on Ad{...SkylineAdFragment adContent{type data{__typename...SkylineAdDataDisplayAdFragment}}}fragment SkylineAdFragment on Ad{status moduleType platform pageId pageType storeId stateCode zipCode pageContext moduleConfigs adsContext adRequestComposite}fragment SkylineAdDataDisplayAdFragment on AdData{...on DisplayAd{json status}}fragment HorizontalChipModuleConfigsFragment on TempoWM_GLASSWWWHorizontalChipModuleConfigs{chipModuleSource:moduleSource chipModule{title url{linkText title clickThrough{type value}}}chipModuleWithImages{title url{linkText title clickThrough{type value}}image{alt clickThrough{type value}height src title width}}}",
"variables":{
"id":"",
"affinityOverride":"default",
"dealsId":"",
"query":"",
"page":1,
"prg":"desktop",
"catId":"3920",
"facet":"",
"sort":"best_seller",
"rawFacet":"",
"seoPath":"",
"ps":40,
"ptss":"",
"trsp":"",
"beShelfId":"",
"recall_set":"",
"module_search":"",
"min_price":"",
"max_price":"",
"storeSlotBooked":"",
"additionalQueryParams":None,
"fitmentFieldParams":None,
"fitmentSearchParams":{
"id":"",
"affinityOverride":"default",
"dealsId":"",
"query":"",
"page":1,
"prg":"desktop",
"catId":"3920",
"facet":"",
"sort":"best_seller",
"rawFacet":"",
"seoPath":"",
"ps":40,
"ptss":"",
"trsp":"",
"beShelfId":"",
"recall_set":"",
"module_search":"",
"min_price":"",
"max_price":"",
"storeSlotBooked":"",
"additionalQueryParams":None,
"cat_id":"3920",
"_be_shelf_id":""
},
"fetchMarquee":True,
"fetchSkyline":True,
"fetchSbaTop":False
}
}
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.107 Safari/537.36',
'content-type':'application/json',
'wm_mp': 'true',
'wm_page_url': 'https://www.walmart.com/browse/books/3920?sort=best_seller&affinityOverride=default',
'wm_qos.correlation_id': 'FWpup9KEKUrLFOY68gppqfprABL16K6qE76g',
'x-apollo-operation-name': 'Browse',
'x-enable-server-timing': '1',
'x-latency-trace': '1',
'x-o-ccm': 'server',
'x-o-correlation-id': 'FWpup9KEKUrLFOY68gppqfprABL16K6qE76g',
'x-o-gql-query': 'query Browse',
'x-o-market': 'us',
'x-o-platform': 'rweb',
'x-o-platform-version': 'main-176-e8acb5',
'x-o-segment': 'oaoh'
}
params= {
"affinityOverride": "default",
"page": "1",
"prg": "desktop",
"catId": "3920",
"sort": "best_seller",
"ps": "40",
"fetchMarquee": "true",
"fetchSkyline": "true",
"fetchSbaTop": "false"}
for i in range(1,25,1):
params['maxPage']=i
api_url='https://www.walmart.com/orchestra/home/graphql/browse'
resp = requests.post(api_url, data=json.dumps(data), headers=headers,params=params)
r=resp.json()
print(r)
# items = r['data']['search']['searchResult']['itemStacks'][0]['itemsV2']
# for item in items:
# price = item['priceInfo']['currentPrice']['price']
# print(price)
Output:
'https://i5.walmartimages.com/asr/deaaef8d-ca7f-4fc1-b556-1209c4c9000c.c6df15d971f1b9cddde27f80f17ae80b.jpeg?odnHeight=180&odnWidth=180&odnBg=ffffff'}, 'canonicalUrl': '/ip/Sonic-The-Hedgehog-Coloring-Book-For-Kids-Girls-Adults-Toddlers-Kids-ages-2-8-Unofficial-25-high-quality-illustrations-Pages-8-5-x-11-Paperback-9781677024223/614029660?athbdg=L1600', 'externalInfo': None, 'category': {'path': None}, 'badges': {'flags': [{'key': 'BESTSELLER', 'text': 'Best seller', 'type': 'LABEL', 'id': 'L1600'}], 'tags': [{'key': 'THREE_PLUS_DAY_SHIPPING', 'text': '3+ day shipping', 'type': 'LABEL'}, {'key': 'SAVE_WITH_W_PLUS', 'text': 'Save with', 'type': 'ICON'}]}, 'classType': 'REGULAR', 'averageRating': 3.9, 'numberOfReviews': 8, 'esrb': None, 'mediaRating': None, 'salesUnitType': 'EACH', 'sellerId': 'F55CDC31AB754BB68FE0B39041159D63', 'sellerName': 'Walmart.com', 'hasSellerBadge': None, 'availabilityStatusV2': {'display': 'In stock',
'value': 'IN_STOCK'}, 'productLocation': None, 'badge': [{'type': 'bestSeller', 'dynamicDisplayName': None}], 'fulfillmentSpeed': None, 'offerId': '27E4BA43A8704A1DABF0B37693611D16', 'preOrder': {'isPreOrder': False, 'preOrderMessage': None, 'preOrderStreetDateMessage': None}, 'priceInfo': {'priceRange': None, 'currentPrice': {'price': 6.99,
'priceString': '$6.99'}, 'wasPrice': None, 'unitPrice': None, 'listPrice': None, 'shipPrice': None, 'subscriptionPrice': None, 'priceDisplayCodes': {'priceDisplayCondition': None, 'finalCostByWeight': None}}, 'variantCriteria': [], 'fulfillmentBadge': None,
'fulfillmentTitle': 'title_shipToHome_not_available', 'fulfillmentType': 'FC', 'manufacturerName': None, 'showAtc': True, 'sponsoredProduct': None, 'showOptions': False}, {'__typename': 'Product', 'id': '16FA2JT4ZT52', 'usItemId': '491355610', 'fitmentLabel': None, 'name': 'Bible Word Search Books: Word Search Bible Puzzle Book - Extra Large
Print: Bible Word Search Large Print Puzzles for Seniors and Adults - Beginners Edition (Large Print) (Paperback)', 'checkStoreAvailabilityATC': False, 'seeShippingEligibility': False, 'brand': None, 'type': 'REGULAR', 'shortDescription': '<li>Format:Paperback</li><li>Publication Date: 2019-11-22</li>', 'imageInfo': {'thumbnailUrl': 'https://i5.walmartimages.com/asr/46269778-a1bc-4a7a-aff2-75a825e35cf9.62e71231ecd42f6cda6d3701a3281b53.jpeg?odnHeight=180&odnWidth=180&odnBg=ffffff'}, 'canonicalUrl': '/ip/Bible-Word-Search-Books-Puzzle-Book-Extra-Large-Print-Print-Puzzles-Seniors-Adults-Beginners-Edition-Large-Print-Paperback-9781710478792/491355610', 'externalInfo': None, 'category': {'path': None}, 'badges': {'flags': None, 'tags': [{'key': 'THREE_PLUS_DAY_SHIPPING', 'text': '3+ day shipping', 'type': 'LABEL'}, {'key': 'SAVE_WITH_W_PLUS', 'text': 'Save with', 'type': 'ICON'}]}, 'classType': 'REGULAR', 'averageRating': 4.7, 'numberOfReviews': 13, 'esrb': None, 'mediaRating': None, 'salesUnitType': 'EACH', 'sellerId': 'F55CDC31AB754BB68FE0B39041159D63', 'sellerName': 'Walmart.com', 'hasSellerBadge': None, 'availabilityStatusV2': {'display': 'In stock', 'value': 'IN_STOCK'}, 'productLocation': None, 'badge': None, 'fulfillmentSpeed': None, 'offerId': '0E3D37D69AE14435A4E83D3AE2789B7F', 'preOrder': {'isPreOrder': False, 'preOrderMessage': None, 'preOrderStreetDateMessage': None}, 'priceInfo': {'priceRange': None, 'currentPrice': {'price': 6.99, 'priceString': '$6.99'}, 'wasPrice': None, 'unitPrice': None, 'listPrice': None, 'shipPrice': None, 'subscriptionPrice': None, 'priceDisplayCodes': {'priceDisplayCondition': None, 'finalCostByWeight': None}}, 'variantCriteria': [], 'fulfillmentBadge': None, 'fulfillmentTitle': 'title_shipToHome_not_available', 'fulfillmentType': 'FC', 'manufacturerName': None, 'showAtc': True, 'sponsoredProduct': None, 'showOptions': False}, {'__typename': 'Product', 'id': '72BDRK2VT8QQ', 'usItemId': '599380007', 'fitmentLabel': None, 'name': 'Trace Letters and Numbers Workbook: Learn How to Write Alphabet Upper and Lower Case and Numbers (Series #2) (Paperback)', 'checkStoreAvailabilityATC': False, 'seeShippingEligibility': False, 'brand': None, 'type': 'REGULAR', 'shortDescription': '9781794540767', 'imageInfo': {'thumbnailUrl': 'https://i5.walmartimages.com/asr/535dff68-7946-4e20-899b-20d05015b05a_1.22a1f229111edd3725505c0db3fe1371.jpeg?odnHeight=180&odnWidth=180&odnBg=ffffff'}, 'canonicalUrl': '/ip/Trace-Letters-and-Numbers-Workbook-Learn-How-to-Write-Alphabet-Upper-and-Lower-Case-and-Numbers-Series-2-Paperback/599380007?athbdg=L1600', 'externalInfo': None, 'category': {'path': None}, 'badges': {'flags': [{'key': 'BESTSELLER', 'text': 'Best seller', 'type': 'LABEL', 'id': 'L1600'}], 'tags': [{'key': 'THREE_PLUS_DAY_SHIPPING', 'text': '3+ day shipping', 'type': 'LABEL'}, {'key': 'SAVE_WITH_W_PLUS', 'text': 'Save with', 'type': 'ICON'}]}, 'classType': 'REGULAR', 'averageRating': 4.7, 'numberOfReviews': 37, 'esrb': None, 'mediaRating':
None, 'salesUnitType': 'EACH', 'sellerId': 'F55CDC31AB754BB68FE0B39041159D63', 'sellerName': 'Walmart.com', 'hasSellerBadge': None, 'availabilityStatusV2': {'display': 'In
stock', 'value': 'IN_STOCK'}, 'productLocation': None, 'badge': [{'type': 'bestSeller', 'dynamicDisplayName': None}], 'fulfillmentSpeed': None, 'offerId': 'B701DAA6361D4A97A599815F29FA450D', 'preOrder': {'isPreOrder': False, 'preOrderMessage': None, 'preOrderStreetDateMessage': None}, 'priceInfo': {'priceRange': None, 'currentPrice': {'price': 6.95, 'priceString': '$6.95'}, 'wasPrice': None, 'unitPrice': None, 'listPrice': None, 'shipPrice': None, 'subscriptionPrice': None, 'priceDisplayCodes': {'priceDisplayCondition': None, 'finalCostByWeight': None}}, 'variantCriteria': [], 'fulfillmentBadge': None, 'fulfillmentTitle': 'title_shipToHome_not_available', 'fulfillmentType': 'FC', 'manufacturerName': None, 'showAtc': True, 'sponsoredProduct': None, 'showOptions': False}, {'__typename': 'Product', 'id': '72DZILK2NY05', 'usItemId': '817841366', 'fitmentLabel': None, 'name': 'Toddler Coloring Book for Kids Age 1-3 : aby Activity Book Boys or Girls, Preschool coloring for Their Fun Early Learning of First Easy Number Shape and Color (Paperback)', 'checkStoreAvailabilityATC': False, 'seeShippingEligibility': False, 'brand': None, 'type': 'REGULAR', 'shortDescription': '<li>Format:Paperback</li><li>Publication Date: 2019-08-02</li>', 'imageInfo': {'thumbnailUrl': 'https://i5.walmartimages.com/asr/d2f8e8be-7fa1-4a25-a80c-e1741c6b2f6f.6392f3a67fccf0b396e1fb6ee2848b4b.jpeg?odnHeight=180&odnWidth=180&odnBg=ffffff'}, 'canonicalUrl': '/ip/Toddler-Coloring-Book-Kids-Age-1-3-aby-Activity-Boys-Girls-Preschool-coloring-Their-Fun-Early-Learning-First-Easy-Number-Shape-Color-Paperback-9781086986501/817841366?athbdg=L1600', 'externalInfo': None, 'category': {'path': None}, 'badges': {'flags': [{'key': 'BESTSELLER', 'text': 'Best seller', 'type': 'LABEL', 'id': 'L1600'}], 'tags': [{'key': 'THREE_PLUS_DAY_SHIPPING', 'text': '3+ day shipping', 'type': 'LABEL'}, {'key': 'SAVE_WITH_W_PLUS', 'text': 'Save with', 'type': 'ICON'}]}, 'classType': 'REGULAR', 'averageRating': 5, 'numberOfReviews': 2, 'esrb': None, 'mediaRating': None, 'salesUnitType': 'EACH', 'sellerId': 'F55CDC31AB754BB68FE0B39041159D63', 'sellerName': 'Walmart.com', 'hasSellerBadge': None, 'availabilityStatusV2': {'display': 'In stock', 'value': 'IN_STOCK'},
'productLocation': None, 'badge': [{'type': 'bestSeller', 'dynamicDisplayName': None}], 'fulfillmentSpeed': None, 'offerId': 'D3D88022487D4BF19D540BED3742A75D', 'preOrder': {'isPreOrder': False, 'preOrderMessage': None, 'preOrderStreetDateMessage': None}, 'priceInfo': {'priceRange': None, 'currentPrice': {'price': 6.95, 'priceString': '$6.95'}, 'wasPrice': None, 'unitPrice': None, 'listPrice': None, 'shipPrice': None, 'subscriptionPrice': None, 'priceDisplayCodes': {'priceDisplayCondition': None, 'finalCostByWeight': None}}, 'variantCriteria': [], 'fulfillmentBadge': None, 'fulfillmentTitle': 'title_shipToHome_not_available', 'fulfillmentType': 'FC', 'manufacturerName': None, 'showAtc': True, 'sponsoredProduct': None, 'showOptions': False}, {'__typename': 'Product', 'id': '46CGMFA2PY1Y', 'usItemId': '56172624', 'fitmentLabel': None, 'name': 'Crystals for Beginners : The Guide to Get Started with the Healing Power of Crystals (Paperback)', 'checkStoreAvailabilityATC': False, 'seeShippingEligibility': False, 'brand': None, 'type': 'VARIANT', 'shortDescription': '<li>Format:Paperback</li><li>Publication
Date: 2017-10-17</li>', 'imageInfo': {'thumbnailUrl': 'https://i5.walmartimages.com/asr/d2954574-c30c-48af-8297-900867a2458e_1.03867d2efc65af18a6fdbff418a68afa.jpeg?odnHeight=180&odnWidth=180&odnBg=ffffff'}, 'canonicalUrl': '/ip/Crystals-for-Beginners-The-Guide-to-Get-Started-with-the-Healing-Power-of-Crystals-Paperback-9781623159917/56172624?athbdg=L1600', 'externalInfo': None, 'category': {'path': None}, 'badges': {'flags':
[{'key': 'BESTSELLER', 'text': 'Best seller', 'type': 'LABEL', 'id': 'L1600'}], 'tags': [{'key': 'THREE_PLUS_DAY_SHIPPING', 'text': '3+ day shipping', 'type': 'LABEL'}, {'key': 'SAVE_WITH_W_PLUS', 'text': 'Save with', 'type': 'ICON'}]}, 'classType': 'VARIANT', 'averageRating': 5, 'numberOfReviews': 13, 'esrb': None, 'mediaRating': None, 'salesUnitType': 'EACH', 'sellerId': 'F55CDC31AB754BB68FE0B39041159D63', 'sellerName': 'Walmart.com', 'hasSellerBadge': None, 'availabilityStatusV2': {'display': 'In stock', 'value': 'IN_STOCK'}, 'productLocation': None, 'badge': [{'type': 'bestSeller', 'dynamicDisplayName': None}], 'fulfillmentSpeed': None, 'offerId': '5F59F4B1DE6945728E7F2EC9A3005472', 'preOrder': {'isPreOrder': False, 'preOrderMessage': None, 'preOrderStreetDateMessage': None}, 'priceInfo': {'priceRange': None, 'currentPrice': {'price': 8.99, 'priceString': '$8.99'}, 'wasPrice': None, 'unitPrice': None, 'listPrice': {'price': 14.99, 'priceString': '$14.99'}, 'shipPrice': None, 'subscriptionPrice': None, 'priceDisplayCodes': {'priceDisplayCondition': None, 'finalCostByWeight': None}}, 'variantCriteria': [], 'fulfillmentBadge': None, 'fulfillmentTitle': 'title_shipToHome_not_available', 'fulfillmentType': 'FC', 'manufacturerName': None, 'showAtc': True, 'sponsoredProduct': None, 'showOptions': False}, {'__typename': 'Product', 'id': '7FF8DA7PEPDT', 'usItemId': '136868031', 'fitmentLabel': None, 'name': 'Hack Learning: Hacking School Discipline : 9 Ways to Create a Culture of Empathy and Responsibility Using Restorative Justice (Series #22) (Paperback)', 'checkStoreAvailabilityATC': False, 'seeShippingEligibility': False, 'brand': None, 'type': 'REGULAR', 'shortDescription': '<li>Format:Paperback</li><li>Publication Date: 2019-03-12</li>', 'imageInfo': {'thumbnailUrl': 'https://i5.walmartimages.com/asr/4c639aa7-2580-4782-84ce-33a428cae000.571d547af78d39ffc35bdd28f988023f.jpeg?odnHeight=180&odnWidth=180&odnBg=ffffff'}, 'canonicalUrl': '/ip/Hack-Learning-Hacking-School-Discipline-9-Ways-Create-Culture-Empathy-Responsibility-Using-Restorative-Justice-Series-22-Paperback-9781948212137/136868031?athbdg=L1600', 'externalInfo': None, 'category': {'path': None}, 'badges': {'flags': [{'key': 'BESTSELLER', 'text': 'Best seller', 'type': 'LABEL', 'id': 'L1600'}], 'tags': [{'key': 'THREE_PLUS_DAY_SHIPPING', 'text': '3+ day shipping', 'type': 'LABEL'}, {'key': 'SAVE_WITH_W_PLUS', 'text': 'Save with', 'type': 'ICON'}]}, 'classType':
Output: Extracted price as example:
22.99
1.22
6.99
9.95
5.95
9.81
5.99
13.17
4.52
6.99
4.99
7.99
6.79
5.99
6.5
6.95
6.99
5.99
4.99
5
4.99
11.93
5.99
4.99
6.99
6.99
6.95
6.95
8.99
14.81
5.13
7.29
3.95
5.99
5.5
5.99
16.88
6.99
6.99
1.99
22.99
1.22
6.99
9.95
5.95
9.81
5.99
13.17
4.52
6.99
4.99
7.99
6.7
While this question specifically relates to Python, consider using Puppeteer or Playwright for browser automation. This allows you to initiate requests as the user from a high-level, and you can use page.on('response') to intercept API server responses. This could remove the low-level schema requirements that are more likely to change compared to the public UI. You could also parse the web page results seen by users, which avoids the low-level data abstractions.

How to subtract key out of Json api response and check if there are more keys, and if so put them in a list?

So I have a complex problem, I have a JSON API response with the key: 'key' in 'persons'
but in some cases there is more than 1 'key', I tried to make a for loop to go through the response but it will print it like 20 times. Also, I have no idea to put those 'keys' in a list or a place where I can access them.
to make it a bit easier i have the response that i get out of my .request
{'id': 'a2b1109e-e142-4559-984c-3f9997b1db6a', 'externalId': None, 'name': 'tyr', 'description': '', 'client': '', 'reference': '56345', 'isMonitoring': False, 'monitoringSince': None, 'hasRiskProfile': True, 'riskProfile': 5, 'monitorFrequency': 4, 'mainBindable': None, 'organizationId': '65647b97-5ada-4362-bb3f-cae016722be6', 'userId': 'dd3cc015-e5cf-4a03-9408-74b102900836', 'createDate': '2021-03-23T11:29:55.2027037Z', 'updateDate': '2021-03-23T11:29:55.2027039Z', 'lastMonitorDate': '2021-03-23T11:29:55.2027039Z', 'persons': [{'firstname': 'ya', 'surname': 'o', 'dateOfBirth': '', 'updatedWithIdinIdentificationRequestPerson': None, 'relatedList': None, 'updatedWithIdinIdentificationRequestPersonDate': None, 'history': [], 'fullname': 'ya o', 'externalId': None, 'key': '8b92c210-eee6-4ab2-a093-48e4428af7f8', 'searchResults': [], 'requests': [], 'createDate': '2021-03-23T11:29:57.3853552Z', 'updateDate': '2021-03-23T11:29:57.3853553Z', 'archivedDate': None, 'isArchived': False, 'hasPepSearchResults': False, 'notes': []}], 'businesses': [], 'monitorIds': [], 'addresses': [], 'notifcations': [], 'monitors': []}
the number of keys can be different each time, so I will need to make a check to see if the key that gets back is already existing if so then do nothing, if the key is not existing then save that key in a variable.
here is a example of a response when there are 2 keys"key",
{'id': '44b2203b-b2c8-41f0-8fde-b697ec02a8c8', 'externalId': None, 'name': 'tyr', 'description': '', 'client': '', 'reference': '56345', 'isMonitoring': False, 'monitoringSince': None, 'hasRiskProfile': True, 'riskProfile': 5, 'monitorFrequency': 4, 'mainBindable': None, 'organizationId': '65647b97-5ada-4362-bb3f-cae016722be6', 'userId': 'dd3cc015-e5cf-4a03-9408-74b102900836', 'createDate': '2021-03-23T20:58:53.0345703Z', 'updateDate': '2021-03-23T20:58:53.0345705Z', 'lastMonitorDate': '2021-03-23T20:58:53.0345706Z', 'persons': [{'firstname': 'marnox', 'surname': 'bolier', 'dateOfBirth': '', 'updatedWithIdinIdentificationRequestPerson': None, 'relatedList': None, 'updatedWithIdinIdentificationRequestPersonDate': None, 'history': [], 'fullname': 'marnox bolier', 'externalId': None, 'key': '68e4a9ad-2431-490f-a216-61a0cbd81c57', 'searchResults': [{'at': '2021-03-23T20:58:54.6796804Z', 'totalHits': 0, 'type': None, 'results': [{'paymentRequired': False, 'service': None, 'source': 'CIR', 'items': [], 'count': 0}, {'paymentRequired': False, 'service': 'VaV61', 'source': 'Entity', 'items': [], 'count': 0}], 'requestable': {'id': 'bf9dea30-2f4a-467a-a7b1-6765ceaee517', 'name': 'marnox bolier', 'createDate': '2021-03-23T20:58:55.5409494Z', 'updateDate': '2021-03-23T20:58:55.5409495Z', 'type': 'NotFoundPerson', 'sourceKey': 'A135D3C449EA15C66B6444611E2C97EC', 'picture': None, 'properties': {}, 'resultKey': None, 'data': None, 'archivedDate': None, 'isArchived': False}, 'cachedResult': False}], 'requests': [{'id': '57866866-85c4-43d8-8caa-b47a90b12be4', 'name': 'marnox bolier (TO UPDATE)', 'createDate': '2021-03-23T20:58:56.3090064Z', 'updateDate': '2021-03-23T20:58:56.3090064Z', 'type': 'NotFoundPerson', 'sourceKey': 'AB1AD3379D84D5D2404CF8326CDA054D', 'picture': None, 'properties': {}, 'resultKey': None, 'data': None, 'archivedDate': None, 'isArchived': False}], 'createDate': '2021-03-23T20:58:53.912784Z', 'updateDate': '2021-03-23T20:58:53.912784Z', 'archivedDate': None, 'isArchived': False, 'hasPepSearchResults': True, 'notes': []}, {'firstname': 'marnix', 'surname': 'bolier', 'dateOfBirth': '', 'updatedWithIdinIdentificationRequestPerson': None, 'relatedList': None, 'updatedWithIdinIdentificationRequestPersonDate': None, 'history': [], 'fullname': 'marnix bolier', 'externalId': None, 'key': 'c0475154-530e-4802-b215-1d26a2c7f208', 'searchResults': [], 'requests': [], 'createDate': '2021-03-23T20:58:56.9078002Z', 'updateDate': '2021-03-23T20:58:56.9078002Z', 'archivedDate': None, 'isArchived': False, 'hasPepSearchResults': False, 'notes': []}], 'businesses': [], 'monitorIds': [], 'addresses': [], 'notifcations': [], 'monitors': []}
update i solved my first problem getting more than 1 key with a for loop:
for persons in api_response['persons']:
print(persons['key'])
output:
0b8eb227-0105-40a3-bc8b-8e3ef345a3f3
d9b68e7a-ffdd-44ea-86a4-ea4c541146b4
how can I only save the last result so in this case
d9b68e7a-ffdd-44ea-86a4-ea4c541146b4
Assuming you are using requests to fetch the data from the api your response will simply have a json() function attached. Meaning you can do something like this:
import requests
response = requests.get("example.com/api/random/endpoint")
data = response.json()
The json function in turn does the equivalent of json.loads() with the content of the response. Assuming your API returns a JSON object this will be converted to a dictionary (in accordance with the json conversion table.
After that you can follow go2nirvana's answer and manipulate this dictionary as you would any dict. For example using data.pop("key") to remove the value at that key, iterate over the dictionary, or whatever else you can do with a dictionary.
Admittedly your question is a bit vague and I am not sure exactly what you want to do with the data you recieve, but this is how you get that data in a form that is easy to work with within python.

How save a json file in python from api response when the class is a list and object is not serializable

I have tried to find the answer but I could not find it
I am looking for the way to save in my computer a json file from python.
I call the API
configuration = api.Configuration()
configuration.api_key['X-XXXX-Application-ID'] = 'xxxxxxx'
configuration.api_key['X-XXX-Application-Key'] = 'xxxxxxxx1'
## List our parameters as search operators
opts= {
'title': 'Deutsche Bank',
'body': 'fraud',
'language': ['en'],
'published_at_start': 'NOW-7DAYS',
'published_at_end': 'NOW',
'per_page': 1,
'sort_by': 'relevance'
}
try:
## Make a call to the Stories endpoint for stories that meet the criteria of the search operators
api_response = api_instance.list_stories(**opts)
## Print the returned story
pp(api_response.stories)
except ApiException as e:
print('Exception when calling DefaultApi->list_stories: %s\n' % e)
I got the response like this
[{'author': {'avatar_url': None, 'id': 1688440, 'name': 'Pranav Nair'},
'body': 'The law firm will investigate whether the bank or its officials have '
'engaged in securities fraud or unlawful business practices. '
'Industries: Bank Referenced Companies: Deutsche Bank',
'categories': [{'confident': False,
'id': 'IAB11-5',
'level': 2,
'links': {'_self': 'https://,
'parent': 'https://'},
'score': 0.39,
'taxonomy': 'iab-qag'},
{'confident': False,
'id': 'IAB3-12',
'level': 2,
'links': {'_self': 'https://api/v1/classify/taxonomy/iab-qag/IAB3-12',
'score': 0.16,
'taxonomy': 'iab-qag'},
'clusters': [],
'entities': {'body': [{'indices': [[168, 180]],
'links': {'dbpedia': 'http://dbpedia.org/resource/Deutsche_Bank'},
'score': 1.0,
'text': 'Deutsche Bank',
'types': ['Bank',
'Organisation',
'Company',
'Banking',
'Agent']},
{'indices': [[80, 95]],
'links': {'dbpedia': 'http://dbpedia.org/resource/Securities_fraud'},
'score': 1.0,
'text': 'securities fraud',
'types': ['Practice', 'Company']},
'hashtags': ['#DeutscheBank', '#Bank', '#SecuritiesFraud'],
'id': 3004661328,
'keywords': ['Deutsche',
'behalf',
'Bank',
'firm',
'investors',
'Deutsche Bank',
'bank',
'fraud',
'unlawful'],
'language': 'en',
'links': {'canonical': None,
'coverages': '/coverages?story_id=3004661328',
'permalink': 'https://www.snl.com/interactivex/article.aspx?KPLT=7&id=58657069',
'related_stories': '/related_stories?story_id=3004661328'},
'media': [],
'paragraphs_count': 1,
'published_at': datetime.datetime(2020, 5, 19, 16, 8, 5, tzinfo=tzutc()),
'sentences_count': 2,
'sentiment': {'body': {'polarity': 'positive', 'score': 0.599704},
'title': {'polarity': 'neutral', 'score': 0.841333}},
'social_shares_count': {'facebook': [],
'google_plus': [],
'source': {'description': None,
'domain': 'snl.com',
'home_page_url': 'http://www.snl.com/',
'id': 8256,
'links_in_count': None,
'locations': [{'city': 'Charlottesville',
'country': 'US',
'state': 'Virginia'}],
'logo_url': None,
'name': 'SNL Financial',
'scopes': [{'city': None,
'country': 'US',
'level': 'national',
'state': None},
{'city': None,
'country': None,
'level': 'international',
'state': None}],
'title': None},
'summary': {'sentences': ['The law firm will investigate whether the bank or '
'its officials have engaged in securities fraud or '
'unlawful business practices.',
'Industries: Bank Referenced Companies: Deutsche '
'Bank']},
'title': "Law firm to investigate Deutsche Bank's US ops on behalf of "
'investors',
'translations': {'en': None},
'words_count': 26}]
In the documentation says "Stories you retrieve from the API are returned as JSON objects by default. These JSON story objects contain 22 top-level fields, whereas a full story object will contain 95 unique data points"​
The class is a list. When I have tried to save json file I have the error "TypeError: Object of type Story is not JSON serializable".
How I can save a json file in my computer?
The response you got is not json, json uses double quotes, but here its single quotes. Copy paste your response in the following link to see the issues
http://json.parser.online.fr/.
If you change it like
[{"author": {"avatar_url": None, "id": 1688440, "name": "Pranav Nair"},
"body": "......
It will work, You can use python json module to do it
import json
json.loads(the_dict_got_from_response).
But it should be the duty of the API provider to, To make it working you can json load the result you got.

Categories