{ "info": { "author": "QAM Team", "author_email": "qamteam@gmail.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 7 - Inactive" ], "description": "=======================================\r\nQAM - A python RPC Framework using AMQP\r\n=======================================\r\n\r\n\r\nIntroduction\r\n------------\r\n \r\n``qam`` is a framework for remote-procedure-calls. It uses the `carrot`_ messaging framework. The RPC specific code is based on `Python XML-RPC`_.\r\n\r\n.. note:: ``qam`` is not actively maintened anymore by the qamteam. The successor of ``qam`` is ``callme`` . ``callme`` uses internally a more simpler approach as ``qam`` due to the improvements the AMQP standard has made since QAM was released. Therefore we made a complete re-design and wrote ``callme`` which has less overhead and is much faster than ``qam``.\r\n\r\n**Key Features:**\r\n\r\n - uses AMQP as Transport Protocol\r\n - supports synchronous and asynchrouns remote method calls\r\n - supports timeouts in synchronous and asynchronous mode\r\n - JSON marshaling for high interoperatbility (see `Serialization: JSON vs. Pickle`_ for details)\r\n - Pickle marshaling for Object Transport Support\r\n - Supports Remote Exception Transfer in JSON/Pickle/Synchronous/Asynchrounus mode\r\n - Fully Threaded\r\n - Easy to Use\r\n - OpenSource BSD-licensed\r\n\r\nThe AMQP messaging system manages the remote-procedure-calls for a client and a server. The client sends a amqp message to the server, where the method is specified which should be called on server.\r\nAfter executing the function the result is packed into a amqp message and sent back to the client.\r\n\r\nThe aim of ``qam`` is to offer a simple RPC framework, which is reliable and secure.\r\n\r\nYou have to install a AMQP message broker. The most popular are:\r\n\r\n - `RabbitMQ`_\r\n - `ZeroMQ`_\r\n - `Apache ActiveMQ`_\r\n \r\nPersonally we have used RabbitMQ, it is easy to install and to configure.\r\n\r\nBefore you start using the ``qam`` framework you should know a little bit about AMQP. \r\nTherefor we advice you to read `Rabbits and warrens`_ a very good article which introduces the basic ideas of AMQP.\r\nFurther you can look at the `carrot`_ documentation. There you can get also good overview of AMQP.\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n.. _`carrot`: http://ask.github.com/carrot/introduction.html\r\n.. _`Python XML-RPC`: http://docs.python.org/library/xmlrpclib.html\r\n.. _`Rabbits and warrens`: http://blogs.digitar.com/jjww/2009/01/rabbits-and-warrens/\r\n.. _`RabbitMQ`: http://www.rabbitmq.com/\r\n.. _`ZeroMQ`: http://www.zeromq.org/\r\n.. _`AMQP`: http://amqp.org\r\n.. _`Apache ActiveMQ`: http://activemq.apache.org/\r\n\r\nDocumentation\r\n-------------\r\n\r\nThe full Documentation including Reference can be found at `pypi documentation`_\r\n\r\n.. _`pypi documentation`: http://packages.python.org/qam/\r\n\r\n\r\nMailing list\r\n------------\r\nJoin the QAM Users mailing list: QAM-Users_\r\n\r\n.. _QAM-Users: http://groups.google.com/group/qam-users\r\n\r\nIf you are developing inside QAM join: QAM-Developers_\r\n\r\n.. _QAM-Developers: http://groups.google.com/group/qam-developers\r\n\r\nBug Tracker:\r\n------------\r\n\r\nIf you find any issues please report them on http://bitbucket.org/qamteam/qam/issues/\r\n\r\n\r\nGetting QAM\r\n-----------\r\n\r\nYou can get the python package on the `Python Package Index`_\r\n\r\n.. _`Python Package Index`: http://pypi.python.org/pypi/qam\r\n\r\nThe Mercurial Repository is available at `bitbucket.org qam`_\r\n\r\n.. _`bitbucket.org qam`: http://bitbucket.org/qamteam/qam/\r\n\r\nInstallation\r\n------------\r\n\r\n\r\n``qam`` can be installed via the Python Package Index of from source.\r\n\r\nUsing ``easy_install`` to install ``qam``::\r\n\r\n $ easy_install qam\r\n\r\n\r\nIf you have downloaded a source tarball you can install it\r\nby doing the following::\r\n\r\n $ python setup.py build\r\n # python setup.py install # as root\r\n\r\n\r\nTutorial\r\n--------\r\n\r\n**Starting the QAMServer**\r\n\r\nFirst it is necessary, to tell the QAMServer which functions are available. Therefore you have to register the functions on the QAMServer.\r\nAfter registering the functions, the QAMServer waits for method-calls from the QAMProxy.\r\n\r\nHere is how you register a function on QAMServer and switch into the serving mode:\r\n\r\n >>> from qam.qam_server import QAMServer\r\n >>> qam_server = QAMServer(hostname=\"localhost\",\r\n ... port=5672,\r\n ... username='guest',\r\n ... password='guest',\r\n ... vhost='/',\r\n ... server_id='qamserver')\r\n ...\r\n >>> def adder_function(x, y): \r\n ... return x + y\r\n ...\r\n >>> qam_server.register_function(adder_function, 'add')\r\n ...\r\n ... # it is also possible to register the adder_function as follows:\r\n ... # qam_server.register_function(adder_function)\r\n ... # the method-name for registering in this case is adder_function.__name__\r\n ...\r\n >>> qam_server.serve()\r\n \r\nIt is also possible to register whole classes on QAMServer. Therefore you only have to register the class instance on the QAMServer.\r\nIt's not necessary to register all functions of the class, it's enough when you register the class instance. \r\n\r\n*IMPORTANT:* When you register an instance you must specify a name as second argument in the ``register_class()`` method which selects the instance when calling it. \r\nIn the example below you would call the remote method ``proxy.my_instance.adder_function(1,2)``\r\n\r\nHere is how you register a class instance on QAMServer and switch into the serving mode:\r\n\r\n >>> from qam.qam_server import QAMServer\r\n >>> qam_server = QAMServer(hostname=\"localhost\",\r\n ... port=5672,\r\n ... username='guest',\r\n ... password='guest',\r\n ... vhost='/',\r\n ... server_id='qamserver')\r\n ...\r\n >>> class TestClass():\r\n ... def __init__(self):\r\n ... pass\r\n ... def adder_function(self,a,b):\r\n ... return a+b\r\n ...\r\n >>> instance = TestClass()\r\n >>> qam_server.register_class(instance,'my_instance')\r\n >>> qam_server.serve()\r\n \r\n\r\n**Managing RPC with QAMProxy**\r\n\r\nThe QAMProxy sends the RPC-requests to the QAMServer and receives the result. It acts like a client which can call Server Methods and receive their\r\nresults.\r\n\r\nThere are two different ways to receive the result:\r\n\r\n - *synchronous call*: the QAMProxy blocks until a result arrives\r\n - *asynchronous call*: it is possible to register a callback-function which will be called when the result arrives. \r\n In the meantime the QAMProxy can execute other functions or you can go in with your programm to execute.\r\n \r\n*Synchronous RPC*\r\n \r\nThis example shows you how to call a simple method registered on the QAMServer. You have to wait for the result, because no callback-function is registered. So it is a synchronous RPC.\r\n\r\n >>> from qam.qam_proxy import QAMProxy, QAMMethodNotFoundException, QAMException\r\n ... # create a new QAMProxy-instance\r\n >>> qam_proxy = QAMProxy(hostname=\"localhost\",\r\n ... port=5672,\r\n ... username='guest',\r\n ... password='guest',\r\n ... vhost='/',\r\n ... server_id='qamserver',\r\n ... client_id='qamproxy')\r\n ...\r\n >>> result = qam_proxy.add(2,3) # call method on QAMServer and wait for a result\r\n ... # close all open AMQP connections and cleanup\r\n >>> qam_proxy.close()\r\n \r\nIn case you have registered a class instance on the QAMServer and you want to call a method from this instance you can simple call this instance on QAMProxy. \r\nYou can call the instance with the name you specified with ``qam.qam_server.QAMServer.register_class(instance,name)``.\r\nIn this example it is a synchronous RPC again. You have to wait for the result.\r\n \r\n >>> from qam.qam_proxy import QAMProxy, QAMMethodNotFoundException, QAMException\r\n >>> qam_proxy = QAMProxy(hostname=\"localhost\",\r\n ... port=5672,\r\n ... username='guest',\r\n ... password='guest',\r\n ... vhost='/',\r\n ... server_id='qamserver',\r\n ... client_id='qamproxy')\r\n ...\r\n >>> result = qam_proxy.my_instance.adder_function(2,4)\r\n >>> qam_proxy.close()\r\n \r\n*Asynchronous RPC*\r\n\r\nIf you don't want to wait for the result it is possible to register a callback-function.\r\nYou can do this by calling ``QAMProxy.callback(callback_function, error_function).method_to_call_on_server(params)``.\r\nThe callback-function takes two parameters as arguments. The first is the callback-function. \r\nThe second is optional and is only called if an error occourd on QAMServer.\r\n\r\n*SIDENOTE:* It is highly recomended that you alway set a error_function as well, as\r\nyou can never know if the remote method will succeed or will throw an exception or if an internal exception will happen. Especially in asynchronous\r\ncalls the only way you will be notified in case of an error WITHOUT an error_function is the qam logging.\r\n\r\nAfter receiving the result from QAMServer the callback-function or the error-function is executed, with the result as parameter.\r\nYou can monitor the state of the callback with ``qam.qam_proxy.get_callback_state(uid)``. Possible States are:\r\n\r\n - 0: waiting on result\r\n - 1: processing (result arrived and callback/error function is currently executing)\r\n - 2: callback finished (callback/error function have finished executing)\r\n\r\nIn the following example you can see how to use callback-functions. In this example a simple method-call on the Server should be executed. \r\nNo class instance is registered on the QAMServer, only the adder_function is registered.\r\n\r\n >>> from qam.qam_proxy import QAMProxy, QAMMethodNotFoundException, QAMException\r\n >>> qam_proxy = QAMProxy(hostname=\"localhost\",\r\n ... port=5672,\r\n ... username='guest',\r\n ... password='guest',\r\n ... vhost='/',\r\n ... server_id='qamserver',\r\n ... client_id='qamproxy')\r\n ...\r\n ... # defining functions for callback\r\n >>> def success(arg):\r\n ... print arg\r\n >>> def error(arg):\r\n ... # if an error occours on QAMServer\r\n ... print arg \r\n >>> uid = qam_proxy.callback(success, error).add(2,4)\r\n >>> while True:\r\n ... state = qam_proxy.get_callback_state(uid)\r\n ... if state == 2 :\r\n ... # execution of callback finished\r\n ... break\r\n ...\r\n >>> qam_proxy.close()\r\n \r\nThe function success and error are registered as callback and error function. If everything succeeds the success-function will be called. \r\nIf an error occoured on the QAMServer the error-function will be called.\r\nIf no error-function is defined and an error occourd a log-message is written into the logging system.\r\n\r\nIt is also possible to execute asynchronous class-instance-method calls on the QAMServer. In the following example you can see how you can manage that.\r\nYou can call the instance with the name you specified with ``qam.qam_server.QAMServer.register_class(instance,name)``.\r\n\r\n >>> from qam.qam_proxy import QAMProxy, QAMMethodNotFoundException, QAMException\r\n >>> qam_proxy = QAMProxy(hostname=\"localhost\",\r\n ... port=5672,\r\n ... username='guest',\r\n ... password='guest',\r\n ... vhost='/',\r\n ... server_id='qamserver',\r\n ... client_id='qamproxy')\r\n ...\r\n ... # defining functions for callback\r\n >>> def success(arg):\r\n ... print arg\r\n >>> def error(arg):\r\n ... # if an error occours on QAMServer\r\n ... print arg \r\n >>> uid = qam_proxy.callback(success, error).my_instance.adder_function(2,4)\r\n >>> while True:\r\n ... state = qam_proxy.get_callback_state(uid)\r\n ... if state == 2 :\r\n ... # execution of callback finished\r\n ... break\r\n ...\r\n >>> qam_proxy.close()\r\n\r\n\r\nTimeouts\r\n--------\r\n\r\nIt is also possible to set timeouts for remote functions. E.g. you might use timeouts if you don't want to wait longer than for example 10 seconds \r\nfor a function to return because after 10 seconds the result isn't important for you anymore.\r\n\r\nA simple client side synchronous code would look like this:\r\n\r\n >>> from qam.qam_proxy import QAMProxy, QAMMethodNotFoundException, QAMException, QAMTimeoutException\r\n ... # create a new QAMProxy-instance\r\n >>> qam_proxy = QAMProxy(hostname=\"localhost\",\r\n ... port=5672,\r\n ... username='guest',\r\n ... password='guest',\r\n ... vhost='/',\r\n ... server_id='qamserver',\r\n ... client_id='qamproxy')\r\n ...\r\n >>> try:\r\n >>> result = qam_proxy.set_timeout(10).add(2,3) # call method on QAMServer and wait for a result\r\n >>> except QAMTimeoutException: \r\n >>> print 'Remote function is too slow, timeout occoured.'\r\n ...# close all open AMQP connections and cleanup\r\n >>> qam_proxy.close()\r\n\r\nBut we also can set timeouts in asynchronous mode. The Callback/Error function will then only get called if it gets executed before the\r\ntimeout occours. If the timeout occours before the callback/error function gets executed, the error function gets called with a \r\n``qam.qam_proxy.QAMTimeoutException`` as argument. Let's have a look at some sample code, again we assume that after 10 seconds result is \r\nnot anymore important to us.\r\n\r\nA simple client side asynchronous code would look like this:\r\n\r\n >>> from qam.qam_proxy import QAMProxy, QAMMethodNotFoundException, QAMException, QAMTimeoutException\r\n >>> qam_proxy = QAMProxy(hostname=\"localhost\",\r\n ... port=5672,\r\n ... username='guest',\r\n ... password='guest',\r\n ... vhost='/',\r\n ... server_id='qamserver',\r\n ... client_id='qamproxy')\r\n ...\r\n ... # defining functions for callback\r\n >>> def success(arg):\r\n ... print arg\r\n >>> def error(arg):\r\n ... if isinstance(arg, QAMTimeoutException):\r\n ... #timeout occoured \r\n ... print 'Timeout occoured'\r\n ... else:\r\n ... print 'Other error happened' \r\n >>> uid = qam_proxy.callback(success, error).set_timeout(10).add(2,4)\r\n >>> while True:\r\n ... state = qam_proxy.get_callback_state(uid)\r\n ... if state == 2 :\r\n ... # execution of callback finished\r\n ... break\r\n ...\r\n >>> qam_proxy.close()\r\n\r\nInternally, if an timeout occours it doesn't matter if the actual function will return some day or if it will never return.\r\nIn case the remote function returns after the timeout exception has occoured the message will be correctly processed (so that everything stays\r\nclean in the AMQP Subsystem) but the result will be thrown away.\r\n\r\n\r\nSerialization: JSON vs. Pickle\r\n------------------------------\r\n\r\nWhen working with QAM all the remote methods and results will get serialized in the background for you that you don't have to bother about that.\r\nBut for flexibility you can choose between two serializer: JSON and Pickle. Both have their benefits and drawbacks. In most cases you will do fine\r\nwith the default Pickle serializer. But if you have special requirements you might choose the JSON serializer. \r\n\r\nIMPORTANT: Anyway which serializer you choose, you must specify the same serializer on the QAMServer and on the QAMProxy, otherwise\r\nthey can't communicate correctly.\r\n\r\n``SIDENOTE:`` The default serializer is *Pickle*.\r\n\r\nTo set the serializer on the proxy, here e.g. json:\r\n\r\n >>> from qam.qam_proxy import QAMProxy\r\n ... # create a new QAMProxy-instance\r\n >>> qam_proxy = QAMProxy(hostname=\"localhost\",\r\n ... port=5672,\r\n ... username='guest',\r\n ... password='guest',\r\n ... vhost='/',\r\n ... server_id='qamserver',\r\n ... serializer='json')\r\n\r\n\r\nTo set the serializer on the server, again json:\r\n\r\n >>> from qam.qam_server import QAMServer\r\n >>> qam_server = QAMServer(hostname=\"localhost\",\r\n ... port=5672,\r\n ... username='guest',\r\n ... password='guest',\r\n ... vhost='/',\r\n ... server_id='qamserver',\r\n ... serializer='json')\r\n\r\n\r\nTo get an slight overview which serializer fits your need best here is a small comparison.\r\nThis comparision is specially trimmed for the use in QAM. In other environments there might be other things to be aware of.\r\n\r\n\r\n+----------------------------------------------+--------------------------------+------------------------------------------+ \r\n| Property | Pickle | JSON |\r\n+==============================================+================================+==========================================+\r\n|Compression | good | no compression |\r\n+----------------------------------------------+--------------------------------+------------------------------------------+\r\n|Complex Object Transport | yes | only json encodable |\r\n| | | objects are supported |\r\n| | | (dict, list, scalar) |\r\n+----------------------------------------------+--------------------------------+------------------------------------------+\r\n|Support for Custom Exception Inheritance | yes | no, but you can use |\r\n| | | Exceptions as well. The |\r\n| | | only drawback is that you |\r\n| | | cannot create custom Exceptions |\r\n| | | with inheritance |\r\n+----------------------------------------------+--------------------------------+------------------------------------------+ \r\n|Interoperability with other languages | worse | good, as our transport format |\r\n| | | is quite easy to implement in |\r\n| | | other languages with json support |\r\n+----------------------------------------------+--------------------------------+------------------------------------------+\r\n|Needs Complex Type Definitions on | yes, because proxy and | no, because we can only transfer dict |\r\n|both sides (Proxy and Server) | the server need to know | list, and scalars we don't need to |\r\n| | which type they will get. | define them seperately. |\r\n| | You have to import your | |\r\n| | custom Argument Classes or | |\r\n| | custom Exceptions you want | |\r\n| | to raise on both proxy side | |\r\n| | and server side. | |\r\n+----------------------------------------------+--------------------------------+------------------------------------------+ \r\n\r\n\r\n\r\nArchitecture\r\n------------\r\n\r\n.. image:: _static/images/qam_arch.png\r\n.. image:: _static/images/qam_proxy_sync.png\r\n.. image:: _static/images/qam_proxy_async.png\r\n\r\nSupported by\r\n------------\r\nWingware - The Python IDE (http://wingware.com)\r\n\r\nContributing\r\n------------\r\n\r\nWe are welcome everyone who wants to contribute to QAM. Development of QAM happens at http://bitbucket.org/qamteam/qam/\r\n\r\nLicense\r\n-------\r\n\r\nQAM is released under the BSD License. The full license text is in the root folder of the QAM Package.", "description_content_type": null, "docs_url": "https://pythonhosted.org/qam/", "download_url": "UNKNOWN", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "http://packages.python.org/qam", "keywords": "rpc amqp", "license": "UNKNOWN", "maintainer": "", "maintainer_email": "", "name": "qam", "package_url": "https://pypi.org/project/qam/", "platform": "any", "project_url": "https://pypi.org/project/qam/", "project_urls": { "Download": "UNKNOWN", "Homepage": "http://packages.python.org/qam" }, "release_url": "https://pypi.org/project/qam/0.2.18/", "requires_dist": null, "requires_python": null, "summary": "QAM is a simple RPC Framework which uses the AMQP Protocol as Transport Protocol.", "version": "0.2.18" }, "last_serial": 798301, "releases": { "0.1.0": [ { "comment_text": "", "digests": { "md5": "0b77b207da107c6c6f44dac995997b40", "sha256": "e639267df014ebf71264569e144e55412f2181d983d7193d61398a5269992a90" }, "downloads": -1, "filename": "qam-0.1.0.tar.gz", "has_sig": false, "md5_digest": "0b77b207da107c6c6f44dac995997b40", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 10198, "upload_time": "2009-08-21T23:19:55", "url": "https://files.pythonhosted.org/packages/be/61/3dd060eb4945a8a3ea63e1b487490ad758b1b6ef2f6bfdd3556c73b89a40/qam-0.1.0.tar.gz" } ], "0.1.1": [ { "comment_text": "", "digests": { "md5": "435ea479feabdfd3e066373045400f51", "sha256": "2e1892956ab349f3f4e37bd7106603d45a058d324fbf90767e1fce5c9ce17f57" }, "downloads": -1, "filename": "qam-0.1.1.tar.gz", "has_sig": false, "md5_digest": "435ea479feabdfd3e066373045400f51", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 49883, "upload_time": "2009-08-21T23:50:00", "url": "https://files.pythonhosted.org/packages/04/ef/c8abefba927eee1344b3fa3299d29db3c064bda00da6e057630e0de6ff6f/qam-0.1.1.tar.gz" } ], "0.1.2": [ { "comment_text": "", "digests": { "md5": "29672c3b6cee3a420c323c82ce5a34d3", "sha256": "3e2d1795787b15e6decbe459bb96d550a01d00c090adc63f614a5a3acf741c83" }, "downloads": -1, "filename": "qam-0.1.2.tar.gz", "has_sig": false, "md5_digest": "29672c3b6cee3a420c323c82ce5a34d3", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 49919, "upload_time": "2009-08-22T00:01:51", "url": "https://files.pythonhosted.org/packages/77/4e/9b57e211b43bbd01110b4ed2954df99d042a81f23bae873f8566f3a9b007/qam-0.1.2.tar.gz" } ], "0.1.3": [ { "comment_text": "", "digests": { "md5": "14ddd7da4a563337aa5e445df11e5e59", "sha256": "f7b04b0c21cab31af8c9dc0c0f4864ba91d8a720fe7d387852e86f5facb2d0f7" }, "downloads": -1, "filename": "qam-0.1.3.tar.gz", "has_sig": false, "md5_digest": "14ddd7da4a563337aa5e445df11e5e59", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 15112, "upload_time": "2009-08-22T15:52:03", "url": "https://files.pythonhosted.org/packages/0d/3e/5982591bf7eb968bd68dadf1dc164099c9717d99f65fc2cfead7aefea6ea/qam-0.1.3.tar.gz" } ], "0.1.4": [ { "comment_text": "", "digests": { "md5": "5f142004f77f552f23d6dddf3d1031b8", "sha256": "972beb1271561aabbc4eb4ded222349cebe96c2f843ee1f16a99eda08b9eb042" }, "downloads": -1, "filename": "qam-0.1.4.tar.gz", "has_sig": false, "md5_digest": "5f142004f77f552f23d6dddf3d1031b8", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 17085, "upload_time": "2009-08-22T15:56:20", "url": "https://files.pythonhosted.org/packages/29/66/fc91bbb737bd3acb11a08c9dec53adbd6b929b3d2396a436b005dac25a3c/qam-0.1.4.tar.gz" } ], "0.2.0": [ { "comment_text": "", "digests": { "md5": "e475e4798cccee6f209b872d859af11e", "sha256": "b0bf712a4c48f380a2dbba6e78c4759727f700c94e1015e2fb5ccd287ce33fa0" }, "downloads": -1, "filename": "qam-0.2.0.tar.gz", "has_sig": false, "md5_digest": "e475e4798cccee6f209b872d859af11e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 45646, "upload_time": "2009-08-24T01:02:10", "url": "https://files.pythonhosted.org/packages/29/0a/630ec3a80b25c15e8acecdf3b7ec65c0a9bdfa8d4f1ab25a3c2fda70b31c/qam-0.2.0.tar.gz" } ], "0.2.1": [ { "comment_text": "", "digests": { "md5": "85b7e80eea2ce39d18d2a6a98148dffe", "sha256": "39def67f319eb6cf7258749b24086f80e025b30536b980ec13d09f2db01c5759" }, "downloads": -1, "filename": "qam-0.2.1.tar.gz", "has_sig": false, "md5_digest": "85b7e80eea2ce39d18d2a6a98148dffe", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 22922, "upload_time": "2009-08-29T05:56:32", "url": "https://files.pythonhosted.org/packages/77/29/e88df26ac1bb340020b8bbbf9caad3e3017fdfcf8ed74514f8f5f6221fbe/qam-0.2.1.tar.gz" } ], "0.2.10": [ { "comment_text": "", "digests": { "md5": "b54e30a03cc5125e2142c02cf0706528", "sha256": "63946767bb1297e48609df0026e3a733a0d0a98a53d4b4202f3991c3842e6ad1" }, "downloads": -1, "filename": "qam-0.2.10.tar.gz", "has_sig": false, "md5_digest": "b54e30a03cc5125e2142c02cf0706528", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 104718, "upload_time": "2009-11-19T16:21:18", "url": "https://files.pythonhosted.org/packages/fb/70/42d3e50db1719962cee8ccbda5b7c993be555262c61131a13ac28619bb38/qam-0.2.10.tar.gz" } ], "0.2.11": [ { "comment_text": "", "digests": { "md5": "0360f92f848a6faf5f4ee81b1202888a", "sha256": "ea3776dc9ff0548d601c41a84e060dcf7f1a5b3ad9e545f67affc7679841dcd8" }, "downloads": -1, "filename": "qam-0.2.11.tar.gz", "has_sig": false, "md5_digest": "0360f92f848a6faf5f4ee81b1202888a", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 93271, "upload_time": "2009-11-20T10:22:40", "url": "https://files.pythonhosted.org/packages/31/09/7de8c860fbaf2a467dd19f613b5f9accd121035f847fa3b72f9f1e630659/qam-0.2.11.tar.gz" } ], "0.2.12": [ { "comment_text": "", "digests": { "md5": "f88c94966f250b6bc4fdc9cbdf697c12", "sha256": "88ee38249f89e88eecf8141d981da8d431dc9404915612a7ce5c2c3934f47351" }, "downloads": -1, "filename": "qam-0.2.12.tar.gz", "has_sig": false, "md5_digest": "f88c94966f250b6bc4fdc9cbdf697c12", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 96924, "upload_time": "2009-11-20T10:28:47", "url": "https://files.pythonhosted.org/packages/eb/f4/781f5bc36841f4ee7a77c2e7a44403cd4cca7f4ae1fbc5a2a51db9be65c0/qam-0.2.12.tar.gz" } ], "0.2.13": [ { "comment_text": "", "digests": { "md5": "3f15248abe5ccc353cd0429ce90f5544", "sha256": "1c28031666bb1fe6acb313f49741f47a8c8d2b4783c6e0f8c74606f2676f83cc" }, "downloads": -1, "filename": "qam-0.2.13.tar.gz", "has_sig": false, "md5_digest": "3f15248abe5ccc353cd0429ce90f5544", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 101681, "upload_time": "2009-11-20T10:35:59", "url": "https://files.pythonhosted.org/packages/7f/e7/a24cfb14256c739aeacf8a3d8ba4c02ba743ce20b890a2d13f10c2af2d49/qam-0.2.13.tar.gz" } ], "0.2.14": [ { "comment_text": "", "digests": { "md5": "09ae58b2bae85b608d7c67204a7cc721", "sha256": "6391d6b7773161d0297209eec7857580aebf7dcf7816eca1bbcfb6bb548992e7" }, "downloads": -1, "filename": "qam-0.2.14.tar.gz", "has_sig": false, "md5_digest": "09ae58b2bae85b608d7c67204a7cc721", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 101689, "upload_time": "2009-11-20T10:40:24", "url": "https://files.pythonhosted.org/packages/f5/a1/dbdbff8417b63612fa870e3844e463ad5a4b908cf2ee914132edb3aa8448/qam-0.2.14.tar.gz" } ], "0.2.15": [ { "comment_text": "", "digests": { "md5": "5cd28eeb244bdb6df8b8f85e7d8bccb9", "sha256": "f82c7d26770b33dc75544bc19d9c1851b25787846b93c6c5aacad8b0456723b5" }, "downloads": -1, "filename": "qam-0.2.15.tar.gz", "has_sig": false, "md5_digest": "5cd28eeb244bdb6df8b8f85e7d8bccb9", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 101686, "upload_time": "2009-11-20T10:43:09", "url": "https://files.pythonhosted.org/packages/73/74/e3a67d104165315013a13a9e6ebf873c19b0b1d35545a71c629e9023b3ba/qam-0.2.15.tar.gz" } ], "0.2.16": [ { "comment_text": "", "digests": { "md5": "cf5992f4cead649dcac34c9928e1b215", "sha256": "5dc2dfb6542ff336ea5d67bc47685b84ff14619f5e73e948caf924ab99886b23" }, "downloads": -1, "filename": "qam-0.2.16.tar.gz", "has_sig": false, "md5_digest": "cf5992f4cead649dcac34c9928e1b215", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 101685, "upload_time": "2009-11-20T10:46:34", "url": "https://files.pythonhosted.org/packages/21/3e/1f3de799c247df9fa16a9ecd91830022b5e5d38ef1db12278a9731ace95f/qam-0.2.16.tar.gz" } ], "0.2.17": [ { "comment_text": "", "digests": { "md5": "8b663099898e65971fb7f8b22991ea65", "sha256": "2612ae2ef526d906dbab4fc235bbc17968ed592460a0e5285d912a4b109b66b5" }, "downloads": -1, "filename": "qam-0.2.17.tar.gz", "has_sig": false, "md5_digest": "8b663099898e65971fb7f8b22991ea65", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 101686, "upload_time": "2009-11-20T10:52:05", "url": "https://files.pythonhosted.org/packages/65/25/5320f2c6c24ed2cf3295ba0ee9cfbb1444af663729ef310f6899fa53f797/qam-0.2.17.tar.gz" } ], "0.2.18": [ { "comment_text": "", "digests": { "md5": "91f6519cc7506a288a6111bb632058e8", "sha256": "29469e6b2b807cbd448bb0b0ee34ed0ff7d15dfc23288b51bc03c6632d8fc03f" }, "downloads": -1, "filename": "qam-0.2.18.tar.gz", "has_sig": false, "md5_digest": "91f6519cc7506a288a6111bb632058e8", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 101687, "upload_time": "2009-11-20T10:55:43", "url": "https://files.pythonhosted.org/packages/9a/13/c5745ca3cd25aafa4be849467d3920490a0c0ad227061e630051724335a8/qam-0.2.18.tar.gz" } ], "0.2.2": [ { "comment_text": "", "digests": { "md5": "4324522c6f86435edfec003e036999b9", "sha256": "671873aab78a77fcf28efa648784fea06e32ebbd600c5451f691189700dda173" }, "downloads": -1, "filename": "qam-0.2.2.tar.gz", "has_sig": false, "md5_digest": "4324522c6f86435edfec003e036999b9", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 64350, "upload_time": "2009-09-16T19:45:03", "url": "https://files.pythonhosted.org/packages/9a/ce/79b782d068a85a5e37e7e877eef937cde3e6d5f6becbed403a6dfcc17116/qam-0.2.2.tar.gz" } ], "0.2.3": [ { "comment_text": "", "digests": { "md5": "b509237cc6e073c7880be86e4c0f994c", "sha256": "fff4f477af53a3904289e75a7e7d0ecac35b7fd922b8026af398e92a36e683ba" }, "downloads": -1, "filename": "qam-0.2.3.tar.gz", "has_sig": false, "md5_digest": "b509237cc6e073c7880be86e4c0f994c", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 75298, "upload_time": "2009-09-16T20:21:15", "url": "https://files.pythonhosted.org/packages/83/53/8d92eedfb84d10cf385ba96ec3ee9636d395762e321daf4dedb3096b860c/qam-0.2.3.tar.gz" } ], "0.2.4": [ { "comment_text": "", "digests": { "md5": "a38c5fcd3576a29301d3053902908e0f", "sha256": "f3a1b70a06d25006271fa870052c8b1893f24c578cb05db600cf33c804ead324" }, "downloads": -1, "filename": "qam-0.2.4.tar.gz", "has_sig": false, "md5_digest": "a38c5fcd3576a29301d3053902908e0f", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 78158, "upload_time": "2009-10-17T00:01:36", "url": "https://files.pythonhosted.org/packages/06/05/70517f5172ea0d6c04a3ad199b6604cd51f82e9694093f7f09e282fdb0b5/qam-0.2.4.tar.gz" } ], "0.2.5": [ { "comment_text": "", "digests": { "md5": "f2dc0f96451fe07d9366cf53297076d2", "sha256": "bfdf3d6011911a847976eb9016eb77c72e158c8af25ce55715bc562142ac985d" }, "downloads": -1, "filename": "qam-0.2.5.tar.gz", "has_sig": false, "md5_digest": "f2dc0f96451fe07d9366cf53297076d2", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 56059, "upload_time": "2009-11-19T14:27:41", "url": "https://files.pythonhosted.org/packages/73/34/4254a60aa1bf3d01d9177625cfbc87fb430020c604d4e5286d70398273c2/qam-0.2.5.tar.gz" } ], "0.2.6": [ { "comment_text": "", "digests": { "md5": "ba0bc151f93797157f1bfffc8ce36cfc", "sha256": "169ef5c9c3d5e04b347c8cff6bf407008ea23115a3b0c6708de11675b330fa06" }, "downloads": -1, "filename": "qam-0.2.6.tar.gz", "has_sig": false, "md5_digest": "ba0bc151f93797157f1bfffc8ce36cfc", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 70722, "upload_time": "2009-11-19T14:51:16", "url": "https://files.pythonhosted.org/packages/db/9a/cff0f3a1e87474f45dd4fbdbb9dee62876fe17bc4505162a86d7bf3a47c7/qam-0.2.6.tar.gz" } ], "0.2.7": [ { "comment_text": "", "digests": { "md5": "281f850fd8b38878b88a2b9e41d6525d", "sha256": "bb5d4bc2430d2f56b9d82650b5a3e7d174ed409b8999a431543704e7fe11d686" }, "downloads": -1, "filename": "qam-0.2.7.tar.gz", "has_sig": false, "md5_digest": "281f850fd8b38878b88a2b9e41d6525d", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 84840, "upload_time": "2009-11-19T15:08:01", "url": "https://files.pythonhosted.org/packages/03/07/fbf4c84c9ff2e1ada128a6604acf7712331e27cf26dca48abb82d70805d8/qam-0.2.7.tar.gz" } ], "0.2.8": [ { "comment_text": "", "digests": { "md5": "4c6ffd29d90f32851290a438c1cd4e0a", "sha256": "a4a8e23029cc7746931d7a30ee8f1dacf45326d821b3cbf9c49947ea7b900c89" }, "downloads": -1, "filename": "qam-0.2.8.tar.gz", "has_sig": false, "md5_digest": "4c6ffd29d90f32851290a438c1cd4e0a", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 97909, "upload_time": "2009-11-19T15:53:44", "url": "https://files.pythonhosted.org/packages/3b/51/5b120ae9adc75aa3cd465c0f2270a11c28c984edf7b61d84a2ddf8afa8af/qam-0.2.8.tar.gz" } ], "0.2.9": [ { "comment_text": "", "digests": { "md5": "e8ef21ec9f63c1f2408d9a4ada76b550", "sha256": "c244d73d9829f2fe061f42da3fec992efd27527f942a7cf0422485bf382f002f" }, "downloads": -1, "filename": "qam-0.2.9.tar.gz", "has_sig": false, "md5_digest": "e8ef21ec9f63c1f2408d9a4ada76b550", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 101423, "upload_time": "2009-11-19T16:14:04", "url": "https://files.pythonhosted.org/packages/32/10/cdae793496fb667db022740e313c23821d25b5d6785917962484cf2d0981/qam-0.2.9.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "91f6519cc7506a288a6111bb632058e8", "sha256": "29469e6b2b807cbd448bb0b0ee34ed0ff7d15dfc23288b51bc03c6632d8fc03f" }, "downloads": -1, "filename": "qam-0.2.18.tar.gz", "has_sig": false, "md5_digest": "91f6519cc7506a288a6111bb632058e8", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 101687, "upload_time": "2009-11-20T10:55:43", "url": "https://files.pythonhosted.org/packages/9a/13/c5745ca3cd25aafa4be849467d3920490a0c0ad227061e630051724335a8/qam-0.2.18.tar.gz" } ] }