Пример #1
0
 def test_unicode_deserialize(self):
     """
     UnicodeAttribute.deserialize
     """
     attr = UnicodeAttribute()
     assert attr.deserialize('foo') == six.u('foo')
     assert attr.deserialize(u'foo') == six.u('foo')
Пример #2
0
 def test_unicode_deserialize(self):
     """
     UnicodeAttribute.deserialize
     """
     attr = UnicodeAttribute()
     self.assertEqual(attr.deserialize('foo'), six.u('foo'))
     self.assertEqual(attr.deserialize(u'foo'), six.u('foo'))
Пример #3
0
 def test_unicode_serialize(self):
     """
     UnicodeAttribute.serialize
     """
     attr = UnicodeAttribute()
     assert attr.serialize('foo') == six.u('foo')
     assert attr.serialize(u'foo') == six.u('foo')
     assert attr.serialize(u'') is None
     assert attr.serialize(None) is None
Пример #4
0
 def test_unicode_serialize(self):
     """
     UnicodeAttribute.serialize
     """
     attr = UnicodeAttribute()
     self.assertEqual(attr.serialize("foo"), six.u("foo"))
     self.assertEqual(attr.serialize(u"foo"), six.u("foo"))
     self.assertEqual(attr.serialize(u""), None)
     self.assertEqual(attr.serialize(None), None)
Пример #5
0
 def test_unicode_serialize(self):
     """
     UnicodeAttribute.serialize
     """
     attr = UnicodeAttribute()
     self.assertEqual(attr.serialize('foo'), six.u('foo'))
     self.assertEqual(attr.serialize(u'foo'), six.u('foo'))
     self.assertEqual(attr.serialize(u''), None)
     self.assertEqual(attr.serialize(None), None)
Пример #6
0
class Photo(Model):
    """
    Photo table for DynamoDB
    """
    class Meta:
        table_name = 'Photo'
        region = AWS_REGION

    user_id = UnicodeAttribute(hash_key=True)
    id = UnicodeAttribute(range_key=True)
    tags = UnicodeAttribute(null=True)
    desc = UnicodeAttribute(null=True)
    filename_orig = UnicodeAttribute(null=True)
    filename = UnicodeAttribute(null=True)
    filesize = NumberAttribute(null=True)
    geotag_lat = UnicodeAttribute(null=True)
    geotag_lng = UnicodeAttribute(null=True)
    upload_date = UTCDateTimeAttribute(default=datetime.now(get_localzone()))
    taken_date = UTCDateTimeAttribute(null=True)
    make = UnicodeAttribute(null=True)
    model = UnicodeAttribute(null=True)
    width = UnicodeAttribute(null=True)
    height = UnicodeAttribute(null=True)
    city = UnicodeAttribute(null=True)
    nation = UnicodeAttribute(null=True)
    address = UnicodeAttribute(null=True)
Пример #7
0
class UserModel(Model):
  """
  DYnamoDB UserModel
  """
  class Meta():
    table_name = os.environ['usersTable']
    if 'IS_LOCAL' in os.environ:
      host = 'http://localhost:8000'
    else:
      region = os.environ['AWS_REGION']
      host = 'https://dynamodb.{}.amazonaws.com'.format(region)
  id = UnicodeAttribute(hash_key = True)
  email = UnicodeAttribute()
  users_gsi_email = EmailIndex()
  userToken = UnicodeAttribute(null = True)
  users_gsi_userToken = UserTokonIndex()
  name = UnicodeAttribute()
  phoneNumber = UnicodeAttribute()
  expiry = UTCDateTimeAttribute(null = True)
  password = UnicodeAttribute()
  createdAt = UTCDateTimeAttribute(default = datetime.now())
  updatedAt = UTCDateTimeAttribute(default = datetime.now())
  lastLogin = UTCDateTimeAttribute(default = datetime.now())
  deleteFlag = BooleanAttribute(default = False)
  
  def __iter__(self):
    for name, attr in self.get_attributes().items():
      if name not in ['deleteFlag', 'password', 'userToken', 'expiry']:
        yield name, attr.serialize(getattr(self, name))

  @classmethod
  def get(cls,
          hash_key,
          range_key=None,
          consistent_read=False,
          attributes_to_get=None):
    """
    override: get()
    """
    user = super().get(hash_key, range_key, consistent_read, attributes_to_get)
    if not user.deleteFlag:
      return user
    else:
      raise cls.DoesNotExist()

  def update(self, actions = [], condition = None):
    actions.append(UserModel.updatedAt.set(datetime.now()))
    super().update(actions, condition)

  def save(self, condition = None):
    self.before_save()
    self.updatedAt = datetime.now()
    super().save(condition)

  def before_save(self):
    # validation for name
    if not self.name:
      raise InvalidNameError('The name attribute has not to be empty')
    if not isinstance(self.name, str):
      raise InvalidNameError('The name attribute has to be string')
    # validation for phoneNumber
    if not self.phoneNumber:
      raise InvalidPhoneNumberError('The phoneNumber attribute has not to be empty')
    if not isinstance(self.phoneNumber, str):
      raise InvalidPhoneNumberError('The phoneNumber attribute has to be string')
    if not re.match(r'^0\d{9,10}$', self.phoneNumber):
      raise InvalidPhoneNumberError('Invalid phoneNumber')
    # validation for email
    if not self.email:
      raise InvalidEmailError('The email attribute has to be string')
    if not isinstance(self.email, str):
      raise InvalidEmailError('The email attribute has not to be empty')
    if not re.match(r'[A-Za-z0-9\._+]+@[A-Za-z]+\.[A-Za-z]', self.email):
      raise InvalidEmailError('Invalid email')
    if self.email_uniqueness():
      raise InvalidEmailError('This email has been registered')

  def logic_delete(self):
    """
    change deleteFlag to True
    """
    actions = [
      UserModel.deleteFlag.set(True),
      UserModel.userToken.remove(),
      UserModel.expiry.remove()
    ]
    self.update(actions)
  
  def email_uniqueness(self):
    check = UserModel.users_gsi_email.query(
      self.email,
      UserModel.deleteFlag == False
    )
    check = [ele for ele in check]
    if len(check) == 0:
      return False
    else:
      if self.id == check[0].id:
        return False
      else:
        return True
  
  def get_tasks(self):
    tasks = models.task_model.TaskModel.scan(
      (models.task_model.TaskModel.userIds.contains(self.id)) &
      (models.task_model.TaskModel.deleteFlag == False)
    )
    return tasks

  def hash_password(self):
    if not self.password:
      raise InvalidPasswordError('no password')
    if not isinstance(self.password, str):
      raise InvalidPasswordError('password must be string')
    if len(self.password) < 8:
      raise InvalidPasswordError('password is longer than 8')
    hash = hashlib.sha256()
    hash.update(self.password.encode() + self.email.encode())
    self.password = hash.hexdigest()

  def create_token(self):
    self.userToken = secrets.token_hex()
    self.expiry = datetime.now() + timedelta(weeks = 2)
  
  def get_expiry(self):
    return self.get_attributes()['expiry'].serialize(self.expiry)
Пример #8
0
class MessageAttribute(MapAttribute):
    MessageContent = UnicodeAttribute(null=False)
    ImagePath = UnicodeAttribute(null=True)
    Timestamp = UTCDateTimeAttribute(null=True)
Пример #9
0
class CustomAttrMap(MapAttribute):
    overridden_number_attr = NumberAttribute(attr_name="number_attr")
    overridden_unicode_attr = UnicodeAttribute(attr_name="unicode_attr")
Пример #10
0
class UpdateExpressionTestCase(TestCase):

    def setUp(self):
        self.attribute = UnicodeAttribute(attr_name='foo')
        self.list_attribute = ListAttribute(attr_name='foo_list', default=[])

    def test_set_action(self):
        action = self.attribute.set('bar')
        placeholder_names, expression_attribute_values = {}, {}
        expression = action.serialize(placeholder_names, expression_attribute_values)
        assert expression == "#0 = :0"
        assert placeholder_names == {'foo': '#0'}
        assert expression_attribute_values == {':0': {'S': 'bar'}}

    def test_set_action_attribute_container(self):
        # Simulate initialization from inside an AttributeContainer
        my_map_attribute = MapAttribute(attr_name='foo')
        my_map_attribute._make_attribute()
        my_map_attribute._update_attribute_paths(my_map_attribute.attr_name)

        action = my_map_attribute.set(MapAttribute(bar='baz'))
        placeholder_names, expression_attribute_values = {}, {}
        expression = action.serialize(placeholder_names, expression_attribute_values)
        assert expression == "#0 = :0"
        assert placeholder_names == {'foo': '#0'}
        assert expression_attribute_values == {':0': {'M': {'bar': {'S': 'baz'}}}}

    def test_increment_action(self):
        action = self.attribute.set(Path('bar') + 0)
        placeholder_names, expression_attribute_values = {}, {}
        expression = action.serialize(placeholder_names, expression_attribute_values)
        assert expression == "#0 = #1 + :0"
        assert placeholder_names == {'foo': '#0', 'bar': '#1'}
        assert expression_attribute_values == {':0': {'N': '0'}}

    def test_increment_action_value(self):
        action = self.attribute.set(Value(0) + Path('bar'))
        placeholder_names, expression_attribute_values = {}, {}
        expression = action.serialize(placeholder_names, expression_attribute_values)
        assert expression == "#0 = :0 + #1"
        assert placeholder_names == {'foo': '#0', 'bar': '#1'}
        assert expression_attribute_values == {':0': {'N': '0'}}

    def test_decrement_action(self):
        action = self.attribute.set(Path('bar') - 0)
        placeholder_names, expression_attribute_values = {}, {}
        expression = action.serialize(placeholder_names, expression_attribute_values)
        assert expression == "#0 = #1 - :0"
        assert placeholder_names == {'foo': '#0', 'bar': '#1'}
        assert expression_attribute_values == {':0': {'N': '0'}}

    def test_decrement_action_value(self):
        action = self.attribute.set(Value(0) - Path('bar'))
        placeholder_names, expression_attribute_values = {}, {}
        expression = action.serialize(placeholder_names, expression_attribute_values)
        assert expression == "#0 = :0 - #1"
        assert placeholder_names == {'foo': '#0', 'bar': '#1'}
        assert expression_attribute_values == {':0': {'N': '0'}}

    def test_append_action(self):
        action = self.attribute.set(Path('bar').append(['baz']))
        placeholder_names, expression_attribute_values = {}, {}
        expression = action.serialize(placeholder_names, expression_attribute_values)
        assert expression == "#0 = list_append (#1, :0)"
        assert placeholder_names == {'foo': '#0', 'bar': '#1'}
        assert expression_attribute_values == {':0': {'L': [{'S': 'baz'}]}}

    def test_prepend_action(self):
        action = self.attribute.set(Path('bar').prepend(['baz']))
        placeholder_names, expression_attribute_values = {}, {}
        expression = action.serialize(placeholder_names, expression_attribute_values)
        assert expression == "#0 = list_append (:0, #1)"
        assert placeholder_names == {'foo': '#0', 'bar': '#1'}
        assert expression_attribute_values == {':0': {'L': [{'S': 'baz'}]}}

    def test_conditional_set_action(self):
        action = self.attribute.set(Path('bar') | 'baz')
        placeholder_names, expression_attribute_values = {}, {}
        expression = action.serialize(placeholder_names, expression_attribute_values)
        assert expression == "#0 = if_not_exists (#1, :0)"
        assert placeholder_names == {'foo': '#0', 'bar': '#1'}
        assert expression_attribute_values == {':0': {'S': 'baz'}}

    def test_remove_action(self):
        action = self.attribute.remove()
        placeholder_names, expression_attribute_values = {}, {}
        expression = action.serialize(placeholder_names, expression_attribute_values)
        assert expression == "#0"
        assert placeholder_names == {'foo': '#0'}
        assert expression_attribute_values == {}

    def test_add_action(self):
        action = Path('foo').add(0)
        placeholder_names, expression_attribute_values = {}, {}
        expression = action.serialize(placeholder_names, expression_attribute_values)
        assert expression == "#0 :0"
        assert placeholder_names == {'foo': '#0'}
        assert expression_attribute_values == {':0': {'N': '0'}}

    def test_add_action_set(self):
        action = NumberSetAttribute(attr_name='foo').add(0, 1)
        placeholder_names, expression_attribute_values = {}, {}
        expression = action.serialize(placeholder_names, expression_attribute_values)
        assert expression == "#0 :0"
        assert placeholder_names == {'foo': '#0'}
        assert expression_attribute_values == {':0': {'NS': ['0', '1']}}

    def test_add_action_serialized(self):
        action = NumberSetAttribute(attr_name='foo').add({'NS': ['0']})
        placeholder_names, expression_attribute_values = {}, {}
        expression = action.serialize(placeholder_names, expression_attribute_values)
        assert expression == "#0 :0"
        assert placeholder_names == {'foo': '#0'}
        assert expression_attribute_values == {':0': {'NS': ['0']}}

    def test_add_action_list(self):
        with self.assertRaises(ValueError):
            Path('foo').add({'L': [{'N': '0'}]})

    def test_delete_action(self):
        action = NumberSetAttribute(attr_name='foo').delete(0, 1)
        placeholder_names, expression_attribute_values = {}, {}
        expression = action.serialize(placeholder_names, expression_attribute_values)
        assert expression == "#0 :0"
        assert placeholder_names == {'foo': '#0'}
        assert expression_attribute_values == {':0': {'NS': ['0', '1']}}

    def test_delete_action_set(self):
        action = NumberSetAttribute(attr_name='foo').delete({0, 1})
        placeholder_names, expression_attribute_values = {}, {}
        expression = action.serialize(placeholder_names, expression_attribute_values)
        assert expression == "#0 :0"
        assert placeholder_names == {'foo': '#0'}
        assert expression_attribute_values == {':0': {'NS': ['0', '1']}}

    def test_delete_action_serialized(self):
        action = NumberSetAttribute(attr_name='foo').delete({'NS': ['0']})
        placeholder_names, expression_attribute_values = {}, {}
        expression = action.serialize(placeholder_names, expression_attribute_values)
        assert expression == "#0 :0"
        assert placeholder_names == {'foo': '#0'}
        assert expression_attribute_values == {':0': {'NS': ['0']}}

    def test_delete_action_non_set(self):
        with self.assertRaises(ValueError):
            Path('foo').delete({'N': '0'})

    def test_update(self):
        update = Update(
            self.attribute.set({'S': 'bar'}),
            self.attribute.remove(),
            self.attribute.add({'N': '0'}),
            self.attribute.delete({'NS': ['0']})
        )
        placeholder_names, expression_attribute_values = {}, {}
        expression = update.serialize(placeholder_names, expression_attribute_values)
        assert expression == "SET #0 = :0 REMOVE #0 ADD #0 :1 DELETE #0 :2"
        assert placeholder_names == {'foo': '#0'}
        assert expression_attribute_values == {
            ':0': {'S': 'bar'},
            ':1': {'N': '0'},
            ':2': {'NS': ['0']}
        }

    def test_list_update_remove_by_index(self):
        update = Update(
            self.list_attribute.remove_indexes(0),
        )
        placeholder_names, expression_attribute_values = {}, {}
        expression = update.serialize(placeholder_names, expression_attribute_values)
        assert expression == "REMOVE #0[0]"
        assert placeholder_names == {'foo_list': '#0'}
        assert expression_attribute_values == {}

        update = Update(
            self.list_attribute.remove_indexes(0, 10),
        )
        placeholder_names, expression_attribute_values = {}, {}
        expression = update.serialize(placeholder_names, expression_attribute_values)
        assert expression == "REMOVE #0[0], #0[10]"
        assert placeholder_names == {'foo_list': '#0'}
        assert expression_attribute_values == {}

        with self.assertRaises(ValueError) as e:
            Update(self.list_attribute.remove_indexes(0, "a"))
        assert str(e.exception) == "Method 'remove_indexes' arguments must be 'int'"
Пример #11
0
class ConditionExpressionTestCase(TestCase):

    def setUp(self):
        self.attribute = UnicodeAttribute(attr_name='foo')

    def test_equal(self):
        condition = self.attribute == 'bar'
        placeholder_names, expression_attribute_values = {}, {}
        expression = condition.serialize(placeholder_names, expression_attribute_values)
        assert expression == "#0 = :0"
        assert placeholder_names == {'foo': '#0'}
        assert expression_attribute_values == {':0': {'S': 'bar'}}

    def test_not_equal(self):
        condition = self.attribute != 'bar'
        placeholder_names, expression_attribute_values = {}, {}
        expression = condition.serialize(placeholder_names, expression_attribute_values)
        assert expression == "#0 <> :0"
        assert placeholder_names == {'foo': '#0'}
        assert expression_attribute_values == {':0': {'S': 'bar'}}

    def test_less_than(self):
        condition = self.attribute < 'bar'
        placeholder_names, expression_attribute_values = {}, {}
        expression = condition.serialize(placeholder_names, expression_attribute_values)
        assert expression == "#0 < :0"
        assert placeholder_names == {'foo': '#0'}
        assert expression_attribute_values == {':0': {'S': 'bar'}}

    def test_less_than_or_equal(self):
        condition = self.attribute <= 'bar'
        placeholder_names, expression_attribute_values = {}, {}
        expression = condition.serialize(placeholder_names, expression_attribute_values)
        assert expression == "#0 <= :0"
        assert placeholder_names == {'foo': '#0'}
        assert expression_attribute_values == {':0': {'S': 'bar'}}

    def test_greater_than(self):
        condition = self.attribute > 'bar'
        placeholder_names, expression_attribute_values = {}, {}
        expression = condition.serialize(placeholder_names, expression_attribute_values)
        assert expression == "#0 > :0"
        assert placeholder_names == {'foo': '#0'}
        assert expression_attribute_values == {':0': {'S': 'bar'}}

    def test_greater_than_or_equal(self):
        condition = self.attribute >= 'bar'
        placeholder_names, expression_attribute_values = {}, {}
        expression = condition.serialize(placeholder_names, expression_attribute_values)
        assert expression == "#0 >= :0"
        assert placeholder_names == {'foo': '#0'}
        assert expression_attribute_values == {':0': {'S': 'bar'}}

    def test_between(self):
        condition = self.attribute.between('bar', 'baz')
        placeholder_names, expression_attribute_values = {}, {}
        expression = condition.serialize(placeholder_names, expression_attribute_values)
        assert expression == "#0 BETWEEN :0 AND :1"
        assert placeholder_names == {'foo': '#0'}
        assert expression_attribute_values == {':0': {'S': 'bar'}, ':1': {'S': 'baz'}}

    def test_in(self):
        condition = self.attribute.is_in('bar', 'baz')
        placeholder_names, expression_attribute_values = {}, {}
        expression = condition.serialize(placeholder_names, expression_attribute_values)
        assert expression == "#0 IN (:0, :1)"
        assert placeholder_names == {'foo': '#0'}
        assert expression_attribute_values == {':0': {'S': 'bar'}, ':1': {'S': 'baz'}}

    def test_exists(self):
        condition = self.attribute.exists()
        placeholder_names, expression_attribute_values = {}, {}
        expression = condition.serialize(placeholder_names, expression_attribute_values)
        assert expression == "attribute_exists (#0)"
        assert placeholder_names == {'foo': '#0'}
        assert expression_attribute_values == {}

    def test_does_not_exist(self):
        condition = self.attribute.does_not_exist()
        placeholder_names, expression_attribute_values = {}, {}
        expression = condition.serialize(placeholder_names, expression_attribute_values)
        assert expression == "attribute_not_exists (#0)"
        assert placeholder_names == {'foo': '#0'}
        assert expression_attribute_values == {}

    def test_is_type(self):
        condition = self.attribute.is_type()
        placeholder_names, expression_attribute_values = {}, {}
        expression = condition.serialize(placeholder_names, expression_attribute_values)
        assert expression == "attribute_type (#0, :0)"
        assert placeholder_names == {'foo': '#0'}
        assert expression_attribute_values == {':0': {'S' : 'S'}}

    def test_begins_with(self):
        condition = self.attribute.startswith('bar')
        placeholder_names, expression_attribute_values = {}, {}
        expression = condition.serialize(placeholder_names, expression_attribute_values)
        assert expression == "begins_with (#0, :0)"
        assert placeholder_names == {'foo': '#0'}
        assert expression_attribute_values == {':0': {'S' : 'bar'}}

    def test_contains(self):
        condition = self.attribute.contains('bar')
        placeholder_names, expression_attribute_values = {}, {}
        expression = condition.serialize(placeholder_names, expression_attribute_values)
        assert expression == "contains (#0, :0)"
        assert placeholder_names == {'foo': '#0'}
        assert expression_attribute_values == {':0': {'S' : 'bar'}}

    def test_contains_string_set(self):
        condition = UnicodeSetAttribute(attr_name='foo').contains('bar')
        placeholder_names, expression_attribute_values = {}, {}
        expression = condition.serialize(placeholder_names, expression_attribute_values)
        assert expression == "contains (#0, :0)"
        assert placeholder_names == {'foo': '#0'}
        assert expression_attribute_values == {':0': {'S' : 'bar'}}

    def test_contains_number_set(self):
        condition = NumberSetAttribute(attr_name='foo').contains(1)
        placeholder_names, expression_attribute_values = {}, {}
        expression = condition.serialize(placeholder_names, expression_attribute_values)
        assert expression == "contains (#0, :0)"
        assert placeholder_names == {'foo': '#0'}
        assert expression_attribute_values == {':0': {'N' : '1'}}

    def test_contains_list(self):
        condition = ListAttribute(attr_name='foo').contains('bar')
        placeholder_names, expression_attribute_values = {}, {}
        expression = condition.serialize(placeholder_names, expression_attribute_values)
        assert expression == "contains (#0, :0)"
        assert placeholder_names == {'foo': '#0'}
        assert expression_attribute_values == {':0': {'S' : 'bar'}}

    def test_contains_attribute(self):
        condition = ListAttribute(attr_name='foo').contains(Path('bar'))
        placeholder_names, expression_attribute_values = {}, {}
        expression = condition.serialize(placeholder_names, expression_attribute_values)
        assert expression == "contains (#0, #1)"
        assert placeholder_names == {'foo': '#0', 'bar': '#1'}
        assert expression_attribute_values == {}

    def test_size(self):
        condition = size(self.attribute) == 3
        placeholder_names, expression_attribute_values = {}, {}
        expression = condition.serialize(placeholder_names, expression_attribute_values)
        assert expression == "size (#0) = :0"
        assert placeholder_names == {'foo': '#0'}
        assert expression_attribute_values == {':0': {'N' : '3'}}

    def test_sizes(self):
        condition = size(self.attribute) == size(Path('bar'))
        placeholder_names, expression_attribute_values = {}, {}
        expression = condition.serialize(placeholder_names, expression_attribute_values)
        assert expression == "size (#0) = size (#1)"
        assert placeholder_names == {'foo': '#0', 'bar': '#1'}
        assert expression_attribute_values == {}

    def test_and(self):
        condition = (self.attribute < 'bar') & (self.attribute > 'baz')
        placeholder_names, expression_attribute_values = {}, {}
        expression = condition.serialize(placeholder_names, expression_attribute_values)
        assert expression == "(#0 < :0 AND #0 > :1)"
        assert placeholder_names == {'foo': '#0'}
        assert expression_attribute_values == {':0': {'S': 'bar'}, ':1': {'S': 'baz'}}

    def test_invalid_and(self):
        condition = self.attribute < 'bar'
        with self.assertRaises(TypeError):
            condition &= None

    def test_rand(self):
        condition = None
        condition &= self.attribute < 'bar'
        placeholder_names, expression_attribute_values = {}, {}
        expression = condition.serialize(placeholder_names, expression_attribute_values)
        assert expression == "#0 < :0"
        assert placeholder_names == {'foo': '#0'}
        assert expression_attribute_values == {':0': {'S': 'bar'}}

    def test_invalid_rand(self):
        condition = 42
        with self.assertRaises(TypeError):
            condition &= self.attribute < 'bar'

    def test_or(self):
        condition = (self.attribute < 'bar') | (self.attribute > 'baz')
        placeholder_names, expression_attribute_values = {}, {}
        expression = condition.serialize(placeholder_names, expression_attribute_values)
        assert expression == "(#0 < :0 OR #0 > :1)"
        assert placeholder_names == {'foo': '#0'}
        assert expression_attribute_values == {':0': {'S': 'bar'}, ':1': {'S': 'baz'}}

    def test_invalid_or(self):
        condition = self.attribute < 'bar'
        with self.assertRaises(TypeError):
            condition |= None

    def test_not(self):
        condition = ~(self.attribute < 'bar')
        placeholder_names, expression_attribute_values = {}, {}
        expression = condition.serialize(placeholder_names, expression_attribute_values)
        assert expression == "(NOT #0 < :0)"
        assert placeholder_names == {'foo': '#0'}
        assert expression_attribute_values == {':0': {'S': 'bar'}}

    def test_compound_logic(self):
        condition = (~(self.attribute < 'bar') & (self.attribute > 'baz')) | (self.attribute == 'foo')
        placeholder_names, expression_attribute_values = {}, {}
        expression = condition.serialize(placeholder_names, expression_attribute_values)
        assert expression == "(((NOT #0 < :0) AND #0 > :1) OR #0 = :2)"
        assert placeholder_names == {'foo': '#0'}
        assert expression_attribute_values == {':0': {'S': 'bar'}, ':1': {'S': 'baz'}, ':2': {'S': 'foo'}}

    def test_indexing(self):
        condition = ListAttribute(attr_name='foo')[0] == 'bar'
        placeholder_names, expression_attribute_values = {}, {}
        expression = condition.serialize(placeholder_names, expression_attribute_values)
        assert expression == "#0[0] = :0"
        assert placeholder_names == {'foo': '#0'}
        assert expression_attribute_values == {':0': {'S' : 'bar'}}

    def test_invalid_indexing(self):
        with self.assertRaises(TypeError):
            self.attribute[0]

    def test_double_indexing(self):
        condition = ListAttribute(attr_name='foo')[0][1] == 'bar'
        placeholder_names, expression_attribute_values = {}, {}
        expression = condition.serialize(placeholder_names, expression_attribute_values)
        assert expression == "#0[0][1] = :0"
        assert placeholder_names == {'foo': '#0'}
        assert expression_attribute_values == {':0': {'S' : 'bar'}}

    def test_map_comparison(self):
        # Simulate initialization from inside an AttributeContainer
        my_map_attribute = MapAttribute(attr_name='foo')
        my_map_attribute._make_attribute()
        my_map_attribute._update_attribute_paths(my_map_attribute.attr_name)

        condition = my_map_attribute == MapAttribute(bar='baz')
        placeholder_names, expression_attribute_values = {}, {}
        expression = condition.serialize(placeholder_names, expression_attribute_values)
        assert expression == "#0 = :0"
        assert placeholder_names == {'foo': '#0'}
        assert expression_attribute_values == {':0': {'M': {'bar': {'S': 'baz'}}}}

    def test_list_comparison(self):
        condition = ListAttribute(attr_name='foo') == ['bar', 'baz']
        placeholder_names, expression_attribute_values = {}, {}
        expression = condition.serialize(placeholder_names, expression_attribute_values)
        assert expression == "#0 = :0"
        assert placeholder_names == {'foo': '#0'}
        assert expression_attribute_values == {':0': {'L': [{'S' : 'bar'}, {'S': 'baz'}]}}

    def test_dotted_attribute_name(self):
        self.attribute.attr_name = 'foo.bar'
        condition = self.attribute == 'baz'
        placeholder_names, expression_attribute_values = {}, {}
        expression = condition.serialize(placeholder_names, expression_attribute_values)
        assert expression == "#0 = :0"
        assert placeholder_names == {'foo.bar': '#0'}
        assert expression_attribute_values == {':0': {'S': 'baz'}}

    def test_map_attribute_indexing(self):
        # Simulate initialization from inside an AttributeContainer
        my_map_attribute = MapAttribute(attr_name='foo.bar')
        my_map_attribute._make_attribute()
        my_map_attribute._update_attribute_paths(my_map_attribute.attr_name)

        condition = my_map_attribute['foo'] == 'baz'
        placeholder_names, expression_attribute_values = {}, {}
        expression = condition.serialize(placeholder_names, expression_attribute_values)
        assert expression == "#0.#1 = :0"
        assert placeholder_names == {'foo.bar': '#0', 'foo': '#1'}
        assert expression_attribute_values == {':0': {'S': 'baz'}}

    def test_map_attribute_dereference(self):
        class MyMapAttribute(MapAttribute):
            nested_string = self.attribute

        # Simulate initialization from inside an AttributeContainer
        my_map_attribute = MyMapAttribute(attr_name='foo.bar')
        my_map_attribute._make_attribute()
        my_map_attribute._update_attribute_paths(my_map_attribute.attr_name)

        condition = my_map_attribute.nested_string == 'baz'
        placeholder_names, expression_attribute_values = {}, {}
        expression = condition.serialize(placeholder_names, expression_attribute_values)
        assert expression == "#0.#1 = :0"
        assert placeholder_names == {'foo.bar': '#0', 'foo': '#1'}
        assert expression_attribute_values == {':0': {'S': 'baz'}}

    def test_map_attribute_dereference_via_indexing(self):
        class MyMapAttribute(MapAttribute):
            nested_string = self.attribute

        # Simulate initialization from inside an AttributeContainer
        my_map_attribute = MyMapAttribute(attr_name='foo.bar')
        my_map_attribute._make_attribute()
        my_map_attribute._update_attribute_paths(my_map_attribute.attr_name)

        condition = my_map_attribute['nested_string'] == 'baz'
        placeholder_names, expression_attribute_values = {}, {}
        expression = condition.serialize(placeholder_names, expression_attribute_values)
        assert expression == "#0.#1 = :0"
        assert placeholder_names == {'foo.bar': '#0', 'foo': '#1'}
        assert expression_attribute_values == {':0': {'S': 'baz'}}

    def test_map_attribute_dereference_via_indexing_missing_attribute(self):
        class MyMapAttribute(MapAttribute):
            nested_string = self.attribute

        # Simulate initialization from inside an AttributeContainer
        my_map_attribute = MyMapAttribute(attr_name='foo.bar')
        my_map_attribute._make_attribute()
        my_map_attribute._update_attribute_paths(my_map_attribute.attr_name)

        with self.assertRaises(AttributeError):
            my_map_attribute['missing_attribute'] == 'baz'
Пример #12
0
class StringValue(TypedValue, discriminator=class_name):
    value = UnicodeAttribute()
Пример #13
0
from datetime import datetime
from pynamodb.models import Model
from pynamodb.attributes import UnicodeAttribute, NumberAttribute, UTCDateTImeAttribute

class Entry(Model);
	class Meta:
		table_name = "serverless_blog_entries"
		region = 'ap-northeast-1'
		aws_access_key_id = 'AWS_ACCESS_KEY_ID'
		aws_secret_access_key = 'AWS_SECRET_ACCESS_KEY'
		host = "http://localhost:8000"
	id = NumberAttribute(hash_key=True, null=False)
	title = UnicodeAttribute(null=True)
	text = UnicodeAttribute(null=True)
	created_at = UTCDateTimeAttribute(default=datetime.now)

Пример #14
0
class Person(MapAttribute):
    firstName = UnicodeAttribute()
    lastName = UnicodeAttribute()
    age = NumberAttribute()
Пример #15
0
class Location(MapAttribute):
    latitude = NumberAttribute()
    longitude = NumberAttribute()
    name = UnicodeAttribute()
Пример #16
0
class ChildModel(DiscriminatorTestModel, discriminator='Child'):
    value = UnicodeAttribute()
Пример #17
0
class Scrap(Base):
    """
    スクラップモデル
    スクレイピングデータを扱う
    """
    class Meta:
        table_name = 'scrap'

    # スクレイピング対象のURL
    scrap_url = UnicodeAttribute(hash_key=True, null=False)
    # スクレイピング対象毎の連番
    unit_id = NumberAttribute(range_key=True, null=False)
    # 取得したテキスト
    text = UnicodeAttribute(null=False)
    # リンク先のURL
    redirect_url = UnicodeAttribute()
    # 公開日時
    released_at = UnicodeAttribute(null=False)

    def save(
            self,
            condition=None,
            conditional_operator=None,
            **expected_values
    ):
        """
        保存処理
        unit_idをインクリメント設定させるので、
        オーバーライド
        """
        # idをインクリメント
        self.unit_id = Sequence.next_sequence('Scrap_'+self.scrap_url)

        super().save(
            condition=condition,
            conditional_operator=conditional_operator,
            **expected_values
        )

    @classmethod
    def get_latest(cls, scrap_url):
        """ 最新データ取得 """
        latest_unit_id = cls.__get_latest_unit_id(scrap_url)
        if latest_unit_id is None:
            return None

        try:
            return cls.get(scrap_url, latest_unit_id)
        except cls.DoesNotExist:
            return None

    @classmethod
    def __get_latest_unit_id(cls, scrap_url):
        try:
            return Sequence.get(
                cls.__target_sequence_name(scrap_url)
            ).current_id
        except Sequence.DoesNotExist:
            return None

    @classmethod
    def __target_sequence_name(cls, scrap_url):
        """ unit_idのシーケンス管理用の名前 """
        return "{}_{}".format(__class__.__name__, scrap_url)
Пример #18
0
class CurrentHistoricalModel(BaseHistoricalModel):
    """The base Historical Current Table model base class."""

    eventTime = EventTimeAttribute(default=default_event_time)
    ttl = NumberAttribute(default=default_ttl())
    eventSource = UnicodeAttribute()
Пример #19
0
class MyModel(Model):
    Meta = dynamodb_table_meta(__name__)

    key = UnicodeAttribute(hash_key=True)
    value = IntegerAttribute(null=True)
Пример #20
0
class ShoppingQuery(MapAttribute):
    # ref: https://developers.naver.com/docs/search/shopping/
    query = UnicodeAttribute()
    display = NumberAttribute(default=50)
    sort = UnicodeAttribute(default='sim')
Пример #21
0
class ConditionExpressionTestCase(TestCase):
    def setUp(self):
        self.attribute = UnicodeAttribute(attr_name='foo')

    def test_equals(self):
        condition = self.attribute == 'bar'
        placeholder_names, expression_attribute_values = {}, {}
        expression = condition.serialize(placeholder_names,
                                         expression_attribute_values)
        assert expression == "#0 = :0"
        assert placeholder_names == {'foo': '#0'}
        assert expression_attribute_values == {':0': {'S': 'bar'}}

    def test_less_than(self):
        condition = self.attribute < 'bar'
        placeholder_names, expression_attribute_values = {}, {}
        expression = condition.serialize(placeholder_names,
                                         expression_attribute_values)
        assert expression == "#0 < :0"
        assert placeholder_names == {'foo': '#0'}
        assert expression_attribute_values == {':0': {'S': 'bar'}}

    def test_less_than_or_equal(self):
        condition = self.attribute <= 'bar'
        placeholder_names, expression_attribute_values = {}, {}
        expression = condition.serialize(placeholder_names,
                                         expression_attribute_values)
        assert expression == "#0 <= :0"
        assert placeholder_names == {'foo': '#0'}
        assert expression_attribute_values == {':0': {'S': 'bar'}}

    def test_greater_than(self):
        condition = self.attribute > 'bar'
        placeholder_names, expression_attribute_values = {}, {}
        expression = condition.serialize(placeholder_names,
                                         expression_attribute_values)
        assert expression == "#0 > :0"
        assert placeholder_names == {'foo': '#0'}
        assert expression_attribute_values == {':0': {'S': 'bar'}}

    def test_greater_than_or_equal(self):
        condition = self.attribute >= 'bar'
        placeholder_names, expression_attribute_values = {}, {}
        expression = condition.serialize(placeholder_names,
                                         expression_attribute_values)
        assert expression == "#0 >= :0"
        assert placeholder_names == {'foo': '#0'}
        assert expression_attribute_values == {':0': {'S': 'bar'}}

    def test_between(self):
        condition = self.attribute.between('bar', 'baz')
        placeholder_names, expression_attribute_values = {}, {}
        expression = condition.serialize(placeholder_names,
                                         expression_attribute_values)
        assert expression == "#0 BETWEEN :0 AND :1"
        assert placeholder_names == {'foo': '#0'}
        assert expression_attribute_values == {
            ':0': {
                'S': 'bar'
            },
            ':1': {
                'S': 'baz'
            }
        }

    def test_begins_with(self):
        condition = self.attribute.startswith('bar')
        placeholder_names, expression_attribute_values = {}, {}
        expression = condition.serialize(placeholder_names,
                                         expression_attribute_values)
        assert expression == "begins_with (#0, :0)"
        assert placeholder_names == {'foo': '#0'}
        assert expression_attribute_values == {':0': {'S': 'bar'}}

    def test_indexing(self):
        condition = ListAttribute(attr_name='foo')[0] == 'bar'
        placeholder_names, expression_attribute_values = {}, {}
        expression = condition.serialize(placeholder_names,
                                         expression_attribute_values)
        assert expression == "#0[0] = :0"
        assert placeholder_names == {'foo': '#0'}
        assert expression_attribute_values == {':0': {'S': 'bar'}}

    def test_invalid_indexing(self):
        with self.assertRaises(TypeError):
            self.attribute[0]

    def test_double_indexing(self):
        condition = ListAttribute(attr_name='foo')[0][1] == 'bar'
        placeholder_names, expression_attribute_values = {}, {}
        expression = condition.serialize(placeholder_names,
                                         expression_attribute_values)
        assert expression == "#0[0][1] = :0"
        assert placeholder_names == {'foo': '#0'}
        assert expression_attribute_values == {':0': {'S': 'bar'}}

    def test_list_comparison(self):
        condition = ListAttribute(attr_name='foo') == ['bar', 'baz']
        placeholder_names, expression_attribute_values = {}, {}
        expression = condition.serialize(placeholder_names,
                                         expression_attribute_values)
        assert expression == "#0 = :0"
        assert placeholder_names == {'foo': '#0'}
        assert expression_attribute_values == {
            ':0': {
                'L': [{
                    'S': 'bar'
                }, {
                    'S': 'baz'
                }]
            }
        }

    def test_dotted_attribute_name(self):
        self.attribute.attr_name = 'foo.bar'
        condition = self.attribute == 'baz'
        placeholder_names, expression_attribute_values = {}, {}
        expression = condition.serialize(placeholder_names,
                                         expression_attribute_values)
        assert expression == "#0 = :0"
        assert placeholder_names == {'foo.bar': '#0'}
        assert expression_attribute_values == {':0': {'S': 'baz'}}
Пример #22
0
class RenamedValue(TypedValue, discriminator='custom_name'):
    value = UnicodeAttribute()
class JiraBug(pynamodb.models.Model):
    id = UnicodeAttribute(hash_key=True)
    key = UnicodeAttribute()
    project = UnicodeAttribute()
    summary = UnicodeAttribute()
    description = UnicodeAttribute(null=True)
    issuetype = UnicodeAttribute()
    universal_id = UnicodeAttribute(null=True)

    table_parameter_name = "/tables/bugdex/jira_bugs"

    class Meta:
        table_name = "bugdex_jira_bugs_v1"
        region = "us-west-2"

    @classmethod
    def from_issue_dict(cls, issue_key, issue_dict):
        return cls(
            key=issue_key,
            project=issue_dict['project']['id'],
            summary=issue_dict['summary'],
            description=issue_dict['description'],
            issuetype=issue_dict['issuetype']['name'],
        )

    @classmethod
    def from_raw_issue(cls, issue: Issue):
        for existing_bug in cls.query(issue.id):
            if existing_bug.universal_id:
                universal_id = existing_bug.universal_id
                break
        else:
            universal_id = str(uuid4()).lower()

        return cls(
            id=issue.id,
            key=issue.key,
            project=issue.fields.project.key,
            summary=issue.fields.summary,
            description=issue.fields.description,
            issuetype=issue.fields.issuetype.name,
            universal_id=universal_id,
        )

    def to_raw_issue(self, jira_server: JIRA):
        return jira_server.issue(self.key)

    @classmethod
    def ingest(cls, jira_server: JIRA, issues: Iterable[Issue] = ()) -> Iterable[JiraBug]:
        from .core import UniversalBug

        jql_str = """
        (labels = AppSec)
        AND (resolution is EMPTY OR status in (Reopened))
        AND status not in (Closed, Resolved) ORDER BY summary ASC, created ASC
        """.strip()

        if not issues:
            issues = chain(
                search_issues_with_scrolling(jira_server, jql_str),
            )

        visited = set()

        for issue in issues:
            if issue.key in visited:
                continue
            bug = cls.from_raw_issue(issue)
            bug.save()
            UniversalBug.propose(
                universal_id=bug.universal_id,
                source='jira',
                source_specific_id=bug.id,
            )
            yield bug
            visited.add(bug.key)

    @classmethod
    def ingest_one(cls, jira_server: JIRA, issue: Issue, canonical_bug=None):
        from .core import UniversalBug

        bug = cls.from_raw_issue(
            issue if isinstance(issue, Issue) else jira_server.issue(issue['id'])
        )
        bug.save()
        UniversalBug.propose(
            universal_id=bug.universal_id,
            source='jira',
            source_specific_id=bug.id,
            canonical_bug=canonical_bug,
        )
        return bug
Пример #24
0
 def setUp(self):
     self.attribute = UnicodeAttribute(attr_name='foo')
Пример #25
0
class DefaultsMap(MapAttribute):
    map_field = MapAttribute(default={})
    string_field = UnicodeAttribute(null=True)
Пример #26
0
 def setUp(self):
     self.attribute = UnicodeAttribute(attr_name='foo')
     self.list_attribute = ListAttribute(attr_name='foo_list', default=[])
Пример #27
0
 class SubMapAttribute(MapAttribute):
     foo = UnicodeAttribute(attr_name='dyn_foo')
Пример #28
0
class RumorModel(Model):
    class Meta:
        region = setting.region if setting.region else 'ap-northeast-1'
        table_name = setting.rumor_ddb_table if setting.rumor_ddb_table else 'stg-rumor_source'
        if setting.role:
            credentials = gen_sts_credentials(setting)
            aws_access_key_id = credentials["AccessKeyId"]
            aws_secret_access_key = credentials["SecretAccessKey"]
            aws_session_token = credentials["SessionToken"]

    id = UnicodeAttribute(hash_key=True)
    clarification = UnicodeAttribute(null=True)
    preface = UnicodeAttribute(null=True)
    create_date = UnicodeAttribute(null=True)
    link = UnicodeAttribute(null=True)
    rumors = ListAttribute(null=True)
    source = UnicodeAttribute(null=True)
    title = UnicodeAttribute(null=True)
    original_title = UnicodeAttribute(null=True)
    image_link = UnicodeAttribute(null=True)
    tags = UnicodeAttribute(null=True)
    sensitive_categories = UnicodeAttribute(null=True)
    rating = UnicodeAttribute(null=True)

    source_create_date_index = SourceCreateDateIndex()
Пример #29
0
 class SubSubMapAttribute(SubMapAttribute):
     bar = UnicodeAttribute(attr_name='dyn_bar')
Пример #30
0
class CourseAttribute(MapAttribute):
    CourseId = NumberAttribute(null=False)
    CourseName = UnicodeAttribute(null=False)
Пример #31
0
class ConditionExpressionTestCase(TestCase):

    def setUp(self):
        self.attribute = UnicodeAttribute(attr_name='foo')

    def test_equal(self):
        condition = self.attribute == 'bar'
        placeholder_names, expression_attribute_values = {}, {}
        expression = condition.serialize(placeholder_names, expression_attribute_values)
        assert expression == "#0 = :0"
        assert placeholder_names == {'foo': '#0'}
        assert expression_attribute_values == {':0': {'S': 'bar'}}

    def test_not_equal(self):
        condition = self.attribute != 'bar'
        placeholder_names, expression_attribute_values = {}, {}
        expression = condition.serialize(placeholder_names, expression_attribute_values)
        assert expression == "#0 <> :0"
        assert placeholder_names == {'foo': '#0'}
        assert expression_attribute_values == {':0': {'S': 'bar'}}

    def test_less_than(self):
        condition = self.attribute < 'bar'
        placeholder_names, expression_attribute_values = {}, {}
        expression = condition.serialize(placeholder_names, expression_attribute_values)
        assert expression == "#0 < :0"
        assert placeholder_names == {'foo': '#0'}
        assert expression_attribute_values == {':0': {'S': 'bar'}}

    def test_less_than_or_equal(self):
        condition = self.attribute <= 'bar'
        placeholder_names, expression_attribute_values = {}, {}
        expression = condition.serialize(placeholder_names, expression_attribute_values)
        assert expression == "#0 <= :0"
        assert placeholder_names == {'foo': '#0'}
        assert expression_attribute_values == {':0': {'S': 'bar'}}

    def test_greater_than(self):
        condition = self.attribute > 'bar'
        placeholder_names, expression_attribute_values = {}, {}
        expression = condition.serialize(placeholder_names, expression_attribute_values)
        assert expression == "#0 > :0"
        assert placeholder_names == {'foo': '#0'}
        assert expression_attribute_values == {':0': {'S': 'bar'}}

    def test_greater_than_or_equal(self):
        condition = self.attribute >= 'bar'
        placeholder_names, expression_attribute_values = {}, {}
        expression = condition.serialize(placeholder_names, expression_attribute_values)
        assert expression == "#0 >= :0"
        assert placeholder_names == {'foo': '#0'}
        assert expression_attribute_values == {':0': {'S': 'bar'}}

    def test_between(self):
        condition = self.attribute.between('bar', 'baz')
        placeholder_names, expression_attribute_values = {}, {}
        expression = condition.serialize(placeholder_names, expression_attribute_values)
        assert expression == "#0 BETWEEN :0 AND :1"
        assert placeholder_names == {'foo': '#0'}
        assert expression_attribute_values == {':0': {'S': 'bar'}, ':1': {'S': 'baz'}}

    def test_in(self):
        condition = self.attribute.is_in('bar', 'baz')
        placeholder_names, expression_attribute_values = {}, {}
        expression = condition.serialize(placeholder_names, expression_attribute_values)
        assert expression == "#0 IN (:0, :1)"
        assert placeholder_names == {'foo': '#0'}
        assert expression_attribute_values == {':0': {'S': 'bar'}, ':1': {'S': 'baz'}}

    def test_exists(self):
        condition = self.attribute.exists()
        placeholder_names, expression_attribute_values = {}, {}
        expression = condition.serialize(placeholder_names, expression_attribute_values)
        assert expression == "attribute_exists (#0)"
        assert placeholder_names == {'foo': '#0'}
        assert expression_attribute_values == {}

    def test_does_not_exist(self):
        condition = self.attribute.does_not_exist()
        placeholder_names, expression_attribute_values = {}, {}
        expression = condition.serialize(placeholder_names, expression_attribute_values)
        assert expression == "attribute_not_exists (#0)"
        assert placeholder_names == {'foo': '#0'}
        assert expression_attribute_values == {}

    def test_is_type(self):
        condition = self.attribute.is_type()
        placeholder_names, expression_attribute_values = {}, {}
        expression = condition.serialize(placeholder_names, expression_attribute_values)
        assert expression == "attribute_type (#0, :0)"
        assert placeholder_names == {'foo': '#0'}
        assert expression_attribute_values == {':0': {'S' : 'S'}}

    def test_begins_with(self):
        condition = self.attribute.startswith('bar')
        placeholder_names, expression_attribute_values = {}, {}
        expression = condition.serialize(placeholder_names, expression_attribute_values)
        assert expression == "begins_with (#0, :0)"
        assert placeholder_names == {'foo': '#0'}
        assert expression_attribute_values == {':0': {'S' : 'bar'}}

    def test_contains(self):
        condition = self.attribute.contains('bar')
        placeholder_names, expression_attribute_values = {}, {}
        expression = condition.serialize(placeholder_names, expression_attribute_values)
        assert expression == "contains (#0, :0)"
        assert placeholder_names == {'foo': '#0'}
        assert expression_attribute_values == {':0': {'S' : 'bar'}}

    def test_contains_string_set(self):
        condition = UnicodeSetAttribute(attr_name='foo').contains('bar')
        placeholder_names, expression_attribute_values = {}, {}
        expression = condition.serialize(placeholder_names, expression_attribute_values)
        assert expression == "contains (#0, :0)"
        assert placeholder_names == {'foo': '#0'}
        assert expression_attribute_values == {':0': {'S' : 'bar'}}

    def test_contains_number_set(self):
        condition = NumberSetAttribute(attr_name='foo').contains(1)
        placeholder_names, expression_attribute_values = {}, {}
        expression = condition.serialize(placeholder_names, expression_attribute_values)
        assert expression == "contains (#0, :0)"
        assert placeholder_names == {'foo': '#0'}
        assert expression_attribute_values == {':0': {'N' : '1'}}

    def test_contains_list(self):
        condition = ListAttribute(attr_name='foo').contains('bar')
        placeholder_names, expression_attribute_values = {}, {}
        expression = condition.serialize(placeholder_names, expression_attribute_values)
        assert expression == "contains (#0, :0)"
        assert placeholder_names == {'foo': '#0'}
        assert expression_attribute_values == {':0': {'S' : 'bar'}}

    def test_contains_attribute(self):
        condition = ListAttribute(attr_name='foo').contains(Path('bar'))
        placeholder_names, expression_attribute_values = {}, {}
        expression = condition.serialize(placeholder_names, expression_attribute_values)
        assert expression == "contains (#0, #1)"
        assert placeholder_names == {'foo': '#0', 'bar': '#1'}
        assert expression_attribute_values == {}

    def test_size(self):
        condition = size(self.attribute) == 3
        placeholder_names, expression_attribute_values = {}, {}
        expression = condition.serialize(placeholder_names, expression_attribute_values)
        assert expression == "size (#0) = :0"
        assert placeholder_names == {'foo': '#0'}
        assert expression_attribute_values == {':0': {'N' : '3'}}

    def test_sizes(self):
        condition = size(self.attribute) == size(Path('bar'))
        placeholder_names, expression_attribute_values = {}, {}
        expression = condition.serialize(placeholder_names, expression_attribute_values)
        assert expression == "size (#0) = size (#1)"
        assert placeholder_names == {'foo': '#0', 'bar': '#1'}
        assert expression_attribute_values == {}

    def test_and(self):
        condition = (self.attribute < 'bar') & (self.attribute > 'baz')
        placeholder_names, expression_attribute_values = {}, {}
        expression = condition.serialize(placeholder_names, expression_attribute_values)
        assert expression == "(#0 < :0 AND #0 > :1)"
        assert placeholder_names == {'foo': '#0'}
        assert expression_attribute_values == {':0': {'S': 'bar'}, ':1': {'S': 'baz'}}

    def test_or(self):
        condition = (self.attribute < 'bar') | (self.attribute > 'baz')
        placeholder_names, expression_attribute_values = {}, {}
        expression = condition.serialize(placeholder_names, expression_attribute_values)
        assert expression == "(#0 < :0 OR #0 > :1)"
        assert placeholder_names == {'foo': '#0'}
        assert expression_attribute_values == {':0': {'S': 'bar'}, ':1': {'S': 'baz'}}

    def test_not(self):
        condition = ~(self.attribute < 'bar')
        placeholder_names, expression_attribute_values = {}, {}
        expression = condition.serialize(placeholder_names, expression_attribute_values)
        assert expression == "(NOT #0 < :0)"
        assert placeholder_names == {'foo': '#0'}
        assert expression_attribute_values == {':0': {'S': 'bar'}}

    def test_compound_logic(self):
        condition = (~(self.attribute < 'bar') & (self.attribute > 'baz')) | (self.attribute == 'foo')
        placeholder_names, expression_attribute_values = {}, {}
        expression = condition.serialize(placeholder_names, expression_attribute_values)
        assert expression == "(((NOT #0 < :0) AND #0 > :1) OR #0 = :2)"
        assert placeholder_names == {'foo': '#0'}
        assert expression_attribute_values == {':0': {'S': 'bar'}, ':1': {'S': 'baz'}, ':2': {'S': 'foo'}}

    def test_indexing(self):
        condition = ListAttribute(attr_name='foo')[0] == 'bar'
        placeholder_names, expression_attribute_values = {}, {}
        expression = condition.serialize(placeholder_names, expression_attribute_values)
        assert expression == "#0[0] = :0"
        assert placeholder_names == {'foo': '#0'}
        assert expression_attribute_values == {':0': {'S' : 'bar'}}

    def test_invalid_indexing(self):
        with self.assertRaises(TypeError):
            self.attribute[0]

    def test_double_indexing(self):
        condition = ListAttribute(attr_name='foo')[0][1] == 'bar'
        placeholder_names, expression_attribute_values = {}, {}
        expression = condition.serialize(placeholder_names, expression_attribute_values)
        assert expression == "#0[0][1] = :0"
        assert placeholder_names == {'foo': '#0'}
        assert expression_attribute_values == {':0': {'S' : 'bar'}}

    def test_list_comparison(self):
        condition = ListAttribute(attr_name='foo') == ['bar', 'baz']
        placeholder_names, expression_attribute_values = {}, {}
        expression = condition.serialize(placeholder_names, expression_attribute_values)
        assert expression == "#0 = :0"
        assert placeholder_names == {'foo': '#0'}
        assert expression_attribute_values == {':0': {'L': [{'S' : 'bar'}, {'S': 'baz'}]}}

    def test_dotted_attribute_name(self):
        self.attribute.attr_name = 'foo.bar'
        condition = self.attribute == 'baz'
        placeholder_names, expression_attribute_values = {}, {}
        expression = condition.serialize(placeholder_names, expression_attribute_values)
        assert expression == "#0 = :0"
        assert placeholder_names == {'foo.bar': '#0'}
        assert expression_attribute_values == {':0': {'S': 'baz'}}

    def test_map_attribute_dereference(self):
        class MyMapAttribute(MapAttribute):
            nested_string = self.attribute

        # Simulate initialization from inside an AttributeContainer
        my_map_attribute = MyMapAttribute(attr_name='foo.bar')
        my_map_attribute._make_attribute()
        my_map_attribute._update_attribute_paths(my_map_attribute.attr_name)

        condition = my_map_attribute.nested_string == 'baz'
        placeholder_names, expression_attribute_values = {}, {}
        expression = condition.serialize(placeholder_names, expression_attribute_values)
        assert expression == "#0.#1 = :0"
        assert placeholder_names == {'foo.bar': '#0', 'foo': '#1'}
        assert expression_attribute_values == {':0': {'S': 'baz'}}
Пример #32
0
class AssetModel(Model):
    class Meta:
        table_name = os.environ['DYNAMODB_TABLE']
        if 'ENV' in os.environ:
            host = 'http://localhost:8000'
        else:
            region = os.environ['REGION']
            host = os.environ['DYNAMODB_HOST']
            # 'https://dynamodb.us-east-1.amazonaws.com'

    asset_id = UnicodeAttribute(hash_key=True)
    state = UnicodeAttribute(null=False, default=State.CREATED.name)
    createdAt = UTCDateTimeAttribute(null=False,
                                     default=datetime.now().astimezone())
    updatedAt = UTCDateTimeAttribute(null=False,
                                     default=datetime.now().astimezone())

    def __str__(self):
        return 'asset_id:{}, state:{}'.format(self.asset_id, self.state)

    def get_key(self):
        return u'{}/{}'.format(KEY_BASE, self.asset_id)

    def save(self, conditional_operator=None, **expected_values):
        try:
            self.updatedAt = datetime.now().astimezone()
            logger.debug('saving: {}'.format(self))
            super(AssetModel, self).save()
        except Exception as e:
            logger.error('save {} failed: {}'.format(self.asset_id, e),
                         exc_info=True)
            raise e

    def __iter__(self):
        for name, attr in self._get_attributes().items():
            yield name, attr.serialize(getattr(self, name))

    def get_upload_url(self, ttl=60):
        """
        :param ttl: url duration in seconds
        :return: a temporary presigned PUT url
        """
        s3 = boto3.client('s3')
        put_url = s3.generate_presigned_url('put_object',
                                            Params={
                                                'Bucket': BUCKET,
                                                'Key': self.get_key()
                                            },
                                            ExpiresIn=ttl,
                                            HttpMethod='PUT')
        logger.debug('upload URL: {}'.format(put_url))
        return put_url

    def get_download_url(self, ttl=60):
        """
        :param ttl: url duration in seconds
        :return: a temporary presigned download url
        """
        s3 = boto3.client('s3')
        if self.state != State.UPLOADED.name:
            raise AssertionError(
                'Asset {} is marked as {}, must be marked {} to retrieve.'.
                format(self.asset_id, self.state, State.UPLOADED.name))
        get_url = s3.generate_presigned_url('get_object',
                                            Params={
                                                'Bucket': BUCKET,
                                                'Key': self.get_key(),
                                            },
                                            ExpiresIn=ttl,
                                            HttpMethod='GET')
        logger.debug('download URL: {}'.format(get_url))
        return get_url

    def mark_received(self):
        """
        Mark asset as having been received via the s3 objectCreated:Put event
        """
        self.state = State.RECEIVED.name
        logger.debug('mark asset received: {}'.format(self.asset_id))
        self.save()

    def mark_uploaded(self):
        """
        Mark asset as having been uploaded via a PUT to the asset's REST path
        """
        uploaded_states = [State.RECEIVED.name, State.UPLOADED.name]
        if self.state not in uploaded_states:
            raise AssertionError('State: \"{}\" must be one of {}'.format(
                self.state, uploaded_states))
        self.state = State.UPLOADED.name
        logger.debug('mark asset uploaded: {}'.format(self.asset_id))
        self.save()

    def mark_deleted(self):
        """
        Mark asset as deleted (soft delete)
        """
        self.state = State.DELETED.name
        logger.debug('mark asset deleted: {}'.format(self.asset_id))
        self.save()
Пример #33
0
class TypedValue(MapAttribute):
    _cls = DiscriminatorAttribute(attr_name='cls')
    name = UnicodeAttribute()
Пример #34
0
class S3Model:
    """S3 specific fields for DynamoDB."""

    BucketName = UnicodeAttribute()
    Region = UnicodeAttribute()
Пример #35
0
 class DiscriminatedModel(Model):
     hash_key = UnicodeAttribute(hash_key=True)
     _cls = DiscriminatorAttribute()
Пример #36
0
def test_should_string_convert_string():
    assert_attribute_conversion(UnicodeAttribute(), graphene.String)
Пример #37
0
 def setUp(self):
     self.attribute = UnicodeAttribute(attr_name='foo')