<commit_before>import sys
import subprocess
import json
import logging
import requests
from binascii import a2b_base64
from uuid import uuid4
from flask import Flask, render_template, request, redirect, session, Response, url_for

from config import config


app = Flask(__name__)
app.secret_key = config['APP_SECRET_KEY']
app.config['SECRET_KEY'] = config['APP_SECRET_KEY']
SECRET_KEY = config['APP_SECRET_KEY']

# So it logs Flask errors to stdout - nice for Heroku logs and CI if used
app.logger.addHandler(logging.StreamHandler(sys.stdout))
app.logger.setLevel(logging.ERROR)


@app.route('/')
def index():
    return render_template('index.html')

@app.route('/img_handler', methods=['POST'])
def img_handler():
    """
    - Grabs the binary data from the WebRTC still grab attached to POST
    - WebRTC is intuitive--unicode or ASCII byte-encodings not-so-much.
      Manipulates the unicode that Python gets from the POST request form dictionary
      and turns it into the appropriate ASCII byte-encoding, which is then base-64-decoded,
      and then piped into a random UUID-named .png file.
    - As a hack, I used sshfs to mount the public_html directory of my UT Austin CS account address
      into my working dir, and sent the new .png files into that folder, chmodding per upload.
    - This renders the image into a resource that's easily accessible by APIs.
      (Although this obviously won't scale, I only have 2 GB as an undergrad.)
    - Finally, sends the URL via POST to the Microsoft Emotions API
    - tl;dr I changed an image data-uri to a publicly available URL so it'd play better with some
      ML libraries that didn't have native Python clients, but did have RESTful APIs.
    """
    data = request.form.get('stillIn')
    data = data[22:].encode('latin-1')
    binary_data = a2b_base64(data)
    fn = str(uuid4()) + ".png"
    with open('./models/mount/{}'.format(fn), 'wb') as fd:
        fd.write(binary_data)
    subprocess.call("chmod 755 ./models/mount/{}".format(fn),
                    shell=True)
    resource = "http://cs.utexas.edu/~rainier/{}".format(fn)
    url = "https://api.projectoxford.ai/emotion/v1.0/recognize"
    headers = {'Ocp-Apim-Subscription-Key': config['MSFT_EMOTION_KEY'],
               'Content-Type': 'application/json'}
    print json.dumps({'url': resource})
    req = requests.post(url=url, data=json.dumps({'url': resource}), headers=headers)
    return str(req.json())

def test_img_handler_msft():
    """Tests the image handler
    """
    pass

def test_img_handler_indicoio():
    """Tests the image handler
    """
    pass

def test_img_handler_clarifai():
    """Tests the image handler
    """
    pass


if __name__ == '__main__':
    app.run(debug=True, host='0.0.0.0', port=5000)
<commit_msg>Implement indico and clarifai API interactions<commit_after>import os
import sys
import subprocess
import json
import logging
import requests
import indicoio
from clarifai.client import ClarifaiApi
from binascii import a2b_base64
from uuid import uuid4
from flask import Flask, render_template, request, redirect, session, Response, url_for

from config import config


app = Flask(__name__)
app.secret_key = config['APP_SECRET_KEY']
app.config['SECRET_KEY'] = config['APP_SECRET_KEY']
SECRET_KEY = config['APP_SECRET_KEY']

# So it logs Flask errors to stdout - nice for Heroku logs and CI if used
app.logger.addHandler(logging.StreamHandler(sys.stdout))
app.logger.setLevel(logging.ERROR)

# Indico set-up
indicoio.config.api_key = config['INDICO_KEY']

# Clarifai set-up
os.environ['CLARIFAI_APP_ID'] = config['CLARIFAI_ID']
os.environ['CLARIFAI_APP_SECRET'] = config['CLARIFAI_SECRET']

@app.before_first_request
def setup_session_dicts():
    session['msft'] = {}
    session['indico'] = {}
    session['clarifai'] = {}

@app.route('/')
def index():
    return render_template('index.html')

@app.route('/img_handler', methods=['POST'])
def img_handler():
    """
    - Grabs the binary data from the WebRTC still grab attached to POST
    - WebRTC is intuitive--unicode or ASCII byte-encodings not-so-much.
      Manipulates the unicode that Python gets from the POST request form dictionary
      and turns it into the appropriate ASCII byte-encoding, which is then base-64-decoded,
      and then piped into a random UUID-named .png file.
    - As a hack, I used sshfs to mount the public_html directory of my UT Austin CS account address
      into my working dir, and sent the new .png files into that folder, chmodding per upload.
    - This renders the image into a resource that's easily accessible by APIs.
      (Although this obviously won't scale, I only have 2 GB as an undergrad.)
    - Finally, sends the URL via POST to the Microsoft Emotions API
    - tl;dr I changed an image data-uri to a publicly available URL so it'd play better with some
      ML libraries that didn't have native Python clients, but did have RESTful APIs.
    """
    data = request.form.get('stillIn')
    data = data[22:].encode('latin-1')
    binary_data = a2b_base64(data)
    fn = str(uuid4()) + ".png"
    with open('./models/mount/{}'.format(fn), 'wb') as fd:
        fd.write(binary_data)
    subprocess.call("chmod 755 ./models/mount/{}".format(fn),
                    shell=True)
    resource = "http://cs.utexas.edu/~rainier/{}".format(fn)
    print json.dumps({'url': resource})

    # msft request
    msft_url = "https://api.projectoxford.ai/emotion/v1.0/recognize"
    headers = {'Ocp-Apim-Subscription-Key': config['MSFT_EMOTION_KEY'],
               'Content-Type': 'application/json'}
    msft_req = requests.post(url=msft_url, data=json.dumps({'url': resource}), headers=headers)
    session['msft'] = msft_parse(msft_req.json())

    # indicoio request
    session['indico'] = indicoio.fer(resource)

    # clarifai request
    clarifai_api = ClarifaiApi()
    clarifai_req = clarifai_api.tag_image_urls(resource)
    session['clarifai'] = clarifai_parse(clarifai_req)

    return str(session['msft']) + '\n\n' + str(session['indico']) + '\n\n' + str(session['clarifai'])

def msft_parse(json_obj):
    """Parses the Microsoft Emotions API data into an useful dictionary
    {
      "anger": 2.0591775E-05,
      "contempt": 0.0148894591,
      "disgust": 0.000142300632,
      "fear": 5.71208257E-05,
      "happiness": 0.00071732566,
      "neutral": 0.9721336,
      "sadness": 0.0119813038,
      "surprise": 5.831113E-05
    }
    """
    return json_obj[0]['scores']

# def indico_parse(json_obj):
#     """Parses the Indicoio API data into an useful dictionary
#        Not needed.
#     """
#     pass

def clarifai_parse(json_obj):
    """Parses the Clarifai API data into an useful list
    """
    probabilities = json_obj['results'][0]['result']['tag']['probs']
    len_over_point_nine_five = len([prob for prob in probabilities if prob >= 0.95])
    classes_of_interest = json_obj['results'][0]['result']['tag']['classes'][0:len_over_point_nine_five]
    return classes_of_interest

def test_img_handler_msft():
    """Tests the msft image handler
    """
    pass

def test_img_handler_indicoio():
    """Tests the indicoio image handler
    """
    pass

def test_img_handler_clarifai():
    """Tests the clarifai image handler
    """
    pass


if __name__ == '__main__':
    app.run(debug=True, host='0.0.0.0', port=5000)

{'fraction_non_alphanumeric': 0.11942740286298568, 'fraction_numerical': 0.01990456714383095, 'mean_word_length': 3.675589547482473, 'pattern_counts': {'":': 8, '<': 3, '<?xml version=': 0, '>': 4, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 2, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6750643', 'n_tokens_mistral': 2496, 'n_tokens_neox': 2348, 'n_words': 688}