def submit(self, code: str, results: str ="<STR_LIT:html>", prompt: dict = None) -> dict:
prompt = prompt if prompt is not None else {}<EOL>odsopen  = b"<STR_LIT>"+self.sascfg.output.encode()+b"<STR_LIT>"+self._sb.HTML_Style.encode()+b"<STR_LIT>"<EOL>odsclose = b"<STR_LIT>"+self.sascfg.output.encode()+b"<STR_LIT>"<EOL>ods      = True;<EOL>mj       = b"<STR_LIT>"<EOL>lstf     = b'<STR_LIT>'<EOL>logf     = b'<STR_LIT>'<EOL>bail     = False<EOL>eof      = <NUM_LIT:5><EOL>bc       = False<EOL>done     = False<EOL>logn     = self._logcnt()<EOL>logcodei = "<STR_LIT>" + logn + "<STR_LIT:;>"<EOL>logcodeo = b"<STR_LIT>" + logn.encode()<EOL>pcodei   = '<STR_LIT>'<EOL>pcodeiv  = '<STR_LIT>'<EOL>pcodeo   = '<STR_LIT>'<EOL>if self.pid == None:<EOL><INDENT>self._sb.SASpid = None<EOL>print("<STR_LIT>")<EOL>return dict(LOG="<STR_LIT>", LST='<STR_LIT>')<EOL><DEDENT>rc = os.waitid(os.P_PID, self.pid, os.WEXITED | os.WNOHANG)<EOL>if rc != None:<EOL><INDENT>self.pid = None<EOL>self._sb.SASpid = None<EOL>return dict(LOG='<STR_LIT>'+str(rc), LST='<STR_LIT>')<EOL><DEDENT>if results.upper() != "<STR_LIT>":<EOL><INDENT>ods = False<EOL><DEDENT>if len(prompt):<EOL><INDENT>pcodei += '<STR_LIT>'<EOL>pcodeo += '<STR_LIT>'<EOL>for key in prompt:<EOL><INDENT>gotit = False<EOL>while not gotit:<EOL><INDENT>var = self.sascfg._prompt('<STR_LIT>'+key+'<STR_LIT:U+0020>', pw=prompt[key])<EOL>if var is None:<EOL><INDENT>raise KeyboardInterrupt<EOL><DEDENT>if len(var) > <NUM_LIT:0>:<EOL><INDENT>gotit = True<EOL><DEDENT>else:<EOL><INDENT>print("<STR_LIT>")<EOL><DEDENT><DEDENT>if prompt[key]:<EOL><INDENT>pcodei += '<STR_LIT>'+key+'<STR_LIT:=>'+var+'<STR_LIT>'<EOL>pcodeo += '<STR_LIT>'+key+'<STR_LIT>'<EOL><DEDENT>else:<EOL><INDENT>pcodeiv += '<STR_LIT>'+key+'<STR_LIT:=>'+var+'<STR_LIT>'<EOL><DEDENT><DEDENT>pcodei += '<STR_LIT>'<EOL>pcodeo += '<STR_LIT>'<EOL><DEDENT>if ods:<EOL><INDENT>self.stdin.write(odsopen)<EOL><DEDENT>pgm  = mj+b'<STR_LIT:\n>'+pcodei.encode(self.sascfg.encoding)+pcodeiv.encode(self.sascfg.encoding)<EOL>pgm += code.encode(self.sascfg.encoding)+b'<STR_LIT:\n>'+pcodeo.encode(self.sascfg.encoding)+b'<STR_LIT:\n>'+mj<EOL>out  = self.stdin.write(pgm)<EOL>if ods:<EOL><INDENT>self.stdin.write(odsclose)<EOL><DEDENT>out = self.stdin.write(b'<STR_LIT:\n>'+logcodei.encode(self.sascfg.encoding)+b'<STR_LIT:\n>')<EOL>self.stdin.flush()<EOL>while not done:<EOL><INDENT>try:<EOL><INDENT>while True:<EOL><INDENT>rc = os.waitid(os.P_PID, self.pid, os.WEXITED | os.WNOHANG)<EOL>if rc is not None:<EOL><INDENT>log = b'<STR_LIT>'<EOL>try:<EOL><INDENT>log = self.stderr.read1(<NUM_LIT>)<EOL>if len(log) > <NUM_LIT:0>:<EOL><INDENT>logf += log<EOL><DEDENT>self._log += logf.decode(self.sascfg.encoding, errors='<STR_LIT:replace>')<EOL><DEDENT>except:<EOL><INDENT>pass<EOL><DEDENT>self.pid = None<EOL>self._sb.SASpid = None<EOL>return dict(LOG='<STR_LIT>' +<EOL>str(rc)+'<STR_LIT:\n>'+logf.decode(self.sascfg.encoding, errors='<STR_LIT:replace>'), LST='<STR_LIT>')<EOL><DEDENT>if bail:<EOL><INDENT>eof -= <NUM_LIT:1><EOL><DEDENT>if eof < <NUM_LIT:0>:<EOL><INDENT>break<EOL><DEDENT>if ods:<EOL><INDENT>lst = self.stdout.read1(<NUM_LIT>)<EOL><DEDENT>else:<EOL><INDENT>lst = self.stdout.read1(<NUM_LIT>)<EOL><DEDENT>if len(lst) > <NUM_LIT:0>:<EOL><INDENT>lstf += lst<EOL><DEDENT>else:<EOL><INDENT>log = self.stderr.read1(<NUM_LIT>)<EOL>if len(log) > <NUM_LIT:0>:<EOL><INDENT>logf += log<EOL>if logf.count(logcodeo) >= <NUM_LIT:1>:<EOL><INDENT>bail = True<EOL><DEDENT>if not bail and bc:<EOL><INDENT>self.stdin.write(odsclose+logcodei.encode(self.sascfg.encoding) + b'<STR_LIT:\n>')<EOL>self.stdin.flush()<EOL>bc = False<EOL><DEDENT><DEDENT><DEDENT><DEDENT>done = True<EOL><DEDENT>except (ConnectionResetError):<EOL><INDENT>log = '<STR_LIT>'<EOL>try:<EOL><INDENT>log = self.stderr.read1(<NUM_LIT>)<EOL>if len(log) > <NUM_LIT:0>:<EOL><INDENT>logf += log<EOL><DEDENT>self._log += logf.decode(self.sascfg.encoding, errors='<STR_LIT:replace>')<EOL><DEDENT>except:<EOL><INDENT>pass<EOL><DEDENT>rc = <NUM_LIT:0><EOL>rc = os.waitpid(self.pid, <NUM_LIT:0>)<EOL>self.pid = None<EOL>self._sb.SASpid = None<EOL>log = logf.partition(logcodeo)[<NUM_LIT:0>]+b'<STR_LIT>'+str(rc).encode()+b'<STR_LIT:\n>'+logf<EOL>return dict(LOG=log.encode(), LST='<STR_LIT>')<EOL><DEDENT>except (KeyboardInterrupt, SystemExit):<EOL><INDENT>print('<STR_LIT>')<EOL>ll = self._breakprompt(logcodeo)<EOL>if ll.get('<STR_LIT>', False):<EOL><INDENT>return ll<EOL><DEDENT>logf += ll['<STR_LIT>']<EOL>lstf += ll['<STR_LIT>']<EOL>bc    = ll['<STR_LIT>']<EOL>if not bc:<EOL><INDENT>print('<STR_LIT>')<EOL><DEDENT>else:<EOL><INDENT>print('<STR_LIT>')<EOL><DEDENT>self.stdin.write(odsclose+logcodei.encode(self.sascfg.encoding)+b'<STR_LIT:\n>')<EOL>self.stdin.flush()<EOL><DEDENT><DEDENT>if ods:<EOL><INDENT>try:<EOL><INDENT>lstf = lstf.decode()<EOL><DEDENT>except UnicodeDecodeError:<EOL><INDENT>try:<EOL><INDENT>lstf = lstf.decode(self.sascfg.encoding)<EOL><DEDENT>except UnicodeDecodeError:<EOL><INDENT>lstf = lstf.decode(errors='<STR_LIT:replace>')<EOL><DEDENT><DEDENT><DEDENT>else:<EOL><INDENT>lstf = lstf.decode(self.sascfg.encoding, errors='<STR_LIT:replace>')<EOL><DEDENT>logf = logf.decode(self.sascfg.encoding, errors='<STR_LIT:replace>')<EOL>trip = lstf.rpartition("<STR_LIT>")<EOL>if len(trip[<NUM_LIT:1>]) > <NUM_LIT:0> and len(trip[<NUM_LIT:2>]) < <NUM_LIT:100>:<EOL><INDENT>lstf = '<STR_LIT>'<EOL><DEDENT>self._log += logf<EOL>final = logf.partition(logcodei)<EOL>z = final[<NUM_LIT:0>].rpartition(chr(<NUM_LIT:10>))<EOL>prev = '<STR_LIT>' %  (self._log_cnt - <NUM_LIT:1>)<EOL>zz = z[<NUM_LIT:0>].rpartition("<STR_LIT>" + prev +'<STR_LIT:\n>')<EOL>logd = zz[<NUM_LIT:2>].replace(mj.decode(self.sascfg.encoding), '<STR_LIT>')<EOL>lstd = lstf.replace(chr(<NUM_LIT:12>), chr(<NUM_LIT:10>)).replace('<STR_LIT>',<EOL>'<STR_LIT>').replace("<STR_LIT>",<EOL>"<STR_LIT>")<EOL>return dict(LOG=logd, LST=lstd)<EOL>
This method is used to submit any SAS code. It returns the Log and Listing as a python dictionary.
code    - the SAS statements you want to execute
results - format of results, HTML is default, TEXT is the alternative
prompt  - dict of names:flags to prompt for; create macro variables (used in submitted code), then keep or delete
          The keys are the names of the macro variables and the boolean flag is to either hide what you type and delete
          the macros, or show what you type and keep the macros (they will still be available later)
          for example (what you type for pw will not be displayed, user and dsname will):

          results = sas.submit(
             """
             libname tera teradata server=teracop1 user=&user pw=&pw;
             proc print data=tera.&dsname (obs=10); run;
             """ ,
             prompt = {'user': False, 'pw': True, 'dsname': False}
             )

Returns - a Dict containing two keys:values, [LOG, LST]. LOG is text and LST is 'results' (HTML or TEXT)

NOTE: to view HTML results in the ipykernel, issue: from IPython.display import HTML  and use HTML() instead of print()
i.e,: results = sas.submit("data a; x=1; run; proc print;run')
      print(results['LOG'])
      HTML(results['LST'])