Skip to content


Subversion checkout URL

You can clone with
Download ZIP
Fetching contributors…
Cannot retrieve contributors at this time
195 lines (153 sloc) 6.96 KB
A combination of utilities used internally by pycassa and utilities
available for use by others working with pycassa.
import random
import uuid
import time
__all__ = ['convert_time_to_uuid', 'convert_uuid_to_time']
_number_types = frozenset((int, long, float))
def convert_time_to_uuid(time_arg, lowest_val=True, randomize=False):
Converts a datetime or timestamp to a type 1 :class:`uuid.UUID`.
This is to assist with getting a time slice of columns or creating
columns when column names are ``TimeUUIDType``. Note that this is done
automatically in most cases if name packing and value packing are
Also, be careful not to rely on this when specifying a discrete
set of columns to fetch, as the non-timestamp portions of the
UUID will be generated randomly. This problem does not matter
with slice arguments, however, as the non-timestamp portions
can be set to their lowest or highest possible values.
:param datetime:
The time to use for the timestamp portion of the UUID.
Expected inputs to this would either be a :class:`datetime`
object or a timestamp with the same precision produced by
:meth:`time.time()`. That is, sub-second precision should
be below the decimal place.
:type datetime: :class:`datetime` or timestamp
:param lowest_val:
Whether the UUID produced should be the lowest possible value
UUID with the same timestamp as datetime or the highest possible
:type lowest_val: bool
:param randomize:
Whether the clock and node bits of the UUID should be randomly
generated. The `lowest_val` argument will be ignored if this
is true.
:type randomize: bool
:rtype: :class:`uuid.UUID`
if isinstance(time_arg, uuid.UUID):
return time_arg
nanoseconds = 0
if hasattr(time_arg, 'timetuple'):
nanoseconds = int(time.mktime(time_arg.timetuple()) * 1e9)
elif type(time_arg) in _number_types:
nanoseconds = int(time_arg * 1e9)
raise ValueError('Argument for a v1 UUID column name or value was ' +
'neither a UUID, a datetime, or a number')
# 0x01b21dd213814000 is the number of 100-ns intervals between the
# UUID epoch 1582-10-15 00:00:00 and the Unix epoch 1970-01-01 00:00:00.
timestamp = int(nanoseconds/100) + 0x01b21dd213814000L
time_low = timestamp & 0xffffffffL
time_mid = (timestamp >> 32L) & 0xffffL
time_hi_version = (timestamp >> 48L) & 0x0fffL
if randomize:
rand_bits = random.getrandbits(8 + 8 + 48)
clock_seq_low = rand_bits & 0xffL # 8 bits, no offset
clock_seq_hi_variant = (rand_bits & 0xff00L) / 0x100 # 8 bits, 8 offset
node = (rand_bits & 0xffffffffffff0000L) / 0x10000L # 48 bits, 16 offset
if lowest_val:
# Make the lowest value UUID with the same timestamp
clock_seq_low = 0 & 0xffL
clock_seq_hi_variant = 0 & 0x3fL
node = 0 & 0xffffffffffffL # 48 bits
# Make the highest value UUID with the same timestamp
clock_seq_low = 0xffL
clock_seq_hi_variant = 0x3fL
node = 0xffffffffffffL # 48 bits
return uuid.UUID(fields=(time_low, time_mid, time_hi_version,
clock_seq_hi_variant, clock_seq_low, node), version=1)
def convert_uuid_to_time(uuid_arg):
Converts a version 1 :class:`uuid.UUID` to a timestamp with the same precision
as :meth:`time.time()` returns. This is useful for examining the
results of queries returning a v1 :class:`~uuid.UUID`.
:param uuid_arg: a version 1 :class:`~uuid.UUID`
:rtype: timestamp
ts = uuid_arg.get_time()
return (ts - 0x01b21dd213814000L)/1e7
# Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Michael Bayer
# The 'as_interface' method is part of SQLAlchemy and is released under
# the MIT License:
import operator
def as_interface(obj, cls=None, methods=None, required=None):
"""Ensure basic interface compliance for an instance or dict of callables.
Checks that ``obj`` implements public methods of ``cls`` or has members
listed in ``methods``. If ``required`` is not supplied, implementing at
least one interface method is sufficient. Methods present on ``obj`` that
are not in the interface are ignored.
If ``obj`` is a dict and ``dict`` does not meet the interface
requirements, the keys of the dictionary are inspected. Keys present in
``obj`` that are not in the interface will raise TypeErrors.
Raises TypeError if ``obj`` does not meet the interface criteria.
In all passing cases, an object with callable members is returned. In the
simple case, ``obj`` is returned as-is; if dict processing kicks in then
an anonymous class is returned.
A type, instance, or dictionary of callables.
Optional, a type. All public methods of cls are considered the
interface. An ``obj`` instance of cls will always pass, ignoring
Optional, a sequence of method names to consider as the interface.
Optional, a sequence of mandatory implementations. If omitted, an
``obj`` that provides at least one interface method is considered
sufficient. As a convenience, required may be a type, in which case
all public methods of the type are required.
if not cls and not methods:
raise TypeError('a class or collection of method names are required')
if isinstance(cls, type) and isinstance(obj, cls):
return obj
interface = set(methods or [m for m in dir(cls) if not m.startswith('_')])
implemented = set(dir(obj))
complies =
if isinstance(required, type):
required = interface
elif not required:
required = set()
complies =
required = set(required)
if complies(implemented.intersection(interface), required):
return obj
# No dict duck typing here.
if not type(obj) is dict:
qualifier = complies is and 'any of' or 'all of'
raise TypeError("%r does not implement %s: %s" % (
obj, qualifier, ', '.join(interface)))
class AnonymousInterface(object):
"""A callable-holding shell."""
if cls:
AnonymousInterface.__name__ = 'Anonymous' + cls.__name__
found = set()
for method, impl in dictlike_iteritems(obj):
if method not in interface:
raise TypeError("%r: unknown in this interface" % method)
if not callable(impl):
raise TypeError("%r=%r is not callable" % (method, impl))
setattr(AnonymousInterface, method, staticmethod(impl))
if complies(found, required):
return AnonymousInterface
raise TypeError("dictionary does not contain required keys %s" %
', '.join(required - found))
Jump to Line
Something went wrong with that request. Please try again.