Python in the Browser, Fetching JSON from an AWS S3 bucket into a Bokeh Line Chart, a Serverless solution
Tags: javascript, python, webdev, aws
Published: 2024-06-15 12:42:32

I needed some quick Python to replace broken code over in AWS Lambda. While looking at IDEs I stumbled upon a way to write and run Python directly in the Browser just with a Notepad. So I opened Notepad and wrote a boiler plate html file with a Python Library called pyscript...core.js. There was no IDE or server involved, just my frontend file. All I had to do was double click the HTML file and my Python, Javascript, JSON and HTML played very nicely together.

Also I had recently ditched React in favor of Plain JS and started fetching JSON from S3 versus the traditional SQL approach. So Fetch in Python? Was this possible? Fetch is JS and Python is not, so I thought. But thanks to WebAssembly now we can combine both Python and Javascript on an HTML page.

Since I never really used much Python and I was mostly Plain JS without Node I was accustomed to using CDN Libraries in my HTML. I was drawing some Python line charts one day and got to thinking about hosting them in JS too. Bokeh was the answer. Bokeh is both a Python library and a JS Library so it fit my new configuration. Now my solution was totally serverless.

So lets look at some Pyscript now. It has only been around since 2022. In 31 lines of code I can do all the above. The only drawback is that my chart takes 8 seconds to load and from Python IDLE it takes 3 seconds. But the data is worth waiting for because of the value it adds to our Marketing effort. Recently Pyscript had a complete rewrite. This code used to be 60 lines just 2 months ago and prior to that it was 100+ lines using popular competitor Matplotlib.

So now below is the no brainer code written in pyscript newest release, June 2024
Note: this is a first for this newest way of writing pyscript as of 6-15-24
Beware that versioning is critical with Pyscript and Bokeh and is not backward compatible.

```js
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>get json from AWS S3</title>
    <link rel="stylesheet" href="https://pyscript.net/releases/2024.6.1/core.css"> <!--most recent pyscript lib-->
    <script type="module" src="https://pyscript.net/releases/2024.6.1/core.js"></script> <!--most recent pyscript lib-->
    <script type="text/javascript" src="https://cdn.bokeh.org/bokeh/release/bokeh-3.4.1.min.js"></script> <!--recent bokeh lib-->
    <py-config>packages = ["bokeh"]</py-config>
</head>
<body>
    <h1>wait 8 seconds to display Bokeh Line Chart</p>
    <div id="chart"></div> <!--inside the script tags below is my Python code-->
    <script type="py" async>
        from bokeh.plotting import figure
        from bokeh.embed import json_item
        from pyscript import window, fetch, ffi 
        Bokeh = window.Bokeh #pass Bokeh into the main threads window object
        async def get_data():
            response = await fetch('https://rickd.s3.us-east-2.amazonaws.com/04.json')
            data = await response.json()
            xAxis=[i['time'] for i in data] #grab s3 data using loop
            yAxis=[i['Quantity'] for i in data] #grab s3 data using loop
            p = figure(width = 700, height = 600) #beware that much code u see still uses plot_width /height which does not work anymore
            p.line(xAxis, yAxis, legend_label="data from AWS S3", line_width=2)
            await Bokeh.embed.embed_item(ffi.to_js(json_item(p, "chart"))) #ffi converts a Python object into its JavaScript counterpart
        await get_data()
    </script>
</body>
</html>
```
Warning, if u previously used urllib or requests packages in Python, note, these packages do not work in Pyscript but Fetch does work. You will need to do some recoding if transitioning from urllib or requests.


Happy coding folks!