<commit_before>#!/usr/bin/python
import logging
import json
import cStringIO
import requests
import ipfsApi
from flask import Flask, request, g
from flask import Response, jsonify, render_template, stream_with_context
from flask_restplus import Api, Resource

app = Flask(__name__, static_url_path="")
logging.basicConfig(level=logging.DEBUG)


@app.before_request
def connect_to_ipfs():
    g.ipfs = ipfsApi.Client("ipfs", 5001)


@app.route("/")
@app.route("/stewards.html")
def stewards():
    return render_template("stewards.html", title="Stewards")


@app.route("/steward.html")
def steward():
    return render_template("steward.html", title="Steward")


@app.route("/submission.html")
def submission():
    return render_template("submission.html", title="Submission")


@app.route("/add.html")
def add():
    return render_template("add.html", title="Add")


@app.route("/data/<string:multihash>")
def ipfs(multihash):
    """
    Proxy requests for ipfs. This should only be used for debugging.
    In production a proper reverse proxy should pass ipfs requests directly
    to the ipfs daemon.
    """
    req = requests.get("http://ipfs:8080/ipfs/{}".format(multihash), stream=True)
    return Response(stream_with_context(req.iter_content()),
                    content_type=req.headers['content-type'])


"""
IPNS helpers to resolve, get and update steward index files

REMIND: Probably need to implement a lock so that only one process/thread
can update at a time.
"""


def resolve_steward(address=None):
    """
    Resolve ipns address to multihash. If address is None resolve this
    steward's address locally.
    """
    logging.debug("Resolving {}...".format(address if address else
                                           g.ipfs.id()["ID"]))
    # If resolving self use local so we get latest, otherwise will
    # use cache for other servers
    multihash = g.ipfs.name_resolve(address if address else g.ipfs.id()["ID"],
                                    opts={'local': address is None})["Path"].rsplit('/')[-1]
    logging.debug("... to {}".format(multihash))
    return multihash


def get_steward(address=None):
    """
    Return the steward's index. If address is None return this steward's index.
    """
    return json.loads(g.ipfs.cat(resolve_steward(address)))


def update_steward(steward):
    """
    Add steward record to ipfs and publish this multihash against the steward's
    address.
    """
    steward_multihash = g.ipfs.add(
        cStringIO.StringIO(json.dumps(steward)))[1]['Hash']
    g.ipfs.name_publish(steward_multihash)
    logging.debug("Published {} to {}".format(steward_multihash,
                                              g.ipfs.id()["ID"]))

"""
RESTful API
"""
api = Api(app, version="v0", title="Cancer Gene Trust API", doc="/api",
          description="""
          RESTful API for the Cancer Gene Trust Daemon (cgtd)

          Note that most operations involve validating public keys, signing, and
          publishing the updated signature to other stewards. As a result some
          operations can take several seconds if the cached resolution from pki
          to multihash has expired.
          """)


@api.route("/v0/")
class API(Resource):

    def get(self):
        """
        Return steward index
        If address is missing return this stewards index.
        """
        return get_steward()


@api.route("/v0/peers/<string:address>")
class PeersAPI(Resource):

    def post(self, address):
        """<commit_msg>Fix REST documentation header formatting<commit_after>#!/usr/bin/python
import logging
import json
import cStringIO
import requests
import ipfsApi
from flask import Flask, request, g
from flask import Response, jsonify, render_template, stream_with_context
from flask_restplus import Api, Resource

app = Flask(__name__, static_url_path="")
logging.basicConfig(level=logging.DEBUG)


@app.before_request
def connect_to_ipfs():
    g.ipfs = ipfsApi.Client("ipfs", 5001)


@app.route("/")
@app.route("/stewards.html")
def stewards():
    return render_template("stewards.html", title="Stewards")


@app.route("/steward.html")
def steward():
    return render_template("steward.html", title="Steward")


@app.route("/submission.html")
def submission():
    return render_template("submission.html", title="Submission")


@app.route("/add.html")
def add():
    return render_template("add.html", title="Add")


@app.route("/data/<string:multihash>")
def ipfs(multihash):
    """
    Proxy requests for ipfs. This should only be used for debugging.
    In production a proper reverse proxy should pass ipfs requests directly
    to the ipfs daemon.
    """
    req = requests.get("http://ipfs:8080/ipfs/{}".format(multihash), stream=True)
    return Response(stream_with_context(req.iter_content()),
                    content_type=req.headers['content-type'])


"""
IPNS helpers to resolve, get and update steward index files

REMIND: Probably need to implement a lock so that only one process/thread
can update at a time.
"""


def resolve_steward(address=None):
    """
    Resolve ipns address to multihash. If address is None resolve this
    steward's address locally.
    """
    logging.debug("Resolving {}...".format(address if address else
                                           g.ipfs.id()["ID"]))
    # If resolving self use local so we get latest, otherwise will
    # use cache for other servers
    multihash = g.ipfs.name_resolve(address if address else g.ipfs.id()["ID"],
                                    opts={'local': address is None})["Path"].rsplit('/')[-1]
    logging.debug("... to {}".format(multihash))
    return multihash


def get_steward(address=None):
    """
    Return the steward's index. If address is None return this steward's index.
    """
    return json.loads(g.ipfs.cat(resolve_steward(address)))


def update_steward(steward):
    """
    Add steward record to ipfs and publish this multihash against the steward's
    address.
    """
    steward_multihash = g.ipfs.add(
        cStringIO.StringIO(json.dumps(steward)))[1]['Hash']
    g.ipfs.name_publish(steward_multihash)
    logging.debug("Published {} to {}".format(steward_multihash,
                                              g.ipfs.id()["ID"]))

"""
RESTful API
"""
api = Api(app, version="v0", title="Cancer Gene Trust API", doc="/api",
          description="""
RESTful API for the Cancer Gene Trust Daemon (cgtd)

Note that most operations involve validating public keys, signing, and
publishing the updated signature to other stewards. As a result some
operations can take several seconds if the cached resolution from pki
to multihash has expired.
          """)


@api.route("/v0/")
class API(Resource):

    def get(self):
        """
        Return steward index
        If address is missing return this stewards index.
        """
        return get_steward()


@api.route("/v0/peers/<string:address>")
class PeersAPI(Resource):

    def post(self, address):
        """
{'fraction_non_alphanumeric': 0.12380271622587563, 'fraction_numerical': 0.003716940671908506, 'mean_word_length': 3.2068550811785927, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 10, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '184087', 'n_tokens_mistral': 2113, 'n_tokens_neox': 2044, 'n_words': 600}