i have a problem with my flask app thaht i'm trying to create,
i wrote a POST Method to take arguments from HTTP and write them to a table.
here's my code:
from flask import Flask
from flask_restful import Resource, Api, reqparse
import pandas as pd
import ast
import sqlalchemy
# SQLAlchemy connectable
engine = sqlalchemy.create_engine("mssql+pymssql://my_connection_string")
conn = engine.connect()
app = Flask(__name__)
api = Api(app)
class Samples(Resource):
def get(self):
data = pd.read_sql_table('DBLIST_DATA', engine)
data = data.to_dict() # convert dataframe to dict
return {'data': data}, 200 # return data and 200 OK
def post(self):
parser = reqparse.RequestParser() # initialize
parser.add_argument('NODE_NO_data', required=True) # add args
parser.add_argument('BLOCK_NAME_data', required=True)
parser.add_argument('BLOCK_TYPE_data', required=True)
args = parser.parse_args() # parse arguments to dictionary
# read our SQL Table
data = pd.read_sql_table('DBLIST_DATA', engine)
#Check if Value Exists
if args['NODE_NO_data'] in list(data['NODE_NO_data']):
return {
'message': f"'{args['NODE_NO_data']}' already exists."
}, 409
else:
# create new dataframe containing new values
new_data = pd.DataFrame({
'NODE_NO_data': [args['NODE_NO_data']],
'BLOCK_NAME_data': [args['BLOCK_NAME_data']],
'BLOCK_TYPE_data': [args['BLOCK_TYPE_data']],
'locations': [[]]
})
# add the newly provided values
data = data.append(new_data, ignore_index=True)
data.to_sql('DBLIST_DATA', index=False) # save back to SQL Table
return {'data': data.to_dict()}, 200 # return data with 200 OK
api.add_resource(Samples, '/samples') # add endpoints
if __name__ == '__main__':
app.run() # run app
when i try to POST via Postman the following values:
127.0.0.1:5000/samples/?NODE_NO_data=1&BLOCK_NAME_data=Machine&BLOCK_TYPE_data=Vertical
i'm getting a 404 not found error.
can someone please tell me what i'm doing wrong?
Thanks!
You could just remove the last / of your request URL http://127.0.0.1:5000/samples.
Related
I am testing/attempting to learn flask, and flast_restful. This issue I get is:
code 400, message Bad request syntax ('name=testitem')
main.py:
from flask import Flask,request
from flask_restful import Api, Resource, reqparse
app = Flask(__name__)
api = Api(app)
product_put_args = reqparse.RequestParser()
product_put_args.add_argument("name", type = str, help = "Name of the product")
product_put_args.add_argument("quantity", type = int, help = "Quantity of the item")
products = {}
class Product(Resource):
def get(self, barcode):
return products[barcode]
def put(self, barcode):
args = product_put_args.parse_args()
return {barcode: args}
api.add_resource(Product, "/product/<int:barcode>")
if(__name__) == "__main__":
app.run(debug = True)
and my
test.py
import requests
base = "http://127.0.0.1:5000/"
response = requests.put(base + "product/1", {"name": "testitem"})
print(response.json())
I have attempted to reform mat and change around both files to figure out what is sending the issue, I feel like it is something simple, but if you can help me, I bet this will help me and many others that are trying to start creating a rest API.
You need to add the location information to the RequestParser by default it tries to parse values from flask.Request.values, and flask.Request.json, but in your case, the values need to be parsed from a flask.request.form. Below code fixes your error
from flask import Flask,request
from flask_restful import Api, Resource, reqparse
app = Flask(__name__)
api = Api(app)
product_put_args = reqparse.RequestParser()
product_put_args.add_argument("name", type = str, help = "Name of the product", location='form')
product_put_args.add_argument("quantity", type = int, help = "Quantity of the item", location='form')
products = {}
class Product(Resource):
def get(self, barcode):
return products[barcode]
def put(self, barcode):
args = product_put_args.parse_args()
products[barcode] = args['name']
return {barcode: args}
api.add_resource(Product, "/product/<int:barcode>")
if(__name__) == "__main__":
app.run(debug = True)
i created this rest api with flask and sql alchemy and i want to not enter the json data manually but get it from another json and add it to my database :
https://www.habitat.fr/api/qDbBye4V7vtMu8qL97vvHTAnLQuEhC/product/911095/sku
my add product route in flask
#add product
#app.route('/product', methods=['POST'])
def add_product():
name = request.json['name']
description = request.json['description']
price = request.json['price']
qty = request.json['qty']
new_product = Product(name,description,price,qty)
db.session.add(new_product)
db.session.commit()
return product_schema.jsonify(new_product)
All you need do is write a function using requests and json modules to fetch the json in the url like this:
import requests
import json
def get_data():
r = requests.get('https://www.habitat.fr/api/qDbBye4V7vtMu8qL97vvHTAnLQuEhC/product/911095/sku')
return json.loads(r.content) #convert content to dict
You may now call the function in your flask app:
#app.route('/product', methods=['POST'])
def add_product():
my_data = get_data()
name = my_data['name']
description = my_data['description']
price = my_data['price']
qty = my_data['qty']
I'm setting up an API using Flask, and add some JSON post using postman to be transferred to mongoDB database.
Then I had to visualize statistics of the real time data from the database into lets say data_analysis_script.py, which means if I post some JSON from postman, the statistics should be changed since the data had been added.
Any suggestion about function or library I could use further in script for showing the data statistics ?
I had tried using manager which could run both app.run() and the code, but not print the code
API code
from flask import Flask, jsonify, request
from flask_pymongo import PyMongo
import pandas as pd
app = Flask(__name__)
app.config['MONGO_DBNAME'] = 'db'
app.config['MONGO_URI'] = 'mongodb://localhost:8000/db'
mongo = PyMongo(app)
#app.route('/stocks', methods=['GET'])
def get_all_stocks():
stocks = mongo.db.stocks
output = []
for i in stocks.find():
output.append({'name' : i['name'], 'item' : i['item']})
return jsonify({'Here yours' : output})
#app.route('/add', methods=['POST'])
def add_stocks():
stocks = mongo.db.stocks
name = request.json['name']
item = request.json['item']
item_id = stocks.insert({'name': name, 'item': item})
new_stocks = stocks.find_one({'_id': stocks_id })
output = {'name' : new_stocks['name'], 'item' : new_stocks['item']}
return jsonify({'Here yours' : output})
#app.route('/stocks/', methods=['GET'])
def get_one_stocks(name):
stocks = mongo.db.stocks
c = stocks.find_one({'name' : name})
if s:
output = {'name' : c['name'], 'item' : c['item']}
else:
output = "Nothing"
return jsonify({'Here yours' : output})
if __name__ == '__main__':
app.run(debug=True)
I expect the data visualization and statistics changed when there is a JSON entry
I'm creating the server end of a test API using flask_restful that will capture a request coming into the API with a ID, and 3 parameters. If the Id does not exists, then it is created and populated with the 3 data arguments. The Asset is created, however only the 3rd parameter is added to the dict.
Code I have:
from flask import Flask, request
from flask_restful import reqparse, abort, Api, Resource
app = Flask(__name__)
api = Api(app)
assets = {}
def abort_if_asset_doesnt_exist(asset_id):
if asset_id not in assets:
abort(404, message="Asset {} doesn't exist".format(asset_id))
parser = reqparse.RequestParser()
parser.add_argument('data1', type=str)
parser.add_argument('data2', type=str)
parser.add_argument('data3', type=str)
class Asset(Resource):
def get(self, asset_id):
return {asset_id: assets[asset_id]}
def put(self, asset_id):
assets[asset_id] = request.form['data1']
assets[asset_id] = request.form['data2']
assets[asset_id] = request.form['data3']
return {asset_id: assets[asset_id]}
def delete(self, asset_id):
abort_if_todo_doesnt_exist(asset_id)
del assets[asset_id]
return '', 204
api.add_resource(Asset, '/api-v1.0/add/<string:asset_id>', methods=['PUT', 'GET'])
if __name__ == '__main__':
app.run(debug=True)
I want to take the id and create a 'instance' in the dictionary, with it's corresponding data fields attached to it. like below
What I want:
{
"123456" {
"data1":"Mydata1"
"data2":"Mydata2"
"data3":"Mydata3"
}
}
With this I can call the asset and receive it's associated data fields.
The curl (PUT) command I use looks like this.
$ curl http://localhost:5000/api-v1.0/add/123456 -d "data1=Mydata1" -d "data2=Mydata2" -d "data3=Mydata3" -X PUT
This is because you're just assigning a value one after the other to the location specified by asset_id in your assets dict. Since the last value assigned to assets is the 3rd parameter this is the value that is contained at that key.
To fix this you need to change that code to create a dict for the asset_id that you want to store the form data against:
assets[asset_id] = dict()
assets[asset_id]['data1'] = request.form['data1']
assets[asset_id]['data2'] = request.form['data2']
assets[asset_id]['data3'] = request.form['data3']
Or even better use a defaultdict:
assets = defaultdict(dict)
...
assets[asset_id]['data1'] = request.form['data1']
First of I'm new to python and flask. I've searched around and tried something things to no avail. I have a model that has a DateTimeField as one of the members, let's call it "created_at". When I go to return the query set as JSON I see this for the field
...
"created_at": {
"$date": 1412938697488
}
...
Is there anyway to get the output, either through a custom JSON encoder, etc to get it to look like this :
"created_at": "2014-10-10T07:33:04Z",
Any guidance or suggestions would be greatly appreciated.
Thanks!
Here is an example using flask and flask-mongoengine to get a date as ISO 8601 string
import datetime
from bson.json_util import dumps
from flask import Flask, Response, request
from flask_mongoengine import MongoEngine
app = Flask(__name__)
db = MongoEngine()
class Movie(db.Document):
name = db.StringField(required=True, unique=True)
casts = db.ListField(db.StringField(), required=True)
genres = db.ListField(db.StringField(), required=True)
created_at = db.DateTimeField(default=datetime.datetime.utcnow)
#app.route('/movies')
def get_movies():
movies = Movie.objects()
movies_list = []
for movie in movies:
movie_dict = movie.to_mongo().to_dict()
movie_dict['created_at'] = movie.created_at.isoformat()
movies_list.append(movie_dict)
movies_josn = dumps(movies_list)
return Response(movies_josn, mimetype="application/json", status=200)
#app.route('/movies', methods=['POST'])
def add_movie():
body = request.get_json()
movie = Movie(**body).save()
id = movie.id
return {'id': str(id)}, 200
if __name__ == '__main__':
app.config['MONGODB_SETTINGS'] = {
'host': 'mongodb://localhost/movie-bag'
}
db.init_app(app)
app.run()