Skip to content
This repository has been archived by the owner on Aug 4, 2022. It is now read-only.

Commit

Permalink
fixed lua global variables
Browse files Browse the repository at this point in the history
  • Loading branch information
quantmind committed May 8, 2012
1 parent b070b08 commit d88c3d8
Show file tree
Hide file tree
Showing 32 changed files with 215 additions and 154 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.rst
Expand Up @@ -50,7 +50,7 @@ Ver. 0.7c3 - 2012 May 02
* Added :mod:`stdnet.utils.path`. * Added :mod:`stdnet.utils.path`.
* Added a Lua test suite for testing stand alone scripts. Requires lunatest_. * Added a Lua test suite for testing stand alone scripts. Requires lunatest_.
* PEP 386-compliant version number. * PEP 386-compliant version number.
* **572 regression tests** with **90%** coverage. * **573 regression tests** with **90%** coverage.


.. _vers06: .. _vers06:


Expand Down
9 changes: 9 additions & 0 deletions docs/source/_templates/sidebarintro.html
Expand Up @@ -4,9 +4,18 @@ <h3>Python Stdnet</h3>
Redis data-structure server. Redis data-structure server.
It is designed to be fast, memory efficient and highly customizable. It is designed to be fast, memory efficient and highly customizable.
</p> </p>
<g:plusone annotation="inline"></g:plusone>
<script type="text/javascript">
(function() {
var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;
po.src = 'https://apis.google.com/js/plusone.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
})();
</script>
<h3>Useful Links</h3> <h3>Useful Links</h3>
<ul> <ul>
<li><a href="http://pypi.python.org/pypi/python-stdnet">Stdnet @ PyPI</a></li> <li><a href="http://pypi.python.org/pypi/python-stdnet">Stdnet @ PyPI</a></li>
<li><a href="https://github.com/lsbardel/python-stdnet">Stdnet @ github</a></li> <li><a href="https://github.com/lsbardel/python-stdnet">Stdnet @ github</a></li>
<li><a href="http://twitter.com/lsbardel">lsbardel @ twitter</a></li> <li><a href="http://twitter.com/lsbardel">lsbardel @ twitter</a></li>
<li><a href="https://groups.google.com/forum/?fromgroups#!forum/python-stdnet">email list @ google</a></li>
</ul> </ul>
7 changes: 3 additions & 4 deletions runtests.py
Expand Up @@ -4,16 +4,15 @@
import sys import sys
import os import os


from stdnet.conf import settings
from stdnet.utils import Path
from stdnet import test, getdb

## This is for dev environment with pulsar and dynts. ## This is for dev environment with pulsar and dynts.
## If not available, some tests won't run ## If not available, some tests won't run
from stdnet.utils import Path
p = Path(__file__) p = Path(__file__)
p.add2python('pulsar', up=1, down=('pulsar',), must_exist=False) p.add2python('pulsar', up=1, down=('pulsar',), must_exist=False)
p.add2python('dynts', up=1, down=('dynts',), must_exist=False) p.add2python('dynts', up=1, down=('dynts',), must_exist=False)


from stdnet.conf import settings
from stdnet import test, getdb
from stdnet.test import nose, pulsar from stdnet.test import nose, pulsar




Expand Down
2 changes: 1 addition & 1 deletion stdnet/__init__.py
Expand Up @@ -29,4 +29,4 @@
'Topic :: Internet' 'Topic :: Internet'
] ]


sphinxtogithub = True sphinxtogithub = False
13 changes: 8 additions & 5 deletions stdnet/apps/columnts/__init__.py
@@ -1,8 +1,11 @@
'''\ '''\
A timeseries application where each field is stored in a redis string. An application for managing multivariate timeseries_. It provides
This data-structure is composed by several redis structure: tools for performing aggregation and statistics via lua scripts.
* A Timeseries for holding times in an ordered fashion. The redis implementation uses several redis structures for a given
class:`ColumnTS` instance:
* A zset for holding times in an ordered fashion.
* A redis *set* for holding *fields* names. * A redis *set* for holding *fields* names.
* A redis string for each *field* in the timeseries. * A redis string for each *field* in the timeseries.
Expand All @@ -17,8 +20,7 @@
from datetime date from datetime date
from stdnet.apps.columnts ColumnTS from stdnet.apps.columnts ColumnTS
ts = ColumnTS(id = 'test') ts = ColumnTS(id='test')
ts.add(date(2012,2,21), {'open': 603.87, 'close': 614.00}) ts.add(date(2012,2,21), {'open': 603.87, 'close': 614.00})
API API
Expand All @@ -28,6 +30,7 @@
:members: :members:
:member-order: bysource :member-order: bysource
.. _timeseries: http://en.wikipedia.org/wiki/Time_series
''' '''
from . import redis from . import redis
from .encoders import * from .encoders import *
Expand Down
3 changes: 3 additions & 0 deletions stdnet/apps/columnts/models.py
Expand Up @@ -9,6 +9,7 @@


__all__ = ['TimeseriesCache', 'ColumnTS', 'ColumnTSField'] __all__ = ['TimeseriesCache', 'ColumnTS', 'ColumnTSField']



class TimeseriesCache(object): class TimeseriesCache(object):
cache = None cache = None
def __init__(self): def __init__(self):
Expand All @@ -30,6 +31,8 @@ def clear(self):




class ColumnTS(odm.TS): class ColumnTS(odm.TS):
'''A specialised timeseries structure for handling several fields and
statistical calculations.'''
default_multi_stats = ['covariance'] default_multi_stats = ['covariance']


cache_class = TimeseriesCache cache_class = TimeseriesCache
Expand Down
4 changes: 3 additions & 1 deletion stdnet/apps/columnts/npts.py
@@ -1,6 +1,8 @@
'''Experimental! '''Experimental!
This is an experimental module for converting ColumnTS into This is an experimental module for converting ColumnTS into
dynts.timeseries. dynts.timeseries. It requires dynts_.
.. _dynts: https://github.com/quantmind/dynts
''' '''
from . import models as columnts from . import models as columnts


Expand Down
29 changes: 17 additions & 12 deletions stdnet/apps/columnts/redis.py
Expand Up @@ -6,8 +6,8 @@
from stdnet.lib import redis from stdnet.lib import redis




class RedisColumnTS(redisb.TS): class RedisColumnTS(redisb.Zset):

'''Redis backend for :class:`ColumnTS`'''
@property @property
def fieldsid(self): def fieldsid(self):
return self.id + ':fields' return self.id + ':fields'
Expand All @@ -25,6 +25,9 @@ def flush(self):
keys, args = cache.merged_series keys, args = cache.merged_series
return self.client.script_call('timeseries_merge', keys, *args) return self.client.script_call('timeseries_merge', keys, *args)


def _iter(self):
return iter(self.irange(novalues=True))

def allkeys(self): def allkeys(self):
return self.client.keys(self.id + '*') return self.client.keys(self.id + '*')


Expand All @@ -44,21 +47,21 @@ def numfields(self):
'''Number of fields''' '''Number of fields'''
return self.client.scard(self.fieldsid) return self.client.scard(self.fieldsid)


def irange(self, start = 0, end = -1, fields = None, novalues = False, def irange(self, start = 0, end = -1, fields=None, novalues=False,
delete = False): delete=False, **kwargs):
noval = 1 if novalues else 0 noval = 1 if novalues else 0
fields = fields or () fields = fields or ()
delete = 1 if delete else 0 delete = 1 if delete else 0
return self.client.script_call( return self.client.script_call(
'timeseries_query', self.id, 'tsrange', 'timeseries_query', self.id, 'zrange',
start, end, noval, delete, len(fields), start, end, noval, delete, len(fields),
*fields, fields = fields, novalues = novalues) *fields, fields = fields, novalues=novalues)


def range(self, start, end, fields = None, novalues = False): def range(self, start, end, fields=None, novalues=False, **kwargs):
noval = 1 if novalues else 0 noval = 1 if novalues else 0
fields = fields or () fields = fields or ()
return self.client.script_call( return self.client.script_call(
'timeseries_query', self.id,'tsrangebytime', 'timeseries_query', self.id, 'zrangebyscore',
start, end, noval, 0, len(fields), *fields, start, end, noval, 0, len(fields), *fields,
fields = fields, novalues = novalues) fields = fields, novalues = novalues)


Expand Down Expand Up @@ -97,18 +100,18 @@ def merge(self, series, fields):
def istats(self, start, end, fields = None): def istats(self, start, end, fields = None):
fields = fields or () fields = fields or ()
return self.client.script_call('timeseries_stats', self.id, return self.client.script_call('timeseries_stats', self.id,
'tsrange', start, end, 'uni', len(fields), *fields) 'zrange', start, end, 'uni', len(fields), *fields)


def stats(self, start, end, fields = None): def stats(self, start, end, fields = None):
fields = fields or () fields = fields or ()
return self.client.script_call('timeseries_stats', self.id, return self.client.script_call('timeseries_stats', self.id,
'tsrangebytime', start, end, 'uni', len(fields), *fields) 'zrangebyscore', start, end, 'uni', len(fields), *fields)


def imulti_stats(self, start, end, fields, series, stats): def imulti_stats(self, start, end, fields, series, stats):
return self._multi_stats('tsrange', start, end, fields, series, stats) return self._multi_stats('zrange', start, end, fields, series, stats)


def multi_stats(self, start, end, fields, series, stats): def multi_stats(self, start, end, fields, series, stats):
return self._multi_stats('tsrangebytime', start, end, fields, series, return self._multi_stats('zrangebyscore', start, end, fields, series,
stats) stats)


def _multi_stats(self, command, start, end, fields, series, stats): def _multi_stats(self, command, start, end, fields, series, stats):
Expand Down Expand Up @@ -136,6 +139,8 @@ def _multi_stats(self, command, start, end, fields, series, stats):
redisb.BackendDataServer.struct_map['columnts'] = RedisColumnTS redisb.BackendDataServer.struct_map['columnts'] = RedisColumnTS




############################################################## SCRIPTS

class timeseries_session(redis.RedisScript): class timeseries_session(redis.RedisScript):
script = (redis.read_lua_file('tabletools'), script = (redis.read_lua_file('tabletools'),
redis.read_lua_file('columnts.columnts'), redis.read_lua_file('columnts.columnts'),
Expand Down
4 changes: 2 additions & 2 deletions stdnet/backends/redisb.py
Expand Up @@ -476,15 +476,15 @@ def flush(self):
return result return result


def get(self, score): def get(self, score):
r = self.range(score,score,withscores=False) r = self.range(score, score, withscores=False)
if r: if r:
if len(r) > 1: if len(r) > 1:
return r return r
else: else:
return r[0] return r[0]


def _iter(self): def _iter(self):
return iter(self.irange(withscores = False)) return iter(self.irange(withscores=False))


def size(self): def size(self):
return self.client.zcard(self.id) return self.client.zcard(self.id)
Expand Down
4 changes: 2 additions & 2 deletions stdnet/conf.py
Expand Up @@ -66,13 +66,13 @@ def __init__(self):


def redis_status(self): def redis_status(self):
from stdnet import getdb from stdnet import getdb
from stdnet.lib.redis import ConnectionError from stdnet.lib.redis import RedisConnectionError
db = getdb(self.DEFAULT_BACKEND) db = getdb(self.DEFAULT_BACKEND)
status = "ok" status = "ok"
if db.name == 'redis': if db.name == 'redis':
status = db.client.redis_status() status = db.client.redis_status()
if not status: if not status:
raise ConnectionError('No connection available for server\ raise RedisConnectionError('No connection available for server\
at "{0}"'.format(self.DEFAULT_BACKEND)) at "{0}"'.format(self.DEFAULT_BACKEND))
os.environ['stdnet_backend_status'] = status os.environ['stdnet_backend_status'] = status
return status return status
Expand Down
25 changes: 24 additions & 1 deletion stdnet/exceptions.py
Expand Up @@ -3,63 +3,86 @@ class StdNetException(Exception):
'''A general StdNet exception''' '''A general StdNet exception'''
pass pass



class ConnectionError(StdNetException):
pass


class SessionNotAvailable(StdNetException): class SessionNotAvailable(StdNetException):
pass pass



class ModelNotAvailable(StdNetException): class ModelNotAvailable(StdNetException):
pass pass



class ModelNotRegistered(SessionNotAvailable): class ModelNotRegistered(SessionNotAvailable):
'''A :class:`StdNetException` raised when trying to save an instance of a :class:`stdnet.odm.StdModel` not yet '''A :class:`StdNetException` raised when trying to save an instance of a :class:`stdnet.odm.StdModel` not yet
registered with a :class:`stdnet.backends.BackendDataServer`. Check :func:`stdnet.odm.register` for details.''' registered with a :class:`stdnet.backends.BackendDataServer`. Check :func:`stdnet.odm.register` for details.'''
pass pass



class InvalidTransaction(StdNetException): class InvalidTransaction(StdNetException):
'''A :class:`StdNetException` raised when trying to create a transaction '''A :class:`StdNetException` raised when trying to create a transaction
with models registered with different backends.''' with models registered with different backends.'''
pass pass


class CommitException(StdNetException):
class ResponseError(StdNetException):
'''Raised when an invalid response is returned from the backebd server.'''
pass


class CommitException(ResponseError):
'''A :class:`StdNetException` raised when trying to create a transaction '''A :class:`StdNetException` raised when trying to create a transaction
with models registered with different backends.''' with models registered with different backends.'''
def __init__(self, msg, failures = 1): def __init__(self, msg, failures = 1):
self.failures = failures self.failures = failures
super(CommitException,self).__init__(msg) super(CommitException,self).__init__(msg)



class AlreadyRegistered(StdNetException): class AlreadyRegistered(StdNetException):
pass pass



class ObjectNotValidated(StdNetException): class ObjectNotValidated(StdNetException):
'''A :class:`StdNetException` raised when an instance of a :class:`stdnet.odm.StdModel` fails to validate '''A :class:`StdNetException` raised when an instance of a :class:`stdnet.odm.StdModel` fails to validate
(probably required :class:`stdnet.odm.Field` are missing from the instance).''' (probably required :class:`stdnet.odm.Field` are missing from the instance).'''
pass pass



class ImproperlyConfigured(StdNetException): class ImproperlyConfigured(StdNetException):
"A :class:`stdnet.StdNetException` raised when stdnet is somehow improperly configured" "A :class:`stdnet.StdNetException` raised when stdnet is somehow improperly configured"
pass pass



class BadCacheDataStructure(StdNetException): class BadCacheDataStructure(StdNetException):
pass pass



class FieldError(StdNetException): class FieldError(StdNetException):
'''Generic Field error''' '''Generic Field error'''
pass pass



class StructureFieldError(StdNetException): class StructureFieldError(StdNetException):
'''A :class:`stdnet.FieldError` for :class:stdnet.odm.StructureField`.''' '''A :class:`stdnet.FieldError` for :class:stdnet.odm.StructureField`.'''
pass pass



class FieldValueError(FieldError): class FieldValueError(FieldError):
'''A :class:`stdnet.FieldError` raised when passing a wrong '''A :class:`stdnet.FieldError` raised when passing a wrong
value to a field. This exception is cought during the model instance value to a field. This exception is cought during the model instance
validation algorithm in :meth:`stdnet.odm.base.Metaclass.is_valid`.''' validation algorithm in :meth:`stdnet.odm.base.Metaclass.is_valid`.'''
pass pass



class QuerySetError(StdNetException): class QuerySetError(StdNetException):
'''A :class:`stdnet.StdNetException` raised during a :class:`stdnet.odm.query.QuerySet` '''A :class:`stdnet.StdNetException` raised during a :class:`stdnet.odm.query.QuerySet`
evaluation.''' evaluation.'''
pass pass



class ObjectNotFound(QuerySetError): class ObjectNotFound(QuerySetError):
'''A :class:`QuerySetError` raised when an object is not found.''' '''A :class:`QuerySetError` raised when an object is not found.'''
pass pass
Expand Down
2 changes: 1 addition & 1 deletion stdnet/lib/__init__.py
@@ -1,4 +1,4 @@
hasextensions = True hasextensions = False
hr = None hr = None
from .fallback import * from .fallback import *
from . import fallback from . import fallback
Expand Down

0 comments on commit d88c3d8

Please sign in to comment.