diff --git a/graphics/EventDisplaysOnline/CMakeLists.txt b/graphics/EventDisplaysOnline/CMakeLists.txt
index 61276e574b98c9c1da2751200f35155ad16affac..b5650338bb96ab0ca024321a6f441d90d5ea77a3 100644
--- a/graphics/EventDisplaysOnline/CMakeLists.txt
+++ b/graphics/EventDisplaysOnline/CMakeLists.txt
@@ -1,12 +1,10 @@
-################################################################################
-# Package: EventDisplaysOnline
-################################################################################
+# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 
 # Declare the package name:
 atlas_subdir( EventDisplaysOnline )
 
 # Install files from the package:
-atlas_install_python_modules( python/*.py )
+atlas_install_python_modules( python/*.py POST_BUILD_CMD ${ATLAS_FLAKE8} )
 atlas_install_joboptions( share/*.py )
 atlas_install_scripts( scripts/*.sh )
 
diff --git a/graphics/EventDisplaysOnline/python/EventDisplaysConfig.py b/graphics/EventDisplaysOnline/python/EventDisplaysConfig.py
index 7cc319be95ae9bdf7ee6f9532064b5741b1cda19..2d9f46b56b3297a25e228f13dd45de1a198ea687 100644
--- a/graphics/EventDisplaysOnline/python/EventDisplaysConfig.py
+++ b/graphics/EventDisplaysOnline/python/EventDisplaysConfig.py
@@ -1,7 +1,5 @@
 # Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 
-from __future__ import print_function
-
 def GetRunType():
   """Get the run type by reading the run-type setting in the partition from IS """
 
@@ -15,9 +13,9 @@ def GetRunType():
     partition = os.environ['TDAQ_PARTITION']
   except KeyError :
     partition = "ATLAS"
-    mlog.warning("TDAQ_PARTITION not defined in environment, using %s as default"%partition)
+    mlog.warning("TDAQ_PARTITION not defined in environment, using %s as default", partition)
   
-  mlog.debug('Probing partition %s for RunType'%partition)
+  mlog.debug('Probing partition %s for RunType', partition)
 
   #now try and read the information from IS
   try :
@@ -30,14 +28,14 @@ def GetRunType():
     mlog.error(err)
     #Set the default runtype
     runType="collisions"
-    mlog.warning("Failed to read run type from IS, using %s as default"%runType)
+    mlog.warning("Failed to read run type from IS, using %s as default", runType)
   finally :
-    if not runType in ['collisions','singlebeam','cosmics']:
-      mlog.fatal("Invalid run type: %s"%runType)
+    if runType not in ['collisions','singlebeam','cosmics']:
+      mlog.fatal("Invalid run type: %s", runType)
       import sys
       sys.exit(1)
 
-  mlog.info("Setting run type to: %s"%runType)
+  mlog.info("Setting run type to: %s", runType)
   return runType
 
 def GetBFields():
@@ -48,16 +46,16 @@ def GetBFields():
 
   #BFields are read from initial partition
   partition='initial'
-  mlog.debug("Trying to read magnetic field configuration from partition %s"%partition)
+  mlog.debug("Trying to read magnetic field configuration from partition %s", partition)
 
   #now try and read the information from IS
   try :
     from ipc import IPCPartition
     from ispy import ISObject
     #Get hold of the initial partition
-    ipcPart = IPCPartition(partition);
+    ipcPart = IPCPartition(partition)
     if not ipcPart.isValid():
-      raise UserWarning("Partition %s invalid - cannot access magnetic field setting"%partition);
+      raise UserWarning("Partition %s invalid - cannot access magnetic field setting"%partition)
     #Get the current and valid status
     toroidCurrent = ISObject(ipcPart,'DCS_GENERAL.MagnetToroidsCurrent.value','DdcFloatInfo')
     solenoidCurrent = ISObject(ipcPart,'DCS_GENERAL.MagnetSolenoidCurrent.value','DdcFloatInfo')
@@ -78,8 +76,8 @@ def GetBFields():
     sys.exit(1)
 
   #print the result
-  mlog.info("Magnetic field in solenoid is %s" % ((solenoidOn and "ON") or "OFF"))
-  mlog.info("Magnetic field in toroid is %s" % ((toroidOn and "ON") or "OFF"))
+  mlog.info("Magnetic field in solenoid is %s", (solenoidOn and "ON") or "OFF")
+  mlog.info("Magnetic field in toroid is %s", (toroidOn and "ON") or "OFF")
 
   #finally return our values
   return (solenoidOn,toroidOn)
diff --git a/graphics/EventDisplaysOnline/python/EventUtils.py b/graphics/EventDisplaysOnline/python/EventUtils.py
index d7e8796e3b1964b8d7f0adfc2b5c3b1e5609d722..89f09777b939cc8d5385cb120f0e0f25f8977935 100644
--- a/graphics/EventDisplaysOnline/python/EventUtils.py
+++ b/graphics/EventDisplaysOnline/python/EventUtils.py
@@ -11,7 +11,7 @@ def getEventlist(msg, directory):
 
 	# Build a list of files ordered by run/event number
 	for file in files:
-		matches = re.search('(?:JiveXML|vp1)_(\d+)_(\d+)(?:\.xml|_.+\.pool\.root)', file)
+		matches = re.search(r'(?:JiveXML|vp1)_(\d+)_(\d+)(?:\.xml|_.+\.pool\.root)', file)
 
 		# Event file, add tot the list
 		if matches:
@@ -27,11 +27,11 @@ def getEventlist(msg, directory):
 			# If the file is recent, it might be from another thread... delete after 5 minutes
 			try:
 				if time.time() - os.path.getmtime(file) > 300:
-					msg.info("File '%s' does not belong in the output directory, removing it." % file)
+					msg.info("File '%s' does not belong in the output directory, removing it.", file)
 					try:
 						os.unlink("%s/%s" % (directory, file))
 					except OSError as err:
-						msg.warning("Could not remove '%s': %s" % (file, err))
+						msg.warning("Could not remove '%s': %s", file, err)
 			except OSError:
 				# File was probably a temp file from another thread that already disappeared
 				pass
@@ -61,7 +61,7 @@ def getEventlist(msg, directory):
 			eventlist.append(evententry)
 			i = i + 1
 
-	return eventlist;
+	return eventlist
 
 # Prune events in the given directory if the number exceeds the specified number
 def pruneEvents(msg, directory, maxevents, eventlist):
@@ -72,15 +72,15 @@ def pruneEvents(msg, directory, maxevents, eventlist):
 	if numevents > maxevents:
 		for i in range(numevents-maxevents):
 			run, event, atlantis, vp1 = eventlist.pop(0)
-			msg.debug("Going to prune files %s and %s for run %s and event %s." % (atlantis, vp1, run, event))
+			msg.debug("Going to prune files %s and %s for run %s and event %s.", atlantis, vp1, run, event)
 			try:
 				os.unlink("%s/%s" % (directory, atlantis))
 				os.unlink("%s/%s" % (directory, vp1))
 			except OSError as err:
-				msg.warning("Could not remove files for run %s, event %s: %s" % (run, event, err))
+				msg.warning("Could not remove files for run %s, event %s: %s", run, event, err)
 
 	else:
-		msg.debug("Nothing to prune (%d <= %d)." % (numevents, maxevents))
+		msg.debug("Nothing to prune (%d <= %d).", numevents, maxevents)
 
 # Build the event.list file that is used by atlas-live.cern.ch for synchronizing events
 def writeEventlist(msg, directory, eventlist):
@@ -91,13 +91,13 @@ def writeEventlist(msg, directory, eventlist):
 			file.write("run:%s,event:%s,atlantis:%s,vp1:%s\n" % (run, event, atlantis, vp1))
 		file.close()
 	except IOError as err:
-		msg.warning("Could not write event list: %s" % err)
+		msg.warning("Could not write event list: %s", err)
 
 	# Rename for an atomic overwrite operation
 	try:
 		os.rename("%s/event.%d" % (directory, pid), "%s/event.list" % directory)
 	except OSError as err:
-		msg.warning("Could not rename event.%d to event.list: %s" % (pid, err))
+		msg.warning("Could not rename event.%d to event.list: %s", pid, err)
 
 # Perform all of these in one command
 def cleanDirectory(msg, directory, maxevents):
diff --git a/graphics/EventDisplaysOnline/python/OnlineEventDisplaysSvc.py b/graphics/EventDisplaysOnline/python/OnlineEventDisplaysSvc.py
index cc346df573366f256eed74623953f4f94e1fd7c0..8a8d621eabed73edd210ed61a01915eef6cf9e32 100644
--- a/graphics/EventDisplaysOnline/python/OnlineEventDisplaysSvc.py
+++ b/graphics/EventDisplaysOnline/python/OnlineEventDisplaysSvc.py
@@ -1,7 +1,5 @@
 # Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 
-from __future__ import print_function
-
 __doc__ = """This service runs in the online Athena event display threads. It
 manages the distribution of incoming events to the right event display streams.
 In order to do that it connects to the different Atlantis and VP1 event output
@@ -63,9 +61,9 @@ class OnlineEventDisplaysSvc( PyAthena.Svc ):
 		vp1alg = PyAthena.py_alg('VP1EventProd')
 		self.VP1EventProducer = InterfaceCast(gbl.IProperty).cast(vp1alg)
 
-		self.msg.info("StreamToFileTool: %s" % self.StreamToFileTool)
-		self.msg.info("StreamToServerTool: %s" % self.StreamToServerTool)
-		self.msg.info("VP1EventProducer: %s" % self.VP1EventProducer)
+		self.msg.info("StreamToFileTool: %s", self.StreamToFileTool)
+		self.msg.info("StreamToServerTool: %s", self.StreamToServerTool)
+		self.msg.info("VP1EventProducer: %s", self.VP1EventProducer)
 
 	def beginEvent(self):
 		if not (self.StreamToFileTool and self.StreamToServerTool and self.VP1EventProducer):
@@ -74,7 +72,7 @@ class OnlineEventDisplaysSvc( PyAthena.Svc ):
 		try:
 			eventInfo = PyEventTools.getEventInfo('EventInfo')
 		except LookupError as err:
-			self.msg.error("Could not retrieve EventInfo: %s" % err)
+			self.msg.error("Could not retrieve EventInfo: %s", err)
 			return StatusCode.Recoverable
 
 		try:
@@ -85,7 +83,7 @@ class OnlineEventDisplaysSvc( PyAthena.Svc ):
 			# Retrieve trigger info
 			streamTags = eventInfo.streamTags()
 		except Exception as err:
-			self.msg.error("Exception occured while reading event/trigger info: %s" % err)
+			self.msg.error("Exception occured while reading event/trigger info: %s", err)
 			return StatusCode.Recoverable
 
 		# Retrieve the physics stream names from the trigger info
@@ -94,7 +92,7 @@ class OnlineEventDisplaysSvc( PyAthena.Svc ):
 			
 			## Added 08/03/15 - sjiggins - Wanted to see if events had physics stream tag or was from random trigger
 			if tag.name():
-				self.msg.debug("Event %d/%d has the corresponding streamTags: %s" % (self.run, self.event, tag.type()))
+				self.msg.debug("Event %d/%d has the corresponding streamTags: %s", self.run, self.event, tag.type())
 			##################################################################################
 			if tag.type() == 'express' and tag.name():
 				streams += [tag.type()+'_'+tag.name()]
@@ -118,14 +116,14 @@ class OnlineEventDisplaysSvc( PyAthena.Svc ):
 					if physicsReady.ready4physics and runparams.T0_project_tag in self.projecttags:
 						streams += ['Public']
 					else:
-						self.msg.debug("RunParams.Ready4Physics is not set, run number is not set, or T0_project_tag is not set to any of %s" % ", ".join(self.projecttags))
+						self.msg.debug("RunParams.Ready4Physics is not set, run number is not set, or T0_project_tag is not set to any of %s", ", ".join(self.projecttags))
 						break
 		except Exception as err:
-			self.msg.error("Exception occured while reading RunParams.Ready4Physics: %s" % err)
+			self.msg.error("Exception occured while reading RunParams.Ready4Physics: %s", err)
 
 		# Randomize list of streams
 		random.shuffle(streams)
-		self.msg.debug("Event %d/%d has event display stream tags: %s" % (self.run, self.event, ", ".join(streams)))
+		self.msg.debug("Event %d/%d has event display stream tags: %s", self.run, self.event, ", ".join(streams))
 
 		# Start from the beginning and send the event to the first stream that passes our directory checks
 		self.directory = ''
@@ -133,20 +131,20 @@ class OnlineEventDisplaysSvc( PyAthena.Svc ):
 			self.directory = "%s/%s" % (self.output, self.stream)
 			if os.access(self.directory, os.F_OK):
 				if os.path.isdir(self.directory) and os.access(self.directory, os.W_OK):
-					self.msg.debug("Going to write file to existing directory: %s" % self.directory)
+					self.msg.debug("Going to write file to existing directory: %s", self.directory)
 					if os.stat(self.directory).st_gid != self.DQMgid:
-						self.msg.debug("Setting group to 'DQM' for directory: %s" % self.directory)
+						self.msg.debug("Setting group to 'DQM' for directory: %s", self.directory)
 						os.chown(self.directory, -1, self.DQMgid)
 					break
 				else:
-					self.msg.warning("Directory \'%s\' is not usable, trying next alternative" % self.directory)
+					self.msg.warning("Directory \'%s\' is not usable, trying next alternative", self.directory)
 					self.directory = ''
 			else:
 				try:
 					os.mkdir(self.directory)
 					os.chmod(self.directory, stat.S_IRWXU | stat.S_IRWXG | stat.S_IROTH | stat.S_IXOTH)
 					os.chown(self.directory, -1, self.DQMgid)
-					self.msg.info("Created output directory \'%s\' for stream \'%s\'" % (self.directory, self.stream))
+					self.msg.info("Created output directory \'%s\' for stream \'%s\'", self.directory, self.stream)
 					break
 				except OSError as err:
 					self.msg.warning("Failed to create output directory \'%s\' for stream \'%s\': %s", (self.directory, self.stream, err.strerror))
@@ -154,7 +152,7 @@ class OnlineEventDisplaysSvc( PyAthena.Svc ):
 
 		# Check if a suitable directory was found
 		if self.directory:
-			self.msg.debug("Event %d/%d will be streamed to: %s" % (self.run, self.event, self.stream))
+			self.msg.debug("Event %d/%d will be streamed to: %s", self.run, self.event, self.stream)
 		else:
 			# This event is hopelessly lost, send StatusCode.Recoverable in an attempt to abort.
 			# But if Athena chooses to ignore that, set the output to the "Unknown" trashcan stream.
@@ -168,7 +166,7 @@ class OnlineEventDisplaysSvc( PyAthena.Svc ):
 			# And also for the VP1 event producer algorithm
 			#self.VP1EventProducer.getProperty('DestinationDirectory').setValue(self.directory) # lshi June 22 2020
 		except Exception as err:
-			self.msg.error("Exception occured while setting job options: %s" % err)
+			self.msg.error("Exception occured while setting job options: %s", err)
 			return StatusCode.Failure
 
 		if not self.directory:
diff --git a/graphics/EventDisplaysOnline/python/PruneAlg.py b/graphics/EventDisplaysOnline/python/PruneAlg.py
index 539c275cdae2ab25edd27a7dabdc0b3230670eb4..41dfdbf56dea2449b15b1da01ad70c2afdc528c0 100755
--- a/graphics/EventDisplaysOnline/python/PruneAlg.py
+++ b/graphics/EventDisplaysOnline/python/PruneAlg.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
+# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 
 __doc__ = """Algorithm for pruning eventdisplay files
 """
@@ -19,7 +19,7 @@ class PruneAlg( PyAthena.Alg ):
 		self.numevents = kw.get("NumberOfEvents", 250)
 	
 	def initialize(self):
-		self.msg.debug("Going to prune %s, keeping %d events" % (self.directory, self.numevents))
+		self.msg.debug("Going to prune %s, keeping %d events", self.directory, self.numevents)
 		return StatusCode.Success
 
 	def execute(self):