2013-05-02 12 views
47

Używam python Requests. Muszę debugować pewną aktywność OAuth i chciałbym, aby rejestrował wszystkie wykonywane żądania. mogę dostać te informacje ngrep, ale niestety nie jest to możliwe do grep połączeń HTTPS (które są potrzebne do OAuth)Zapisywanie wszystkich żądań z modułu python-request

Jak mogę włączyć rejestrowanie wszystkich adresów URL (+ parametry), które Requests korzysta?

+0

odpowiedzi przez @yohann pokazuje jak uzyskać jeszcze większą moc rejestrowania, w tym nagłówki wysyłasz. Powinna to być zaakceptowana odpowiedź, a nie Martijn, która nie pokazuje nagłówków, które skończyły się uzyskiwaniem przez wireshark i ręcznym dostosowywaniem żądania. – nealmcb

Odpowiedz

40

Biblioteka podrzędna urllib3 rejestruje wszystkie nowe połączenia i adresy URL z obiektami logging module, ale nie POST. Dla GET wniosków powinno to wystarczyć:

import logging 

logging.basicConfig(level=logging.DEBUG) 

który daje możliwość rejestrowania najbardziej opisowy; Więcej informacji na temat konfigurowania poziomów rejestrowania i miejsc docelowych można znaleźć w sekcji logging HOWTO.

Krótkie demo:

>>> import requests 
>>> import logging 
>>> logging.basicConfig(level=logging.DEBUG) 
>>> r = requests.get('http://httpbin.org/get?foo=bar&baz=python') 
INFO:requests.packages.urllib3.connectionpool:Starting new HTTP connection (1): httpbin.org 
DEBUG:requests.packages.urllib3.connectionpool:"GET /get?foo=bar&baz=python HTTP/1.1" 200 353 

Poniższe wiadomości są rejestrowane:

  • INFO: Nowe połączenia (HTTP lub HTTPS)
  • INFO: Dropped połączenia
  • INFO: Przekierowania
  • puli połączeń pełna (jeśli to się dzieje często zwiększyć rozmiar puli połączeń)
  • WARN::Ponowna próba połączenia
  • DEBUG: Połączenie szczegóły: metoda, ścieżka, wersja HTTP, kod stanu i długość odpowiedź
+0

O dziwo, nie widzę "access_token" w żądaniu OAuth.Linkedin skarży się na nieautoryzowane żądanie i chcę sprawdzić, czy biblioteka, której używam ('rauth' na górze' request') wysyła token z prośbą. Spodziewałem się, że jest to parametr zapytania, ale może jest w nagłówkach żądań? Jak mogę zmusić 'urllib3' do wyświetlenia nagłówków? A ciało wniosku? Aby to było proste: jak mogę zobaczyć prośbę ** FULL **? – dangonfast

+0

Nie możesz tego zrobić bez łatania, obawiam się. Najczęstszym sposobem diagnozowania takich problemów jest proxy lub rejestrator pakietów (ja używam Wireshark do przechwytywania pełnych żądań i odpowiedzi samemu). Widzę jednak, że zadałeś nowe pytanie na ten temat. –

+1

Oczywiście, teraz debuguję z wireshark, ale mam problem: jeśli robię http, widzę pełną zawartość pakietu, ale Linkedin zwraca 401, co jest oczekiwane, ponieważ Linkedin mówi, aby używać https. Ale z https też nie działa i nie mogę go debugować, ponieważ nie mogę sprawdzić warstwy TLS za pomocą wireshark. – dangonfast

63

Musisz włączyć debugowanie na poziomie httplib (→ urllib3urllib3 ).

Oto niektóre funkcje zarówno przerzutowe (..._on() i ..._off()) lub tymczasowo mieć go na:

import logging 
import contextlib 
try: 
    from http.client import HTTPConnection # py3 
except ImportError: 
    from httplib import HTTPConnection # py2 

def debug_requests_on(): 
    '''Switches on logging of the requests module.''' 
    HTTPConnection.debuglevel = 1 

    logging.basicConfig() 
    logging.getLogger().setLevel(logging.DEBUG) 
    requests_log = logging.getLogger("requests.packages.urllib3") 
    requests_log.setLevel(logging.DEBUG) 
    requests_log.propagate = True 

def debug_requests_off(): 
    '''Switches off logging of the requests module, might be some side-effects''' 
    HTTPConnection.debuglevel = 0 

    root_logger = logging.getLogger() 
    root_logger.setLevel(logging.WARNING) 
    root_logger.handlers = [] 
    requests_log = logging.getLogger("requests.packages.urllib3") 
    requests_log.setLevel(logging.WARNING) 
    requests_log.propagate = False 

@contextlib.contextmanager 
def debug_requests(): 
    '''Use with 'with'!''' 
    debug_requests_on() 
    yield 
    debug_requests_off() 

użycie Demo:

>>> requests.get('http://httpbin.org/') 
<Response [200]> 

>>> debug_requests_on() 
>>> requests.get('http://httpbin.org/') 
INFO:requests.packages.urllib3.connectionpool:Starting new HTTP connection (1): httpbin.org 
DEBUG:requests.packages.urllib3.connectionpool:"GET/HTTP/1.1" 200 12150 
send: 'GET/HTTP/1.1\r\nHost: httpbin.org\r\nConnection: keep-alive\r\nAccept- 
Encoding: gzip, deflate\r\nAccept: */*\r\nUser-Agent: python-requests/2.11.1\r\n\r\n' 
reply: 'HTTP/1.1 200 OK\r\n' 
header: Server: nginx 
... 
<Response [200]> 

>>> debug_requests_off() 
>>> requests.get('http://httpbin.org/') 
<Response [200]> 

>>> with debug_requests(): 
...  requests.get('http://httpbin.org/') 
INFO:requests.packages.urllib3.connectionpool:Starting new HTTP connection (1): httpbin.org 
... 
<Response [200]> 

Pojawi się żądanie, w tym nagłówki i dane, a REAGOWANIE z HEADERS, ale bez DATA. Brakuje tylko odpowiedzi. Ktoś, kto nie jest zalogowany.

Source

+0

Dziękujemy za wgląd w użycie 'httplib.HTTPConnection.debuglevel = 1', aby uzyskać nagłówki - doskonałe! Ale myślę, że uzyskuję takie same wyniki, używając tylko 'logging.basicConfig (level = logging.DEBUG)' w miejsce pozostałych 5 linii. Czy czegoś brakuje? Sądzę, że może to być sposób na ustawienie różnych poziomów logowania dla root'a w stosunku do urllib3, jeśli jest to pożądane. – nealmcb

+0

Nie masz nagłówka z rozwiązaniem. – Yohann

+5

'httplib.HTTPConnection.debuglevel = 2' umożliwi również wydruk treści POST. – Mandible79

21

Dla tych z użyciem Pythona 3+

import requests 
import logging 
import http.client 

http.client.HTTPConnection.debuglevel = 1 

logging.basicConfig() 
logging.getLogger().setLevel(logging.DEBUG) 
requests_log = logging.getLogger("requests.packages.urllib3") 
requests_log.setLevel(logging.DEBUG) 
requests_log.propagate = True 
Powiązane problemy