{ "info": { "author": "Alessandro Molina", "author_email": "alessandro.molina@axant.it", "bugtrack_url": null, "classifiers": [ "Environment :: Web Environment", "Framework :: TurboGears", "Topic :: Software Development :: Libraries :: Python Modules" ], "description": "About Data Helpers\n-------------------------\n\n.. image:: https://drone.io/bitbucket.org/axant/tgext.datahelpers/status.png\n :target: https://drone.io/bitbucket.org/axant/tgext.datahelpers\n\ntgext.datahelpers is a collection of utilities to help manage stored data\nin common web applications.\n\ntgext.datahelpers contains:\n\n- Validators to fetch objects from database by Id (both SQLA and Ming)\n- Store Attachments by just declaring a Column in your model\n- Store image and thumbnails by just declaring a Column in your model\n\nInstalling\n-------------------------------\n\ntgext.datahelpers can be installed both from pypi or from bitbucket::\n\n easy_install tgext.datahelpers\n\nshould just work for most of the users\n\nValidators\n--------------------------------\n\n``tgext.datahelpers.validators`` provides the ``SQLAEntityConverter`` and\n``MingEntityConverter`` that convert the given\nparameter (which is expected to be the primary key of an object) to\nthe actually object itself::\n\n from tgext.datahelpers.validators import SQLAEntityConverter\n\n @expose()\n @validate({'doc':SQLAEntityConverter(Document)}, error_handler=index)\n def photo(self, doc):\n return redirect(doc.photo.url)\n\nValidators module provides also the ``validated_handler`` utility which\nmakes possible to apply validation also to error_handlers.\nNormally TurboGears would execute @validate based validation only when\nthe controller method is called through a request, when you use a controller\nmethod as the error_handler of another method the error_handler @validate\ngets skipped and arguments are passed as they are.\n\nUsing ``validated_handler`` it is possible to change this behavior and\napply validation even to error_handlers::\n\n from tgext.datahelpers.validators import SQLAEntityConverter, validated_handler\n\n @expose()\n @validate({'doc':validators.Int(not_empty=True)},\n error_handler=index)\n def next(self, doc):\n return dict(doc=doc+1)\n\n @expose()\n @validate({'doc':SQLAEntityConverter(Document)},\n error_handler=validated_handler(next))\n def photo(self, doc):\n return redirect(doc.photo.url)\n\nIn the previous example when calling /photo/3 if document 3 is not available\nit would be retrieved the successive document by calling next. If validated_handler\ngets removed from photo @validate you would get an error as doc wouldn't be an integer.\n\nUtilities\n-----------------------------------\n\n``tgext.datahelpers.utils`` provides the ``slugify`` function to\ngenerate slug urls for entities which are meaningful for users.\n\nThe generated slugs includes the entity id so that it can identify\nunique elements making possible for EntityConverter validators\nto support retrieving objects from the generated slug. Add\n``slugified=True`` option to the entity converted to load\nback an entity by its slug.\n\nSample usage::\n\n >>> from tgext.datahelpers.utils import slugify\n\n >>> entity = DBSession.query(Entity).get(5)\n >>> url = slugify(entity, entity.name)\n >>> print url\n 'this-is-a-very-long-phrase-5'\n\nUtility functions also provide a ``fail_with`` object which\ncan be used with turbogears @validate error_handler to report\na missing element or forbidden access::\n\n from tgext.datahelpers.validators import SQLAEntityConverter\n from tgext.datahelpers.utils import fail_with\n\n @expose()\n @validate({'doc':SQLAEntityConverter(Document, slugified=True)},\n error_handler=fail_with(404))\n def photo(self, doc):\n return redirect(doc.photo.url)\n\nEntities Based Caching\n-----------------------------------\n\n``tgext.datahelpers.caching`` provides the ``@entitycached`` decorator\nwhich can be used to cache methods (and helpers) based on a parameter\nwhich is a Ming or SQLAlchemy entity.\n\nWhenever the entity gets updated the cache is invalidated and the method\ncalled again, otherwise calling the method will return the value from the cache.\n\nTo determine if the entity has changed it will try to retrieve the\n``cache_key`` property of the entity, if not available a cache key\nwill be automatically generated using the primary key and ``updated_at``\nproperty of the entity.\n\nSample usage::\n\n from tgext.datahelpers.caching import entitycached\n\n @entitycached('post')\n def render_post(post):\n return '
%s
' % post.html\n\n blog = ''.join(map(render_post, blog_posts))\n\n``@entitycached`` decorator can also be used to cache any function by using\nthe ``tgext.datahelpers.caching.CacheKey`` object as a function argument instead\nof a Ming/SQLAlchemy entity.\n\nIf you want to cache an SQLAlchemy query give a look at the ``sqla_merge`` option.\n\n``@entitycached`` decorator supports also various options:\n\n- ``expire`` - How long the cached value will be kept around, by default 3 days\n- ``cache_type`` - Which type of cache to use, by default memory will be used\n- ``namespace`` - The cache namespace, by default this is autogenerated by the cached class and method names\n- ``sqla_merge`` - Whenever the cached function return value is a SQLAlchemy query.\n When this option is True you will always get the results instead of the query itself and the resulting\n objects will be merged back in to the currently existing TurboGears DBSession to avoid\n ``DetachedInstanceError`` exceptions.\n\nAttachments\n-----------------------------------\n\n``tgext.datahelpers.fields`` provides the ``Attachment`` field for SQLAlchemy\nto provide an easy and convenient way to store attachments.\n\nThe ``Attachment`` field will permit to assign files to the attribute\ndeclared with ``Attachment`` type and will store a copy of the file on disk\nas soon as the object is committed to the database.\n\nThe document field will provide a bunch of attributes you can use to\naccess the file:\n\n- ``file`` - A file object pointing to the saved file\n- ``filename`` - The name of the saved file\n- ``url`` - Url from which the file is fetchable\n- ``local_path`` - Local path of the file on disk\n\nFiles will be saved in ``tg.config['attachments_path']`` and url will be\ngenerated using ``tg.config['attachments_url']``. By default those are set\nat */public/attachments* and */attachments*.\n\nThe ``Attachment`` field accepts a *attachment_type* parameter which specifies\nthe kind of attachment that it is going to be saved. The default is\n``tgext.datahelpers.fields.AttachedFile`` which just stores the file itself::\n\n from tgext.datahelpers.fields import Attachment\n class Document(DeclarativeBase):\n __tablename__ = 'document'\n\n uid = Column(Integer, autoincrement=True, primary_key=True)\n file = Column(Attachment)\n\n d = Document(file=open('/myfile.txt'))\n DBSession.add(d)\n DBSession.flush()\n DBSession.commit()\n\n d = DBSession.query(Document).first()\n print d.file.url\n\n '/attachments/747722ca-1a07-11e1-83fc-001ff3d72e6b/myfile.txt'\n\nApart from file objects also instances of ``cgi.FieldStorage`` can be assigned\nto permit to quickly store uploaded files.\n\nImage Attachments with Thumbnail\n--------------------------------------\n\nUsing the ``tgext.datahelpers.fields.AttachedImage`` as the argument of the\n``Attachment`` field it is possible to quickly store images with their thumbnail.\n\nThe resulting object will provide the same attributes as the generic Attachment one\nadding two more thumbnail related properties:\n\n- ``thumb_local_path`` - The local path of the image thumbnail\n- ``thumb_url`` - The url of the thumbnail\n\nStoring image with thumbnails is as easy as storing the file itself::\n\n from tgext.datahelpers.fields import Attachment, AttachedImage\n class Document(DeclarativeBase):\n __tablename__ = 'document'\n\n uid = Column(Integer, autoincrement=True, primary_key=True)\n image = Column(Attachment(AttachedImage))\n\n d = Document(image=open('/photo.jpg'))\n DBSession.add(d)\n DBSession.flush()\n DBSession.commit()\n\n d = DBSession.query(Document).first()\n print d.image.url\n '/attachments/d977144a-1a08-11e1-8131-001ff3d72e6b/aperto.tiff'\n print d.image.thumb_url\n 'attachments/d977144a-1a08-11e1-8131-001ff3d72e6b/thumb.png'\n\n\nThumbnail Options\n=======================================\n\nBy default thumbnails will be generated with size 128, 128 and in PNG format.\nThis can be changed by sublcassing the ``AttachedImage`` class and specifying\nthe ``thumbnail_size`` and ``thumbnail_format`` attributes::\n\n class BigThumbnailAttachedImage(AttachedImage):\n thumbnail_size = (320, 320)\n thumbnail_format = 'jpg'\n\n class Document(DeclarativeBase):\n __tablename__ = 'document'\n\n uid = Column(Integer, autoincrement=True, primary_key=True)\n image = Column(Attachment(BigThumbnailAttachedImage))\n", "description_content_type": "", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/axant/tgext.datahelpers", "keywords": "turbogears2.extension", "license": "MIT", "maintainer": "", "maintainer_email": "", "name": "tgext.datahelpers", "package_url": "https://pypi.org/project/tgext.datahelpers/", "platform": "", "project_url": "https://pypi.org/project/tgext.datahelpers/", "project_urls": { "Homepage": "https://github.com/axant/tgext.datahelpers" }, "release_url": "https://pypi.org/project/tgext.datahelpers/0.2.1/", "requires_dist": null, "requires_python": "", "summary": "Helpers to manage data and attachments on TurboGears", "version": "0.2.1" }, "last_serial": 5486091, "releases": { "0.0.1": [ { "comment_text": "", "digests": { "md5": "fb8cc4ecdea31eef0bb93479fa5e2ca9", "sha256": "7239e24e3d6414db392a6e92cf18eb58bff554abb7c151ad623704206d30f4d9" }, "downloads": -1, "filename": "tgext.datahelpers-0.0.1.tar.gz", "has_sig": false, "md5_digest": "fb8cc4ecdea31eef0bb93479fa5e2ca9", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7011, "upload_time": "2011-11-29T00:25:35", "url": "https://files.pythonhosted.org/packages/b3/3b/8c7b947409c73efc83c2555b25ba0c7b81784a017b3d1d0ed0dce4efaf04/tgext.datahelpers-0.0.1.tar.gz" } ], "0.0.2": [ { "comment_text": "", "digests": { "md5": "f07d652d9d1db6933e8bf7ab2f84222a", "sha256": "3a4c4771485eae0b7aa05513e914e8a44cf7f41c50cc362998ab0691889af01c" }, "downloads": -1, "filename": "tgext.datahelpers-0.0.2.tar.gz", "has_sig": false, "md5_digest": "f07d652d9d1db6933e8bf7ab2f84222a", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8700, "upload_time": "2012-01-26T23:11:56", "url": "https://files.pythonhosted.org/packages/8f/69/ac7ffbb8f56131b56a040740cc7418bc70ab560e9d18bf006093a65a7628/tgext.datahelpers-0.0.2.tar.gz" } ], "0.0.3": [ { "comment_text": "", "digests": { "md5": "df1fb96bcbfd2f7b6907744b27eb14f3", "sha256": "3930e5911f25863c57492be9d58e40b803229fb2a7df0d373ebaba5b4be02063" }, "downloads": -1, "filename": "tgext.datahelpers-0.0.3.tar.gz", "has_sig": false, "md5_digest": "df1fb96bcbfd2f7b6907744b27eb14f3", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 9486, "upload_time": "2012-05-11T23:24:00", "url": "https://files.pythonhosted.org/packages/59/1c/62a652c373a621fa90555fbdb7bc2062be4f15c4c5ba4e70325c68ba043a/tgext.datahelpers-0.0.3.tar.gz" } ], "0.0.4": [ { "comment_text": "", "digests": { "md5": "e5bf2f270324059aa62c5ea3f31c9449", "sha256": "b9ded64bebc6b7ad300f4a0631ee3dacb1a7b6c43ae2e2744d37cba40dfa7737" }, "downloads": -1, "filename": "tgext.datahelpers-0.0.4.tar.gz", "has_sig": false, "md5_digest": "e5bf2f270324059aa62c5ea3f31c9449", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 12541, "upload_time": "2012-05-18T11:06:29", "url": "https://files.pythonhosted.org/packages/50/14/870daba7147fb6283b7904302ecab63f988f45e1004152c915869a9b2a29/tgext.datahelpers-0.0.4.tar.gz" } ], "0.0.5": [ { "comment_text": "", "digests": { "md5": "5e8d6bbba2bb4440bde0a15a573835b3", "sha256": "a1f2c51be64f0eeeec4cd570ff4d55d2e1543889279af422fe46cdff1e687217" }, "downloads": -1, "filename": "tgext.datahelpers-0.0.5.tar.gz", "has_sig": false, "md5_digest": "5e8d6bbba2bb4440bde0a15a573835b3", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 11780, "upload_time": "2012-07-13T23:45:11", "url": "https://files.pythonhosted.org/packages/6d/bc/53ff077cd24a5131fb1196bded6567e86e7429405320fab23e1231029fe3/tgext.datahelpers-0.0.5.tar.gz" } ], "0.0.6": [ { "comment_text": "", "digests": { "md5": "afdbc06a73287edc6bf34c7bf72ff2ce", "sha256": "85c0f0cbb4c70ba56cc32e5001e33ee9fd0164b0d2d5b5ccbfc751af75e19f01" }, "downloads": -1, "filename": "tgext.datahelpers-0.0.6.tar.gz", "has_sig": false, "md5_digest": "afdbc06a73287edc6bf34c7bf72ff2ce", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 11864, "upload_time": "2012-07-25T15:17:28", "url": "https://files.pythonhosted.org/packages/44/c2/6bdcf4eb77fe960a795b0abb408c77f26cb13bec5234b07359621b83bc4e/tgext.datahelpers-0.0.6.tar.gz" } ], "0.0.7": [ { "comment_text": "", "digests": { "md5": "403c19c6f07ecd9e672c88562c4b94ba", "sha256": "ff5f8f100d76bd7a3de0251a66735e5324336e2345990aa38ade32105ed69110" }, "downloads": -1, "filename": "tgext.datahelpers-0.0.7.tar.gz", "has_sig": false, "md5_digest": "403c19c6f07ecd9e672c88562c4b94ba", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 11543, "upload_time": "2012-08-08T15:05:29", "url": "https://files.pythonhosted.org/packages/f0/96/6e559c057ddfdeb1fafddd4df6d714988dec6d2ff60bcd66694da00325e4/tgext.datahelpers-0.0.7.tar.gz" } ], "0.0.8": [ { "comment_text": "", "digests": { "md5": "d7bb47a9adc10597ba995f156acf2622", "sha256": "4851cf84befed5e0d733778cf222db63b909dfc855df447378ad82b0ab4b84b0" }, "downloads": -1, "filename": "tgext.datahelpers-0.0.8.tar.gz", "has_sig": false, "md5_digest": "d7bb47a9adc10597ba995f156acf2622", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 12345, "upload_time": "2012-08-16T14:53:23", "url": "https://files.pythonhosted.org/packages/2a/01/cbed13e84315d288e268ffb6474a404829427468ed620edb3d93c0575d79/tgext.datahelpers-0.0.8.tar.gz" } ], "0.0.9": [ { "comment_text": "", "digests": { "md5": "a32931075c7d7db73fa2d1f16d213355", "sha256": "035088d95cea4eec31320f24aa320e09615e0766d4f30abbee0232b30ee606af" }, "downloads": -1, "filename": "tgext.datahelpers-0.0.9.tar.gz", "has_sig": false, "md5_digest": "a32931075c7d7db73fa2d1f16d213355", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 12376, "upload_time": "2012-11-01T01:56:24", "url": "https://files.pythonhosted.org/packages/a2/7f/df3972a1c3d26112c32a52167aebb1b325f7a189d1dd099421a7f679e4a4/tgext.datahelpers-0.0.9.tar.gz" } ], "0.1.0": [ { "comment_text": "", "digests": { "md5": "a4fa3270eb0c2de8fcfa12fbdd949fb4", "sha256": "c1dcdfdfe63d673b0646c3ed6a8baa499d31202ad8cd509091c50aa347101f25" }, "downloads": -1, "filename": "tgext.datahelpers-0.1.0.tar.gz", "has_sig": false, "md5_digest": "a4fa3270eb0c2de8fcfa12fbdd949fb4", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 14197, "upload_time": "2013-07-31T16:00:42", "url": "https://files.pythonhosted.org/packages/1f/70/8b593e714804d358757e36e52ac968352ee56d2be4d0906358228c8bb089/tgext.datahelpers-0.1.0.tar.gz" } ], "0.1.1": [ { "comment_text": "", "digests": { "md5": "28a8b70f700621a40e0bfb16547b18cd", "sha256": "82fbc357c722f030ced7368aab8886b9d5a05302c7e7183018463ac7d02db186" }, "downloads": -1, "filename": "tgext.datahelpers-0.1.1.tar.gz", "has_sig": false, "md5_digest": "28a8b70f700621a40e0bfb16547b18cd", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 14316, "upload_time": "2013-08-20T11:12:15", "url": "https://files.pythonhosted.org/packages/bb/3f/7ec3d9a5e86737d5fc1600b79ed23e9929c1504e0bb534f4d0e59ea34e1a/tgext.datahelpers-0.1.1.tar.gz" } ], "0.1.2": [ { "comment_text": "", "digests": { "md5": "c70fbd8a55b616ce9b7dbf494a762aca", "sha256": "c8973320184afe61a358556595060696035efdfca8c4f024222d9cb1eaaed868" }, "downloads": -1, "filename": "tgext.datahelpers-0.1.2.tar.gz", "has_sig": false, "md5_digest": "c70fbd8a55b616ce9b7dbf494a762aca", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 14555, "upload_time": "2013-08-20T20:37:41", "url": "https://files.pythonhosted.org/packages/3b/8a/c70ec3ccc170e71c923eea9952319fb70452743d66f4fdd05110f8c899ff/tgext.datahelpers-0.1.2.tar.gz" } ], "0.2.0": [ { "comment_text": "", "digests": { "md5": "831e018df893408468be02c3599a281d", "sha256": "f4d92dcd3e50133198fcec43b260dc892c45faee2836daac5f13f8e333231dd1" }, "downloads": -1, "filename": "tgext.datahelpers-0.2.0.tar.gz", "has_sig": false, "md5_digest": "831e018df893408468be02c3599a281d", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 14667, "upload_time": "2013-12-11T21:25:28", "url": "https://files.pythonhosted.org/packages/80/e6/3a32473d7dcfd682fef58c3dba7ed7a9d6147f582f32947b5e8684e09d5e/tgext.datahelpers-0.2.0.tar.gz" } ], "0.2.1": [ { "comment_text": "", "digests": { "md5": "d678592c6d306fe861512b78214e18d9", "sha256": "a600636158c3eeac6fe1a6d7ceafc56b17ecc433f7498ec5d8cc585cdf25d422" }, "downloads": -1, "filename": "tgext.datahelpers-0.2.1.tar.gz", "has_sig": false, "md5_digest": "d678592c6d306fe861512b78214e18d9", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 18170, "upload_time": "2019-07-04T10:39:21", "url": "https://files.pythonhosted.org/packages/28/9c/85828c846125260ddef30d6ee9f8f015363edcbc988b661f3ac06554e9d1/tgext.datahelpers-0.2.1.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "d678592c6d306fe861512b78214e18d9", "sha256": "a600636158c3eeac6fe1a6d7ceafc56b17ecc433f7498ec5d8cc585cdf25d422" }, "downloads": -1, "filename": "tgext.datahelpers-0.2.1.tar.gz", "has_sig": false, "md5_digest": "d678592c6d306fe861512b78214e18d9", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 18170, "upload_time": "2019-07-04T10:39:21", "url": "https://files.pythonhosted.org/packages/28/9c/85828c846125260ddef30d6ee9f8f015363edcbc988b661f3ac06554e9d1/tgext.datahelpers-0.2.1.tar.gz" } ] }