如何在heroku上托管cython web app?

Мар*_*лак 7 python heroku cython flask

目前我正在玩Cython并试图找出如何在heroku上托管Cython Flask应用程序(例如).

假设我的项目看起来像这样(在cython编译之后):

_/cythonheroku
 |-- requirements.txt
 |-- run.py
 |-- Procfile
 |__/app
    |-- __init__.py
    |-- app.c
    |-- app.cpython-36m-darwin.so
    |-- app.pyx
Run Code Online (Sandbox Code Playgroud)

现在,app.pyx中有一个标准的Flask应用程序,有一些cython调整,如下所示:

#cython: infer_types=True
from flask import Flask

app = Flask(__name__)

@app.route('/', methods=['GET'])
def index():
    cdef long x = 10000000
    cdef long long y = 0
    cdef int i
    for i in range(x):
        y += i
    return str(y)
Run Code Online (Sandbox Code Playgroud)

然后,使用命令cythonize -i app/app.pyx编译我的app.pyx代码.

run.py档案中我有:

from app.app import app

app.run()
Run Code Online (Sandbox Code Playgroud)

python run.py当我从for循环中看到返回的值时,从我的命令行启动它将在本地主机上启动服务器.

问题:在我将其推送到heroku之后,我在run.py的第一行得到了错误:

no module named app
Run Code Online (Sandbox Code Playgroud)

据我了解 - heroku只是看不到我编译的应用程序文件.

UPD:命令在Procfile:

web: gunicorn run:app --log-file=-
Run Code Online (Sandbox Code Playgroud)

UPD2:经过一些测试,我发现Heroku无法识别app.cpython-36m-darwin.so为模块.这就是我得到那个错误的原因.

现在的问题是 - 如何让heroku识别.so文件为python模块?

Мар*_*лак 7

好的,我设法找到了解决方案.

假设我们的项目看起来像这样

_/cythonheroku
 |-- requirements.txt
 |-- Procfile
 |__/app
    |-- __init__.py
    |-- app.pyx
Run Code Online (Sandbox Code Playgroud)

步骤如下:

  1. 创建一个项目并将其推送到heroku 而无需.pyx使用cython 编译文件
  2. 您需要设置堆栈container并安装一些Linux软件包.所以,基本上,你需要:
  3. 删除Procfile并安装清单插件:

    heroku update beta
    heroku plugins:install @heroku-cli/plugin-manifest
    heroku manifest:create
    
    Run Code Online (Sandbox Code Playgroud)
  4. 在创建时,heroku.yml您需要指定包和运行命令.最小可行清单文件将如下所示:

    setup:
      config: {}
    build:
      languages:
        - python
      packages:
        - build-essential
    run:
      web: 'gunicorn app.app:app'
    
    Run Code Online (Sandbox Code Playgroud)

    我们想要安装,build-essential所以在heroku端的linux机器将能够编译我们的cython代码.run命令有点棘手 - 据我所知,你无法在heroku中正确运行你的cython应用程序,例如:

    from app.app import app
    app.run()
    
    Run Code Online (Sandbox Code Playgroud)

    Heroku会出现错误,该地址已在使用中(出于某种原因,它会在本地运行您的应用程序,然后尝试启动您的应用程序进行网络处理,您将收到错误.我不知道,我会尝试以某种方式解决这个问题,但atm并不是那么重要).

  5. 将堆栈更改为容器并推送:

    heroku stack:set container
    git push heroku master
    
    Run Code Online (Sandbox Code Playgroud)
  6. 你会在终端看到很多东西.没关系.Heroku将尝试使用指定的命令运行您的应用程序,heroku.yml您将收到错误.那是因为我们还没有我们的cython文件.现在,问题是编译文件对于每个操作系统都是唯一的,我猜,每台机器(我认为取决于CPU芯片组).这就是为什么我们要在heroku端编译我们的文件而不是本地.要做到这一点,你需要连接到heroku终端,只需输入:

    heroku run bash
    
    Run Code Online (Sandbox Code Playgroud)

    然后你需要简单地编译你的代码:

    cythonize -i app/app.pyx
    
    Run Code Online (Sandbox Code Playgroud)

    现在,每个heroku dyno都有自己的短暂文件系统,并带有最近部署的代码的新副本,因此您编译的文件根本不会保存.您需要在您的计算机上下载它,添加到项目并再次推送到heroku.你可以使用transfer.sh这样做:

    curl --upload-file ./app/<your-file> https://transfer.sh/<name-of-file>
    
    Run Code Online (Sandbox Code Playgroud)

    然后,您可以使用命令行中生成的链接下载它.注意:您必须复制2个文件 - <file>.c<file>.cpython-36m-x86_64-linux-gnu.so..so文件名称可以不同,但​​你明白了.

  7. 将这两个文件添加到项目中,提交并推送到heroku.

  8. 而已.您的应用将启动并在网络上提供.

http://cython.herokuapp.com/