I develop a nameko http micro servie, and it can run well, but if I replace the file myhttp.py with a cyphon compiled file named myhttp.py, I will get [curl: (7) Failed to connect to localhost port 8000: Connection refused],please help me.
step 1: use the below 3 files(build.bat,setup.py,myhttp.py) to generate myhttp.pyd
build.bat
python setup.py build_ext --inplace
setup.py
from setuptools import setup
from Cython.Build import cythonize
setup(
name = 'myapp',
ext_modules=cythonize("myhttp.py"),
zip_safe=False,
)
myhttp.py
from nameko.web.handlers import http
import json
class MyHttpService:
name = 'my_http_service'
@http('POST','/hello') #curl -i -d "world" localhost:8000/hello
def hello(self, request):
return "Hello, {}!".format(request.get_data(as_text=True))
step 2: use the below 3 files(installer.bat, namekorun.py, namekorun.spec) and generated myhttp.pyd just now to generate namekorun.exe
installer.bat
pyinstaller --noconfirm namekorun.spec
namekorun.py
import eventlet;
eventlet.monkey_patch()
from nameko.runners import ServiceRunner
import myhttp
import signal
runner = ServiceRunner(config={'WEB_SERVER_ADDRESS': '0.0.0.0:8000'})
runner.add_service(myhttp.MyHttpService)
def shutdown(signum, frame):
# signal handlers are run by the MAINLOOP and cannot use eventlet
# primitives, so we have to call `stop` in a greenlet
eventlet.spawn_n(runner.stop)
signal.signal(signal.SIGTERM, shutdown)
runner.start()
runnlet = eventlet.spawn(runner.wait)
while True:
try:
runnlet.wait()
except OSError as exc:
if exc.errno == errno.EINTR:
# this is the OSError(4) caused by the signalhandler.
# ignore and go back to waiting on the runner
continue
raise
except KeyboardInterrupt:
print() # looks nicer with the ^C e.g. bash prints in the terminal
try:
runner.stop()
except KeyboardInterrupt:
print() # as above
runner.kill()
else:
# runner.wait completed
break
namekorun.spec
# -*- mode: python ; coding: utf-8 -*-
block_cipher = None
partylibs = ['nameko.constants','nameko.containers','nameko.contextdata','nameko.dependency_providers','nameko.events','nameko.exceptions','nameko.extensions','nameko.log_helpers','nameko.messaging','nameko.rpc','nameko.runners','nameko.serialization','nameko.timer','nameko.amqp.publish','nameko.cli.actions','nameko.cli.backdoor','nameko.cli.code','nameko.cli.commands','nameko.cli.main','nameko.cli.run','nameko.cli.shell','nameko.cli.show_config','nameko.standalone.events','nameko.standalone.rpc','nameko.testing.pytest','nameko.testing.rabbit','nameko.testing.services','nameko.testing.utils','nameko.testing.waiting','nameko.testing.websocket','nameko.utils.retry','nameko.utils.concurrency','nameko.web.handlers','nameko.web.server','nameko.web.websocket']
partylibs += ['eventlet','eventlet.hubs.epolls','eventlet.hubs.kqueue','eventlet.hubs.selects']
partylibs += ['dns','dns.dnssec','dns.e164','dns.hash','dns.namedict','dns.tsigkeyring','dns.update','dns.version','dns.zone']
a = Analysis(['namekorun.py'],
pathex=[],
binaries=[],
datas=[],
hiddenimports=partylibs,
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False)
pyz = PYZ(a.pure, a.zipped_data,
cipher=block_cipher)
exe = EXE(pyz,
a.scripts,
[],
exclude_binaries=True,
name='namekorun',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
console=True,
disable_windowed_traceback=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None )
coll = COLLECT(exe,
a.binaries,
a.zipfiles,
a.datas,
strip=False,
upx=True,
upx_exclude=[],
name='namekorun')
step 3: start dist/namekorun/namekorun.exe, then type curl -i -d "world" localhost:8000/hello in a command window, and got curl: (7) Failed to connect to localhost port 8000: Connection refused, if replace myhttp.pyd with myhttp.py, it run well
my package as below and use vs2015
| Package | Version |
|---|---|
| python | 3.6.8 |
| Cython | 3.0.0a9 |
| decorator | 4.4.2 |
| eventlet | 0.25.1 |
| kombu | 4.6.8 |
| nameko | 2.12.0 |
| pyinstaller | 4.7 |
| pyinstaller-hooks-contrib | 2021.4 |
Tracing through the definition of
nameko.web.handlers.http:Essentially it's trying to set attributes on the function object. Cython functions are a different class to regular Python functions, and that class doesn't have an instance dictionary so
setattrwill fail (I'm slightly surprised you don't get an obvious error about this).I therefore would not expect this code to work when compiled with Cython.