Home > Enterprise >  extract data from JSON api with python
extract data from JSON api with python

Time:10-04

hello fellows as you see on my code here i got the min price value but the problem is i cant get the rest of the data linked with the minimum price such as ingame_name and status especially status for the minimum price :

for example we take this item url : https://api.warframe.market/v1/items/mirage_prime_systems/orders?include=item

as result we will get lot of open orders from that JSON Link , the thing i need to do here is to get min price of selling from an online player with all his basic info for the user .

here is my code

import requests
import json


item = input('put your item here please :  ')
gg = item.replace(' ', '_')
response_url =  requests.get(f'https://api.warframe.market/v1/items/'  gg  '/orders?include=item')

data = json.loads(response_url.text)
orders = data["payload"]["orders"]
           
min_price = min(o["platinum"] for o in orders if o["order_type"] == "sell")


print(min_price)

and i seem i cant get do it unless u help me guys and i really appreciate it .

CodePudding user response:

Filter the list by order type and find the min using lambda

orders = [{'order_type':'sell','other':88,'platinum':4},
          {'order_type':'sell','other':77,'platinum':9},
          {'order_type':'buy','other':88,'platinum':4}]

min_price = min([o for o in orders if o["order_type"] == "sell"],key= lambda x : x ['platinum'])
print(min_price)

output

{'order_type': 'sell', 'other': 88, 'platinum': 4}

CodePudding user response:

You can use built-in min() with custom key. As you need to apply some filtering on initial data, there're two possible ways:

  1. Filter data before searching minimum (one of possible methods shown in this answer);
  2. Exploit lexicographical comparison which is used in python to compare sequences (docs).

I found second method is better as it makes possible to iterate over all orders just once (which more efficient).

So to implement this we should return from lambda which we will pass to min() not just "platinum" key value, but also boolean result of inverted conditions.

Why inverted? Because we are searching for minimum value. It means that every return of our lambda will be compared with previous minimum. In python False equals 0 and True equals 1 (docs). 0 < 1 so if any of inverted conditions will be True all key will be greater ignoring "platinum" value.

Code:

import requests
from json import JSONDecodeError

item = input("Put your item here please: ")

try:
    response = requests.get("https://api.warframe.market/v1/items/"  
                            item.lower().replace(" ", "_")   "/orders",
                            params={"include": "item"})
    json_data = response.json()
    orders = json_data["payload"]["orders"]
except requests.RequestException as e:
    print("An error occurred during processing request:", e)
except JSONDecodeError:
    print("Server response is not valid json:", response.text)
except KeyError as e:
    print("Response doesn't contain", e, "key")
except Exception as e:
    print("Unexpected error:", e)
else:
    min_price_order = min(orders, key=lambda x: (x["order_type"] != "sell",
                                                 x["user"]["status"] != "ingame",
                                                 x["platinum"]))
    print(min_price_order)
  • Related