为什么Python请求库未能得到响应? [英] Why Python requests library failing to get response?

查看:204
本文介绍了为什么Python请求库未能得到响应?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个视图方法:

 #此视图方法是通过api调用注册新用户
def register(request):
如果request.method =='GET':
registrationForm = RegistrationForm(request.GET)

如果registrationForm.is_valid():

r = requests.get('http:// localhost:8000 / api / create-user /',timeout = 10)
打印r.content
返回HttpResponseRedirect('/')
else:
registrationForm = RegistrationForm()

return render(request,'frontend / index.html',{'registrationForm':registrationForm})

在上述视图方法中,请求库只是继续加载,只是没有得到响应,最终在10秒后失败作为timedout。



其他应用程序的api / create-user /url映射到同一个项目中,这可能是原因吗?



该应用中的URL映射的url urls.py(不是main urls.py)是:

  from django.conf.urls import include,url 
from django.contrib import admin

from。导入视图

urlpatterns = [
url(r'^ create-user /',views.create_user),
]
/ pre>

我也使用Django休息框架,上面提到的url匹配的视图是:

  from django.shortcuts import render 

from rest_framework import status
from rest_framework.decorators import api_view
from rest_framework.response import Response


#在这里创建您的意见。
@api_view(['GET'])
def create_user(request):
print'coming ....'
#print request.GET.get('username' )
#print request.POST.get('password')
data = {}

data.update({'result':'good'})

返回响应(数据)

单元测试工作正常,这里是单元测试我写了:

 从django.test导入TestCase 

导入请求

#在这里创建你的测试。
#这个类用于单元测试api模块的请求/响应。
#在这里我们可以测试我们正在做的REST api调用是否正常工作。
class FrontEndTests(TestCase):

def test_user_creation(self):
r = requests.get('http:// localhost:8000 / api / create-user /')
print r.content
self.assertIsNotNone(r,Not none)

我还在settings.py和django rest框架中添加了很多设置,如ALLOWED_HOSTS等,我添加了:

  REST_FRAMEWORK = {
#使用Django的标准`django.contrib.auth`权限,
#或允许未经身份验证的用户的只读访问。
'DEFAULT_PERMISSION_CLASSES':[
'rest_framework.permissions.AllowAny',
]
}

SESSION_SAVE_EVERY_REQUEST = True

ALLOWED_HOSTS = ['localhost','127.0.0.1']

我在这里做错什么?
谢谢






我也尝试使用来自manage.py shell的请求,似乎在那里工作正常。
这是因为我在form.is_valid()块中使用它,它不工作,或者我也怀疑django-rest-framework是罪魁祸首。是否有任何需要添加的设置?



---------- 答案






我正在使用不是多线程的runserver_plus来解决这个问题,我使用的是runserver,它的工作正常,否则你必须启动相同的项目两个不同的端口!

解决方案

我相信这是因为你正在使用Django runserver(纠正我,如果我错了)不是多线程的



https:// code。 djangoproject.com/ticket/3357



所以你要求localhost:8000排队等待请求完成的请求!不太理想。



在生产中,使用wsgi应用程序(如uwsgi)运行服务器时,这将是正常的,因为它是多线程的。



这个测试用例的原因是因为您正在将测试线程的请求发送到正在运行的 的测试服务器一个不同的线程。



编辑#1:需要考虑的几件事



1)为什么你接受您的注册表单在GET请求中,而不是POST请求?这是滥用GET动词,因为您实际上是在服务器上创建一些东西。



2)为什么要从应用程序内部调用自己的API,而不是将此功能成为可以从需要它的所有端点调用的方法?



编辑#2:



如所述在评论中,开发者服务器多线程



https://github.com/django/django/commit/ce165f7bbf


I have a view method:

# This view method is to register a new user through api call
def register(request):
    if request.method == 'GET':
        registrationForm = RegistrationForm(request.GET)

        if registrationForm.is_valid():

            r = requests.get('http://localhost:8000/api/create-user/', timeout=10)
            print r.content
            return HttpResponseRedirect('/')
    else:
        registrationForm = RegistrationForm()

    return render(request, 'frontend/index.html', {'registrationForm': registrationForm})

Here in the above mentioned view method, the requests library just keeps on loading and just doesnt get the response and ultimately fails after 10 secs as timedout.

The other app where 'api/create-user/' url maps to is in the same project, could this be the reason?

The url for that mapping in that app urls.py (not main urls.py) is :

from django.conf.urls import include, url
from django.contrib import admin

from . import views

urlpatterns = [
    url(r'^create-user/', views.create_user),
]

I am also using Django rest framework and the view which the above mentioned url matches to is:

from django.shortcuts import render

from rest_framework import status
from rest_framework.decorators import api_view
from rest_framework.response import Response


# Create your views here.
@api_view(['GET'])
def create_user(request):
    print 'coming....'
    # print request.GET.get('username')
    # print request.POST.get('password')
    data = {}

    data.update({'result': 'good'})

    return Response(data)

With the unit testing it works fine, here is the unit test which I wrote:

from django.test import TestCase

import requests

# Create your tests here.
# This class is for unit testing the request/response for api module.
# Here we can test if the REST api call we are making are working perfect or not.
class FrontEndTests(TestCase):

    def test_user_creation(self):
        r = requests.get('http://localhost:8000/api/create-user/')
        print r.content
        self.assertIsNotNone(r, "Not none")

I have also added few settings such as ALLOWED_HOSTS etc. in settings.py and for django rest framework I added:

REST_FRAMEWORK = {
    # Use Django's standard `django.contrib.auth` permissions,
    # or allow read-only access for unauthenticated users.
    'DEFAULT_PERMISSION_CLASSES': [
        'rest_framework.permissions.AllowAny',
    ]
}

SESSION_SAVE_EVERY_REQUEST = True

ALLOWED_HOSTS = ['localhost', '127.0.0.1']

What am I doing wrong here? Thanks


I also tried using requests from manage.py shell, and it seems to work fine there. Is it because I am using it inside a form.is_valid() block that it is not working or I also suspect django-rest-framework to be the culprit. Is there any settings which I need to add more?

---------- Answer


I was using runserver_plus which is not multithreaded, to solve this problem I am using runserver and it works fine, otherwise you have to start same project on two different ports!

解决方案

I believe this is because you are using the Django runserver (correct me if I am wrong) which is not multi-threaded

https://code.djangoproject.com/ticket/3357

So you request to localhost:8000 is queued waiting for the request that made the request to finish! Not ideal.

In production, where you are running your server with a wsgi app (like uwsgi) this would be OK because it is multithreaded.

The reason it works in this test case is because you are making the request from the test thread to the test server that is being run in a different thread.

EDIT #1: A few things to think about

1) Why are your accepting your registration form in a GET request and not a POST request? This is an abuse of the GET verb because you are actually creating something on the server

2) Why are you calling your own API from inside your application and not putting this functionality into a method that can be called from all endpoints that need it?

EDIT #2:

As stated in the comments, the dev server is multithreaded

https://github.com/django/django/commit/ce165f7bbf

这篇关于为什么Python请求库未能得到响应?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆