POST запрос в urllib python3 - PullRequest
0 голосов
/ 18 марта 2020

У меня проблема с отправкой запроса POST на мой flask сервер с помощью библиотеки urllib. Все на моем сервере тестировалось с использованием Postman и Advanced REST Client, поэтому я уверен, что на моем сервере нет очевидных ошибок, но я получаю ошибку 500 при использовании этого кода. Я перепробовал много постов с переполнением стека и ответов, перечисленных там, но пока не нашел решения, которое работает.
Как правило, сервер имеет маршруты для / name / add, который принимает запрос POST для получения имени для добавления в глобальный список, в то время как / names возвращает словарь со значением в виде списка строковых имен. Просто очень озадачен, потому что все прекрасно работает на почтальоне и AR C: (

   pkt = parse.urlencode({'name':'Hayden'}).encode('ascii')
   req = request.Request('http://127.0.0.1:5000/name/add', pkt)
   with request.urlopen(req) as response:
        print(response.read())

Код сервера таков:

APP = Flask(__name__)

NAMES = []

@APP.route("/name/add", methods=['POST'])
def add_name():
    '''
    Adds a new name to the NAMES list
    '''
    data = request.get_json()
    NAMES.append(data['name'])
    return {}

@APP.route("/names", methods=['GET'])
def ret_names():
    '''
    Displays the NAMES list
    '''
    return dumps({
        'name':str(NAMES)
    })

@APP.route("/name/remove", methods=['DELETE'])
def rm_name():
    '''
    Removes a name from the NAMES list
    '''
    data = request.get_json()
    NAMES.remove(data['name'])
    return {}

if __name__ == "__main__":
    APP.run(port=5000)

Сообщение об ошибке выглядит следующим образом:

Traceback (most recent call last):
  File "/import/reed/3/z5265106/.local/lib/python3.7/site-packages/flask/app.py", line 2446, in wsgi_app
    response = self.full_dispatch_request()
  File "/import/reed/3/z5265106/.local/lib/python3.7/site-packages/flask/app.py", line 1951, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/import/reed/3/z5265106/.local/lib/python3.7/site-packages/flask/app.py", line 1820, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/import/reed/3/z5265106/.local/lib/python3.7/site-packages/flask/_compat.py", line 39, in reraise
    raise value
  File "/import/reed/3/z5265106/.local/lib/python3.7/site-packages/flask/app.py", line 1949, in full_dispatch_request
    rv = self.dispatch_request()
  File "/import/reed/3/z5265106/.local/lib/python3.7/site-packages/flask/app.py", line 1935, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "simple.py", line 18, in add_name
    NAMES.append(data['name'])
TypeError: 'NoneType' object is not subscriptable

Ответы [ 2 ]

1 голос
/ 18 марта 2020

Попробуйте этот код и посмотрите, работает ли он:

import urllib.parse
import urllib.request

url = 'http://127.0.0.1:5000/name/add'
user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'
values = {'name' : 'Hayden' }
headers = { 'User-Agent' : user_agent }

data = urllib.parse.urlencode(values)
req = urllib.request.Request(url, data, headers)
response = urllib.request.urlopen(req)
the_page = response.read()

Кроме того, проверьте эту ссылку

Пожалуйста, подумайте над тем, чтобы поместить свой код в Try / Catch так Вы можете увидеть, в чем проблема

try: urllib.request.urlopen(req)
except urllib.error.URLError as e:
    print(e.reason)

И чтобы использовать ваш метод GET, попробуйте это:

 import urllib.request
 contents = urllib.request.urlopen("http://127.0.0.1:5000/names").read()
0 голосов
/ 18 марта 2020

В коде вашего сервера вы читаете запрос с .get_json(), который в случае, если тип данных не соответствует json, возвращает Nothing. Тип none соответствует ошибке, которую вы получаете, когда нет доступа 'name'. Дополнительная документация о get_ json () здесь https://flask.palletsprojects.com/en/1.1.x/api/#flask .Request.get_ json

Таким образом, чтобы решить вашу проблему, вы можете заменить предыдущую функцию urlencode на json. dumps () для сериализации данных для запроса. Не забудьте сохранить .encode (), чтобы убедиться, что вы отправляете запрос в виде байтов, а не строк.

import urllib.parse
import urllib.request
import json

pkt = json.dumps({'name':'Hayden'}).encode('utf-8')
req = urllib.request.Request('http://127.0.0.1:5000/name/add', pkt, method='POST')
with urllib.request.urlopen(req) as response:
  print(response.read())
...