Package: gsfpy
gsfpy - Generic Sensor Format for PythonPython wrapper for the C implementation of the Generic Sensor Format library.Free software: MIT licenseNotes on licensing: The bundledgsfpy3_0x/libgsf/libgsf03_0x.sobinaries are covered by theLGPL v2.1license. Copies of this license are included in the project atgsfpy3_0x/libgsf/libgsf_LICENSE.md. The top-level MIT licensing of the  overallgsfpyproject is not affected by this. However, as required by the libgsf license, the libgsf shared object libraries used by thegsfpy3_0xpackages at runtime may be replaced with a different version by setting theGSFPY3_08_LIBGSF_PATHand/orGSFPY3_09_LIBGSF_PATHenvironment variables to the absolute file path of the new library.Namespaces and supported GSF versionsThegsfpypackage provides three namespaces:gsfpy,gsfpy3_08andgsfpy3_09.The default version of GSF supported is3.08. Top level package functionality for3.08can be used either viaimport gsfpy(without setting theDEFAULT_GSF_VERSIONenvironment variable - see below) orimport gsfpy3_08. Note thatimport gsfpywill also work for versions 3.06 and 3.07 of GSF as well (older versions have not been tested).If you are using GSF v3.09, there are two options:Set theDEFAULT_GSF_VERSIONenvironment variable to"3.09", thenimport gsfpyImport the 3.09 package directly withimport gsfpy3_09FeaturesThegsfpy(3_0x).bindingsmodules provide wrappers for all GSFlib functions, including I/O, utility and info functions.
Minor exceptions are noted in the sections below.For added convenience the gsfpy top level package provides the following higher level abstractions:open_gsf()GsfFile(class)GsfFile.read()GsfFile.get_number_records()GsfFile.seek()GsfFile.write()GsfFile.close()Install usingpipFrom PyPIpipinstallgsfpyFrom GitHub (SSH)pipinstallgit+ssh://git@github.com/UKHO/gsfpy.git@masterFrom GitHub (HTTPS)pipinstallgit+https://github.com/UKHO/gsfpy.git@masterExamples of usageOpen/close/read from a GSF file (GSF v3.08)fromctypesimportstring_atfromgsfpy3_08importopen_gsffromgsfpy3_08.enumsimportRecordTypewithopen_gsf("path/to/file.gsf")asgsf_file:# Note - file is closed automatically upon exiting 'with' block_,record=gsf_file.read(RecordType.GSF_RECORD_COMMENT)# Note use of ctypes.string_at() to access POINTER(c_char) contents of# c_gsfComment.comment field.print(string_at(record.comment.comment))Write to a GSF file (GSF v3.09)fromctypesimportc_int,create_string_bufferfromgsfpy3_09importopen_gsffromgsfpy3_09.enumsimportFileMode,RecordTypefromgsfpy3_09.gsfRecordsimportc_gsfRecordscomment=b"My comment"# Initialize the contents of the record that will be written.# Note use of ctypes.create_string_buffer() to set POINTER(c_char) contents.record=c_gsfRecords()record.comment.comment_time.tvsec=c_int(1000)record.comment.comment_length=c_int(len(comment))record.comment.comment=create_string_buffer(comment)withopen_gsf("path/to/file.gsf",mode=FileMode.GSF_CREATE)asgsf_file:gsf_file.write(record,RecordType.GSF_RECORD_COMMENT)Copy GSF records (GSF v3.08 as default)fromctypesimportbyref,c_int,pointerfromgsfpyimport*# This example uses the bindings module to illustrate use of the lower level functionsfile_handle=c_int(0)data_id=gsfDataID.c_gsfDataID()source_records=gsfRecords.c_gsfRecords()target_records=gsfRecords.c_gsfRecords()ret_val_open=bindings.gsfOpen(b"path/to/file.gsf",enums.FileMode.GSF_READONLY,byref(file_handle))# Note use of ctypes.byref() as a shorthand way of passing POINTER parameters to# the underlying foreign function call. ctypes.pointer() may also be used.bytes_read=gsfpy.bindings.gsfRead(file_handle,enums.RecordType.GSF_RECORD_COMMENT,byref(data_id),byref(source_records),)# Note use of pointer() rather than byref() when passing parameters to# gsfCopyRecords(). Implementation of this function is in Python as calling# the native underlying function causes memory ownership clashes. byref()# is only suitable for passing parameters to foreign function calls (see# ctypes docs).ret_val_cpy=bindings.gsfCopyRecords(pointer(target_records),pointer(source_records))ret_val_close=bindings.gsfClose(file_handle)Troubleshootfromgsfpy3_09.bindingsimportgsfIntError,gsfStringError# The gsfIntError() and gsfStringError() functions are useful for# diagnostics. They return an error code and corresponding error# message, respectively.retValIntError=gsfIntError()retValStringError=gsfStringError()print(retValIntError,retValStringError)Notes on implementationgsfPrintError()ThegsfPrintError()method of GSFlib is not implemented as there is noFILE*equivalent in Python. UsegsfStringError()instead - this will
give the same error message, which can then be written to file as
required.gsfCopyRecords() and gsfFree()gsfFree()the sibling method togsfCopyRecord()in GSFlib, used to
deallocate memory assigned by the library but managed by the calling
application, is not required by gsfpy as memory allocation and
deallocation is handled by ctypes.gsfFree()is therefore omitted from
the package.gsf_register_progress_callback()Implementation of the GSFlib functiongsf_register_progress_callback()is not applicable for gsfpy as the
DISPLAY_SPINNER macro was not defined during compilation. It is
therefore omitted from the package.Generic Sensor Format DocumentationGeneric Sensor Format specification: see e.g.https://github.com/schwehr/generic-sensor-format/blob/master/doc/GSF_lib_03-06.pdfGeneric Sensor Format C library v3.06 specification: see e.g.https://github.com/schwehr/generic-sensor-format/blob/master/doc/GSF_spec_03-06.pdfMore recent versions of these documents can be downloaded from theLeidoswebsite.Dev SetupEnsure Poetry is installed before proceedingPoetry (Recommended)By default Poetry will create it's own virtual environment using your system's Python.This feature can be disabled.gitclonegit@github.com:UKHO/gsfpy.gitcdgsfpy
poetryinstallPyenvA good choice if you want to run a version of Python different than available through your system's package managergitclonegit@github.com:UKHO/gsfpy.gitcdgsfpy
pyenvinstall3.8.3
pyenvvirtualenv3.8.3gsfpy
pyenvlocalgsfpy
poetryinstallRun TestsmaketestRun ChecksmakelintNotes on SecuritySome known concerns relating to the underlying GSFlib C library are
documented athttps://github.com/dwcaress/MB-System/issues/368andhttps://github.com/schwehr/generic-sensor-format/issues. Note that
gsfpy simply wraps GSFlib and does not purport to stop or mitigate these
potential vulnerabilities. It is left to the authors of applications
calling gsfpy to assess these risks and mitigate where deemed necessary.GSF data processed using gsfpy should be sourced from reliable providers
and checked for integrity where possible.Please also refer to the LICENSE file for the terms of use of gsfpy.Creditslibgsf03-08.sowas built from theLeidosC code using the
Makefile inUKHO/libgsfThis package was created withCookiecutterand theUKHO/cookiecutter-pypackageproject template.Related ProjectsAlso seeschwehr/generic-sensor-format