学习《Flask Web开发:基于Python的应用开发实战(version 2)》遇到的一些坑

按照书中的顺序和代码编写过程中,遇到了一些问题,大致记录一下:

1 、坑一:

git branch 15c中:
tests/test_api.py

    def test_404(self):
        response = self.client.get(
            '/wrong/url',
            headers=self.get_api_headers('email', 'password'))
        print(response)
        self.assertEqual(response.status_code, 404)
        json_response = json.loads(response.get_data(as_text=True))
        self.assertEqual(json_response['error'], 'not found')

进行测试:
(venv) [fancy@localhost flasky]$ flask test,结果如下:

======================================================================
ERROR: test_404 (test_api.APITestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/fancy/Desktop/WebPrograming/PythonWeb/Flaskprojects/flasky/tests/test_api.py", line 37, in test_404
    json_response = json.loads(response.get_data(as_text=True).encode('utf-8'))
  File "/usr/lib64/python3.6/json/__init__.py", line 354, in loads
    return _default_decoder.decode(s)
  File "/usr/lib64/python3.6/json/decoder.py", line 339, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/usr/lib64/python3.6/json/decoder.py", line 357, in raw_decode
    raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

----------------------------------------------------------------------
Ran 34 tests in 13.461s

FAILED (errors=1, skipped=1)

解决方法:

raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

查了一下,应该是编码问题。解码出现了错误:

定位到源码,是:

json_response = json.loads(response.get_data(as_text=True))

loads()函数:

def loads(s, *, encoding=None, cls=None, object_hook=None, parse_float=None,
        parse_int=None, parse_constant=None, object_pairs_hook=None, **kw):
"""
Deserialize ``s`` (a ``str``, ``bytes`` or ``bytearray`` instance
    containing a JSON document) to a Python object.
"""

额,有点逃避问题。。。。

2、坑二

分析源码,给应用中添加一个新命令行选项
git branch 16b中:
flasky.py

@app.cli.command()
@click.option('--length', default=25,
              help='Number of functions to include in the profiler report.')
@click.option('--profile-dir', default=None,
              help='Directory where profiler data files are saved.')
def profile(length, profile_dir):
    """Start the application under the code profiler."""
    from werkzeug.middleware.profiler import ProfilerMiddleware
    app.wsgi_app = ProfilerMiddleware(app.wsgi_app, restrictions=[length], profile_dir=profile_dir)

    app.run(debug=False)

首先: 要注意werkzeug工具包的版本,

(venv) [fancy@localhost flasky]$ pip show werkzeug
Name: Werkzeug
Version: 1.0.1
Summary: The comprehensive WSGI web application library.
Home-page: https://palletsprojects.com/p/werkzeug/
Author: Armin Ronacher
Author-email: armin.ronacher@active-4.com
License: BSD-3-Clause
Location: /home/fancy/Desktop/WebPrograming/PythonWeb/Flaskprojects/flasky/venv/lib/python3.6/site-packages
Requires: 
Required-by: Flask
(venv) [fancy@localhost flasky]$ 

和书中代码的Werkzeug的版本不一样,需要看一下工具包,找到ProfilerMiddleware位置

使用flask profile命令启动应用:

(venv) [fancy@localhost flasky]$ flask profile
/home/fancy/Desktop/WebPrograming/PythonWeb/Flaskprojects/flasky/flasky.py:64: Warning: Silently ignoring app.run() because the application is run from the flask command line executable.  Consider putting app.run() behind an if __name__ == "__main__" guard to silence this warning.
  app.run(debug=False)
(venv) [fancy@localhost flasky]$ 
解决办法:

文加最下面添加:

if __name__ == "__main__":
    app.cli()

然后使用:
python flasky.py profile启动。这和书中说的启动方式貌似不管用。

问题三

在 ch17.5 Docker容器那里,我按照书中的操作出现了问题:

# boot.sh

#!/bin/bash
source venv/bin/activate
flask deploy
exec gunicorn -b 0.0.0.0:5000 --access-logfile - --error-logfile - flasky:app
# Dockerfile

FROM python:3.6-alpine

ENV FLASK_APP flasky.py
ENV FLASK_CONFIG docker

RUN adduser -D flasky
USER flasky

WORKDIR /home/flasky

COPY requirements requirements
RUN python -m venv venv
RUN venv/bin/pip install -r requirements/docker.txt

COPY app app
COPY migrations migrations
COPY flasky.py config.py boot.sh ./

# run-time configuration
EXPOSE 5000
ENTRYPOINT [ "./boot.sh" ]

构建镜像:

(venv) [root@localhost flasky]# docker build -t flasky:2.0 .
Sending build context to Docker daemon  61.55MB
Step 1/14 : FROM python:3.6-alpine
 ---> 815c1103df84
Step 2/14 : ENV FLASK_APP flasky.py
 ---> Using cache
 ---> 711e206e54e0
Step 3/14 : ENV FLASK_CONFIG docker
 ---> Using cache
 ---> fd19a27436b3
Step 4/14 : RUN adduser -D flasky
 ---> Using cache
 ---> 161cf843b8d3
Step 5/14 : USER flasky
 ---> Using cache
 ---> 6e32628caa83
Step 6/14 : WORKDIR /home/flasky
 ---> Using cache
 ---> 481e60f5f57e
Step 7/14 : COPY requirements requirements
 ---> Using cache
 ---> e59abe75bd06
Step 8/14 : RUN python -m venv venv
 ---> Using cache
 ---> 9135a3db4924
Step 9/14 : RUN venv/bin/pip install -r requirements/docker.txt
 ---> Using cache
 ---> c43599de9e49
Step 10/14 : COPY app app
 ---> Using cache
 ---> 702afba484ed
Step 11/14 : COPY migrations migrations
 ---> Using cache
 ---> 1e2d2b46dcc0
Step 12/14 : COPY flasky.py config.py boot.sh ./
 ---> ca49da4e8a28
Step 13/14 : EXPOSE 5000
 ---> Running in 1d8b81ccaba8
Removing intermediate container 1d8b81ccaba8
 ---> 512dd2a55ea3
Step 14/14 : ENTRYPOINT [ "./boot.sh" ]
 ---> Running in 1c3848c559a5
Removing intermediate container 1c3848c559a5
 ---> 836f18881e44
Successfully built 836f18881e44
Successfully tagged flasky:2.0

然后,查看镜像,并启动

[root@localhost home]# docker images
REPOSITORY   TAG          IMAGE ID       CREATED              SIZE
flasky       2.0          836f18881e44   47 seconds ago       85.1MB
python       3.6-alpine   815c1103df84   5 days ago           40.7MB
[root@localhost home]# docker run --name flasky01 -d -p 9000:5000 flasky:2.0
3661d35bdfa21a45b838896d797023033447ac9df2b54b58ab4f474f16662c49


[root@localhost home]# docker ps
CONTAINER ID   IMAGE        COMMAND       CREATED          STATUS          PORTS                    NAMES
[root@localhost home]# docker ps -a
CONTAINER ID   IMAGE        COMMAND       CREATED          STATUS                      PORTS                    NAMES
3661d35bdfa2   flasky:1.0   "./boot.sh"   13 seconds ago   Exited (1) 11 seconds ago                            flasky01

虽然docker在后台运行下没有进程会自动退出,但是这里不是这种情况,排除
查看容器日志,看一下怎麼回事,日志真的很重要

[root@localhost home]# docker logs 3661d35bdfa2
standard_init_linux.go:219: exec user process caused: no such file or directory

这个错误,我在网络上看到了,但是都是说的是fileformat的问题,我试了下,不管用
排除一下问题的原因,我在centos上编码,所以我的问题不是网上那个回答

最后想到了,每次都是在执行boot.sh文件时退出,据此逐一排除

# boot.sh

#!/bin/bash
source venv/bin/activate
flask deploy
exec gunicorn -b 0.0.0.0:5000 --access-logfile - --error-logfile - flasky:app

后三条命令在本地都可以正常运行,那么问题很可能就是第一行声明的shell。

这里我电脑用的是:

[root@localhost home]# which bash
/usr/bin/bash
[root@localhost home]#

我把boot.sh 启动shell换成我电脑的/usr/bin/bash,还是同样的问题。。。
/usr/bin/bash 不行
/bin/bash 也不行。。。
/bin/sh 突然就行了。。

[root@localhost home]# docker run --name myblog -d -p 8000:5000 myblog:1.0
c5e1873674b28b3db1049a73bc48f07ef22a225adb9b7a5b48b7abb144d55c94
[root@localhost home]# docker ps
CONTAINER ID   IMAGE        COMMAND       CREATED          STATUS          PORTS                    NAMES
f586b29949cd   myblog:1.0   "./boot.sh"   14 minutes ago   Up 14 minutes   0.0.0.0:8000->5000/tcp   myblog
[root@localhost home]# docker ps -a
CONTAINER ID   IMAGE        COMMAND       CREATED              STATUS                          PORTS                    NAMES
f586b29949cd   myblog:1.0   "./boot.sh"   14 minutes ago       Up 14 minutes                   0.0.0.0:8000->5000/tcp   myblog
[root@localhost home]# 

不同shell之间是有区别的,好吧。。。

参考一下:linux———/bin/sh、 /bin/bash、 /bin/dash的区别

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值