Giter VIP home page Giter VIP logo

tinyweb's People

Contributors

belyalov avatar fabianclemenz avatar introquest avatar j0ono0 avatar jackburdick avatar keredson avatar metachris avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

tinyweb's Issues

Failed to instalat the firware of esp8266 and the tinyweb module

Make sure you are running the latest version of TinyWeb before reporting an issue.

Device and/or platform:
ESP8266

Description of problem:
hi try to install the firmware of esp8266 to use the module tinyweb because I need to have my esp with support to AJAX requests but at the time of importing it tells me that this module does not exist any ide with which you can access

Expected:

Traceback (if applicable):

import tintyweb
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>                        
ImportError: no module named 'tintyweb' 

Additional info:

This is NOT an issue - more a request

Firstly want to say - I really appreciate you efforts with tinyweb, I hope you can help - or point me in the right direction

I'm new to using tinyweb - I got my little Pico W webserver running, but want to add an image to the embedded html script (using the conventional 'scr img...' doesn't work.

The image is save to the Pico W in the /Image folder

I can open another html page using the technique you outlined in the server.py comments.

but I'm looking for away of doing it so it on my index page.

Hope thats clear

I have attached a pdf of my test script (apologies for the messy code & comments)
tinyWeb_AP_5.py.pdf

websockets

Thanks for the great library.
Wondering if websockets are possible?

Remove dot prefix from mime_types data structure

Minor: I suppose period prefix could be removed from data structure

i.e.

                  'jpg': 'image/jpeg',
...
ext = fname[idx+1:]

It makes no sense to keep period prefix as you are not using this field other than as key for value
It will improve readability and save 1 char for each extension :-)

mime_types = {'.html': 'text/html',
'.css': 'text/css',
'.js': 'application/javascript',
'.png': 'image/png',
'.jpg': 'image/jpeg',
'.jpeg': 'image/jpeg',
'.gif': 'image/gif'}
idx = fname.rfind('.')
if idx == -1:
return 'text/plain'
ext = fname[idx:]

sendfile support

A simple and efficient way needed to send files with auto/manual mime type.

Limit max concurrent connections

In order to avoid OutOfMemory state we need to implement incoming connection limiting.

Default value can be chosen based on running platform.

Build flash file for ESP01 1M ?

Device and/or platform:
ESP01 1M esp8266

Description of problem:
No room for user files

Expected:
Remove example files from build in order to free some space ?

Traceback (if applicable):

Additional info:
Hello Konstantin,
I am using TinyWeb on a D1 Mini device, and it runs fine,
Now I am interested in using Tinyweb on an ESP01 1M device.
I could flash it and works fine with REPL.
But I cannot download any file because no more space.
Possible to build a new package without the example files please ?

Thanks in advance.

Real device examples

Tinyweb is intended to work mostly on real devices like esp8266, esp32, etc.
However, currently there are no any examples that works on real devices.
To make first release we need at least one example for at least one real device.

Updated tinyweb for new uasyncio?

Damien has merged the new uasyncio into mainline for ESP32 (and other ports) so I was hoping that we could get a new "compatible" version of tinyweb that uses it.

From what I understand (been told by Jim Mussared) tinyweb is using some internal asyncio APIs that wont carry over to the newer uasyncio. I'm not sure how hard it will be to move it, but the plan is to have the new uasyncio ship in 1.13 (frozen), so things are going to likely break when that happens.

I'm happy to be a bleeding edge tester on this as I'm keeping the project I am working on the latest mainline right now, so I'm happy to break things on my side to help get it done.

Cheers!
Seon

Question: tinyweb on esp8266 compared to other frameworks

Hi there,

Thanks for building tinyweb!

I am working on an enduser-friendly, lowcost, DYI IOT device that will run on esp8266 and at the moment it uses tinyweb for providing a REST-API and a WebUI. I need to be very thrifty with memory utilization. It might seem like an odd question, but would you recommend tinyweb over other servers like picoweb or MicroWebSrv (not sure if this would run on esp8266 properly), and why?

If so, I would consider contributing to the project once i feel comfortable with results in my own project.

Thank you!

Logger calls exc instead of exception

Unless I have missed something obvious, the webserver includes the standard micropython logging module and then attempts to call log.exc() instead of log.exception()

I have manually patched my server code to adjust this and exceptions are now correctly being surfaced in the logs instead of an error that log does not have function exc.

There are 3 occurrences in the _handler function lines 479, 484 and 488.

shutdown() tries to access non-existent attribute "cancel" on uasyncio module

asyncio.cancel(self._server_coro)

Board: esp8266, generic nodeMCU dev board
Micropython: 1.17 (esp8266 port), with frozen modules tinyweb and logging

I'm trying to perform the "shutdown" procedure as per instructions in the reference material for the webserver class, i.e.

async def all_shutdown():
    await asyncio.sleep_ms(100)

try:
    web = tinyweb.webserver()
    web.run()
except KeyboardInterrupt as e:
    print(' CTRL+C pressed - terminating...')
    web.shutdown()
    uasyncio.get_event_loop().run_until_complete(all_shutdown())

When I run my server then hit Ctrl-C, I get:

Traceback (most recent call last):
  File "main.py", line 30, in run
  File "tinyweb/server.py", line 689, in shutdown
  File "uasyncio/__init__.py", line 1, in __getattr__
AttributeError: cancel

Task exception wasn't retrieved

Hi,

i am trying to run the hello_world.py of the example section and get the following error:

Task exception wasn't retrieved
future: coro= <generator object '_tcp_server' at 3fff0510>
Traceback (most recent call last):
File "uasyncio/core.py", line 1, in run_until_complete
File "tinyweb/server.py", line 619, in _tcp_server
File "uasyncio/init.py", line 1, in getattr
AttributeError: IORead

I also can't access the webpage.
I included the required library's and also have a WIFI-Connection established.
So how can i fix this error?

(I'm sorry if it's something simple. I'm pretty new to this server stuff.)

Any kind of help is highly appreciated!

Device and/or platform:
M5StackGrey, which uses the ESP32

ENOMEM when running sample code from readme.md

Make sure you are running the latest version of TinyWeb before reporting an issue.

Device and/or platform:
ESP8266

Description of problem:

  • I downloaded the latest Tinyweb firmware
  • I loaded the sample code into the ESP and ran it
  • Error: ENOMEM

Expected:
Running example code

Traceback (if applicable):

>>> exec(open('./TinyWebTest.py').read(),globals())
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<string>", line 32, in <module>
  File "tinyweb/server.py", line 651, in run
  File "uasyncio/core.py", line 126, in run_forever
  File "uasyncio/core.py", line 87, in run_forever
  File "tinyweb/server.py", line 614, in _tcp_server
OSError: [Errno 12] ENOMEM
>>> scandone

>>> gc.mem_free()
13584

Additional info:
The code rus fine after a Hard-reset. Every re-run after that results in ENOMEM.
Line 613: sock.bind(addr)
Line 614: sock.listen(backlog)
It seems the socket is not freed properly or something like that?

Add support for generators in REST API calls

Currently, REST API classes whose implements get, post, etc methods have to return dict or string.

Sometimes it is problematic to return relatively big response due to memory constrains.
Solution could be add support for generators as it is done for non REST methods.

Like:

class CustomersList():
    async def get(self, data):
        for c in self.customers:
            yield '"customer": {}'.format(c)

Documentation

Currently there is no any documentation present.
For first release this is the must.

Force push response content out?

Is there a way I can force tinyweb to push out the response content before the end of the function is reached?

If I have this code. html is declared above this snippet.

await response.start_html()
st_str = '<h2>Credentials saved!</h2><br>You can now close this page...'
html = html.format(self.web_title, st_str)
await response.send(html)
await asyncio.sleep(5)
self.stop( True )

The html is never served to the user because stop() stops the web server, and in all of my tests, the page is never sent, until the end of the function is reached, even if I give it a 5 second sleep.

even if I just do this...

await response.start_html()
st_str = '<h2>Credentials saved!</h2><br>You can now close this page...'
html = html.format(self.web_title, st_str)
await response.send(html)
await asyncio.sleep(30)

The page doesn't get sent for 30 seconds.

So I'm looking for something like a "response.flush()" or similar that will just push the data immediately.

BTW, I can't see anything in the code that looks like it's waiting for any specific thing before writing the data, but I can repro this behaviour quite easily. That said, it might be my own implementation causing this, but I have nothing blocking the event_loop that I can find.

File Upload support

Currently there is any simple way to handle file uploads.

Some great way to do that is required for release 1.1

tinyweb not working above micropython ESP32 firmware 1.19

ESP32C3 with firmware 1.20 -1.22 throws a uasyncio related error but the problem and solution is related with the micropython changes from v1.19.1 (which works) to 1.21-1.22

Description of problem:
the traceback says the error occurs on the def _tcp_server function
specifically on line 650 -> yield uasyncio.core._io_queue.queue_read(sock)
it errors out there and if you try to load the page/ip location you get a connection refused on the browser.

No CaptivePortal support?

I've tried everything, but I can't get TinyWeb to serve me a webpage when my DNS is setup for a CaptivePortal.

DNS is set as a wildcard for 192.168.4.1, and I can surf to that page, and see the website, but it doesn't auto load it on connection to the AP.

It works correctly with other web servers (MicroWebSrv2, Sockets server).

Is there something I am missing? Should this be working, or if not, can this be added?

Thanks,
Seon

tinyweb.mpy not working

Device and/or platform:
ESP8266, Micropython v1.13

Description of problem:
I can't run the module from the .py file because I'm already out of memory. After mpy-cross compilation there is an error during import:

>>> import tinyweb
Trackback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: invalid syntax for number

Other modules after compilation working fine.

Still can't get captive portals working :(

Hi, I'm back on this after a long hiatus - Sorry for the delay.

I can't seem to be able to re-open this previous issue so I have created a new one:
#26

I just can't get tinydns to work - or I just don't understand what I am doing (most likely).

I'm an asyncio noob as well, so that doesn't help at all.

I have all of the captive routes setup, I still have my own tinyweb hack always falls back to '/' if it can't find a route, and no matter what I do, I can't get it to serve a page once I connect to my AP.

The exact same code using MicroDNSSrv works as expected.

I'd gladly keep using MicroDNSSrv, but I still have this outstanding issue:
#25

I've tried setting the DNS to 0.0.0.0:53 and to the IP of the AP, but same issue. I'm thinking maybe the DNS is just not running as I can't see how to make it "run forever" like I can with tinyweb.

I've followed your implementation examples from your int-platform example, but I just can't get it to work :(

So I really don't know where to go from here. I'd love to only be using tinyweb & tinydns for my MP web projects.

LmacRxblk:1 error

Make sure you are running the latest version of TinyWeb before reporting an issue.

Device and/or platform:
ESP8266
micropython latest version

Description of problem:
when my phone lost connection,then reconnect to the AP,
LmacRxblk:1 erro occur.
Expected:

Traceback (if applicable):

Additional info:
I am new to python,maybe you don't close sock when CTRL+C interrupt.
maybe you can check this link
[https://forum.micropython.org/viewtopic.php?t=3602]

Release image broken: ImportError: no module named 'tinyweb'

Make sure you are running the latest version of TinyWeb before reporting an issue.
Fresh download today

Device and/or platform:
ESP8266

Description of problem:
After flashing .bin firmware file:
import network --> ok
import tinyweb (copy-pasted name, no typo...) --> ImportError: no module named 'tinyweb'

Expected:
Successfull import

Traceback (if applicable):

>>> import network
>>> import tinyweb
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: no module named 'tinyweb'
>>> >>> help('modules')
__main__          hashlib           socket            urandom
_boot             inisetup          ssl               ure
_onewire          io                struct            uselect
_webrepl          json              sys               usocket
apa102            lwip              time              ussl
array             machine           ubinascii         ustruct
binascii          math              ucollections      utime
btree             micropython       ucryptolib        utimeq
builtins          neopixel          uctypes           uzlib
collections       network           uerrno            webrepl
dht               ntptime           uhashlib          webrepl_setup
ds18x20           onewire           uheapq            websocket
errno             os                uio               websocket_helper
esp               port_diag         ujson             zlib
flashbdev         random            uos
framebuf          re                upip
gc                select            upip_utarfile
Plus any modules on the filesystem

Additional info:
There are no modules in the file system either,,,

Some functions are not working

Hi,
I'm trying to use this great webserver (very good job!) in my app. Some functions don't work for me, so I test on pure ESP8266. After compiling to .mpy the tinyweb and logging module while importing tinyweb I receive a message: ValueError: invalid syntax for number

To fast fix this I decided to delete all logging references in tinyweb module - with succeeded because server started up. The example from README.md works fine! But...

  1. Sending a static file doesn't work (resp.send_file)
  2. REST API exable doesn't work too (app.add_resource)

Each time I get a blank page, server are respond. I need help because I haven't been able to run it properly for 4 days :-/ I used clean ESP8266 with 4MB memory, Micropython 1.13 with official .bin

My corrections and "improvements":

#import logging
import uasyncio as asyncio
import uasyncio.core, sys, gc
from ujson import loads, dumps
from uos import stat
from uerrno import ENOENT, EACCES, ECONNABORTED, ECONNRESET
from usocket import getaddrinfo, socket, AF_INET, SOCK_STREAM, SOL_SOCKET, SO_REUSEADDR

#log = logging.getLogger('WEB')

(...)
        except OSError as e:
            if e.args[0] not in (ECONNABORTED, ECONNRESET, 32):
                await resp.error(500)
        except HTTPException as e:
            await resp.error(e.code)
        except Exception as e:
            # Unhandled expection in user's method
            #log.error(req.path.decode())
            #log.exc(e, "")
            try:
                await resp.error(500)
(...)

Add ability to pass some arguments to RESTful handler

Currently, there is no way to pass additional parameters into restful handler:

class rest():
    def put(self, data):
        # .. no way to distinguish between URIs

# Use one handler to handle 2 different URIs 
web.add_resource(rest, '/api1')
web.add_resource(rest, '/api2')

Proposed way is to add ability to pass any additional keyword args **kwargs:

class rest():
    def put(self, data, type):
        if type == 1:
            # do something for first case
        else:
            # second case

# Use one handler to handle 2 different URIs 
web.add_resource(rest, '/api1', type=1)
web.add_resource(rest, '/api2', type=2)

Connection closed without response on nonexistent paths

Device and/or platform:

Device: Wemos D1 Mini / ESP8266

I've tried the latest tinyweb firmware firmware_esp8266-v1.3.4.bin as well as the latest MicroPython stable release esp8266-20191220-v1.12.bin with tinyweb precompiled to .mpy format.

Description of problem:

When requesting a path that was not added as a route (i.e. something like GET /nonexistent) the connection is simply closed without returning a proper HTTP error document or status code.

Expected:

The handler for HTTPException should trigger resp.error(404) and return a Not Found error to the client.

Traceback (if applicable):

On the client:

$ curl --http1.0 --verbose 192.168.1.178/nonexistent
*   Trying 192.168.1.178:80...
* TCP_NODELAY set
* Connected to 192.168.1.178 (192.168.1.178) port 80 (#0)
> GET /nonexistent HTTP/1.0
> Host: 192.168.1.178
> User-Agent: curl/7.68.0
> Accept: */*
> 
* Recv failure: Connection reset by peer
* Closing connection 0
curl: (56) Recv failure: Connection reset by peer

The ESP8266 prints nothing on serial during this time.

Additional info:

I've attempted to modify the tinyweb.py and added a few print() statements in the response.error function .. it is called and it looks like it completes without further exceptions .. but an answer is never received at the client?


: I've commented out the import logging and replaced log.exc() calls with pass to do this trivially. This should only affect what's printed to serial though?

How to run (in proper way) second function in parallel?

Hello,

Thanks for your code. Nice job!

I have one question. I'm looking for a proper method to run a function in parallel to web server. I would like to check every 30 seconds my temperature and send values to MQTT server. This should be independent of normal web server activity. What is the best way to do this (assuming that I would like to use uasyncio as tinyweb do).

Best regards,
MvincM

Automatic firmware builds for esp devices

In order to simplify release cycle it is great to have auto firmware deployment (publishing) on github.
It could be easily done (I believe) by Travis CI.

Firmware should contain all deps, tinyweb and proper example for target platform
For release1.0 we're going to support 2 devices:

  • esp8266
  • esp32

UTF-8 char garbled in json response by frontend

Hi, thanks for your new firmware, it can handle UTF-8 char properly, but it has new problem about garbling. my codes is the following:

@websvr.resource('/config/wifi/aplist', method='GET')
async def connect_to_ap(data):
    gc.collect()
    sta = network.WLAN(network.STA_IF)
    sta.active(True)
    ap_list = sta.scan()
    resp = json.dumps({
        "msg": "OK",
        "result": [
            {"ssid": x[0].decode(), "authmode": x[4], "rssi": x[3]}
            for x in ap_list
        ]
    })
    for s in resp:
        yield s

the above codes works correctly if values of resp['result'] contains no UTF-8 chars, otherwise the front end would receive unreadable code, like this:
图片

I guess this due to Content-Type field should not be 'application/json;charset=utf-8' in Response-Header, but I can't debug it..

Regarding blinking LED

HI, I have this problem on ESP8266 (Wemos D1 Mini) when flash the version 1.3.5, when the upload is completed at restart the binking led start like crazy and the serial console is filled by extrange chars (I tryed diferents bauds sets but always is the same).
Also has try the versions 1.3.3 / 1.3.4 and works fine...

Any idea?

Regarding blinking LED - I have no idea, sorry.. (

Originally posted by @belyalov in #19 (comment)

Kernel Panic serving anything if local MicroDNSSrv used

Make sure you are running the latest version of TinyWeb before reporting an issue.

Device and/or platform:

  • MicroPython, TinyPICO (ESP32) (latest - built from source today)
  • Built against IDF 4.0 release
  • Using latest MicroDNSSrv for DNS + latest TinyWeb for Webserver.

Description of problem:

Webserver is running as expected if I connect to my wifi and run the server with the host set to my IP given by the DNS.

But my use case is to set local DNS and start an AP and connect to my AP, and have it serve pages from that - Making a MicroPython WifiManager-esq system for my application.

If I set the DNS to be MicroDNSSrv using this...

dns = MicroDNSSrv.Create({ '*' : '192.168.4.1' })

And connect to it, as soon as it tries to serve the / page, I get a kernel panic!

Expected:

It should just serve me the page. Even the most basic of pages kernel panics. There should never be a kernel panic from a module.

This setup works with MicroWebServ2 as the web server, and my basic sockets based web server. I moved to TinyWeb as I need an uasyncio based web server as I'm transitioning the rest of my app to be asyncio based.

Error:

`>>> import tw
I (110680) phy: phy_version: 4180, cb3948e, Sep 12 2019, 16:39:13, 0, 0

tw.run()
Guru Meditation Error: Core 1 panic'ed (Interrupt wdt timeout on CPU1)
Core 1 register dump:
PC : 0x40093c30 PS : 0x00060034 A0 : 0x80096544 A1 : 0x3ffbb150
A2 : 0x3ffba694 A3 : 0x3f427d11 A4 : 0x3ffba6a8 A5 : 0x3ffbeaf0
A6 : 0x3ffbeb38 A7 : 0x00000001 A8 : 0x00000000 A9 : 0x00000000
A10 : 0x00000000 A11 : 0x00000011 A12 : 0x8009707b A13 : 0x3ffbeac0
A14 : 0x00000020 A15 : 0x00000020 SAR : 0x00000018 EXCCAUSE: 0x00000006
EXCVADDR: 0x00000000 LBEG : 0x400948e0 LEND : 0x4009490e LCOUNT : 0x00000000
ELF file SHA256: `

Traceback (if applicable):

Additional info:

Please let me know if there is anything else I can provide!

Code:

import tinyweb, network
from microDNSSrv import MicroDNSSrv

wlan_ap = network.WLAN(network.AP_IF)
wlan_ap.active(True)
wlan_ap.config(essid='Seon')

dns = MicroDNSSrv.Create({ '*' : '192.168.4.1' })

# sta = network.WLAN(network.STA_IF)
# sta.active(True)
# sta.connect('aaa', 'bbb')
# sta.ifconfig()

# Create web server application
app = tinyweb.webserver()


# Index page
@app.route('/')
async def index(request, response):
    # Start HTTP response with content-type text/html
    await response.start_html()
    # Send actual HTML page
    await response.send('<html><body><h1>Hello, world! (<a href="/table">table</a>)</h1></html>\n')


# Another one, more complicated page
@app.route('/table')
async def table(request, response):
    # Start HTTP response with content-type text/html
    await response.start_html()
    await response.send('<html><body><h1>Simple table</h1>'
                        '<table border=1 width=400>'
                        '<tr><td>Name</td><td>Some Value</td></tr>')
    for i in range(10):
        await response.send('<tr><td>Name{}</td><td>Value{}</td></tr>'.format(i, i))
    await response.send('</table>'
                        '</html>')


def run():
    app.run()

chunk mode send json

Hi , thank you very much for your wonderful framework , but I regret to find an error in processing NON-ASCII characters by using the framework .

for chunk in res:
     await resp.send('{:x}\r\n'.format(len(chunk)))
     await resp.send(chunk)
     await resp.send('\r\n')

the above codes in server.py at line 337-340 , "len(chunk)" refer to the numbers of the character variable "chunk" , not the bytes length . It's OK with the return of the function "len( )" , when the character variable is ASCII type , but for the NON-ASCII type , such as a Chinese character , the character number is 1 in function "len( )" , and the length is 3 bytes . So , this function will cause a loss in transmission .

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.