I have simplified my problem into this:
├── demo
│ ├── mypkg
│ │ ├── a.py
│ │ ├── b.py
│ │ └── api.py
│ │ └── startserver.py
│ └── readme.md
a.py has =>
from b import name
def greeting():
return name()
b.py has =>
def name():
return 'Joe'
api.py has =>
import hug
from a import greeting
@hug.get('/ping')
def ping():
return {"response": "pong"}
@hug.get('/hello')
def hello():
#name = hello()
return {"response": greeting()}
startserver.py has =>
import subprocess
with open('testapi.log', 'w') as fd:
subprocess.run(['hug', '-f', 'api.py'], stdout=fd , stderr=subprocess.STDOUT, bufsize=0)
Using .venv in VSCode terminal from \demo\mypkg> on windows 10 either of the following two commands work great, so that browser can see both /ping and /hello results just fine:
\demo\mypkg> hug -f api.py
\demo\mypkg> python startserver.py
I want to be able to run this from outside mypkg, so to the folder "mypkg" I added init & main also changed to relative imports, now I have:
├── demo
│ ├── mypkg
│ │ ├── __init__.py
│ │ ├── __main__.py
│ │ ├── a.py
│ │ ├── b.py
│ │ └── api.py
│ │ └── startserver.py
│ └── readme.md
__init__.py has =>
print('inside __init__.py')
__all__ = [
"a",
"b",
"api",
"startserver"
]
from . import *
__main__.py has =>
print('inside __main__.py')
import traceback
from .startserver import start
def main():
try:
start()
except Exception:
print(traceback.format_exc())
if __name__ == "__main__":
print('... inside name == main ...')
main()
a.py has =>
from .b import name
def greeting():
return name()
b.py has =>
def name():
return 'Joe'
api.py has =>
import hug
from .a import greeting
@hug.get('/ping')
def ping():
return {"response": "pong"}
@hug.get('/hello')
def hello():
#name = hello()
return {"response": greeting()}
startserver.py has =>
import subprocess
import traceback
import os
from pathlib import Path
def start():
try:
currentpath = Path(__file__)
print(f'Currently executing from {currentpath}')
apipath = os.path.join(currentpath.parent, 'api.py')
print(f'parse api path is {apipath}')
print('inside startserver start()')
with open('testapi.log', 'w') as fd:
subprocess.run(['hug', '-f', apipath], stdout=fd , stderr=subprocess.STDOUT, bufsize=0)
except Exception:
print(traceback.format_exc())
then when called with "python -m mypkg"
I get this error:
File "...\demo\mypkg\api.py", line 2, in <module>
from .a import greeting
ImportError: attempted relative import with no known parent package
Reading lots of similar questions here, I figure its probably because of being called directly as a script. Issue is, how can I call the hug api inside a subprocess from outside the package? I need to be able to run this thru pyinstaller to produce a .exe Any help is greatly appreciated, thanks!
From nigh_anxiety link, doing this worked for me:
try:
from .b import name
except ImportError:
from b import name