sider.types — Conversion between Python and Redis types¶
In Redis all data are byte strings — bulks. Lists are lists of byte strings, sets are sets of byte strings, and hashes consist of byte string keys and byte string values.
To store richier objects into Redis we have to encode Python values and
decode Redis data. Bulk and its subclasses are for that, it
defines two basic methods: encode() and
decode(). For example, Integer encodes Python
int 3 into Redis bulk "3" and decodes Redis bulk "3"
into Python int 3.
-
class
sider.types.Boolean¶ Bases:
sider.types.IntegerStores
boolvalues as'1'or'0'.>>> boolean = Boolean() >>> boolean.encode(True) '1' >>> boolean.encode(False) '0'
-
class
sider.types.Bulk¶ Bases:
sider.types.ValueThe abstract base class to be subclassed. You have to implement
encode()anddecode()methods in subclasses.-
decode(bulk)¶ Decodes a Redis
bulkto Python object. Every subclass ofBulkmust implement this method. By default it raisesNotImplementedError.Parameters: bulk ( str) – a Redis bullk to decode into Python objectReturns: a decoded Python object
-
encode(value)¶ Encodes a Python
valueinto Redis bulk. Every subclass ofBulkmust implement this method. By default it raisesNotImplementedError.Parameters: value – a Python value to encode into Redis bulk Returns: an encoded Redis bulk Return type: strRaises exceptions.TypeError: if the type of a given value is not acceptable by this type
-
-
class
sider.types.ByteString¶ Bases:
sider.types.BulkStores byte strings. It stores the given byte strings as these are. It works simply transparently for
strvalues.>>> bytestr = ByteString() >>> bytestr.encode('annyeong') 'annyeong' >>> bytestr.decode('sayonara') 'sayonara'
-
bytes_type¶ alias of
str
-
-
class
sider.types.Date¶ Bases:
sider.types.BulkStores
datetime.datevalues. Dates are internally formatted in RFC 3339 format e.g.2012-03-28.>>> import datetime >>> date = Date() >>> date.encode(datetime.date(2012, 3, 28)) '2012-03-28' >>> date.decode(_) datetime.date(2012, 3, 28)
-
DATE_FORMAT= '%Y-%m-%d'¶ (
str) Thestrftime()format string for RFC 3339.
-
-
class
sider.types.DateTime¶ Bases:
sider.types.BulkStores naive
datetime.datetimevalues. Values are internally formatted in RFC 3339 format e.g.2012-03-28T09:21:34.638972.>>> dt = DateTime() >>> dt.decode('2012-03-28T09:21:34.638972') datetime.datetime(2012, 3, 28, 9, 21, 34, 638972) >>> dt.encode(_) '2012-03-28T09:21:34.638972'
It doesn’t store
tzinfodata.>>> from sider.datetime import UTC >>> decoded = dt.decode('2012-03-28T09:21:34.638972Z') >>> decoded datetime.datetime(2012, 3, 28, 9, 21, 34, 638972) >>> dt.encode(decoded.replace(tzinfo=UTC)) '2012-03-28T09:21:34.638972'
Note
If you must be aware of time zone, use
TZDateTimeinstead.-
parse_datetime(bulk)¶ Parses a RFC 3339 formatted string into
datetime.datetime.>>> dt = DateTime() >>> dt.parse_datetime('2012-03-28T09:21:34.638972') datetime.datetime(2012, 3, 28, 9, 21, 34, 638972)
Unlike
decode()it is aware oftzinfodata if the string contains time zone notation.>>> a = dt.parse_datetime('2012-03-28T09:21:34.638972Z') >>> a datetime.datetime(2012, 3, 28, 9, 21, 34, 638972, tzinfo=sider.datetime.Utc()) >>> b = dt.parse_datetime('2012-03-28T18:21:34.638972+09:00') >>> b datetime.datetime(2012, 3, 28, 18, 21, 34, 638972, tzinfo=sider.datetime.FixedOffset(540)) >>> a == b True
Parameters: bulk ( basestring) – a RFC 3339 formatted stringReturns: a parsing result Return type: datetime.datetimeNote
It is for internal use and
decode()method actually uses this method.
-
-
class
sider.types.Hash(key_type=None, value_type=None)¶ Bases:
sider.types.ValueThe type object for
sider.hash.Hashobjects and othercollections.Mappingobjects.Parameters:
-
class
sider.types.Integer¶ Bases:
sider.types.BulkStores integers as decimal strings. For example:
>>> integer = Integer() >>> integer.encode(42) '42' >>> integer.decode('42') 42
Why it doesn’t store integers as binaries but decimals is that Redis provides INCR, INCRBY, DECR and DECRBY for decimal strings. You can simply add and subtract integers.
-
class
sider.types.List(value_type=None)¶ Bases:
sider.types.ValueThe type object for
sider.list.Listobjects and othercollections.Sequenceobjects except strings. (UseByteStringorUnicodeStringfor strings.)Parameters: value_type ( Bulk,type) – the type of values the list will contain. default isString
-
class
sider.types.Set(value_type=None)¶ Bases:
sider.types.ValueThe type object for
sider.set.Setobjects and othercollections.Setobjects.Parameters: value_type ( Bulk,type) – the type of values the set will contain. default isString
-
class
sider.types.SortedSet(value_type=None)¶ Bases:
sider.types.SetThe type object for
sider.sortedset.SortedSetobjects.Parameters: value_type ( Bulk,type) – the type of values the sorted set will contain. default isString
-
sider.types.String¶ alias of
ByteString
-
class
sider.types.TZDateTime¶ Bases:
sider.types.DateTimeSimilar to
DateTimeexcept it accepts only tz-awaredatetime.datetimevalues. All values are internally stored inUTC.>>> from sider.datetime import FixedOffset >>> dt = datetime.datetime(2012, 3, 28, 18, 21, 34, 638972, ... tzinfo=FixedOffset(540)) >>> tzdt = TZDateTime() >>> tzdt.encode(dt) '2012-03-28T09:21:34.638972Z' >>> tzdt.decode(_) datetime.datetime(2012, 3, 28, 9, 21, 34, 638972, tzinfo=sider.datetime.Utc())
If any naive
datetime.datetimehas passed it will raiseValueError.
-
class
sider.types.TZTime¶ Bases:
sider.types.TimeSimilar to
Timeexcept it accepts only tz-awaredatetime.timevalues.>>> from sider.datetime import FixedOffset >>> time = datetime.time(18, 21, 34, 638972, ... tzinfo=FixedOffset(540)) >>> tztime = TZTime() >>> tztime.encode(time) '18:21:34.638972+09:00' >>> tztime.decode(_) datetime.time(18, 21, 34, 638972, tzinfo=sider.datetime.FixedOffset(540)) >>> utctime = datetime.time(9, 21, 34, 638972, tzinfo=UTC) >>> tztime.encode(utctime) '09:21:34.638972Z' >>> tztime.decode(_) datetime.time(9, 21, 34, 638972, tzinfo=sider.datetime.Utc())
If any naive
datetime.timehas passed it will raiseValueError.
-
class
sider.types.Time¶ Bases:
sider.types.BulkStores naive
datetime.timevalues.>>> time = Time() >>> time.decode('09:21:34.638972') datetime.time(9, 21, 34, 638972) >>> time.encode(_) '09:21:34.638972'
It doesn’t store
tzinfodata.>>> from sider.datetime import UTC >>> time = Time() >>> decoded = time.decode('09:21:34.638972Z') >>> decoded datetime.time(9, 21, 34, 638972) >>> time.encode(decoded.replace(tzinfo=UTC)) '09:21:34.638972'
Note
If you must be aware of time zone, use
TZTimeinstead.-
parse_time(bulk, drop_tzinfo)¶ Parses an encoded
datetime.time.Parameters: bulk ( basestring) – an encoded timeReturns: a parsed time Return type: datetime.timeNote
It is for internal use and
decode()method actually uses this method.
-
-
class
sider.types.TimeDelta¶ Bases:
sider.types.BulkStores
datetime.timedeltavalues.>>> import datetime >>> td = TimeDelta() >>> delta = datetime.timedelta(days=3, seconds=53, microseconds=123123) >>> td.encode(delta) '3,53,123123' >>> td.decode(_) datetime.timedelta(3, 53, 123123)
-
class
sider.types.Tuple(*field_types)¶ Bases:
sider.types.BulkStores tuples of fixed fields. It can be used for compositing multiple fields into one field in ad-hoc way. For example, if you want to store 3D point value without defining new
Type:Tuple(Integer, Integer, Integer)
The above type will store three integers in a field.
>>> int_str_int = Tuple(Integer, ByteString, Integer) >>> int_str_int.encode((123, 'abc\ndef', 456)) '3,7,3\n123\nabc\ndef\n456' >>> int_str_int.decode(_) (123, 'abc\ndef', 456)
Encoded values become a bulk bytes. It consists of a header line and other lines that contain field values. The first header line is a comma-separated integers that represent each byte size of encoded field values.
tuple ::=
header(newline field)* header ::= [size(","size)*] size ::= digit+ digit ::= "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"Parameters: *field_types – the variable number of field types -
field_types= None¶ (
tuple) The tuple of field types.
-
-
class
sider.types.UUID¶ Bases:
sider.types.BulkStores
uuid.UUIDvalues. For example:>>> import uuid >>> u = UUID() >>> u.encode(uuid.UUID(int=134626331218489933988508161913704617318)) '65481698-2f85-4bd6-8f7c-ee8aaecf1566' >>> u.decode('65481698-2f85-4bd6-8f7c-ee8aaecf1566') UUID('65481698-2f85-4bd6-8f7c-ee8aaecf1566')
-
class
sider.types.UnicodeString¶ Bases:
sider.types.BulkStores Unicode strings (
unicode), not byte strings (str). Internally all Unicode strings are encoded into and decoded from UTF-8 byte strings.>>> unistr = UnicodeString() >>> unistr.encode(u'\uc720\ub2c8\ucf54\ub4dc') '\xec\x9c\xa0\xeb\x8b\x88\xec\xbd\x94\xeb\x93\x9c' >>> unistr.decode(_) u'\uc720\ub2c8\ucf54\ub4dc'
-
string_type¶ alias of
unicode
-
-
class
sider.types.Value¶ Bases:
objectThere are two layers behind Sider types: the lower one is this
Valueand the higher one isBulk.Valuetypes can be set to Redis keys, but unlikeBulkit cannot be a value type of other richValuetypes e.g.List,Hash.In most cases you (users) don’t have to subclass
Value, and should not. Direct subclasses ofValuearen’t about encodings/decodings of Python object but simply Python-side representations of Redis types. It actually doesn’t have methods likeencode()anddecode(). These methods appear underBulkor its subtypes.But it’s about how to save Python objects into Redis keys and how to load values from associated Redis keys. There are several commands to save like SET, MSET, HSET, RPUSH and the rest in Redis and subtypes have to decide which command of those to use.
All subtypes of
Valueimplementsave_value()andload_value()methods. The constructor which takes no arguments have to be implemented as well.-
classmethod
ensure_value_type(value_type, parameter=None)¶ Raises a
TypeErrorif the givenvalue_typeis not an instance of nor a subclass of the class.>>> Integer.ensure_value_type(Bulk ... ) Traceback (most recent call last): ... TypeError: expected a subtype of sider.types.Integer, but sider.types.Bulk was passed >>> Integer.ensure_value_type(UnicodeString() ... ) Traceback (most recent call last): ... TypeError: expected an instance of sider.types.Integer, but <sider.types.UnicodeString object at ...> was passed >>> Bulk.ensure_value_type(1) Traceback (most recent call last): ... TypeError: expected a type, not 1
Otherwise it simply returns an instance of the given
value_type.>>> Bulk.ensure_value_type(Bulk) <sider.types.Bulk object at ...> >>> Bulk.ensure_value_type(ByteString) <sider.types.ByteString object at ...> >>> ByteString.ensure_value_type(ByteString ... ) <sider.types.ByteString object at ...> >>> bytestr = ByteString() >>> ByteString.ensure_value_type(bytestr) <sider.types.ByteString object at ...>
If an optional
parametername has present, the error message becomes better.>>> Integer.ensure_value_type(Bulk, ... parameter='argname') Traceback (most recent call last): ... TypeError: argname must be a subtype of sider.types.Integer, but sider.types.Bulk was passed >>> Integer.ensure_value_type(UnicodeString(), ... parameter='argname' ... ) Traceback (most recent call last): ... TypeError: argname must be an instance of sider.types.Integer, but <sider.types.UnicodeString object at ...> was passed >>> Bulk.ensure_value_type(1, parameter='argname') Traceback (most recent call last): ... TypeError: argname must be a type, not 1
Parameters: - value_type (
Value,type) – a type expected to be a subtype of the class - parameter (
str) – an optional parameter name. if present the error message becomes better
Raises exceptions.TypeError: if the given
subtypeis not a subclass of the class- value_type (
-
load_value(session, key)¶ How to load the value from the given Redis
key. Subclasses have to implement it. By default it raisesNotImplementedError.Parameters: - session (
sider.session.Session) – the session object that stores the givenkey - key (
str) – the key name to load
Returns: the Python representation of the loaded value
- session (
-
save_value(session, key, value)¶ How to save the given
valueinto the given Rediskey. Subclasses have to implement it. By default it raisesNotImplementedError.Parameters: - session (
sider.session.Session) – the session object going to store the givenkey–valuepair - key (
str) – the key name to save thevalue - value – the value to save into the
key
Returns: the Python representation of the saved value. it is equivalent to the given
valuebut may not equal nor the same to- session (
-
classmethod