Package: glasswall
Glasswall Python WrapperA high level Python wrapper for interfacing with Glasswall libraries.InstallationInstall or upgrade to the latest version via pip:Online installationpip install --upgrade glasswallOffline installation for CentOS 7 and RHEL8Run the following commands within the directory containing the offline installation files.pip install --upgrade --no-index --find-links=. glasswallNote:The lxml wheel includes the required lxml dependencies and has been tested on CentOS 7 and RHEL8 environments.PrerequisitesPython >= 3.6Auto-generated Documentationhttps://gw-engineering.github.io/glasswall-python-wrapper/ExamplesLoading a Glasswall libraryLoggingContent management policiesEditorProtectProtect from file path to file pathProtect from file path to memoryProtect from memoryProtect files in a directoryProtect files in a directory that may contain unsupported file typesProtect files in a directory using a custom content management policyProtect files in a directory conditionally based on file formatAnalysisAnalyse from file path to file pathAnalyse from file path to memoryAnalyse from memoryAnalyse files in a directoryAnalyse files in a directory that may contain unsupported file typesAnalyse files in a directory using a custom content management policyAnalyse files in a directory conditionally based on file formatExportExport from file path to file pathExport from file path to memoryExport from memoryExport files in a directoryExport files in a directory that may contain unsupported file typesExport files in a directory using a custom content management policyExport files in a directory conditionally based on file formatImportImport from file path to file pathImport from file path to memoryImport from memoryImport files in a directoryImport files in a directory that may contain unsupported file typesImport files in a directory using a custom content management policyImport files in a directory conditionally based on file formatRebuildArchive ManagerProtect an archiveProtect all archives in a directory using a custom content management policyExtraction - Unpacking an archiveOther useful arguments when unpackingExtraction - Unpacking a directory of archivesCompression - Packing a directory into an archiveWordSearchRedactRedact from file path to file pathRedact from file path to memoryRedact from memoryRedact files in a directoryRedact files in a directory that may contain unsupported file typesRedact files in a directory conditionally based on file formatLoading a Glasswall libraryEach library is a subclass of theglasswall.libraries.library.Libraryclass and can be accessed from the top level of theglasswallmodule. The following subclasses are available:ArchiveManagerEditorRebuildSecurityTaggingWordSearchLibraries are loaded on initialisation and have one required argument:library_pathwhich can be the path to a file or a directory. If a directory is specified it is recursively searched and the library with the latest change time will be loaded.importglasswall# Load the Glasswall Editor libraryeditor=glasswall.Editor(r"C:\gwpw\libraries\embedded_engine_release_5.3")>>> 2021-03-15 12:27:42.337 glasswall INFO     __init__                  Loaded Glasswall Editor version 2.173 from C:\gwpw\libraries\sdk.editor\windows-drop-no-kill-switch\glasswall_core2.dllLoggingLogs are saved to the temp directory and are also output to console with a default logging level of INFO. You can view the file path of the temp directory or the log file:importglasswallprint(glasswall._TEMPDIR)print(glasswall.config.logging.log_file_path)>>> C:\Users\ANGUSR~1\AppData\Local\Temp\glasswall
>>> C:\Users\ANGUSR~1\AppData\Local\Temp\glasswall\logs\2021-03-15 122826.txtThe logging level can be modified, for a list of levels see:https://docs.python.org/3/library/logging.html#logging-levelsimportloggingimportglasswall# Modify logging level for logs to the consoleglasswall.config.logging.console.setLevel(logging.DEBUG)# Modify logging level for logs to fileglasswall.config.logging.log.setLevel(logging.DEBUG)Content management policiesDocumentation about content management policies can be found on thePolicy Managementpage.Subclasses of theglasswall.content_management.policies.Policyclass can be used to easily create content management policies of varying complexity by passing thedefaultandconfigkeyword arguments. Subclasses include:ArchiveManagerEditorRebuildWordSearchSome examples of content management policies are below. Note that if a content management policy is required but has not been specified with the keyword argumentcontent_management_policythen the default content management policy will be used.Content management policies can be specified using subclasses of thePolicyclass:Expand setting an Editor policyimportglasswall# Load the Glasswall Editor libraryeditor=glasswall.Editor(r"C:\gwpw\libraries\embedded_engine_release_5.3")editor.protect_directory(input_directory=r"C:\gwpw\input",output_directory=r"C:\input_sanitised",content_management_policy=glasswall.content_management.policies.Editor(default="sanitise"))...or loaded from a file path:Expand setting an Editor policy from file pathimportglasswall# Load the Glasswall Editor libraryeditor=glasswall.Editor(r"C:\gwpw\libraries\embedded_engine_release_5.3")editor.protect_directory(input_directory=r"C:\gwpw\input",output_directory=r"C:\input_sanitised",content_management_policy=r"C:\gwpw\configs\config.xml")Some examples of policies and how to create them using the Policy subclasses are shown below.Expand Editor default sanitise all policyimportglasswall# Print the default Editor content management policyprint(glasswall.content_management.policies.Editor(default="sanitise"))<?xml version="1.0" encoding="utf-8"?><config><pdfConfig><acroform>sanitise</acroform><actions_all>sanitise</actions_all><digital_signatures>sanitise</digital_signatures><embedded_files>sanitise</embedded_files><embedded_images>sanitise</embedded_images><external_hyperlinks>sanitise</external_hyperlinks><internal_hyperlinks>sanitise</internal_hyperlinks><javascript>sanitise</javascript><metadata>sanitise</metadata></pdfConfig><pptConfig><embedded_files>sanitise</embedded_files><embedded_images>sanitise</embedded_images><external_hyperlinks>sanitise</external_hyperlinks><internal_hyperlinks>sanitise</internal_hyperlinks><javascript>sanitise</javascript><macros>sanitise</macros><metadata>sanitise</metadata><review_comments>sanitise</review_comments></pptConfig><sysConfig><interchange_pretty>false</interchange_pretty><interchange_type>sisl</interchange_type></sysConfig><tiffConfig><geotiff>sanitise</geotiff></tiffConfig><wordConfig><dynamic_data_exchange>sanitise</dynamic_data_exchange><embedded_files>sanitise</embedded_files><embedded_images>sanitise</embedded_images><external_hyperlinks>sanitise</external_hyperlinks><internal_hyperlinks>sanitise</internal_hyperlinks><macros>sanitise</macros><metadata>sanitise</metadata><review_comments>sanitise</review_comments></wordConfig><xlsConfig><dynamic_data_exchange>sanitise</dynamic_data_exchange><embedded_files>sanitise</embedded_files><embedded_images>sanitise</embedded_images><external_hyperlinks>sanitise</external_hyperlinks><internal_hyperlinks>sanitise</internal_hyperlinks><macros>sanitise</macros><metadata>sanitise</metadata><review_comments>sanitise</review_comments></xlsConfig></config>Expand Rebuild custom allow all policyimportglasswall# Print a custom Rebuild content management policy with a default of allow# that only sanitises macros in wordConfig, and embedded images and files in# xlsConfigprint(glasswall.content_management.policies.Rebuild(default="allow",config={"wordConfig":{"macros":"sanitise",},"xlsConfig":{"embedded_files":"sanitise","embedded_images":"sanitise",},}))<?xml version="1.0" encoding="utf-8"?><config><pdfConfig><acroform>allow</acroform><actions_all>allow</actions_all><digital_signatures>allow</digital_signatures><embedded_files>allow</embedded_files><embedded_images>allow</embedded_images><external_hyperlinks>allow</external_hyperlinks><internal_hyperlinks>allow</internal_hyperlinks><javascript>allow</javascript><metadata>allow</metadata></pdfConfig><pptConfig><embedded_files>allow</embedded_files><embedded_images>allow</embedded_images><external_hyperlinks>allow</external_hyperlinks><internal_hyperlinks>allow</internal_hyperlinks><javascript>allow</javascript><macros>allow</macros><metadata>allow</metadata><review_comments>allow</review_comments></pptConfig><sysConfig><default>allow</default><interchange_pretty>false</interchange_pretty><interchange_type>sisl</interchange_type></sysConfig><tiffConfig><geotiff>allow</geotiff></tiffConfig><wordConfig><dynamic_data_exchange>allow</dynamic_data_exchange><embedded_files>allow</embedded_files><embedded_images>allow</embedded_images><external_hyperlinks>allow</external_hyperlinks><internal_hyperlinks>allow</internal_hyperlinks><macros>sanitise</macros><metadata>allow</metadata><review_comments>allow</review_comments></wordConfig><xlsConfig><dynamic_data_exchange>allow</dynamic_data_exchange><embedded_files>sanitise</embedded_files><embedded_images>sanitise</embedded_images><external_hyperlinks>allow</external_hyperlinks><internal_hyperlinks>allow</internal_hyperlinks><macros>allow</macros><metadata>allow</metadata><review_comments>allow</review_comments></xlsConfig></config>Elements within a content management policy may have attributes. Attributes can be set by prefixing a key with the@character. In the below example therecursionDepthattribute is set with a value of"30".Expand Archive Manager custom recursionDepth policyimportglasswall# Print a custom Archive Manager content management policy with a default of# sanitise and an archive default of process. Set the recursionDepth attribute# to 30. Discard any bmp files in the archive.print(glasswall.content_management.policies.ArchiveManager(default="sanitise",default_archive_manager="process",config={"archiveConfig":{"@recursionDepth":"30","bmp":"discard",}}))<?xml version="1.0" encoding="utf-8"?><config><archiveConfigdefaultCompression="zip"libVersion="core2"recursionDepth="30"><bmp>discard</bmp><doc>process</doc><docx>process</docx><elf>process</elf><emf>process</emf><gif>process</gif><jpeg>process</jpeg><mp3>process</mp3><mp4>process</mp4><mpg>process</mpg><o>process</o><pdf>process</pdf><pe>process</pe><png>process</png><ppt>process</ppt><pptx>process</pptx><tiff>process</tiff><txt>process</txt><wav>process</wav><wmf>process</wmf><xls>process</xls><xlsx>process</xlsx></archiveConfig><pdfConfig><acroform>sanitise</acroform><actions_all>sanitise</actions_all><digital_signatures>sanitise</digital_signatures><embedded_files>sanitise</embedded_files><embedded_images>sanitise</embedded_images><external_hyperlinks>sanitise</external_hyperlinks><internal_hyperlinks>sanitise</internal_hyperlinks><javascript>sanitise</javascript><metadata>sanitise</metadata></pdfConfig><pptConfig><embedded_files>sanitise</embedded_files><embedded_images>sanitise</embedded_images><external_hyperlinks>sanitise</external_hyperlinks><internal_hyperlinks>sanitise</internal_hyperlinks><javascript>sanitise</javascript><macros>sanitise</macros><metadata>sanitise</metadata><review_comments>sanitise</review_comments></pptConfig><sysConfig><export_embedded_images>true</export_embedded_images><interchange_best_compression>false</interchange_best_compression><interchange_pretty>false</interchange_pretty><interchange_type>sisl</interchange_type><run_mode>enablerebuild</run_mode></sysConfig><tiffConfig><geotiff>sanitise</geotiff></tiffConfig><wordConfig><dynamic_data_exchange>sanitise</dynamic_data_exchange><embedded_files>sanitise</embedded_files><embedded_images>sanitise</embedded_images><external_hyperlinks>sanitise</external_hyperlinks><internal_hyperlinks>sanitise</internal_hyperlinks><macros>sanitise</macros><metadata>sanitise</metadata><review_comments>sanitise</review_comments></wordConfig><xlsConfig><dynamic_data_exchange>sanitise</dynamic_data_exchange><embedded_files>sanitise</embedded_files><embedded_images>sanitise</embedded_images><external_hyperlinks>sanitise</external_hyperlinks><internal_hyperlinks>sanitise</internal_hyperlinks><macros>sanitise</macros><metadata>sanitise</metadata><review_comments>sanitise</review_comments></xlsConfig></config>Expand Word Search custom policyimportglasswall# Print a custom Word Search content management policy with a default of# allow. Redact instances of the string "lorem" by replacing each character# with an asterisk, and redact instances of the string "ipsum" by replacing# each character with the letter "X".print(glasswall.content_management.policies.WordSearch(default="allow",config={"textSearchConfig":{"textList":[{"name":"textItem","switches":[{"name":"text","value":"lorem"},{"name":"textSetting","@replacementChar":"*","value":"redact"},]},{"name":"textItem","switches":[{"name":"text","value":"ipsum"},{"name":"textSetting","@replacementChar":"X","value":"redact"},]},]}}))<?xml version="1.0" encoding="utf-8"?><config><pdfConfig><acroform>allow</acroform><actions_all>allow</actions_all><digital_signatures>allow</digital_signatures><embedded_files>allow</embedded_files><embedded_images>allow</embedded_images><external_hyperlinks>allow</external_hyperlinks><internal_hyperlinks>allow</internal_hyperlinks><javascript>allow</javascript><metadata>allow</metadata></pdfConfig><pptConfig><embedded_files>allow</embedded_files><embedded_images>allow</embedded_images><external_hyperlinks>allow</external_hyperlinks><internal_hyperlinks>allow</internal_hyperlinks><javascript>allow</javascript><macros>allow</macros><metadata>allow</metadata><review_comments>allow</review_comments></pptConfig><sysConfig><export_embedded_images>true</export_embedded_images><interchange_best_compression>false</interchange_best_compression><interchange_pretty>false</interchange_pretty><interchange_type>xml</interchange_type><run_mode>enablerebuild</run_mode></sysConfig><textSearchConfiglibVersion="core2"><textList><textItem><text>lorem</text><textSettingreplacementChar="*">redact</textSetting></textItem><textItem><text>ipsum</text><textSettingreplacementChar="X">redact</textSetting></textItem></textList></textSearchConfig><tiffConfig><geotiff>allow</geotiff></tiffConfig><wordConfig><dynamic_data_exchange>allow</dynamic_data_exchange><embedded_files>allow</embedded_files><embedded_images>allow</embedded_images><external_hyperlinks>allow</external_hyperlinks><internal_hyperlinks>allow</internal_hyperlinks><macros>allow</macros><metadata>allow</metadata><review_comments>allow</review_comments></wordConfig><xlsConfig><dynamic_data_exchange>allow</dynamic_data_exchange><embedded_files>allow</embedded_files><embedded_images>allow</embedded_images><external_hyperlinks>allow</external_hyperlinks><internal_hyperlinks>allow</internal_hyperlinks><macros>allow</macros><metadata>allow</metadata><review_comments>allow</review_comments></xlsConfig></config>EditorProtectFiles can be protected individually from a file path or in memory using theprotect_filemethod, or all files from a directory can be protected using theprotect_directorymethod.Protect from file path to file pathimportglasswall# Load the Glasswall Editor libraryeditor=glasswall.Editor(r"C:\gwpw\libraries\embedded_engine_release_5.3")# Use the default policy to sanitise a file, writing the sanitised file to a new patheditor.protect_file(input_file=r"C:\gwpw\input\TestFile_11.doc",output_file=r"C:\gwpw\output\editor\protect_f2f\TestFile_11.doc",)Protect from file path to memoryprotect_filereturns the protected file's bytes. The below example demonstrates assigning the variablefile_bytes. We can see that after sanitisation the first 8 bytes offile_bytesmatches thefile signaturefor the Microsoft Compound File Binary (CFB) format,D0 CF 11 E0 A1 B1 1A E1.importglasswall# Load the Glasswall Editor libraryeditor=glasswall.Editor(r"C:\gwpw\libraries\embedded_engine_release_5.3")# Use the default policy to sanitise a file in memory, returning the file bytes in memoryfile_bytes=editor.protect_file(input_file=r"C:\gwpw\input\TestFile_11.doc")assertfile_bytes[:8]==b'\xd0\xcf\x11\xe0\xa1\xb1\x1a\xe1'Protect from memoryimportglasswall# Load the Glasswall Editor libraryeditor=glasswall.Editor(r"C:\gwpw\libraries\embedded_engine_release_5.3")# Read file from disk to memorywithopen(r"C:\gwpw\input\TestFile_11.doc","rb")asf:input_bytes=f.read()# Use the default policy to sanitise a filefile_bytes=editor.protect_file(input_file=input_bytes,)assertfile_bytes[:8]==b'\xd0\xcf\x11\xe0\xa1\xb1\x1a\xe1'Protect files in a directoryimportglasswall# Load the Glasswall Editor libraryeditor=glasswall.Editor(r"C:\gwpw\libraries\embedded_engine_release_5.3")# Use the default policy to protect a directory of files, writing the sanitised files to a new directory.editor.protect_directory(input_directory=r"C:\gwpw\input",output_directory=r"C:\gwpw\output\editor\protect_directory")Protect files in a directory that may contain unsupported file typesThe default behaviour of the Glasswall Python wrapper is to raise the relevant exception (see:glasswall.libraries.editor.errors) if processing fails. Passingraise_unsupported=Falsewill prevent an exception being raised and can be useful when working with a directory containing a mixture of both supported and unsupported file types when it is desired to process as many of the files as possible instead of terminating on the first failure.importglasswall# Load the Glasswall Editor libraryeditor=glasswall.Editor(r"C:\gwpw\libraries\embedded_engine_release_5.3")# Use the default policy to protect a directory of files, writing the sanitised files to a new directory.editor.protect_directory(input_directory=r"C:\gwpw\input_with_unsupported_file_types",output_directory=r"C:\gwpw\output\editor\protect_directory_unsupported",raise_unsupported=False)Protect files in a directory using a custom content management policyUsingglasswall.content_management.policies.Editor:importglasswall# Load the Glasswall Editor libraryeditor=glasswall.Editor(r"C:\gwpw\libraries\embedded_engine_release_5.3")# Use a custom Editor policy to sanitise all files in the input directory# and write them to the input_sanitised directory. If macros are present# in ppt or word files, the file will be marked as non-conforming and blocked.# If internal or external hyperlinks are present in word files they will not# be sanitised, and will remain in the regenerated document.editor.protect_directory(input_directory=r"C:\gwpw\input",output_directory=r"C:\gwpw\output\editor\protect_directory_custom",content_management_policy=glasswall.content_management.policies.Editor(default="sanitise",config={"pptConfig":{"macros":"disallow",},"wordConfig":{"internal_hyperlinks":"allow","external_hyperlinks":"allow","macros":"disallow",}}))Protect files in a directory conditionally based on file formatThe example below demonstrates processing of only doc and docx files from a nested directory containing multiple file formats.importosimportglasswall# Load the Glasswall Editor libraryeditor=glasswall.Editor(r"C:\gwpw\libraries\embedded_engine_release_5.3")input_directory=r"C:\gwpw\input"output_directory=r"C:\gwpw\output\editor\protect_directory_file_format"# Iterate relative file paths from input_directoryforrelative_fileinglasswall.utils.list_file_paths(input_directory,absolute=False):# Construct absolute pathsinput_file=os.path.join(input_directory,relative_file)output_file=os.path.join(output_directory,relative_file)# Get the file type of the filefile_type=editor.determine_file_type(input_file=input_file,as_string=True,raise_unsupported=False)# Protect only doc and docx filesiffile_typein["doc","docx"]:editor.protect_file(input_file,output_file)AnalysisFiles can be analysed individually from a file path or in memory using theanalyse_filemethod, or all files from a directory can be analysed using theanalyse_directorymethod.Analyse from file path to file pathimportglasswall# Load the Glasswall Editor libraryeditor=glasswall.Editor(r"C:\gwpw\libraries\embedded_engine_release_5.3")# Use the default policy to analyse a file, writing the analysis report to a new patheditor.analyse_file(input_file=r"C:\gwpw\input\TestFile_11.doc",output_file=r"C:\gwpw\output\editor\analyse_f2f\TestFile_11.doc.xml",)Analyse from file path to memoryanalyse_filereturns the analysis report xml file's bytes. The below example demonstrates assigning the variableanalysis_reportand checking the contents of the beginning of an Editor analysis report.importglasswall# Load the Glasswall Editor libraryeditor=glasswall.Editor(r"C:\gwpw\libraries\embedded_engine_release_5.3")# Use the default policy to analyse a fileanalysis_report=editor.analyse_file(input_file=r"C:\gwpw\input\TestFile_11.doc",)assertanalysis_report[:500]==b'<?xml version="1.0" encoding="utf-8"?>\n<gw:GWallInfo xsi:schemaLocation="http://glasswall.com/namespace/gwallInfo.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:gw="http://glasswall.com/namespace">\n\t<gw:DocumentStatistics>\n\t\t<gw:DocumentSummary>\n\t\t\t<gw:TotalSizeInBytes>35840</gw:TotalSizeInBytes>\n\t\t\t<gw:FileType>doc</gw:FileType>\n\t\t\t<gw:Version>Not Applicable</gw:Version>\n\t\t\t<gw:InputSHA256>9FDE85B8800C1019D2865FA298A7F75873E09870B71F9825827E354B865686A6</gw:InputSHA256>\n\t\t\t<gw'Analyse from memoryimportglasswall# Load the Glasswall Editor libraryeditor=glasswall.Editor(r"C:\gwpw\libraries\embedded_engine_release_5.3")# Read file from disk to memorywithopen(r"C:\gwpw\input\TestFile_11.doc","rb")asf:input_bytes=f.read()# Use the default policy to analyse a fileanalysis_report=editor.analyse_file(input_file=input_bytes,)assertanalysis_report[:500]==b'<?xml version="1.0" encoding="utf-8"?>\n<gw:GWallInfo xsi:schemaLocation="http://glasswall.com/namespace/gwallInfo.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:gw="http://glasswall.com/namespace">\n\t<gw:DocumentStatistics>\n\t\t<gw:DocumentSummary>\n\t\t\t<gw:TotalSizeInBytes>35840</gw:TotalSizeInBytes>\n\t\t\t<gw:FileType>doc</gw:FileType>\n\t\t\t<gw:Version>Not Applicable</gw:Version>\n\t\t\t<gw:InputSHA256>9FDE85B8800C1019D2865FA298A7F75873E09870B71F9825827E354B865686A6</gw:InputSHA256>\n\t\t\t<gw'Analyse files in a directoryimportglasswall# Load the Glasswall Editor libraryeditor=glasswall.Editor(r"C:\gwpw\libraries\embedded_engine_release_5.3")# Use the default policy to analyse a directory of files, writing the analysis reports to a new directory.editor.analyse_directory(input_directory=r"C:\gwpw\input",output_directory=r"C:\gwpw\output\editor\analyse_directory")Analyse files in a directory that may contain unsupported file typesThe default behaviour of the Glasswall Python wrapper is to raise the relevant exception (see:glasswall.libraries.editor.errors) if processing fails. Passingraise_unsupported=Falsewill prevent an exception being raised and can be useful when working with a directory containing a mixture of both supported and unsupported file types when it is desired to process as many of the files as possible instead of terminating on the first failure.importglasswall# Load the Glasswall Editor libraryeditor=glasswall.Editor(r"C:\gwpw\libraries\embedded_engine_release_5.3")# Use the default policy to analyse a directory of files, writing the analysis reports to a new directory.editor.analyse_directory(input_directory=r"C:\gwpw\input_with_unsupported_file_types",output_directory=r"C:\gwpw\output\editor\analyse_directory_unsupported",raise_unsupported=False)Analyse files in a directory using a custom content management policyUsingglasswall.content_management.policies.Editor:importglasswall# Load the Glasswall Editor libraryeditor=glasswall.Editor(r"C:\gwpw\libraries\embedded_engine_release_5.3")# Use a custom Editor policy to analyse all files in the input directory# and write them to analyse_directory_custom directory. If macros are# present in ppt or word files, a GeneralFail exception will be raised if the# raise_unsupported argument is left at it's default value of False, but the# analysis report will still be written to file and will contain IssueItems.# If internal or external hyperlinks are present in word files they will not# be sanitised, and will remain in the regenerated document.editor.analyse_directory(input_directory=r"C:\gwpw\input",output_directory=r"C:\gwpw\output\editor\analyse_directory_custom",content_management_policy=glasswall.content_management.policies.Editor(default="sanitise",config={"pptConfig":{"macros":"disallow",},"wordConfig":{"internal_hyperlinks":"allow","external_hyperlinks":"allow","macros":"disallow",}}),raise_unsupported=False)Analyse files in a directory conditionally based on file formatThe example below demonstrates processing of only doc and docx files from a nested directory containing multiple file formats.importosimportglasswall# Load the Glasswall Editor libraryeditor=glasswall.Editor(r"C:\gwpw\libraries\embedded_engine_release_5.3")input_directory=r"C:\gwpw\input"output_directory=r"C:\gwpw\output\editor\analyse_directory_file_format"# Iterate relative file paths from input_directoryforrelative_fileinglasswall.utils.list_file_paths(input_directory,absolute=False):# Construct absolute pathsinput_file=os.path.join(input_directory,relative_file)output_file=os.path.join(output_directory,relative_file+".xml")# Get the file type of the filefile_type=editor.determine_file_type(input_file=input_file,as_string=True,raise_unsupported=False)# Analyse only doc and docx filesiffile_typein["doc","docx"]:editor.analyse_file(input_file,output_file)ExportFiles can be exported individually from a file path or in memory using theexport_filemethod, or all files from a directory can be exported using theexport_directorymethod.Export from file path to file pathimportglasswall# Load the Glasswall Editor libraryeditor=glasswall.Editor(r"C:\gwpw\libraries\embedded_engine_release_5.3")# Use the default policy to export a file, writing the export archive to a new patheditor.export_file(input_file=r"C:\gwpw\input\TestFile_11.doc",output_file=r"C:\gwpw\output\editor\export_f2f\TestFile_11.doc.zip",)Export from file path to memoryexport_filereturns the exported archive file's bytes. The below example demonstrates assigning the variableexport_archiveand checking the contents of the beginning of an Editor export archive.importglasswall# Load the Glasswall Editor libraryeditor=glasswall.Editor(r"C:\gwpw\libraries\embedded_engine_release_5.3")# Use the default policy to export a fileexport_archive=editor.export_file(input_file=r"C:\gwpw\input\TestFile_11.doc",)assertexport_archive[:8]==b'PK\x03\x04\x14\x00\x0e\x00'Export from memoryimportglasswall# Load the Glasswall Editor libraryeditor=glasswall.Editor(r"C:\gwpw\libraries\embedded_engine_release_5.3")# Read file from disk to memorywithopen(r"C:\gwpw\input\TestFile_11.doc","rb")asf:input_bytes=f.read()# Use the default policy to export a fileexport_archive=editor.export_file(input_file=input_bytes,)assertexport_archive[:8]==b'PK\x03\x04\x14\x00\x0e\x00'Export files in a directoryimportglasswall# Load the Glasswall Editor libraryeditor=glasswall.Editor(r"C:\gwpw\libraries\embedded_engine_release_5.3")# Use the default policy to export a directory of files, writing the export archives to a new directory.editor.export_directory(input_directory=r"C:\gwpw\input",output_directory=r"C:\gwpw\output\editor\export_directory")Export files in a directory that may contain unsupported file typesThe default behaviour of the Glasswall Python wrapper is to raise the relevant exception (see:glasswall.libraries.editor.errors) if processing fails. Passingraise_unsupported=Falsewill prevent an exception being raised and can be useful when working with a directory containing a mixture of both supported and unsupported file types when it is desired to process as many of the files as possible instead of terminating on the first failure.importglasswall# Load the Glasswall Editor libraryeditor=glasswall.Editor(r"C:\gwpw\libraries\embedded_engine_release_5.3")# Use the default policy to export a directory of files, writing the export archives to a new directory.editor.export_directory(input_directory=r"C:\gwpw\input_with_unsupported_file_types",output_directory=r"C:\gwpw\output\editor\export_directory_unsupported",raise_unsupported=False)Export files in a directory using a custom content management policyUsingglasswall.content_management.policies.Editor:importglasswall# Load the Glasswall Editor libraryeditor=glasswall.Editor(r"C:\gwpw\libraries\embedded_engine_release_5.3")# Use a custom Editor policy to export all files in the input directory# and write them to export_directory_custom directory. Write streams as# ".xml" instead of the default interchange_type, ".sisl". Export embedded# images as ".xml" instead of their default image file type.editor.export_directory(input_directory=r"C:\gwpw\input",output_directory=r"C:\gwpw\output\editor\export_directory_custom",content_management_policy=glasswall.content_management.policies.Editor(default="sanitise",config={"sysConfig":{"interchange_type":"xml","export_embedded_images":"true",},}),raise_unsupported=False)Export files in a directory conditionally based on file formatThe example below demonstrates processing of only doc and docx files from a nested directory containing multiple file formats.importosimportglasswall# Load the Glasswall Editor libraryeditor=glasswall.Editor(r"C:\gwpw\libraries\embedded_engine_release_5.3")input_directory=r"C:\gwpw\input"output_directory=r"C:\gwpw\output\editor\export_directory_file_format"# Iterate relative file paths from input_directoryforrelative_fileinglasswall.utils.list_file_paths(input_directory,absolute=False):# Construct absolute pathsinput_file=os.path.join(input_directory,relative_file)output_file=os.path.join(output_directory,relative_file+".zip")# Get the file type of the filefile_type=editor.determine_file_type(input_file=input_file,as_string=True,raise_unsupported=False)# Export only doc and docx filesiffile_typein["doc","docx"]:editor.export_file(input_file,output_file)ImportExport archives can be imported individually from a file path or in memory using theimport_filemethod, or all export archives from a directory can be imported using theimport_directorymethod.Import from file path to file pathimportglasswall# Load the Glasswall Editor libraryeditor=glasswall.Editor(r"C:\gwpw\libraries\embedded_engine_release_5.3")# Use the default policy to import an export archive, writing the imported file to a new patheditor.import_file(input_file=r"C:\gwpw\output\editor\export_f2f\TestFile_11.doc.zip",output_file=r"C:\gwpw\output\editor\import_f2f\TestFile_11.doc",)Import from file path to memoryimport_filereturns the imported file's bytes. The below example demonstrates assigning the variablefile_bytesand checking the contents of the beginning of an Editor export archive.importglasswall# Load the Glasswall Editor libraryeditor=glasswall.Editor(r"C:\gwpw\libraries\embedded_engine_release_5.3")# Use the default policy to import an export archivefile_bytes=editor.import_file(input_file=r"C:\gwpw\output\editor\export_f2f\TestFile_11.doc.zip",)assertfile_bytes[:8]==b'\xd0\xcf\x11\xe0\xa1\xb1\x1a\xe1'Import from memoryimportglasswall# Load the Glasswall Editor libraryeditor=glasswall.Editor(r"C:\gwpw\libraries\embedded_engine_release_5.3")# Read file from disk to memorywithopen(r"C:\gwpw\output\editor\export_f2f\TestFile_11.doc.zip","rb")asf:export_archive_bytes=f.read()# Use the default policy to import an export archivefile_bytes=editor.import_file(input_file=export_archive_bytes,)assertfile_bytes[:8]==b'\xd0\xcf\x11\xe0\xa1\xb1\x1a\xe1'Import files in a directoryimportglasswall# Load the Glasswall Editor libraryeditor=glasswall.Editor(r"C:\gwpw\libraries\embedded_engine_release_5.3")# Use the default policy to import a directory of export archives, writing the import archives to a new directory.editor.import_directory(input_directory=r"C:\gwpw\output\editor\export_directory",output_directory=r"C:\gwpw\output\editor\import_directory")Import files in a directory that may contain unsupported file typesThe default behaviour of the Glasswall Python wrapper is to raise the relevant exception (see:glasswall.libraries.editor.errors) if processing fails. Passingraise_unsupported=Falsewill prevent an exception being raised and can be useful when working with a directory containing a mixture of both supported and unsupported file types when it is desired to process as many of the files as possible instead of terminating on the first failure.importglasswall# Load the Glasswall Editor libraryeditor=glasswall.Editor(r"C:\gwpw\libraries\embedded_engine_release_5.3")# Use the default policy to export a directory of export archives, writing the export archives to a new directory.editor.import_directory(input_directory=r"C:\gwpw\output\editor\export_directory_unsupported",output_directory=r"C:\gwpw\output\editor\import_directory_unsupported",raise_unsupported=False)Import files in a directory using a custom content management policyUsingglasswall.content_management.policies.Editor:importglasswall# Load the Glasswall Editor libraryeditor=glasswall.Editor(r"C:\gwpw\libraries\embedded_engine_release_5.3")# Use a custom Editor policy to import all files in the export directory# and write them to import_directory_custom directory. Read streams as# ".xml" instead of the default interchange_type, ".sisl".editor.import_directory(input_directory=r"C:\gwpw\output\editor\export_directory_custom",output_directory=r"C:\gwpw\output\editor\import_directory_custom",content_management_policy=glasswall.content_management.policies.Editor(default="sanitise",config={"sysConfig":{"interchange_type":"xml",},}),raise_unsupported=False)Import files in a directory conditionally based on file formatThe example below demonstrates processing of only doc and docx files from a nested directory containing multiple file formats.importosimportglasswall# Load the Glasswall Editor libraryeditor=glasswall.Editor(r"C:\gwpw\libraries\embedded_engine_release_5.3")input_directory=r"C:\gwpw\output\editor\export_directory_file_format"output_directory=r"C:\gwpw\output\editor\import_directory_file_format"# Iterate relative file paths from input_directoryforrelative_fileinglasswall.utils.list_file_paths(input_directory,absolute=False):# Construct absolute pathsinput_file=os.path.join(input_directory,relative_file)output_file=os.path.join(output_directory,os.path.splitext(relative_file)[0])# Get the file type of the filefile_type=editor.determine_file_type(input_file=input_file,as_string=True,raise_unsupported=False)# Import only doc.zip and docx.zip filesiffile_type=="zip"andinput_file.endswith(("doc.zip","docx.zip",)):editor.import_file(input_file,output_file)RebuildSeeEditordocumentation. High level functionality is the same between the Editor and Rebuild classes, simply use the Rebuild class instead of the Editor class:importglasswall# Load the Glasswall Rebuild libraryrebuild=glasswall.Rebuild(r"C:\gwpw\libraries\rebuild\1.661.0")# Use the default policy to sanitise a file, writing the sanitised file to a new pathrebuild.protect_file(input_file=r"C:\gwpw\input\TestFile_11.doc",output_file=r"C:\gwpw\output\rebuild\protect_f2f\TestFile_11.doc",)Archive ManagerProtect an archiveimportglasswall# Load the Glasswall Archive Manager libraryam=glasswall.ArchiveManager(r"C:\gwpw\libraries\embedded_engine_release_5.3")# Use the default Archive Manager policy: sanitise all, process all, writing# the sanitised archive and the analysis report to the output directory.am.protect_archive(input_file=r"C:\gwpw\input_archives\7Zip\0000001.jpg.7z",output_file=r"C:\gwpw\output\archive_manager\protect_archive\7Zip\0000001.jpg.7z",output_report=r"C:\gwpw\output\archive_manager\protect_archive\7Zip\0000001.jpg.7z.xml")Protect all archives in a directory using a custom content management policyimportglasswall# Load the Glasswall Archive Manager libraryam=glasswall.ArchiveManager(r"C:\gwpw\libraries\embedded_engine_release_5.3")# Use a custom Archive Manager policy: sanitise all, process all, but discard# mp3 and mp4 files. Write the sanitised archives and the analysis reports to# different directoriesam.protect_directory(input_directory=r"C:\gwpw\input_archives",output_directory=r"C:\gwpw\output\archive_manager\protect_directory_custom",output_report_directory=r"C:\gwpw\output\archive_manager\protect_directory_custom_reports",content_management_policy=glasswall.content_management.policies.ArchiveManager(default="sanitise",default_archive_manager="process",config={"archiveConfig":{"mp3":"discard","mp4":"discard"}}),raise_unsupported=False)Extraction - Unpacking an archiveimportglasswall# Load the Glasswall Archive Manager libraryam=glasswall.ArchiveManager(r"C:\gwpw\libraries\embedded_engine_release_5.3")# Unpack the Nested_4_layers.zip archive to a new directoryam.unpack(input_file=r"C:\gwpw\input_archives\Nested_4_layers.zip",output_directory=r"C:\gwpw\output\archive_manager\unpack")A new directory is created:C:\gwpw\output\archive_manager\unpack\Nested_4_layerscontaining the unpacked contents of theNested_4_layerszip archive. Nested archives are recursively unpacked while maintaining the same directory structure. To disable recursive unpacking use therecursivearg:importglasswall# Load the Glasswall Archive Manager libraryam=glasswall.ArchiveManager(r"C:\gwpw\libraries\embedded_engine_release_5.3")# Unpack the Nested_4_layers.zip archive to a new directory without recursing the archive.am.unpack(input_file=r"C:\gwpw\input_archives\Nested_4_layers.zip",output_directory=r"C:\gwpw\output\archive_manager\unpack_nonrecursive",recursive=False)Other useful arguments when unpackinginclude_file_typedefault False, keep the archive format in the directory name when unpacking. e.g. when TrueNested_4_layers.zipwill be unpacked to a directoryNested_4_layers.zipinstead ofNested_4_layers. This can be necessary when unpacking multiple same-named archives that have different archive formats.raise_unsupporteddefault True, raise an error if the Glasswall library encounters an error.delete_origindefault False, delete theinput_fileafter it has been unpacked tooutput_directory.Extraction - Unpacking a directory of archivesimportglasswall# Load the Glasswall Archive Manager libraryam=glasswall.ArchiveManager(r"C:\gwpw\libraries\embedded_engine_release_5.3")# Recursively unpack all archives found in the `archives` directoryam.unpack_directory(input_directory=r"C:\gwpw\input_archives",output_directory=r"C:\gwpw\output\archive_manager\unpack_directory")Theunpack_directorymethod shares the same optional arguments asunpack. See also:Extraction - Unpacking an archiveCompression - Packing a directory into an archiveimportglasswall# Load the Glasswall Archive Manager libraryam=glasswall.ArchiveManager(r"C:\gwpw\libraries\embedded_engine_release_5.3")# Pack the `input_archives` directory as zip to `input_archives.zip` in the 'C:\gwpw\output\archive_manager\pack' directoryam.pack_directory(input_directory=r"C:\gwpw\input_archives",output_directory=r"C:\gwpw\output\archive_manager\pack",file_type="zip",)WordSearchGlasswall WordSearch can be used to redact text from files and generates an XML report on the redacted file's details.This report includes details on the file size, the determined file type, the total number of text matches, and the location of each of the text matches.Example report<gw:WordSearchStatisticsxmlns:gw="http://glasswall.com/namespace"><gw:DocumentSummary><gw:TotalSizeInBytes>13084</gw:TotalSizeInBytes><gw:FileType>docx</gw:FileType><gw:TotalItemMatchCount>8</gw:TotalItemMatchCount></gw:DocumentSummary><gw:WordItem><gw:Name>ipsum</gw:Name><gw:ItemMatchCount>5</gw:ItemMatchCount><gw:Locations><gw:Location><gw:Offset>120</gw:Offset><gw:Page>0</gw:Page><gw:Paragraph>0</gw:Paragraph></gw:Location><gw:Location><gw:Offset>267</gw:Offset><gw:Page>0</gw:Page><gw:Paragraph>0</gw:Paragraph></gw:Location><gw:Location><gw:Offset>691</gw:Offset><gw:Page>0</gw:Page><gw:Paragraph>0</gw:Paragraph></gw:Location><gw:Location><gw:Offset>973</gw:Offset><gw:Page>0</gw:Page><gw:Paragraph>0</gw:Paragraph></gw:Location><gw:Location><gw:Offset>1034</gw:Offset><gw:Page>0</gw:Page><gw:Paragraph>0</gw:Paragraph></gw:Location></gw:Locations></gw:WordItem><gw:WordItem><gw:Name>lorem</gw:Name><gw:ItemMatchCount>3</gw:ItemMatchCount><gw:Locations><gw:Location><gw:Offset>114</gw:Offset><gw:Page>0</gw:Page><gw:Paragraph>0</gw:Paragraph></gw:Location><gw:Location><gw:Offset>244</gw:Offset><gw:Page>0</gw:Page><gw:Paragraph>0</gw:Paragraph></gw:Location><gw:Location><gw:Offset>1224</gw:Offset><gw:Page>0</gw:Page><gw:Paragraph>0</gw:Paragraph></gw:Location></gw:Locations></gw:WordItem></gw:WordSearchStatistics>A homoglyphs JSON file can be specified either as a file path or in memory as bytes, bytearray, or io.BytesIO. If this is not specified then the default will be used:Default homoglyphs.json file{"!":"ǃⵑ","$":"＄","%":"％","&":"ꝸ＆","'":"`´ʹʻʼʽʾˈˊˋ˴ʹ΄՚՝י׳ߴߵᑊᛌ᾽᾿`´῾‘’‛′‵ꞌ＇｀𖽑𖽒","(":"❨❲〔﴾（［",")":"❩❳〕﴿）］","*":"٭⁎∗＊𐌟","+":"᛭＋𐊛",",":"¸؍٫‚ꓹ，","-":"˗۔‐‑‒–⁃−➖Ⲻ﹘",".":"٠۰܁܂․ꓸ꘎．𐩐𝅭","/":"᜵⁁⁄∕╱⟋⧸Ⳇ⼃〳ノ㇓丿／𝈺","0":"OoΟοσОоՕօסه٥ھہە۵߀०০੦૦ଠ୦௦ం౦ಂ೦ംഠ൦ං๐໐ဝ၀ჿዐᴏᴑℴⲞⲟⵔ〇ꓳꬽﮦﮧﮨﮩﮪﮫﮬﮭﻩﻪﻫﻬ０Ｏｏ𐊒𐊫𐐄𐐬𐓂𐓪𐔖𑓐𑢵𑣈𑣗𑣠𝐎𝐨𝑂𝑜𝑶𝒐𝒪𝓞𝓸𝔒𝔬𝕆𝕠𝕺𝖔𝖮𝗈𝗢𝗼𝘖𝘰𝙊𝙤𝙾𝚘𝚶𝛐𝛔𝛰𝜊𝜎𝜪𝝄𝝈𝝤𝝾𝞂𝞞𝞸𝞼𝟎𝟘𝟢𝟬𝟶𞸤𞹤𞺄","1":"Il|ƖǀΙІӀ׀וןا١۱ߊᛁℐℑℓⅠⅼ∣⏽Ⲓⵏꓲﺍﺎ１Ｉｌ￨𐊊𐌉𐌠𖼨𝐈𝐥𝐼𝑙𝑰𝒍𝓁𝓘𝓵𝔩𝕀𝕝𝕴𝖑𝖨𝗅𝗜𝗹𝘐𝘭𝙄𝙡𝙸𝚕𝚰𝛪𝜤𝝞𝞘𝟏𝟙𝟣𝟭𝟷𞣇𞸀𞺀","2":"ƧϨᒿꙄꛯꝚ２𝟐𝟚𝟤𝟮𝟸","3":"ƷȜЗӠⳌꝪꞫ３𑣊𖼻𝈆𝟑𝟛𝟥𝟯𝟹","4":"Ꮞ４𑢯𝟒𝟜𝟦𝟰𝟺","5":"Ƽ５𑢻𝟓𝟝𝟧𝟱𝟻","6":"бᏮⳒ６𑣕𝟔𝟞𝟨𝟲𝟼","7":"７𐓒𑣆𝈒𝟕𝟟𝟩𝟳𝟽","8":"Ȣȣ৪੪ଃ８𐌚𝟖𝟠𝟪𝟴𝟾𞣋","9":"৭੧୨൭ⳊꝮ９𑢬𑣌𑣖𝟗𝟡𝟫𝟵𝟿","A":"4ΑАᎪᗅᴀꓮꭺＡ𐊠𖽀𝐀𝐴𝑨𝒜𝓐𝔄𝔸𝕬𝖠𝗔𝘈𝘼𝙰𝚨𝛢𝜜𝝖𝞐","B":"ʙΒВвᏴᏼᗷᛒℬꓐꞴＢ𐊂𐊡𐌁𝐁𝐵𝑩𝓑𝔅𝔹𝕭𝖡𝗕𝘉𝘽𝙱𝚩𝛣𝜝𝝗𝞑","C":"ϹСᏟℂℭⅭⲤꓚＣ𐊢𐌂𐐕𐔜𑣩𑣲𝐂𝐶𝑪𝒞𝓒𝕮𝖢𝗖𝘊𝘾𝙲🝌","D":"ᎠᗞᗪᴅⅅⅮꓓꭰＤ𝐃𝐷𝑫𝒟𝓓𝔇𝔻𝕯𝖣𝗗𝘋𝘿𝙳","E":"ΕЕᎬᴇℰ⋿ⴹꓰꭼＥ𐊆𑢦𑢮𝐄𝐸𝑬𝓔𝔈𝔼𝕰𝖤𝗘𝘌𝙀𝙴𝚬𝛦𝜠𝝚𝞔","F":"ϜᖴℱꓝꞘＦ𐊇𐊥𐔥𑢢𑣂𝈓𝐅𝐹𝑭𝓕𝔉𝔽𝕱𝖥𝗙𝘍𝙁𝙵𝟊","G":"ɢԌԍᏀᏳᏻꓖꮐＧ𝐆𝐺𝑮𝒢𝓖𝔊𝔾𝕲𝖦𝗚𝘎𝙂𝙶","H":"ʜΗНнᎻᕼℋℌℍⲎꓧꮋＨ𐋏𝐇𝐻𝑯𝓗𝕳𝖧𝗛𝘏𝙃𝙷𝚮𝛨𝜢𝝜𝞖","I":"","J":"ͿЈᎫᒍᴊꓙꞲꭻＪ𝐉𝐽𝑱𝒥𝓙𝔍𝕁𝕵𝖩𝗝𝘑𝙅𝙹","K":"ΚКᏦᛕKⲔꓗＫ𐔘𝐊𝐾𝑲𝒦𝓚𝔎𝕂𝕶𝖪𝗞𝘒𝙆𝙺𝚱𝛫𝜥𝝟𝞙","L":"ʟᏞᒪℒⅬⳐⳑꓡꮮＬ𐐛𐑃𐔦𑢣𑢲𖼖𝈪𝐋𝐿𝑳𝓛𝔏𝕃𝕷𝖫𝗟𝘓𝙇𝙻","M":"ΜϺМᎷᗰᛖℳⅯⲘꓟＭ𐊰𐌑𝐌𝑀𝑴𝓜𝔐𝕄𝕸𝖬𝗠𝘔𝙈𝙼𝚳𝛭𝜧𝝡𝞛","N":"ɴΝℕⲚꓠＮ𐔓𝐍𝑁𝑵𝒩𝓝𝔑𝕹𝖭𝗡𝘕𝙉𝙽𝚴𝛮𝜨𝝢𝞜","O":"0","P":"ΡРᏢᑭᴘᴩℙⲢꓑꮲＰ𐊕𝐏𝑃𝑷𝒫𝓟𝔓𝕻𝖯𝗣𝘗𝙋𝙿𝚸𝛲𝜬𝝦𝞠","Q":"ℚⵕＱ𝐐𝑄𝑸𝒬𝓠𝔔𝕼𝖰𝗤𝘘𝙌𝚀","R":"ƦʀᎡᏒᖇᚱℛℜℝꓣꭱꮢＲ𐒴𖼵𝈖𝐑𝑅𝑹𝓡𝕽𝖱𝗥𝘙𝙍𝚁","S":"$ЅՏᏕᏚꓢＳ𐊖𐐠𖼺𝐒𝑆𝑺𝒮𝓢𝔖𝕊𝕾𝖲𝗦𝘚𝙎𝚂","T":"ŤΤτТтᎢᴛ⊤⟙ⲦꓔꭲＴ𐊗𐊱𐌕𑢼𖼊𝐓𝑇𝑻𝒯𝓣𝔗𝕋𝕿𝖳𝗧𝘛𝙏𝚃𝚻𝛕𝛵𝜏𝜯𝝉𝝩𝞃𝞣𝞽🝨","U":"Սሀᑌ∪⋃ꓴＵ𐓎𑢸𖽂𝐔𝑈𝑼𝒰𝓤𝔘𝕌𝖀𝖴𝗨𝘜𝙐𝚄","V":"Ѵ٧۷ᏙᐯⅤⴸꓦꛟＶ𐔝𑢠𖼈𝈍𝐕𝑉𝑽𝒱𝓥𝔙𝕍𝖁𝖵𝗩𝘝𝙑𝚅","W":"ԜᎳᏔꓪＷ𑣦𑣯𝐖𝑊𝑾𝒲𝓦𝔚𝕎𝖂𝖶𝗪𝘞𝙒𝚆","X":"ΧХ᙭ᚷⅩ╳ⲬⵝꓫꞳＸ𐊐𐊴𐌗𐌢𐔧𑣬𝐗𝑋𝑿𝒳𝓧𝔛𝕏𝖃𝖷𝗫𝘟𝙓𝚇𝚾𝛸𝜲𝝬𝞦","Y":"ΥϒУҮᎩᎽⲨꓬＹ𐊲𑢤𖽃𝐘𝑌𝒀𝒴𝓨𝔜𝕐𝖄𝖸𝗬𝘠𝙔𝚈𝚼𝛶𝜰𝝪𝞤","Z":"ΖᏃℤℨꓜＺ𐋵𑢩𑣥𝐙𝑍𝒁𝒵𝓩𝖅𝖹𝗭𝘡𝙕𝚉𝚭𝛧𝜡𝝛𝞕","a":"@ɑαа⍺ａ𝐚𝑎𝒂𝒶𝓪𝔞𝕒𝖆𝖺𝗮𝘢𝙖𝚊𝛂𝛼𝜶𝝰𝞪","b":"ƄЬᏏᖯｂ𝐛𝑏𝒃𝒷𝓫𝔟𝕓𝖇𝖻𝗯𝘣𝙗𝚋","c":"ϲсᴄⅽⲥꮯｃ𐐽𝐜𝑐𝒄𝒸𝓬𝔠𝕔𝖈𝖼𝗰𝘤𝙘𝚌","d":"ԁᏧᑯⅆⅾꓒｄ𝐝𝑑𝒅𝒹𝓭𝔡𝕕𝖉𝖽𝗱𝘥𝙙𝚍","e":"еҽ℮ℯⅇꬲｅ𝐞𝑒𝒆𝓮𝔢𝕖𝖊𝖾𝗲𝘦𝙚𝚎","f":"ſϝքẝꞙꬵｆ𝐟𝑓𝒇𝒻𝓯𝔣𝕗𝖋𝖿𝗳𝘧𝙛𝚏𝟋","g":"ƍɡցᶃℊｇ𝐠𝑔𝒈𝓰𝔤𝕘𝖌𝗀𝗴𝘨𝙜𝚐","h":"һհᏂℎｈ𝐡𝒉𝒽𝓱𝔥𝕙𝖍𝗁𝗵𝘩𝙝𝚑","i":"ıɩɪ˛ͺιіӏᎥιℹⅈⅰ⍳ꙇꭵｉ𑣃𝐢𝑖𝒊𝒾𝓲𝔦𝕚𝖎𝗂𝗶𝘪𝙞𝚒𝚤𝛊𝜄𝜾𝝸𝞲","j":"ϳјⅉｊ𝐣𝑗𝒋𝒿𝓳𝔧𝕛𝖏𝗃𝗷𝘫𝙟𝚓","k":"ｋ𝐤𝑘𝒌𝓀𝓴𝔨𝕜𝖐𝗄𝗸𝘬𝙠𝚔","l":"1","m":"ｍ","n":"ոռｎ𝐧𝑛𝒏𝓃𝓷𝔫𝕟𝖓𝗇𝗻𝘯𝙣𝚗","o":"","p":"ρϱр⍴ⲣｐ𝐩𝑝𝒑𝓅𝓹𝔭𝕡𝖕𝗉𝗽𝘱𝙥𝚙𝛒𝛠𝜌𝜚𝝆𝝔𝞀𝞎𝞺𝟈","q":"ԛգզｑ𝐪𝑞𝒒𝓆𝓺𝔮𝕢𝖖𝗊𝗾𝘲𝙦𝚚","r":"гᴦⲅꭇꭈꮁｒ𝐫𝑟𝒓𝓇𝓻𝔯𝕣𝖗𝗋𝗿𝘳𝙧𝚛","s":"$ƽѕꜱꮪｓ𐑈𑣁𝐬𝑠𝒔𝓈𝓼𝔰𝕤𝖘𝗌𝘀𝘴𝙨𝚜","t":"ｔ𝐭𝑡𝒕𝓉𝓽𝔱𝕥𝖙𝗍𝘁𝘵𝙩𝚝","u":"ʋυսᴜꞟꭎꭒｕ𐓶𑣘𝐮𝑢𝒖𝓊𝓾𝔲𝕦𝖚𝗎𝘂𝘶𝙪𝚞𝛖𝜐𝝊𝞄𝞾","v":"νѵטᴠⅴ∨⋁ꮩｖ𑜆𑣀𝐯𝑣𝒗𝓋𝓿𝔳𝕧𝖛𝗏𝘃𝘷𝙫𝚟𝛎𝜈𝝂𝝼𝞶","w":"ɯѡԝաᴡꮃｗ𑜊𑜎𑜏𝐰𝑤𝒘𝓌𝔀𝔴𝕨𝖜𝗐𝘄𝘸𝙬𝚠","x":"×хᕁᕽ᙮ⅹ⤫⤬⨯ｘ𝐱𝑥𝒙𝓍𝔁𝔵𝕩𝖝𝗑𝘅𝘹𝙭𝚡","y":"ɣʏγуүყᶌỿℽꭚｙ𑣜𝐲𝑦𝒚𝓎𝔂𝔶𝕪𝖞𝗒𝘆𝘺𝙮𝚢𝛄𝛾𝜸𝝲𝞬","z":"ᴢꮓｚ𑣄𝐳𝑧𝒛𝓏𝔃𝔷𝕫𝖟𝗓𝘇𝘻𝙯𝚣","£":"₤","©":"Ⓒ","®":"Ⓡ"}RedactFiles can be redacted individually from a file path or in memory using theredact_filemethod, or all files from a directory can be redacted using theredact_directorymethod.Redact from file path to file pathimportglasswall# Load the Glasswall WordSearch libraryword_search=glasswall.WordSearch(r"C:\gwpw\libraries\embedded_engine_release_5.3")# Redact occurrences of the text "lorem" and "ipsum" within the input file, writing the redacted file to a new pathword_search.redact_file(input_file=r"C:\gwpw\input_redact\lorem_ipsum.docx",output_file=r"C:\gwpw\output\word_search\redact_f2f\lorem_ipsum.docx",content_management_policy=glasswall.content_management.policies.WordSearch(config={"textSearchConfig":{"@libVersion":"core2","textList":[{"name":"textItem","switches":[{"name":"text","value":"lorem"},{"name":"textSetting","@replacementChar":"*","value":"redact"},]},{"name":"textItem","switches":[{"name":"text","value":"ipsum"},{"name":"textSetting","@replacementChar":"*","value":"redact"},]},]}}))Redact from file path to memoryredact_filereturns an object with the attributes: "status" (int), "output_file" (bytes), "output_report" (bytes). The below example demonstrates assigning the variableresultand checking the contents of the beginning of the redacted output_file and the output_report.importglasswall# Load the Glasswall WordSearch libraryword_search=glasswall.WordSearch(r"C:\gwpw\libraries\embedded_engine_release_5.3")# Redact occurrences of the text "lorem" and "ipsum" within the input file, writing the redacted file to a new pathresult=word_search.redact_file(input_file=r"C:\gwpw\input_redact\lorem_ipsum.docx",output_file=None,content_management_policy=glasswall.content_management.policies.WordSearch(config={"textSearchConfig":{"@libVersion":"core2","textList":[{"name":"textItem","switches":[{"name":"text","value":"lorem"},{"name":"textSetting","@replacementChar":"*","value":"redact"},]},{"name":"textItem","switches":[{"name":"text","value":"ipsum"},{"name":"textSetting","@replacementChar":"*","value":"redact"},]},]}}))assertresult.output_file[:6]==b'PK\x03\x04\x14\x00'assertresult.output_report[:500]==b'<gw:WordSearchStatistics xmlns:gw="http://glasswall.com/namespace">\n\t<gw:DocumentSummary>\n\t\t<gw:TotalSizeInBytes>14292</gw:TotalSizeInBytes>\n\t\t<gw:FileType>docx</gw:FileType>\n\t\t<gw:TotalItemMatchCount>14</gw:TotalItemMatchCount>\n\t</gw:DocumentSummary>\n\t<gw:WordItem>\n\t\t<gw:Name>ipsum</gw:Name>\n\t\t<gw:ItemMatchCount>8</gw:ItemMatchCount>\n\t\t<gw:Locations>\n\t\t\t<gw:Location>\n\t\t\t\t<gw:Offset>120</gw:Offset>\n\t\t\t\t<gw:Page>0</gw:Page>\n\t\t\t\t<gw:Paragraph>0</gw:Paragraph>\n\t\t\t</gw:Location>\n\t\t\t<gw:Location>\n\t\t\t'Redact from memoryimportglasswall# Load the Glasswall WordSearch libraryword_search=glasswall.WordSearch(r"C:\gwpw\libraries\embedded_engine_release_5.3")# Read file from disk to memorywithopen(r"C:\gwpw\input_redact\lorem_ipsum.docx","rb")asf:input_bytes=f.read()# Redact occurrences of the text "lorem" and "ipsum" within the input file, writing the redacted file to a new pathresult=word_search.redact_file(input_file=input_bytes,output_file=r"C:\gwpw\output\word_search\redact_m2f\lorem_ipsum.docx",content_management_policy=glasswall.content_management.policies.WordSearch(config={"textSearchConfig":{"@libVersion":"core2","textList":[{"name":"textItem","switches":[{"name":"text","value":"lorem"},{"name":"textSetting","@replacementChar":"*","value":"redact"},]},{"name":"textItem","switches":[{"name":"text","value":"ipsum"},{"name":"textSetting","@replacementChar":"*","value":"redact"},]},]}}))assertresult.output_file[:6]==b'PK\x03\x04\x14\x00'assertresult.output_report[:500]==b'<gw:WordSearchStatistics xmlns:gw="http://glasswall.com/namespace">\n\t<gw:DocumentSummary>\n\t\t<gw:TotalSizeInBytes>14292</gw:TotalSizeInBytes>\n\t\t<gw:FileType>docx</gw:FileType>\n\t\t<gw:TotalItemMatchCount>14</gw:TotalItemMatchCount>\n\t</gw:DocumentSummary>\n\t<gw:WordItem>\n\t\t<gw:Name>ipsum</gw:Name>\n\t\t<gw:ItemMatchCount>8</gw:ItemMatchCount>\n\t\t<gw:Locations>\n\t\t\t<gw:Location>\n\t\t\t\t<gw:Offset>120</gw:Offset>\n\t\t\t\t<gw:Page>0</gw:Page>\n\t\t\t\t<gw:Paragraph>0</gw:Paragraph>\n\t\t\t</gw:Location>\n\t\t\t<gw:Location>\n\t\t\t'Redact files in a directoryredact_directoryreturns a dictionary of file paths relative to the input_directory, and an object with the attributes: "status" (int), "output_file" (bytes), "output_report" (bytes). The below example demonstrates assigning the variableresultsand checking the keys and values of theresultsdictionary.importglasswall# Load the Glasswall WordSearch libraryword_search=glasswall.WordSearch(r"C:\gwpw\libraries\embedded_engine_release_5.3")# Redact occurrences of the text "lorem" and "ipsum" within each file in the input_directory, writing the redacted file# to a new path in the output_directoryresults=word_search.redact_directory(input_directory=r"C:\gwpw\input_redact",output_directory=r"C:\gwpw\output\word_search\redact_directory",content_management_policy=glasswall.content_management.policies.WordSearch(config={"textSearchConfig":{"@libVersion":"core2","textList":[{"name":"textItem","switches":[{"name":"text","value":"lorem"},{"name":"textSetting","@replacementChar":"*","value":"redact"},]},{"name":"textItem","switches":[{"name":"text","value":"ipsum"},{"name":"textSetting","@replacementChar":"*","value":"redact"},]},]}}))assertlist(results.keys())==['lorem_ipsum.docx','lorem_ipsum.pptx']assertall(result.status==1forresultinresults.values())Redact files in a directory that may contain unsupported file typesThe default behaviour of the Glasswall Python wrapper is to raise the relevant exception (see:glasswall.libraries.word_search.errors) if processing fails. Passingraise_unsupported=Falsewill prevent an exception being raised and can be useful when working with a directory containing a mixture of both supported and unsupported file types when it is desired to process as many of the files as possible instead of terminating on the first failure.The below example input directory contains the same two files in the above example as well as a file with an unsupported file format:python-package.yml. We can inspect the key value pairs in theresultsdictionary and see that the object returned for thepython-package.ymlfile returned astatus: 0, a failure. Theoutput_fileattribute is empty bytes, and theoutput_reportbytes is populated with a report that includes anIssueItemdescribing the problems encountered while attempting to redact the file:File contents could not be accessed.importglasswall# Load the Glasswall WordSearch libraryword_search=glasswall.WordSearch(r"C:\gwpw\libraries\embedded_engine_release_5.3")# Redact occurrences of the text "lorem" and "ipsum" within each file in the input_directory, writing the redacted file# to a new path in the output_directoryresults=word_search.redact_directory(input_directory=r"C:\gwpw\input_redact_with_unsupported_file_types",output_directory=r"C:\gwpw\output\word_search\redact_directory_unsupported",content_management_policy=glasswall.content_management.policies.WordSearch(config={"textSearchConfig":{"@libVersion":"core2","textList":[{"name":"textItem","switches":[{"name":"text","value":"lorem"},{"name":"textSetting","@replacementChar":"*","value":"redact"},]},{"name":"textItem","switches":[{"name":"text","value":"ipsum"},{"name":"textSetting","@replacementChar":"*","value":"redact"},]},]}}),raise_unsupported=False)assertlist(results.keys())==["lorem_ipsum.docx","lorem_ipsum.pptx","python-package.yml"]assert[result.statusforresultinresults.values()]==[1,1,0]print(results["python-package.yml"].__dict__)# {'status': 0,# 'output_file': b'',# 'output_report': b'<gw:WordSearchStatistics xmlns:gw="http://glasswall.com/namespace">\n\t<gw:IssueItem>\n\t\t<gw:Description>File contents could not be accessed</gw:Description>\n\t</gw:IssueItem>\n\t<gw:DocumentSummary>\n\t\t<gw:TotalSizeInBytes>1460</gw:TotalSizeInBytes>\n\t\t<gw:FileType>Unknown</gw:FileType>\n\t\t<gw:TotalItemMatchCount>0</gw:TotalItemMatchCount>\n\t</gw:DocumentSummary>\n\t<gw:WordItem>\n\t\t<gw:Name>ipsum</gw:Name>\n\t\t<gw:ItemMatchCount>0</gw:ItemMatchCount>\n\t\t<gw:Locations/>\n\t</gw:WordItem>\n\t<gw:WordItem>\n\t\t<gw:Name>lorem</gw:Name>\n\t\t<gw:ItemMatchCount>0</gw:ItemMatchCount>\n\t\t<gw:Locations/>\n\t</gw:WordItem>\n</gw:WordSearchStatistics>\n\n'}Redact files in a directory conditionally based on file formatThe example below demonstrates redacting of only docx and pptx files from a directory that also contains other unsupported file types.importosimportglasswall# Load the Glasswall Editor libraryeditor=glasswall.Editor(r"C:\gwpw\libraries\embedded_engine_release_5.3")# Load the Glasswall WordSearch libraryword_search=glasswall.WordSearch(r"C:\gwpw\libraries\embedded_engine_release_5.3")input_directory=r"C:\gwpw\input_redact_with_unsupported_file_types"output_directory=r"C:\gwpw\output\word_search\redact_directory_file_format"# Iterate relative file paths from input_directoryforrelative_fileinglasswall.utils.list_file_paths(input_directory,absolute=False):# Construct absolute pathsinput_file=os.path.join(input_directory,relative_file)output_file=os.path.join(output_directory,relative_file)# Get the file type of the filefile_type=editor.determine_file_type(input_file=input_file,as_string=True,raise_unsupported=False)# Protect only doc and docx filesiffile_typein["docx","pptx"]:# Redact occurrences of the text "lorem" and "ipsum" within the input file, writing the redacted file to a new pathword_search.redact_file(input_file=input_file,output_file=output_file,content_management_policy=glasswall.content_management.policies.WordSearch(config={"textSearchConfig":{"@libVersion":"core2","textList":[{"name":"textItem","switches":[{"name":"text","value":"lorem"},{"name":"textSetting","@replacementChar":"*","value":"redact"},]},{"name":"textItem","switches":[{"name":"text","value":"ipsum"},{"name":"textSetting","@replacementChar":"*","value":"redact"},]},]}}))