<commit_before>import logging
import random
from flask import Flask, request, abort, jsonify, make_response
from flask.ext.sqlalchemy import SQLAlchemy, DeclarativeMeta
from json import JSONEncoder

logger = logging.getLogger(__name__)


class ProductJSONEncoder(JSONEncoder):
    def default(self, obj):
        if isinstance(obj.__class__, DeclarativeMeta):
            return obj.to_dict()
        return super(ProductJSONEncoder, self).default(obj)


app = Flask(__name__)
app.json_encoder = ProductJSONEncoder

user = 'postgress'
password = '<PASSWORD>'
host = 'localhost'
port = '5432'
dbname = 'timeseries'
url = 'postgresql://{}:{}@{}:{}/{}'
url = url.format(user, password, host, port, dbname)
app.config['SQLALCHEMY_DATABASE_URI'] = url  # 'sqlite:////tmp/tasks.db'
db = SQLAlchemy(app)


class TimeseriesEntry(db.Model):
    __tablename__ = 'timeseries'

    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    blarg = db.Column(db.Float, nullable=False)
    level = db.Column(db.String(1), nullable=False)
    mean = db.Column(db.Float, nullable=False)
    std = db.Column(db.Float, nullable=False)
    fpath = db.Column(db.String(80), nullable=False)

    def __repr__(self):
        return '<ID %r>' % self.id

    def to_dict(self):
        return dict(id=self.id, blarg=self.blarg, level=self.level, mean=self.mean, std=self.std, fpath=self.fpath)


@app.route('/timeseries', methods=['GET'])
def get_all_metadata():
    if 'mean_in' in request.args:
        mean_in = request.args.get('mean_in')
        # Do query
        mean_range=mean_in.split('-')
        query=db.session.query.filter(db.mean >= float(mean_range[0]) & db.mean < float(mean_range[1]))
    logger.info('Getting all TimeseriesEntries')
    return jsonify(dict(tasks=TimeseriesEntry.query.all()))


@app.route('/timeseries', methods=['POST'])
def create_entry():
    if not request.json:
        abort(400)
    logger.info('Creating TimeseriesEntry')
    blarg = random.random()
    level = random.choice(["A","B","C","D","E","F"])
    #save to file and get fpath (replace with storage manager)
    fpath=""
    #Create timeseries object from json
    #get mean and std
    mean=0
    std=0
    prod = TimeseriesEntry(blarg=blarg, level=level, mean=mean, std=std, fpath=fpath)
    db.session.add(prod)
    db.session.commit()
    return jsonify({'op': 'OK', 'task': prod}), 201

@app.route('/timeseries/<int:timeseries_id>', methods=['GET'])
def get_timeseries_by_id(timeseries_id):
    ts = TimeseriesEntry.query.filter_by(id=timeseries_id).first()
    if ts is None:
        logger.info('Failed to get TimeseriesEntry with id=%s', timeseries_id)
        abort(404)
    logger.info('Getting TimeseriesEntry with id=%s', timeseries_id)<commit_msg>Add documentation for website PostGres table and flesh out /timeseries endpoint<commit_after>import logging
import random
from flask import Flask, request, abort, jsonify, make_response
from flask.ext.sqlalchemy import SQLAlchemy, DeclarativeMeta
from json import JSONEncoder

logger = logging.getLogger(__name__)


class ProductJSONEncoder(JSONEncoder):
    def default(self, obj):
        if isinstance(obj.__class__, DeclarativeMeta):
            return obj.to_dict()
        return super(ProductJSONEncoder, self).default(obj)


app = Flask(__name__) # Create an instance of the Flask web server
app.json_encoder = ProductJSONEncoder

# Set up PostGres database
user = 'postgress'
password = '<PASSWORD>'
host = 'localhost'
port = '5432'
dbname = 'timeseries'
url = 'postgresql://{}:{}@{}:{}/{}'
url = url.format(user, password, host, port, dbname)
app.config['SQLALCHEMY_DATABASE_URI'] = url  # 'sqlite:////tmp/tasks.db' # NEEDS FIXING
db = SQLAlchemy(app)


class TimeseriesEntry(db.Model):
    """A single timeseries dataset in the timeseries database.
        Contains the following columns:
            id - int - The unique identifier of the timeseries (generated by SQL)
            blarg - float - A random metadata value sampled from [0,1]
            level - char - Randomly selected letter between A and F
            mean - float - Average value of the timeseries
            std - float - Standard deviation of the timeseries
            fpath - string - File path to the time series file (NEEDS TO BE REPLACED WITH STORAGE MANAGER)
    """
    __tablename__ = 'timeseries'

    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    blarg = db.Column(db.Float, nullable=False)
    level = db.Column(db.String(1), nullable=False)
    mean = db.Column(db.Float, nullable=False)
    std = db.Column(db.Float, nullable=False)
    fpath = db.Column(db.String(80), nullable=False)

    def __repr__(self):
        return '<ID %d, blarg %f, level %s>' % (self.id, self.blarg, self.level)

    def to_dict(self):
        return dict(id=self.id, blarg=self.blarg, level=self.level, mean=self.mean, std=self.std, fpath=self.fpath)

def get_floating_range(range_str):
    if "-" not in range_str:
        raise Exception("Invalid input range: %s" % range_str)
    range_components = range_str.split('-')
    if len(range_components) != 2:
        raise Exception("Found too many range indications in: %s" % range_str)
    return float(range_components[0]), float(range_components[1])

@app.route('/timeseries', methods=['GET'])
def get_all_metadata():
    """/timeseries endpoint
        Defines two API calls:
            * /timeseries GET - Return a JSON containing metadata info from all timeseries
            * /timeseries?request=value(s) - Return timeseries that match the request. Valid requests are:
                + blarg_in=lower-upper - Get data with a blarg that falls within the floating point range
                + level_in=X,Y - Get data that contains one of the comma separated letters
                + mean_in=lower-upper - Get data with a mean that falls within the floating point range
                + std_in=lower-upper - Get data with a std that falls within the floating point range
    """
    if 'blarg_in' in request.args:
        logger.debug("Getting entries by blarg value")
        lower, upper = get_floating_range(request.args.get('blarg_in'))
        results = db.session.query(TimeseriesEntry).\
            filter(TimeseriesEntry.blarg >= lower).\
            filter(TimeseriesEntry.blarg < upper)
    elif 'level_in' in request.args:
        logger.debug("Getting entries by level value")
        levels = request.args.get('mean_in').split(",")
        results = db.session.query(TimeseriesEntry).\
            filter(TimeseriesEntry.level.in_(levels))
    elif 'mean_in' in request.args:
        logger.debug("Getting entries by mean value")
        lower, upper = get_floating_range(request.args.get('mean_in'))
        results = db.session.query(TimeseriesEntry).\
            filter(TimeseriesEntry.mean >= lower).\
            filter(TimeseriesEntry.mean < upper)
    elif 'std_in' in request.args:
        logger.debug("Getting entries by std value")
        lower, upper = get_floating_range(request.args.get('std_in'))
        results = db.session.query(TimeseriesEntry).\
            filter(TimeseriesEntry.std >= lower).\
            filter(TimeseriesEntry.std < upper)
    else:
        logger.info("Getting all TimeseriesEntries")
        results = db.session.query(TimeseriesEntry).all()
    return jsonify(dict(timeseries=results))


@app.route('/timeseries', methods=['POST'])
def create_entry():
    if not request.json:
        abort(400)
    logger.info('Creating TimeseriesEntry')
    blarg = random.random()
    level = random.choice(["A","B","C","D","E","F"])
    #save to file and get fpath (replace with storage manager)
    fpath=""
    #Create timeseries object from json
    #get mean and std
    mean=0
    std=0
    prod = TimeseriesEntry(blarg=blarg, level=level, mean=mean, std=std, fpath=fpath)
    db.session.add(prod)
    db.session.commit()
    return jsonify({'op': 'OK', 'task': prod}), 201

@app.route('/timeseries/<int:timeseries_id>', methods=['GET'])
def get_timeseries_by_id(timeseries_id):
    ts = TimeseriesEntry.query.filter_by(id=timeseries_id).first()
    if ts is None:
        logger.info('Failed to get TimeseriesEntry with id=%s', timeseries_id)
        abort(404)
    logger.info('Getting TimeseriesEntry with id=%s', timeseries_id)
{'fraction_non_alphanumeric': 0.12522598529589007, 'fraction_numerical': 0.005182596119079185, 'mean_word_length': 3.495124593716143, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, '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': '4083794', 'n_tokens_mistral': 2615, 'n_tokens_neox': 2539, 'n_words': 656}