ESP8266: HTTP GET Requests to Flask server

The objective of this post is to explain how to connect the ESP8266 to a Flask Webserver and send a HTTP GET Request.


The Python code

For this example, we will use Flask to deploy a simple webserver that will listen to HTTP GET requests on a certain URL and output a simple text message to the client. The code will be very similar to the one of this previous post, where we explain the basics of Flask.

First of all, we import the Flask class from the flask module, so all the functionality we need becomes available. Then, we create an instance of the Flask class. In the constructor, we pass the name of the module of our application, using the __name__ global variable.

from flask import Flask
app = Flask(__name__)

Then, we will declare the route where our web server will be listening to incoming requests. We will use the /helloesp URL. The handler function for this route will just return a simple hello message, as seen bellow.

@app.route('/helloesp')
def helloHandler():
    return 'Hello ESP8266, from Flask'

Finally, we run our application with the run method.

app.run(host='0.0.0.0', port= 8090)

So, as indicated by the arguments of the run method, our server will be listening on port 8090 and on the machine default IP address. You can check here in more detail the meaning of the 0.0.0.0 IP address. But, to sum up, in the context of servers, 0.0.0.0 means all IPv4 addresses on the local machine [1], which is what we want so the server becomes available on our local network.

The full code for the server can be seen bellow.

from flask import Flask

app = Flask(__name__)

@app.route('/helloesp')
def helloHandler():
    return 'Hello ESP8266, from Flask'

app.run(host='0.0.0.0', port= 8090)

I recommend to do a quick test without the ESP8266 to check for problems in the server code. This way is much easier to debug than running the whole code and trying to figure out in which component the problems are.

So, we can run the code, for example, from IDLE, the Python IDE.

Since we want to confirm that our server is available in the network, we need to discover its IP on the network. In windows, we can do it from the command line using the ipconfig command. On Linux, we can use the ifconfig command.

After discovering our IP address on the network, we can test the server using, for example, a web browser or a tool like Postman, which allows us to do HTTP Requests very easily.

Ideally, if you have another computer on your network, you can send a HTTP request from there, to the previously discovered IP address. If not, you can test it from the same machine, although it will only allow to confirm that the server code is running correctly, not that it is reachable from other devices on the network.

As seen in figure 1, I tested it from Postman. So, I sent a GET request on the following URL: IP:port/route, where /route is equal to the /helloesp we defined early. Note that, in postman, we don’t need to put the http prefix before specifying the IP address.

POSTMAN Flask ESP8266 test.png

Figure 1 – Testing the server code with Postman.

If you don’t wan’t to use Postman, simply open a web browser and put the following in the address bar:

http://IP:port/route

The result can be seen in figure 2 below.

flask-webserver-testing-from-browser

Figure 2 – Testing the server code from a web browser.


Important
: you are not going to be able to connect to the Flask app from outside your router’s network with this method. To do it, you would need to do port forwarding, so the server would become accessible from the Internet. Port forwarding a router depends on the model of the device, so explaining how to do it is outside the scope of this post. So, our use case only works if the ESP8266 is connected to the same router of the computer that is running the Flask server.


The ESP8266 code

The ESP8266 code will also be based on a previous post, which you can check for more details on the functions used.

First, we need do include some libraries that will allow us to connect to a WiFi Network and to send HTTP requests.

#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>

Now, in the setup function, we will start a serial connection, so we can print the output of the request to our server. We will also connect to the WiFi network.

void setup () {

  Serial.begin(115200);
  WiFi.begin("YourNetwork", "YouNetworkPassword");

  while (WiFi.status() != WL_CONNECTED) {

    delay(1000);
    Serial.println("Connecting..");

  }
  Serial.println("Connected to WiFi Network");

}

Our code to make the request will be now specified in the main loop function. First, we declare an object of class HTTPClient, which we will simply call http. This class provides the methods to create and send the HTTP request.

After that, we call the begin method on the http object and pass the URL that we want to connect to and make the GET request. The URL will be the one specified in the previous section. Note that in this example code I used the IP of my machine where the Flask server is running. You should change it to the one you discovered with the ipconfig or ifconfig command.

HTTPClient http; //Declare an object of class HTTPClient
http.begin("http://192.168.1.88:8090/helloesp"); //Specify request destination

Then, we send the request by calling the GET method on the http object. This method will return the status of the operation. If the value is greater than 0, then it’s a standard HTTP code. If the value is less than 0, then it’s a client error, related with the connection. All available error codes for this method are listed here.

So, if the code is greater than 0, we can get and print the response payload, by calling the getString method on the http object. If not, we print an error message.

int httpCode = http.GET(); //Send the request

if (httpCode > 0) { //Check the returning code

    String payload = http.getString();   //Get the request response payload
    Serial.println(payload);             //Print the response payload

}else Serial.println("An error ocurred");

Finally, we call the end method. This is very important to close the TCP connection and thus free the resources.

http.end();   //Close connection

The full code can be seen bellow. Note that we introduced a delay of 10 seconds between each GET request.

#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>

void setup () {

  Serial.begin(115200);
  WiFi.begin("YourNetwork", "YouNetworkPassword");

  while (WiFi.status() != WL_CONNECTED) {

    delay(1000);
    Serial.println("Connecting..");

  }
  Serial.println("Connected to WiFi Network");

}

void loop() {

  if (WiFi.status() == WL_CONNECTED) { //Check WiFi connection status

    HTTPClient http;  //Declare an object of class HTTPClient

    http.begin("http://192.168.1.88:8090/helloesp"); //Specify request destination

    int httpCode = http.GET(); //Send the request

    if (httpCode > 0) { //Check the returning code

      String payload = http.getString();   //Get the request response payload
      Serial.println(payload);             //Print the response payload

    }else Serial.println("An error ocurred");

    http.end();   //Close connection

  }

  delay(10000);    //Send a request every 10 seconds

}


Testing everything

To test the full system, just upload the code to the ESP8266 using the Arduino IDE, with the Flask server running. You should get something similar to figure 3.

esp8266-hello-flask

Figure 3 – Output of the ESP8266 application.

We can also test if our ESP8266 application works well if an error occurs on the Flask server. To do so, after some successful  requests, just shut down the server, wait for some error messages, and then re run the server. The ESP8266 application should handle it fine, as shown in figure 4.

esp8266-flask-server-error-recovery

Figure 4 – Response of the ESP8266 application when the server is down.


Related Posts


References

[1] http://www.howtogeek.com/225487/what-is-the-difference-between-127.0.0.1-and-0.0.0.0/


Technical details

  • Python version: v3.4.2
  • Flask library: v0.10.1
  • ESP8266 libraries: v2.2.0

11 Replies to “ESP8266: HTTP GET Requests to Flask server”

  1. hello antepher hope u are fine this content is really very good but in want you to help me in this tutorial on single http request from wifi module flask server is returning a string but i want to send 3 http request from wifi module and in accordance to these request my desired string in received back .
    can you help me out of this

    1. Hi!

      Thanks for the feedback 🙂

      How do the strings to be returned differ? What will be used in those 3 requests to differentiate which string should be returned from the Flask server?

      There’s many ways to achieve that. You can either have multiple routes on the flask server and send each of the request to a different route, each route returning the string you want.

      Alternatively, you can have a single route and the request you send have some parameter so the route handling function knows which string to return.

      Hope it helps getting you in the right direction 🙂

      Best regards,
      Nuno Santos

  2. hello antepher hope u are fine this content is really very good but in want you to help me in this tutorial on single http request from wifi module flask server is returning a string but i want to send 3 http request from wifi module and in accordance to these request my desired string in received back .
    can you help me out of this

    1. Hi!
      Thanks for the feedback 🙂
      How do the strings to be returned differ? What will be used in those 3 requests to differentiate which string should be returned from the Flask server?
      There’s many ways to achieve that. You can either have multiple routes on the flask server and send each of the request to a different route, each route returning the string you want.
      Alternatively, you can have a single route and the request you send have some parameter so the route handling function knows which string to return.
      Hope it helps getting you in the right direction 🙂
      Best regards,
      Nuno Santos

  3. Dear sir.
    can you give me the arduino part of code in esp8266 AT Command.It will be much helpful for
    me as im using software serial .
    Thanx in advance

    1. Hi!

      Unfortunately I’ve not been using AT commands for a couple of years, so I’m no longer aware how the interface is currently.

      My recommendation is for you to check the documentation of the AT firmware to confirm which commands you need to send.

      Note however that going to a custom development gives you much more flexibility. You can still interact with the ESP via serial and code your own optimized firmware to read the data from the serial port and send the requests as you need.

      Best regards,
      Nuno Santos

  4. Dear sir.
    can you give me the arduino part of code in esp8266 AT Command.It will be much helpful for
    me as im using software serial .
    Thanx in advance

    1. Hi!
      Unfortunately I’ve not been using AT commands for a couple of years, so I’m no longer aware how the interface is currently.
      My recommendation is for you to check the documentation of the AT firmware to confirm which commands you need to send.
      Note however that going to a custom development gives you much more flexibility. You can still interact with the ESP via serial and code your own optimized firmware to read the data from the serial port and send the requests as you need.
      Best regards,
      Nuno Santos

  5. Hello,
    Python/Flask is one of my habitual web languages. The thing is that, for a project I’m working on, I’m trying to send an image base64 encoded to my server through a POST. After a lot of trials and errors, event trying your POST example in this blog, I have to reckon that the server, for some reason, never reads the parameters. I always read nulls. Curl and html forms work perfectly but not from ESP8266.
    Do you know of any reason/bug that might exist?

    1. Hi!

      Unfortunately that is an use case that I’ve never tested, so I’m not sure what might be the cause :/

      How big is the result of the base64 encoding of the image? Maybe it exceeds some internal buffer and instead of crashing it simply doesn’t send the content?

      One thing you can try to test this theory is using a really small image (just some pixels) and sending it from the ESP to check if the problem is related. If for small images it works, then this might be the cause

      Another suggestion is to ask around the ESP8266 Arduino core github page, maybe someone there already faced the same issue and can help.

      Please let us know if you find a solution, as it might help others trying to achieve the same 🙂

      Best regards,
      Nuno Santos

  6. Hello,
    Python/Flask is one of my habitual web languages. The thing is that, for a project I’m working on, I’m trying to send an image base64 encoded to my server through a POST. After a lot of trials and errors, event trying your POST example in this blog, I have to reckon that the server, for some reason, never reads the parameters. I always read nulls. Curl and html forms work perfectly but not from ESP8266.
    Do you know of any reason/bug that might exist?

    1. Hi!
      Unfortunately that is an use case that I’ve never tested, so I’m not sure what might be the cause :/
      How big is the result of the base64 encoding of the image? Maybe it exceeds some internal buffer and instead of crashing it simply doesn’t send the content?
      One thing you can try to test this theory is using a really small image (just some pixels) and sending it from the ESP to check if the problem is related. If for small images it works, then this might be the cause
      Another suggestion is to ask around the ESP8266 Arduino core github page, maybe someone there already faced the same issue and can help.
      Please let us know if you find a solution, as it might help others trying to achieve the same 🙂
      Best regards,
      Nuno Santos

Leave a Reply