OEViz - A Simple Depiction Web Service

Problem

You want to generate OEDepict images from SMILES using your web browser. This examples works in Python 2 & 3.

Ingredients

Difficulty Level

../_images/chilly.png ../_images/chilly.png

Solution

Flask is a web microframework for Python. It allows you to create a web server with ease. Using Flask and OEDepict TK we can generate images based on input from a web page. This simple example has a single web page built using Bootstrap and JavaScript to update the image after every keystroke. From within Flask we generate images like you normally do with Python.

Usage:

The code for this example is on GitHub, as it requires multiple files. You must clone the code from https://github.com/oess/python-cookbook-simple-oeviz/. Learn more about GitHub here. From the command line run:

prompt > git clone https://github.com/oess/python-cookbook-simple-oeviz/

After cloning you should create a Python virtualenv environment which includes the OpenEye Python Toolkit and Flask. Flask can be installed with pip install flask. Finally start the Flask web server:

(myvirtualenv) prompt > python simpe-oeviz.py

Now visit http://127.0.0.1:5000 with your browser and enter a SMILES string to visualize it.

../_images/simple-oeviz.png

Discussion

OERenderMolecule writes a file, this is not required on a web server, as writing and then reading the file adds an unnecessary step. Instead you build your image up then write it to a string using OEWriteImageToString then return this directly to the browser with a MIME type and it will render the file for you.

There are two main functions in simple-oeviz.py. The first is depict() which tells Flask that when someone requests the route of the website, /, to render the template oeviz.html. You can find this file in the templates directory, it is HTML, CSS and JavaScript.

@app.route('/')
def depict():
""" Return a simple HTML file """
return render_template('oeviz.html')

depict_smiles() is where OEDepict TK comes in. When /smiles/<smiles>/ is requested by the browser Flask will call this function. It passes the value of smiles as a variable where OESmilesToMol will attempt to parse the value. If it is a valid SMILES strings we depict the molecule, if it is not we place an error message on the OEImage we have already created. Finally we return this to the browser with MIME information so it knows the data should be treated as an SVG image. You will notice the SMILES string is wrapped with an unquote, this is to escape URL encodings for example # will become %23, which is not valid SMILES notation.

@app.route('/smiles/<smiles>/')
def depict_smiles(smiles):
    """ OEChem and OEDepict image generation """
    # Image to draw on
    image = OEImage(400, 400)

    # Process SMILES
    mol = OEGraphMol()
    parsed = OESmilesToMol(mol, str(unquote(smiles)))

    if parsed:
        # Create image of molecule
        OEPrepareDepiction(mol)
        OERenderMolecule(image, mol)
    else:
        # Create error image
        font = OEFont(OEFontFamily_Helvetica, OEFontStyle_Default, 20,
                      OEAlignment_Center, OERed)
        image.DrawText(OE2DPoint(image.GetWidth()/2.0, image.GetHeight()/2.0),
                       'Your SMILES is not valid', font)

    img_content = OEWriteImageToString('svg', image)

    return Response(img_content, mimetype='image/svg+xml')

We use JavaScript, static/oeviz.js, to listen to the keystrokes in the text box. After each keystroke it sends the contents to the SMILES API and returns the response to the img tag in the HTML, which displays the image to the user, either a valid molecule or an error message.

See also in Flask manual

Theory

API

See also in OEDepict TK manual

Theory

API