def testList(self):
        cats = []
        for i in range(0, 3):
            s = ParaObject(self.catsType + str(i))
            s.type = self.catsType
            cats.append(s)

        self.pc.createAll(cats)
        sleep(1)

        self.assertIs(len(self.pc.list(None)), 0)
        self.assertIs(len(self.pc.list("")), 0)

        list1 = self.pc.list(self.catsType)
        self.assertIsNot(len(list1), 0)
        self.assertEqual(3, len(list1))
        self.assertEqual(isinstance(list1[0], ParaObject), True)

        list2 = self.pc.list(self.catsType, Pager(limit=2))
        self.assertIsNot(len(list2), 0)
        self.assertEqual(2, len(list2))

        nl = [cats[0].id, cats[1].id, cats[2].id]
        self.pc.deleteAll(nl)

        self.assertIs(self.catsType in self.pc.getApp()["datatypes"].values(),
                      True)
Пример #2
0
 def getEntity(res: Response, returnRawJSON: bool = True):
     """
     Deserializes a Response object to POJO of some type.
     @param res: response
     @param returnRawJSON: true if an array should be returned
     @return: an object
     """
     if res:
         code = res.status_code
         if code == 200 or code == 201 or code == 304:
             if returnRawJSON:
                 try:
                     body = res.json()
                     return body if body else {}
                 except JSONDecodeError:
                     return res.text
             else:
                 obj = ParaObject()
                 obj.setFields(res.json())
                 return obj
         elif code != 404 or code != 304 or code != 204:
             error = res.json()
             if error and error["code"]:
                 msg = (error["message"] if error["message"] else "error")
                 logging.error(msg + " - " + error["code"])
             else:
                 logging.error(code + " - " + res.reason)
     return None
Пример #3
0
 def signIn(self, provider: str, providertoken: str, rememberjwt: bool = True):
     """
     Takes an identity provider access token and fetches the user data from that provider.
     A new User object is created if that user doesn't exist.
     Access tokens are returned upon successful authentication using one of the SDKs from
     Facebook, Google, Twitter, etc.
     <b>Note:</b> Twitter uses OAuth 1 and gives you a token and a token secret.
     <b>You must concatenate them like this: <code>{oauth_token}:{oauth_token_secret}</code> and
     use that as the provider access token.</b>
     @param provider: identity provider, e.g. 'facebook', 'google'...
     @param providertoken: access token from a provider like Facebook, Google, Twitter
     @param rememberjwt: it true the access token returned by Para will be stored locally and
     available through getAccessToken(). True by default.
     @return: a User object or None if something failed
     """
     if not provider or not providertoken:
         return None
     credentials = {"appid": self.__accessKey, "provider": provider, "token": providertoken}
     result = self.getEntity(self.invokePost(self.JWT_PATH, json.dumps(credentials)))
     if result and result["user"] and result["jwt"]:
         jwt_data = result["jwt"]
         if rememberjwt:
             self.__tokenKey = jwt_data["access_token"]
             self.__tokenKeyExpires = jwt_data["expires"]
             self.__tokenKeyNextRefresh = jwt_data["refresh"]
         obj = ParaObject()
         obj.setFields(result["user"])
         return obj
     else:
         self.clearAccessToken()
         return None
Пример #4
0
 def update(self, obj: ParaObject):
     """
     Updates an object permanently. Supports partial updates.
     @param obj: the object to update
     @return: updated object
     """
     if not obj:
         return None
     return self.getEntity(self.invokePatch(obj.getObjectURI(), obj.jsonSerialize()), False)
Пример #5
0
    def testGetObjectURI(self):
        o1 = ParaObject()
        self.assertEqual(o1.getObjectURI(), "/sysprop")
        o1.type = "dog"
        self.assertEqual(o1.getObjectURI(), "/dog")
        o1.id = "123"
        self.assertEqual(o1.getObjectURI(), "/dog/123")

        o2 = ParaObject(id_="123 56", type_="dog 2")
        self.assertEqual(o2.getObjectURI(), "/dog%202/123%2056")
Пример #6
0
 def create(self, obj: ParaObject):
     """
     Persists an object to the data store. If the object's type and id are given,
     then the request will be a {@code PUT} request and any existing object will be overwritten.
     @param obj: the domain object
     @return: the same object with assigned id or null if not created.
     """
     if not obj:
         return None
     if obj.id and obj.type:
         return self.getEntity(self.invokePut(obj.getObjectURI(), obj.jsonSerialize()), False)
     else:
         return self.getEntity(self.invokePost(self.urlenc(obj.type), obj.jsonSerialize()), False)
Пример #7
0
 def getItemsFromList(result: list):
     """
     Deserializes ParaObjects from a JSON array (the "items:[]" field in search results).
     @param result: a list of deserialized objects
     @return: a list of ParaObjects
     """
     if result and len(result) > 0:
         # this isn't very efficient but there's no way to know what type of objects we're reading
         objects = []
         for obj in result:
             if obj and len(obj) > 0:
                 p = ParaObject()
                 p.setFields(obj)
                 objects.append(p)
         return objects
     return []
Пример #8
0
 def delete(self, obj: ParaObject):
     """
     Deletes an object permanently.
     @param obj: the object
     """
     if obj:
         self.invokeDelete(obj.getObjectURI())
Пример #9
0
 def getChildren(self,
                 obj: ParaObject,
                 type2: str,
                 field: str,
                 term: str,
                 pager: Pager = None):
     """
     Returns all child objects linked to this object.
     @param obj: the object to execute this method on
     @param type2: the type of children to look for
     @param field: the field name to use as filter
     @param term: the field value to use as filter
     @param pager: a Pager
     @return: a list of ParaObject in a one-to-many relationship with this object
     """
     if not obj or not obj.id or not type2:
         return []
     params = self.pagerToParams(pager)
     params["childrenonly"] = "true"
     if field:
         params["field"] = field
     if term:
         params["term"] = term
     url = obj.getObjectURI() + "/links/" + self.urlenc(type2)
     return self.getItems(self.getEntity(self.invokeGet(url, params)),
                          pager=pager)
    def testMisc(self):
        types = self.pc.types()
        self.assertIsNotNone(types)
        self.assertIsNot(len(types), 0)
        self.assertIs(ParaObject(None, "user").type in types.values(), True)

        self.assertEqual("app:test", self.pc.me().id)
Пример #11
0
 def deleteChildren(self, obj: ParaObject, type2: str):
     """
     Deletes all child objects permanently.
     @param obj: the object to execute this method on
     @param type2: the children's type.
     """
     params = {"childrenonly": "true"}
     url = obj.getObjectURI() + "/links/" + self.urlenc(type2)
     self.invokeDelete(url, params)
    def testValidationConstraints(self):
        # Validations string
        kittenType = "kitten"
        constraints = self.pc.validationConstraints()
        self.assertIsNot(len(constraints), 0)
        self.assertIs("app" in constraints.keys(), True)
        self.assertIs("user" in constraints.keys(), True)

        constraint = self.pc.validationConstraints("app")

        self.assertIsNot(len(constraint), 0)
        self.assertIs("app" in constraint.keys(), True)
        self.assertEqual(1, len(constraint))

        self.pc.addValidationConstraint(kittenType, "paws",
                                        Constraint.required())
        constraint = self.pc.validationConstraints(kittenType)
        self.assertIs("paws" in constraint[kittenType].keys(), True)

        ct = ParaObject("felix")
        ct.type = kittenType

        # validation fails
        ct2 = self.pc.create(ct)

        self.assertIsNone(ct2)
        ct["paws"] = "4"
        self.assertIsNotNone(self.pc.create(ct))

        self.pc.removeValidationConstraint(kittenType, "paws", "required")
        constraint = self.pc.validationConstraints(kittenType)
        self.assertIs(kittenType in constraint.keys(), False)

        # votes
        self.assertIs(self.pc.voteUp(ct, self.u.id), True)
        self.assertIsNot(self.pc.voteUp(ct, self.u.id), True)
        self.assertIs(self.pc.voteDown(ct, self.u.id), True)
        self.assertIs(self.pc.voteDown(ct, self.u.id), True)
        self.assertIsNot(self.pc.voteDown(ct, self.u.id), True)
        self.pc.delete(ct)
        self.pc.delete(ParaObject("vote:" + self.u.id + ":" + ct.id, "vote"))

        self.assertIs(self.pc.getServerVersion().startswith("1"), True)
        self.assertNotEqual("unknown", self.pc.getServerVersion())
Пример #13
0
    def testSetFields(self):
        o1 = ParaObject("123", "dog")
        o1.one = 1
        o1.two = "two"

        assert o1.type == "dog"
        assert o1.id == "123"

        obj = json.loads(o1.jsonSerialize())
        obj1 = ParaObject()
        obj1.setFields(obj)

        assert obj1.type == "dog"
        assert obj1.id == "123"
        assert obj1.two == "two"
Пример #14
0
 def unlinkAll(self, obj: ParaObject):
     """
     Unlinks all objects that are linked to this one.
     Deletes all Linker objects. Only the links are deleted. Objects are left untouched.
     @param obj: the object to execute this method on
     """
     if not obj or not obj.id:
         return
     url = obj.getObjectURI() + "/links"
     self.invokeDelete(url)
    def setUpClass(cls):
        cls.pc = ParaClient(
            "app:test",
            "Yi/b6Bw6dCFWBqHiExNUwqqT/UoUf8NuWbwOcxe7ddKuqF9luUxagA==")
        cls.pc.setEndpoint("http://localhost:8080")
        cls.pc2 = ParaClient("app:test", "")
        cls.pc2.setEndpoint("http://localhost:8080")
        if not cls.pc.me():
            raise Exception(
                "Local Para server must be started before testing.")

        cls.u = ParaObject("111")
        cls.u.name = "John Doe"
        cls.u.tags = ["one", "two", "three"]

        cls.u1 = ParaObject("222")
        cls.u1.name = "Joe Black"
        cls.u1.tags = ["two", "four", "three"]

        cls.u2 = ParaObject("333")
        cls.u2.name = "Ann Smith"
        cls.u2.tags = ["four", "five", "three"]

        cls.t = ParaObject("tag:test", "tag")
        cls.t["count"] = 3
        cls.t["tag"] = "test"

        cls.a1 = ParaObject("adr1", "address")
        cls.a1.name = "Place 1"
        cls.a1["address"] = "NYC"
        cls.a1["country"] = "US"
        cls.a1["latlng"] = "40.67,-73.94"
        cls.a1.parentid = cls.u.id
        cls.a1.creatorid = cls.u.id

        cls.a2 = ParaObject("adr2", "address")
        cls.a2.name = "Place 2"
        cls.a2["address"] = "NYC"
        cls.a2["country"] = "US"
        cls.a2["latlng"] = "40.69,-73.95"
        cls.a2.parentid = cls.t.id
        cls.a2.creatorid = cls.t.id

        cls.s1 = ParaObject("s1")
        cls.s1[
            "text"] = "This is a little test sentence. Testing, one, two, three."

        cls.s2 = ParaObject("s2")
        cls.s2[
            "text"] = "We are testing this thing. This sentence is a test. One, two."

        cls.pc.createAll(
            [cls.u, cls.u1, cls.u2, cls.t, cls.s1, cls.s2, cls.a1, cls.a2])
Пример #16
0
 def voteDown(self, obj: ParaObject, voterid: str):
     """
     Downvote an object and register the vote in DB.
     @param obj: the object to receive -1 votes
     @param voterid: the userid of the voter
     @return: true if vote was successful
     """
     if not obj or not voterid:
         return False
     res = self.getEntity(self.invokePatch(obj.getObjectURI(), json.dumps({"_votedown": voterid})))
     return True if res else False
Пример #17
0
 def unlink(self, obj: ParaObject, type2: str, id2: str):
     """
     Unlinks an object from this one. Only a link is deleted. Objects are left untouched.
     @param obj: the object to execute this method on
     @param type2: the other type
     @param id2: the other id
     """
     if not obj or not obj.id or not type2 or not id2:
         return
     url = obj.getObjectURI() + "/links/" + self.urlenc(type2) + "/" + self.urlenc(id2)
     self.invokeDelete(url)
Пример #18
0
 def getLinkedObjects(self, obj: ParaObject, type2: str, pager: Pager = None):
     """
     Returns all objects linked to the given one. Only applicable to many-to-many relationships.
     @param obj: the object to execute this method on
     @param type2: type of linked objects to search for
     @param pager: a Pager
     @return: a list of linked objects
     """
     if not obj or not obj.id or not type2:
         return []
     url = obj.getObjectURI() + "/links/" + self.urlenc(type2)
     return self.getItems(self.getEntity(self.invokeGet(url, self.pagerToParams(pager))), pager=pager)
Пример #19
0
 def countLinks(self, obj: ParaObject, type2: str):
     """
     Count the total number of links between this object and another type of object.
     @param obj: the object to execute this method on
     @param type2: the other type of object
     @return: the number of links for the given object
     """
     if not obj or not obj.id or not type2:
         return 0
     pager = Pager()
     url = obj.getObjectURI() + "/links/" + self.urlenc(type2)
     self.getItems(self.getEntity(self.invokeGet(url, {"count": "true"})), pager=pager)
     return pager.count
Пример #20
0
 def link(self, obj: ParaObject, id2: str):
     """
     Links an object to this one in a many-to-many relationship.
     Only a link is created. Objects are left untouched.
     The type of the second object is automatically determined on read.
     @param obj: the object to execute this method on
     @param id2: link to the object with this id
     @return: the id of the Linker object that is created
     """
     if not obj or not obj.id or not id2:
         return
     url = obj.getObjectURI() + "/links/" + self.urlenc(id2)
     return self.getEntity(self.invokePost(url))
Пример #21
0
 def isLinked(self, obj: ParaObject, type2: str, id2: str):
     """
     Checks if this object is linked to another.
     @param obj: the object to execute this method on
     @param type2: type of linked objects to search for
     @param id2: the other id
     @return: true if the two are linked
     """
     if not obj or not obj.id or not type2 or not id2:
         return False
     url = obj.getObjectURI() + "/links/" + self.urlenc(type2) + "/" + self.urlenc(id2)
     res = self.getEntity(self.invokeGet(url))
     return True if res else False
Пример #22
0
 def countChildren(self, obj: ParaObject, type2: str):
     """
     Count the total number of child objects for this object.
     @param obj: the object to execute this method on
     @param type2: the type of the other object
     @return: the number of links
     """
     if not obj or not obj.id or not type2:
         return 0
     params = {"count": "true", "childrenonly": "true"}
     pager = Pager()
     url = obj.getObjectURI() + "/links/" + self.urlenc(type2)
     self.getItems(self.getEntity(self.invokeGet(url, params)), pager=pager)
     return pager.count
Пример #23
0
 def findChildren(self, obj: ParaObject, type2: str, query: str, pager: Pager = None):
     """
     Search through all child objects. Only searches child objects directly
     connected to this parent via the {@code parentid} field.
     @param obj: the object to execute this method on
     @param type2: the type of children to look for
     @param query: a query string
     @param pager: a Pager
     @return: a list of ParaObject in a one-to-many relationship with this object
     """
     if not obj or not obj.id or not type2:
         return []
     params = self.pagerToParams(pager)
     params["childrenonly"] = "true"
     params["q"] = query
     url = obj.getObjectURI() + "/links/" + self.urlenc(type2)
     return self.getItems(self.getEntity(self.invokeGet(url, params)), pager=pager)
Пример #24
0
 def findLinkedObjects(self, obj: ParaObject, type2: str, field: str = "name", query: str = "*",
                       pager: Pager = None):
     """
     Searches through all linked objects in many-to-many relationships.
     @param obj: the object to execute this method on
     @param type2: type of linked objects to search for
     @param field: the name of the field to target (within a nested field "nstd")
     @param query: a query string
     @param pager: a Pager
     @return: a list of linked objects
     """
     if not obj or not obj.id or not type2:
         return []
     params = self.pagerToParams(pager)
     params["field"] = field
     params["q"] = query
     url = obj.getObjectURI() + "/links/" + self.urlenc(type2)
     return self.getItems(self.getEntity(self.invokeGet(url, params)), pager=pager)
    def testCRUD(self):
        self.assertIsNotNone(self.pc.create(ParaObject()))
        t1 = self.pc.create(ParaObject("test1", "tag"))
        t1["tag"] = "test1"
        self.assertIsNotNone(t1)

        self.assertIsNone(self.pc.read(None, None))
        self.assertIsNone(self.pc.read("", ""))

        tr_id = self.pc.read(id_=t1.id)
        self.assertIsNotNone(tr_id)
        self.assertIsNotNone(tr_id.timestamp)
        self.assertEqual(t1.tag, tr_id.tag)

        tr = self.pc.read(t1.type, t1.id)
        self.assertIsNotNone(tr)
        self.assertIsNotNone(tr.timestamp)
        self.assertEqual(t1["tag"], tr["tag"])

        tr["count"] = 15
        tu = self.pc.update(tr)
        self.assertIsNone(self.pc.update(ParaObject("None")))
        self.assertIsNotNone(tu)
        self.assertEqual(tu["count"], tr["count"])
        self.assertIsNotNone(tu.updated)

        s = ParaObject()
        s.type = self.dogsType
        s["foo"] = "bark!"
        s = self.pc.create(s)

        dog = self.pc.read(self.dogsType, s.id)
        self.assertIsNotNone(dog["foo"])
        self.assertEqual("bark!", dog["foo"])

        self.pc.delete(t1)
        self.pc.delete(dog)
        self.assertIsNone(self.pc.read(tr.type, tr.id))
    def testBatchCRUD(self):
        dogs = []
        for i in range(0, 3):
            s = ParaObject()
            s.type = self.dogsType
            s["foo"] = "bark!"
            dogs.append(s)

        self.assertIs(len(self.pc.createAll(None)), 0)
        l1 = self.pc.createAll(dogs)
        self.assertEqual(3, len(l1))
        self.assertIsNotNone(l1[0].id)

        self.assertIs(len(self.pc.readAll(None)), 0)
        nl = []
        self.assertIs(len(self.pc.readAll(nl)), 0)
        nl.append(l1[0].id)
        nl.append(l1[1].id)
        nl.append(l1[2].id)
        l2 = self.pc.readAll(nl)
        self.assertEqual(3, len(l2))
        self.assertEqual(l1[0].id, l2[0].id)
        self.assertEqual(l1[1].id, l2[1].id)
        self.assertIsNotNone(l2[0]["foo"])
        self.assertEqual("bark!", l2[0]["foo"])

        self.assertIs(len(self.pc.updateAll(None)), 0)

        part1 = ParaObject(l1[0].id)
        part2 = ParaObject(l1[1].id)
        part3 = ParaObject(l1[2].id)
        part1.type = self.dogsType
        part2.type = self.dogsType
        part3.type = self.dogsType

        part1["custom"] = "prop"
        part1.name = "NewName1"
        part2.name = "NewName2"
        part3.name = "NewName3"

        l3 = self.pc.updateAll([part1, part2, part3])

        self.assertIsNotNone(l3[0]["custom"])
        self.assertEqual(self.dogsType, l3[0].type)
        self.assertEqual(self.dogsType, l3[1].type)
        self.assertEqual(self.dogsType, l3[2].type)

        self.assertEqual(part1.name, l3[0].name)
        self.assertEqual(part2.name, l3[1].name)
        self.assertEqual(part3.name, l3[2].name)

        self.pc.deleteAll(nl)
        sleep(1)

        l4 = self.pc.list(self.dogsType)
        self.assertIs(len(l4), 0)

        self.assertIs(self.dogsType in self.pc.getApp()["datatypes"].values(),
                      True)