我正在尝试将Python金字塔应用移植到Heroku。
我必须承认,我不理解Python应用程序的文件结构,即使在阅读了这个信息非常丰富的帖子后,似乎它包含了所有答案:https://what.thedailywtf.com/topic/18922/python-project-structure/27
我已经完成了所有设置,因此我可以将源更新推送到Heroku并尝试构建。由于显然缺少“主要”属性,整个过程正在崩溃。我不知道从哪里开始这个问题,因为我不知道'主要'是什么,它的结构应该是什么,或者它应该驻留在哪个文件中。
我已经粘贴了我认为下面的相关内容,但请告诉我,如果我遗漏了一些可能有用的内容。
我正在尝试按照此处的说明操作:http://docs.pylonsproject.org/projects/pyramid_cookbook/en/latest/deployment/heroku.html
文件结构:
Procfile
run
runapp.py
wsgi.py
--->/corefinance/
----setup.py
----production.ini
------->/corefinance/
--------__init__.py
Heroku构建错误:
2016-10-10T04:44:45.496214+00:00 app[web.1]:
2016-10-10T04:44:45.496215+00:00 app[web.1]: Using /app/.heroku/python/lib/python3.5/site-packages
2016-10-10T04:44:45.497067+00:00 app[web.1]: Searching for zope.deprecation==4.1.1
2016-10-10T04:44:45.497245+00:00 app[web.1]: Best match: zope.deprecation 4.1.1
2016-10-10T04:44:45.497356+00:00 app[web.1]: Adding zope.deprecation 4.1.1 to easy-install.pth file
2016-10-10T04:44:45.497742+00:00 app[web.1]:
2016-10-10T04:44:45.497745+00:00 app[web.1]: Using /app/.heroku/python/lib/python3.5/site-packages
2016-10-10T04:44:45.498530+00:00 app[web.1]: Searching for Mako==1.0.0
2016-10-10T04:44:45.498709+00:00 app[web.1]: Best match: Mako 1.0.0
2016-10-10T04:44:45.498818+00:00 app[web.1]: Adding Mako 1.0.0 to easy-install.pth file
2016-10-10T04:44:45.503267+00:00 app[web.1]: Installing mako-render script to /app/.heroku/python/bin
2016-10-10T04:44:45.503522+00:00 app[web.1]:
2016-10-10T04:44:45.503524+00:00 app[web.1]: Using /app/.heroku/python/lib/python3.5/site-packages
2016-10-10T04:44:45.503725+00:00 app[web.1]: Finished processing dependencies for corefinance==0.0
2016-10-10T04:44:46.082134+00:00 app[web.1]: Traceback (most recent call last):
2016-10-10T04:44:46.082145+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.5/site-packages/setuptools-25.2.0-py3.5.egg/pkg_resources/__init__.py", line 2238, in resolve
2016-10-10T04:44:46.082291+00:00 app[web.1]: AttributeError: module 'corefinance' has no attribute 'main'
2016-10-10T04:44:46.082295+00:00 app[web.1]:
2016-10-10T04:44:46.082296+00:00 app[web.1]: During handling of the above exception, another exception occurred:
2016-10-10T04:44:46.082297+00:00 app[web.1]:
2016-10-10T04:44:46.082299+00:00 app[web.1]: Traceback (most recent call last):
2016-10-10T04:44:46.082334+00:00 app[web.1]: File "runapp.py", line 8, in <module>
2016-10-10T04:44:46.082511+00:00 app[web.1]: app = loadapp('config:production.ini', relative_to='./corefinance/')
2016-10-10T04:44:46.082519+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.5/site-packages/paste/deploy/loadwsgi.py", line 247, in loadapp
2016-10-10T04:44:46.082666+00:00 app[web.1]: return loadobj(APP, uri, name=name, **kw)
2016-10-10T04:44:46.082668+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.5/site-packages/paste/deploy/loadwsgi.py", line 271, in loadobj
2016-10-10T04:44:46.082894+00:00 app[web.1]: global_conf=global_conf)
2016-10-10T04:44:46.082898+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.5/site-packages/paste/deploy/loadwsgi.py", line 296, in loadcontext
2016-10-10T04:44:46.083142+00:00 app[web.1]: global_conf=global_conf)
2016-10-10T04:44:46.083165+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.5/site-packages/paste/deploy/loadwsgi.py", line 320, in _loadconfig
2016-10-10T04:44:46.083511+00:00 app[web.1]: return loader.get_context(object_type, name, global_conf)
2016-10-10T04:44:46.083514+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.5/site-packages/paste/deploy/loadwsgi.py", line 454, in get_context
2016-10-10T04:44:46.083857+00:00 app[web.1]: section)
2016-10-10T04:44:46.083862+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.5/site-packages/paste/deploy/loadwsgi.py", line 476, in _context_from_use
2016-10-10T04:44:46.084217+00:00 app[web.1]: object_type, name=use, global_conf=global_conf)
2016-10-10T04:44:46.084221+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.5/site-packages/paste/deploy/loadwsgi.py", line 406, in get_context
2016-10-10T04:44:46.084536+00:00 app[web.1]: global_conf=global_conf)
2016-10-10T04:44:46.084539+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.5/site-packages/paste/deploy/loadwsgi.py", line 296, in loadcontext
2016-10-10T04:44:46.084822+00:00 app[web.1]: global_conf=global_conf)
2016-10-10T04:44:46.084826+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.5/site-packages/paste/deploy/loadwsgi.py", line 328, in _loadegg
2016-10-10T04:44:46.085119+00:00 app[web.1]: return loader.get_context(object_type, name, global_conf)
2016-10-10T04:44:46.085123+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.5/site-packages/paste/deploy/loadwsgi.py", line 620, in get_context
2016-10-10T04:44:46.085560+00:00 app[web.1]: object_type, name=name)
2016-10-10T04:44:46.085561+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.5/site-packages/paste/deploy/loadwsgi.py", line 646, in find_egg_entry_point
2016-10-10T04:44:46.086013+00:00 app[web.1]: possible.append((entry.load(), protocol, entry.name))
2016-10-10T04:44:46.086015+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.5/site-packages/setuptools-25.2.0-py3.5.egg/pkg_resources/__init__.py", line 2230, in load
2016-10-10T04:44:46.086217+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.5/site-packages/setuptools-25.2.0-py3.5.egg/pkg_resources/__init__.py", line 2240, in resolve
2016-10-10T04:44:46.086408+00:00 app[web.1]: ImportError: module 'corefinance' has no attribute 'main'
运行
#!/bin/bash
set -e
python ./corefinance/setup.py develop
python runapp.py
runapp.py
import os
from paste.deploy import loadapp
from waitress import serve
if __name__ == "__main__":
port = int(os.environ.get("PORT", 5000))
app = loadapp('config:production.ini', relative_to='./corefinance/')
serve(app, host='0.0.0.0', port=port)
./ corefinance / setup.py
import os
from setuptools import setup, find_packages
here = os.path.abspath(os.path.dirname(__file__))
with open(os.path.join(here, 'README.txt')) as f:
README = f.read()
with open(os.path.join(here, 'CHANGES.txt')) as f:
CHANGES = f.read()
requires = [
'setuptools',
'markupsafe',
'pyramid',
'pyramid_chameleon',
'pyramid_debugtoolbar',
'pyramid_tm',
'SQLAlchemy',
'transaction',
'zope.sqlalchemy',
'waitress',
'docutils',
'pyramid_exclog',
'cryptacular',
'pycrypto',
'webtest',
]
setup(name='corefinance',
version='0.0',
description='corefinance',
long_description=README + '\n\n' + CHANGES,
classifiers=[
"Programming Language :: Python",
"Framework :: Pyramid",
"Topic :: Internet :: WWW/HTTP",
"Topic :: Internet :: WWW/HTTP :: WSGI :: Application",
],
author='',
author_email='',
url='',
keywords='web wsgi bfg pylons pyramid',
packages=find_packages(),
include_package_data=True,
zip_safe=False,
test_suite='corefinance',
install_requires=requires,
entry_points="""\
[paste.app_factory]
main = corefinance:main
[console_scripts]
initialize_corefinance_db = corefinance.scripts.initializedb:main
""",
)
./ corefinance / corefinance /的初始化的.py
from pyramid.config import Configurator
from sqlalchemy import engine_from_config
from configparser import SafeConfigParser
import os
from pyramid.authentication import AuthTktAuthenticationPolicy
from pyramid.authorization import ACLAuthorizationPolicy
from pyramid.session import SignedCookieSessionFactory
from .security import groupfinder
from sqlalchemy import engine_from_config
from corefinance.models.meta import DBSession
from corefinance.models.utilities import RootFactory
from corefinance.models.meta import Base
def main(global_config, **settings):
""" This function returns a Pyramid WSGI application.
"""
parser = SafeConfigParser()
db_ini_file = settings['db_ini_file']
iniloc = os.path.abspath(os.path.join(os.path.dirname( __file__ ), '..', db_ini_file))
read_list = parser.read(iniloc)
connstring = parser.get('postgres', 'connstring')
settings['sqlalchemy.url'] = connstring
engine = engine_from_config(settings, 'sqlalchemy.')
DBSession.configure(bind=engine)
session_factory = SignedCookieSessionFactory(
settings['session.secret']
)
authn_policy = AuthTktAuthenticationPolicy(
settings['session.secret'], callback=groupfinder, hashalg='sha512')
authz_policy = ACLAuthorizationPolicy()
config = Configurator(
settings=settings,
root_factory=RootFactory,
authentication_policy=authn_policy,
authorization_policy=authz_policy,
session_factory=session_factory
)
Base.metadata.bind = engine
config.include('pyramid_chameleon')
config.include(addroutes)
config.scan()
return config.make_wsgi_app()
答案 0 :(得分:2)
我认为没有明确的理由不起作用。但是你可以改进一些事情。
1)大多数setup.py
个文件都希望从自己的目录中执行。当你运行python some_folder/setup.py develop
时,你要求的是一段糟糕的时间。 pip
为您解决了这个问题,您应该通过pip install -e some_folder
切换到它。
2)确保与__init.py__
位于同一文件夹中的setup.py
不会因为runapp.py
脚本中依赖PYTHONPATH
的内容而造成混淆}发现代码,当前文件夹通常在路径上,这意味着您的setup.py
文件夹可以被视为一个包(在main
中找不到__init__.py
。
计算出这些东西的一个重大考验就是尝试在失败的同一环境中运行python
并尝试import corefinance
并看看你得到了什么。这应该为你提供一些线索,说明它为什么不起作用。