按照书中的顺序和代码编写过程中,遇到了一些问题,大致记录一下:
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之间是有区别的,好吧。。。