Example #1
0
def run():
    # Create web server application
    app = tinyweb.webserver()
    # Add our resources
    app.add_resource(CustomersList, '/customers')
    app.add_resource(Customer, '/customers/<user_id>')
    app.run(host='0.0.0.0', port=8081)
Example #2
0
 def setUp(self):
     self.srv = webserver()
     self.tempfn = '__tmp.html'
     self.ctype = None
     self.max_age = 2592000
     with open(self.tempfn, 'wb') as f:
         f.write('someContent blah blah')
Example #3
0
 def testUrlFinderParameterized(self):
     srv = webserver()
     # Add few routes
     srv.add_route('/', 0)
     srv.add_route('/<user_name>', 1)
     srv.add_route('/a/<id>', 2)
     # Check first url (non param)
     rq = request(mockReader([]))
     rq.path = b'/'
     f, args = srv._find_url_handler(rq)
     self.assertEqual(f, 0)
     # Check second url
     rq.path = b'/user1'
     f, args = srv._find_url_handler(rq)
     self.assertEqual(f, 1)
     self.assertEqual(args['_param_name'], 'user_name')
     self.assertEqual(rq._param, 'user1')
     # Check third url
     rq.path = b'/a/123456'
     f, args = srv._find_url_handler(rq)
     self.assertEqual(f, 2)
     self.assertEqual(args['_param_name'], 'id')
     self.assertEqual(rq._param, '123456')
     # When param is empty and there is no non param endpoint
     rq.path = b'/a/'
     f, args = srv._find_url_handler(rq)
     self.assertEqual(f, 2)
     self.assertEqual(rq._param, '')
Example #4
0
 def setup_modules(self):
     # Base config
     self.config = SimpleConfig()
     self.config.add_param('configured', False)
     self.config.add_param(
         'hostname',
         'neopixel_{:s}'.format(platform.utils.mac_last_digits()))
     # Setup remote logging
     self.rlogging = RemoteLogging(self.config)
     # MQTT
     self.mqtt = tinymqtt.MQTTClient('neopixelctrl-{:s}'.format(
         platform.utils.mac_last_digits()),
                                     config=self.config)
     # DNS
     self.dns = tinydns.Server(ttl=10)
     # Modules
     self.ambi = AmbientLightAnalogSensor(self.config, self.mqtt,
                                          machine.ADC(0))
     self.setupbtn = SetupButton(self.config, machine.Pin(setup_btn_pin))
     self.status = StatusLed(self.config, machine.Pin(status_led_pin))
     # WebServer
     self.web = tinyweb.webserver(max_concurrency=1, debug=True)
     # LED strip handler (+ associated web routes)
     self.neo = NeopixelStrip(machine.Pin(neopixel_pin), self.config,
                              self.web, self.mqtt, self.loop)
Example #5
0
 def setUp(self):
     self.srv = webserver()
     self.srv.conns[id(1)] = None
     self.srv.add_resource(ResourceGetPost, '/')
     self.srv.add_resource(ResourceGetParam, '/param/<user_id>')
     self.srv.add_resource(ResourceGetArgs, '/args', arg1=1, arg2=2)
     self.srv.add_resource(ResourceNegative, '/negative')
Example #6
0
 def setup_modules(self):
     # Base config
     self.config = SimpleConfig()
     self.config.add_param('configured', False)
     self.config.add_param('hostname',
                           'wifiswitch_{:s}'.format(mac_last_digits()))
     # Setup remote logging
     self.rlogging = RemoteLogging(self.config)
     # MQTT
     self.mqtt = tinymqtt.MQTTClient('wifiswitch-{:s}'.format(
         mac_last_digits()),
                                     server='192.168.1.1',
                                     port=3883,
                                     config=self.config)
     # Modules
     self.status = StatusLed(self.config, machine.Pin(status_led_pin))
     # self.setupbtn = SetupButton(self.config, machine.Pin(setup_btn_pin))
     # WebServer
     self.web = tinyweb.webserver(debug=True)
     # Relays
     self.relays = []
     for num, pin in enumerate(relays_pins):
         self.relays.append(
             Relay(num + 1, machine.Pin(pin), self.config, self.web,
                   self.mqtt))
     # Binary Sensors (user GPIO - currently only GPIO)
     self.binary_sensors = []
     for num, pin in enumerate(binary_sensor_pins):
         pname = 'mqtt_binary_sensor{}_status'.format(num + 1)
         self.config.add_param(pname, 'binary_sensor{}'.format(num + 1))
         self.binary_sensors.append(
             BinarySensor(machine.Pin(pin), self.config, self.mqtt, pname))
Example #7
0
 def testMalformedRequest(self):
     """Verify that malformed request generates proper response"""
     rdr = mockReader(['GET /\r\n', HDR('Host: blah.com'), HDRE])
     wrt = mockWriter()
     srv = webserver()
     run_generator(srv._handler(rdr, wrt))
     exp = ['HTTP/1.0 400 Bad Request\r\n', '\r\n']
     self.assertEqual(wrt.history, exp)
     # Connection must be closed
     self.assertTrue(wrt.closed)
Example #8
0
 def testStartHTML(self):
     """Verify that request.start_html() works well"""
     srv = webserver()
     srv.add_route('/', self.hello_world_handler)
     rdr = mockReader(['GET / HTTP/1.1\r\n', HDR('Host: blah.com'), HDRE])
     wrt = mockWriter()
     # "Send" request
     run_generator(srv._handler(rdr, wrt))
     # Ensure that proper response "sent"
     self.assertEqual(wrt.history, self.hello_world_history)
     self.assertTrue(wrt.closed)
Example #9
0
    def startServer(self):
        self.server = tinyweb.webserver()
        self.server.add_route('/', self.app, methods=["GET"])
        self.server.add_route('/execute',
                              self.execute,
                              methods=['POST'],
                              save_headers=['Content-Length', 'Content-Type'])
        self.server.add_route('/static/<loc>', self.static, methods=['GET'])

        self.toggleServerStatusLED()
        self.server.run(self.address, self.port)
Example #10
0
 def setUp(self):
     self.dummy_called = False
     self.data = {}
     # "Register" one connection into map for dedicated decor server
     server_for_decorators.conns[id(1)] = None
     self.hello_world_history = ['HTTP/1.0 200 MSG\r\n' +
                                 'Content-Type: text/html\r\n\r\n',
                                 '<html><h1>Hello world</h1></html>']
     # Create one more server - to simplify bunch of tests
     self.srv = webserver()
     self.srv.conns[id(1)] = None
Example #11
0
 def testUrlFinderNegative(self):
     srv = webserver()
     # empty URL is not allowed
     with self.assertRaises(ValueError):
         srv.add_route('', 1)
     # Query string is not allowed
     with self.assertRaises(ValueError):
         srv.add_route('/?a=a', 1)
     # Duplicate urls
     srv.add_route('/duppp', 1)
     with self.assertRaises(ValueError):
         srv.add_route('/duppp', 1)
Example #12
0
 def testRequestBodyJson(self):
     """JSON encoded POST body"""
     srv = webserver()
     srv.add_route('/', self.dummy_post_handler, methods=['POST'])
     rdr = mockReader([
         'POST / HTTP/1.1\r\n',
         HDR('Content-Type: application/json'),
         HDR('Content-Length: 10'), HDRE, '{"a": "b"}'
     ])
     wrt = mockWriter()
     run_generator(srv._handler(rdr, wrt))
     # Check parsed POST body
     self.assertEqual(self.data, {'a': 'b'})
Example #13
0
 def testRequestBodyUnknownType(self):
     """Unknow HTTP body test - empty dict expected"""
     srv = webserver()
     srv.add_route('/', self.dummy_post_handler, methods=['POST'])
     rdr = mockReader([
         'POST / HTTP/1.1\r\n',
         HDR('Host: blah.com'),
         HDR('Content-Length: 5'), HDRE, '12345'
     ])
     wrt = mockWriter()
     run_generator(srv._handler(rdr, wrt))
     # Check extracted POST body
     self.assertEqual(self.data, {})
Example #14
0
 def testRequestBodyNegative(self):
     """Regular HTML form"""
     srv = webserver()
     srv.add_route('/', self.dummy_post_handler, methods=['POST'])
     rdr = mockReader([
         'POST / HTTP/1.1\r\n',
         HDR('Content-Type: application/json'),
         HDR('Content-Length: 9'), HDRE, 'some junk'
     ])
     wrt = mockWriter()
     run_generator(srv._handler(rdr, wrt))
     # payload broken - HTTP 400 expected
     self.assertEqual(wrt.history, ['HTTP/1.0 400 Bad Request\r\n', '\r\n'])
Example #15
0
 def testRequestBodyUrlencoded(self):
     """Regular HTML form"""
     srv = webserver()
     srv.add_route('/', self.dummy_post_handler, methods=['POST'])
     rdr = mockReader([
         'POST / HTTP/1.1\r\n',
         HDR('Content-Type: application/x-www-form-urlencoded; charset=UTF-8'
             ),
         HDR('Content-Length: 10'), HDRE, 'a=b&c=%20d'
     ])
     wrt = mockWriter()
     run_generator(srv._handler(rdr, wrt))
     # Check parsed POST body
     self.assertEqual(self.data, {'a': 'b', 'c': ' d'})
Example #16
0
def run():
    # Create web server application
    app = tinyweb.webserver()
    # Add our resources
    
    @app.route('/')
    @app.route('/index.html')
    async def index(req, resp):
        # Just send file
        await resp.send_file('/index.html')
    
    app.add_resource(CustomersList, '/customers')
    app.add_resource(Customer, '/customers/<user_id>')
    app.add_resource(lightShow, '/light')
    app.run(host='0.0.0.0', port=8081, loop_forever=False)
Example #17
0
 def testRequestLargeBody(self):
     """Max Body size check"""
     srv = webserver()
     srv.add_route('/',
                   self.dummy_post_handler,
                   methods=['POST'],
                   max_body_size=5)
     rdr = mockReader([
         'POST / HTTP/1.1\r\n',
         HDR('Content-Type: application/json'),
         HDR('Content-Length: 9'), HDRE, 'some junk'
     ])
     wrt = mockWriter()
     run_generator(srv._handler(rdr, wrt))
     # payload broken - HTTP 400 expected
     self.assertEqual(wrt.history,
                      ['HTTP/1.0 413 Payload Too Large\r\n', '\r\n'])
Example #18
0
 def testRouteParameterized(self):
     """Verify that route with params works fine"""
     srv = webserver()
     srv.add_route('/db/<user_name>', self.route_parameterized_handler)
     rdr = mockReader(
         ['GET /db/user1 HTTP/1.1\r\n',
          HDR('Host: junk.com'), HDRE])
     wrt = mockWriter()
     # "Send" request
     run_generator(srv._handler(rdr, wrt))
     # Ensure that proper response "sent"
     expected = [
         'HTTP/1.0 200 OK\r\n', 'Content-Type: text/html\r\n\r\n',
         '<html>Hello, user1</html>'
     ]
     self.assertEqual(wrt.history, expected)
     self.assertTrue(wrt.closed)
Example #19
0
    def testAutoOptionsMethod(self):
        """Test auto implementation of OPTIONS method"""
        srv = webserver()
        srv.add_route('/',
                      self.hello_world_handler,
                      methods=['POST', 'PUT', 'DELETE'])
        srv.add_route('/disabled',
                      self.hello_world_handler,
                      auto_method_options=False)
        rdr = mockReader(['OPTIONS / HTTP/1.0\r\n', HDRE])
        wrt = mockWriter()
        run_generator(srv._handler(rdr, wrt))

        exp = [
            'HTTP/1.0 200 OK\r\n', 'Access-Control-Allow-Headers: *\r\n'
            'Access-Control-Allow-Origin: *\r\n'
            'Access-Control-Allow-Methods: POST PUT DELETE\r\n\r\n'
        ]
        self.assertEqual(wrt.history, exp)
        self.assertTrue(wrt.closed)
Example #20
0
    def testCatchAllDecorator(self):
        # A fresh server for the catchall handler
        server_for_catchall_decorator = webserver()

        # Catchall decorator and handler
        @server_for_catchall_decorator.catchall()
        async def route_for_catchall_decorator(req, resp):
            await resp.start_html()
            await resp.send('my404')

        rdr = mockReader(['GET /this/is/an/invalid/url HTTP/1.1\r\n',
                          HDRE])
        wrt = mockWriter()
        server_for_catchall_decorator.conns[id(1)] = None
        run_coro(server_for_catchall_decorator._handler(rdr, wrt))
        expected = ['HTTP/1.0 200 MSG\r\n' +
                    'Content-Type: text/html\r\n\r\n',
                    'my404']
        self.assertEqual(wrt.history, expected)
        self.assertTrue(wrt.closed)
Example #21
0
 def testUrlFinderExplicit(self):
     urls = [('/', 1), ('/%20', 2), ('/a/b', 3), ('/aac', 5)]
     junk = ['//', '', '/a', '/aa', '/a/fhhfhfhfhfhf']
     # Create server, add routes
     srv = webserver()
     for u in urls:
         srv.add_route(u[0], u[1])
     # Search them all
     for u in urls:
         # Create mock request object with "pre-parsed" url path
         rq = request(mockReader([]))
         rq.path = u[0].encode()
         f, args = srv._find_url_handler(rq)
         self.assertEqual(u[1], f)
     # Some simple negative cases
     for j in junk:
         rq = request(mockReader([]))
         rq.path = j.encode()
         f, args = srv._find_url_handler(rq)
         self.assertIsNone(f)
         self.assertIsNone(args)
Example #22
0
    def testDisallowedMethod(self):
        """Verify that server respects allowed methods"""
        srv = webserver()
        srv.add_route('/', self.hello_world_handler)
        srv.add_route('/post_only', self.dummy_handler, methods=['POST'])
        rdr = mockReader(['GET / HTTP/1.0\r\n', HDRE])
        # "Send" GET request, by default GET is enabled
        wrt = mockWriter()
        run_generator(srv._handler(rdr, wrt))
        self.assertEqual(wrt.history, self.hello_world_history)
        self.assertTrue(wrt.closed)

        # "Send" GET request to POST only location
        self.dummy_called = False
        rdr = mockReader(['GET /post_only HTTP/1.1\r\n', HDRE])
        wrt = mockWriter()
        run_generator(srv._handler(rdr, wrt))
        # Hanlder should not be called - method not allowed
        self.assertFalse(self.dummy_called)
        exp = ['HTTP/1.0 405 Method Not Allowed\r\n', '\r\n']
        self.assertEqual(wrt.history, exp)
        # Connection must be closed
        self.assertTrue(wrt.closed)
Example #23
0
    def testParseHeadersOnOff(self):
        """Verify parameter parse_headers works"""
        srv = webserver()
        srv.add_route('/parse', self.dummy_handler, parse_headers=True)
        srv.add_route('/noparse', self.dummy_handler, parse_headers=False)
        rdr = mockReader([
            'GET /noparse HTTP/1.1\r\n',
            HDR('Host: blah.com'),
            HDR('Header1: lalalla'),
            HDR('Junk: junk.com'), HDRE
        ])
        # "Send" request with parsing off
        wrt = mockWriter()
        run_generator(srv._handler(rdr, wrt))
        self.assertTrue(self.dummy_called)
        # Check for headers
        self.assertEqual(self.dummy_req.headers, {})
        self.assertTrue(wrt.closed)

        # "Send" request with parsing on
        rdr = mockReader([
            'GET /parse HTTP/1.1\r\n',
            HDR('Host: blah.com'),
            HDR('Header1: lalalla'),
            HDR('Junk: junk.com'), HDRE
        ])
        wrt = mockWriter()
        run_generator(srv._handler(rdr, wrt))
        self.assertTrue(self.dummy_called)
        # Check for headers
        hdrs = {
            b'Junk': b'junk.com',
            b'Host': b'blah.com',
            b'Header1': b'lalalla'
        }
        self.assertEqual(self.dummy_req.headers, hdrs)
        self.assertTrue(wrt.closed)
Example #24
0
 def setUp(self):
     self.srv = webserver()
     self.srv.add_resource(ResourceGetPost, '/')
     self.srv.add_resource(ResourceGetParam, '/param/<user_id>')
Example #25
0
from tinyweb import webserver
from tinyweb.server import HTTPException
from radio.tuner import device

app = webserver()


@app.resource('/status', method='GET')
def status(params):
    status = {
        'state': device.state,
        'volume': device.volume,
        'frequency': device.frequency,
        'stereo': device.stereo,
        'mute': device.mute
    }
    return (status, 200)


@app.resource('/mute', method='PUT')
def mute(params):
    try:
        device.mute = int(params.get('value'))
    except ValueError:
        raise HTTPException(400)
    return ('', 202)


@app.resource('/volume', method='PUT')
def volume(params):
    try:
Example #26
0
    def testUrlFinderNegative(self):
        srv = webserver()
        # empty URL is not allowed
        with self.assertRaises(ValueError):
            srv.add_route('', 1)
        # Query string is not allowed
        with self.assertRaises(ValueError):
            srv.add_route('/?a=a', 1)
        # Duplicate urls
        srv.add_route('/duppp', 1)
        with self.assertRaises(ValueError):
            srv.add_route('/duppp', 1)


# We want to test decorator @server.route as well
server_for_decorators = webserver()


@server_for_decorators.route('/uid/<user_id>')
@server_for_decorators.route('/uid2/<user_id>')
async def route_for_decorator(req, resp, user_id):
    await resp.start_html()
    await resp.send('YO, {}'.format(user_id))


class ServerFull(unittest.TestCase):

    def setUp(self):
        self.dummy_called = False
        self.data = {}
        # "Register" one connection into map for dedicated decor server
Example #27
0
def main():
    # Some ports requires to allocate extra mem for exceptions
    if hasattr(micropython, 'alloc_emergency_exception_buf'):
        micropython.alloc_emergency_exception_buf(100)

    loop = asyncio.get_event_loop()
    logging.basicConfig(level=logging.DEBUG)

    # Base config
    config = SimpleConfig()
    config.add_param('configured', False)
    wsetup = WifiSetup(config)

    # MQTT
    mqtt = tinymqtt.MQTTClient('LEDcontroller-{}'.format(
        platform.utils.mac_last_digits()), config=config)

    # DNS
    dns = tinydns.Server(ttl=10)

    # WebServer
    web = tinyweb.webserver()

    # Enable REST API for config & wifi
    web.add_resource(config, '/config')
    web.add_resource(wsetup, '/wifi')

    # Create LED strip handler
    WhiteLedStrip(machine.Pin(green_pin), config, web, mqtt, loop)

    # Peripheral modules
    setupbtn = SetupButton(config, None)

    # Other web routes
    @web.route('/')
    async def index(req, resp):
        if config.configured:
            await resp.redirect('/dashboard')
        else:
            await resp.redirect('/setup')

    @web.route('/dashboard')
    async def page_dashboard(req, resp):
        await resp.send_file('dashboard_all.html.gz',
                             content_encoding='gzip',
                             content_type='text/html')

    @web.route('/setup')
    async def page_setup(req, resp):
        await resp.send_file('setup_all.html.gz',
                             content_encoding='gzip',
                             content_type='text/html')

    # Setup AP parameters
    ap_if = network.WLAN(network.AP_IF)
    essid = b'LedCtrl-%s' % platform.utils.mac_last_digits()
    ap_if.active(True)
    ap_if.config(essid=essid, authmode=network.AUTH_WPA_WPA2_PSK, password=b'ledledled')
    ap_if.ifconfig(('192.168.168.1', '255.255.255.0', '192.168.168.1', '192.168.168.1'))
    ap_if.active(False)
    # Captive portal
    platform.utils.captiveportal.enable(web, dns, '192.168.168.1')

    # Load configuration
    try:
        config.load()
    except Exception as e:
        log.warning('Config load failed: {}'.format(e))
        pass

    # Main loop
    try:
        wport = 80
        dport = 53
        if platform.utils.is_emulator():
            wport = 8080
            dport = 5335
        # Start services
        dns.run(host='0.0.0.0', port=dport, loop=loop)
        web.run(host='0.0.0.0', port=wport, loop_forever=False, loop=loop)
        mqtt.run(loop)
        setupbtn.run(loop)

        # Run main loop
        loop.run_forever()
    except KeyboardInterrupt as e:
        if platform.utils.is_emulator():
            for s in [web, dns, mqtt]:
                s.shutdown()
            loop.run_until_complete(shutdown_wait())
        else:
            raise
    except Exception as e:
        log.exc(e, "Unhandled exception")
Example #28
0
#!/usr/bin/env micropython
"""
MIT license
(C) Konstantin Belyalov 2017-2018
"""
import tinyweb


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


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


# Another one, more complicated page
@app.route('/table')
def table(request, response):
    # Start HTTP response with content-type text/html
    yield from response.start_html()
    yield from 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):
        yield from response.send('<tr><td>Name{}</td><td>Value{}</td></tr>'.format(i, i))
Example #29
0
    await client.connect(loop)
    # n=0
    #sreader = uasyncio.StreamReader(sys.stdin)
    n = 0
    while True:
        res = await sreader.readline()
        await client.publish(PUB_TOPIC, res, qos=1)
        await uasyncio.sleep(0)


gc.collect()

loop.create_task(mqtt_main(client))

app = tinyweb.webserver(external_loop=loop, debug=True)


# Index page
@app.route('/')
async def index(request, response):
    global wifi
    wifi.active(True)
    # Start HTTP response with content-type text/html
    ssids = sorted(ssid.decode('utf-8') for ssid, *_ in wifi.scan()[:10])
    gc.collect()
    await response.start_html()
    # Send actual HTML page
    await response.send("""
        <html>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />