parser/healthcareio/__main__.py

214 lines
6.6 KiB
Python
Raw Normal View History

2024-02-06 03:56:46 +00:00
#!/usr/bin/env python
2019-11-06 20:37:26 +00:00
"""
(c) 2019 EDI Parser Toolkit,
Health Information Privacy Lab, Vanderbilt University Medical Center
Steve L. Nyemba <steve.l.nyemba@vanderbilt.edu>
Khanhly Nguyen <khanhly.t.nguyen@gmail.com>
This code is intended to process and parse healthcare x12 837 (claims) and x12 835 (remittances) into human readable JSON format.
The claims/outpout can be forwarded to a NoSQL Data store like couchdb and mongodb
Usage :
Commandline :
2024-02-06 03:56:46 +00:00
# parse {x12}
healthcare-io parse <x12_folder>
# export {x12}
healthcare-io export
2023-12-07 19:00:16 +00:00
-
2019-11-06 20:37:26 +00:00
Embedded :
"""
2020-09-16 15:58:32 +00:00
# import healthcareio
2023-12-07 19:00:16 +00:00
import typer
from typing import Optional
from typing_extensions import Annotated
import uuid
import os
2024-02-06 03:56:46 +00:00
import meta
2023-12-07 19:00:16 +00:00
import json
import time
from healthcareio import x12
from healthcareio.x12.parser import X12Parser
2024-02-06 03:56:46 +00:00
import requests
2024-02-06 18:37:55 +00:00
import pandas as pd
import numpy as np
2023-12-07 19:00:16 +00:00
# import healthcareio
# import healthcareio.x12.util
# from healthcareio.x12.parser import X12Parser
app = typer.Typer()
CONFIG_FOLDER = os.sep.join([os.environ['HOME'],'.healthcareio'])
2024-02-06 18:37:55 +00:00
HOST = "https://healthcareio.the-phi.com" if 'PARSER_HOST_URL' not in os.environ else os.environ['PARSER_HOST_URL']
2023-12-07 19:00:16 +00:00
@app.command(name='init')
def config(email:str,provider:str='sqlite') :
2024-02-06 03:56:46 +00:00
"""\b
2023-12-07 19:00:16 +00:00
Generate configuration file needed with default data store. For supported data-store providers visit https://hiplab.mc.vanderbilt.edu/git/hiplab/data-transport.git
:email your email
2024-02-06 03:56:46 +00:00
:provider data store provider (visit https://hiplab.mc.vanderbilt.edu/git/hiplab/data-transport.git)
2023-12-07 19:00:16 +00:00
"""
_db = "healthcareio"
2024-02-06 18:37:55 +00:00
global CONFIG_FOLDER
2023-12-07 19:00:16 +00:00
# _PATH = os.sep.join([os.environ['HOME'],'.healthcareio'])
if not os.path.exists(CONFIG_FOLDER) :
os.mkdir(CONFIG_FOLDER)
if provider in ['sqlite','sqlite3'] :
_db = os.sep.join([CONFIG_FOLDER,_db+'.db3'])
_config = {
"store":{
"provider":provider,"database":_db,"context":"write"
},
"plugins":None,
"system":{
"uid":str(uuid.uuid4()),
"email":email,
2024-02-06 03:56:46 +00:00
"version":meta.__version__,
"copyright":meta.__author__
2023-12-07 19:00:16 +00:00
}
}
#
2024-02-06 03:56:46 +00:00
# Let create or retrieve a user's key/token to make sure he/she has access to features they need
# This would also allow us to allow the users to be informed of new versions
#
try:
2024-02-06 18:37:55 +00:00
global HOST
# HOST = "https://healthcareio.the-phi.com" if 'PARSER_HOST_URL' not in os.environ else os.environ['PARSER_HOST']
url = f"{HOST}/api/users/signup"
2024-02-06 03:56:46 +00:00
_body = {"email":email,"version":meta.__version__}
_headers = {"content-type":"application/json"}
resp = requests.post(url,headers=_headers,data=json.dumps(_body))
if resp.ok :
_config['system'] = dict(_config['system'],**resp.json())
except Exception as e:
print (e)
pass
2023-12-07 19:00:16 +00:00
# store this on disk
f = open(os.sep.join([CONFIG_FOLDER,'config.json']),'w')
f.write(json.dumps(_config))
f.close()
2024-02-06 03:56:46 +00:00
_msg = f"""
Thank you for considering using our {{x12}} parser verion {meta.__version__}
The generatted configuration file found at {CONFIG_FOLDER}
The database provider is {provider}
2024-02-06 18:37:55 +00:00
visit {HOST} to learn more about the features,
2024-02-06 03:56:46 +00:00
"""
print (_msg)
2023-12-07 19:00:16 +00:00
@app.command(name='about')
def copyright():
2024-02-09 15:06:00 +00:00
f"""
2024-02-09 15:04:27 +00:00
This function will return information about the {meta.__name__}
"""
2024-02-06 03:56:46 +00:00
for note in [meta.__name__,meta.__author__,meta.__license__]:
2023-12-07 19:00:16 +00:00
print (note)
pass
@app.command()
def parse (claim_folder:str,plugin_folder:str = None,config_path:str = None):
"""
2024-02-06 03:56:46 +00:00
This function will parse 837 and or 835 claims given a location of parsing given claim folder and/or plugin folder.
plugin_folder folder containing user defined plugins (default are loaded)
config_path default configuration path
2023-12-07 19:00:16 +00:00
"""
_plugins,_parents = x12.plugins.instance(path=plugin_folder)
_files = x12.util.file.Location.get(path=claim_folder,chunks=10)
_path = config_path if config_path else os.sep.join([CONFIG_FOLDER,'config.json'])
if os.path.exists(_path) :
f = open(_path)
_config = json.loads(f.read())
f.close()
_store = _config['store']
2024-02-06 03:56:46 +00:00
# # print (len(_files))
2023-12-07 19:00:16 +00:00
jobs = []
for _chunks in _files:
pthread = X12Parser(plugins=_plugins,parents=_parents,files=_chunks, store=_store)
pthread.start()
jobs.append(pthread)
while jobs :
jobs = [pthread for pthread in jobs if pthread.is_alive()]
time.sleep(1)
2024-02-06 03:56:46 +00:00
# pass
# else:
# pass
2024-02-06 20:58:31 +00:00
print ()
print (" PARSED ")
2024-02-06 03:56:46 +00:00
print ("...................... FINISHED .........................")
2023-12-07 19:00:16 +00:00
#
#
2024-02-06 18:37:55 +00:00
@app.command()
def check():
"""
This function checks for the version running against the current version
"""
_info = [meta.__version__,None]
url = f'{HOST}/api/store/version'
try:
resp= requests.post(url)
_info[1] = resp.text if resp.status_code == 200 else "NA"
except Exception as e:
_info[1] = "NA"
pass
if _info[1] == "NA" :
_msg = "Unavailable server (unreachable)"
else:
_msg = ""
print ()
_info =pd.DataFrame(_info,columns=["versions"],index=["Yours","Current"])
print (_info)
print (_msg)
2024-02-06 03:56:46 +00:00
@app.command(name="export")
def publish (file_type:str,path:str):
"""
This function will export to a different database
file_type values are either claims or remits
path path to export configuration (data transport file)
file_type claims or remits (835 or 837)
2024-02-06 03:56:46 +00:00
"""
_type = None
if file_type.strip() in ['837','claims'] :
2024-02-06 03:56:46 +00:00
_type = 'claims'
_x12 = '837'
elif file_type.strip() in ['835','remits']:
2024-02-06 03:56:46 +00:00
_type = 'remits'
_x12 = '835'
if _type :
_store = {'source':os.sep.join([CONFIG_FOLDER,'config.json']),'target':path}
for _key in _store :
f = open(_store[_key])
_store[_key] = json.loads(f.read())
f.close()
_store['source'] = _store['source']['store']
_plugins,_parents = x12.plugins.instance()
x12.publish.init(plugins=_plugins,x12=_x12,store=_store)
else:
print ("Can not determine type, (837 or 835)")
2024-02-06 20:58:31 +00:00
print ()
print (" EXPORT ")
print ("...................... FINISHED .........................")
2024-02-06 03:56:46 +00:00
2023-12-07 19:00:16 +00:00
if __name__ == '__main__' :
app()