Select to view content in your preferred language

Zip File Script & if __name__ == '__main__':

4155
17
Jump to solution
11-17-2016 01:45 PM
JaredPilbeam1
Occasional Contributor
#11/17/2016
#
#take all of the shapefiles in a directory and compress them into individual zip files
#
#########################################################################################

#import workspace

import arcpy, os
from arcpy import env
from os import path as p
import RemoveAddLayer
import zipfile
arcpy.overwriteOutput = True


def ZipShapes(path, outpath):
    arcpy.env.workspace = path
    shapes = arcpy.ListFeatureClasses()

#iterate through list of shapefiles
    for shape in shapes:
        name = p.splitext(shape)[0]
        print name
        zip_path = p.join(out_path, name + '.zip')
        zip = zipfile.ZipFile(zip_path, 'w', compression=zipfile.ZIP_DEFLATED)
        zip.write(p.join(path,shape), shape)
        for f in arcpy.ListFiles('%s*' %name):
            if not f.endswith('.shp'):
                zip.write(p.join(path,f),f)
        print 'All file written to %s' %zip_path
        zip.close()


if __name__ == '__main__':

    path = r"Z:\Jared\Python Scripts"
    outpath = r"W:\Data"

    ZipShapes(path, outpath)
        ‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

Only a novice at Python. Using ArcMap for Desktop 10.3. My ultimate objective is to send some shapefiles to a zip file using script. I ran the above based on someone's existing script.

1.) What is if __name__ == '__main__': doing in this scenario?

      From what I understand you can use this when importing another Python script? That's why I have the       "RemoveAddLayer" script as an import at the top. I may be completely wrong?

2.) The RemoveAddLayer script (that's imported at the top) is what I created to update Streets and Address Points layers. Should I save these to a folder in the script and then set that as the path variable in the ZipFiles2 script?

There was no error when I ran this but also no file was put into the outpath folder. 

Edit: @Rebecca: Thanks, I took your advice and put the script in instead of the image. 

0 Kudos
17 Replies
JaredPilbeam1
Occasional Contributor

path = r"Z:\Jared\Python Scripts"

That was my mistake. It's meant to be the above path. I had, in fact, set that path to an SDE until I realized it was the wrong path. In the RemoveAddLayer module (used in this script) I have that SDE path as my workspace. 

0 Kudos
JaredPilbeam1
Occasional Contributor

Ok, let me follow up as I'm still not sure how to call another module to this Zipfiles2.py script. 

How can I call RemoveAddLayer.py from Zipfiles2.py? Both of these scripts run correctly. I'm not too worried how sloppy RemoverAddLayer.py might look. My concern is being able to call it while running ZipFiles2.py.

In a nutshell, RemoveAddLayer.py is meant to update the Streets and Address Points layers from the SDE (as I work for local government and these things change once and a while). First, it updates by removing the old layers. Second, it adds new ones straight from the SDE. Third, these are copied to a folder. And then by running ZipFiles.py I can successfully zip them and then save them in our Data folder where they are accessed from our website. 

So, my goal is to bridge the gap and not run these two scripts separately. 

Thanks!

#RemoveAddLayer.py
import arcpy
from arcpy import env

env.workspace = r"Database Connections\ims to plainfield.sde\gisedit.DBO.MGU_Will"

#set path to mxd 
mxd = arcpy.mapping.MapDocument(r"Z:\Jared\Data_Request.mxd")

#reference the dataframe
for df in arcpy.mapping.ListDataFrames(mxd):
    print df
#reference the layers to be removed
    for lyr in arcpy.mapping.ListLayers(mxd, "gisedit.DBO.Address_Points", df):
        arcpy.mapping.RemoveLayer(df, lyr)
        print lyr
        for lyr in arcpy.mapping.ListLayers(mxd, "gisedit.DBO.Street", df):
            arcpy.mapping.RemoveLayer(df, lyr)
            print lyr
#reference the layers to be added
        addLayer = arcpy.mapping.Layer(r"Database Connections\ims to plainfield.sde\gisedit.DBO.MGU_Will\gisedit.DBO.Address_Points")
        arcpy.mapping.AddLayer(df, addLayer, "TOP")
        print addLayer
        addLayer = arcpy.mapping.Layer(r"Database Connections\ims to plainfield.sde\gisedit.DBO.MGU_Will\gisedit.DBO.Street")
        arcpy.mapping.AddLayer(df, addLayer, "TOP")
        print addLayer

#address points variables to be copied/saved in folder
        inFeatures = "gisedit.DBO.Address_Points"
        outLocation = r"Z:\Jared\Python Scripts\Data"
        outFeatureClass = "WillCounty_AddressPoint"

#execute and copy/save in folder. FeatureClassToFeatureClass_conversion syntax (in_features, out_path, out_name,
#       {where_clause}, {field_mapping}, {config_keyword})
        arcpy.FeatureClassToFeatureClass_conversion(inFeatures, outLocation, outFeatureClass)
        print "finished Address_Point.shp"

#variables to be copied/saved in folder
        inFeatures = "gisedit.DBO.Street"
        outLocation = r"Z:\Jared\Python Scripts\Data"
        outFeatureClass = "WillCounty_Street"

#execute and copy/save in folder. FeatureClassToFeatureClass_conversion syntax (in_features, out_path, out_name,
#       {where_clause}, {field_mapping}, {config_keyword})
        arcpy.FeatureClassToFeatureClass_conversion(inFeatures, outLocation, outFeatureClass)
        print "finished Street.shp"
#ZipFiles2.py
#import workspace
import arcpy
import os
from arcpy import env
from os import path as p
import zipfile
arcpy.overwriteOutput = True


def ZipShapes(path, out_path):
    arcpy.env.workspace = path
    shapes = arcpy.ListFeatureClasses()

#iterate through list of shapefiles
    for shapes in shapes:
        name = p.splitext(shapes)[0]
        print name
        print shapes
        zip_path = p.join(out_path, name + '.zip')
        zip = zipfile.ZipFile(zip_path, 'w', compression=zipfile.ZIP_DEFLATED)
        zip.write(p.join(path,shapes), shapes)
        for f in arcpy.ListFiles('%s*' %name):
            if not f.endswith('.shp'):
                zip.write(p.join(path,f),f)
        print 'All file written to %s' %zip_path
        zip.close()
         

if __name__ == '__main__':

    path = r"Z:\Jared\Python Scripts\Data"
    
    out_path = r"W:\Data"

    ZipShapes(path, out_path)
0 Kudos
RebeccaStrauch__GISP
MVP Emeritus

My take....I would make RemoveAddLayer   your main script, including moveing wrapping it in the '__main__" section.  Then you cou either just keep the ZipShapes function in the same file (above the __main__ is ok), or

from ZipFiles2 import *
and then you should be able to call it. Note: I have not tested or looked at it in detail, but a quick glance, that is how I would approach it.
JaredPilbeam1
Occasional Contributor

Thanks Rebecca,

.I would make RemoveAddLayer   your main script, including moveing wrapping it in the '__main__" section. 

So, how is this done exactly? I'm unsure where to put this and how the syntax looks. And by going this route I should also remove lines 36-42 from ZipFiles2, correct?

0 Kudos
DarrenWiens2
MVP Honored Contributor

You don't need to include a '__main__' section in the main script (although it is good practice), nor remove the '__main__' from an imported script (I think this might actually not be good practice).

Why you don't need a '__main__' section: when you call your script, it is read from top to bottom, executing lines as it goes. If you know that script will always be the main script (i.e. not imported as a module) then it will execute as if everything was wrapped within a '__main__' section - you just skip the part where it confirms that it is indeed the main script. The problem arises when you want different behaviour between the script as run as a main script and when it's imported. Making Python scripts modular is good practice, although to be honest, I never do it.

Why you don't need to remove the '__main__' section from the imported script: since you're importing the module, it will not be named '__main__' so that section will not execute.

JaredPilbeam1
Occasional Contributor

Ok, thanks all! It ran. 

It ran correctly after putting the '__main__' section at the bottom of the RemoveAddLayer.py and erasing it from ZipFiles2. Then, after reading your response, Darren, I put the '__main__' section back where it was in ZipFiles2 and it also ran correctly. 

Here are both scripts. 

#RemoveAddLayer.py

import arcpy
from arcpy import env

env.workspace = r"Database Connections\ims to plainfield.sde\gisedit.DBO.MGU_Will"

#set path to mxd 
mxd = arcpy.mapping.MapDocument(r"Z:\Jared\Data_Request.mxd")

#reference the dataframe
for df in arcpy.mapping.ListDataFrames(mxd):
    print df
#reference the layers to be removed
    for lyr in arcpy.mapping.ListLayers(mxd, "gisedit.DBO.Address_Points", df):
        arcpy.mapping.RemoveLayer(df, lyr)
        print lyr
        for lyr in arcpy.mapping.ListLayers(mxd, "gisedit.DBO.Street", df):
            arcpy.mapping.RemoveLayer(df, lyr)
            print lyr
#reference the layers to be added
        addLayer = arcpy.mapping.Layer(r"Database Connections\ims to plainfield.sde\gisedit.DBO.MGU_Will\gisedit.DBO.Address_Points")
        arcpy.mapping.AddLayer(df, addLayer, "TOP")
        print addLayer
        addLayer = arcpy.mapping.Layer(r"Database Connections\ims to plainfield.sde\gisedit.DBO.MGU_Will\gisedit.DBO.Street")
        arcpy.mapping.AddLayer(df, addLayer, "TOP")
        print addLayer

#address points variables to be copied/saved in folder
        inFeatures = "gisedit.DBO.Address_Points"
        outLocation = r"Z:\Jared\Python Scripts\Data"
        outFeatureClass = "WillCounty_AddressPoint"

#execute and copy/save in folder. FeatureClassToFeatureClass_conversion syntax (in_features, out_path, out_name,
#       {where_clause}, {field_mapping}, {config_keyword})
        arcpy.FeatureClassToFeatureClass_conversion(inFeatures, outLocation, outFeatureClass)
        print "finished Address_Point.shp"

#variables to be copied/saved in folder
        inFeatures = "gisedit.DBO.Street"
        outLocation = r"Z:\Jared\Python Scripts\Data"
        outFeatureClass = "WillCounty_Street"

#execute and copy/save in folder. FeatureClassToFeatureClass_conversion syntax (in_features, out_path, out_name,
#       {where_clause}, {field_mapping}, {config_keyword})
        arcpy.FeatureClassToFeatureClass_conversion(inFeatures, outLocation, outFeatureClass)
        print "finished Street.shp"

if __name__ == '__main__':

    path = r"Z:\Jared\Python Scripts\Data"
    
    out_path = r"W:\Data"

    ZipShapes(path, out_path)‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
#ZipFiles2.py
#import workspace
import arcpy
import os
from arcpy import env
from os import path as p
import zipfile
arcpy.overwriteOutput = True


def ZipShapes(path, out_path):
    arcpy.env.workspace = path
    shapes = arcpy.ListFeatureClasses()

#iterate through list of shapefiles
    for shapes in shapes:
        name = p.splitext(shapes)[0]
        print name
        print shapes
        zip_path = p.join(out_path, name + '.zip')
        zip = zipfile.ZipFile(zip_path, 'w', compression=zipfile.ZIP_DEFLATED)
        zip.write(p.join(path,shapes), shapes)
        for f in arcpy.ListFiles('%s*' %name):
            if not f.endswith('.shp'):
                zip.write(p.join(path,f),f)
        print 'All file written to %s' %zip_path
        zip.close()

if __name__ == '__main__':
    
    path = r"Z:\Jared\Python Scripts\Data"
    
    out_path = r"W:\Data"

    ZipShapes(path, out_path)
0 Kudos
RebeccaStrauch__GISP
MVP Emeritus

Good info Darren.  I do make a lot of my tools modular since I reuse many of the functions...and trying to keep my main program readable.    I've never included a  __main__ in my scripts with just a bunch of functions, but may tr i...although typically they are just a list of function definitions.

0 Kudos
DanPatterson_Retired
MVP Emeritus

in my post way up top, I provided a link to  There are some examples in the poll discussion