I'm using the requests module. I have a number of programs that would like to make a complex check on the results of a requests.get(url) call. I thought perhaps I could add this new function in a class that inherited from some part of requests. But the get call is in an api.py file that contains just static function definitions, no class declaration. So I can't figure out what my import or subclass definition should look like ("class Subclass(requests.api)" isn't working.)
What I was think of ending up with:
r = requests.get(url)
r.my_check()
Is there a class-oriented way to accomplish this, or should I just write a function in a separate module of my own, pass it the results of the requests.get(url) call and be done with it?
Not saying it is a great idea, but ultimately I think you are just trying to dynamically add a method to the Response object?
import requests
from requests import Response
def my_method(self):
print(self.content)
Response.my_method = my_method
r = requests.get('https://www.google.com')
r.my_method()
Gives...
b'<!doctype html><html itemscope="" itemtype="http://schema.org/WebPage" lang="en"><head><me
You can define your own function and attach to requests module at run-time.
def my_get(self, *args, **kwargs):
original_get = self.get(args, kwargs)
# do what you want with the original_get, maybe change it according to your needs, then return the changed response.
return changed_get
requests.my_get = my_get
# now you can use both of them
requests.get(url) # regular get method
requests.my_get(url) # your own get method
Related
I'm calling a python function and passing an HTTP request as a parameter but it's not working. I created the function in a View and called it in another, but the parameter fails.
Here's the function I'm calling
def load_colmeias(request):
apiario = request.GET.get('apiario')
if apiario != "":
colmeias = Colmeia.objects.filter(apiario=apiario)
return render(request, 'colmeias_choices.html', {'colmeias': colmeias})
else:
return render(request, 'colmeias_choices.html')
Here I call her
load_colmeias(request)
But the following error occurs
NameError: name 'request' is not defined
I already imported the "urlib" and "requests" libraries but it always gives the same error:
AttributeError: module has no attribute 'GET'
Can someone help me ?? I'm new to Python/Django and I'm still learning how to do things
Check if you have requests installed:
import requests
r=requests.get("https://automatetheboringstuff.com/files/rj.txt")
print(len(r.text))
Now, check:
In load_colmeias(request), make sure the parameter is actually request and not requests throughout.
Your filename is not requests.py; otherwise you would be importing your own file.
request and requests are two different things, one without 's' is a parameter and with 's' is a method. to use requests you have to import requests library this is a third party library to fetch data from an API.
if you want to call this function you have to make a request through an API. create an API for this function and then make a request.
your views.py file:
def load_colmeias(request):
apiario = request.GET.get('apiario')
if apiario != "":
colmeias = Colmeia.objects.filter(apiario=apiario)
return render(request, 'colmeias_choices.html', {'colmeias': colmeias})
else:
return render(request, 'colmeias_choices.html')
Your urls.py file:
from django.urls import path
from . import views
urlpatterns = [
path('load_colmeias', views.load_colmeias)
]
Now your API is:
http://127.0.0.1:8000/load_colmeias?apiario=1234
make sure you have used the correct port in the api and have started the server before making the request and pass the correct value of apiario.
There is another way to call this function by using requests library:
import requests
res = requests.get('http://127.0.0.1:8000/load_colmeias?apiario=1234')
print(res.text)
you can use this in any file and call your function like this using this library again the server must be running and pass the correct value of apiario.
Well if you are passing a request parameter then you have to make the request. You can't call it the way you have shown.
I SOLVED THE PROBLEM !! Basically, I just created a function that calls another function and passed the same argument to both... As can be seen below:
def load_colmeias(request):
return carregar_colmeia(request)
I don't know if it's recommended, but it solved my problem of having to rewrite the same code in multiple views.
I'm new to Python, and I'm working in Pycharm to read data line by line from a webpage. For this task, I'm attempting to use the requests module. However, when I try to print the response object, I see "Process finished with exit code 0" and no object displayed.
Do I need to create some sort of setting to be able to work with HTTP requests in Python?
Code:
import re
import requests
def find_phone_number(url='https://www.python-course.eu/barneyhouse.txt'):
response = requests.get(url)
return response
print(find_phone_number(url='https://www.python-course.eu/barneyhouse.txt'))
You need to call the function and access the 'text' element.
Also, in your code the print statement is not indented properly so it will never be run.
Here is an example of the code doing what I think you intendend:
import re
import requests
def find_phone_number(url='https://www.python-course.eu/simpsons_phone_book.txt'):
response = requests.get(url)
return response
text_you_want = find_phone_number().text
print(text_you_want)
Well, for starters, your find_phone_number() function calls itself after it returns. This is because your last line is indented and therefore inside the function definition. The reason you keep getting Process finished with exit code 0 is because your function is never actually called. This should work:
import re
import requests
def find_phone_number(url='https://www.python-course.eu/barneyhouse.txt'):
response = requests.get(url)
return response
print(find_phone_number(url='https://www.python-course.eu/barneyhouse.txt'))
Can you please help me out to figure what I did wrong? I have the following unit test for a python lambdas
class Tests(unittest.TestCase):
def setUp(self):
//some setup
#mock.patch('functions.tested_class.requests.get')
#mock.patch('functions.helper_class.get_auth_token')
def test_tested_class(self, mock_auth, mock_get):
mock_get.side_effect = [self.mock_response]
mock_auth.return_value = "some id token"
response = get_xml(self.event, None)
self.assertEqual(response['statusCode'], 200)
The problem is that when I run this code, I get the following error for get_auth_token:
Invalid URL '': No schema supplied. Perhaps you meant http://?
I debugged it, and it doesn't look like I patched it correctly. The Authorization helper file is in the same folder "functions" as the tested class.
EDIT:
In the tested_class I was importing get_auth_token like this:
from functions import helper_class
from functions.helper_class import get_auth_token
...
def get_xml(event, context):
...
response_token = get_auth_token()
After changing to this, it started to work fine
import functions.helper_class
...
def get_xml(event, context):
...
response_token = functions.helper_class.get_auth_token()
I still don't fully understand why though
In your first scenario
in tested_class.py, get_auth_token is imported
from functions.helper_class import get_auth_token
The patch should be exactly the get_auth_token at tested_class
#mock.patch('functions.tested_class.get_auth_token')
Second scenario
With the following usage
response_token = functions.helper_class.get_auth_token()
The only way to patch is this
#mock.patch('functions.helper_class.get_auth_token')
alternative
With import like this in tested_class
from functions import helper_class
helper_class.get_auth_token()
patch could be like this:
#mock.patch('functions.tested_class.helper_class.get_auth_token')
patch() works by (temporarily) changing the object that a name points to with another one. There can be many names pointing to any individual object, so for patching to work, you must ensure that you patch the name used by the system under test.
The basic principle is that you patch where an object is looked up, which is not necessarily the same place as where it is defined.
Python documentation has a very good example. where to patch
My code:
r = requests.get('http://www.pythonchallenge.com/pc/def/banner.p')
t = urlopen('http://www.pythonchallenge.com/pc/def/banner.p')
print(r)
'Response [200]'
print(t)
'http.client.HTTPResponse object at 0x0430A370'
Why does requests.get only return the object instance (in this case the respond code) while urlopen returns the actual object?
My question then would be: how can I use requests to return an object instead of the response code? (I want to desearialize the content using pickle)
You are confusing what is returned by print with the object itself. requests.get does get the object. The developer of requests made the executive decision to return r.status_code when you call the print function. They could have returned anything: r.text, or r.raw, for example. It sounds like you were expecting to see the latter.
If you're interested, here is a bit more information about how developers can define what print returns: How to print a class or objects of class using print()?
Given a standard urllib.request object, retrieved so:
req = urllib.urlopen('http://example.com')
If I read its contents via req.read(), afterwards the request object will be empty.
Unlike normal file-like objects, however, the request object does not have a seek method, for I am sure are excellent reasons.
However, in my case I have a function, and I want it to make certain determinations about a request and then return that request "unharmed" so that it can be read again.
I understand that one option is to re-request it. But I'd like to be able to avoid making multiple HTTP requests for the same url & content.
The only other alternative I can think of is to have the function return a tuple of the extracted content and the request object, with the understanding that anything that calls this function will have to get the content in this way.
Is that my only option?
Delegate the caching to a StringIO object(code not tested, just to give the idea):
import urllib
from io import StringIO
class CachedRequest(object):
def __init__(self, url):
self._request = urllib.urlopen(url)
self._content = None
def __getattr__(self, attr):
# if attr is not defined in CachedRequest, then get it from
# the request object.
return getattr(self._request, attr)
def read(self):
if self._content is None:
content = self._request.read()
self._content = StringIO()
self._content.write(content)
self._content.seek(0)
return content
else:
return self._content.read()
def seek(self, i):
self._content.seek(i)
If the code actually expects a real Request object(i.e. calls isinstance to check the type) then subclass Request and you don't even have to implement __getattr__.
Note that it is possible that a function checks for the exact class(and in this case you can't do nothing) or, if it's written in C, calls the method using C/API calls(in which case the overridden method wont be called).
Make a subclass of urllib2.Request that uses a cStringIO.StringIO to hold whatever gets read. Then you can implement seek and so forth. Actually you could just use a string, but that'd be more work.