{ "info": { "author": "Bump Technologies", "author_email": "dev@bu.mp", "bugtrack_url": null, "classifiers": [ "Development Status :: 5 - Production/Stable" ], "description": "========================\r\nPython Client for Montage\r\n========================\r\n\r\nInstall\r\n=======\r\n\r\nRecommended Python 2.7\r\n\r\nFrom montage-python-client/ execute::\r\n\r\n python setup.py install\r\n\r\nTo setup montage itself, see github.com/bumptech/montage\r\n\r\n===========\r\nExamples\r\n===========\r\n\r\nYou must have montage installed to run the basic proxy which the examples talk with. In your montage/ directory::\r\n\r\n cd examples && runhaskell basic_proxy.hs\r\n\r\nSee github.com/bumptech/montage for more on the montage haskell setup.\r\n\r\nA Basic Resolution\r\n===========\r\n\r\nThe montage/examples/basic_proxy defines resolutions for three simple protocol-buffers: UserInfo, UserEvent, and UserName (view them in montage-python-client/examples/user.proto).\r\n\r\nTo see a basic last write wins resolution in action, throw UserInfo data at montage, at the same bucket and key destination, and query that bucket and key pair::\r\n\r\n from montage import MontageClient\r\n from user_palm import UserInfo\r\n\r\n # UserInfo is a constructor with one required integer field, uid\r\n\r\n client = MontageClient('localhost', 7078)\r\n\r\n bucket = 'u-info'\r\n key = '1'\r\n\r\n data_1 = UserInfo(uid=4393)\r\n first = client.put(bucket, key, data_1.dumps())\r\n data_2 = UserInfo(uid=4920)\r\n second = client.put(bucket, key, data_2.dumps())\r\n\r\n resolved = client.get(bucket, key)\r\n assert UserInfo(resolved.data) == data_2, \"Failed last write wins\"\r\n\r\nThe type signatures of get and put::\r\n\r\n # Haskell-style\r\n # where vclock is optional and obj has fields 'data', 'bucket', 'key', 'vclock'\r\n\r\n put :: String -> String -> ByteString -> Maybe ByteString -> Object\r\n put bucket key data vclock = obj\r\n\r\n get :: String -> String -> Object\r\n get bucket key = obj\r\n\r\n'put' returns the data stored in riak, which comes equipped with an assigned vclock (obj.vclock).\r\n\r\nThe montage-python-client sends requests to montage over a zmq socket using diesel. To execute the above code, wrap the above logic in a function that can be diesel quickstarted::\r\n\r\n from diesel import quickstart\r\n from montage import MontageClient\r\n from user_palm import UserInfo\r\n\r\n def resolve():\r\n client = MontageClient('localhost', 7078)\r\n\t...\r\n\tassert UserInfo(resolved.data) == data_2, \"Failed last write wins\"\r\n\r\n quickstart(resolve)\r\n\r\nDelete\r\n===========\r\n\r\nTo delete the data you just resolved (above)::\r\n\r\n from montage import MontageClient\r\n\r\n client = MontageClient('localhost', 7078)\r\n\r\n bucket = 'u-info'\r\n key = '1'\r\n client.delete(bucket, key)\r\n\r\nBatches\r\n===========\r\n\r\nMontage supports batch commands, which means getting from many destinations, or putting data in many destinations. The put many interface requires the building of a newMontageObject::\r\n\r\n from montage import MontageClient\r\n from user_palm import UserInfo, UserEvent\r\n\r\n client = MontageClient('localhost', 7078)\r\n\r\n bucket = 'u-info'\r\n key = '2'\r\n data = UserInfo(uid=3244)\r\n mo_ui = client.newMontageObject(bucket, key, data.dumps())\r\n\r\n bucket = 'u-event'\r\n key = '1'\r\n data = UserEvent(eid=1301)\r\n mo_ue = client.newMontageObject(bucket, key, data.dumps())\r\n\r\n what_was_put = client.put_many([mo_ui, mo_ue])\r\n\r\nLikewise, if you desire to get from many destination, you may do so by ordering your requests as (bucket, key) pairs in a list::\r\n\r\n found = client.get_many([('u-info', '2'), ('u-event', '1')])\r\n\r\n assert found[0].data == mo_ui.data\r\n assert found[1].data == mo_ue.data\r\n\r\n found = client.get_many([('u-info', '2'), ('u-whatever', '1')])\r\n\r\n assert found[1] == None\r\n\r\nThe response is a list the same length of the request: the (bucket, key) pairs are exactly replaced with either a value found or None.\r\n\r\nReference Gets\r\n===========\r\n\r\nA reference get request is two chained get requests, where the first lookup produces a value that is used as the key for the second lookup.\r\n\r\nIf we've defined a way to transform a datatype to a bytestring key (as we've done for UserInfo in basic_proxy), we first deposit data that can be chained::\r\n\r\n # basic_proxy defines a transformation from UserInfo's uid -> key\r\n\r\n from montage import MontageClient\r\n from user_palm import UserInfo, UserEvent\r\n\r\n client = MontageClient('localhost', 7078)\r\n\r\n refdata = UserInfo(uid=2) # key for targets\r\n reference = cl.put('u-info', str(1), refdata.dumps())\r\n\r\n target1data = UserEvent(eid=3)\r\n target1 = client.put('u-event', str(2), target1data.dumps())\r\n\r\n target2data = UserName(name=\"montage\")\r\n target2 = client.put('u-name', str(2), target2data.dumps())\r\n\r\nThen to make the reference get requests::\r\n\r\n (referenceFound, valuesFound) = client.get_by_('u-info', str(1), ['u-event', 'u-name'])\r\n\r\n assert UserInfo(referenceFound.data) == reference\r\n assert len(valuesFound) == 2\r\n assert (valuesFound[0] is not None) and (valuesFound[1] is not None)\r\n assert UserEvent(valuesFound[0].data) == target1data\r\n assert UserName(valuesFound[1].data) == target2data\r\n\r\nThe values returned by a reference get request will be ordered to match the buckets given. If the reference get failed to return one of the values, it will be None in the valuesFound list.\r\n\r\nThere is also a client.get_by method which only returns valuesFound in the case that you don't care about the intermediate (referenceFound) lookup object. This object, though, can be useful if you need to do another lookup conditionally on referenceFound.", "description_content_type": null, "docs_url": null, "download_url": "http://static.bumpserver.com/oss/montage/montageclient-0.1.0.tar.gz", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/bumptech/montage-python-client", "keywords": "montage, database, riak, resolution, network", "license": "Copyright 2011 Bump Technologies Inc. All rights reserved.\r\n\r\nRedistribution and use in source and binary forms, with or without modification, are\r\npermitted provided that the following conditions are met:\r\n\r\n 1. Redistributions of source code must retain the above copyright notice, this list of\r\n conditions and the following disclaimer.\r\n\r\n 2. Redistributions in binary form must reproduce the above copyright notice, this list\r\n of conditions and the following disclaimer in the documentation and/or other materials\r\n provided with the distribution.\r\n\r\nTHIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED\r\nWARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND\r\nFITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR\r\nCONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\r\nSERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON\r\nANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\r\nNEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF\r\nADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r\n\r\nThe views and conclusions contained in the software and documentation are those of the\r\nauthors and should not be interpreted as representing official policies, either expressed\r\nor implied, of Bump Technologies Inc.", "maintainer": "", "maintainer_email": "edahlgren@bu.mp, wmoss@bu.mp", "name": "montageclient", "package_url": "https://pypi.org/project/montageclient/", "platform": "", "project_url": "https://pypi.org/project/montageclient/", "project_urls": { "Download": "http://static.bumpserver.com/oss/montage/montageclient-0.1.0.tar.gz", "Homepage": "https://github.com/bumptech/montage-python-client" }, "release_url": "https://pypi.org/project/montageclient/0.1.0/", "requires_dist": null, "requires_python": null, "summary": "A Riak resolution proxy client", "version": "0.1.0" }, "last_serial": 803094, "releases": { "0.1.0": [ { "comment_text": "", "digests": { "md5": "9525b90f0a42cd95067b6b622bd6bf8e", "sha256": "093e066409a24a188c09925fd589a7273a939e9fc35c38ed622cea5ef6d1dda1" }, "downloads": -1, "filename": "montageclient-0.1.0.tar.gz", "has_sig": false, "md5_digest": "9525b90f0a42cd95067b6b622bd6bf8e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 5735, "upload_time": "2012-10-27T03:21:56", "url": "https://files.pythonhosted.org/packages/db/6c/f17fd4bb96799e002e5d46dd45c807e54b62440afcd9930d200ca21db02b/montageclient-0.1.0.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "9525b90f0a42cd95067b6b622bd6bf8e", "sha256": "093e066409a24a188c09925fd589a7273a939e9fc35c38ed622cea5ef6d1dda1" }, "downloads": -1, "filename": "montageclient-0.1.0.tar.gz", "has_sig": false, "md5_digest": "9525b90f0a42cd95067b6b622bd6bf8e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 5735, "upload_time": "2012-10-27T03:21:56", "url": "https://files.pythonhosted.org/packages/db/6c/f17fd4bb96799e002e5d46dd45c807e54b62440afcd9930d200ca21db02b/montageclient-0.1.0.tar.gz" } ] }