示例#1
0
 def sqlalchemy_orders(self, input_sorts):
     criterions = []
     for direction, fieldname in input_sorts:
         attr = getattr(self.db_model, fieldname, None)
         if not attr: raise exceptions.BadRequest("The sort field '{}' is not valid.".format(fieldname), fieldname=fieldname, direction=direction)
         criteria_dict = {
             "+": lambda: attr.asc(),
             "-": lambda: attr.desc()}
         criterions.append(criteria_dict[direction]())
     return criterions
示例#2
0
 def post(self):
     args = self.get_parsed_request_data()
     transaction_keys = ["sender", "receiver", "amount"]
     if not all(key in args for key in transaction_keys):
         raise exceptions.BadRequest(
             "Please include only sender,receiver and amount parameters")
     index = blockchain_list.add_transaction(args.get("sender"),
                                             args.get("receiver"),
                                             args.get("amount"))
     result = {"message": "The Transaction has been successfully added"}
     return jsonify(result)
示例#3
0
 def _create_relation_filter(self, db_model, fieldname, filtername, value):
     rel_name, fieldname = fieldname.split(".",1)
     rel_attr = getattr(db_model, rel_name, None)
     #https://stackoverflow.com/questions/6843144/how-to-find-sqlalchemy-remote-side-objects-class-or-class-name-without-db-queri
     try: rel_db_model = rel_attr.property.mapper.class_
     except: raise exceptions.BadRequest("The filter field '{}' is not valid.".format(rel_name+'.'+fieldname),\
                                         relation_name=rel_name, fieldname=fieldname, filtername=filtername)
     #https://stackoverflow.com/questions/22861960/sqlalchemy-check-if-relationshipproperty-is-scalar
     rel_type = 'scalar' if isinstance(rel_attr.impl, ScalarObjectAttributeImpl) else 'collection'
     query_filter = self._create_filter(rel_db_model, fieldname, filtername, value)
     if rel_type == 'collection': return rel_attr.any(query_filter)
     else:                        return rel_attr.has(query_filter)
示例#4
0
def validate_and_send_email(data: SendData):
    config = configuration.get_config_for_validation(data)
    if config is None:
        raise exceptions.NotFound('Configuration not found for this AppId')
    if config.send_from is None:
        raise exceptions.BadRequest('\"From\" is required')
    if config.send_to is None or not config.send_to:
        raise exceptions.BadRequest('\"To\" is required')
    if config.subject is None:
        raise exceptions.BadRequest('\"Subject\" is required')
    if config.template is None:
        raise exceptions.BadRequest('\"Template\" is required')
    for field in config.required_vars:
        if field not in data.request_data:
            raise exceptions.BadRequest('\"%s\" is required' % field)

    if config.confirm:
        if data.confirm is None:
            raise exceptions.BadRequest('\"Confirm\" address is required')
        id = SenderStorageService.store_data(data,
                                             CONFIRMATION_EXPIRATION_SECS)
        deliver_confirmation(id)
    else:
        id = SenderStorageService.store_data(data)
        deliver_email(id)
    return config
示例#5
0
 def post(self):
     args = self.get_parsed_request_data()
     node_addresses = args.get("nodes")
     if not node_addresses:
         for node in node_addresses:
             blockchain_list.add_node(node)
     else:
         raise exceptions.BadRequest(
             "Please enter some node addresses in the request list")
     result = {
         "message": "The nodes were successfully added",
         "nodes": list(blockchain_list.nodes)
     }
     return jsonify(result)
示例#6
0
 def select_fields(self, raw_response_data, exclude=None, many=False):
     """:feild selection:
     Fields in the response can be pre-selected by passing the feilds agrument in the query string
     /api/User?fields=name,parents.name
     -raises BadRequest, If a fieldname is not avaibale in the response data.
     """
     if not raw_response_data:
         raise exceptions.NotFound("No data available for the requested query")
     def _fetch(schema, data, many, exclude, only=None):
         kwargs = {'only': only} if only else {}
         if exclude: kwargs['exclude'] = exclude
         #many=True attribute does not work well for relationships that are dynamically lazy loaded
         if many: return [schema(**kwargs).dump(response_data).data for response_data in data]
         else:    return  schema(**kwargs).dump(data).data
     fields = request.args.get('fields', None)
     if fields:
         try: return _fetch(self.response_schema, raw_response_data, many, exclude, only=fields.split(','))
         except KeyError as err:
             raise exceptions.BadRequest("feild '{}' not found in response data".format(err.message))
     else:
         return _fetch(self.response_schema, raw_response_data, many, exclude)
示例#7
0
 def get_parsed_request_data(self):
     """combine the request data in query string and json body
     used mainly to record the requests for POST and PATCH calls
     """
     #assume query string is in the format of a jQuery param, to enable support for nested dictionaries in the query string
     #https://api.jquery.com/jQuery.param/
     query_string_dict = jquery_unparam(request.query_string)
     #override with data in json if available
     if request.json: query_string_dict.update(request.json)
     applogger.debug(request.json)
     request_data   = self.request_schema().load(query_string_dict)
     applogger.debug(request_data)
     request_errors = request_data.errors
     request_data   = request_data.data
     applogger.debug(request_data)
     if request_errors: raise exceptions.BadRequest('error in request format', errors=request_errors)
     #add additional request information to request_data
     request_data['source_ip']         = utils.get_request_ip()
     request_data['user_agent_string'] = request.user_agent.string
     request_data['user_agent']        = {'platform': request.user_agent.platform,
                                          'browser' : request.user_agent.browser,
                                          'version' : request.user_agent.version,
                                          'language': request.user_agent.language}
     return request_data
示例#8
0
    def input_filters(self):
        """:filtering:
        A url query may contain these filters, and multple criteria can be combined
        *   `eq`,          equality
        *   `ne`,          non equality
        *   `lt`,          less than
        *   `lte`,         less than or equal to
        *   `gt`,          greater than
        *   `gte`,         greater than or equal to
        *   `in`,          in the specified list
        *   `nin`,         not in the specified list
        *   `contains`,    contains string
        *   `icontains`,   contains string (case insensitive)
        *   `startswith`,  string startswith
        *   `istartswith`, string startswith (case insensitive)
        *   `endswith`,    string endswith
        *   `iendswith`,   string endswith (case insensitive)

        /api/User/?filter[name]=endswith:"Simpson"
        /api/User/?filter[parents.name]=endswith:"Home"
        /api/User/?filter[name]=in:["Homer Simpson", "Darth Vader"]&filter[age]=eq:101
        /api/User/?filter[email]=startswith:"lisa"&filter[age]=lt:20

        be careful with queries like
        /api/User/?filter[parents.children.name]=eq:"lisa"
        while this query will work, it might not work as you expect
        the query will first get all parents whose children have the name "lisa"
        then the query will return all users who have parents that are returned by the previous step.

        -raises BadRequest, If a filtername is used, which does not exist.
        -raises BadRequest, If the value of a filter is not a JSON object.
        """
        filters = []
        KEY_RE = re.compile(r"filter\[([A-z0-9_\.]+)\]")
        # The first group captures the filters, the second captures the value.
        VALUE_RE = re.compile(
            r"(eq:|ne:|lt:|lte:|gt:|gte:|in:|nin:"\
            r"|contains:|icontains:|startswith:|istartswith:|endswith:"\
            r"|iendswith:)(.*)"
        )
        for key in request.args.keys():
            for value in request.args.getlist(key):
                key_match = re.match(KEY_RE, key)
                value_match = re.match(VALUE_RE, value)
                # If the key indicates a filter, but the filtername does not exist,
                # throw a BadRequest exception.
                if key_match and not value_match:
                    filtername = value.split(':')[0]
                    raise exceptions.BadRequest("The filter '{}' does not exist.".format(filtername), source_parameter=key)
                # The key indicates a filter and the filternames exists.
                elif key_match and value_match:
                    field = key_match.group(1)
                    # Remove the tailing ":" from the filter.
                    filtername = value_match.group(1)
                    filtername = filtername[:-1]
                    # The value may be encoded as json.
                    value = value_match.group(2)
                    try: value = json.loads(value)
                    except: raise exceptions.BadRequest("The value of the filter '{}' is not a JSON object.".format(filtername), source_parameter=key)
                    # Add the filter.
                    filters.append((field, filtername, value))
        return filters
示例#9
0
 def _create_attribute_filter(self, db_model, fieldname, filtername, value):
     attr = getattr(db_model, fieldname, None)
     if attr: return self._create_query_filter(filtername, attr, value)
     else:    raise exceptions.BadRequest("The filter field '{}' is not valid.".format(fieldname), fieldname=fieldname, filtername=filtername)
示例#10
0
 def get(self, api_id):
     api = api_tracker_models.ApiTracker.query.filter_by(id=api_id).first()
     if not api:
         raise exceptions.BadRequest('no api exists with id', id=api_id)
     return jsonify(self.select_fields(api))