I found that the DRF's return value could be various upon different occasions. So I want to make sure all my JSON return have "code" "message" or other values nested inside in order to keep consistency of my APIs.
For example:
Success
{"code": 1, "status": "success", "message": "", "data": [{"id": 1, "name": "John Doe", "email": "johndoe#gmail.com"}]}
Error
{"code": -1, "status": "error", "message":"Something went wrong","data": [] }
The return will always have "code" "status" "message" "data" inside whatever the result would become.
After looked up on Google but couldn't find any work-around over DRF. So I suppose everybody is redefining the APIViews or Mixins (get put post etc. ) to control the response. But I am not very sure if the return should be that widely different without a certain pattern. Or is it cool that DRF's JSON response could be directly adopted as a production case?
Hope to have some advice from you guys.
Thanks.
You can use the status code of the HTTP to indicate the errors and success and you dont have to explicitly specify the error codes and response codes. In DRF status codes are defined in the module rest_framework.status
and you should use them and form the response accordingly.
Related
everyone
I started programming in python yesterday to create a project. This consists of taking data from an API using the "Requests" library
So far I had no trouble getting familiar with the library, but I can't get results for what I'm specifically looking for.
My idea is just to get the name of the account.
Here the code
import requests
user = 'example'
payload = {'data': 'username'}
r = requests.get('https://api.imvu.com/user/user-'+user, params=payload)
json = r.json()
print(json)
My idea is that, within all the data that can be obtained, only obtain the name of the account. just the name
The code works perfectly, but it throws me all the account data.
For example:
{
"https://api.imvu.com/user/user-x?data=created": {
"data": {
"created": "2020-11-30T17:56:31Z",
"registered": "x",
"gender": "f",
"display_name": " ",
"age": "None",
"country": "None",
"state": "None",
"avatar_image": "x",
"avatar_portrait_image": "https://......",
"is_vip": false,
"is_ap": true,
"is_creator": false,
"is_adult": true,
"is_ageverified": true,
"is_staff": false,
"is_greeter": false,
"greeter_score": 0,
"badge_level": 0,
"username": "=== ONLY THIS I NEED ==="
}
}
}
As you can see, I only need one thing from all that data.
Sorry for bothering and I hope I can learn from your answers. Thanks so much for reading
Unless API allows you to specify exactly what data to return (some does) then you got no control about the API behavior nor what data (and how) given endpoint returns. Publicly exposed API is all you can have in hand and sometimes you may get tons of useless data and there's basically nothing you can do about that.
To get specific item from json, you can simply make few changes in your code.
r = requests.get('https://api.imvu.com/user/user-'+user, params=payload)
json = r.json()
username = json["https://api.imvu.com/user/user-x?data=created"]["data"]["username"]
print(username)
you might check whether there is an alternative REST method that only provides you with the username.
The REST response you cannot modify as it is sent from the server, so you need to parse the response e.g. like here
Extract value from json response python?
python
I have to implement a web service using Flask and MongoDB. I have two collections. The JSON files are shown below:
File products.json:
{ "name":"red apples", "price":0.5, "description":"Apples from Greece", "category":"fruits", "stock":25 }
{ "name":"fish", "price":5, "description":"Fresh fish", "category":"fish", "stock":25 }
{ "name":"pasta", "price":1.5, "description":"Pasta from Italia", "category":"pasta", "stock":25 }
File users.json:
{"name":"George Vaios", "password":"321", "email":"george#gmail.gr", "category":"admin"}
{"name":"Admin", "password":"admin", "email":"admin#gmail.gr", "category":"admin"}
What I'm trying to do?
I'm trying to implement a function called add_product. This function allows users whose category is admin ("category": "admin"). As a route has a POST method because I'm parsing the email of a user and the details are needed to import a new product in products.json.
Code:
(lines of code for loading data)
user = users.find_one({"email":data['email']})
if (user['category']=="admin"):
product = {
"name": data['name'],
"price": data['price'],
"description": data['description'],
"category": data['category'],
"stock": data['stock']
}
products.insert_one(product)
return Response("Product was added succesfully", status=200, mimetype='application/json')
else:
return Response("Account has no permission. Must be an admin", status=400, mimetype='application/json')
With that code I'm trying to check if the user is an admin by finding him in the JSON file using the find_one method and then compare the user['category'] with the string 'admin'.
Data that I'm parsing to postman:
{
"email": "george#gmail.gr",
"name": "chocolate",
"price": 25,
"description": "mklkgj",
"category": "sweets",
"stock": 30
}
Error that I get:
File "/home/michael/main.py", line 241, in add_product_admin
if (user['category']=="admin"):
TypeError: 'NoneType' object is not subscriptable
I can't understand why the if statement doesn't make the comparison. Any thoughts?
Mongo is telling you that nothing came up when searching for that value. I would start by checking if data['email'] has the value you would expect and if your collection is initialized correctly.
Thanks to everyone who explained to me what's going on. The actual problem was on MongoDB and client parameters on Python script. That's why the entries and JSON files were unreadable. If anyone comes up again with this problem be sure that you have checked:
# Choose database
database = client['database you want to access']
Then don't forget to check with mongo shell if your expected collections exist:
db.(your database name).find({})
Thank you for your time!
I am trying to obtain the ticker channel data via a websocket. I am getting a response with some data, however the data I am getting is not matching the what it is suppose to show.
I have tried doing what the API specifies. The API (https://docs.pro.coinbase.com/#the-ticker-channel) says to send the request as follows:
params = {
"type": "subscribe",
"channels": [{"name": "ticker", "product_ids": ["BTC-USD"]}]
}
Now this works, and I get a response, however the response I get is:
{
"type":"ticker",
"sequence":9568995003,
"product_id":"BTC-USD",
"price":"7779.00000000",
"open_24h":"7895.99000000",
"volume_24h":"19546.97986005",
"low_24h":"7467.10000000",
"high_24h":"7945.50000000",
"volume_30d":"569908.80402872",
"best_bid":"7775.66",
"best_ask":"7778.81"
}
when the api says the output should be:
{
"type": "ticker",
"trade_id": 20153558,
"sequence": 3262786978,
"time": "2017-09-02T17:05:49.250000Z",
"product_id": "BTC-USD",
"price": "4388.01000000",
"side": "buy", // Taker side
"last_size": "0.03000000",
"best_bid": "4388",
"best_ask": "4388.01"
}
As you can see, I am missing the last_size, and side. I am unsure as to what I am doing wrong.
from websocket import create_connection
import json
URL = "wss://ws-feed.pro.coinbase.com"
ws = create_connection(URL)
params = {
"type": "subscribe",
"channels": [{"name": "ticker", "product_ids": ["BTC-USD"]}]
}
def single():
ws.send(json.dumps(params))
result = ws.recv()
print(result)
single()
The expected output should include the last_size, and side tags. Any help is greatly appreciated.
I have been implementing the same code myself and I also am not getting last_size and side included in the json. My best guess is that the json object being sent is not retrieving this information, which with my understanding means you will have to go without this information. If anyone does know of a way to retrieve this information, feel free to correct me.
EDIT: I think I have discovered the issue for why last_size is not being included in some of the responses (still unsure about side though). When the json is being printed, the price isn't changing, as I realized when I ran in a continuous while loop. Only when a trade has occurred will there be a shift in price, and therefore a 'last_size' category. I will provide the params I am passing as well as the code to illustrate how I get this result.
params = {"type": "subscribe", "product_ids": ["BTC-USD"],
"channels": ["heartbeat", {"name": "ticker", "product_ids": ["BTC-USD"]}]}
while True:
ws.send(json.dumps(params))
result = ws.recv()
print(result)
time.sleep(1)
converted = json.loads(result)
You will receive a KeyError if you try to access the 'last_size' if the price hasn't changed. My advice would be to catch this error and ignore that json, as you have all the information you already need from the json returned previously.
Hope this helps in clarifying your issue, my original response is still valid for 'side' as I have not come across anyway to receive that information.
I want to get post's likes count using HTTP request. I am doing in this way
https://graph.facebook.com/10153608167431961?fields=likes.limit(0).summary(true)?access_token=EAANep****
and getting the error
{
"error": {
"message": "Syntax error \"Expected end of string instead of \"?\".\" at character 14: likes.limit(0)?access_token=EA*****",
"type": "OAuthException",
"code": 2500,
"fbtrace_id": "FgmjqQQgY+J"
}
}
Is it syntactically something wrong?
Correct:
https://graph.facebook.com/10153608167431961?fields=likes.limit(0).summary(true)&access_token=xxx
You can´t have more than one questionmark, separate the different parameter with &.
I am trying to set the 'transition' property in a JIRA issue from whatever it is, to completed(which according to the doc is 10000). According to the documentation, this error is 'If there is no transition specified.'
Also I have used ?expand=transitions.fields to verify that 10000 is for complete.
using these docs
https://docs.atlassian.com/jira/REST/latest/#api/2/issue-doTransition
https://jira.atlassian.com/plugins/servlet/restbrowser#/resource/api-2-issue-issueidorkey-transitions/POST
Here is my request
url = 'http://MYURL/rest/api/2/issue/ISSUE-ID/transitions'
payload1 = open('data3.json', 'r').read()
payload = json.loads(payload1)
textFile = requests.post(url, auth=('username', 'password'), json=payload)
The contents on my data3.json file are
{
"transition": 10000
}
edit: I also changed my JSON to this and I get a 500 error
{
"transition": {
"id": "10000"
}
}
The error I get
{"errorMessages":["Can not instantiate value of type [simple type,classcom.atlassian.jira.rest.v2.issue.TransitionBean] from JSON integral number;no single-int-arg constructor/factory method (through reference chain:com.atlassian.jira.rest.v2.issue.IssueUpdateBean[\"transition\"])"]}400
I'm pretty confident that my issue is in my json file since I have used GET in the code above this snippit multiple times, but I could be wrong.
Possible cause - https://jira.atlassian.com/browse/JRA-32132
I believe the issue I was having was a process flow one. I cannot jump right from my issue being opened, to 'completed'. However, I can go from the issue being created to 'Done'.
{
"transition": {
"name": "Done",
"id": "151"
}
}
As this does what I need, I will use it. If I find how to make ticket complete I will post back.
Also, I think the fact we customize our JIRA lead to my getting 'Completed' as a valid transition even though it wasn't.
Yes, you're right that the JSON is wrong, it's not even a valid json since the value is not a number, string, object, or array. The doc says:
The fields that can be set on transtion, in either the fields
parameter or the update parameter can be determined using the
/rest/api/2/issue/{issueIdOrKey}/transitions?expand=transitions.fields
resource.
So you need to do a get request on /rest/api/2/issue/{issueIdOrKey}/transitions?expand=transitions.fields to get the list of possible values and then set that in the json
{
"transition": {
"id" : "an_id_from_response"
}
}