I'm new to python and I faced an error which I totally don't understand why occures.
In the Insomnia client REST API I'm creating item with POST method, and it works well, below it the code
#app.post('/item')
def create_item():
item_data = request.get_json()
if (
"price" not in item_data
or "store_id" not in item_data
or "name" not in item_data
):
abort(
400,
message="Bad request"
)
for item in items.values():
if (
item_data["name"] == item["name"]
and item_data["store_id"] == item["store_id"]
):
abort(400, message="Item already exist")
if item_data["store_id"] not in stores:
abort(404, message="Store not found")
if item_data["store_id"] not in stores:
abort(404, message="Store not found")
item_id = uuid.uuid4().hex
item = {**item_data, "id": item_id}
items["item_id"] = item
return item, 201
and here is the outcome of post method, created item with "id"
{
"id": "1c0deba2c86542e3bde3bcdb5da8adf8",
"name": "chair",
"price": 17,
"store_id": "e0de0e2641d0479c9801a32444861e06"
}
when I run GET method using "id" from above item putting it to the link I get error code 304
#app.get("/item/<string:item_id>")
def get_item(item_id):
try:
return items[item_id]
except KeyError:
abort(404, message="Item not found")
Can You please suggest what is wrong here ?
thanks
Try this:
#app.route('/item/<string:id>')
def get_item(id):
instance = YourMOdel.query.filter_by(id=id).first()
if instance:
return render_template('data.html', instance = instance)
return f"Employee with id ={id} Doenst exist"
Related
I am using FastAPI to make get/post/put/del requests, which all work perfectly fine in the browser. I wanted to use Postman to do the exact same thing; however, I am running into an issue trying to do anything other than GET. Below is the error I am getting:
{
"detail": [
{
"loc": [
"body"
],
"msg": "field required",
"type": "value_error.missing"
}
]
}
422 Unprocessable Entity is the exact error.
Below is the code I am using:
from lib2to3.pytree import Base
from fastapi import FastAPI, Path, Query, HTTPException, status, File, Form
from typing import Optional, Dict, Type
from pydantic import BaseModel
import inspect
app = FastAPI()
class Item(BaseModel):
name: str
price: float
brand: Optional[str] = None
class UpdateItem(BaseModel):
name: Optional[str] = None
price: Optional[float] = None
brand: Optional[str] = None
inventory = {}
#app.get("/get-item/{item_id}")
def get_item(item_id: int = Path(None, description = "The ID of the item")):
if item_id not in inventory:
raise HTTPException(status_code = 404, detail = "Item ID not found")
return inventory[item_id]
#app.get("/get-by-name/")
def get_item(name: str = Query(None, title = "Name", description = "Test")):
for item_id in inventory:
if inventory[item_id].name == name:
return inventory[item_id]
# return {"Data": "Not found"}
raise HTTPException(status_code = 404, detail = "Item ID not found")
#app.post("/create-item/{item_id}")
def create_item(item_id: int, item: Item):
if item_id in inventory:
raise HTTPException(status_code = 400, detail = "Item ID already exists")
inventory[item_id] = item
print(type(item))
return inventory[item_id]
#app.put("/update-item/{item_id}")
def update_item(item_id: int, item: UpdateItem):
if item_id not in inventory:
# return {"Error": "Item does not exist"}
raise HTTPException(status_code = 404, detail = "Item ID not found")
if item.name != None:
inventory[item_id].name = item.name
if item.brand != None:
inventory[item_id].brand = item.brand
if item.price != None:
inventory[item_id].price = item.price
return inventory[item_id]
#app.delete("/delete-item/{item_id}")
def delete_item(item_id: int = Query(..., description="ID of item you want to delete", ge=0)):
if item_id not in inventory:
# return {"Error": "ID does not exist"}
raise HTTPException(status_code = 404, detail = "Item ID not found")
del inventory[item_id]
return {"Success": "Item deleted"}
I tried this possible solution with no luck: https://github.com/tiangolo/fastapi/issues/2387
Your endpoint expects Item as JSON (body) data, but the screenshot you provided shows that you are sending the required fields as Query parameters (using the Params tab in Postman); hence, the error that the body is missing. You should instead add your data to the body of your POST request in Postman. To do that, you should go to Body > raw, and select JSON from the dropdown list to indicate the format of your data. Your payload should look something like this:
{
"name": "foo",
"price": 1.50
}
See related answers here and here as well. In case you needed to pass the parameters of Item model as Query parameters, you should then use Depends(), as described in this answer (Method 2).
On postman you need to change headers, by default, the value of Content-Type is plain/text, change it to application/json.
View answer at
POST request response 422 error {'detail': [{'loc': ['body'], 'msg': 'value is not a valid dict', 'type': 'type_error.dict'}]}
from http.client import responses
from random import randrange
from tkinter.tix import STATUS
from typing import Optional
from urllib import response
from fastapi import Body, FastAPI, Response ,status, HTTPException
from pydantic import BaseModel
app= FastAPI()
class Post(BaseModel):
title: str
content: str
Published: bool = True
rating: Optional[int] = None
my_post = [{"title": "title of post 1", "content": "content of post 1", "id": 2},{"title": "title of post 2","content":"content of post 2", "id":3}]
def find_post(id):
for p in my_post:
if p["id"] == id:
return p
def find_index_post(id):
for i,p in enumerate(my_post):
if p["id"]== id:
return i
#app.get("/posts/{id}")
def get_posts(id: int , response: Response):
post= find_post(id)
if not post :
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail= f"post with id {id} not found bludd")
# response.status_code=status.HTTP_404_NOT_FOUND
# return {"message": f" post with id : {id} not found"}
return{"here is the post": post}
#app.delete("/posts/{id}", status_code= status.HTTP_204_NO_CONTENT)
def delete_post(id: int):
index= find_index_post(id)
if index == None:
raise HTTPException(status_code= status.HTTP_404_NOT_FOUND, detail= f"post with id {id} does not exist")
my_post.pop(index)
return Response(status_code= status.HTTP_204_NO_CONTENT)
#app.put("/posts/{id}")
def update_post(id: int , post: Post):
index = find_index_post(id)
if index == None :
raise HTTPException(status_code= status.HTTP_404_NOT_FOUND, detail= f"post with id {id} does not exist")
post_dict = my_post.dict()
post_dict["id"]= id
my_post[index]= post_dict
return {"message" : "updated post"}
Everything else works, but the put/update function at the end.
Literally coding along with a tutorial and have non-stop irritating issues.
Python console says: 422 Unprocessable Entity.
Postman says:
"detail":
"loc":
"body","msg": "field required",
"type": "value_error.missing"
The 422 unprocessable entity error tells exactly which part of your request doesn't match the expected format. In your case, it says that the body is missing. When using Pydantic models, you essentially declare a JSON object (or Python dict), and hence, your endpoint expects a request body with that object. Thus, the request you send must include a JSON payload matching the model. Below is an example using Python requests, but you could also test that through OpenAPI at http://127.0.0.1:8000/docs.
import requests
url = 'http://127.0.0.1:8000/posts/2'
payload = {"title": "string", "content": "string", "Published": True,"rating": 0}
resp = requests.put(url, json=payload)
print(resp.json())
Additionally, make sure in your endpoint that you get the Post object properly. That is, the line post_dict = my_post.dict() should be replaced with post_dict = post.dict().
having some problems with checking item existence in dynamo table..code so far :
#app.route("/", methods=['GET'])
def index1():
name = request.form["fullname"]
get_res=requests.get('api-url',json=name)
temp=get_res.json()
get_res=temp['body']
return get_res
Lambda get_item func :
def lambda_handler(event, context):
try:
get_response=table.get_item(
Key={
'name':event['name']
}
)
res=get_response
except:
res={
'result':'not in DB'
}
return {
'statusCode': 200,
'body': res
}
result im getting ( even if input name is in DB ) :
{
"result": "not in DB"
}
i think i somehow managed to go around it..
get_res = requests.get('https://g7ry7a4ix6.execute-api.eu-central-1.amazonaws.com/prod/req', json=item)
temp = get_res.json()
try:
if temp['body']['Item']['name']:
pass
except:
res = requests.post('api-url', json=item)
return render_template('reg.html', name=name, phone=phone)
I am trying to check how many records a player has using the Hypixel API friends endpoint (api.hypixel.net/friends)
It keeps giving me a key error when trying to count the records. Here is what the API gives me:
{
"success": true,
"records": [{"_id":"5806841c0cf247f13be18b9d","uuidSender":"71ef88df5f7e482fb472f344965beba8","uuidReceiver":"976129e438b54a839944b1c0703d4da3","started":1476822044856},{"_id":"59589dde0cf250df95af825e","uuidSender":"71ef88df5f7e482fb472f344965beba8","uuidReceiver":"2c5bfce120c04ef1bfb3b798fe0d650e","started":1498979806692},{"_id":"5a444d820cf2604c12e0f6bd","uuidSender":"71ef88df5f7e482fb472f344965beba8","uuidReceiver":"ea703151981a409f8d0ff7cb782ab1c1","started":1514425730370},{"_id":"5aa595800cf24bd1104381cc","uuidSender":"71ef88df5f7e482fb472f344965beba8","uuidReceiver":"27af346e5bde40f0a665e808a331576f","started":1520801152354},{"_id":"5e2511f90cf289be2d0ea273","uuidSender":"71ef88df5f7e482fb472f344965beba8","uuidReceiver":"24a90aca074c4293a656f5fda047f816","started":1579487737061},{"_id":"5e36448c0cf2174287f94af7","uuidSender":"71ef88df5f7e482fb472f344965beba8","uuidReceiver":"1nmHNU1mERJEG452cx1FazPx3RpAuZ9vW","started":1580614796544},{"_id":"5e3f54190cf2ab010c5a21ce","uuidSender":"71ef88df5f7e482fb472f344965beba8","uuidReceiver":"63817f05823945a2b58f4ba1de5589a3","started":1581208601957},{"_id":"55bec5e0c8f2e017bca39176","uuidSender":"1nmHNU1mERJEG452cx1FazPx3RpAuZ9vW","uuidReceiver":"71ef88df5f7e482fb472f344965beba8","started":1438565856136},{"_id":"55e21268c8f21846db2f2566","uuidSender":"8fca5ebf02f74a369b13f3407ad4a9bc","uuidReceiver":"71ef88df5f7e482fb472f344965beba8","started":1440879208434},{"_id":"56c26b190cf2d1a91ec25e83","uuidSender":"1nmHNU1mERJEG452cx1FazPx3RpAuZ9vW","uuidReceiver":"71ef88df5f7e482fb472f344965beba8","started":1455581977070},{"_id":"5755edc20cf2db67507e3a2e","uuidSender":"0ce4597de5484c0e82a067fa0bf171df","uuidReceiver":"71ef88df5f7e482fb472f344965beba8","started":1465249218466},{"_id":"5851ed8d0cf2b9563974034d","uuidSender":"d3dd0059775e46b1b1a63b94a10d2450","uuidReceiver":"71ef88df5f7e482fb472f344965beba8","started":1481764237412},{"_id":"5d087a1f0cf2d7aebbf96fd6","uuidSender":"d6695d1ea7ae480bb2129a3b7d0269ad","uuidReceiver":"71ef88df5f7e482fb472f344965beba8","started":1560836639346},{"_id":"5d703a880cf299e651b71cbb","uuidSender":"cbd9e9009ee94d159d52dff284ad7bf8","uuidReceiver":"71ef88df5f7e482fb472f344965beba8","started":1567636104118},{"_id":"5deeff7f0cf2d87bd75df1a0","uuidSender":"c53c4524ad174fd78134223fddedc484","uuidReceiver":"71ef88df5f7e482fb472f344965beba8","started":1575944063334},{"_id":"5e0638f20cf24f983d2cb02c","uuidSender":"1nmHNU1mERJEG452cx1FazPx3RpAuZ9vW","uuidReceiver":"71ef88df5f7e482fb472f344965beba8","started":1577466098097},{"_id":"5e1e70e70cf2795e4f1322be","uuidSender":"85090a8b495d4856817fd6df1d4da0bd","uuidReceiver":"71ef88df5f7e482fb472f344965beba8","started":1579053287837},{"_id":"5e1fbe4b0cf2795e4f14a36f","uuidSender":"1nmHNU1mERJEG452cx1FazPx3RpAuZ9vW","uuidReceiver":"71ef88df5f7e482fb472f344965beba8","started":1579138635859},{"_id":"5e25910d0cf2a892e569db39","uuidSender":"63ac73044aca4b2f908baff858cf34b9","uuidReceiver":"71ef88df5f7e482fb472f344965beba8","started":1579520269103},{"_id":"5e712f890cf2d292e1148ba6","uuidSender":"1nmHNU1mERJEG452cx1FazPx3RpAuZ9vW","uuidReceiver":"71ef88df5f7e482fb472f344965beba8","started":1584476041946},{"_id":"5e819f550cf2675e4372109b","uuidSender":"8cd38d8f97a24090a43e2e0ce898c521","uuidReceiver":"71ef88df5f7e482fb472f344965beba8","started":1585553237302},{"_id":"5e82c5ad0cf2675e437308aa","uuidSender":"d618457dd6044256bdb287b0df8137d4","uuidReceiver":"71ef88df5f7e482fb472f344965beba8","started":1585628589448},{"_id":"5eae3e420cf26efdbd55b592","uuidSender":"a936c3468bec4a2685199a398212b62d","uuidReceiver":"71ef88df5f7e482fb472f344965beba8","started":1588477506714},{"_id":"5ebd9da40cf22f431e9164d8","uuidSender":"1nmHNU1mERJEG452cx1FazPx3RpAuZ9vW","uuidReceiver":"71ef88df5f7e482fb472f344965beba8","started":1589484964296}]
}
Here is my code:
def get_friend_count(name):
getUUID = f"https://api.mojang.com/users/profiles/minecraft/{name}"
res = requests.get(getUUID)
data = res.json()
if data["id"] is None:
return None
returnUuid = (data["id"])
url1 = f"https://api.hypixel.net/friends?key={API_KEY}&uuid=" + returnUuid
res2 = requests.get(url1)
data2 = res2.json()
if data2["records"] is None:
return None
friend_count = len(data["records"])
return "Friends: " + friend_count
getUUID gets the UUID from the requested username and then uses the UUID to get the players Hypixel stats.
Any help is appreciated, thanks!
Mojang API: https://wiki.vg/Mojang_API
Hypixel API: https://github.com/HypixelDev/PublicAPI/tree/master/Documentation
Did you just forget to request.get(url1)?
In any case, from the mojang API doc, it seems the endpoint you query (https://api.mojang.com/users/profiles/minecraft/) never returns a "records" key ... thus the error when you do if data["records"] is None
I have django project with 2 models:
class DeviceModel(models.Model):
name = models.CharField(max_length=255)
def __unicode__(self):
return self.name
class Device(models.Model):
created_at = models.DateTimeField(auto_now_add=True)
device_model = models.ForeignKey(DeviceModel)
serial_number = models.CharField(max_length=255)
def __unicode__(self):
return self.device_model.name + " - " + self.serial_number
There many devices in the database and I want to plot chart "amount of devices" per "device model".
I'm trying to do this task with django chartit.
Code in view.py:
ds = PivotDataPool(
series=[
{'options': {
'source':Device.objects.all(),
'categories':'device_model'
},
'terms':{
u'Amount':Count('device_model'),
}
}
],
)
pvcht = PivotChart(
datasource=ds,
series_options =
[{'options':{
'type': 'column',
'stacking': True
},
'terms':[
u'Amount']
}],
chart_options =
{'title': {
'text': u'Device amount chart'},
'xAxis': {
'title': {
'text': u'Device name'}},
'yAxis': {
'title': {
'text': u'Amount'}}}
)
return render(request, 'charts.html', {'my_chart': pvcht})
This seems to plot result I need, but instead of device names it plots values of ForeignKey (1,2,3,4...) and I need actual device model names.
I thought that solution is to change 'categories' value to:
'categories':'device_model__name'
But this gives me error:
'ManyToOneRel' object has no attribute 'parent_model'
This type of referencing should work accoring to official example http://chartit.shutupandship.com/demo/pivot/pivot-with-legend/
What am I missing here?
C:\Anaconda\lib\site-packages\django\core\handlers\base.py in get_response
response = middleware_method(request, callback, callback_args, callback_kwargs)
if response:
break
if response is None:
wrapped_callback = self.make_view_atomic(callback)
try:
response = wrapped_callback(request, *callback_args, **callback_kwargs) ###
except Exception as e:
# If the view raised an exception, run it through exception
# middleware, and if the exception middleware returns a
# response, use that. Otherwise, reraise the exception.
for middleware_method in self._exception_middleware:
response = middleware_method(request, e)
D:\django\predator\predator\views.py in charts
series=[
{'options': {
'source':Device.objects.all(),
'categories':'device_model__name'
},
#'legend_by': 'device_model__device_class'},
'terms':{
u'Amount':Count('device_model'), ###
}
}
],
#pareto_term = 'Amount'
)
C:\Anaconda\lib\site-packages\chartit\chartdata.py in __init__
'terms': {
'asia_avg_temp': Avg('temperature')}}]
# Save user input to a separate dict. Can be used for debugging.
self.user_input = locals()
self.user_input['series'] = copy.deepcopy(series)
self.series = clean_pdps(series) ###
self.top_n_term = (top_n_term if top_n_term
in self.series.keys() else None)
self.top_n = (top_n if (self.top_n_term is not None
and isinstance(top_n, int)) else 0)
self.pareto_term = (pareto_term if pareto_term in
self.series.keys() else None)
C:\Anaconda\lib\site-packages\chartit\validation.py in clean_pdps
def clean_pdps(series):
"""Clean the PivotDataPool series input from the user.
"""
if isinstance(series, list):
series = _convert_pdps_to_dict(series)
clean_pdps(series) ###
elif isinstance(series, dict):
if not series:
raise APIInputError("'series' cannot be empty.")
for td in series.values():
# td is not a dict
if not isinstance(td, dict):
C:\Anaconda\lib\site-packages\chartit\validation.py in clean_pdps
try:
_validate_func(td['func'])
except KeyError:
raise APIInputError("Missing 'func': %s" % td)
# categories
try:
td['categories'], fa_cat = _clean_categories(td['categories'],
td['source']) ###
except KeyError:
raise APIInputError("Missing 'categories': %s" % td)
# legend_by
try:
td['legend_by'], fa_lgby = _clean_legend_by(td['legend_by'],
td['source'])
C:\Anaconda\lib\site-packages\chartit\validation.py in _clean_categories
else:
raise APIInputError("'categories' must be one of the following "
"types: basestring, tuple or list. Got %s of "
"type %s instead."
%(categories, type(categories)))
field_aliases = {}
for c in categories:
field_aliases[c] = _validate_field_lookup_term(source.model, c) ###
return categories, field_aliases
def _clean_legend_by(legend_by, source):
if isinstance(legend_by, basestring):
legend_by = [legend_by]
elif isinstance(legend_by, (tuple, list)):
C:\Anaconda\lib\site-packages\chartit\validation.py in _validate_field_lookup_term
# and m2m is True for many-to-many relations.
# When 'direct' is False, 'field_object' is the corresponding
# RelatedObject for this field (since the field doesn't have
# an instance associated with it).
field_details = model._meta.get_field_by_name(terms[0])
# if the field is direct field
if field_details[2]:
m = field_details[0].related.parent_model ###
else:
m = field_details[0].model
return _validate_field_lookup_term(m, '__'.join(terms[1:]))
def _clean_source(source):
In categories you can only use fields that are included in source queryset.
On the other hand in terms you can use foreignKey or manyTomany connected fields.
Find an example below.
Instead of using
'source':Device.objects.all()
'categories':'device_model'
try to use
'source':DeviceModel.objects.all()
'categories':'name'
and next
'Amount':Count('device__device_model')
I think there is a problem with newer version of django (1.8).
This code is deprecated:
m = field_details[0].related.parent_model
instead of it use
m = field_details[0].getattr(field.related, 'related_model', field.related.model)
You can also find fix to this problem on GitHub.
Hope this helps.