{ "info": { "author": "Gregory Terzian", "author_email": "gregory.terzian@gmail.com", "bugtrack_url": null, "classifiers": [ "Environment :: Web Environment", "Natural Language :: English", "Operating System :: OS Independent", "Programming Language :: Python" ], "description": "django-async\n=============\n\n:Author: Gregory Terzian\n:License: BSD\n\nA package of Django apps for common async tasks using Celery. For now only one app, used for saving an uploaded image with a Celery worker.\n\nasync_image_save\n----------------\n\nAs you cannot pass as image to a Celery task, this app deconstructs the UploadedFile instance, passes it to a Celery task and reconstructs it there.\nFinally saving the uploaded image.\n\n\nLicense\n-------\n\nAll code is under a BSD-style license, see LICENSE for details.\n\nSource: https://github.com/gterzian/django_async.git\n\nRequirements\n------------\n\n* python >= 2.7\n* django >= 1.4\n* Celery >= 3.0\n* PIL >= 1.1.6\n\nInstallation\n------------\n\nTo install run::\n\n pip install django-async-gt\n\n\nConfiguration\n-------------\n\nYou first of all need to have django-celery set up in your project.\n\nsettings.py\n^^^^^^^^^^^\n\nAdd to ``INSTALLED_APPS``::\n\n 'async_image_save'\n\n\nThe Problem: Celery tasks cannot accept images as arguments\n-----------------------------------------------------------\n\nDjango uploads images and other files in the form of UpLoadedFile objects.\nUpLoadedFile is the abstract baseclasse, while TemporaryUploadedFile and InMemoryUploadedFile are the built-in concrete subclasses.\nAn UploadedFile object behaves somewhat like a file object and represents some file data that the user submitted with a form.\n\nThe uploadedfile is received in the view as part of request.FILES, which you will usually bind to a form.\nRunning the form's is_valid method will then validate this file, or in the case of an ImageField whether the fiel is an actual image, and return the UpLoadedFile object for you to use,\nas either a TemporaryUploadedFile or InMemoryUploadedFile.\n\nOnce Django form validation has been succesfully run, you can safely assume that you are dealing with an actual image. The normal course of business is to immediatly bind the uploaded file object\nto a model instance, and saving the instance to the database. This means saving the image to your data store while the client is still waiting for a response from the server, which takes a few seconds, especially if you are using S3.\n\nWouldn't it be better to pass the image along to a celery worker to save in the background?\n\nThe problem is that Celery needs to be able to pickle objects to pass them along to workers, and it cannot pickle a file like object such as an image.\n\nThe Solution: de- and reconstruct the image\n-------------------------------------------\n\nThe remaining option is to deconstruct the file object, write it's data into a string and taking all the other info that you need.\nThis data can be pickled and therefore passed on to Celery. You then simply need to reconstruct an actual TemporaryUploadedFile or InMemoryUploadedFile object on the other end,\nand bind this object to an instance of a model, by passing the id of that instance along with all other raw file 'data'. You can then finally save the model instance.\n\n\nRead the Django docs\n--------------------\n\nUploadedFile: https://docs.djangoproject.com/en/1.4/topics/http/file-uploads/#django.core.files.uploadedfile.UploadedFile\n\nBinding data to forms: https://docs.djangoproject.com/en/1.4/ref/forms/api/#binding-uploaded-files\n\n\nHow to use it in your project\n-----------------------------\n\nThe functionalities of this app reside in the save_image function, to be used in your views like the below.\nThe function deconstructs the image and sends the data to the async_save task. Please not that the task clears the cache. This is necessary in my opinion because\njust adding the image to the instance doesn't invalidate the cache like creating a new instance would, therefore the saved image is not seen by the user until after the cache time out.\nTherefore clearing the cache in the task seems necessary.\n\n::\n\n from async_image_save.utils import save_image\n\n def example_view(request):\n if request.method == \"POST\":\n form = YourModelForm(request.POST, request.FILES)\n if form.is_valid():\n # assuming your model has a main_photo ImageField \n # save the instance without an image \n instance = form.save(commit=False)\n instance.main_photo = None\n instance.save()\n instance.users.add(request.user.userprofile)\n # send the image to be saved by a worker\n save_image(form.cleaned_data['main_photo'], instance)\n \n return HttpResponseRedirect(reverse('home'))\n else: \n form = YourModelForm()\n context['form'] = form\n return render_to_response(\"home.html\", context, context_instance=RequestContext(request))", "description_content_type": null, "docs_url": null, "download_url": "UNKNOWN", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "http://github.com/gterzian/django_async.git", "keywords": null, "license": "BSD License", "maintainer": null, "maintainer_email": null, "name": "django-async-gt", "package_url": "https://pypi.org/project/django-async-gt/", "platform": "any", "project_url": "https://pypi.org/project/django-async-gt/", "project_urls": { "Download": "UNKNOWN", "Homepage": "http://github.com/gterzian/django_async.git" }, "release_url": "https://pypi.org/project/django-async-gt/0.6.2/", "requires_dist": null, "requires_python": null, "summary": "a simple app to asynchronously upload images with Django, using Celery", "version": "0.6.2" }, "last_serial": 789117, "releases": { "0.1": [ { "comment_text": "", "digests": { "md5": "3bcef18b28976bfbba039ef6bdcafe8d", "sha256": "79ebf3d649830e2007cb86176adc1650d73d96eeef5bfd884a53024eea647593" }, "downloads": -1, "filename": "django-async-gt-0.1.tar.gz", "has_sig": false, "md5_digest": "3bcef18b28976bfbba039ef6bdcafe8d", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 2061, "upload_time": "2013-02-11T21:36:40", "url": "https://files.pythonhosted.org/packages/1c/f6/e75856247db6fd7bc8c78b0f61af1ce13d1f288bd3ecf5977858d04fca5c/django-async-gt-0.1.tar.gz" } ], "0.2": [ { "comment_text": "", "digests": { "md5": "002788ba70532c35cff21d2fb21bbcf2", "sha256": "db8c2c3d26e787a69ab80c94c4fc4f86559e9d722305fae0e243f3aedc71245d" }, "downloads": -1, "filename": "django-async-gt-0.2.tar.gz", "has_sig": false, "md5_digest": "002788ba70532c35cff21d2fb21bbcf2", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 3273, "upload_time": "2013-02-11T23:09:45", "url": "https://files.pythonhosted.org/packages/e3/b7/885bf206786dcb2f74a25b8152da4fa86dc613cf64881b910b7d932e5864/django-async-gt-0.2.tar.gz" } ], "0.3": [ { "comment_text": "", "digests": { "md5": "6466c277630d6fdccd0dd7c9e7c89316", "sha256": "c9e0738aa7302458e181632c8773fd909fb66f9b936b6d640e36157b19dba5ee" }, "downloads": -1, "filename": "django-async-gt-0.3.tar.gz", "has_sig": false, "md5_digest": "6466c277630d6fdccd0dd7c9e7c89316", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 3267, "upload_time": "2013-02-11T23:14:01", "url": "https://files.pythonhosted.org/packages/ec/b5/442173be19f64482f3bd9bc4efd66f169acaffec9d46a2e96b41af91aa34/django-async-gt-0.3.tar.gz" } ], "0.4": [ { "comment_text": "", "digests": { "md5": "80020429b86ad2f2c797d00b46ed7bf0", "sha256": "f0cf7b8ce38a244d20fcdfd4fc7c5b3b15637e3fa90335ee196c2b8cca3a9766" }, "downloads": -1, "filename": "django-async-gt-0.4.tar.gz", "has_sig": false, "md5_digest": "80020429b86ad2f2c797d00b46ed7bf0", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 3263, "upload_time": "2013-02-11T23:20:44", "url": "https://files.pythonhosted.org/packages/a9/b8/ac53794519225116eb1119b1b916ffc0301f17b4bfd1f62c2b29d36948fd/django-async-gt-0.4.tar.gz" } ], "0.5": [], "0.6": [ { "comment_text": "", "digests": { "md5": "e75135a6459b3d3223d0cc6226cf585b", "sha256": "eaabed46a8bfffe7e9ed9c68ddb807bf60cfb60147408e606199c58139ef141f" }, "downloads": -1, "filename": "django-async-gt-0.6.tar.gz", "has_sig": false, "md5_digest": "e75135a6459b3d3223d0cc6226cf585b", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 3269, "upload_time": "2013-02-11T23:40:54", "url": "https://files.pythonhosted.org/packages/10/65/e1b52bb0011077f5e641d1265aa59c7dfada51e48160df5928b0aaa0054b/django-async-gt-0.6.tar.gz" } ], "0.6.1": [ { "comment_text": "", "digests": { "md5": "88bc79be36ea09de9abde0e3be8a405c", "sha256": "4ddd465305d8749ffeca9c1755f3c622fc78e2bd1bbf53cb0c53ac6a8c722c38" }, "downloads": -1, "filename": "django-async-gt-0.6.1.tar.gz", "has_sig": false, "md5_digest": "88bc79be36ea09de9abde0e3be8a405c", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 4372, "upload_time": "2013-02-12T20:58:11", "url": "https://files.pythonhosted.org/packages/96/d5/97c2b5e7e060abfa7d860e5983b59c4d81960bc282a6339d10fbfce7c690/django-async-gt-0.6.1.tar.gz" } ], "0.6.2": [ { "comment_text": "", "digests": { "md5": "45e96875541b92fe0e2c49118203b3e8", "sha256": "350993aa13712b5842b5c56c09258e33484e77e56efe94c7b881557afafc77f7" }, "downloads": -1, "filename": "django-async-gt-0.6.2.tar.gz", "has_sig": false, "md5_digest": "45e96875541b92fe0e2c49118203b3e8", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 4730, "upload_time": "2013-02-19T12:44:37", "url": "https://files.pythonhosted.org/packages/35/cc/09f6d1784e36444263f0268e2d05b8e5ef1c60f828a6b0cc3695cc1220e6/django-async-gt-0.6.2.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "45e96875541b92fe0e2c49118203b3e8", "sha256": "350993aa13712b5842b5c56c09258e33484e77e56efe94c7b881557afafc77f7" }, "downloads": -1, "filename": "django-async-gt-0.6.2.tar.gz", "has_sig": false, "md5_digest": "45e96875541b92fe0e2c49118203b3e8", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 4730, "upload_time": "2013-02-19T12:44:37", "url": "https://files.pythonhosted.org/packages/35/cc/09f6d1784e36444263f0268e2d05b8e5ef1c60f828a6b0cc3695cc1220e6/django-async-gt-0.6.2.tar.gz" } ] }