Flask服务器自动测试赢得';无法识别呈现模板中的HTML标记(Python)
我对堆栈溢出(以及为此编写的一般代码)非常陌生。我们在大学网络编程期间的最后一项任务是制作一个Flask服务器,它将从openFDA API(商业药物标签汇编)中恢复信息。它必须检索药品的名称/制造商/医疗警告。。。并将它们显示在HTML列表中,然后使用“render_template”命令进行渲染 服务器的代码将由老师给我们的一个程序进行测试,我们需要通过所有测试才能不让整个课程失败。目前我只剩下三个测试了,但我想不出来 然而,我对发生的事情略知一二。我认为测试无法识别列表元素的标记“li”标记,因此认为列表是空的。我试图解决这个问题,但到目前为止我运气不好 如果你们能在两天内给我一个解决方案,我将非常感激。如果我考试不及格,我将不得不为明年的学费支付一大笔钱,所以,是的 这是我的服务器:Flask服务器自动测试赢得';无法识别呈现模板中的HTML标记(Python),python,html,flask,Python,Html,Flask,我对堆栈溢出(以及为此编写的一般代码)非常陌生。我们在大学网络编程期间的最后一项任务是制作一个Flask服务器,它将从openFDA API(商业药物标签汇编)中恢复信息。它必须检索药品的名称/制造商/医疗警告。。。并将它们显示在HTML列表中,然后使用“render_template”命令进行渲染 服务器的代码将由老师给我们的一个程序进行测试,我们需要通过所有测试才能不让整个课程失败。目前我只剩下三个测试了,但我想不出来 然而,我对发生的事情略知一二。我认为测试无法识别列表元素的标记“li”标
from flask import Flask
from flask import render_template
from flask import request
from flask import Response
from flask import redirect
from functools import wraps
import http.client
import json
app = Flask(__name__)
MAIN_INPUT = "api.fda.gov"
headers = {'User-Agent': 'http-client'}
DEBUG = True
main_conn = http.client.HTTPSConnection(MAIN_INPUT)
@app.route ("/searchDrug", methods = ['GET']) # Busca hasta 100 medicamentos con el principio activo especificado
def getActIng():
name = request.args['active_ingredient']
limit = request.args['limit']
try:
openfda_input = '/drug/label.json?search=active_ingredient:{acting}&limit={lim}'.format(acting=name,lim=limit)
main_conn.request('GET', openfda_input, None, headers)
except:
print("Error")
exit(1)
data_stage1 = main_conn.getresponse()
data_stage2 = data_stage1.read()
main_conn.close()
data_final = json.loads(data_stage2)
main_dict = data_final['results']
name_list=[]
for elem in main_dict:
if 'brand_name' in elem['openfda']:
name_list.append("<li>" + str(elem['openfda']['brand_name']).strip("['']") + "</li>")
else:
name_list.append("<li>Desconocido</li>")
name_str = str(''.join(name_list))
def print_ul(elements):
print("<ul>")
for s in elements:
ul = "<li>" + str(s) + "</li>"
print(ul)
print("</ul>")
html_str = """
<!DOCTYPE html>
<html>
<body>
<p>Nombres comerciales disponibles para medicamentos con {r} como principio activo en openFDA:</p>
<p>Mostrando {l} resultados</p>
<ul>
<p>{mans}</p>
</ul>
</body>
</html>
"""
with open("templates/getActIng.html","w") as main_output:
main_output.write("")
html_str_mod = html_str.format(r=name, l=limit, mans=name_str)
main_output.write(html_str_mod)
print(name_str)
return render_template('getActIng.html')
@app.route ("/searchCompany", methods = ['GET']) # Busca hasta 100 medicamentos fabricados por la empresa especificada
def getComName():
company_name = request.args['company']
limit = request.args['limit']
try:
openfda_input = '/drug/label.json?search=manufacturer_name:{comnam}&limit={lim}'.format(comnam=company_name,lim=limit)
main_conn.request('GET', openfda_input, None, headers)
except:
print("Error")
exit(1)
data_stage1 = main_conn.getresponse()
data_stage2 = data_stage1.read()
main_conn.close()
data_final = json.loads(data_stage2)
main_dict = data_final['results']
med_list=[]
for elem in main_dict:
if 'manufacturer_name' in elem['openfda']:
med_list.append("<li>" + str(elem['openfda']['brand_name']).strip("['']") + "</li>")
else:
med_list.append("<li>Desconocido</li>")
med_str = str(''.join(med_list))
html_str = """
<!DOCTYPE html>
<html>
<body>
<p>Medicamentos fabricados por {r} en openFDA:</p>
<p>Mostrando {l} resultados</p>
<ul>
<p>{meds}</p>
</ul>
</body>
</html>
"""
with open("templates/getComName.html","w") as main_output:
html_str_mod = html_str.format(r=company_name,l=limit,meds=med_str)
main_output.write(html_str_mod)
return render_template('getComName.html')
@app.route ("/listDrugs", methods = ['GET']) # Devuelve una cantidad aleatoria de medicamentos
def getListDrugs():
limit = request.args['limit']
try:
openfda_input = '/drug/label.json?limit={amount}'.format(amount=limit)
main_conn.request('GET', openfda_input, None, headers)
except:
print("Error")
exit(1)
data_stage1 = main_conn.getresponse()
data_stage2 = data_stage1.read()
main_conn.close()
data_final = json.loads(data_stage2)
main_dict = data_final['results']
ran_list=[]
for elem in main_dict:
if 'brand_name' in elem['openfda']:
ran_list.append("<li>" + str(elem['openfda']['brand_name']).strip("['']") + "</li>")
else:
ran_list.append("<li>Desconocido</li>")
ran_str = str(''.join(ran_list))
html_str = """
<!DOCTYPE html>
<html>
<body>
<p>Nombres comerciales de {r} medicamentos de openFDA:</p>
<p>Mostrando {l} resultados</p>
<ul>
<p>{rans}</p>
</ul>
</body>
</html>
"""
with open("templates/getListDrugs.html","w") as main_output:
html_str_mod = html_str.format(r=limit,l=limit, rans=ran_str)
main_output.write(html_str_mod)
return render_template('getListDrugs.html')
@app.route ("/listCompanies", methods = ['GET']) # Devuelve una cantidad especificada de empresas con uno de sus productos
def getListCom():
limit = request.args['limit']
try:
openfda_input = '/drug/label.json?limit={amount}'.format(amount=limit)
main_conn.request('GET', openfda_input, None, headers)
except:
print("Error")
exit(1)
data_stage1 = main_conn.getresponse()
data_stage2 = data_stage1.read()
main_conn.close()
data_final = json.loads(data_stage2)
main_dict = data_final['results']
com_list=[]
for elem in main_dict:
if 'manufacturer_name' in elem['openfda']:
com_list.append("<li>" + str(elem['openfda']['manufacturer_name']).strip("['']") + "</li>")
else:
com_list.append("<li>Desconocido</li>")
com_str = str(''.join(com_list))
html_str = """
<!DOCTYPE html>
<html>
<body>
<p>Nombres de {r} fabricantes (y sus respectivos productos) de openFDA:</p>
<p>Mostrando {l} resultados</p>
<ul>
<p>{prod}</p>
</ul>
</body>
</html>
"""
with open("templates/getListCom.html","w") as main_output:
html_str_mod = html_str.format(r=limit,l=limit, prod=com_str)
main_output.write(html_str_mod)
return render_template('getListCom.html')
@app.route ("/listWarnings", methods = ['GET']) # Devuelve una cantidad aleatoria de medicamentos
def getListWar():
limit = request.args['limit']
try:
openfda_input = '/drug/label.json?limit={amount}'.format(amount=limit)
main_conn.request('GET', openfda_input, None, headers)
except:
print("Error")
exit(1)
data_stage1 = main_conn.getresponse()
data_stage2 = data_stage1.read()
main_conn.close()
data_final = json.loads(data_stage2)
main_dict = data_final['results']
war_list=[]
for elem in main_dict:
if 'warnings' in elem:
war_list.append("<li>" + str(elem['warnings']).strip("['']") + "</li>")
else:
war_list.append("<li>Desconocido</li>")
war_str = str(''.join(war_list))
html_str = """
<!DOCTYPE html>
<html>
<body>
<p>Advertencias:</p>
<p>Mostrando {l} resultados</p>
<ul>
<p>{wars}</p>
</ul>
</body>
</html>
"""
with open("templates/getListWars.html","w") as main_output:
html_str_mod = html_str.format(l=limit, wars=war_str)
main_output.write(html_str_mod)
return render_template('getListWars.html')
@app.route('/secret', methods = ['GET'])
def getSecret():
return Response(
'Could not verify your access level for that URL.\n'
'You have to login with proper credentials', 401,
{'WWW-Authenticate': 'Basic realm="Not Authorized"'})
@app.route('/redirect', methods = ['GET'])
def getRedirect():
return redirect("http://127.0.0.1:8000/", code=302)
@app.route('/', methods=['GET', 'POST'])
def index():
return """
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<title>OpenFDA-project</title>
</head>
<body>
<form action = "listDrugs" method="get">
<input type="submit" value="Listar fármacos">
Limite: <input type="text" name="limit" value="">
</form>
<form action = "listCompanies" method="get">
<input type="submit" value="Listar empresas">
Limite: <input type="text" name="limit" value="">
</form>
<form action = "searchDrug" method="get">
<input type="submit" value="Buscar fármaco">
Campo: <input type="text" name="active_ingredient" value="">
Limite Drug: <input type="text" name="limit" value="">
</form>
<form action = "searchCompany" method="get">
<input type="submit" value="Buscar empresas">
Campo: <input type="text" name="company" value="">
Limite Com: <input type="text" name="limit" value="">
</form>
<form action = "listWarnings" method="get">
<input type="submit" value="Advertencias">
Limite: <input type="text" name="limit" value="">
</form>
</body>
</html>
"""
if __name__ == "__main__":
app.run('127.0.0.1', port = 8000, debug = True, use_reloader = False)
下面是我在Windows命令提示符下得到的回溯(我知道,我知道,我会在我得到一个新的硬盘XD时切换到一些Linux发行版):
这里有一些奇怪的事情,但直接原因可能是这实际上并不是您在Flask中创建输出的方式。看一看。还要注意,Flask有一种内置的方式,你可以向它发出请求,而不需要在子流程中乱搞。我知道这个测试有点傻,但不管我们说什么,老师都会这样评价我们的工作。我已经告诉他这个测试似乎有点不必要,但我们对此无能为力。这很公平。但是回到Flask文档,学习如何从处理程序函数生成输出。绝对不应该从Python代码中写出模板,然后用render_template读取它们,这根本不是它的工作方式。问题是,我尝试输出文本的HTML块本身,而不将其存储在模板中,如“return(在此处插入HTML块)”。它也不起作用。我坚持我的观点,测试只是不识别列表元素的列表标记
import os
import subprocess
import sys
import threading
import time
import unittest
import requests
from html.parser import HTMLParser
PYTHON_CMD = os.path.abspath(sys.executable)
class OpenFDAHTMLParser(HTMLParser):
def __init__(self):
super().__init__()
self.actions_list = []
self.forms_number = 0
self.items_number = 0
def handle_starttag(self, tag, attrs):
# print("Encountered a start tag:", tag)
if tag == "form":
self.forms_number += 1
for attr in attrs:
if attr[0] == 'action':
self.actions_list.append(attr[1])
elif tag == "li":
self.items_number += 1
def handle_endtag(self, tag):
# print("Encountered an end tag :", tag)
pass
def handle_data(self, data):
# print("Encountered some data :", data)
pass
class WebServer(threading.Thread):
""" Thread to start the web server """
def run(self):
# Start the web server in a thread. It will be killed once tests have finished
cmd = [PYTHON_CMD, 'server.py']
proc = subprocess.Popen(cmd, stderr=subprocess.PIPE)
TestOpenFDA.WEBSERVER_PROC = proc
outs, errs = proc.communicate()
errs_str = errs.decode("utf8")
if 'Address already in use' in errs_str:
TestOpenFDA.PORT_BUSY = True
return
class TestOpenFDA(unittest.TestCase):
""" Automatic testing for OpenFDA web server main features """
WEBSERVER_PROC = None
PORT_BUSY = False
TEST_PORT = 8000
TEST_DRUG = 'Aspirin'
TEST_COMPANY = 'Bayer'
TEST_ACTIONS = ['listDrugs', 'searchDrug', 'listCompanies', 'searchCompany', 'listWarnings']
@classmethod
def setUpClass(cls):
""" Start the web server to be tested """
WebServer().start()
# Wait for web sever init code
time.sleep(1)
if cls.PORT_BUSY:
raise RuntimeError("PORT BUSY")
@classmethod
def tearDownClass(cls):
""" Shutdown the webserver """
cls.WEBSERVER_PROC.kill()
def test_web_server_init(self):
resp = requests.get('http://localhost:' + str(self.TEST_PORT))
# print(resp.text)
parser = OpenFDAHTMLParser()
parser.feed(resp.text)
# Remove listWarnings that it is not in the basic specification
self.TEST_ACTIONS.remove('listWarnings')
try:
parser.actions_list.remove('listWarnings')
except ValueError:
# The form does not include this option
pass
self.assertEqual(len(parser.actions_list), 4)
self.assertEqual(set(self.TEST_ACTIONS), set(parser.actions_list))
self.TEST_ACTIONS.append('listWarnings')
def test_web_server_init_warnings(self):
# In the complete project a listWarnings is included
resp = requests.get('http://localhost:' + str(self.TEST_PORT))
# print(resp.text)
parser = OpenFDAHTMLParser()
parser.feed(resp.text)
self.assertEqual(parser.forms_number, 5)
self.assertEqual(set(self.TEST_ACTIONS), set(parser.actions_list))
def test_list_drugs(self):
url = 'http://localhost:' + str(self.TEST_PORT)
url += '/listDrugs?limit=10'
resp = requests.get(url)
parser = OpenFDAHTMLParser()
parser.feed(resp.text)
self.assertEqual(parser.items_number, 10)
def test_list_drugs_limit(self):
url = 'http://localhost:' + str(self.TEST_PORT)
url += '/listDrugs?limit=22'
resp = requests.get(url)
parser = OpenFDAHTMLParser()
parser.feed(resp.text)
self.assertEqual(parser.items_number, 22)
def test_search_drug(self):
url = 'http://localhost:' + str(self.TEST_PORT)
url += '/searchDrug?active_ingredient="%s"' % self.TEST_DRUG
resp = requests.get(url)
# print(resp.text)
parser = OpenFDAHTMLParser()
parser.feed(resp.text)
self.assertEqual(parser.items_number, 10)
def test_list_companies(self):
url = 'http://localhost:' + str(self.TEST_PORT)
url += '/listCompanies?limit=10'
resp = requests.get(url)
# print(resp.text)
parser = OpenFDAHTMLParser()
parser.feed(resp.text)
self.assertEqual(parser.items_number, 10)
def test_list_warnings(self):
url = 'http://localhost:' + str(self.TEST_PORT)
url += '/listWarnings?limit=10'
resp = requests.get(url)
# print(resp.text)
parser = OpenFDAHTMLParser()
parser.feed(resp.text)
self.assertEqual(parser.items_number, 10)
def test_search_company(self):
url = 'http://localhost:' + str(self.TEST_PORT)
url += '/searchCompany?company=' + self.TEST_COMPANY
resp = requests.get(url)
# print(resp.text)
parser = OpenFDAHTMLParser()
parser.feed(resp.text)
self.assertEqual(parser.items_number, 10)
def test_not_found(self):
url = 'http://localhost:' + str(self.TEST_PORT)
url += '/not_exists_resource'
resp = requests.get(url)
self.assertEqual(resp.status_code, 404)
def test_redirect(self):
url = 'http://localhost:' + str(self.TEST_PORT)
url += '/redirect'
resp = requests.get(url)
self.assertEqual(resp.status_code, 200)
def test_auth(self):
url = 'http://localhost:' + str(self.TEST_PORT)
url += '/secret'
resp = requests.get(url)
self.assertEqual(resp.status_code, 401)
if __name__ == "__main__":
unittest.main(warnings='ignore')