如何在 OpenShift 上从 mod_wsgi 访问其他文件

How to access other files from mod_wsgi on OpenShift

假设我有以下两个文件:

main.html

<!DOCTYPE html>
<html>
<head>
    <title>Friendly Testing!</title>
    %(HEAD)
</head>
<body>
    %(HEADING)
    Hi! This is just a friendly person being a friendly tester!
</body>
</html>

wsgi.py

#!/usr/bin/env python
import os

def application(environ, start_response):
    # Mimetype
    ctype = 'text/html'
    # File contents as body
    file_contents = [I NEED HELP HERE]
    response_body = b"<header>This is a header!</header>".join( \
        b"<meta charset=\"utf-8\"/>".join( \
            file_contents.split(b"%(HEAD)") \
        ).split(b"%(HEADING)") \
    )

    # Heading
    status = '200 OK'
    response_headers = [ \
        ('Content-Type', ctype), ('Content-Length', str(len(response_body))) \
    ]

    # Send response
    start_response(status, response_headers)
    return [response_body.encode('utf-8') ]

现在,我想将 main.htmlwsgi.py 分开,但获取 main.html 的文件内容并使用它来创建动态网页。我不能将 main.html 作为字节串放入 wsgi.py 中,因为我有 lots of HTML、CSS 和这样的 JS 文件我不能把它放到一个文件中。另外,我不能将其设为静态文件,因为它不是静态文件,即使在本示例中也是如此。我正在使用 Apache+mod_wsgi 并使用 Python 3.3 包在 OpenShift 上托管它。我也在使用 Github 来部署我的应用程序。

我假设有一种方法可以做到这一点,因为肯定有其他人遇到了将他们的代码分成多个文件的问题,但我在 Google 上研究了这个问题后找不到任何解决方案。有人可以帮我吗?谢谢!

您可以通过查看 environ["SCRIPT_FILENAME"] 在 Github 存储库中找到这些文件。该值是一个字符串,其中包含 Github 存储库中 wsgi.py 的文件位置。因此,environ["SCRIPT_FILENAME"][:environ["SCRIPT_FILENAME"].rindex("/")] 是 Github 存储库的目录,您可以从那里找到所有文件。

#!/usr/bin/env python
import os

def application(environ, start_response):
    # Mimetype
    ctype = 'text/html'

    # Directory
    dir = environ["SCRIPT_FILENAME"][:environ["SCRIPT_FILENAME"].rindex("/")]
    # Get File Contents
    file_contents = b""
    with open(dir+"/main.html", "rb") as file:
        file_contents = file.read()

    # Add Dynamic Content
    response_body = b"This is a header!".join( \
        b"".join( \
            file_contents.split(b"%(HEAD)") \
        ).split(b"%(HEADING)") \
    )

    # Heading
    status = '200 OK'
    response_headers = [ \
        ('Content-Type', ctype), ('Content-Length', str(len(response_body))) \
    ]

    # Send Response
    start_response(status, response_headers)
    return [response_body.encode('utf-8') ]

忘记 wsgi.py,它只是初始样板代码。如果您在 wsgi 文件夹中创建应用程序文件,那么 wsgi.py 将被忽略,并且该应用程序文件中定义的 Flask 模块将改为 运行。只需在根目录的 ..\wsgi\ 文件夹中创建一个名为 application 的文件,其中包含以下内容(将末尾的 rafinder 替换为您自己的应用程序名称):

#!/usr/bin/python
import os

virtenv = os.environ['OPENSHIFT_PYTHON_DIR'] + '/virtenv/'
os.environ['PYTHON_EGG_CACHE'] = os.path.join(virtenv, 'lib/python2.7/site-packages')
virtualenv = os.path.join(virtenv, 'bin/activate_this.py')
try:
    execfile(virtualenv, dict(__file__=virtualenv))
except IOError:
    pass

from rafinder import app as application

现在,在 wsgi 目录中创建一个名为 rafinder.py(或您定义的任何名称)的 Flask 模块。现在将从该模块引用所有静态 html/css 文件。您的文件夹结构现在应该如下所示:

wsgi.py
setup.py
.openshift/..
.settings/..
wsgi/..         => your python source files go here.
wsgi/application  => your application definition file.
wsgi/static..   => your static folders viz css, img, fonts, et al. go here.

这是我在我的一个应用程序中实现的示例模块 rafinder.py。你可以看到这里使用了一些基本的路由:

import os
import flask
from flask import Flask
from flask import request
import models

app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = 'static/img'
# These are the extension that we are accepting to be uploaded
app.config['ALLOWED_EXTENSIONS'] = set(['txt', 'pdf', 'png', 'jpg', 'jpeg', 'gif'])

@app.route("/reset_database")
def reset_database():
    import_from_csv("wsgi/students.csv")
    return "Reset successful!"

@app.route("/")
def home():
    pass

阅读我的 entire article 以更详细地了解这一点。