Is it possible to block a code in view from execution by all users accessing the view while it is being executed by a single user? Kind of single-thread view.
I need it because i generate the python executable with pyinstaller
in this view and passing a username into the executable through the config file.
For example:
class CliConfig(APIView): def get(self, request, format=None): try: config['DEFAULT']['username'] = request.user #make a build with pyinstaller bin_file = open(*generated filepath *, 'rb') response = Response(FileWrapper(bin_file), content_type='application/octet-stream') response['Content-Disposition'] = 'attachment; filename="%s"' % '*filename*' return response finally: config['DEFAULT']['username'] = ''
So, basically what i want is to generate a python executable which will have a unique username it it's settings, in django rest framwork APIView
. I don't see other approach except passing the username through the settings file. If there is a way - would appreciate an advise.
python 3.6.5
, djangorestframework==3.8.2
, pyinstaller==3.3.1
3 Answers
Answers 1
Why do you store the username in the config? Shouldn't this generation be per user?
Anyhow it is not good practice to do time-consuming tasks inside views.
Use Celery for long-term tasks that will generate executables and will accept any variables without stopping Django. At the end of this task Celery can send executable to email or something.
from celery import Celery app = Celery('hello', broker='amqp://guest@localhost//') @app.task def generate_executable(username): # make a build with pyinstaller with username bin_file = open(*generated filepath *, 'rb') response = Response(FileWrapper(bin_file), content_type='application/octet-stream') response['Content-Disposition'] = 'attachment; filename="%s"' % '*filename*' # send email and/or returns as task result return response class CliConfig(APIView): def get(self, request, format=None): task = generate_executable(request.user) task.delay() return Response({"status": "started", "task_id": task.task_id})
Answers 2
Take a look at Django-channels project. channels give abstraction to developer and support many protocols including HTTP. You can rewrite critical pages to channels consumers. So you will be able to write asynchronious code in block manner using async/await
constructions. https://channels.readthedocs.io/en/latest/topics/consumers.html#asynchttpconsumer
Answers 3
This is not Django related question. What you would like is to lock the 'method' and not allow the other threads to access it while there is a lock on this method. This is somenthing that python can do for you.
I recommend you reading this post http://effbot.org/zone/thread-synchronization.htm#locks or refer to this answer Locking a method in Python?
0 comments:
Post a Comment