When you are looking for "separate threads of execution", the threading module becomes your friend...

<pre>from threading import Thread
from datetime import datetime
from collections import namedtuple
from time import sleep

CameraConfig = namedtuple('CameraConfig', 'id armed sensitivity')

theCameras = (CameraConfig(1, 0, 5),
CameraConfig(2, 1, 6),
CameraConfig(3, 0, 2))

class CameraConfigThread(Thread):
def init(self, inCameraConfig):
#Thread.init(self)
super(self.class, self).init() # only works with single inheritance
self.cameraConfig = inCameraConfig

def run(self): theName = self.getName() theURL = 'http://camera{id}.com:8080/set_alarm.cgi?motion_armed={armed}?motion_sensitivity={sensitivity}'.format(**self.cameraConfig._asdict()) fmt = '{} doing {} at {}\n Using URL: {}\n' print(fmt.format(theName, self.cameraConfig, datetime.now(), theURL)) for i in xrange(5): sleep(1) print('{}: i = {}'.format(theName, i))

theThreads = [] # empty list
for theCamera in theCameras:
theThread = CameraConfigThread(theCamera)
theThread.start()
theThreads.append(theThread)
#theThread.join() # calling join() at this point would causes the app to pause until this thread completes before launching the next one. This is NOT what we want.

now that all threads are running pause the app until they all complete

for theThread in theThreads:
if theThread.is_alive():
theThread.join() # pause the main app thread until the thread completes
else:
print('{} is no longer alive at join time.'.format(theThread.getName()))
print('\nAll threads have completed.\n')

fmt = 'Check results using: http://camera{id}.com:8080/get_params.cgi?'
for theCamera in theCameras:
print(fmt.format(**theCamera._asdict()))

print('=' * 60)</pre>