예제 #1
0
def fromJson(json, protoClass):
  """
  Deserialise json into an instance of protobuf class
  """
  try:
    return json_format.Parse(json, protoClass())
  except Exception as e:
    raise BadRequestException(str(e))
예제 #2
0
def _validate_params(subreddit, start, end):
    """
    Checks that all parameters exist and
    that the time interval is correct
    """
    exc = None
    if subreddit is None:
        exc = BadRequestException(message="Missing 'subreddit' parameter")
    elif start is None:
        exc = BadRequestException(message="Missing 'from' parameter")
    elif end is None:
        exc = BadRequestException(message="Missing 'to' parameter")
    elif start > end:
        exc = BadRequestException(message='Time interval is invalid')

    if exc:
        _log.error(str(exc), exc_info=True)
        raise exc
예제 #3
0
def _normalize_params(subreddit, start, end):
    """
    Makes sure that 'subreddit' is low case
    and 'start' and 'end' are floats
    """
    try:
        subreddit = subreddit.lower()
        start = float(start)
        end = float(end)
    except:
        msg = 'Invalid parameters'
        _log.error(msg, exc_info=True)
        raise BadRequestException(msg)
    return subreddit, start, end
예제 #4
0
def filter():
    subreddit = request.args.get("subreddit")
    start = request.args.get("from")
    end = request.args.get("to")
    keyword = request.args.get("keyword")

    subreddit, start, end = _normalize_params(subreddit, start, end)

    _validate_params(subreddit, start, end)

    try:
        items = _db.filter(subreddit, start, end, keyword)
    except:
        _log.error('Unable to query mongo', exc_info=True)
        raise BadRequestException(
            message='Internal server error',
            status_code=500,
        )

    return jsonify(items)
예제 #5
0
    def create(self, request, *args, **kwargs):
        serializer = self.serializer_class(data=request.data)
        serializer.is_valid(raise_exception=True)

        try:
            from_id = request.data[self.from_field]["pk"]
            to_id = request.data[self.to_field]["pk"]
        except:
            raise BadRequestException()

        try:
            from_qs = self.from_model.objects.get(
                pk=from_id, user=request.user.pk
            )
            to_qs = self.to_model.objects.get(pk=to_id, user=request.user.pk)
        except ObjectDoesNotExist:
            raise NotFoundException()

        transaction = self.model_class(**serializer.data)
        setattr(transaction, self.from_field, from_qs)
        setattr(transaction, self.to_field, to_qs)
        transaction.save()

        return Response({"pk": transaction.pk}, status=status.HTTP_201_CREATED)
예제 #6
0
    def searchDataFrames(self, request, from_get=False):
        """
    DataFrame Search Function
    """
        # enforce project level access control by enforcing restrictions on keyspaces
        check_ks = request.get('keyspaceIds', None)
        if check_ks is None or (len(check_ks) == 1
                                and check_ks[0] == unicode('mask-keys')):
            raise BadRequestException(
                "keyspaceIds required when searching dataframes")

        # get proto, validates
        jreq = util.fromJson(json.dumps(request), fs.SearchDataFramesRequest)

        # handle masks, ommitting contents from endpoint
        mask_contents = {"contents": 0}
        mask_keys = None

        # handle filters
        filters = {}
        if len(jreq.dataframe_ids) > 0:
            filters['_id'] = util.getMongoFieldFilter(jreq.dataframe_ids,
                                                      ObjectId,
                                                      from_get=from_get)

        if len(jreq.keyspace_ids) > 0:
            # grab keys mask
            keyspace_ids = jreq.keyspace_ids
            if from_get:
                keyspace_ids = jreq.keyspace_ids[0].split(',')

            mask_keys = util.setMask(keyspace_ids, unicode('mask-keys'),
                                     'keys')

            # process keyspace ids
            if len(keyspace_ids) > 0:
                filters.setdefault('$or', []).append({
                    'major':
                    util.getMongoFieldFilter(keyspace_ids,
                                             ObjectId,
                                             from_get=from_get)
                })
                filters['$or'].append({
                    'minor':
                    util.getMongoFieldFilter(keyspace_ids,
                                             ObjectId,
                                             from_get=from_get)
                })

        if len(jreq.unit_ids) > 0:
            filters.setdefault('$and', []).append({
                'units':
                util.getMongoFieldFilter(jreq.unit_ids,
                                         ObjectId,
                                         from_get=from_get)
            })

        result = self.db.dataframe.find(filters, mask_contents)
        # make proto
        _protoresp = fs.SearchDataFramesResponse(dataframes=[])
        for r in result:
            kmaj_name, kmaj_keys = util.getKeySpaceInfo(
                self.db, r['major'], mask_keys)
            kmin_name, kmin_keys = util.getKeySpaceInfo(
                self.db, r['minor'], mask_keys)

            dataframe = fs.DataFrame(id=str(r['_id']), \
              major=fs.Dimension(keyspace_id=str(r['major']), keys=kmaj_keys), \
              minor=fs.Dimension(keyspace_id=str(r['minor']), keys=kmin_keys), \
              units=[], contents=[])

            for unit in r['units']:
                _unit = self.db.units.find_one({'_id': unit})
                dataframe.units.extend([fs.Unit(name=_unit['name'], \
                                                description=_unit['description'], \
                                                id=str(_unit['_id']))])

            _protoresp.dataframes.extend([dataframe])

            return util.toFlaskJson(_protoresp)
예제 #7
0
    def sliceDataFrame(self, request, transpose=False):

        # inits
        vec_filters = {}

        # validate request
        jreq = util.fromJson(request, fs.SliceDataFrameRequest)

        if not jreq.dataframe_id:
            raise BadRequestException(
                "dataframeId is required for sliceDataFrame")

        # first request to get dataframe
        result = self.db.dataframe.find_one(
            {"_id": ObjectId(str(jreq.dataframe_id))})

        if result is None:
            raise DataFrameNotFoundException(jreq.dataframe_id)

        # prep vector query
        vc = result.get('contents', [])

        # save page end for later check
        page_end = int(jreq.page_end)
        # if page start is outside of dataframe length, return empty
        if jreq.page_start > len(vc):
            dataframe = {"id": str(result["_id"]), \
                       "major": {"keyspaceId": str(result['major']), "keys": []}, \
                       "minor": {"keyspaceId": str(result['minor']), "keys": []}, \
                       "contents": []}
            return util.buildResponse(dataframe)

        elif jreq.page_end > len(vc) or len(
                jreq.new_minor.keys) > 0 or jreq.page_end == 0:
            jreq.page_end = len(vc)

        # construct vector filters
        vec_filters["_id"] = {"$in": vc[jreq.page_start:jreq.page_end]}

        if not transpose:
            kmaj_keys = self.setDimensionFilters(jreq.new_major.keys,
                                                 jreq.new_minor.keys,
                                                 vec_filters)
        else:
            kmaj_keys = self.setDimensionFilters(jreq.new_minor.keys,
                                                 jreq.new_major.keys,
                                                 vec_filters)

        # seconrd query to backend to get contents
        vectors = self.db.vector.find(vec_filters, kmaj_keys)
        vectors.batch_size(1000000)
        # construct response

        contents = {vector["key"]: vector["contents"] for vector in vectors}
        if transpose:
            # this is the overhead
            d = pd.DataFrame.from_dict(contents, orient="index")
            contents = d.to_dict()

        # avoid invalid keys passing through to keys
        # explore impacts on response time
        kmaj_keys = []
        if len(jreq.new_major.keys) > 0:
            kmaj_keys = contents[contents.keys()[0]].keys()
        # return keys in dimension,
        # if the whole dimension is not returned
        kmin_keys = []
        # if len(jreq.new_minor.keys) > 0 or page_end < len(vc):
        if len(jreq.new_minor.keys) > 0 or page_end == 0:
            kmin_keys = contents.keys()

        dataframe = {"id": str(result["_id"]), \
                     "major": {"keyspaceId": str(result['major']), "keys": kmaj_keys}, \
                     "minor": {"keyspaceId": str(result['minor']), "keys": kmin_keys}, \
                     "contents": contents}

        return util.buildResponse(dataframe)