Package: komle-witslm-client
Komle WITSML Clientkomle-witsml-client is forked fromkomle-pluswith based fromkomle, a python library for WITSML, usesPyXB-Eto marshal/unmarshal xml files according to the schemas.What is this fork for?:At work I use some closed source tools that use Komle - some of which I keep. This repository has the necessary patches for komle to work for me. Intend to have a published copy of PyPI available and an automated test pipeline.Some of the features are:WITSML data model bindings for schema v1.3.1.1, v1.4.1.0, v1.4.1.1 and v2.0Notejust one version can be used in the same runtime, due to namespace collisionWITSML to dict, for use in a pandas dataframe or jsonUnit converter based onwitsmlUnitDictSoap client to request data from a witsml server, according to thewebservice descriptionValidation that xml files conforms to the WITSML schemaSupport for the generated write schemas, to be used for WMLS_AddToStoreNotethat write_bindings can not be imported at the same time as read_bindings. See below for details.Instalation by GitHubPre-requisites:poetry >= 1.0python >= 3.9GNU Make >= 4.3gitclonehttps://github.com/nqtung/komle-witsml-client/if the repo is clonedmakeinstallInstalation by PyPIpipinstallkomle-witslm-clientGetting startedfromkomle.bindings.v1411.readimportwitsml
fromkomleimportutilsasku
importpandasaspd# Not part of komle setupwithopen('log.xml','r')aslog_file:# logs is a regular python object according to the witsml schemalogs=witsml.CreateFromDocument(log_file.read())# Print the witsml documentation for logsprint(logs._element().documentation())# Print the schema location for logCurveInfo, nice to have for referenceprint(logs.log[0].logCurveInfo[0]._element().xsdLocation().locationBase)print([l.nameforlinlogs.log])# Convert logdata to a dictlog=logs.log[0]data_dict=ku.logdata_dict(log)# Create a dataframe, if you have installed pandasdf_data=pd.DataFrame(data_dict)# Do the same for the plural logCurveInfo elementdf_curve=pd.DataFrame(ku.plural_dict(log.logCurveInfo))witsml.CreateFromDocumentworks on any witsml object, like trajectorys, mudLogs, tubulars etc, and returns a python representation according to
the schema. Nodes are converted to there corresponding python types and accessed like any other python object, the exception is leaf nodes with attributes where one must callvalue()since primitive types in python does not have custom attributes. For examplemdTop.value()where mdTop also has the attributemdTop.uom, also seeexamples/hello_witsml.py.Usage of different schemasThe difference between the schemas is describedhere. In summary,Read Schemas: [...] a copy of the normative files except that all choices, elements and attributes are optional. [...] these schema files must represent the XMLout response from the WITSML WMLS_GetFromStore method.Write Schemas: [...] a copy of the normative files except that some unique identifier attributes have had their optionality changed. [...] these schema files must represent the XMLin input to the WITSML WMLS_AddToStore method.Update Schemas(not currently supported): [...] a copy of the normative files with all elements and attributes optional except that all unique identifier attributes and uom attributes are mandatory. [...] these schema files must represent the XMLin input to the WITSML WMLS_UpdateInStore method.Delete Schemas(not currently supported): [...] a copy of the normative files with all elements and attributes optional except for all object uids and parentage-pointers which are mandatory. [...] these schema files must represent the QueryIn input to the WITSML WMLS_DeleteFromStore method.As a practical matter, any program needing to work on both read and write (and update/delete) should only import thereadbindings, since they have the least restrictions. The read bindings will be valid also for write/update/delete, as long as the mandatory elements and attributes are present. For validation of the write schema, a separate test program which only imports the write bindings must be used. (Note that the multiprocessing module can not easily be used for this purpose, since the child processes will inherit the parent process' imports.)