1

How can I use the Segno qrcode python library to generate a QR Code on the fly to show it on a web page.

For example, exporting it as an SVG:

import segno
qr = segno.make('Up Jumped the Devil')
svgvar = qr.export_as_svg()

Is there a better way?

not2qubit
  • 14,531
  • 8
  • 95
  • 135
qnx Smith
  • 11
  • 2

2 Answers2

1
import segno
# var contains a SVG data URI
var = segno.make('Up Jumped the Devil').svg_data_uri()

Here var contains the QR code as data URI:

data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns[...]

which can be used to embed the code directly into any HTML img, or even a browser.

Another option:
Write the SVG into a binary buffer instead of a file:

import segno 
import io
buff = io.BytesIO()
segno.make('Up Jumped the Devil').save(buff, kind="svg")
# Returns the SVG output
buff.getvalue()

buff contains the complete SVG document:

<?xml version="1.0" encoding="utf-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="33" height="33" class="segno"><path[...]</svg>

The output cannot be used directly within a HTML page, but you can omit the XML declaration and SVG namespace:

segno.make('Up Jumped the Devil').save(buff, kind="svg", xmldecl=False, svgns=False)

Result of buff.getvalue():

<svg width="33" height="33" class="segno"><path[...]</svg>
not2qubit
  • 14,531
  • 8
  • 95
  • 135
1

I was able to do this in my views.py to generate a QR code dynamically.

import segno
from django.views.generic.base import TemplateView

from .models import MyModel

class QRCodeView(TemplateView):
    template_name = "my_template.html"

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        
        param = self.kwargs['param'] # this is how to grab something from the url pattern

        # scale=10 changes size of saved image
        # svg_data_uri (or png_data_uri) is saved in memory and easily put in html <img src='uri'>
        # .make_qr forces a non-micro QR code
        qr_code = segno.make_qr(f"MY {param} DATA").svg_data_uri(scale=10)
        
        context['qrcode'] = qr_code
        return context

Now I can access this in my template.html

<img src="{{ qrcode }}" ...>

I prefer this to using a buffer because there is no need to convert to/from Byte/Image, no other libraries needed.

risaco
  • 11
  • 3