def create(self, **kwargs): if not self.empty(): raise InvalidQuery("create query must be empty") resource = kwargs.pop("resource", None) if resource is None: resource = self.resource_class(**kwargs) if resource.max_participants > self.max_participants: msg = "max participants may not exceed %s" % self.max_participants raise InvalidQuery(message=msg, developer_message=msg, user_message=msg) if resource.max_duration > self.max_duration: msg = "max duration may not exceed %s" % self.max_duration raise InvalidQuery(message=msg, developer_message=msg, user_message=msg) try: with self.transaction_factory() as db_session: model = self.resource_to_model(resource) model.token = uuid.uuid4().hex db_session.add(model) db_session.flush() return self.model_to_resource(model, resource) except IntegrityError as error: raise InvalidQuery("invalid create query: %s" % str(error))
def create(self, **kwargs): if not self.empty(): raise InvalidQuery("create query must be empty") resource = kwargs.pop("resource", None) if resource is None: resource = self.resource_class(**kwargs) chat_token = resource.header.chat_token try: service = self._get_service_proxy(chat_token) model = self.resource_to_model(resource) model = service.sendMessage(requestContext=self._request_context, message=model, N=-1, W=-1) resource = self.model_to_resource(model) return resource except InvalidChatException: msg = "invalid chat token: %s" % chat_token raise InvalidQuery(message=msg, developer_message=msg) except InvalidMessageException: msg = "invalid message" raise InvalidQuery(message=msg, developer_message=msg)
def all(self): as_of = self.options.get("as_of") chat_token = self.options.get("chat_token") if chat_token is None: msg = "chat token is required to read chat messages" raise InvalidQuery(message=msg, developer_message=msg) service = self._get_service_proxy(chat_token) try: messages = service.getMessages( requestContext=self._request_context, chatToken=chat_token, asOf=as_of, block=True, timeout=10) resources = self.resource_class.Collection() resources.total_count = len(messages) start, end = self.slices messages = messages[start:end] for message in messages: resources.append(self.model_to_resource(message)) return resources except InvalidChatException: msg = "invalid chat token: %s" % chat_token raise InvalidQuery(message=msg, developer_message=msg, user_message="Your chat has expired.")
def parse(resource_class, **kwargs): results = [] for arg, value in kwargs.items(): current = resource_class parts = arg.split("__") path_fields = [] target_field = None operation_class = None if parts[-1] in OPERATIONS: operation_name = parts[-1] operation_class = OPERATIONS[operation_name] parts = parts[:-1] else: operation_class = Equal for part in parts: if part in current.desc.fields_by_name: field = current.desc.fields_by_name[part] if isinstance(field, StructField): current = field path_fields.append(field) elif isinstance(field, ListField) and \ isinstance(field.field, StructField): current = field.field.struct_class path_fields.append(field) else: #target field should be the last part if parts[-1] != part: raise InvalidQuery("invalid filter '%s'" % arg) target_field = field elif part in current.desc.related_fields_by_name: field = current.desc.related_fields_by_name[part] if field.relation is resource_class: target_field = field else: path_fields.append(field) current = field.relation else: raise InvalidQuery("invalid filter '%s'" % arg) primary_key = getattr(current.desc, "primary_key", None) target_field = target_field or current.desc.fields_by_name[ primary_key] operation = operation_class(target_field, value) filter = Filter(path_fields=path_fields, operation=operation) results.append(filter) return results
def one(self): if len(self.filters) != 1: raise InvalidQuery("id filter is required") filter = self.filters[0] if filter.name() != "id__eq": raise InvalidQuery("invalid filter: %s" % filter.name()) operation = filter.operation encoded_chat_id = operation.operands[0] chat_id = operation.target_field.to_model(encoded_chat_id) token = self._get_chat_token(chat_id) return self.resource_class(id=encoded_chat_id, token=token)
def parse(resource_class, **kwargs): results = [] for arg, value in kwargs.items(): current = resource_class parts = arg.split("__") path_fields = [] target_field = None if parts[-1].upper() in DIRECTIONS: direction = parts[-1].upper() parts = parts[:-1] else: direction = DIRECTIONS["ASC"] for part in parts: if part in current.desc.fields_by_name: field = current.desc.fields_by_name[part] if isinstance(field, StructField): current = field path_fields.append(field) elif isinstance(field, ListField) and \ isinstance(field.field, StructField): current = field.field.struct_class path_fields.append(field) else: #target field should be the last part if parts[-1] != part: raise InvalidQuery("invalid order_by '%s'" % arg) target_field = field target_field = field elif part in current.desc.related_fields_by_name: field = current.desc.related_fields_by_name[part] path_fields.append(field) current = field.relation else: raise InvalidQuery("invalid order_by '%s'" % arg) primary_key = current.desc.primary_key target_field = target_field or current.desc.fields_by_name[ primary_key] results.append(OrderBy(path_fields, target_field, direction)) return results
def build_related_query_kwargs(self, related_field, resource_instance, **kwargs): if related_field.self_referential: if isinstance(related_field, ForeignKey): arg = resource_instance.desc.primary_key value = getattr(resource_instance, related_field.attname, None) if value is None: #Fetch resource and double check primary_key = getattr(resource_instance, arg) resource_instance = resource_instance.desc.manager.get( primary_key) value = getattr(resource_instance, related_field.attname, None) else: arg = related_field.reverse.attname value = getattr(resource_instance, resource_instance.desc.primary_key) else: if isinstance(related_field, ForeignKey): arg = related_field.container_class.desc.primary_key primary_key_name = resource_instance.primary_key_name() primary_key_value = resource_instance.primary_key_value() value = getattr(resource_instance, related_field.attname, None) if value is None: #Fetch resource and double check fetch_kwargs = {} fetch_kwargs[primary_key_name] = primary_key_value resource_instance = resource_instance.desc.manager.one( **fetch_kwargs) value = getattr(resource_instance, related_field.attname, None) else: arg = "%s__%s" % (related_field.reverse.name, resource_instance.desc.primary_key) value = getattr(resource_instance, resource_instance.desc.primary_key) #arg = "%s__%s" % (related_field.reverse.name, resource_instance.desc.primary_key) #value = getattr(resource_instance, resource_instance.desc.primary_key) if arg in kwargs and kwargs[arg] != value: raise InvalidQuery("contradicting related filter") kwargs[arg] = value return kwargs
def parse(resource_class, **kwargs): results = [] for arg, value in kwargs.items(): current = resource_class parts = arg.split("__") related_fields = [] for part in parts: if part in current.desc.related_fields_by_name: field = current.desc.related_fields_by_name[part] related_fields.append(field) current = field.relation else: raise InvalidQuery("invalid with relation '%s'" % arg) results.append(WithRelation(related_fields)) return results
def process_request(self, context, request, **kwargs): response = None try: if context.is_direct_resource(): query = self._build_query(context, request, **kwargs) elif context.is_related_resource(): query = self._build_related_query(context, request, **kwargs) context.query = query except InvalidQuery as error: logging.warning(repr(error)) response = ExceptionResponse(error) except ValidationError as error: logging.warning(repr(error)) response = ExceptionResponse(error) except Exception as error: logging.exception(error) response = ExceptionResponse(InvalidQuery()) return response