wybiral / micropython-aioweb

A minimalist asyncio web framework for MicroPython.
MIT License
29 stars 14 forks source link

Need more instructions and examples #3

Open rkompass opened 1 year ago

rkompass commented 1 year ago

Hello @wybiral,

I'm interested in this project. But I'm also a beginner. I successfully ran the hello example, but need more of such examples. In general instructions how to use/test the examples would be very helpful.

The post example I wrapped into the same import and starting code like with hello:

import web
import uasyncio as asyncio

app = web.App(host='0.0.0.0', port=80)

@app.route('/', methods=['POST'])
async def handler(r, w):
    body = await r.read(1024)
    form = web.parse_qs(body.decode())
    name = form.get('name', 'world')
    # write http headers
    w.write(b'HTTP/1.0 200 OK\r\n')
    w.write(b'Content-Type: text/html; charset=utf-8\r\n')
    w.write(b'\r\n')
    # write page body
    w.write(b'Hello {}!'.format(name))
    # drain stream buffer
    await w.drain()

# Start event loop and create server task
loop = asyncio.get_event_loop()
loop.create_task(app.serve())
loop.run_forever()

The network connection is established beforehand, of course. Now with e.g. curl -i -X POST -H 'Content-Type: application/json' -d '{"name": "Raul", "world": "all"}' http://192.168.178.67:80 where the letter is my cw600's IP, I get only a curl: (7) Failed to connect ..

How do I test this correctly? Or is perhaps the example not set up correctly? Or is the code not working? You see that for a beginner it's hard to find out where is the fault.

Thanks for taking the time..

Raul

rkompass commented 1 year ago

Giving myself a preliminary answer: I can open the following file named post.html in a browser:

<!DOCTYPE html>
<html lang="en-us">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <title>Post method example</title>
  </head>
  <body>
    <form action="http://192.168.178.67" method="post">
      <input type="text" name="name" value="your-name" />
      <input type="submit" />
    </form>
  </body>
</html>

and start the server like above and observe that it works. If the from action could be made to be user input in a simple manner (every device has another ip, of course) then this code would be helpful to be included in the example.

damiencorpataux commented 1 year ago

Hello @rkompass,

Your example looks fine. I am surprise that your browser can POST to 192.168.178.67 while curlfails to connect. Are you sure your device was correctly connected to the network when you tried curl ? Can you ping the device ?

Cheers,

rkompass commented 1 year ago

I see now that curl also connects. But curl sends the data differently: With my html: body= b'name=Raul' which leads to the correct processing and an Html page with 'Hello Raul'. With the curl: body= b'{"name": "Raul", "world": "all"}' from what it cannot extract the name.

The correct curl command is: curl -i -X POST -H 'Content-Type: application/json' -d 'name=Raul' http://192.168.178.67:80 And this now works. I had to restart the server, ping no longer worked. Is this an error, or is there an automatic timeout?

A html file where the ip address of the device could be set would be helpful for newbies like me!

I tried:

<!DOCTYPE html>
<html lang="en-us">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <title>Post method example</title>

    <script type="text/javascript">
      function setURL() {
        var board_url = "http://"+document.getElementById('burl').value;
      }
    </script>
  </head>
  <body>
    <form>
      Board URL:
      <input type="text" id="burl" value="192.168.178.">
      <input type="submit" value="Submit" onclick="setURL()">
    </form> 
    <form action="{{board_url}}" method="post">
      <input type="text" name="name" value="your-name" />
      <input type="submit" />
    </form>
  </body>
</html>

now but no success. Anyway, thanks for responding. Are you wybiral or did you just happen to see my issue?

damiencorpataux commented 1 year ago

@rkompass This is because the HTML form sends the data encoded in query-string format. On the countrary, the curl you are using sends data in JSON format.

The rationale behind the minimalistic flavour of the examples is that the target audience is rather experienced developers with a low-lever understanding of the HTTP protocol.

wybiral commented 1 year ago

@damiencorpataux is correct, web.parse_qs parses query string encoding but you could switch that part to parse JSON.

And, yeah, I wrote this library to be minimal and mostly just have helper methods for dealing with hhtp. It isn't a full fledged framework.

wybiral commented 1 year ago

Oops, didn't mean to close this, typing on a phone right now.

More examples would be good. I'll try to write more when I get some time. Examples are certainly welcome!

rkompass commented 1 year ago

web.parse_qs parses query string encoding but you could switch that part to parse JSON.

I found that out by including print statements, but thank you.

I'm ready to help with examples, if you like. In the form of questions :-)) But also experiments, as I'm learning but not stupid. I could try things that work with other frameworks and give feedback, if I encounter difficulties.

At my first glance I'm really impressed. Big congratulations ! This framework is quite compact and it works (tried some others, which do not function well).

The fs-web, offered as a pull request by @aguaviva is impressing and it's running here on a Winner w600 board quite stable. (1.50$ board, formerly advertised as esp8266-killer but then somehow given up, with an initial port of Micropython that was lacking many features, that is being improved continually now) . The handlers in fs-web seem to indicate that it's not a full framework yet: For example repeated

    w.write(b'HTTP/1.0 200 OK\r\n')
    w.write(b'Content-Type: text/json; charset=utf-8\r\n')
    w.write(b'\r\n')

in the handlers could be part of framework code perhaps. But fs-web also gives a shining demonstration of the possibilities/the potential of your code. I was almost blown away trying it out yesterday. Almost a Thonny as website.

Examples with explanations for the existing code would be very nice and very helpful.