Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/285.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Flask服务器自动测试赢得';无法识别呈现模板中的HTML标记(Python)_Python_Html_Flask - Fatal编程技术网

Flask服务器自动测试赢得';无法识别呈现模板中的HTML标记(Python)

Flask服务器自动测试赢得';无法识别呈现模板中的HTML标记(Python),python,html,flask,Python,Html,Flask,我对堆栈溢出(以及为此编写的一般代码)非常陌生。我们在大学网络编程期间的最后一项任务是制作一个Flask服务器,它将从openFDA API(商业药物标签汇编)中恢复信息。它必须检索药品的名称/制造商/医疗警告。。。并将它们显示在HTML列表中,然后使用“render_template”命令进行渲染 服务器的代码将由老师给我们的一个程序进行测试,我们需要通过所有测试才能不让整个课程失败。目前我只剩下三个测试了,但我想不出来 然而,我对发生的事情略知一二。我认为测试无法识别列表元素的标记“li”标

我对堆栈溢出(以及为此编写的一般代码)非常陌生。我们在大学网络编程期间的最后一项任务是制作一个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')