Exemple #1
0
def _bool_param_handler(input):
    if isinstance(input, bool):
        if input:
            return "true"
        else:
            return "false"

    if isinstance(input, basestring):
        if input not in ("true", "false"):
            raise InvalidArgumentException.pyexc(
                "String for boolean must be "
                "'true' or 'false'", input)
        return input

    try:
        input + 0
        if input:
            return "true"
        else:
            return "false"

    except TypeError:
        raise InvalidArgumentException.pyexc(
            "Boolean value must be boolean, "
            "numeric, or a string of 'true' "
            "or 'false'", input)
    def __init__(self,
                 id_generator=None,
                 data_converter=lambda x: x,
                 operation=BucketOperators.UPSERT):
        # type: (IdGenerator, DataConverter, BucketOperator) -> None
        """
        Initialise ingester.

        :param DataConverter data_converter: Single parameter Callable which takes a JSON
            input and returns a transformed JSON output.
        :param IdGenerator id_generator: Callable that takes a JSON input and
            returns an ID string
        :param BucketOperator operation: Callable that takes a bucket object, a key and a
            value and applies the key and value to the bucket (e.g. upsert/insert/replace)
        """
        if not isinstance(operation, BucketOperator):
            raise InvalidArgumentException("Operation is not a BucketOperator")

        if operation == BucketOperators.REPLACE and not id_generator:
            raise InvalidArgumentException(
                "Replace cannot use default ID generator.")

        self.id_generator = id_generator or (lambda x: str(uuid.uuid4()))
        self.data_converter = data_converter
        self.operation = operation
 def upsert_index(self,      # type: SearchIndexManager
                  index,     # type: SearchIndex
                  *options,  # type: UpsertSearchIndexOptions
                  **kwargs   # type: Any
                  ):
     # type: (...) -> None
     """
     Creates or updates an index.
     :param SearchIndex index: Index to upsert.
     :param UpsertSearchIndexOptions options: options to upsert index.
     :param Any kwargs: override corresponding value in options
     :raise:
       :exc: `~.InvalidArgumentsException`
         if the arguments were invalid
       :exc: `~.CouchbaseException`
         for various server errors
     Uri
     PUT http://localhost:8094/api/index/<index_name>"""
     if not index:
         raise InvalidArgumentException("expected index to not be None")
     else:
         if not index.is_valid():
             raise InvalidArgumentException("Index must have name, source set")
     try:
         self._http_request(
             path="api/index/{}".format(index.name),
             method="PUT",
             content=json.dumps(index.as_dict()),
             **forward_args(kwargs, *options))
     except HTTPException as h:
         error = getattr(getattr(h, 'objextra', None), 'value', {}).get('error', "")
         if not "index with the same name already exists" in error:
             raise
def validate_project(project):
    if not project:
        return
    if isinstance(project, str):
        raise InvalidArgumentException("project must be an array of paths")
    if hasattr(project, "__getitem__") or hasattr(project, "__iter__"):
        return
    raise InvalidArgumentException("project must be an Iterable[str]")
Exemple #5
0
def _num_param_handler(input):
    # Don't allow booleans:
    if isinstance(input, bool):
        raise InvalidArgumentException.pyexc(
            "Cannot use booleans as numeric values", input)
    try:
        return str(int(input))
    except Exception as e:
        raise InvalidArgumentException.pyexc("Expected a numeric argument",
                                             input, e)
Exemple #6
0
def _jval_param_handler(input):
    try:
        ret = json.dumps(input)
        return _string_param_handler(ret)
    except Exception as e:
        raise InvalidArgumentException.pyexc("Couldn't convert value to JSON",
                                             input, e)
    def get_index(self,       # type: SearchIndexManager
                  index_name, # type: str
                  *options,   # type: GetSearchIndexOptions
                  **kwargs    # type: Any
                  ):
        # type: (...)-> SearchIndex
        """
        Fetches an index from the server if it exists.

        param str index_name: Name of the index to get.
        param GetSearchIndexOptions: options to use when getting index.
        param Any kwargs: overrides corresponding value in options

        :return: a :class:`~.SearchIndex` object.
        :raise:
          :exc:`~.SearchIndexNotFoundException`
            if the index was not found.
          :exc:`~.InvalidArgumentsException`
            if the arguments were not understood
          :exc:`~.CouchbaseException`
            for various server errors
        Uri
        GET http://localhost:8094/api/index/<name>"""
        if not index_name:
            raise InvalidArgumentException("expected index_name to not be empty")

        return SearchIndex.from_server(
            **self._http_request(
                path="api/index/{}".format(index_name),
                method='GET',
                **forward_args(kwargs, *options)).value["indexDef"]
        )
Exemple #8
0
def _jarry_param_handler(input):
    ret = _jval_param_handler(input)
    if not ret.startswith('['):
        raise InvalidArgumentException.pyexc(
            "Value must be converted to JSON array", input)

    return ret
    def unfreeze_plan(self,  # type: SearchIndexManager
                      index_name,  # type: str
                      *options,  # type: UnfreezePlanSearchIndexOptions
                      **kwargs  # type: Any
                      ):
        """
        Unfreeze the assignment of index partitions to nodes.
        :param str index_name: Name of index to freeze.
        :param UnfreezePlanSearchIndexOptions options: Options for freezing index.
        :param kwargs Any: Override corresponding value in options.
        :return: None
        :raise:
          :exc: `~.SearchIndexNotFoundException`
            if the index doesn't exist
          :exc: `~.InvalidArgumentsException`
            if the arguments were invalid
          :exc: `~.CouchbaseException`
            for various server errors
        Uri
        POST http://localhost:8094/api/index/{index_name}/planFreezeControl/unfreeze
        """
        if not index_name:
            raise InvalidArgumentException("expected an index_name")

        self._http_request(
            path='api/index/{}/planFreezeControl/unfreeze'.format(index_name),
            method='POST',
            **forward_args(kwargs, *options))
    def disallow_querying(self,  # type: SearchIndexManager
                          index_name,  # type: str
                          *options,  # type: DisallowQueryingSearchIndexOptions
                          **kwargs  # type: Any
                          ):
        """
        Allow querying against an index.
        :param str index_name: Name of index to allow querying.
        :param AllowQueryingSearchIndexOptions options: options for allowing querying.
        :param Any kwargs: Override corresponding value in options.
        :return: None
        :raise:
          :exc: `~.SearchIndexNotFoundException`
            if the index doesn't exist
          :exc: `~.InvalidArgumentsException`
            if the arguments were invalid
          :exc: `~.CouchbaseException`
            for various server errors
        Uri
        POST http://localhost:8094/api/index/{index_name}/queryControl/allow
        """
        if not index_name:
            raise InvalidArgumentException("expected an index_name")

        self._http_request(
            path='api/index/{}/queryControl/allow'.format(index_name),
            method='POST',
            **forward_args(kwargs, *options))
Exemple #11
0
    def _set_common(self, param, value, set_user=True):
        # Invalidate encoded string
        self._encoded = None

        if value is UNSPEC:
            self._real_options.pop(param, None)
            if set_user:
                self._user_options.pop(param, None)
            return

        handler = _HANDLER_MAP.get(param)
        if not handler:
            if not self.unrecognized_ok:
                raise InvalidArgumentException.pyexc(
                    "Unrecognized parameter. To use unrecognized parameters, "
                    "set 'unrecognized_ok' to True")

        if not handler:
            self._extra_options[param] = _string_param_handler(value)
            return

        if self.passthrough:
            handler = _string_param_handler

        self._real_options[param] = handler(value)
        if set_user:
            self._user_options[param] = value
    def resume_ingest(self,  # type: SearchIndexManager
                      index_name,  # type: str
                      *options,  # type: ResumeIngestSearchIndexOptions
                      **kwargs  # type: Any
                      ):
        """
        Resume the ingestion of documents for an index.
        :param str index_name: Name of index to resume.
        :param ResumeIngestSearchIndexOptions options: Options for resuming ingestion of index.
        :param Any kwargs: Override corresponding value in options.
        :return: None
        :raise:
          :exc: `~.InvalidArgumentsException`
            if the arguments were invalid
          :exc: `~.CouchbaseException`
            for various server errors
        Uri
        POST http://localhost:8094/api/index/{index_name}/ingestControl/resume
        """

        if not index_name:
            raise InvalidArgumentException("expected an index_name")

        self._http_request(
            path="api/index/{}/ingestControl/resume".format(index_name),
            method="POST",
            **forward_args(kwargs, *options))
    def get_indexed_documents_count(self,       # type: SearchIndexManager
                                    index_name, # type: str
                                    *options,   # type: GetSearchIndexedDocumentsCountOptions
                                    **kwargs    # type: Any
                                    ):
        """
        Get a count of the documents indexed by the given index.

        :param str index_name: Name of index to get indexed document count.
        :param GetIndexedDocumentsSearchIndexOptions options: Options for geting the indexed document count.
        :param Any kwargs: Override corresponding value in options.
        :return: A :class: `int`, the count of documents indexed by the index.
        :raise:
          :exc: `~.InvalidArgumentsException`
            if the arguments were invalid
          :exc: `~.CouchbaseException`
            for various server errors
        Uri
        GET http://localhost:8094/api/index/{index_name}/count
        """
        if not index_name:
            raise InvalidArgumentException("expected an index_name")

        return self._http_request(
            path="api/index/{}/count".format(index_name),
            **forward_args(kwargs, *options)).value['count']
    def drop_index(self,       # type: SearchIndexManager
                   index_name, # type: str
                   *options,   # type: DropSearchIndexOptions
                   **kwargs    # type: Any
                   ):
        # type: (...)  -> None
        """
        Drop an index.
        :param str index_name: Name of index to drop.
        :param DropSearchIndexOptions options: options for dropping index.
        :param Any kwargs: override corresponding option in options
        :raise:
          :exc: `~.InvalidArgumentsException`
            if the arguments were invalid
          :exc: `~.CouchbaseException`
            for various server errors

        Uri
        DELETE http://localhost:8094/api/index/{index_name}
        """
        if not index_name:
            raise InvalidArgumentException("expected an index_name")

        self._http_request(
            path="api/index/{}".format(index_name),
            method='DELETE',
            **forward_args(kwargs, *options))
Exemple #15
0
    def _set_range_common(self, k_sugar, k_start, k_end, value):
        """
        Checks to see if the client-side convenience key is present, and if so
        converts the sugar convenience key into its real server-side
        equivalents.

        :param string k_sugar: The client-side convenience key
        :param string k_start: The server-side key specifying the beginning of
            the range
        :param string k_end: The server-side key specifying the end of the
            range
        """

        if not isinstance(value, (list, tuple, _Unspec)):
            raise InvalidArgumentException.pyexc(
                "Range specification for {0} must be a list, tuple or UNSPEC".
                format(k_sugar))

        if self._user_options.get(
                k_start, UNSPEC) is not UNSPEC or (self._user_options.get(
                    k_end, UNSPEC) is not UNSPEC):

            raise InvalidArgumentException.pyexc(
                "Cannot specify {0} with either {1} or {2}".format(
                    k_sugar, k_start, k_end))

        if not value:
            self._set_common(k_start, UNSPEC, set_user=False)
            self._set_common(k_end, UNSPEC, set_user=False)
            self._user_options[k_sugar] = UNSPEC
            return

        if len(value) not in (1, 2):
            raise InvalidArgumentException.pyexc(
                "Range specification "
                "must have one or two elements", value)

        value = value[::]
        if len(value) == 1:
            value.append(UNSPEC)

        for p, ix in ((k_start, 0), (k_end, 1)):
            self._set_common(p, value[ix], set_user=False)

        self._user_options[k_sugar] = value
Exemple #16
0
 def __call__(self, src: Enum_Type) -> str:
     if not self._enforce and isinstance(src, str) and src in map(
             lambda x: x.value, self._type):
         warnings.warn("Using deprecated string parameter {}".format(src))
         return src
     if not isinstance(src, self._type):
         raise InvalidArgumentException(
             "Argument must be of type {} but got {}".format(
                 self._type, src))
     return src.value
 def __init__(self,  # type: DiagnosticsResult
              source_diagnostics  # type: Union[Mapping[str,Any], list[Mapping[str,Any]]]
              ):
     self._id = self._version = self._sdk = self._endpoints = None
     # we could have an array of dicts, or just a single dict
     if isinstance(source_diagnostics, dict):
         source_diagnostics = [source_diagnostics]
     if not isinstance(source_diagnostics, list):
         raise InvalidArgumentException("DiagnosticsResult expects a dict or list(dict)")
     for d in source_diagnostics:
         self.append_endpoints(d)
Exemple #18
0
 def convert(mapping: Orig_Mapping,
             raw_info: Mapping[str, Any]) -> Mapping[str, Any]:
     converted = {}
     for k, v in raw_info.items():
         entry = mapping.get(k, {k: Identity(object)})
         for dest, transform in entry.items():
             try:
                 converted[dest] = transform(v)
             except InvalidArgumentException as e:
                 raise InvalidArgumentException(
                     "Problem processing argument {}: {}".format(
                         k, e.message))
     return converted
Exemple #19
0
def _string_param_common(input, do_quote=False):
    # TODO, if we pass this to urlencode, do we ever need to quote?
    # For the moment, i'm always forcing non-quote behavior
    do_quote = False

    s = None
    if isinstance(input, basestring):
        s = input

    elif isinstance(input, bool):
        raise InvalidArgumentException.pyexc("Can't use boolean as string",
                                             input)

    elif isinstance(input, (int, long, float)):
        # Basic numeric types:
        s = str(input)

    else:
        raise InvalidArgumentException.pyexc(
            "Expected simple numeric type or string ", input)
    if do_quote:
        s = ulp.quote(s)

    return s
    def __init__(
            self,
            name=None,  # type: str
            bucket=None,  # type: str
            scope=None,  # type: str
            collection=None,  # type: str
    ):

        if not name:
            raise InvalidArgumentException('A role must have a name')

        self._name = name
        self._bucket = bucket
        self._scope = scope
        self._collection = collection
 def analyze_document(self,  # type: SearchIndexManager
                      index_name,  # type: str
                      document,  # type: Any
                      *options,  # type: AnalyzeDocumentSearchIndexOptions
                      **kwargs  # type: Any
                      ):
     """
     Shows how a given document will be analyzed against a specific index
     :param str index_name: Index to use.
     :param Any document: Document to analyze.
     :param AnalyzeDocumentSearchIndexOptions options: Options for analyzing document.
     :param Any kwargs: Override corresponding value in options.
     :return: dict
     :raise:
       :exc: `~.SearchIndexNotFoundException`
         if the index doesn't exist
       :exc: `~.InvalidArgumentsException`
         if the arguments were invalid
       :exc: `~.CouchbaseException`
         for various server errors
     Uri
     POST http://localhost:8094/api/index/{index_name}/analyzeDoc
     """
     if not index_name:
         raise InvalidArgumentException("expected an index_name")
     if not document:
         raise InvalidArgumentException("expected a document to analyze")
     try:
         jsonDoc = json.dumps(document)
     except:
         raise InvalidArgumentException("cannot convert doc to json to analyze")
     return self._http_request(
         path="api/index/{}/analyzeDoc".format(index_name),
         method='POST',
         content=jsonDoc,
         **forward_args(kwargs, *options)).value
    def _design_poll(self, name, mode, oldres, timeout=5, use_devmode=False):
        """
        Poll for an 'async' action to be complete.
        :param string name: The name of the design document
        :param string mode: One of ``add`` or ``del`` to indicate whether
            we should check for addition or deletion of the document
        :param oldres: The old result from the document's previous state, if
            any
        :param float timeout: How long to poll for. If this is 0 then this
            function returns immediately
        :type oldres: :class:`~couchbase_core.result.HttpResult`
        """
        if not timeout:
            return True

        if timeout < 0:
            raise InvalidArgumentException.pyexc(
                "Interval must not be negative")

        t_end = time.time() + timeout
        old_rev = None

        if oldres:
            old_rev = self._doc_rev(oldres)

        while time.time() < t_end:
            try:
                cur_resp = self.design_get(name, use_devmode=use_devmode)
                if old_rev and self._doc_rev(cur_resp) == old_rev:
                    continue

                try:
                    if not self._poll_vq_single(name, use_devmode,
                                                cur_resp.value):
                        continue
                    return True

                except CouchbaseException:
                    continue

            except CouchbaseException:
                if mode == 'del':
                    # Deleted, whopee!
                    return True

        raise exceptions.TimeoutException.pyexc(
            "Wait time for design action completion exceeded")
    def __init__(
            self,
            username=None,  # type: str
            display_name=None,  # type: str
            groups=None,  # type: Set[str]
            roles=None,  # type: Set[Role]
            password=None  # type: str
    ):

        if not username:
            raise InvalidArgumentException('A user must have a username')

        self._username = username
        self._display_name = display_name
        self._groups = SetHelper.to_set(groups, str, 'Groups')
        self._roles = SetHelper.to_set(roles, Role, 'Roles')
        self._password = password
    def __init__(
            self,
            name=None,  # type: str
            description=None,  # type: str
            roles=None,  # type: Set[Role]
            ldap_group_reference=None,  # type: str
            **kwargs  # type: Any
    ):

        if not name:
            raise InvalidArgumentException('A group must have a name')

        self._name = name
        self._description = description
        self._roles = SetHelper.to_set(roles, Role, 'Roles')
        self._ldap_group_reference = ldap_group_reference
        self._raw_data = kwargs.get('raw_data', None)
    def to_set(cls, value, valid_type, display_name):

        if not value:
            return value
        elif isinstance(value, set):
            cls.validate_all_set_types(value, valid_type, display_name)
            return value
        elif isinstance(value, list):
            cls.validate_all_set_types(value, valid_type, display_name)
            return set(value)
        elif isinstance(value, tuple):
            cls.validate_all_set_types(value, valid_type, display_name)
            return set(value)
        elif isinstance(value, valid_type):
            return set([value])
        else:
            raise InvalidArgumentException('{} must be of type {}.'.format(
                display_name, valid_type.__name__))
    def _http_request(self, **kwargs):
        #  TODO: maybe there is a more general way of making this
        # call?  Ponder
        # the kwargs can override the defaults
        imeth = None
        method = kwargs.get('method', 'GET')
        if not method in METHMAP:
            raise InvalidArgumentException("Unknown HTTP Method", method)

        imeth = METHMAP[method]
        return self._admin_bucket._http_request(
            type=LCB.LCB_HTTP_TYPE_SEARCH,
            path=kwargs['path'],
            method=imeth,
            content_type=kwargs.get('content_type', 'application/json'),
            post_data=kwargs.get('content', None),
            response_format=LCB.FMT_JSON,
            timeout=kwargs.get('timeout', None))
Exemple #27
0
    def from_any(cls, params, **ctor_opts):
        """
        Creates a new Query object from input.

        :param params: Parameter to convert to query
        :type params: dict, string, or :class:`Query`

        If ``params`` is a :class:`Query` object already, a deep copy is made
        and a new :class:`Query` object is returned.

        If ``params`` is a string, then a :class:`Query` object is contructed
        from it. The string itself is not parsed, but rather prepended to
        any additional parameters (defined via the object's methods)
        with an additional ``&`` characted.

        If ``params`` is a dictionary, it is passed to the :class:`Query`
        constructor.

        :return: a new :class:`Query` object
        :raise: :exc:`InvalidArgumentException` if the input is none of the acceptable
            types mentioned above. Also raises any exceptions possibly thrown
            by the constructor.

        """
        if isinstance(params, cls):
            return deepcopy(params)

        elif isinstance(params, dict):
            ctor_opts.update(**params)
            if cls is QueryBase:
                if ('bbox' in params or 'start_range' in params
                        or 'end_range' in params):
                    return SpatialQuery(**ctor_opts)
                else:
                    return ViewQuery(**ctor_opts)

        elif isinstance(params, basestring):
            ret = cls()
            ret._base_str = params
            return ret

        else:
            raise InvalidArgumentException.pyexc(
                "Params must be Query, dict, or string")
def gen_projection_spec(project, with_exp=False):
    def generate(path):
        if path is None:
            return with_expiry()
        if path:
            return SD.get(path)
        return get_full()

    validate_project(project)
    # empty string = with_expiry
    # None = get_full
    if not project:
        project = [""]
    if with_exp:
        project = [None] + project

    if len(project) > MAX_SPECS:
        raise InvalidArgumentException(
            "Project only accepts {} operations or less".format(MAX_SPECS))

    return map(generate, project)
Exemple #29
0
    def update(self, copy=False, **params):
        """
        Chained assignment operator.

        This may be used to quickly assign extra parameters to the
        :class:`Query` object.

        Example::

            q = Query(reduce=True, full_sec=True)

            # Someplace later

            v = View(design, view, query=q.update(mapkey_range=["foo"]))

        Its primary use is to easily modify the query object (in-place).

        :param boolean copy:
            If set to true, the original object is copied before new attributes
            are added to it
        :param params: Extra arguments. These must be valid query options.

        :return: A :class:`Query` object. If ``copy`` was set to true, this
            will be a new instance, otherwise it is the same instance on which
            this method was called

        """
        if copy:
            self = deepcopy(self)

        for k, v in params.items():
            if not hasattr(self, k):
                if not self.unrecognized_ok:
                    raise InvalidArgumentException.pyexc("Unknown option", k)
                self._set_common(k, v)

            else:
                setattr(self, k, v)

        return self
    def view_query(self, *args, **kwargs):
        """
        Reimplemented from base class.

        This method does not add additional functionality of the
        base class' :meth:`~couchbase_v2.bucket.Bucket.query` method (all the
        functionality is encapsulated in the view class anyway). However it
        does require one additional keyword argument

        :param class itercls: A class used for instantiating the view
          object. This should be a subclass of
          :class:`~couchbase.asynchronous.view.AsyncViewBase`.
        """
        if not issubclass(kwargs.get('itercls', None), AsyncViewBase):
            raise InvalidArgumentException.pyexc(
                "itercls must be defined "
                "and must be derived from AsyncViewBase")

        try:
            return super(AsyncClientMixin, self).view_query(*args, **kwargs)
        except Exception as e:
            raise