{ "info": { "author": "Aaron Westendorf", "author_email": "aaron@agoragames.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 4 - Beta", "Intended Audience :: Developers", "License :: OSI Approved :: BSD License", "Operating System :: POSIX", "Programming Language :: Python", "Programming Language :: Python :: 2.7", "Topic :: Communications", "Topic :: Software Development :: Libraries", "Topic :: Software Development :: Libraries :: Python Modules", "Topic :: System :: Distributed Computing" ], "description": "=====\nTorus\n=====\n\n:Version: 0.7.1\n:Download: http://pypi.python.org/pypi/torus\n:Source: https://github.com/agoragames/torus\n:Keywords: python, redis, time, rrd, gevent, carbon, graphite, whisper, statsd, kairos\n\nA suite of tools designed to replace `Graphite`__ and expand on its capabilities. \nUses `kairos `_ to support storing and \nreading data from many different types of data stores, and focuses on providing\nprogrammatic tools for storing, retrieving and processing of streaming \ntimeseries data.\n\n__ http://graphite.readthedocs.org\n\n.. contents::\n :local:\n\nMotivation\n==========\n\nKairos, an RRD-inspired timeseries library, provides an improved storage\nengine and many more features than most other systems backing statsd. Compared\nto traditional disk stores such as RRD and Whisper, Torus adds:\n\n* simple runtime for ease in development and deployment\n* abstraction on top of kairos for histograms\n* compact storage for sparse data points\n* scaling with per-schema hosting and sharding\n* non-buffering semantics for aggregate processing\n* consistent hashing of timestamps for ease in interleaving and interpolation\n* programmatic interface to data processing\n\nStatsD Quick Start\n==================\n\nA configuration file that tracks hourly, daily and monthly data in SQLite is\navailable in ``examples/statsd.py``. The default will create a temp directory\nfor the current user to store the databases (e.g. ``/tmp/torus.user`` on Unix).\nChange ``STORAGE_DIR`` at the top of the file to set a permanent location.\n\nIf you have installed torus in a virtual env, you can use ``foreman`` to start\nboth ``karbon`` and ``torus``. If you're running torus out of the repository,\nthen you can use ``foreman start -f Procfile.dev``.\n\nThe example configuration includes support for performance testing (see below).\n\nCarbon Server\n=============\n\nThe ``karbon`` application runs the `Carbon `_-compatible\nstat collection application. It is a drop-in replacement for the Carbon backend of\n`statsd `_. It takes the following arguments: ::\n\n usage: karbon [-h] [--tcp TCP] [--config CONFIG]\n\n Karbon, a Carbon-replacement data collection server\n\n optional arguments:\n -h, --help show this help message and exit\n --tcp TCP TCP binding, in the form of \"host:port\", \":port\", or\n \"port\". Defaults to \"localhost:2003\".\n --config CONFIG Configuration file to load. Can be called multiple times\n for multiple configuration files.\n\n\nThe configuration is documented below. To reload the configuration(s), send a \n``SIGHUP`` to the ``karbon`` process.\n\nQuery Server\n============\n\nThe `torus` application is a replacement for `Graphite `_.\nIt is not API compatible with Graphite though it does aim to be familiar to\nGraphite users and provides a graphite-compatible JSON format for ease in integrating\nwith existing toolchains. ::\n\n usage: torus [-h] [--tcp TCP] [--config CONFIG]\n\n Torus, a web server for mining data out of kairos\n\n optional arguments:\n -h, --help show this help message and exit\n --tcp TCP TCP binding, in the form of \"host:port\", \":port\", or\n \"port\". Defaults to \"localhost:8080\".\n --config CONFIG Configuration file to load. Can be called multiple times\n for multiple configuration files.\n\n\nFor most use cases it can share a configuration with ``karbon``. However, one \ncould use ``Chef``, ``puppet`` or a similar tool to templatize the \nconfiguration, and replace strings such as the ``host`` definition, so as to \ntarget a specific set of resources at reading the data.\n\nTo reload the configuration(s), send a ``SIGHUP`` to the ``torus`` process.\n\n``torus`` will respond to ``http://$tcp/$command?$parameters`` for the \nfollowing commands, where ``$parameters`` is a standard URL encoded \nparameter list.\n\nCommands\n--------\n\n/series\n#######\n\nDEPRECATED: formerly ``/data``\n\n\nParameters\n**********\n\nFetches data for one or more statistics and returns a list of objects for each statistic. Returns data from the first schema that matches a statistic.\n\n* stat\n\n The name of the statistic to fetch. Each instance of the ``stat`` parameter\n is interpreted as a separate statistic. The statistic can either be in the\n form of ``$stat_name`` or ``$func($stat_name)``, where ``$func`` can be one of:\n\n * avg - the average of each datapoints in each time slice.\n * min - the minimum value of datapoints in each time slice. \n * max - the maximum value of datapoints in each time slice.\n * sum - the sum of datapoints in each time slice.\n * count - the number of datapoints in each time slice.\n\n Additionally, ``$func`` can be either a transform or a macro defined in the\n configuration. The ``$func`` can be anything that matches the \n pattern ``[a-zA-Z0-9_]``.\n\n* format\n\n One of ``[graphite, json]``, where ``graphite`` is a Graphite-compatible json\n format and ``json`` offers more nuanced representation of ``kairos``' data\n structures.\n\n* condense\n\n One of ``[true, false]``, if ``kairos`` resolutions are configured for a \n schema, determines whether resolutions are flattened or returned as-is. \n Forced to ``true`` for ``graphite`` format.\n\n* collapse\n\n One of ``[true, false]``, if ``true`` then all of the data for each time\n interval will be collapsed into a single value. This is useful for\n calculating aggregates across a range (e.g. \"all hits in last 5 days\"). \n\n* schema\n\n In cases where multiple schemas match a stat name, force a particular \n schema to be used.\n\n* interval\n\n The interval to choose, one of the intervals available in whatever schema\n matches ``stat``. Must apply to all ``stat`` arguments.\n\n* start\n\n An optional timestamp for the beginning of the return interval. Can be in\n the form of a unix timestamp, a ``strftime``-formatted string, or a \n human-readable relative value such as \"today\", \"5 days ago\", \"last week\",\n etc.\n\n* end\n\n An optional timestamp for the end of the return interval. Can accept the\n same values as ``start``. With no arguments, this is implicitely the time\n at which the query is made.\n\n* steps\n\n Given either a ``start`` or ``end`` timestamp, this parameter defines the\n number of intervals (inclusive) after or before (respectively) to return. \n So if ``start`` is \"last week\" and ``steps=7``, the result data will end \n with yesterday's data. If no timestamps are given, this is the number of\n intervals before the current time (inclusive).\n\n\nReturns\n*******\n\nA json structure. ::\n\n [{\n 'function': 'avg',\n 'interval': 'hour',\n 'schema': 'calls',\n 'stat': 'avg(calls.system)',\n 'stat_name' : 'calls.system',\n 'target': 'calls.system',\n 'datapoints': [[0.0391, 1362153600], [0, 1362157200]],\n\n }, \n ...\n ]\n\nThe ``stat`` field will be the full name of the corresponding parameter, \nincluding the function (if any). The ``stat_name`` field will be just the\nname of the statistic that was matched to the schema, and ``target`` will\nbe a copy of the same for clients which are expecting data in ``graphite``\nformat.\n\n\nConfiguration\n=============\n\nAll torus applications load one or more configurations, where a configuration\nis a python module that is loaded into the application. Torus looks for the\nconstants documented below, but as the configuration is a full python module,\nextensions, plugins and additional runtime configuration can be included. For\nexample, one can connect torus' use of the standard python \n`logger `_\nto syslog, logstash or one of many error reporting tools, such as Sentry.\nFor ``torus``, log messages prioritize the header ``X-Forwarded-For`` and \nthen use the remote IP address if that's not available. For this reason and \ngeneral security, you should always use a proxy server in front of ``torus``.\n\nThe configuration for ``torus`` includes a definition for schemas, aggregates,\ncustom functions that can be used in queries, and debugging settings. The \nschema for ``torus`` is an extension of the ``kairos`` schema; each of the \nkey-value pairs in a schema definition will be passed to the timeseries\n`constructor `_.\nThe configuration files can include 1 or more of the following.\n\non_load\n-------\n\nIf this is a callable, will be called the first time the configuration is \nloaded. Useful for one-time configuration such as Sentry logging handlers.\n\non_reload\n---------\n\nIf this is a callable, will be called when the configuration module is\nreloaded.\n\nSCHEMAS\n-------\n\nA dictionary of unique names to the configuration for capturing and storing \nthe statistics which match the regular expressions. A schema definition\nsupports the following fields, many of which are passed directly to\n`kairos `_.\n\n* type\n\n Required, defines the type of the timeseries. One of \n ``[series, histogram, count, set, gauge]``, depending on what the backend\n supports.\n\n* host\n\n Required, the URL connection string or an instance of a supported\n connection type. See \n `Storage Engines`__ \n\n__ https://github.com/agoragames/kairos#storage-engines\n\n* client_config\n\n Optional, is a dictionary of parameters to use in the connection \n constructor associated with the ``host`` URL. See `Storage Engines`__\n\n__ https://github.com/agoragames/kairos#storage-engines\n\n* match\n\n A string, or a list of strings, which are regular expressions that define\n the stat names which should be stored and queried in this schema. In the\n case where a ``transform`` is defined, it is likely the one or more \n expressions will define the input stats, and another expression will define\n the stat which can be queried. See GitHub \n `issue `_.\n\n* rolling\n\n Optional, defines how many intervals before (negative) or after (positive) \n that a copy of data should be written to whenever data is inserted. The\n extra storage size offsets much faster calculation of aggregates over\n pre-determined date range. For example, when storing daily values, a value\n of ``-30`` will store a value as if it occurred any time in the last 30 days.\n\n* prefix\n\n Optional, is used to scope data in redis data stores. If supplied and it\n doesn't end with \":\", it will be automatically appended.\n\n* transform\n \n Optional, allows one to replace the stat name and value with another.\n Takes two arguments and must return a tuple of two items (statistic,\n value). If the statistic is None, will skip writing the statistic.\n The value will be a string on input, and on output must be acceptable\n to any write_func defined.\n Example: ``transform: lambda s,v: (None,None) if 0>long_or_float(v)>3.14 else (s,v)``\n\n* read_func\n\n Optional, is a function applied to all values read back from the\n database. Without it, values will be strings. Must accept a string\n value and can return anything. Defaults to ``long_or_float``, which\n tries to cast to a long and failing that, cast to a float.\n ``long_or_float`` is available for all schemas to use.\n\n* write_func\n\n Optional, is a function applied to all values when writing. Can be\n used for histogram resolution, converting an object into an id, etc.\n Must accept whatever can be inserted into a timeseries and return an\n object which can be cast to a string. Defaults to ``long_or_float``,\n which tries to cast to a long and failing that, cast to a float.\n Example: ``write_func: lambda v: '%0.3f'%(v)``\n\n* intervals\n\n Required, defines the `intervals `_\n in which data should be stored.\n\n* generator\n\n Optional, defines a function which can be used to generate load tests. Must\n return a tuple in the form ``(stat_name, value)``.\n Example: ``lambda: ('application.hits.%d'%(random.choice([200,404,500])), 1)``\n\nExample: ::\n\n SCHEMAS = {\n\n 'response_times' : {\n 'type': 'histogram'\n 'host': 'redis://localhost:6379/0'\n 'match': [ 'application.*.response_time', 'application.response_time' ]\n 'read_func': float\n 'write_func': lambda v: '%0.3f'%(v)\n\n 'intervals': {\n 'minute': {\n 'step': 60,\n 'steps': 240,\n },\n 'daily' : {\n 'step': 'daily',\n 'steps': 30\n }\n },\n }\n }\n\n\nAGGREGATES\n----------\n\nSimilar to Carbon aggregator but without the time buffer. Matching stats\nwill be processed through any matching schemas. Is a list of tuples to\nsupport rolling up any number of dissimilar stats into a single one. At\nthis time key names must be in the character set ``[a-zA-Z0-9_-]``. Each aggregate\nis defined as a tuple in the form of ``(rollup_stat, source_stat)``. Captures\ncan be defined in the form of ```` and used in each rollup.\n\nExample: ::\n \n AGGREGATES = [\n ('application.response_time', 'application.*.response_time'),\n ('application.', 'application.*.status.'),\n ]\n\n\nTRANSFORMS\n----------\n\nA named mapping of functions which can be used in queries. \n\nExample: ::\n\n TRANSFORMS = {\n # Returns the number of elements\n 'size' : lambda row: len(row)\n }\n\nMACROS\n------\n\nA named map of configuration options so that \"foo(stat)\" will result in\na fixed set of options passed to kairos. This is especially useful for\nusing the customized read feature of kairos. This example assumes a \nhistogram stored in redis. A more complicated macro might use server-side\nscripting. All custom read functions exposed in kairos can be defined here.\nAll fields of the query string, other than 'stat', can be set in the\nmacro definition and will override those query parameters if they're\nprovided. To use a transform in a macro, set the 'transform' field to\neither a string or a callable. Macros can make use of transforms defined\nin ``TRANSFORMS``.\n\nExample: ::\n\n MACROS = {\n 'unique' : {\n 'fetch' : lambda handle,key: handle.hlen(key)\n 'condense' : lambda data: sum(data.values()),\n 'process_row' : lambda data: data,\n 'join_rows' : lambda rows: sum(rows),\n }\n }\n\nDEBUG\n-----\n\nA boolean or integer to define the amount of log output. \n\n* 0 or ``False``\n\n Only errors are logged.\n\n* 1 or ``True``\n\n Basic information is logged, should not generate substantial output.\n\n* 2\n\n Significant information is logged, particularly from the ``karbon`` process.\n \n\nDebugging\n=========\n\nDebugging a schema or set of schemas can pose a challenge. Torus ships with ``schema_debug``,\na tool for testing any number of input strings against any number of schemas. It will \noutput which rules match the input string, which database that match will be stored in, any\naggregates that will be generated from the input rule, and then recursively any schemas and\naggregates that match each aggregate. ::\n\n usage: schema_debug [-h] [--config CONFIG] strings [strings ...]\n\n Debugging tool for schemas\n\n positional arguments:\n strings One or more input strings to test against the scheams\n\n optional arguments:\n -h, --help show this help message and exit\n --config CONFIG Configuration file to load. Can be called multiple times\n for multiple configuration files.\n\nTorus also supports the ``DEBUG`` flag which can be defined in any of the\nconfiguration files and which will cause ``karbon`` to print to stdout. If \nit is ``0``, or not defined, no output will be generated. If it is ``1``,\n``karbon`` will log when it stores a raw value (``STOR``) or aggregate\n(``AGRT``), and statistics on the quantity and duration of processing\n(``DONE``). If ``DEBUG==2``, ``karbon`` will also log every line it \nrecieves (``RECV``) and lines that it skips (``SKIP``).\n\nTo use the debugging flag, you can change the value in one of the configuration\nfiles loaded by ``karbon``, and then signal the process to reload with the \ncommand ``kill -SIGHUP `pidof karbon```.\n\nPerformance Testing\n===================\n\nTo test your schema for performance and regressions, torus includes \n``schema_test``. The tool looks for ``generator`` definitions in schemas,\nand continually calls them to emit data points that are processed through\nall the schemas and aggregates. Prints out some basic statistics. ::\n\n usage: schema_test [-h] [--config CONFIG] [--clear] [--duration DURATION]\n\n Tool for performance testing of schemas\n\n optional arguments:\n -h, --help show this help message and exit\n --config CONFIG Configuration file to load. Can be called multiple\n times for multiple configuration files.\n --clear If true, clear all data before running the test.\n Defaults to false.\n --duration DURATION Duration of the test. Defaults to 60 seconds.\n\nMigration\n=========\n\nThere will be times that you need to migrate data from one schema to another. \nTorus ships with ``migrate`` to facilitate that. ::\n\n usage: migrate [-h] --config CONFIG --source SOURCE --destination DESTINATION\n --interval INTERVAL [--start START] [--end END]\n [--concurrency CONCURRENCY] [--stat STAT] [--match MATCH]\n [--dry-run] [--verbose]\n\n A tool to migrate data from one schema to another\n\n optional arguments:\n -h, --help show this help message and exit\n --config CONFIG Configuration file to load. Can be called multiple\n times for multiple configuration files.\n --source SOURCE The name of the source schema [required]\n --destination DESTINATION\n The name of the destination schema [required]\n --interval INTERVAL The name of the interval from which to read data\n [required]\n --start START Only copy stats occurring on or after this date. Same\n format as web parameter. [optional]\n --end END Only copy stats occurring on or before this date. Same\n format as web parameter. [optional]\n --concurrency CONCURRENCY\n Set the concurrency on the schema target writing.\n Defaults to 10.\n --stat STAT The name of the stat to copy. Can be called multiple\n times for a list of stats. If not provided, all stats\n will be copied. [optional]\n --match MATCH Pattern match to migrate a subset of the data.\n [optional]\n --dry-run Print out status but do not save results in the\n destination schema. [optional]\n --verbose Print out even more information during the migration\n [optional]\n\n\nInstallation\n============\n\nTorus is available on `pypi `_ and can be installed using ``pip`` ::\n\n pip install torus\n\n\nIf installing from source:\n\n* with development requirements (e.g. testing frameworks) ::\n\n pip install -r development.pip\n\n* without development requirements ::\n\n pip install -r requirements.pip\n\nSQL\n---\n\nTorus installs SQLAlchemy to support SQL. To use your dialect of choice, you\nwill likely have to install additional packages. Refer to the\n`documentation `_ \nfor more details.\n\nTests\n=====\n\nUse `nose `_ to run the test suite. ::\n\n $ nosetests\n\nRoadmap\n=======\n\n* Record metrics on karbon and torus usage\n* Add \"dead letter\" support for tracking stats that don't match any schema\n* Add stat delete endpoint to ``torus``\n* Command line tools for querying data and optionally plotting using `bashplotlib `_\n* Add tools for generating tasseo configurations (https://github.com/obfuscurity/tasseo)\n* Add ability to set transaction-commit intervals for Redis and SQLite backends\n* Investigate faster regular expression engines. `pyre2 `_ is currently in the running.\n* Expand supported stat naming (unicode, symbols, etc)\n* A ``relay`` host type for forwarding karbon data to another Carbon-compatible host\n* Schema migration tools\n* log and stdout for ``torus`` and ``karbon``", "description_content_type": null, "docs_url": null, "download_url": "UNKNOWN", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/agoragames/torus", "keywords": "python,redis,mongo,sql,mysql,sqlite,postgresql,cassandra,time,timeseries,gevent,graphite,carbon,rrd,statistics", "license": "LICENSE.txt", "maintainer": null, "maintainer_email": null, "name": "torus", "package_url": "https://pypi.org/project/torus/", "platform": "UNKNOWN", "project_url": "https://pypi.org/project/torus/", "project_urls": { "Download": "UNKNOWN", "Homepage": "https://github.com/agoragames/torus" }, "release_url": "https://pypi.org/project/torus/0.7.1/", "requires_dist": null, "requires_python": null, "summary": "Carbon and Graphite replacement using Kairos for timeseries storage", "version": "0.7.1" }, "last_serial": 1029658, "releases": { "0.1.0": [ { "comment_text": "", "digests": { "md5": "93547e54038a4debfbe2cef50d04175c", "sha256": "bef4c51bb52f53858dc2a0c93b151f6e4e6b032d97f0a53754f1d56a99ce1b0c" }, "downloads": -1, "filename": "torus-0.1.0.tar.gz", "has_sig": false, "md5_digest": "93547e54038a4debfbe2cef50d04175c", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 10854, "upload_time": "2013-03-01T21:44:03", "url": "https://files.pythonhosted.org/packages/0b/5a/ec502707f4b8fff867911cba0ca1b1012be9ed58c35b6632a299e5bf4116/torus-0.1.0.tar.gz" } ], "0.1.1": [ { "comment_text": "", "digests": { "md5": "c712dfe57de3ef0b0712afff641277e2", "sha256": "5fd7fe76558e9bfc5644c7395d3c4caf1365054e8c5c85d8c58970fb70100fd1" }, "downloads": -1, "filename": "torus-0.1.1.tar.gz", "has_sig": false, "md5_digest": "c712dfe57de3ef0b0712afff641277e2", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 11023, "upload_time": "2013-03-11T15:01:59", "url": "https://files.pythonhosted.org/packages/f6/8a/b636f9313cd8ae1f866966b275a2aaf5a5f79fbc8bb650ffbaf1f97bc5e0/torus-0.1.1.tar.gz" } ], "0.1.2": [ { "comment_text": "", "digests": { "md5": "79d68511f793446c9cbcb25c3d6fc0e4", "sha256": "90323c903863d4daa6520aa53a84557837165ce2d7d74b9ebc4da2d0dc888f97" }, "downloads": -1, "filename": "torus-0.1.2.tar.gz", "has_sig": false, "md5_digest": "79d68511f793446c9cbcb25c3d6fc0e4", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 11322, "upload_time": "2013-03-11T20:39:25", "url": "https://files.pythonhosted.org/packages/3c/a0/6747853b95f6f7f94f6f2b743b1a35222adb68f0d797632d23f074a32457/torus-0.1.2.tar.gz" } ], "0.1.3": [ { "comment_text": "", "digests": { "md5": "26023ac96bdd26d065c3cad0cf6cc0e3", "sha256": "28392274d426ba74c78fc54edd800f859c78afb7c38490159a65a6074076ccd3" }, "downloads": -1, "filename": "torus-0.1.3.tar.gz", "has_sig": false, "md5_digest": "26023ac96bdd26d065c3cad0cf6cc0e3", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 11359, "upload_time": "2013-03-12T17:26:51", "url": "https://files.pythonhosted.org/packages/4a/cb/a46ba2d915f88dda6d7c7cd012ee1dbc8c7e33cd5906868fab3718ea6582/torus-0.1.3.tar.gz" } ], "0.1.4": [ { "comment_text": "", "digests": { "md5": "5a4b189698e803717f72b549f1fef220", "sha256": "dd5de11f759d41fa5045cd9373fb7b5f391b956d7475227955d7cb0c2ef01263" }, "downloads": -1, "filename": "torus-0.1.4.tar.gz", "has_sig": false, "md5_digest": "5a4b189698e803717f72b549f1fef220", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 11409, "upload_time": "2013-04-04T16:51:29", "url": "https://files.pythonhosted.org/packages/95/63/bb4c5a4beb2c1a02ba28ad5540ccb4243b713edc61d9fe0c3551b3206f84/torus-0.1.4.tar.gz" } ], "0.2.0": [ { "comment_text": "", "digests": { "md5": "1389dfec08d54c72ae10c0f683387717", "sha256": "ea9c63ee6c0ac357fae6fb55ab8f451d1f3b7049f7e4b505fadacc3aea66c7d1" }, "downloads": -1, "filename": "torus-0.2.0.tar.gz", "has_sig": false, "md5_digest": "1389dfec08d54c72ae10c0f683387717", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 12659, "upload_time": "2013-05-10T13:45:47", "url": "https://files.pythonhosted.org/packages/53/f4/e4aba2c203e52520a7d08de01fc3a0123c39a9613a3b83d7c1fb12647741/torus-0.2.0.tar.gz" } ], "0.2.1": [ { "comment_text": "", "digests": { "md5": "ad3a44d735f36e3a4fec5aceac40c930", "sha256": "65f466c6f06c56e20ae2ade2faece3d6b2bb880acb6c533f4a92dc28c6d73fba" }, "downloads": -1, "filename": "torus-0.2.1.tar.gz", "has_sig": false, "md5_digest": "ad3a44d735f36e3a4fec5aceac40c930", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 13119, "upload_time": "2013-05-14T20:39:13", "url": "https://files.pythonhosted.org/packages/e8/00/eda0e9af9dabba0ba386c783d9c35a19465d10bb0388dfc097ab35d1e31c/torus-0.2.1.tar.gz" } ], "0.3.0": [ { "comment_text": "", "digests": { "md5": "4577f6cbc9860683df0d47c81a0a79f7", "sha256": "e978b59ad526a3fa9caa7504d661e80b9b2188a02b7fae96d7be1d46c45196c9" }, "downloads": -1, "filename": "torus-0.3.0.tar.gz", "has_sig": false, "md5_digest": "4577f6cbc9860683df0d47c81a0a79f7", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 15904, "upload_time": "2013-05-16T01:45:31", "url": "https://files.pythonhosted.org/packages/3f/5f/e7ff6315b84ac75bb34ad216f95fb037384a5da9b7f8b3096269861a4a31/torus-0.3.0.tar.gz" } ], "0.3.1": [ { "comment_text": "", "digests": { "md5": "1b336950c36d256070043cd8c06a141c", "sha256": "e5de2b9695abe510ec30f7c6c0852643f0c475c38fbb4f67a7093466a8b8aba6" }, "downloads": -1, "filename": "torus-0.3.1.tar.gz", "has_sig": false, "md5_digest": "1b336950c36d256070043cd8c06a141c", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 13781, "upload_time": "2013-05-23T19:58:19", "url": "https://files.pythonhosted.org/packages/cf/4b/f53fffcba198450439743a43740f2b7091f4841919c9889d732a4af9ce90/torus-0.3.1.tar.gz" } ], "0.3.2": [ { "comment_text": "", "digests": { "md5": "ff692aabf2f632c1a898efa0237e778c", "sha256": "c96e1924e7acadc372948282cf46698f874f063f1507b64011fea5dc3533c908" }, "downloads": -1, "filename": "torus-0.3.2.tar.gz", "has_sig": false, "md5_digest": "ff692aabf2f632c1a898efa0237e778c", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 13779, "upload_time": "2013-05-23T20:07:04", "url": "https://files.pythonhosted.org/packages/6b/f4/f0a0efa4990ecee0b0b923cf4f01ec69416d6f188aff7773b2055567374d/torus-0.3.2.tar.gz" } ], "0.3.3": [ { "comment_text": "", "digests": { "md5": "92b5e69faea35a5a3df79bd3625180a3", "sha256": "2be236093d892d9504dd6a9b672bc6d0df54e2dc973ec34cf4aab2db147ed685" }, "downloads": -1, "filename": "torus-0.3.3.tar.gz", "has_sig": false, "md5_digest": "92b5e69faea35a5a3df79bd3625180a3", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 15249, "upload_time": "2013-05-29T20:51:06", "url": "https://files.pythonhosted.org/packages/1d/ba/1a270239cb6201f867508065d06470cf517689c1b403761a7f6981d02503/torus-0.3.3.tar.gz" } ], "0.4.0": [ { "comment_text": "", "digests": { "md5": "863c656481a06ee8d38f2cee9c3fdac4", "sha256": "30656f9c00f386ba10a28ac64893401bb64de70dd96609fb3cd5a1bb635e1c10" }, "downloads": -1, "filename": "torus-0.4.0.tar.gz", "has_sig": false, "md5_digest": "863c656481a06ee8d38f2cee9c3fdac4", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 16303, "upload_time": "2013-07-03T20:11:01", "url": "https://files.pythonhosted.org/packages/59/d8/0ee4d6fc8f5ebf74944dd01772e7d3910c33d5af9f48c6d56a60f46ca78d/torus-0.4.0.tar.gz" } ], "0.4.1": [ { "comment_text": "", "digests": { "md5": "2b3a667171ab5d58e52e888d5ee4b5a7", "sha256": "d70c31162c22703816424dabdd7efbe967370859c0c2d583edda1e632e6affa2" }, "downloads": -1, "filename": "torus-0.4.1.tar.gz", "has_sig": false, "md5_digest": "2b3a667171ab5d58e52e888d5ee4b5a7", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 16547, "upload_time": "2013-07-19T15:11:55", "url": "https://files.pythonhosted.org/packages/d0/92/a1772db53a28f1515067c6492ba25075bcf824fa4fedfbb384b039e6f5fd/torus-0.4.1.tar.gz" } ], "0.4.2": [ { "comment_text": "", "digests": { "md5": "2f38b472a8982e8e0aa6a39cb8320e97", "sha256": "31a834e7bd1c65038fec8da0f002708c024d59a53d40217c20e4403cfb6e1ba2" }, "downloads": -1, "filename": "torus-0.4.2.tar.gz", "has_sig": false, "md5_digest": "2f38b472a8982e8e0aa6a39cb8320e97", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 16590, "upload_time": "2013-07-29T18:26:51", "url": "https://files.pythonhosted.org/packages/54/5a/fa674551fbb8d2a0f119f58b1aa725f9a82d5141c13f7d51cd54bf0d6d8f/torus-0.4.2.tar.gz" } ], "0.4.3": [ { "comment_text": "", "digests": { "md5": "bf765219b4f0ec7f0878d7ce49de35e2", "sha256": "18e66f362216e7ce6bb4ff8d3f23357bf6dfc97963447d195210c24f8c9ecbc0" }, "downloads": -1, "filename": "torus-0.4.3.tar.gz", "has_sig": false, "md5_digest": "bf765219b4f0ec7f0878d7ce49de35e2", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 16634, "upload_time": "2013-07-30T12:48:19", "url": "https://files.pythonhosted.org/packages/80/0b/01dfabbfd4c7db978027a08658eefe4a48fcfa48383887ccbba1a6601290/torus-0.4.3.tar.gz" } ], "0.5.0": [ { "comment_text": "", "digests": { "md5": "87e882743f7ea3218e761ad37e19690f", "sha256": "f51f128df0357d0ee97d3340ff6a5c45dde27a51e8c1b02662fcf97f07646f82" }, "downloads": -1, "filename": "torus-0.5.0.tar.gz", "has_sig": false, "md5_digest": "87e882743f7ea3218e761ad37e19690f", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 17943, "upload_time": "2013-10-11T20:04:55", "url": "https://files.pythonhosted.org/packages/e1/b9/5179a6c143f980de4eb40cee36b919ef42ae7cbf44776201216b2ff4d272/torus-0.5.0.tar.gz" } ], "0.6.0": [ { "comment_text": "", "digests": { "md5": "94c1b7a00bb5e3e071b312ac377d9963", "sha256": "3ea31210e7e03dd90d901c8ea78f504538ba558aba3ce1bb520f34d499b7afa6" }, "downloads": -1, "filename": "torus-0.6.0.tar.gz", "has_sig": false, "md5_digest": "94c1b7a00bb5e3e071b312ac377d9963", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 30609, "upload_time": "2013-11-19T04:17:37", "url": "https://files.pythonhosted.org/packages/e3/e6/fd4ecd0faee2cc3db0b2170c3d3f533c26fe9647639f799f8d9044660b8d/torus-0.6.0.tar.gz" } ], "0.6.1": [ { "comment_text": "", "digests": { "md5": "144a324d33a556230b7dfb3da22b219d", "sha256": "59d6080eac998d38fdfb5014924ac9368537cd707c7b53cd5f69a543993c435e" }, "downloads": -1, "filename": "torus-0.6.1.tar.gz", "has_sig": false, "md5_digest": "144a324d33a556230b7dfb3da22b219d", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 21537, "upload_time": "2013-11-21T16:24:40", "url": "https://files.pythonhosted.org/packages/00/47/82c0a2aec48cb141fc088e059bc1b81d17761c740ef45b18ec7dca1f3800/torus-0.6.1.tar.gz" } ], "0.6.2": [ { "comment_text": "", "digests": { "md5": "34c28f1f6255bd0d4d3deb6aa81cfe0a", "sha256": "a5973c8c660239ddf1b683af7a487da36eaa28e5bf90e5cb8fcebe3351c6376b" }, "downloads": -1, "filename": "torus-0.6.2.tar.gz", "has_sig": false, "md5_digest": "34c28f1f6255bd0d4d3deb6aa81cfe0a", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 21869, "upload_time": "2014-01-17T20:42:48", "url": "https://files.pythonhosted.org/packages/9d/72/ee071ab6e6dc430fad93741619f0fb473af8fcde710b891a68d3c00c226a/torus-0.6.2.tar.gz" } ], "0.6.3": [ { "comment_text": "", "digests": { "md5": "ebc209ae694c2412d72dc1a706ded00d", "sha256": "727f9e800a1c6d4f0b45d1a96a7d556049c78b1be9350e426d4a294be9e1e06c" }, "downloads": -1, "filename": "torus-0.6.3.tar.gz", "has_sig": false, "md5_digest": "ebc209ae694c2412d72dc1a706ded00d", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 22033, "upload_time": "2014-02-04T15:54:55", "url": "https://files.pythonhosted.org/packages/e1/07/4a799bb329935970b307d0879c32735fb89392d4816b0c4a3c161074566f/torus-0.6.3.tar.gz" } ], "0.6.4": [ { "comment_text": "", "digests": { "md5": "7134593ba985b9f9e249ce67b77f79f8", "sha256": "a0918f1b6440621b8b2364228caa4ba02e41d0fa66ce0c25d495bf14bb8b9124" }, "downloads": -1, "filename": "torus-0.6.4.tar.gz", "has_sig": false, "md5_digest": "7134593ba985b9f9e249ce67b77f79f8", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 22052, "upload_time": "2014-02-06T18:41:04", "url": "https://files.pythonhosted.org/packages/ad/ab/09946cb0c7961a6b4616b7d1ac848e8d2bfd08c7c2a31018590a3a379828/torus-0.6.4.tar.gz" } ], "0.6.5": [ { "comment_text": "", "digests": { "md5": "00de4634381d3a8a386304631787bd6e", "sha256": "9d6f36c56828ec10e45e8158e3b6f99f49677ca39c5b17487f17e43c74279a9a" }, "downloads": -1, "filename": "torus-0.6.5.tar.gz", "has_sig": false, "md5_digest": "00de4634381d3a8a386304631787bd6e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 22000, "upload_time": "2014-02-18T14:12:34", "url": "https://files.pythonhosted.org/packages/d5/52/8a5ff56e12dce70ea36dafcde77d8e6e90408247ffd9f07b23f113614b92/torus-0.6.5.tar.gz" } ], "0.7.0": [ { "comment_text": "", "digests": { "md5": "76c66b469086660d759aeb8d75fbe220", "sha256": "63438c1e8aa9ee5bcc1f23f2aee19cc42acea4da4ed41d0e248dc8e4a9960589" }, "downloads": -1, "filename": "torus-0.7.0.tar.gz", "has_sig": false, "md5_digest": "76c66b469086660d759aeb8d75fbe220", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 23137, "upload_time": "2014-02-28T22:05:31", "url": "https://files.pythonhosted.org/packages/24/2e/4f0a2d905dcf782de00b581b521f165ae76cf77ee6cd90535da106684a03/torus-0.7.0.tar.gz" } ], "0.7.1": [ { "comment_text": "", "digests": { "md5": "a4a2ac6e7a790c5231905a8866aae582", "sha256": "e08b36a9b9e9657232ee755a2035e994d7b65e4d4bfa4564115814c3b36130a9" }, "downloads": -1, "filename": "torus-0.7.1.tar.gz", "has_sig": false, "md5_digest": "a4a2ac6e7a790c5231905a8866aae582", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 23147, "upload_time": "2014-03-14T15:07:17", "url": "https://files.pythonhosted.org/packages/9a/37/1ee3468870ac88f6c0c37955a9f68cc91aab8a8e0903100c16f76111fda2/torus-0.7.1.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "a4a2ac6e7a790c5231905a8866aae582", "sha256": "e08b36a9b9e9657232ee755a2035e994d7b65e4d4bfa4564115814c3b36130a9" }, "downloads": -1, "filename": "torus-0.7.1.tar.gz", "has_sig": false, "md5_digest": "a4a2ac6e7a790c5231905a8866aae582", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 23147, "upload_time": "2014-03-14T15:07:17", "url": "https://files.pythonhosted.org/packages/9a/37/1ee3468870ac88f6c0c37955a9f68cc91aab8a8e0903100c16f76111fda2/torus-0.7.1.tar.gz" } ] }