Proof of Concept #1: QRNG Web Application

Interested in learning how to program quantum computers? Then check out our Qiskit textbook Introduction to Quantum Computing with Qiskit.

Proof of Concept is a new exciting tutorial series that will show you how to create quantum applications step by step.

Introduction

In this tutorial we will create a web application that allows users to generate random numbers using IBM’s quantum devices. This web application will consist of a backend and frontend.

For the frontend we will use a bootstrap site consisting of HTML/CSS and JavaScript

For the backend we will use Django as the webservice and the Qiskit quantum framework.

2021-01-29 15_25_55-Window.png

Step 1: Install Django and Qiskit

If you don’t have Django and Qiskit then open up your terminal and enter the following:

To install Django type in:

pip install Django==3.1.5

To install Qiskit type in:

pip install qiskit

Step 2: Setting up the Django project

Now that we have django installed we need to setup the project that will contain the webservice. In your terminal point to the directory you wish to put the project and type in the following:

django-admin startproject qsite

After this the project folder will be created named qsite with the following structure:

qsite/     manage.py     qsite/         __init__.py         settings.py         urls.py         asgi.py         wsgi.py

Next cd in to the outer qsite directory (the directory with manage.py) and type in the following:

python manage.py runserver

Then go to your web browser and enter localhost:8000 and you will get the following:

2021-01-10 15_14_57-Window.png

Congratulations! Your server has been setup successfully.

Step 3: Setup the QRNG app

Now that the project has been setup we now need to create the QRNG app.

In Django the project is basically a container for an application. So in our case qsite is the project that will contain our QRNG application. You can have multiple applications in each project.

To setup the QRNG app type in to the terminal:

python manage.py startapp qrng

This will create a new folder called qrng with the following structure:

qrng/     __init__.py     admin.py     apps.py     migrations/         __init__.py     models.py     tests.py     views.py

Next we will need to add the QRNG code in to views.py:

from django.http import JsonResponse
from django.shortcuts import render
import json

from qiskit import QuantumRegister, ClassicalRegister, QuantumCircuit, execute, IBMQ
from qiskit.tools.monitor import job_monitor

IBMQ.enable_account('ENTER API KEY HERE')
provider = IBMQ.get_provider(hub='ibm-q')

def home(request):
    return render(request, 'index.html', {})

def random(request):

    print(request.body)

    body_unicode = request.body.decode('utf-8')
    body = json.loads(body_unicode);

    device = body['device']

    min = int(body['min'])
    max = int(body['max'])

    backend = provider.get_backend(device)

    if device == "ibmq_qasm_simulator":
        num_q = 32
    else:
        num_q = 5

    q = QuantumRegister(num_q, 'q')
    c = ClassicalRegister(num_q, 'c')

    circuit = QuantumCircuit(q, c)
    circuit.h(q)  # Applies hadamard gate to all qubits
    circuit.measure(q, c)  # Measures all qubits


    job = execute(circuit, backend, shots=1)

    print('Executing Job...\n')
    job_monitor(job)
    counts = job.result().get_counts()

    print('RESULT: ', counts, '\n')
    print('Press any key to close')

    result = int(counts.most_frequent(), 2)

    result1 = min + result % (max+1 - min)

    print(result1)

    response = JsonResponse({'result': result1})
    return response

Note: In the code you will see a line called IBMQ.enable_account('ENTER API KEY HERE'). This is where you need to put in an API token. In order to get an API key you will have to register to the IBM quantum experience: https://quantum-computing.ibm.com

Now in the qrng directory we will need to create a file called urls.py. This file will contain all the url endpoints for our application.

Once created enter the following code:

from django.urls import path
from qrng import views

urlpatterns = [
    path('',  views.home, name='home'),
    path('random/', views.random)]


Here we have two url patterns:

  • path('', views.home, name='home') which will serve the web application to the user when they browse to localhost:8000 in their browser

  • path('random/', views.random) which will point to our QRNG code (in views.random) and send a random number generated by IBMs quantum devices to the user in the web application

Now in qsite/urls.py enter the following code:

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('qrng.urls'))
]

In qsite/settings.py add ‘qrng’ to the list of installed apps such that it looks like this:

INSTALLED_APPS = [

'django.contrib.admin',

'django.contrib.auth',

'django.contrib.contenttypes',

'django.contrib.sessions',

'django.contrib.messages',

'django.contrib.staticfiles',

'qrng'

]


Next in qsite/settings.py replace ROOT_URLCONF = 'qsite.urls' to:

ROOT_URLCONF = 'qrng.urls'

Next in qsite/settings.py under MIDDLEWARE get rid of 'django.middleware.csrf.CsrfViewMiddleware',

Step 4: Create the Website

Now we need to create the website that will server as the frontend. The website will be a simple bootstrap site that will allow the user to do the following things:

1.) Pick a quantum device to use to generate a random number

2.) Pick the minimum and maximum number that can be generated by the device

3.) A button called Generate that will call a script which in turn will send a request to ‘random/’ which will contain json data for the target device and minimum and maximum value for the generated number.

4.) A loading animation that will run while the request is being processed

To implement the site we will need to create a folder called templates within the qrng directory. Then within the templates folder add a file called index.html.

Within index.html enter the following code:

<!DOCTYPE html>
<html lang="en">
   <head>
      <meta charset="utf-8">
      <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
      <meta name="description" content="">
      <meta name="author" content="">
      <title>Quantum Random Number Generator</title>
      <!-- Bootstrap core CSS -->
      <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">
      <!-- Custom styles for this template -->
      <link href="css/business-frontpage.css" rel="stylesheet">
      <script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
   </head>
   <body>
      <script>
         function generate() {
           console.log("REQUEST SUCCEEDED");
           document.getElementById("loader").style.display = "block";
           document.getElementById("loader").style.visibility = "visible";
           document.getElementById("keyHeader").innerHTML = "";
           document.getElementById("keyView").innerHTML = "";
         
         targetDevice = document.getElementById("devices").value
         
         min = document.getElementById("min").value
         max = document.getElementById("max").value
         
         data = JSON.stringify({ device: targetDevice,min:min, max:max});
         
         $.ajax({
         type: "POST",
         url: "http://localhost:8000/random/",
         contentType: "application/json; charset=utf-8",
         data: data,
         success: function(d){
           console.log(d);
           document.getElementById("loader").style.display = "none";
           document.getElementById("loader").style.visibility = "hidden";
           document.getElementById("keyHeader").innerHTML = "Result:";
           document.getElementById("keyView").innerHTML = d['result'];
           }
         });
         }
      </script>
      <style>
         .loader,
         .loader:before,
         .loader:after {
         border-radius: 50%;
         width: 2.5em;
         height: 2.5em;
         -webkit-animation-fill-mode: both;
         animation-fill-mode: both;
         -webkit-animation: load7 1.8s infinite ease-in-out;
         animation: load7 1.8s infinite ease-in-out;
         }
         .loader {
         visibility:hidden;
         display:none;
         color: #0277bd;
         font-size: 10px;
         margin: 80px auto;
         position: relative;
         text-indent: -9999em;
         -webkit-transform: translateZ(0);
         -ms-transform: translateZ(0);
         transform: translateZ(0);
         -webkit-animation-delay: -0.16s;
         animation-delay: -0.16s;
         }
         .loader:before,
         .loader:after {
         content: '';
         position: absolute;
         top: 0;
         }
         .loader:before {
         left: -3.5em;
         -webkit-animation-delay: -0.32s;
         animation-delay: -0.32s;
         }
         .loader:after {
         left: 3.5em;
         }
         @-webkit-keyframes load7 {
         0%,
         80%,
         100% {
         box-shadow: 0 2.5em 0 -1.3em;
         }
         40% {
         box-shadow: 0 2.5em 0 0;
         }
         }
         @keyframes load7 {
         0%,
         80%,
         100% {
         box-shadow: 0 2.5em 0 -1.3em;
         }
         40% {
         box-shadow: 0 2.5em 0 0;
         }
         }
      </style>
      <header class="bg-dark py-5 mb-5">
         <div class="container h-100">
            <div class="row h-100 align-items-center">
               <div class="col-lg-12">
                  <h1 class="display-4 text-white mt-5 mb-2">Quantum Random Number Generator</h1>
               </div>
            </div>
         </div>
      </header>
      <div class="container">
         <div class="row">
            <div class="col-md-8 mb-5">
               <h2>Pick a device and click generate</h2>
               <hr>
               <span>
                  <label>Pick a quantum device:</label>
                  <select name="devices" id="devices">
                     <option value="ibmq_qasm_simulator">ibmq_qasm_simulator (32 qubits)</option>
                     <option value="ibmq_16_melbourne">ibmq_16_melbourne (15 qubits)</option>
                     <option value="ibmqx2">ibmq_5_yorktown (5 qubits)</option>
                     <option value="ibmq_ourense">ibmq_ourense (5 qubits)</option>
                     <option value="ibmq_vigo">ibmq_vigo (5 qubits)</option>
                     <option value="ibmq_valencia">ibmq_valencia (5 qubits)</option>
                  </select>
               </span>
               <br><br>
               <label>Min:</label>
               <input type="text" id="min" name="min" value="0"><br>
               <label>Max:</label>
               <input type="text" id="max" name="max" value="100"><br><br>
               <div id="loader" class="loader"></div>
               <p id="keyHeader"></p>
               <strong>
                  <p id="keyView"></p>
               </strong>
               <button class="btn btn-primary"  onclick="generate();">Generate &raquo;</button>
            </div>
         </div>
      </div>
      <footer class="bg-dark py-5">
         <div class="container">
            <p class="m-0 text-center text-white">Copyright &copy; Quantum Computing UK 2020</p>
         </div>
      </footer>
   </body>
</html>

After this open index.html in your browser and it should look something like this:

2021-01-10 21_19_58-Window.png

Now click Generate and it should generate a random number from whatever quantum device you have chosen.

Make sure you have the django webservice running by entering: python manage.py runserver in to your terminal.

Note: Depending on the device it may take a while as there may be a queue.

2021-01-29 15_25_55-Window.png

Congratulations! You have created your first quantum application. Later in the proof of concept series you will learn how to create more complex and useful applications.