Best django questions in April 2011

Looking for good Django interview questions

14 votes

When I post a job position, I seem to spend a lot of time going through a lot of resumes for people that aren't qualified, and sometimes I don't find out until during a phone screen. This wastes a lot of my time.

Moving forward I would like to improve my job interviewing process by giving potential candidates a test that they can fill out and submit with their resume. If they get a good score on the test, then they make it to the next level.

I'm looking for good Django interview questions. If you have them, please submit them. If possible I would like to have different levels of questions basic, moderate and advanced, so that depending on the position, I can give the appropriate level of questions.

Bonus points if you can make it a multiple choice question.

Thanks for your help, Ken

I stopped trying to come up with specific tests for hiring programmers, it's too much work. Instead I took a combination of Jeff Atwood's FizzBuzz problem and Joel Spolsky's interview guide. This makes weeding out programmers a breeze. I only interview the guys that can code FizzBuzz, then the actual interview is rather quick because I only ask 5-7 questions. I am no longer as concerned if the applicant can code in language I need, most qualified programmers can switch languages without too much effort. I would rather hire a good coder that needs to pick up a new language rather than a guy who thinks he can code.

Read these, you may change your interviewing technique - http://www.joelonsoftware.com/articles/GuerrillaInterviewing3.html

http://www.codinghorror.com/blog/2007/02/why-cant-programmers-program.html

Since switching to this tactic, I have had a lot better results with the programmers I have hired.

Using MongoDB as our master database, should I use a separate graph database to implement relationships between entities?

9 votes

We're currently in the process of implementing a CRM-like solution internally for a professional firm. Due to the nature of the information stored, and the varying values and keys for the information we decided to use a document storage database, as it suited the purposes perfectly (In this case we chose MongoDB).

As part of this CRM solution we wish to store relationships and associations between entities, examples include storing conflicts of interest information, shareholders, trustees etc. Linking all these entities together in the most effective way we determined a central model of "relationship" was necessary. All relationships should have history information attached to them ( commencement and termination dates), as well as varying meta data; for example a shareholder relationship would also contain number of shares held.

As traditional RDBMS solutions didn't suit our former needs, using them in our current situation is not viable. What I'm trying to determine is whether using a graph database is more pertinent in our case, or if in fact just using mongo's built-in relational information is appropriate.

The relationship information is going to be used quite heavily throughout the system. An example of some of the informational queries we wish to perform are:

  • Get all 'key contact' people of companies who are 'clients' of 'xyz limited'
  • Get all other 'shareholders' of companies where 'john' is a shareholder
  • Get all 'Key contact' people of entities who are 'clients' of 'abc limited' and are clients of 'trust us bank limited'

Given this "tree" structure of relationships, is using a graph database (such as Neo4j) more appropriate?

Mike,

you should be able to store your relationship data in the graph database. Its high performance on traversing big graphs comes from locality, i.e. you don't run queries globally but rather start a a set of nodes (which equal documents in your case, which are looked up by an index. you might even store start-node-ids for quick access in your mongo documents). From there you can traverse arbitrarily large paths in constant time (wrt data set size).

What are your other requirements (i.e. data set size, # of concurrent accesses etc, relationship/graph complexity).

Your queries are a really good fit for the graph database and easily expressable in its terms.

I'd suggest that you just grab a graphdb like neo4j and do a quick spike with your domain to verify the general feasibility and also find out additional questions you would like to have answered before investing in the second technology.

P.S. If you hadn't started yet, you could also have gone with a pure graphdb approach as graph databases are a superset of document databases. And you'd rather talk domain in your case anyway than just generic documents. (E.g. structr is a CMS built on top of Neo4j).

Django custom field with multiple inheritance

6 votes

I have two custom Django fields, a JSONField and a CompressedField, both of which work well. I would like to also have a CompressedJSONField, and I was rather hoping I could do this:

class CompressedJSONField(JSONField, CompressedField):
    pass

but on import I get:

RuntimeError: maximum recursion depth exceeded while calling a Python object

I can find information about using models with multiple inheritance in Django, but nothing about doing the same with fields. Should this be possible? Or should I just give up at this stage?

edit:

Just to be clear, I don't think this has anything to do with the specifics of my code, as the following code has exactly the same problem:

class CustomField(models.TextField, models.CharField):
    pass

edit 2:

I'm using Python 2.6.6 and Django 1.3 at present. Here is the full code of my stripped-right-down test example:

customfields.py

from django.db import models


class CompressedField(models.TextField):
    """ Standard TextField with automatic compression/decompression. """

    __metaclass__ = models.SubfieldBase
    description = 'Field which compresses stored data.'

    def to_python(self, value):
        return value

    def get_db_prep_value(self, value, **kwargs):
        return super(CompressedField, self)\
                        .get_db_prep_value(value, prepared=True)


class JSONField(models.TextField):
    """ JSONField with automatic serialization/deserialization. """

    __metaclass__ = models.SubfieldBase
    description = 'Field which stores a JSON object'

    def to_python(self, value):
        return value

    def get_db_prep_save(self, value, **kwargs):
        return super(JSONField, self).get_db_prep_save(value, **kwargs)


class CompressedJSONField(JSONField, CompressedField):
    pass

models.py

from django.db import models
from customfields import CompressedField, JSONField, CompressedJSONField

class TestModel(models.Model):

    name = models.CharField(max_length=150)
    compressed_field = CompressedField()
    json_field = JSONField()
    compressed_json_field = CompressedJSONField()

    def __unicode__(self):
        return self.name

as soon as I add the compressed_json_field = CompressedJSONField() line I get errors when initializing Django.

after doing a few quick tests i found that if you remove the metaclass from the JSON and compressed fields and put it in the compressedJSON field it compiles. if you then need the JSON or Compressed fields then subclass them and jusst add the __metaclass__ = models.SubfieldBase

i have to admit that i didn't do any heavy testing with this:

from django.db import models                                                       


class CompressedField(models.TextField):                                           
    """ Standard TextField with automatic compression/decompression. """           

    description = 'Field which compresses stored data.'                            

    def to_python(self, value):                                                    
        return value                                                               

    def get_db_prep_value(self, value, **kwargs):                                  
        return super(CompressedField, self).get_db_prep_value(value, prepared=True)


class JSONField(models.TextField):                                                 
    """ JSONField with automatic serialization/deserialization. """                

    description = 'Field which stores a JSON object'                               

    def to_python(self, value):                                                    
        return value 

    def get_db_prep_save(self, value, **kwargs):                                   
        return super(JSONField, self).get_db_prep_save(value, **kwargs)            


class CompressedJSONField(JSONField, CompressedField):                             
    __metaclass__ = models.SubfieldBase                                            

class TestModel(models.Model):                                                     

    name = models.CharField(max_length=150)                                        
    #compressed_field = CompressedField()                                          
    #json_field = JSONField()                                                      
    compressed_json_field = CompressedJSONField()                                  

    def __unicode__(self):                                                         
        return self.name

if you then want to uses the JSON and Commpressed fields separately i assume this idea will work:

class JSONFieldSubClass(JSONField):
    __metaclass__ = models.SubfieldBase

Honestly ... I don't really understand any of this.

EDIT base method hack

class CompressedJSONField(JSONField, CompressedField):
    __metaclass__ = models.SubfieldBase

    def to_python(self, value):
        value = JSONField.to_python(self, value)
        value = CompressedField.to_python(self, value)
        return value

the other way is to make the to_python() on the classes have unique names and call them in your inherited classes to_python() methods

or maybe check out this answer

EDIT after some reading if you implement a call to super(class, self).method(args) in the first base to_python() then it will call the second base. If you use super consistently then you shouldn't have any problems. http://docs.python.org/library/functions.html#super is worth checking out and http://www.artima.com/weblogs/viewpost.jsp?thread=237121

class base1(object):                                                               
    def name(self, value):                                                         
        print "base1", value                                                       
        super(base1, self).name(value)                                             

    def to_python(self, value):                                                    
        value = value + " base 1 "                                                 
        if(hasattr(super(base1, self), "to_python")):                              
            value = super(base1, self).to_python(value)                            
        return value                                                               

class base2(object):                                                               
    def name(self, value):                                                         
        print "base2", value                                                       

    def to_python(self, value):                                                    
        value = value + " base 2 "                                                 
        if(hasattr(super(base2, self), "to_python")):                              
            value = super(base2, self).to_python(value)                            
        return value                                                               

class superClass(base1, base2):                                                    
    def name(self, value):                                                         
        super(superClass, self).name(value)                                        
        print "super Class", value    

Sending notification to the user on database change

5 votes

I am building a cafeteria management system in which there are two types of users;customres & counter owners.

For each dish offered in cafeteria, there is aunique dish.id associated to it.

Till now, I have dome something like student sends a POST request with dish,id and counter number to a URL which updates the "orders table'(which has PK as id). When the dish is prepared, the counter owner presses "Prepeared" button.

At this point, I want the customer whose order is next to what is prepared to get notified that "Your order preparation is in progress."

How should I do it? One way is to simply make a view which has its argument as customer.id & status and it replies with True or Flase. I can simply poll the URL and provide the notification if I recieve True.

But, I feel like polling is not a better approach as there will be so many customers logged in and each will poll to the server which is not acceptible. Any better way?

It really depends what you really need.

If notification can be sent ad part of user activity, simply add a user message, and it will be displayed whenever user do an action on the page. django.contrib.messages plus few lines in your main html template will do it.

But if you want the notification to be interactive - you can use one of the few PUSH options

Interesting links:

From the servers side, there are few options available, the simplest is Green Unicorn. Using it will allow you to have few thousands connections open and managed by only few processes.

Django: how to change the choices of AdminTimeWidget

5 votes

The AdminTimeWidget rendered in admin for a DateTimeField displays an icon of a clock and when you click you have the choice between: "Now Midnight 6:00 Noon".

How can I change these choices to "16h 17h 18h"?

Chris has a great answer. As an alternative you could do this using just javascript. Place the following javascript on the pages where you want the different time options.

DateTimeShortcuts.overrideTimeOptions = function () {
    //Find the first time element
    timeElement = django.jQuery("ul.timelist li").eq(0).clone();
    originalHref = timeElement.find('a').attr('href');

    //remove all existing time elements
    django.jQuery("ul.timelist li").remove();

    //add new time elements representing those you want
    var i=0;
    for (i=0;i<=23;i++) {
        //use a regular expression to update the the link
        newHref = originalHref.replace(/Date\([^\)]*\)/g, "Date(1970,1,1," + i + ",0,0,0)");
        //update the text for the element
        timeElement.find('a').attr('href', newHref).text(i+"h");
        //Add the new element into the document
        django.jQuery("ul.timelist").append(timeElement.clone());
    }
}

addEvent(window, 'load', DateTimeShortcuts.overrideTimeOptions);

thread safety in django with asynchronous tasks and redis

4 votes

I have a django application that calls an asynchronous task on a queryset (using celery). The task takes the queryset and performs a whole bunch of operations that could potentially take a very long time based on the obects therein. Objects could be shared across querysets, so a user could submit a task on a queryset that contains objects that are already running, and that new task should should only execute on the objects that aren't yet running, but wait for all objects to complete before it returns.

My explanation is a bit confusing, so imagine the following code:

from time import sleep
import redis
from celery.task import Task
from someapp.models import InterestingModel
from someapp.longtime import i_take_a_while

class LongRunningTask(Task):
    def run(self, process_id, *args, **kwargs):
        _queryset = InterestingModel.objects.filter(process__id=process_id)

        r = redis.Redis()
        p = r.pipeline()
        run_check_sets = ('run_check', 'objects_already_running')

        # There must be a better way to do this:
        for o in _queryset.values_list('pk', flat=True):
            p.sadd('run_check')
        p.sdiff(run_check_sets) # Objects that need to be run
        p.sunion(run_check_sets) # Objects that we need to wait for
        p.sunionstore('objects_already_running',run_check_sets)
        p.delete('run_check')
        redis_result = p.execute()

        objects_to_run = redis_result[-3]
        objects_to_wait_for = redis_result[-2]

        if objects_to_run:
            i_take_a_while(objects_to_run)
            p = r.pipeline()
            for o in objects_to_run:
                p.srem('objects_already_running', o)
            p.execute()

        while objects_to_wait_for:
            p = r.pipeline()
            for o in objects_to_wait_for:
                p.sismember('objects_already_running',o)
            redis_result = p.execute()
            objects_to_wait_for = [objects_to_wait_for[i] for i, member in enumerate(redis_result) if member]
            # Probably need to add some sort of timeout here or in redis
            sleep(30) 

I am extremely new to Redis, so my main question is whether there is a more efficient way to manipulate Redis to achieve the same result. More broadly, I wonder if Redis is necessary/the right approach to dealing with this problem. It seems like there should be a better way to interact Django models with Redis. Finally, I wonder if this code is, in fact, thread safe. Can anyone punch any holes in my logic?

Any commentary is appreciated.

Is it possible for you to architect this slightly differently? Specifically, I would kick off the tasks for each object and then store information about your long running jobs somewhere (e.g., database, cache, etc). When each individual object was finished, it would update the long running job info and check to see if all of the jobs had returned. If so, then you can run whatever code needs to be run when the long running task is complete.

This has the advantage of not tying up a thread on your server while you wait for other things to happen. On the client side, you could check the status of the long running job periodically and even use the number of objects complete to update a progress meter if you want.

How do I handle file upload via PUT request in Django?

4 votes

I'm implementing a REST-style interface and would like to be able to create (via upload) files via a HTTP PUT request. I would like to create either a TemporaryUploadedFile or a InMemoryUploadedFile which I can then pass to my existing FileField and .save() on the object that is part of the model, thereby storing the file.

I'm not quite sure about how to handle the file upload part. Specifically, this being a put request, I do not have access to request.FILES since it does not exist in a PUT request.

So, some questions:

  • Can I leverage existing functionality in the HttpRequest class, specifically the part that handles file uploads? I know a direct PUT is not a multipart MIME request, so I don't think so, but it is worth asking.
  • How can I deduce the mime type of what is being sent? If I've got it right, a PUT body is simply the file without prelude. Do I therefore require that the user specify the mime type in their headers?
  • How do I extend this to large amounts of data? I don't want to read it all into memory since that is highly inefficient. Ideally I'd do what TemporaryUploadFile and related code does - write it part at a time?

I've taken a look at this code sample which tricks Django into handling PUT as a POST request. If I've got it right though, it'll only handle form encoded data. This is REST, so the best solution would be to not assume form encoded data will exist. However, I'm happy to hear appropriate advice on using mime (not multipart) somehow (but the upload should only contain a single file).

Django 1.3 is acceptable. So I can either do something with request.raw_post_data or request.read() (or alternatively some other better method of access). Any ideas?

Django 1.3 is acceptable. So I can either do something with request.raw_post_data or request.read() (or alternatively some other better method of access). Any ideas?

You don't want to be touching request.raw_post_data - that implies reading the entire request body into memory, which if you're talking about file uploads might be a very large amount, so request.read() is the way to go. You can do this with Django <= 1.2 as well, but it means digging around in HttpRequest to figure out the the right way to use the private interfaces, and it's a real drag to then ensure your code will also be compatible with Django >= 1.3.

I'd suggest that what you want to do is to replicate the existing file upload behaviour parts of the MultiPartParser class:

  1. Retrieve the upload handers from request.upload_handlers (Which by default will be MemoryFileUploadHandler & TemporaryFileUploadHandler)
  2. Determine the request's content length (Search of Content-Length in HttpRequest or MultiPartParser to see the right way to do this.)
  3. Determine the uploaded file's filename, either by letting the client specify this using the last path part of the url, or by letting the client specify it in the "filename=" part of the Content-Disposition header.
  4. For each handler, call handler.new_file with the relevant args (mocking up a field name)
  5. Read the request body in chunks using request.read() and calling handler.receive_data_chunk() for each chunk.
  6. For each handler call handler.file_complete(), and if it returns a value, that's the uploaded file.

How can I deduce the mime type of what is being sent? If I've got it right, a PUT body is simply the file without prelude. Do I therefore require that the user specify the mime type in their headers?

Either let the client specify it in the Content-Type header, or use python's mimetype module to guess the media type.

I'd be interested to find out how you get on with this - it's something I've been meaning to look into myself, be great if you could comment to let me know how it goes!


Edit by Ninefingers as requested, this is what I did and is based entirely on the above and the django source.

upload_handlers = request.upload_handlers
content_type   = str(request.META.get('CONTENT_TYPE', ""))
content_length = int(request.META.get('CONTENT_LENGTH', 0))

if content_type == "":
    return HttpResponse(status=400)
if content_length == 0:
    # both returned 0
    return HttpResponse(status=400)

content_type = content_type.split(";")[0].strip()
try:
    charset = content_type.split(";")[1].strip()
except IndexError:
    charset = ""

# we can get the file name via the path, we don't actually
file_name = path.split("/")[-1:][0]
field_name = file_name

Since I'm defining the API here, cross browser support isn't a concern. As far as my protocol is concerned, not supplying the correct information is a broken request. I'm in two minds as to whether I want say image/jpeg; charset=binary or if I'm going to allow non-existent charsets. In any case, I'm putting setting Content-Type validly as a client-side responsibility.

Similarly, for my protocol, the file name is passed in. I'm not sure what the field_name parameter is for and the source didn't give many clues.

What happens below is actually much simpler than it looks. You ask each handler if it will handle the raw input. As the author of the above states, you've got MemoryFileUploadHandler & TemporaryFileUploadHandler by default. Well, it turns out MemoryFileUploadHandler will when asked to create a new_file decide whether it will or not handle the file (based on various settings). If it decides it's going to, it throws an exception, otherwise it won't create the file and lets another handler take over.

I'm not sure what the purpose of counters was, but I've kept it from the source. The rest should be straightforward.

counters = [0]*len(upload_handlers)

for handler in upload_handlers:
    result = handler.handle_raw_input("",request.META,content_length,"","")

for handler in upload_handlers:

    try:
        handler.new_file(field_name, file_name, 
                         content_type, content_length, charset)
    except StopFutureHandlers:
        break

for i, handler in enumerate(upload_handlers):
    while True:
        chunk = request.read(handler.chunk_size)
        if chunk:

            handler.receive_data_chunk(chunk, counters[i])
            counters[i] += len(chunk)
        else:
            # no chunk
            break

for i, handler in enumerate(upload_handlers):
    file_obj = handler.file_complete(counters[i])
    if not file_obj:
        # some indication this didn't work?
        return HttpResponse(status=500) 
    else:
        # handle file obj!

Launching an Android Emulator from Python-Django

4 votes
def start_test(request):
    os.system('echo Starting emulator...')
    os.system('./android-sdk-linux_x86/tools/emulator -avd testavd &')
    return HttpResponse("OK")

Here is the barebones code of what I am trying to do.
When this code gets executed, the server stops responding while running the emulator. Any help appreciated.
I am using the django development server. Here is the server output:

Django version 1.1.1, using settings 'Cloust.settings'
Development server is running at http://0.0.0.0:8000/
Quit the server with CONTROL-C.
Starting emulator...
[21/Apr/2011 02:00:06] "GET /start_test/a.apk/ HTTP/1.1" 200 5
emulator: warning: opening audio output failed

emulator: emulator window was out of view and was recentred

I still haven't gotten around to properly solving this problem, but using subprocess.Popen allows me to perform commands on the emulator afterwards:

print 'Starting emulator...'
subprocess.Popen(['emulator', '-avd', 'testavd'])
os.system('adb wait-for-device')
os.system('Perform whatever adb commands you need')

It's worth noting that this is using the django development server, which has been started using sudo, so obviously this is far from ideal.

How do I redirect Django commands using PyDev?

4 votes

I would like to run the following Django command (to dump the contents of my database into a text file):

python manage.py dumpdata my_app > data.json

I'm using the Django framework within PyDev as an Eclipse plugin. Therefore, in order to run the above command in PyDev I go to "Custom command" and insert dumpdata my_app > data.json. However, doing so results in an error because of the > character:

Error: Unknown application: >

How can I use > (redirection) in PyDev?

  1. Open Eclipse and go to menu Run > Run configurations
  2. Click on Pydev Django and then the "New" icon to create a new launch configuration
  3. Tab main: select the project and main module (manage.py)
  4. Tab interpreter: select which interpreter will run manage.py
  5. Tab arguments: write dumpdata my_app in Program arguments
  6. Tab common: check File in "Standard input and Output" and set your output location and filename. Uncheck "Allocate console".

Finally click on Apply and Run. A bit tricky but works as it should.

Django: 'unique_together' and 'blank=True'

4 votes

I have a Django model which looks like this:

class MyModel(models.Model):
    parent = models.ForeignKey(ParentModel)
    name   = models.CharField(blank=True, max_length=200)
    ... other fields ...

    class Meta:
        unique_together = ("name", "parent")

This works as expected; If there is the same 'name' more than once in the same 'parent' then i get an error: "MyModel with this Name and Parent already exists."

However, i also get an error when i save more than one 'MyModel' with the same 'parent' but with the 'name' field blank, but this should be allowed. So basically i dont want to get the above error when the 'name' field is blank. Is that possible somehow?

Using unique_together, you're telling Django that you don't want any two MyModel instances with the same parent and name attributes -- which applies even when name is an empty string.

This is enforced at the database level using the unique attribute on the appropriate database columns. So to make any exceptions to this behavior, you'll have to avoid using unique_together in your model.

Instead, you can get what you want by overriding the save method on the model and enforcing the unique restraint there. When you try to save an instance of your model, your code can check to see if there are any existing instances that have the same parent and name combination, and refuse to save the instance if there are. But you can also allow the instance to be saved if the name is an empty string. A basic version of this might look like this:

class MyModel(models.Model):
    ...

    def save(self, *args, **kwargs):

        if self.name != '':
            conflicting_instance = MyModel.objects.filter(parent=self.parent, \
                                                          name=self.name)
            if self.id:
                # This instance has already been saved. So we need to filter out
                # this instance from our results.
                conflicting_instance = conflicting_instance.exclude(pk=self.id)

            if conflicting_instance.exists():
                raise Exception('MyModel with this name and parent already exists.')

        super(MyModel, self).save(*args, **kwargs)

Hope that helps.

CSS styling in Django forms

4 votes

How do I style the following:

in forms.py --

from django import forms

class ContactForm(forms.Form):
    subject = forms.CharField(max_length=100)
    email = forms.EmailField(required=False)
    message = forms.CharField(widget=forms.Textarea)

in contact_form.html --

    <form action="" method="post">
        <table>
            {{ form.as_table }}
        </table>
        <input type="submit" value="Submit">
    </form>

For example, how do I set a class or ID for the subject, email, message to provide an external style sheet to? Thank you

Taken from my answer to: How to markup form fields with <div class='field_type'> in Django

class MyForm(forms.Form):
    myfield = forms.CharField(widget=forms.TextInput(attrs={'class' : 'myfieldclass'}))

or

class MyForm(forms.ModelForm):
    class Meta:
        model = MyModel

    def __init__(self, *args, **kwargs):
        super(MyForm, self).__init__(*args, **kwargs)
        self.fields['myfield'].widget.attrs.update({'class' : 'myfieldclass'})

--- EDIT ---
The above is the easiest change to make to original question's code that accomplishes what was asked. It also keeps you from repeating yourself if you reuse the form in other places; your classes or other attributes just work if you use the Django's as_table/as_ul/as_p form methods. If you need full control for a completely custom rendering, this is clearly documented

Deploying matlab app on the web using python

4 votes

Hi I want to deploy a matlab application on the web using python. Is there a way to do it.I have converted my application into jar files (java classes) as per the documentation on math works site. Can someone point me in the right direction to go ahead

The fact that your Matlab code is packaged up as Jars may not help that much here, at least not with pure Python.

There are a few ways you can take code written in Java and expose it to Python.

Jython

If you are willing to give Jython a shot this may be a really easy way to provide a Django interface to your jars.

Basically you'll get to write a normal Django App and also use Jython to work natively with your Jars. This could be the best of both worlds assuming you aren't tied to CPython.

Django-Jython

Java Compatibility Interfaces

On CPYTHON either of the following projects will help you work with the code in your Jar files:

  • JCC: Create a Python extension module that wraps your Jar file
  • JPype: Provides an API for running the JVM and calling into code running in that JVM from Python.

Separate Process:

If you have a standalone program written in Matlab (really any language) you could execute it as a child process of your Django application. You'd look into a simple web form in Django that allowed you to submit values to be inputs to this process and then in your view (after validating the form) you'd do something like:

command = "mymatlabprogram.exe %s"%(arg1,)
process = subprocess.Popen(command.split())
stdout, stderr = process.communicate()

Assuming that worked you could pull answers out of stdout or error messages out of stderr. You could serve an image created by that process, etc. Once something like this is working you could look into celeryd to extract the subprocess stuff from your web app.

The advantage of working with a separate process is that you isolate bugs in your Matlab code from breaking your web application and vice versus. The disadvantage is you have to serialize everything and work with multiple times between the client's browser and your web app, between the web app and the executable, and back to the client.