def test_list_of_map_with_of_and_custom_attribute(self, mocker): class CustomMapAttribute(MapAttribute): custom = NumberAttribute() def __eq__(self, other): return self.custom == other.custom serialize_mock = mocker.spy( CustomMapAttribute.custom, 'serialize', ) deserialize_mock = mocker.spy(CustomMapAttribute.custom, 'deserialize') attribute1 = CustomMapAttribute() attribute1.custom = 1 attribute2 = CustomMapAttribute() attribute2.custom = 2 inp = [attribute1, attribute2] list_attribute = ListAttribute(default=[], of=CustomMapAttribute) serialized = list_attribute.serialize(inp) deserialized = list_attribute.deserialize(serialized) assert deserialized == inp assert serialize_mock.call_args_list == [call(1), call(2)] assert deserialize_mock.call_args_list == [call('1'), call('2')]
def test_list_of_map_with_of(self): class Person(MapAttribute): name = UnicodeAttribute() age = NumberAttribute() def __lt__(self, other): return self.name < other.name def __eq__(self, other): return (self.name == other.name and self.age == other.age) person1 = Person() person1.name = 'john' person1.age = 40 person2 = Person() person2.name = 'Dana' person2.age = 41 inp = [person1, person2] list_attribute = ListAttribute(default=[], of=Person) serialized = list_attribute.serialize(inp) deserialized = list_attribute.deserialize(serialized) assert sorted(deserialized) == sorted(inp)
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_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_list_of_map_with_of_and_custom_attribute(self, mocker): class CustomMapAttribute(MapAttribute): custom = NumberAttribute() def __eq__(self, other): return self.custom == other.custom serialize_mock = mocker.spy(CustomMapAttribute.custom, 'serialize',) deserialize_mock = mocker.spy(CustomMapAttribute.custom, 'deserialize') attribute1 = CustomMapAttribute() attribute1.custom = 1 attribute2 = CustomMapAttribute() attribute2.custom = 2 inp = [attribute1, attribute2] list_attribute = ListAttribute(default=[], of=CustomMapAttribute) serialized = list_attribute.serialize(inp) deserialized = list_attribute.deserialize(serialized) assert deserialized == inp assert serialize_mock.call_args_list == [call(1), call(2)] assert deserialize_mock.call_args_list == [call('1'), call('2')]
def test_untyped_list(self): untyped_list = [{ 'Hello': 'World' }, ['!'], {'foo', 'bar'}, None, "", 0, False] serialized = ListAttribute().serialize(untyped_list) # set attributes are serialized as lists untyped_list[2] = list(untyped_list[2]) assert ListAttribute().deserialize(serialized) == untyped_list
class RetrospectiveV2(Retrospective): class Meta: table_name = 'retrospective-{}'.format(ENVIRONMENT) if ENVIRONMENT == 'test': host = "http://localhost:8008" issues = ListAttribute(of=IssueAttributeV2) groups = ListAttribute(of=GroupAttribute) version = UnicodeAttribute()
class ReceiptLinesModel(Model): class Meta: region = config.AWS_REGION_DEFAULT table_name = 'receipt_lines' host = config.DYNAMODB_LOCAL_URL if is_lambda_local() else None image_hash = UnicodeAttribute(hash_key=True) receipt_lines = ListAttribute(default=None) receipt_lines_tokens = ListAttribute(default=None)
def test_typed_list_indexing(self): class StringMap(MapAttribute): bar = UnicodeAttribute() condition = ListAttribute(attr_name='foo', of=StringMap)[0].bar == 'baz' placeholder_names, expression_attribute_values = {}, {} expression = condition.serialize(placeholder_names, expression_attribute_values) assert expression == "#0[0].#1 = :0" assert placeholder_names == {'foo': '#0', 'bar': '#1'} assert expression_attribute_values == {':0': {'S': 'baz'}}
class UserReminder(Model): class Meta: table_name = TABLE_USER_REMINDER region = 'us-east-2' user_id = NumberAttribute(hash_key=True) registration_time = NumberAttribute() time_delta = NumberAttribute(default=DEFAULT_DELTA) active_reminders = ListAttribute(default=list, of=ReminderMap) passive_reminders = ListAttribute(default=list, of=ReminderMap) temp_reminder = ReminderMap(default=ReminderMap)
class Retrospective(Model): class Meta: table_name = 'retrospective-{}'.format(ENVIRONMENT) if ENVIRONMENT == 'test': host = "http://localhost:8008" id = UnicodeAttribute(hash_key=True) name = UnicodeAttribute() current_step = UnicodeAttribute() issues = ListAttribute(of=IssueAttribute) participants = ListAttribute(of=ParticipantAttribute) version = UnicodeAttribute()
class Doc(MapAttribute): aliases = ListAttribute(attr_name="aliases", default=[]) status = UnicodeAttribute(attr_name="status", default="ready") columns = ListAttribute(attr_name="columns", of=Column, default=[]) bucket = UnicodeAttribute(attr_name="bucket", default="") database = UnicodeAttribute(attr_name="database", default="") tablename = UnicodeAttribute(attr_name="tablename", default="") field = UnicodeAttribute(attr_name="field", default="") crawler = UnicodeAttribute(attr_name="crawler", default="") prefix = UnicodeAttribute(attr_name="prefix", default="") replacements = ListAttribute(attr_name="replacements", default=[]) sql = UnicodeAttribute(attr_name="sql", default="") reply = ListAttribute(attr_name="reply", default=[])
class LogMessage(Model): class Meta: table_name = 'hakkuu_message' guild = NumberAttribute(hash_key=True) snowflake = NumberAttribute(range_key=True) author = NumberAttribute() channel = NumberAttribute() revisions = ListAttribute(of=LogRevision) embeds = ListAttribute(of=LogEmbed) attachments = ListAttribute(of=LogAttachment) tts = BooleanAttribute(null=True) deleted = BooleanAttribute(null=True) deleted_by = BooleanAttribute(null=True)
class Office(Model): class Meta: table_name = "OfficeModel" host = "http://localhost:{}".format(environ.get("DOCKER_PORT", 8000)) aws_access_key_id = "my_access_key_id" aws_secret_access_key = "my_secret_access_key" office_id = UUIDAttribute(hash_key=True) address = Location() employees = ListAttribute(of=OfficeEmployeeMap) departments = UnicodeSetAttribute() numbers = NumberSetAttribute() security_number = UnicodeAttribute(null=True) office_times = ListAttribute() cls = DiscriminatorAttribute()
class TrackMap(MapAttribute): id = UnicodeAttribute() name = UnicodeAttribute() album_id = UnicodeAttribute() album_name = UnicodeAttribute() artist_id = UnicodeAttribute() artist_name = UnicodeAttribute() duration = NumberAttribute() listeners = NumberAttribute() playback_date = UnicodeAttribute() playcount = UnicodeAttribute() reproduction = NumberAttribute() total_tracks = NumberAttribute() tags = ListAttribute() genres = ListAttribute() release_date = UnicodeAttribute()
class ReplyIdsByQid(BaseModel): class Meta: table_name = gen_table_name("qanda-reply-ids-ddb") region = env.AWS_REGION qid = UnicodeAttribute(hash_key=True) rids = ListAttribute(of=GenericPointer, default=list)
class UserQuestionsModel(BaseModel): class Meta: table_name = gen_table_name("qanda-user-qs-ddb") region = env.AWS_REGION uid = UnicodeAttribute(hash_key=True) qs = ListAttribute(of=UserQuestionLogEntry, default=list)
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()
class Poll(Model): """ A DynamoDB User """ class Meta: table_name = DYNAMO_DB_TABLE_NAME key = UnicodeAttribute(hash_key=True) question = UnicodeAttribute() author = JSONAttribute() # option_id is index of the option in the list options = ListAttribute(default=list) votes = MapAttribute(default=dict) # user_id -> option_id users = MapAttribute(default=dict) # user_id -> data # see https://pynamodb.readthedocs.io/en/latest/optimistic_locking.html version = VersionAttribute() # information about poll message in telegram telegram_version = NumberAttribute() telegram_datetime = UTCDateTimeAttribute() def get_users_by_option_id(self): users_by_option_id = {} for user_id in self.votes: option_id = self.votes[user_id] users_by_option_id.setdefault(option_id, []) users_by_option_id[option_id].append(self.users[user_id]) return users_by_option_id
class BaseTestModel(BaseModel): __update_action_hooks__ = { 'set': { 'non_key_value': 'test_hook_action_generation' } } class Meta(BaseMeta): table_name = 'base' def __init__(self, hash_key=None, range_key=None, **attributes): self.assign_or_update('update_action_hooks', __class__.__update_action_hooks__) super().__init__(hash_key, range_key, **attributes) hash_key = UnicodeAttribute(hash_key=True) range_key = UnicodeAttribute(range_key=True) hook_attribute = UnicodeAttribute(null=True) list_attribute = ListAttribute(default=list()) non_key_value = UnicodeAttribute() numeric_value = NumberAttribute(null=True) unicode_set = UnicodeSetAttribute(default=set()) def test_hook_action_generation(self, value): return [BaseTestModel.hook_attribute.set(value)]
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_should_list_convert_list_of_map(): class Address(MapAttribute): latitude = NumberAttribute(null=False) longitude = NumberAttribute(null=False) address = UnicodeAttribute() assert_attribute_conversion(ListAttribute(of=Address), ListOfMapToObject)
class VPCModel(object): VpcId = UnicodeAttribute() State = UnicodeAttribute() CidrBlock = UnicodeAttribute() Tags = ListAttribute() IsDefault = BooleanAttribute() Name = UnicodeAttribute(null=True)
class PaintingModel(Model): class Meta: table_name = "painting" episode = UnicodeAttribute(hash_key=True) title = UnicodeAttribute() colors = ListAttribute()
class Game(BaseModel): class Meta(BaseModel.Meta): pass game_id = UnicodeAttribute( hash_key=True, attr_name="pk", default_for_new=str(uuid4()) ) secret = UnicodeAttribute(default_for_new="".join(choices(COLORS, k=TOTAL_LETTERS))) tries_left = NumberAttribute(default_for_new=MAX_TRIES) created_at = UTCDateTimeAttribute(default_for_new=datetime.utcnow()) is_solved = BooleanAttribute(default_for_new=False) guesses = ListAttribute(of=Guess, null=True, default=[]) def check_win_condition(self, guess: Guess) -> None: if guess.combination == self.secret: self.is_solved = True def get_info(self) -> dict: return {k: v for k, v in self.to_dict().items() if k != "secret"} def save_guess(self, guess: Guess): self.update( actions=[ Game.guesses.set((Game.guesses | []).append([guess])), Game.tries_left.set(Game.tries_left - 1), Game.is_solved.set(self.is_solved), ] ) def is_playable(self) -> bool: if not self.is_solved and self.tries_left: return True return False def get_black_and_white_pegs(self, guess: Guess) -> Tuple[int, int]: combination_cp = guess.combination secret_cp = self.secret black_pegs_counter = 0 black_pegs_indexes = [] white_pegs_counter = 0 for i, letter in enumerate(self.secret): if guess.combination[i] == letter: black_pegs_counter += 1 black_pegs_indexes.append(i) black_pegs_indexes.reverse() for index in black_pegs_indexes: combination_cp = combination_cp[:index] + combination_cp[index + 1 :] secret_cp = secret_cp[:index] + secret_cp[index + 1 :] for letter in combination_cp: if letter in secret_cp: white_pegs_counter += 1 return black_pegs_counter, white_pegs_counter
class Planets(Model): """ Describes the schema used on our DynamoDB table. """ class Meta: """ Table name on DynamoDB """ PlanetsConfig.table_name = 'Planets' climate = ListAttribute(null=False) terrain = ListAttribute(null=False) name = UnicodeAttribute(null=False) planet_id = NumberAttribute(hash_key=True) read_capacity_units = 5 write_capacity_units = 5 PlanetsConfig.region = 'us-east-1'
class SecurityGroupModel(object): GroupId = UnicodeAttribute() GroupName = UnicodeAttribute() VpcId = UnicodeAttribute(null=True) OwnerId = UnicodeAttribute() Description = UnicodeAttribute() Tags = ListAttribute() Region = UnicodeAttribute()
class UserModel(BaseModel): class Meta: table_name = 'users' user_id = UnicodeAttribute(hash_key=True) email = UnicodeAttribute() email_index = EmailIndex() password = UnicodeAttribute() lists = ListAttribute(default=[])
class Thread(Model): class Meta: table_name = 'Thread' forum_name = UnicodeAttribute(hash_key=True) subjects = UnicodeSetAttribute(default=dict) views = NumberAttribute(default=0) notes = ListAttribute(default=list)
class DiscriminatorTestModel(Model, discriminator='Parent'): class Meta: host = 'http://localhost:8000' table_name = 'test' hash_key = UnicodeAttribute(hash_key=True) value = TypedValue() values = ListAttribute(of=TypedValue) type = DiscriminatorAttribute()