I am trying to use react to get data from an API (Python, I'm hosting it on the same machine).
API Code:
from flask import Flask, jsonify, request
app = Flask(__name__)
#app.route('/')
def all_data():
all_data = "Hello"
return jsonify({
'data':all_data,
'message':"success"
}), 200
if __name__ == "__main__":
app.run(debug=True)
React code(Didn't include the render()):
export default class HomeScreen extends Component {
constructor(props){
super(props);
this.state = {
listData:[],
url:"http://localhost:5000"
}
}
getPlanets=()=>{
console.log("Axios called")
const url = this.state.url;
console.log(url)
axios.get(url).then((response)=>{
console.log(response.data)
return this.setState({listData:response.data})
}).catch((error)=>{
console.log(error.message)
Alert.alert(error.message);
})
}
componentDidMount(){
this.getPlanets();
}
}
I'm always getting Network Error for the console.log(error.message).
I'm also getting a larger Error: "Network Error" in Error: Network Error << at e.exports (axios.js:3:7286) << at d.onerror (axios.js:3:6270) for console.log(error).
Simultaneously, I got two weird error messages in my API:
code 400, message Bad request version ('localhost\x00\x17\x00\x00ÿ\x01\x00\x01\x00\x00')
"▬♥☺☻☺☺ü♥♥ÆuaTÁS¾eài ¸ ²`½‼/cùCf{&*½(¨qh↓(â®z↨Ó ×D ÚÚ‼☺‼☻‼♥À+À/À,À0̨̩À‼À¶úú♫♀ l
ocalhost↨ÿ☺☺" HTTPStatus.BAD_REQUEST -
Help?
I've tried looking through a lot of websites for the problem, but they all just suggested adding the http:// prefix to my url, which I had already done. I'm also using Python for the API and not NodeJS, so I don't need to use CORS. I just couldn't find a relevant fix anywhere.
Related
from flask import Flask, jsonify, request
app = Flask(__name__)
tasks = [
{
"id":1,
"title":"You buy groceries",
"description":"Milk, Cheeses, Pizza",
"done":False,
},
{
"id":2,
"title":"Learn Python",
"description":"The most important language in the world",
"done":False,
},
]
#app.route('/add-data', methods = ['POST'])
def add_data():
if not request.json:
return jsonify({
"status":"error",
"message":"Please provide the data"
},400)
task = {
"id":tasks[-1][id]+1,
"title":request.json["title"],
"description":request.json.get("description",""),
"done":False,
}
tasks.append(task)
return jsonify({
"status":"success",
"message":"Task added successfully!"
})
#app.route("/get-data")
def get_task():
return jsonify({
"data":tasks
})
if __name__ == "__main__":
app.run(debug=True)
I am just a beginner in this api creating with python and I was trying to create an api to get the data and to post data.
But when I run the code, it gives me the error :
The screenshot of the error
Let me know if there is some error in the code or problem of the virtual environment. Would be very much grateful if the solution is also given.
try "http://127.0.0.1:5000/get-data"
it pretty much serves your data.
you do not have an auto route to the get-method yet.
This question already has answers here:
Configure Flask dev server to be visible across the network
(17 answers)
Closed 1 year ago.
I've created a simple flutter app which will get data from an api in json format sent from the backend (Python flask) and print out the data on click of a button.
When I click on the button, I get the error
[ERROR:flutter/lib/ui/ui_dart_state.cc(177)]
Unhandled Exception: SocketException: OS Error: Connection refused, errno = 111, address = 127.0.0.1, port = 36820
I'm very new to flutter, please tell me where I did wrong and help me figure it out.
Flutter Dart code:
import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
void main() {
runApp(new MaterialApp(
home: new HomePage(),
));
}
class HomePage extends StatefulWidget {
#override
HomePageState createState() => new HomePageState();
}
class HomePageState extends State<HomePage> {
List data;
Future<String> getData() async {
var response = await http.get(
Uri.encodeFull("http://127.0.0.1:5000/ "),
headers: {
"Accept": "application/json"
}
);
data = json.decode(response.body);
print(data);
return "Success!";
}
#override
Widget build(BuildContext context) {
return new Scaffold(
body: new Center(
child: new RaisedButton(
child: new Text("Get data"),
onPressed: getData,
),
),
);
}
}
Python code:
from flask import Flask, jsonify
app = Flask(__name__)
#app.route('/')
def hello_world():
return jsonify({"about": "Hello World!"})
if __name__ == '__main__':
app.run()
Looks like you are running your back-end from localhost. In this case, 127.0.0.1 will only work if you run the application on your PC (and not another phone/device. Not sure about simulators though).
Trying to access 127.0.0.1 from a phone is like trying to access a server hosted on your phone (which evidently will not be found).
So, to run the app on your phone, you need to find your PC's (private) IP address, using e.g. ifconfig from your terminal. Once you get this IP address, use the URL {your-priv-IP}:5000 instead of 127.0.0.1:5000 in your code. Make sure though that your PC and phone are connected to the same Wifi network for this to work.
So currently I am trying to learn how to connect a flutter front end with a Python backend using flask and I am making a basic project where you basically input a number in the flutter app the number you input being the index of a list I have stored in my python app the python app will then return the number at the index you specified and it will be displayed on the screen. The issue I am having is that when I run the applications the flutter application just displays an error message. I have tried a whole bunch of things and can't figure out what is wrong
Here is the link to the screenshot of my Flutter App (Includes error message received from the server):
https://imgur.com/a/K6KYRAu
Here is my Python Code
from flask import Flask
from flask_restful import Api, Resource
app = Flask(__name__)
api = Api(app)
myList = [3,4,8,1,9,4,2,0,2,9,3,8,4,7,2,7,0,1]
#app.route('/', methods = ['GET'])
class Update(Resource):
def get(self,pos):
if(pos > len(myList)):
return {"num" : "invalid number: out of list range"}
else:
return {"num": str(myList[pos])}
api.add_resource(Update, "/Update/<int:pos>")
if __name__ == "__main__":
app.run(debug=True)
here is my Flutter Code:
import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
Future<Entry> fetchEntry() async {
final response =
await http.get('https://127.0.0.1:5000/Update/3');
if (response.statusCode == 200) {
return Entry.fromJson(jsonDecode(response.body));
} else {
throw Exception('Failed to load Entry');
}
}
class Entry {
final String number;
Entry({this.number});
factory Entry.fromJson(Map<String, dynamic> json) {
return Entry(
number: json['num'],
);
}
}
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
MyApp({Key key}) : super(key: key);
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
Future<Entry> futureEntry;
#override
void initState() {
super.initState();
futureEntry = fetchEntry();
}
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Fetch Data Example',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
appBar: AppBar(
title: Text('Fetch Data Example'),
),
body: Center(
child: FutureBuilder<Entry>(
future: futureEntry,
builder: (context, snapshot) {
if (snapshot.hasData) {
return Text(snapshot.data.number);
} else if (snapshot.hasError) {
return Text("${snapshot.error}");
}
// By default, show a loading spinner.
return CircularProgressIndicator();
},
),
),
),
);
}
}
Also I have double checked my dependencies in my pubspec.yaml file and AndroidManifest.xml file so that shouldn't be the issue. Any help would be greatly appreciated, thanks.
EDIT: for clarification I am using and android emulator for this and have tried using a different ip address for my flutter get request (I found the ip address when trying to figure out how to fix this problem and it said that ip address needs to be used for android emulators) but it still returned the same error when I did that.
Not exactly sure why this is throwing this error as you do specify the port as 5000, but a simple solution would be to change the flask port to 50162.
if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0', port=50162)
EDIT:
On further review, you might want to change your http request in the flutter code to http, not https.
I figured out the solution:
for my get request I need to be using an IP address that can be used by android the IP address that android uses is 10.0.2.2 I found this solution on this stack overflow post:
How to connect to my http://localhost web server from Android Emulator
I'm currently using Flasks's development server instead of using a separate one because I don't need the extra bulk. My server will not be processing many requests at once, so I feel the development server is fine enough.
What I'm Trying To Do
I have a python script that I'm trying to run with the click of a button on a web page. This web page is run on an Apache 2 web server on Ubuntu.
What I've Done
I've installed Flask and tried to post to my python script, but I always get this error:
* Serving Flask app "ResetPOE" (lazy loading)
* Environment: production WARNING: Do not use the development server in a production environment. Use a production WSGI server instead. * Debug mode: on
It always returns to my error block in my Ajax request and never to my success block. I do not get any return JSON from my Python script. I just want to know whether or not my script ran, I don't necessarily need any output from the script itself.
P.S. my Python may be incorrect, but I haven't even gotten it to recognize it yet, so that's been on the back burner for now. I'm just trying to get the post request to be successful.
ajax.js
function ajaxCall(input) {
var data = {"param" : input};
$.ajax({
url: "/cgi-bin/reset.py/request",
type: "POST",
contentType: "application/json",
data: JSON.stringify(data),
dataType: 'json',
success: function(response){
console.log("success");
console.log(response);
},
error: function(xhr, status, error) {
console.log("error");
var err = xhr.responseText;
console.log(err);
}
});
}
reset.py
#!/usr/bin/python3
print("Content-type: text/html")
print ("")
from flask import Flask, request, jsonify
import json
app = Flask(__name__)
#app.route('/')
def sendOK(environ, start_response):
status = '200 OK'
output = "Hello World!"
response_headers = [('Content-type', 'text/plain'),('Content-Length', str(len(output)))]
start_response(status, response_headers)
return [output]
#app.route('/request', methods=['POST'])
def processRequest():
data = request.form["param"]
# other code to do stuff with the data...
return Response(json.dumps({"status":"success"}), mimetype="application/json")
if __name__=="__main__":
app.run(debug=True, threaded=True, host="192.168.1.101")
It returns a 200 (OK) in my browser, but I'm not getting any return values, and I can tell my error block is executing and not my success block.
I'm trying to get the FB messenger API working using Python's Flask, adapting the following instructions: https://developers.facebook.com/docs/messenger-platform/quickstart
So far, things have been going pretty well. I have verified my callback and am able to receive the messages I send using Messenger on my page, as in the logs in my heroku server indicate the appropriate packets of data are being received by my server. Right now I'm struggling a bit to send responses to the client messenging my app. In particular, I am not sure how to perform the following segment from the tutorial in Flask:
var token = "<page_access_token>";
function sendTextMessage(sender, text) {
messageData = {
text:text
}
request({
url: 'https://graph.facebook.com/v2.6/me/messages',
qs: {access_token:token},
method: 'POST',
json: {
recipient: {id:sender},
message: messageData,
}
}, function(error, response, body) {
if (error) {
console.log('Error sending message: ', error);
} else if (response.body.error) {
console.log('Error: ', response.body.error);
}
});
}
So far, I have this bit in my server-side Flask module:
#app.route('/', methods=["GET", "POST"])
def chatbot_response():
data = json.loads(req_data)
sender_id = data["entry"][0]["messaging"][0]["sender"]["id"]
url = "https://graph.facebook.com/v2.6/me/messages"
qs_value = {"access_token": TOKEN_OMITTED}
json_response = {"recipient": {"id": sender_id}, "message": "this is a test response message"}
response = ("my response text", 200, {"url": url, "qs": qs_value, "method": "POST", "json": json_response})
return response
However, running this, I find that while I can process what someone send my Page, it does not send a response back (i.e. nothing shows up in the messenger chat box). I'm new to Flask so any help would be greatly appreciated in doing the equivalent of the Javascript bit above in Flask.
Thanks!
This is the code that works for me:
data = json.loads(request.data)['entry'][0]['messaging']
for m in data:
resp_id = m['sender']['id']
resp_mess = {
'recipient': {
'id': resp_id,
},
'message': {
'text': m['message']['text'],
}
}
fb_response = requests.post(FB_MESSAGES_ENDPOINT,
params={"access_token": FB_TOKEN},
data=json.dumps(resp_mess),
headers = {'content-type': 'application/json'})
key differences:
message needs a text key for the actual response message, and you need to add the application/json content-type header.
Without the content-type header you get the The parameter recipient is required error response, and without the text key under message you get the param message must be non-empty error response.
This is the Flask example using fbmq library that works for me:
echo example :
from flask import Flask, request
from fbmq import Page
page = fbmq.Page(PAGE_ACCESS_TOKEN)
#app.route('/webhook', methods=['POST'])
def webhook():
page.handle_webhook(request.get_data(as_text=True))
return "ok"
#page.handle_message
def message_handler(event):
page.send(event.sender_id, event.message_text)
In that scenario in your tutorial, the node.js application is sending an HTTP POST request back to Facebook's servers, which then forwards the content on to the client.
So far, sounds like your Flask app is only receiving (AKA serving) HTTP requests. The reason is that that's what the Flask library is all about, and it's the only thing that Flask does.
To send an HTTP request back to Facebook, you can use any Python HTTP client library you like. There is one called urllib in the standard library, but it's a bit clunky to use... try the Requests library.
Since your request handler is delegating to an outgoing HTTP call, you need to look at the response to this sub-request also, to make sure everything went as planned.
Your handler may end up looking something like
import json
import os
from flask import app, request
# confusingly similar name, keep these straight in your head
import requests
FB_MESSAGES_ENDPOINT = "https://graph.facebook.com/v2.6/me/messages"
# good practice: don't keep secrets in files, one day you'll accidentally
# commit it and push it to github and then you'll be sad. in bash:
# $ export FB_ACCESS_TOKEN=my-secret-fb-token
FB_TOKEN = os.environ['FB_ACCESS_TOKEN']
#app.route('/', method="POST")
def chatbot_response():
data = request.json() # flasks's request object
sender_id = data["entry"][0]["messaging"][0]["sender"]["id"]
send_back_to_fb = {
"recipient": {
"id": sender_id,
},
"message": "this is a test response message"
}
# the big change: use another library to send an HTTP request back to FB
fb_response = requests.post(FB_MESSAGES_ENDPOINT,
params={"access_token": FB_TOKEN},
data=json.dumps(send_back_to_fb))
# handle the response to the subrequest you made
if not fb_response.ok:
# log some useful info for yourself, for debugging
print 'jeepers. %s: %s' % (fb_response.status_code, fb_response.text)
# always return 200 to Facebook's original POST request so they know you
# handled their request
return "OK", 200
When doing responses in Flask, you have to be careful. Simply doing a return statement won't return anything to the requester.
In your case, you might want to look at jsonify(). It will take a Python dictionary and return it to your browser as a JSON object.
from flask import jsonify
return jsonify({"url": url, "qs": qs_value, "method": "POST", "json": json_response})
If you want more control over the responses, like setting codes, take a look at make_response()