<< return to Vizycam.com

Generating HTML with kapp.layout & serving static HTML

I’m working with a “hacked” version of Pet Companion and have a couple problems:

I want to insert an html link into the layout, but the kapp.layout() function is escaping HTML when I do this:

self.kapp.layout = [self.video,"<h1>Hello World</h1>",call_pet_button, dispense_treat_button,brightness,awb]

How do I get it to render unaltered HTML?

Secondly, using Google to host images is irreparably broken. The (new) instructions for generating the API key don’t match the actual user experience, but even once I got Google to generate the API key it wanted me to grant VizyCam.com permissions to all of my Google account data. Not doing so resulted in a message that said “Google hasn’t verified this app”. Not wanting to start over and make a new throw away Google account, I just moved on.

I extricated the Google code from the Pet Companion app and replaced it with a function that saves the images to the MEDIA_DIR with cv2.imwrite() and generates an index.html file there which displays the images. My plan was to place a hyperlink to the index.html file where the “Hello World” is in the above layout. Currently I’m just running a second vanilla python3 web server on a different port to view that page.

How do I generate and reference generic static HTML pages with/for the VizyCam’s inherent HTTP server? (FWIW I’ve negative interest in learning how to code with the undocumented wrappered React stuff, it’s just too convoluted for my simple needs.)

Oh, one last question while I’m at it: How do I preserve the video.overlay info showing what Tensor Flow matched and my time-stamps on the images? When I write the frame only the raw un-overlay-ed is saved.


It does look like Google changed their console a bit and we’ll need to remake the key generation video. One thing to note is that if the API key generation doesn’t work for some reason, you don’t need to create a new Google account when creating a new (or different) API key. You can have many keys associated with a single Google account. We’ll update the video hopefully soon to reflect the changes.

If you want to create links you can do something like this:

import dash_html_components as html

url = "https://google.com"
self.kapp.layout = ['Go to ', html.A("Google", href=url, target="_blank")]

There is some documentation on the A component here.

Vizy is built on a Flask server, so you can serve HTML content if you wish. It would look something like this:

async def foo():
   return "hello world" # This would be a string containing the HTML content

And then you could point your browser to http://vizy.local/foo to see the page.

The render_detected function renders the boxes to an overlay that sits on top of the image, so it essentially draws on top of the image in the browser without modifying the image. If you want the boxes in the image when you save them, you’ll need to modify the image itself before saving. There is another function called render_detected_image which takes an image instead of an overlay. It modifies the image like you want. For example:

image = <some BGR image array>
dets = <list of detections>
kritter.render_detected_image(image, dets)
cv2.imwrite("image.jpg", image)

Hope this helps!


Thanks loads for the tips.

The html.A() function works fine, thanks. I had a look at Dash’s docs here and they might be useful to someone else reading this thread: https://dash.plotly.com/dash-html-components . I have to say that the benefit of having to code HTML like that isn’t clear. It seems like it might be a pain to maintain. Also, I keep getting This page is using significant energy warnings from my Mac on Plotly’s page above which seems like it should be purely static.

The @self.kapp.server.route("/foo")method works fine but I was hoping for a vanilla static file sever. This is because as a function driven server I’d have to write code to stat() the directory and deliver the files in code. That said, knowing how to generate dynamic content with the method you described is invaluable.

The kritter.render_detected_image(image, dets) works great , thanks. There is a minor anomaly with the tagging. The font seems oversized for some reason. Here’s an example of what I mean.

Sure thing – glad you got it working :slight_smile:

Dash makes it fairly easy to instantiate, remove, and render components on a web page from Python. You could (in theory) make a bunch of calls to the html module within Dash and create a static html page, but benefit wouldn’t be clear, like you said. Pages created with Dash are typically dynamic in nature not static.

Regarding the energy warning, does the page have a video window?

Try this:
kritter.render_detected_image(image, dets, font_size=0.5)

the default font_size is 1.0 (it’s the size defined with cv2.putText)


Thanks, that worked great. ( I’ve finally learned to root around in your Github for clues. )

The page that generated the “too much energy” error was not yours, it was https://dash.plotly.com/dash-html-components and there’s no video or anything obviously active on it. I just commented on it because I wondered if it was indicative of Dash’s behavior in general.

Here’s the new and improved labeling:

Nice! Glad you got it working :slight_smile:

1 Like