belyalov / tinyweb Goto Github PK
View Code? Open in Web Editor NEWSimple and lightweight HTTP async server for micropython
License: MIT License
Simple and lightweight HTTP async server for micropython
License: MIT License
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:
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
Thanks for the great library.
Wondering if websockets are possible?
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 :-)
Lines 9 to 19 in 4ea409c
A simple and efficient way needed to send files with auto/manual mime type.
In order to avoid OutOfMemory state we need to implement incoming connection limiting.
Default value can be chosen based on running platform.
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.
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.
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
Currently there is no any request timeout implemented.
Saying that it is possible just open TCP connection and it will never be timed out.
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!
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.
Line 689 in 33d73c9
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
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
Make sure you are running the latest version of TinyWeb before reporting an issue.
Device and/or platform:
ESP8266
Description of problem:
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?
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)
Currently there is no any documentation present.
For first release this is the must.
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.
Currently there is any simple way to handle file uploads.
Some great way to do that is required for release 1.1
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.
Make sure you are running the latest version of TinyWeb before reporting an issue.
Device and/or platform:
Description of problem:
read_headers
is not case-insensitive on keys, as described in the standard.
This can lead to problems, if the client uses different cases for ie. content-length
.
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers
Expected:
Lowercase all the received headers.
Traceback (if applicable):
Additional info:
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
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.
It will be great to have some native, simple way to enforce HTTP authorization.
Since we're running on esp8266
it is too much to parse / save all HTTP request headers.
Moreover, for small applications it doesn't actually make sense to have all headers parsed.
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.
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]
To archive v1.0 release test on esp32
must be completed
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,,,
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...
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)
(...)
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)
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?
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
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
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..
@belyalov could you disable this codefactor.io warning: https://github.com/belyalov/tinyweb/pull/36/checks?check_run_id=1503119325 (i hate seeing my PRs fail the pipeline for no reason)
Should work like this: https://support.codefactor.io/i18-ignoring-issues-and-patterns
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)
Make sure you are running the latest version of TinyWeb before reporting an issue.
Device and/or platform:
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()
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 .
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.