我真的是Stack Overflow的新手(对此通常进行编码)。我们在大学网络编程期间的最终任务是制造一个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)
这是自动测试:
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')
这是我在Windows命令提示符中获得的追溯信息(我知道,我知道,在获得新的硬盘XD之后,我将切换到一些Linux发行版):