Q:

Calling and Running Another python script and running all the code from it

I am writing a python script on jupyter where the first script: a.ipynb has the majority of the analysis within, and multiple other scripts, which include the data cleaning [b.ipynb, c.ipynb, d.ipynb etc]. I am trying to call the data cleaning scripts [b.ipynb, c.ipynb, d.ipynb etc] into a.ipynb, but it keeps throwing errors. 
I have tried some various different ways to read the data but these all are throwing errors:
subprocess.getoutput([sys.executable,'d.ipynb'])

Error: "execution_count": null,\nNameError: name \'null\' is not defined'

b_checks = open("d.ipynb", 'r').read()
exec(b_checks)

---> 21     exec(b_checks)
NameError: name 'null' is not defined

exec(open('d.ipynb').read())

NameError: name 'null' is not defined

Currently, I am conditionally calling the scripts based on variable value as the data is imported from SQL and has multiple different properties prop
# a.ipynb

prop = 'y'
#function to call data: checks
b_checks = checks(dbcon,prop)

if prop == 'w':
    b_checks = subprocess.getoutput([sys.executable, 'b.ipynb'])
elif prop =='x':
    b_checks = subprocess.getoutput([sys.executable, 'c.ipynb'])
elif prop == 'y':
    b_checks = subprocess.getoutput([sys.executable,'d.ipynb'])
elif prop == 'z':
    b_checks = subprocess.getoutput([sys.executable, 'e.ipynb'])

and the script I am trying to call at the moment is d.ipynb which includes the data cleaning of a certain column.
#d.ipynb
def  replace_server(to_r, server):
    return b_checks['Server'].str.replace(to_r, server)

b_checks['Server'] = b_checks['Server'].str.upper()
b_checks['Server'] = b_checks['Server'].str.strip()

b_checks['Server'] = replace_server('xxxx', 'x')
b_checks['Server'] = replace_server('123', 'x')

(there are more lines within this script)
My Current output of b_checks in the uncleaned dataset xxxx, 123, but the output I am hoping for is to run the entire second script d.ipynb so that the first script a.ipynb updates the variables in the b_checks table

A:

it's a good practice to make a kind of API in another notebook:
say you have a func() in b.ipynb, and you need to call it from a.ipnyb, then 'a' notebook should contain:
%run ./b.ipynb
func()

