Package: jeng
JengA simple WITSML client with utilities.If you encounter any issues, please report them promptlyhere. Additionally, feel free to request any necessary featureshere.Installationpip install jengGetting startedJeng should be compatible with Python 3.8 and higher.Jeng should work with WITSML data schema v1.3.1.1 and v1.4.1.1.Jeng should work the same for both TIME log type and DEPTH log type.Log curve info list is not technically required for TIME log type. For DEPTH log type, the index log curve info is required. Thus, log curve info is set to required forgenerate.generate_log_query()to ensure the API stays consistent and not confusing.Incompatible package version update:0.0.6to0.0.7: Change fromjeng.client.WitsmlClientpackage tojeng.jeng.WitsmlClientClientTo create and connect to WITSML Server:fromjengimportjengclient=jeng.WitsmlClient()# return True if success, else Falsestatus=client.connect(url=CONNECTION_URL,username=CONNECTION_USERNAME,password=CONNECTION_PASSWORD,)To call wrapper API (make sure to connect to WTISML Server first):# send query to WMLS_AddToStore APIwithopen(f"{QUERY_PATH}/query.xml","r")asquery:reply=client.add_to_store(wml_type_in="well",xml_in=query.read(),)# send query to WMLS_UpdateInStore APIwithopen(f"{QUERY_PATH}/query.xml","r")asquery:reply=client.update_in_store(wml_type_in="well",xml_in=query.read(),)# send query to WMLS_GetFromStore APIwithopen(f"{QUERY_PATH}/query.xml","r")asquery:reply=client.get_from_store(wml_type_in="well",xml_in=query.read(),return_element="all",)# send query to WMLS_DeleteFromStore APIwithopen(f"{QUERY_PATH}/query.xml","r")asquery:reply=client.delete_from_store(wml_type_in="well",xml_in=query.read(),)# string is expected for xml_in and you can# pass string query to all the wrapper APIclient.add_to_store(wml_type_in="well",xml_in=query_xml_str,)To call other WITSML APIs than provided wrapper APIs (make sure to connect to WTISML Server first):# send WMLS_GetVersion directly from Jeng client servicereply=client.service().WMLS_GetVersion()Log Query Generatorfromjengimportmodel,generate# set log basic infolog_basic_info=model.LogBasicInfoModel(well_uid="WELL_001",well_name="WELL 001",wellbore_uid="WELLBORE_001",wellbore_name="WELLBORE 001",log_uid="LOG_001",log_name="LOG 001",)# set time log curve infolog_curve_info_list=[model.LogCurveInfoModel(uid="TIME",mnemonic="TIME",unit="s",curve_description="Time",type_log_data="date time",index_type="date time",is_index_curve=True,),model.LogCurveInfoModel(uid="HKLA",mnemonic="HKLA",unit="klbf",curve_description="Average Hookload",type_log_data="double",),...]# set depth log curve infolog_curve_info_list=[model.LogCurveInfoModel(uid="DEPTH",mnemonic="DEPTH",unit="m",curve_description="Depth Index",type_log_data="double",index_type="measured depth",is_index_curve=True,),model.LogCurveInfoModel(uid="HKLA",mnemonic="HKLA",unit="klbf",curve_description="Average Hookload",type_log_data="double",),...]...# generate very basic query (log curve info list is optional)query_xml=generate.generate_log_query(log_basic_info=log_basic_info,)# generate query (make sure to use mnemonic as column name)query_xml=generate.generate_log_query(log_basic_info=log_basic_info,log_curve_info_list=log_curve_info_time_list,dataframe=dataframe,)# it's possible to generate WMLS_GetFromStore compatible# query with specific time intervalquery_xml=generate.generate_log_query(log_basic_info=log_basic_info,log_curve_info_list=log_curve_info_time_list,log_index=model.LogIndexModel(start="2020-06-30T17:44:00.000+08:00",end="2020-06-30T17:45:00.000+08:00",),)# it's possible to generate WMLS_GetFromStore compatible# query with specific non-time intervalquery_xml=generate.generate_log_query(log_basic_info=log_basic_info,log_curve_info_list=log_curve_info_depth_list,log_index=model.LogIndexModel(start="2575.2",end="2575.5",type=model.LogIndexTypeEnum.NON_TIME,),)Log Reply Parserfromjengimportparse...# parse WITSML XMLout reply data into dataframedataframe=parse.parse_log_into_dataframe(xml_out=reply["XMLout"],)# parse WITSML XMLout reply into model.LogCurveInfoModellog_curve_info_list=parse.parse_log_into_curve_info(xml_out=reply["XMLout"],)TestMake sure to have a WITSML server running for the test.Clone the project:gitclonehttps://github.com/nazebzurati/jeng.gitPrepare environment:# create environment and activatevirtualenvenv
.\env\Scripts\activate# on Windowssource.\env\bin\activate# on Mac and Linux# install development dependenciespipinstall-e.[dev]# bashpipinstall-e.\[dev\]# zshChange the source code and test.# formattingisort.--skipenv&&black--line-length120.# run coverage and pytestcoveragerun-mpytest-v
coveragerun-mpytest-mintegration-v# test with WITSML server integrationcoveragerun-mpytest-munit-v# test without WITSML server integration# run static code testcoveragexml&&sonar-scanner.bat-D"sonar.projectKey=<project-key>"-D"sonar.sources=."-D"sonar.host.url=<host-url>"-D"sonar.login=<project-token>"