From 0f3d2bb259c1b22917dfa654b40af1656338cf3e Mon Sep 17 00:00:00 2001 From: Roy <88516395+moraroy@users.noreply.github.com> Date: Thu, 8 Jan 2026 02:26:54 -0800 Subject: [PATCH] Delete Modules/requests directory --- Modules/requests/__init__.py | 180 --- .../__pycache__/__init__.cpython-311.pyc | Bin 6262 -> 0 bytes .../__pycache__/__version__.cpython-311.pyc | Bin 548 -> 0 bytes .../_internal_utils.cpython-311.pyc | Bin 2112 -> 0 bytes .../__pycache__/adapters.cpython-311.pyc | Bin 23104 -> 0 bytes .../requests/__pycache__/api.cpython-311.pyc | Bin 7465 -> 0 bytes .../requests/__pycache__/auth.cpython-311.pyc | Bin 14592 -> 0 bytes .../__pycache__/certs.cpython-311.pyc | Bin 682 -> 0 bytes .../__pycache__/compat.cpython-311.pyc | Bin 2066 -> 0 bytes .../__pycache__/cookies.cpython-311.pyc | Bin 27072 -> 0 bytes .../__pycache__/exceptions.cpython-311.pyc | Bin 8474 -> 0 bytes .../__pycache__/hooks.cpython-311.pyc | Bin 1212 -> 0 bytes .../__pycache__/models.cpython-311.pyc | Bin 38662 -> 0 bytes .../__pycache__/packages.cpython-311.pyc | Bin 1296 -> 0 bytes .../__pycache__/sessions.cpython-311.pyc | Bin 29655 -> 0 bytes .../__pycache__/status_codes.cpython-311.pyc | Bin 6199 -> 0 bytes .../__pycache__/structures.cpython-311.pyc | Bin 6184 -> 0 bytes .../__pycache__/utils.cpython-311.pyc | Bin 40206 -> 0 bytes Modules/requests/__version__.py | 14 - Modules/requests/_internal_utils.py | 50 - Modules/requests/adapters.py | 538 -------- Modules/requests/api.py | 157 --- Modules/requests/auth.py | 315 ----- Modules/requests/certs.py | 17 - Modules/requests/compat.py | 79 -- Modules/requests/cookies.py | 561 --------- Modules/requests/exceptions.py | 141 --- Modules/requests/help.py | 134 -- Modules/requests/hooks.py | 33 - Modules/requests/models.py | 1034 ---------------- Modules/requests/packages.py | 28 - Modules/requests/sessions.py | 833 ------------- Modules/requests/status_codes.py | 128 -- Modules/requests/structures.py | 99 -- Modules/requests/utils.py | 1094 ----------------- 35 files changed, 5435 deletions(-) delete mode 100644 Modules/requests/__init__.py delete mode 100644 Modules/requests/__pycache__/__init__.cpython-311.pyc delete mode 100644 Modules/requests/__pycache__/__version__.cpython-311.pyc delete mode 100644 Modules/requests/__pycache__/_internal_utils.cpython-311.pyc delete mode 100644 Modules/requests/__pycache__/adapters.cpython-311.pyc delete mode 100644 Modules/requests/__pycache__/api.cpython-311.pyc delete mode 100644 Modules/requests/__pycache__/auth.cpython-311.pyc delete mode 100644 Modules/requests/__pycache__/certs.cpython-311.pyc delete mode 100644 Modules/requests/__pycache__/compat.cpython-311.pyc delete mode 100644 Modules/requests/__pycache__/cookies.cpython-311.pyc delete mode 100644 Modules/requests/__pycache__/exceptions.cpython-311.pyc delete mode 100644 Modules/requests/__pycache__/hooks.cpython-311.pyc delete mode 100644 Modules/requests/__pycache__/models.cpython-311.pyc delete mode 100644 Modules/requests/__pycache__/packages.cpython-311.pyc delete mode 100644 Modules/requests/__pycache__/sessions.cpython-311.pyc delete mode 100644 Modules/requests/__pycache__/status_codes.cpython-311.pyc delete mode 100644 Modules/requests/__pycache__/structures.cpython-311.pyc delete mode 100644 Modules/requests/__pycache__/utils.cpython-311.pyc delete mode 100644 Modules/requests/__version__.py delete mode 100644 Modules/requests/_internal_utils.py delete mode 100644 Modules/requests/adapters.py delete mode 100644 Modules/requests/api.py delete mode 100644 Modules/requests/auth.py delete mode 100644 Modules/requests/certs.py delete mode 100644 Modules/requests/compat.py delete mode 100644 Modules/requests/cookies.py delete mode 100644 Modules/requests/exceptions.py delete mode 100644 Modules/requests/help.py delete mode 100644 Modules/requests/hooks.py delete mode 100644 Modules/requests/models.py delete mode 100644 Modules/requests/packages.py delete mode 100644 Modules/requests/sessions.py delete mode 100644 Modules/requests/status_codes.py delete mode 100644 Modules/requests/structures.py delete mode 100644 Modules/requests/utils.py diff --git a/Modules/requests/__init__.py b/Modules/requests/__init__.py deleted file mode 100644 index 300a16c..0000000 --- a/Modules/requests/__init__.py +++ /dev/null @@ -1,180 +0,0 @@ -# __ -# /__) _ _ _ _ _/ _ -# / ( (- (/ (/ (- _) / _) -# / - -""" -Requests HTTP Library -~~~~~~~~~~~~~~~~~~~~~ - -Requests is an HTTP library, written in Python, for human beings. -Basic GET usage: - - >>> import requests - >>> r = requests.get('https://www.python.org') - >>> r.status_code - 200 - >>> b'Python is a programming language' in r.content - True - -... or POST: - - >>> payload = dict(key1='value1', key2='value2') - >>> r = requests.post('https://httpbin.org/post', data=payload) - >>> print(r.text) - { - ... - "form": { - "key1": "value1", - "key2": "value2" - }, - ... - } - -The other HTTP methods are supported - see `requests.api`. Full documentation -is at . - -:copyright: (c) 2017 by Kenneth Reitz. -:license: Apache 2.0, see LICENSE for more details. -""" - -import warnings - -import urllib3 - -from .exceptions import RequestsDependencyWarning - -try: - from charset_normalizer import __version__ as charset_normalizer_version -except ImportError: - charset_normalizer_version = None - -try: - from chardet import __version__ as chardet_version -except ImportError: - chardet_version = None - - -def check_compatibility(urllib3_version, chardet_version, charset_normalizer_version): - urllib3_version = urllib3_version.split(".") - assert urllib3_version != ["dev"] # Verify urllib3 isn't installed from git. - - # Sometimes, urllib3 only reports its version as 16.1. - if len(urllib3_version) == 2: - urllib3_version.append("0") - - # Check urllib3 for compatibility. - major, minor, patch = urllib3_version # noqa: F811 - major, minor, patch = int(major), int(minor), int(patch) - # urllib3 >= 1.21.1 - assert major >= 1 - if major == 1: - assert minor >= 21 - - # Check charset_normalizer for compatibility. - if chardet_version: - major, minor, patch = chardet_version.split(".")[:3] - major, minor, patch = int(major), int(minor), int(patch) - # chardet_version >= 3.0.2, < 6.0.0 - assert (3, 0, 2) <= (major, minor, patch) < (6, 0, 0) - elif charset_normalizer_version: - major, minor, patch = charset_normalizer_version.split(".")[:3] - major, minor, patch = int(major), int(minor), int(patch) - # charset_normalizer >= 2.0.0 < 4.0.0 - assert (2, 0, 0) <= (major, minor, patch) < (4, 0, 0) - else: - raise Exception("You need either charset_normalizer or chardet installed") - - -def _check_cryptography(cryptography_version): - # cryptography < 1.3.4 - try: - cryptography_version = list(map(int, cryptography_version.split("."))) - except ValueError: - return - - if cryptography_version < [1, 3, 4]: - warning = "Old version of cryptography ({}) may cause slowdown.".format( - cryptography_version - ) - warnings.warn(warning, RequestsDependencyWarning) - - -# Check imported dependencies for compatibility. -try: - check_compatibility( - urllib3.__version__, chardet_version, charset_normalizer_version - ) -except (AssertionError, ValueError): - warnings.warn( - "urllib3 ({}) or chardet ({})/charset_normalizer ({}) doesn't match a supported " - "version!".format( - urllib3.__version__, chardet_version, charset_normalizer_version - ), - RequestsDependencyWarning, - ) - -# Attempt to enable urllib3's fallback for SNI support -# if the standard library doesn't support SNI or the -# 'ssl' library isn't available. -try: - try: - import ssl - except ImportError: - ssl = None - - if not getattr(ssl, "HAS_SNI", False): - from urllib3.contrib import pyopenssl - - pyopenssl.inject_into_urllib3() - - # Check cryptography version - from cryptography import __version__ as cryptography_version - - _check_cryptography(cryptography_version) -except ImportError: - pass - -# urllib3's DependencyWarnings should be silenced. -from urllib3.exceptions import DependencyWarning - -warnings.simplefilter("ignore", DependencyWarning) - -# Set default logging handler to avoid "No handler found" warnings. -import logging -from logging import NullHandler - -from . import packages, utils -from .__version__ import ( - __author__, - __author_email__, - __build__, - __cake__, - __copyright__, - __description__, - __license__, - __title__, - __url__, - __version__, -) -from .api import delete, get, head, options, patch, post, put, request -from .exceptions import ( - ConnectionError, - ConnectTimeout, - FileModeWarning, - HTTPError, - JSONDecodeError, - ReadTimeout, - RequestException, - Timeout, - TooManyRedirects, - URLRequired, -) -from .models import PreparedRequest, Request, Response -from .sessions import Session, session -from .status_codes import codes - -logging.getLogger(__name__).addHandler(NullHandler()) - -# FileModeWarnings go off per the default. -warnings.simplefilter("default", FileModeWarning, append=True) diff --git a/Modules/requests/__pycache__/__init__.cpython-311.pyc b/Modules/requests/__pycache__/__init__.cpython-311.pyc deleted file mode 100644 index 4d95750823499161d1db30b840299593d0c6f31d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6262 zcmd5gTWlNIb$2)nMwT~{(!hfP%$Rd6jWk0t zcZRE#EfvBd0fe9*LVi{Y1gH`un+-N8HfVzSbJzLl=g?rW!~lyLC<@en3bqA|{V00Q z3`vug+m8ZGJ9ByF-gD2r_dM=7_gwy}u`x{G`PUz9sOeTh{uvvUM=V#qeupRIL!uIy zsGRE4Ihk|6KG~=8s$b^~zwGBo2zvv1zzE6$M>37Qgo@_~3vfjB$-;e-@o$p%`TJy( zD^rGmGJK3OTuZ42e@NtrDgbN<5g(xu>RS(17^Gn;dl}Qvb(3SOtFG!;xAZL!RV5y;*L4P3q=aI^d**Hme~uT+g%F z4||=WkBdTN?QAEtAA4w`|R?TF1Rx!1-bZdS^ z%A3k6oeGB~Nt&LXmNX-mWtPOs>{QT9x?aU4SE)5Pux42~b82K{b8|D9bJs~`+3G-| zIwEOWij_B0>8wf-IX*gC>3cBXaV8=EQjTR;nPM2gnWQV3)jTjXfb6qmI-3DeEF8DO z@-!SyCX*5f^X|Rnl~+9Hlr250sKBDCrLDmYx;1uv;5|jp)3JdI5;Vul&G8!cY6Z$= z%^HbNvIklQ#TmgKm_t=8<$8IUs)RYFWvoG#wCMYmi+qfHN)qtsReC`0M$eQ~#!FHU zvIdAAkGY-;9-Y@QUhNp~@$ft4{_=!7;qb~Dm9o|vWuDCq3iee&hm1;QK8Kd0sx&N_ zluF;Pm@uj2wC^XSn|WQA)NDF$fI<~Z%Vxr;eM`Dlv1D}sqlyZP0I`|WveU_Mcq*OE zZ82?i&6<)1(+RNU*cIu)mh^3!$p8=164k6n$?%k}rD?{bQ_@UMNdvFr$ z<`|_yU7gf^$w){NM)7(Tqwn>8uh!>!|+v5ge@WmoVcFzvJHtSi&pXZN8qeuJ5&3>iPop<8}ftGr!HNfeq9G z@uYCu9@z-?^Lz_&mn;-Zu8sz?Z87m?R($1;hteE zsD?INE=+%h;|SVECCg;n=StxFe>r_nyoPe3rHOt|3nsI_k4qesZAsRZN`S;T_ zhtVYwbfS5t!?AR+;P+J`_w@ix~>PX(CY@`y;Mp7v)qgkmGoKsFKgr)Qb97+aEs6Eg?j4c*} zS*PGHC9(5MG5$=9AD9KPwPMEM(6G;a@M!l@DcW}6`|;yF_l5by z&La{DEOVv!#e-}ye(|%pLVU6qpM28t{@dP9 z=&y%dFH~;?s#7hR|`v_-Xjup z*Pga<(dj2O`Z11?-ZJricL$lxb!vHjHIjiE;R6# zf)4Wae*pLpa&fDsw>Gw0=nUltq9IwwQSS44G_22t>wR^HWSV=4Rk<6%c(`Z4?dLw+ zkCsX0hO~L0NwUew@PmgWRs=2q+^9NZatc<^e zf05x3hy*B`7ciQj_UO_*U6slwsg!*vrP)@_!W=BOwj~Wd-bqM?vL&Sz@FL07vzuym zGm}h&9KWua;Pi%)V=Xu%UZkAxUtpp&&losq5ECB7a>PyV%r+fA))?wK;d9z*7pnTX zP$9;!B}ojgB2H_n?58!Xv3}^e4?pv70PK<@KOcyG)!qBcx!>~k@GX0IrZ{}-ANa!X zLUDMZaPDsL+}%R=VzGPC7Q3Ll{3_CZM7Tio6)1^Kd%?Zn5f9jxFJGc#bscEF$w&7VvxIMF+ zT3)wlYL#RWn$c8BrDmFG?x6q( zNaD&_A~awIOS5zwC!|uKom7gUYa~P`s8XF;)ZyW_;rQ1eC3S?XJBi6KHF5lyn>&0i zZ#hCa)C0%Sxh$llX*_|vJ=s)7tY`+!0&VoBrqjD{Cn@KZP6%&Y9&PlU<$H@aDBf5+ zL}Urpt&BWT&P}UFoFi1bRp^u0<-O&E zY2^quUB`1;j&Cei$*cp%MeevaK2Khud_XhIG~8p+bvmbM#)K2Ks#GRncQ1mo0304R zn@3rS4J_=Pr{0-mVNfugmvL~jF{hu*I=!@PN&%_ zH1X6k=OFGvY~#42hO?aih#Sb13zS|EUO z{jWgjY@h9qdj*&4cS9-9#Y+Cm_OVi#Achlopww}C_a44DI)Eup>^-d{>6jP;Y1;lC`J-TL=23V#9_O> zJQw@+LPfE!APyA80b3kE&gMB=yir@8i!mEY*Jwc;D~e;bIQFul@DM8810}z>djpjn za+OUuu>WXnc~07Q#Ug3nU$dpL0vRuoahr_8id@v&G9}V&*O%wyjQyr^W&L%hiXXXEr?JG99{9lz4>9^lh-ei#GU7<*t_Xi6kRwS`6N&hp_fB5+D@y~XC zu~Q%uMKWQN2{dYlXKd}T`$?NkrVC`cNT#9U6;p;_@{`~x@{!QX|D5aPe-%uUzZE9= zzvm|TFMKUC?c|I0@!2r{G{hl{`e)n7(^hV-ojh$5X5;+Rm=Eh`IIPDnL;a8Kfw?pM JAG4e-6rR0H?)LVwmm?7mL~t9yBQTr9A|MhJn}8reQ%y6h`zE);?e1)5W`)~o z8%t{&!BXu6|A^&sr8bra=~DUDctPL5%=djW@8i8UpM2jV7{A`m;hRIq&z7tM`JcF? zc)TY-7y*Yl&|w|uvMy|}4cKIx&|^L5vp%@Yg#jCY_liu1OIM4FQW$Hh$?3u-Di2Q1 z&Q61KrGt|)i*iG&dx^D$c@&20r&NmwY$8C#hDufS4(Y=Kx-ZE=hgAM^k>|oD!Al`+ zRqbZt$^2T;tw5EYRo>GgiW3nW(*0`kOce_)XNe8|%PhCBogW`Q2dj_oz6JC_OFSQh*^r5ePFZ5*(4tgvU0)44(2T}+=^*?(bn$w5Q?f!4(|2hBp z{bqk08d4FAf4;eC{uxH-Z?Wi(P-pVucbGgzCMqCPGUc*VkW9r4mF0?3P$VQHBHifv zA~XC{Lg*R1?NJE#*&}`SNS{60XOH&TV}14*iICW;To@o>5`}-2#ED7<$$%vnhRi`z zy)P9KX8b-XBuzPwQbX%MtCW1@62@6tvusYNt(P^ITV zUEAQ6V>8T4I>$OC*npK=AtvtTD%WtahI5@7>RQP%O4uY-Vw>2pF}cktsSxm5C2L|8 zYyg)?xk@O*Gt32dok8A8Rp%-7xj4x4&&7$RBtKqstunW4jd99GK(}&vW%dfYDkQyP zUwvYP;xXbqSP|Ml{58*~ zFn`utQ)L6)k?pY!^nFhU33_8g+703zc|$-Wt^e_vb&J?o$IzW+U&l`I1~K>tn3C%{ zHOquC?5tv5s}iB(E(IWTm{loZ#OAty20T;@BLJwA$FgBbuni8kNH=*q4Y3W!6t#4K z$0VJ_T8U5+q_K$sWp!Fh48!Kh~}9D~`*VIBeMa%ehR+sgMk~-^`?eVXM~l4689tDrUxI zgl4)F&h$|@U9I`U+|k;t3YI``bO_Rp!^@6=xQqT(QEbnn>F?gJN2eRn=@wGL)6K-_ zrn0GQCq^Gu9#pnY*Aqt?i6fwhC+?no0b$5^4Sm#O#yzn7e`YZGEV?HR0DIof46~0J z5)zm8UBn||2kkM1Xh=fK$W-!Z4c%6j(VCPBt^az8z*VYPHo?{^0Am4^J**uY?i-vV z*8z|Yc1B63x&bjPtpoMGjVK0W8$#*vS&R_A#7LvkauS7FBy6JAZEd{hYJ3CAi|90#{^ozQn z{3b0ZDJf_uHS9+<&2$V+^JPl>Nc&sXz5`LQu*$@r(7ssw{LCrsbawGnHm99mJeSpS zS?%QVQq~`TyDh(z^Y`yIL5@qW;`(y-j3RJvw^C4cap^)XuL=FWx9EdSgo`y!7#)Tt z{gKWtU&RKODmdq#5KVwj0L9DLe8n-{GFhO9K_@U`br5i5lGKtTQmBQ5NFYhQJ0O1B z=#aPj*`7SQm3va~W=_;67aEfb9-3$#nBF@1%>;}%(C+8ZIa}c;aam+h@!5hEmp}o!h$Gwkp-bCI*`?f;^Ui@$~6!iuU cwZh7n?4gm?peiL>Xt$Uclz;$lilF8H02l>6&Hw-a diff --git a/Modules/requests/__pycache__/adapters.cpython-311.pyc b/Modules/requests/__pycache__/adapters.cpython-311.pyc deleted file mode 100644 index 03d8a4e3bec4c79ad28cdb71487adff67b45dff6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 23104 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
Y}E;{K5gJQNI6q*CxuHLkS& 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 diff --git a/Modules/requests/__pycache__/api.cpython-311.pyc b/Modules/requests/__pycache__/api.cpython-311.pyc deleted file mode 100644 index f77c3fcbf98fd5438ed2edb36e634f1400beafd3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7465 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 SoIAsni}y*+7mvs%^!k4VEqS^C diff --git a/Modules/requests/__pycache__/certs.cpython-311.pyc b/Modules/requests/__pycache__/certs.cpython-311.pyc deleted file mode 100644 index 89b279a693231b2a420d1acbead0b33cfc75c498..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 682 zcmY*XL2DE-6i#MlZH@M*usyv?sSC>t-bD~m5b7SZr(TA1@@6;eOtK~!bv?)m3M+UN z{09{&{+HrO_9S}I+d^+WnaoZ>U-H6xZ{GXzzP$Oov%`p&-|wd4D<$Mta4se3jPnC; zd?JDz5kW;%(KAD>PrsH%7 zr8dCfK&s{?2x*;>$BmO(K^w2R@>qhQdM=GtH7Yl3K?|;+m~b`5_Hs`_D!HjE;YH~9 z)&QLD82cM6&baZksyXXA6oGI@lKlyNuL% zCx;xxYxMEn%t+t&z<-oFbVCigrv3+MV zpu6U}M+mdFkNvTZDW&Txj3#Rmj+=z;o{|2)`$v3j`RZHTKa2a{ldFpd%f02^`~465 UZ$@uNi*~JJlI;4=Cj6p*0d$nmN&o-= diff --git a/Modules/requests/__pycache__/compat.cpython-311.pyc b/Modules/requests/__pycache__/compat.cpython-311.pyc deleted file mode 100644 index 173fbf490b049f9e03256db1acef0caf68c1be97..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2066 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 diff --git a/Modules/requests/__pycache__/hooks.cpython-311.pyc b/Modules/requests/__pycache__/hooks.cpython-311.pyc deleted file mode 100644 index 24b4d1fd278d3cd58711f5721322b3aa44b6e1f6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1212 zcmZWo&1(}u6o0cHX}d|SA5n=^7{MsXu{`TnHlebE5E zNhJ}ow;4?0W&=D}0FPA20`auRu%LN5qV5^j9Y7o?f_3$sTtUFa- z&_>`b)fsK^VA=PWpkb9!*J(NT{JJ0dXeb9<8E@|;qbeB{D`JreKSUmn@2M2a_f?T47DbosfC7%!3AX=w9Zc6^|xCZt`HcA_<`59GpbJ zN0Y}8;x3UH*uw30q5?i%n{yMUq}jlE2xI!ZOAo%f;5pt~KTPZs-P$ z*7WKLkCmOJdT0;5Q}w`g>SDV1J7hneBaR`oVJBS}j?H{$wtN1UIzTTJNNirab?fH5 zx+|AW!bcI}@xPAX8MIB{6h{!+&{H|zUch9Z(uL2c83pyRD>+Rhg_|_a!Bd0{h)9e0 zASrr{`u`Ha781Pui)0ze^Wh&EBjS-Qq;Ol(sD$fCIFXSvaCc(O&>%7*t&HbH`Wy0s zteKJdNQ=xhZGC^F$ttd1obg4=3Ee98p`-eXN@o3_>F^aAG|^b`u~@X_GndhzOg$%b zit(szBg=K$#)|3{7RDo0M>t`~3#nMIv6a|V)riOBV#{yhRPBMoDpIZ?|WAnFBAcKfm5}pUth$p*oW3L&`k;C4I1a zVe`zVbpCTX-v=@_**ko!d$lv$%jWu^kDXS~nd#+@Z)P|Bo!ogG?=KG5&W+wgZf7Fj zn>^JW`_W5hcZ{s6#8Id z3gxUywU2!NIo&@mlfBjy}) z#$01AmS>H+W1cY&JGMnDW8N_@JFbZOV*W8dj_qMbv?^9TRvoJut6}HPXl<-+td1SK zqV=(cv4&XVSYxbdtSQz!)*NdYYl*dvwZ_`U+E^Jk%4`^u*s%x4?PKk+j8^<=rHjQm!Y2N7OSYRv=>ly2bZ5i7V>mBQj^^Nt#f@49J??Zm$*j9Gz z$MLqYZS1%T$F8w{c3h3)?PJ^7aZPkbZ0Fccc3d0X727?wn;q9hpNj1n+ry6QqkCfm zV*{~$WBX$J$M(k#j2(y_96K0$dhF@gGh@%h4vig(9UeOz8yp)Hg~;wpL+UHR@e$qe zur($i=^s`y9*dL~d7EozI6&XN5rb+&QNl`NnJ{ zkxT?*)8R-o;e6e=Ih~^yrxFq}XQL5mVmh7-O~n&Z@?u1qk*8uI`I^ zG&6lQB1>n~N}a!w498DPtQc;P;zQI9DeStv7bGAk{#hLZspFyQ;}#G=Z%p# z)jl4ZjV7mNLUM9^a$1gsL&*>_9Y{z-#%JZ|Z$z{*U@H2O)8lb8;7VjXk(8(67mB{w z_!O&QDlr~POiWGTI?uDCqt6`}aXcxob9^k0Z1)j}81hY>ko zE7lBNoQ+?OgpW`+p_#l#y@S*7INmAV5KpKfyaL(I)2q)W$=u{&4n>KX8l(3lqu)ze* zv`xhhkDo)*J3>SN-WSG95n%oA2tP#HkF=s=mWVZMT9s-;s(DpvMc9JbZ!Oj+vqgRT zr>0(;icip7P&dLf^#AzZ0K6ky5az|CEuF7i`=u`wPDk$YuCGrrMzU=ylB<8Lp@H3#**kS%Usi8 z%-b+Wexc+=31eGIPD`_iNboCh>sR8_MIm658&OBmOoPlagHlBsFhC?8E?R+TGJ<=ky~ zcUxL~==I&alC~7Q)hmMNs4rC4rH3BcU2i$xbY^zu>Pi<1Rlwcee zL&B>cyn&T{ZXnUTs9}-V#;Kw)$+tzEx&iI7Q7_`ju3^LGdCBLv^FSP zN(@`?*o-YdE6}?PRLuP=hNeJwgk)fBpyz}%6_-NN%v59|B27<9w5$i6PBwV}UYd$V zrNrz6FnD5eHX6Mq@r6`h!PSeAIL;G^NLUIbP#GS5_=jeS1b}RSZujBHsu&iq0u4u8CwQJ`pLJiMFtwzm~-MRdF$t z2qlxUydC{4R}PQtXv6A-HMb~UE}E_+isF?LMv@QFRh8rXvT@e@ z#9Zf^h{jmx5-v=D+y}b(ZI$4z%Y@%Q`%(A8$($>YcLi32YDYt%x;}kk*#jiBusi4J z$a^|g1ivA9Am`bb_iS7dyhyICPY*9QZeFU%H3svI!4<*jX=31QYevj$U#@OlIR8;k zuDUN@-3JWjZ~N&>_s)FMl-qSOzw0DRC^WS!)MO498k<*y3O_Ce$Q&xvH)Q4u4Q(HI z-t#=#_4Fs=uXp5j9nJ4Lnw3Tt#eZV|fqkhyC-vv0{;bsh+4IZ4yU2>w+}ifJ+1l9j zg#fTZ;L8;&?)F=sP}92b;?mA+^|oB~wtV%rtb5x->IZoc9X6rEc7lc%uK@48gE^7# z>Srmin_+H!TTGf!g|ekYJ+?H?FWFd6*&O}02n=X4;45)PoGQbDz+qY9dM-{`+}M=wjQ|B3S4PTSyB7<=WQw58*drvwmkt4dy^iuhd_bY zj6I0D*1?#D`Yr3%51eaRBno%c7PcDi1)OU!)M`t*OBWfR7`56Kb$wDQw??hDHE`~& zo4-m4LqbM;Rb+3YV%`?E%-iwrC~HGasqSQ5>3G#@yDv#JkFu5bW7u|?jbj<_hTYFO z?~3nw;uRIj6&1Jwqj(-y%-iG5IK$ZIXY-DDb+TE#=jyjNBc>|mohjSA%kWGteZT78 zT(YH9*JRlklg%mDygS}w7>Ta1ebsw$EqY6}l#Yy)I%=|}T-U{$zo1%^?WJ<5ij+I$ zOgZj2jC}mOC*@hxt&+Mc?01~TkwkR!+ADI(Q(iJ7-ZUq>b+whvefG90=e?=Qly{Qk z1+LIXKr$sF`22MEngoU#i=M_{ZzTr1k5&>akBmJ1eU@b6!xGXTup0k?YcVhW?`0(( zh3G@6E*82bosX0j`pqgk*(=cz1S5f7X@^2LNUL*unLq`6^|hHuKwIk3pF4lQYjFK+ zA_)ecbEb(viC&niA7)(|Ljh{zj68j1DjW$1=bDD--LUldG|LM~pcTNC2W1jxjmRX( z`VGz5-_Q~wle{ZnDO!k6mPc?>w5!hv%7RG}h$VM}Lm?T#ID4AvqVvU2be79-g^-Y;b#$2dvSP?uPTnvyA3)MB51CN@!7eha;%{6b$H*ZDZ z+Ro*c4U6Kt!?%YQ#D_I)4{Eya*L45ZCP+O?-9N3(ZFnlb;i(m~sddxBkq=J3cM_yj zOMkwlKiks(uzlll|Gs;NexAtn59a#^vn|IL4t?5uh81|_HgF#f@#6DT-&hVfBVH-FD`uJdoO2R zF0^;NeVpYSUO4=)d*j<9{AAIzXnIuJxp*j7yD?w8F2GA(emRZ(ZzP+I4UHCvw(*Jm){2_aDcjxho&ITkpGDm$rks&bfnmcQES?7Tk3_ zdEtD{-JW;1XWi{Mc+|T4?p&_*aK80$&fb)^q@xeL)tOha-uA4$ol%@40Xwl6G}Fh& zi_YkZI7GqQxdL`Xbox=h|%q4URGs1lU92&tHwCtMNbYCQ!K7E|J12w~IvW%4f2>r{`jfdkiZ`(<=Shra%l zSR%a^K^?8$Qe~?;^dDBpMqH(mDN{LBE%&Z_4_&)THH0nS0o^fFCX+0uH|W0fAF$0e zLa2`c1fE=uTmX^>KOK@t${U;u>J$Z1DA^k;ib5~VB@dqQ{s!lJ0e6BEn$csJ{Cs;Cccaj@`tLx z6x>!6FD7W2lq5F9zjExq5Q#@#n~@LBZC^EHg6e}ZVRmqT6q=4`;$Tp_rhu9f{Q&<0 zf7gX<*K^pH`hV{Hr2p3!b9+wb_nbz;;`2O150$A~QM58Sx%@IJDYca?uQDyU;P+p{ z3LXB~EI&=BR@RS23%iO&FxE0<88b9?Zo}_*n*SEpCjKb^)-apk_Agj&JF~71>}(-> z@v}&_^+mqts$R-hy_9vo^vG2UA;7aaS9jjkO^e?1V!`dZc|0=v}E^=zcEmelDx-D`vWi*3jog)^8K~sZ0}yO=X(E z?||oCcN(bJ1LaEF8dFU?D|8w}m0f~t5rwY<1)LSG3a^>JE?gA@=DDe%h}!3v2{Ur! z%GC61LN`Ak7Gm>5BNNX=lCv^Yaij8VgalBelA{t*~*eTv5T_;vhjQz;*3!#pJNkK+wTD5EqnC4tR}J*#!Qzjix?rj|Tws3&@z+fuU3W z7q&qYBVtjpU}>?2t$;SBg{>%7C>cy#vizL2;MlDIz&}c$4Fgld_ z2bi=^;%oeXM5;gKL{)*Xk*O4e0%AZ_kD$shAAU-v!ZQpoVJmcuOo==xDalmbs!JHD zTzGx+Uu3TQ_MyJubw+cJ*skE;0cK{X0lT-TUg1WQLUyV zco=CW8k&e0dWzJM0}?^TX46Y~Vr!+%Km@F>NQTXraI}EfJZ%Y8ctqt@a1kzlRqU9{ z)u}g_(n{?OXu5*`QG0^4w*wOC+og-4csL4z0Z+J@rb;gp;0O3yFmxYRgC~sRMwSMF zC8r|CL#SdB95|h@@uD99=r(l(=*Kl%DvkA_3TXe&hbAsF^qXMs8JY>uH1SXrlR0z& zFO^mD0v!(ws49ws2Mx|mGPBnGx_ zrQh>Y@!+(4VJkHJn^ZZ1Qbka~2b!u3= zB$ZZ3TP@151==a|b<-53o1w9?DaSTQPaVp!19C;(a`{7G%O4TmWLruY*YXS$uw!jK zvGHmng$W683zJzvu9gxOflF6!DObvUr%V$FBCnOG_Hm5@PeFe;u2H%vGtM;mcFKY? zO{$x+;!KmqLV72RlK_HkDI3nT9))yI7}un_DLc+I=`)d-0TYp!Z{SM#+W>(|c_SUu zN-h5pK+y`#Pb|S!yP{3uwP@*)zfRyh0g}$h^#Da1pV>tVO&r*m@KGM{Fv?H<2UKpY zYj0A?M~Ya#U9mm zyghzvJZ-t@T&`sw%oKA>f7++F4TfEzUeH~G~maf{wO7tL|!uOPP;h?sf}Pf zqgnZXOiDG_>>0ShzhImn-nDsT&Z(~C(#v0&UOo7+$leNmh&E49l?pMAp2Z3-8+(?g zbW_jPqUd#@;N7w?bo)fsyG7aUTUIxYh95QX@vi`k%5~$!ng^S@sDCV!=Nl+umGB|z zm}+AijmSK0tuJ2>4Qm&^dD(?5OjmK4w&Y? zMpi>fd6rDj{t%*vuc&e;o`{iA5|&u3E5Ns$s-8*)1J3p537ZpZOqPJV=q*FA#R>%l z|KYWLY~s`P8T7E8)0E#q!kkx~XDW)P!4N{ub>We_nVVds#e&`Omg7wa$n9JE3ci|K zb`0rTCks_|w|XELyVb}6%Vnop?ngh^-yLH2gUB^+R>M3UKP4+Ax8CZBqyN<2R9Hr0%(JsGPp1 z^ROS(y{J+5HqiJL;R--|#1XcyvcqzQ9msQqoq+CeRoI1VJz+P_D#O*`N}PGaUYz;D zK0rScN7cxGjs}GSXdh`JxM4$VHc94(e*np^Fb}ksGF3^fL+bQ^wQj8O-Wpwo`s2(qM6{< z49O{0Su7NX1TuPUpA?1#)deX53Lgp>(AVMFiHI~ChiTxHO#Q%WicC(DS?Yf*(u>n> ztH>`#ma+Cp(t4zrl1)VudJ^y~3|WAuG*XTg2okTfS=PwAGm7n@^z!y?+Z4LaARD8B zO<4Q!bpSFd2O)wZzOge6@3S*?BJh%QCEHk@hVk{{MB_?=+BN*ouF+NiB6{RGR2Hz8 zp+?A{6@o>MA-_Zj!S;mspYfS#GW(p4%il+~Zmne4X0D+O0|!+?GMb(XE!C;Z-_g#Ir}uW6WQ`_3ubRCy10OQO%sV<12an zb4C%3iZ#yBcwNM0jBs{%9@v}j+nX1LbN0@>y)$d?EZE%-><#zr4GYx^lR0~L-rk+H zceB)%`}UTFmwtCz<9&PMLf4{oF`2XX=Iy;%doR0QNjK;0U3q&~*50+^hQ{oHz3ILk zM0d{Kp0|_Qi0`W@O~Mll%ls}fxN0>Pl;6h1^7jao&u=0m)|%g(98OVxspRmE#i0*D z4)0KQ`;I3xvWd;v^|@4#!#Ydnlvv_fk*>{1q?e9$r12Y#D5W9J#WiP}5oyL@=Z)I5 zYxL+9b!oH8IFE3JmV;6nqD6Y?SWk9~IzCoUf{Qwi7BiD0X(uB*$}zQtd=F$Y#F5`8 z!04fS5rRTsgiHe%S#~py0EMxUx_kJi(t=)cEy3Uux0C={n;&p znW0-JxqdlUvngM*DObNL(D)7}bk|ibC^-d~+}@ z!ic%x^(h3c!Q75s5*xoM9B`#xX_Z9hB9(7%^y$@m`kX~=FsNne*Z88#UZ8#@M#n2? zaf8xb94&J6r<1<||C#w~A=bQTg%v4$I~3M|IDNwlSVY2HTlou^;Rr~dB_{ zXa*G%V;mNua3_F{WnE4)Y`RlsinVs1mYXoo3-Q`c)LWW#(7M<~A*pek&?$(j_Jx@j zTSsJiUCf+zHksJDn_0n-QS4M00_s!9lV1TSI*tvE9O5o6?iaXw2X|L7ks=L@DCxoU zJzlIEC(j$IMllWvL!FXH&TTAz32T?j(93ugmEvXCtJ5y}Td|lO8^F@Nv+sNR7LrRl zGyAyt=!5E~?pHr`uOe6dOuqV=^iX=}OR!2eUnhYG7$g-eSG7SDLMoOGP_e)WAni&J z1OCT7{lZ^Y9Wt8@N-<)&*;M#jK%>wAcBQ&OZe0K6I=on2E^1M>a$D7TG43_kkCxf8 zGGPP_pH-W2GR?y`G9_LSh# zo!(|LY=s?xDQsib1QqX>*^_=7QrbkdzJ8^=eGR(=ThzYyLxDQOk(P4diF=+}Rv1%`f_tf=gv28icKd*z=Vbl=tG= zuf%8Mr`YetKn=HXIDu1!nwc?S(H13RMp*7e$rH8cgkVBWCdh1r3%rR6mkBw@odA%J z%NG)I7oF26m;V`oy98)4<+e;)>8J@n6`wQ7IZ6MDHvaHjWd7HbVj+D_$(;+fl5*%m z47^NHj1+D0ND_u0MJKd?iu=Sm@^twhp|ZK=@+CrDr@_^{N9)2>AXvCmRFX@@#QVE) zuJ*jEovbOE3str6^n9-e24+=V`Kqq;V0!RTRc&VC?aj9~rw765daK^L^yZ}-(VNk< zdBrKXy_wGRKzd+d;)AL8rry1L`|^Xfo%h>z-hDCGwm;vtKRp0DK&9l5*b?jC6N(GJl8Zw(c|7GxoGdoo+qoppC( z-T9IhppEov6MQh`vp6c3t2V5dME}l(1TORMWT4Qu4F#1Gmh!pTTwVEv0Dvd;RHE^| z8oJFbKvo z-+p&zu6|Fxeow}dv3$8)O^c=HUSkd{u5|E=*i#}~$O zp3QmBW@^L$Yr~#g)!uy7-mH5s9N@p3XwElx^6GeQ|*QlCj~#h7K4RRyMxh zvpBglc{hA-=#%cx8nWGIa!qIRO=okJqxs6wv{})Wr0r>Yf+o$Umiogj!ly0H!+Xu2 zZmc}K)BNd9D~^A;w|2-Y{L0%j6fhg;YGP0rF>wzEMqnN*S7k2*bpbgjk?Sl~;0LHJJC85dmbPd^1S&xI&Xl>!D3W!~mk)DsRSBTsucX zWH~^9&kp*W;#&jaV7r%S#v5EpxSY$LITzJ`+p&P!1*T_+%{~< z)%WJ>dr7QSa8<#+)N!ED)c!%=dwuV2y$xGki{}6X8QUWtjUQiM-q)A)^%dH>-gaRY zL<&#s&sc7`|E{%fDV%HFk#F6R^X<&~cCNTk6{~N>q*lVIeLab$5sm+b5shJS-hzJ+ zEs3d=`Hc%<)4UZ#l=g-N-Frxx!{$2{BQZH|iFdBDqpF*?8OTPcTklwn*MX1{=WVas zN`#c*EkD6|Cqd3TG+I|};j(3R-jei|3K@uXfS?ZspOmY*5ypkQRS|xsANKj^M zz;F*(gZLp}wWo0%5f-bqaxpRbThoxDR>R0KjrjV*>P{c|1bVM}JsM0QHSkvShsju3Bw z#sAn!Hc!LwDse#LGkp~n>2aJ?D6(M2o6EzvThWq?M5A;4XIcCOXq-?XS@V!8m)k*+ zLJI0Jra6LUYa%+Efc!Z4RVCEM4Ya?f_Fp-iou*s=Gyhm zd#&&4)vJBXpbMlJ_lFJ7sV*>mHMs0axGWSUTNKNWFMy<8Gec?jOUQ}8q9=Q6FZ#R`ZWnAh)r zO_z{3u2^yUEWg0UgSHf_N2ZgXI3QghbXSGB&$|B8ZCcM z%iKI8dsiw!9l?kM${RO?7^I=@U9e;uHiK+x38qg%O5)kOT;Gwehnw)d+HC#Px%#K` z^-n7_UMr|4&)yPPuG_dM-`$z5+mox?lds#8_3Z(PM^vh3FMhG8*0e2zKRS}D?#Wj( zUzuLq`kiln@0*KH$hYqk80{4`QWUxa4F{tSz z&9nKMXS2R%;S}ttgi~-WwCezA2Oh=^I<42Sp9s^o<;IT1o$qeAy&+@E*uGq@X?_3o zzuP*PtsbKGwv|Akv6V_>Y}Cv)YA%}DkRE#Et;-}AUW5rX^X$pO_rz}X?rtQCzoP{3s9X9!-h5}XS_ZP!l?oK0`ax}zlai-uxh_zsIr_QT zRA2Rl0DuS({wf5MAX*-z^>Y9IdoSkthw}YHL`P&>`*OZu))#!Z^8i2Jmh<&zef>n^ zqC&gpgjm?L<-w-C_c!gm*ZoONZqsmn({Rq$m8r?3GAU^4Ky>&~sCmPK=HUJ2;8HTz zyffdtGc&YY-@e%OV`r{@N4}mOqxOXO)2sKApS+lR>SX>YczaU{DqnCfxF2ph4nS5x zo9??eEm?BzzP!6H>+Yj=zyn3}>|boVoBT;C+dhcBuyr4`cHxiUL#1d1(~h(wu^R*R zW?iT7kDU;g{n&rd{5Mt{e7e^==n#JCXdLV||FTOYxW93zPWV+_>(FlVuXc%m26C7t zD*Y=4IVtgtUOiE?Y8gOO6}izMa4sVNfRHga_!c%1LRN`Zhfk?&C9izzs%fhxZq{O{)mX#vHifBLmQ(T)5LQGX5|bz1&{yciG^>$C5ybW zpuuoI@JaW5;3fNWzU_J6_N;FJGbY#%#`6Nj;a~wF4bQIS&83vDzrZ&Dtxa;f0qvgtD1Wz$T0VR^aNWN;IutmKDy^OACF(|3Z zXwI-nap`s#T<*p1LIYqz%ge*6fH%`Au-0~>PgzPTF5~ktHMNdjLO&@RY9-EuZROXf z69wKF>(VQv5aw}4M&uVz3$(#K_~BuE%%S)-zK*k%n)F37aR%g4M+W3@qqEJ^zqFl}heuPr%FOPH)!pI4Uzd|vnjO~Kkm)^fjtKXf5T>bWZ z{r2>;%Nsft_q;oQdp=veJF_RV=WbVe2xEOka66bYXxB&9oOfg13&D-a)BEEcOUaM- z-r0Lk{L6z&2OrgUErzqS&H-8aYq5@wzU{o_OdrB2M*67-Zt1>TTJ(R|lympy-Mv|N zFUwJJ?HxzXy*=-SucETAG~%x8)|`XXP!}FR8{MlV1xB?)3E`EENIMgFYDh0$W2B*t z?;l)+_};!z?=Zkm+UbwhOR_lf+oQX4jnIXOR`>An8Bl*D`7i$ z=XYq2q`U*>Hb72Q;6x&LoCrB9lzgv7iZ*^B3?`4!j3-9F=-_E^NZ>kj;-2JI0%X~( zE^o9f6+QfIsWKlLv7n$i?fj2%vc8mvUzi~3BXJ%jAvLZesquyPujMyv&$)KwT|_!L z_7++?u^OF9pL*1?^=?J3Wlz3k4<$Tm2rPBo>AP2xYdDy1IGFYnTn$-QSD|}5EnW)^ zId?~v?JH0LcOz%@lqPWsHTm�JLDuP;?nAGeg3wZA?>w^wk?N(J51jzcx-nSnqFO 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 diff --git a/Modules/requests/__pycache__/sessions.cpython-311.pyc b/Modules/requests/__pycache__/sessions.cpython-311.pyc deleted file mode 100644 index 4147462b28e58fd73ae52b5dc5e3d3f6cf8f21a8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 29655 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 M>2lMo{^(Tof0LL>@&Et; diff --git a/Modules/requests/__pycache__/structures.cpython-311.pyc b/Modules/requests/__pycache__/structures.cpython-311.pyc deleted file mode 100644 index 56925ddf07d71ba245937e9999d7329603331360..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6184 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

=!C?q>8`2KaS zkaW4|w2+{&I4vZ88xNz7LgKHY(?YUS?b&j^4+hA5U$JK?XZt>Cd?C5c+o|>Xq^6q6 z6p}qP^!oZ_z`}#A(kJCk>cm3Q&`h-yk`r*#@UmrPE@o|wlC5#soU?mUWpCClTM7s3 zmM!!$h2(L*jvoQ{rAY_fRHBdsY&_QDEF^v(4|b@Kw0Za;+^$KRz5E&EY@RZL`u_)a CNT19A diff --git a/Modules/requests/__version__.py b/Modules/requests/__version__.py deleted file mode 100644 index 5063c3f..0000000 --- a/Modules/requests/__version__.py +++ /dev/null @@ -1,14 +0,0 @@ -# .-. .-. .-. . . .-. .-. .-. .-. -# |( |- |.| | | |- `-. | `-. -# ' ' `-' `-`.`-' `-' `-' ' `-' - -__title__ = "requests" -__description__ = "Python HTTP for Humans." -__url__ = "https://requests.readthedocs.io" -__version__ = "2.31.0" -__build__ = 0x023100 -__author__ = "Kenneth Reitz" -__author_email__ = "me@kennethreitz.org" -__license__ = "Apache 2.0" -__copyright__ = "Copyright Kenneth Reitz" -__cake__ = "\u2728 \U0001f370 \u2728" diff --git a/Modules/requests/_internal_utils.py b/Modules/requests/_internal_utils.py deleted file mode 100644 index f2cf635..0000000 --- a/Modules/requests/_internal_utils.py +++ /dev/null @@ -1,50 +0,0 @@ -""" -requests._internal_utils -~~~~~~~~~~~~~~ - -Provides utility functions that are consumed internally by Requests -which depend on extremely few external helpers (such as compat) -""" -import re - -from .compat import builtin_str - -_VALID_HEADER_NAME_RE_BYTE = re.compile(rb"^[^:\s][^:\r\n]*$") -_VALID_HEADER_NAME_RE_STR = re.compile(r"^[^:\s][^:\r\n]*$") -_VALID_HEADER_VALUE_RE_BYTE = re.compile(rb"^\S[^\r\n]*$|^$") -_VALID_HEADER_VALUE_RE_STR = re.compile(r"^\S[^\r\n]*$|^$") - -_HEADER_VALIDATORS_STR = (_VALID_HEADER_NAME_RE_STR, _VALID_HEADER_VALUE_RE_STR) -_HEADER_VALIDATORS_BYTE = (_VALID_HEADER_NAME_RE_BYTE, _VALID_HEADER_VALUE_RE_BYTE) -HEADER_VALIDATORS = { - bytes: _HEADER_VALIDATORS_BYTE, - str: _HEADER_VALIDATORS_STR, -} - - -def to_native_string(string, encoding="ascii"): - """Given a string object, regardless of type, returns a representation of - that string in the native string type, encoding and decoding where - necessary. This assumes ASCII unless told otherwise. - """ - if isinstance(string, builtin_str): - out = string - else: - out = string.decode(encoding) - - return out - - -def unicode_is_ascii(u_string): - """Determine if unicode string only contains ASCII characters. - - :param str u_string: unicode string to check. Must be unicode - and not Python 2 `str`. - :rtype: bool - """ - assert isinstance(u_string, str) - try: - u_string.encode("ascii") - return True - except UnicodeEncodeError: - return False diff --git a/Modules/requests/adapters.py b/Modules/requests/adapters.py deleted file mode 100644 index 78e3bb6..0000000 --- a/Modules/requests/adapters.py +++ /dev/null @@ -1,538 +0,0 @@ -""" -requests.adapters -~~~~~~~~~~~~~~~~~ - -This module contains the transport adapters that Requests uses to define -and maintain connections. -""" - -import os.path -import socket # noqa: F401 - -from urllib3.exceptions import ClosedPoolError, ConnectTimeoutError -from urllib3.exceptions import HTTPError as _HTTPError -from urllib3.exceptions import InvalidHeader as _InvalidHeader -from urllib3.exceptions import ( - LocationValueError, - MaxRetryError, - NewConnectionError, - ProtocolError, -) -from urllib3.exceptions import ProxyError as _ProxyError -from urllib3.exceptions import ReadTimeoutError, ResponseError -from urllib3.exceptions import SSLError as _SSLError -from urllib3.poolmanager import PoolManager, proxy_from_url -from urllib3.util import Timeout as TimeoutSauce -from urllib3.util import parse_url -from urllib3.util.retry import Retry - -from .auth import _basic_auth_str -from .compat import basestring, urlparse -from .cookies import extract_cookies_to_jar -from .exceptions import ( - ConnectionError, - ConnectTimeout, - InvalidHeader, - InvalidProxyURL, - InvalidSchema, - InvalidURL, - ProxyError, - ReadTimeout, - RetryError, - SSLError, -) -from .models import Response -from .structures import CaseInsensitiveDict -from .utils import ( - DEFAULT_CA_BUNDLE_PATH, - extract_zipped_paths, - get_auth_from_url, - get_encoding_from_headers, - prepend_scheme_if_needed, - select_proxy, - urldefragauth, -) - -try: - from urllib3.contrib.socks import SOCKSProxyManager -except ImportError: - - def SOCKSProxyManager(*args, **kwargs): - raise InvalidSchema("Missing dependencies for SOCKS support.") - - -DEFAULT_POOLBLOCK = False -DEFAULT_POOLSIZE = 10 -DEFAULT_RETRIES = 0 -DEFAULT_POOL_TIMEOUT = None - - -class BaseAdapter: - """The Base Transport Adapter""" - - def __init__(self): - super().__init__() - - def send( - self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None - ): - """Sends PreparedRequest object. Returns Response object. - - :param request: The :class:`PreparedRequest ` being sent. - :param stream: (optional) Whether to stream the request content. - :param timeout: (optional) How long to wait for the server to send - data before giving up, as a float, or a :ref:`(connect timeout, - read timeout) ` tuple. - :type timeout: float or tuple - :param verify: (optional) Either a boolean, in which case it controls whether we verify - the server's TLS certificate, or a string, in which case it must be a path - to a CA bundle to use - :param cert: (optional) Any user-provided SSL certificate to be trusted. - :param proxies: (optional) The proxies dictionary to apply to the request. - """ - raise NotImplementedError - - def close(self): - """Cleans up adapter specific items.""" - raise NotImplementedError - - -class HTTPAdapter(BaseAdapter): - """The built-in HTTP Adapter for urllib3. - - Provides a general-case interface for Requests sessions to contact HTTP and - HTTPS urls by implementing the Transport Adapter interface. This class will - usually be created by the :class:`Session ` class under the - covers. - - :param pool_connections: The number of urllib3 connection pools to cache. - :param pool_maxsize: The maximum number of connections to save in the pool. - :param max_retries: The maximum number of retries each connection - should attempt. Note, this applies only to failed DNS lookups, socket - connections and connection timeouts, never to requests where data has - made it to the server. By default, Requests does not retry failed - connections. If you need granular control over the conditions under - which we retry a request, import urllib3's ``Retry`` class and pass - that instead. - :param pool_block: Whether the connection pool should block for connections. - - Usage:: - - >>> import requests - >>> s = requests.Session() - >>> a = requests.adapters.HTTPAdapter(max_retries=3) - >>> s.mount('http://', a) - """ - - __attrs__ = [ - "max_retries", - "config", - "_pool_connections", - "_pool_maxsize", - "_pool_block", - ] - - def __init__( - self, - pool_connections=DEFAULT_POOLSIZE, - pool_maxsize=DEFAULT_POOLSIZE, - max_retries=DEFAULT_RETRIES, - pool_block=DEFAULT_POOLBLOCK, - ): - if max_retries == DEFAULT_RETRIES: - self.max_retries = Retry(0, read=False) - else: - self.max_retries = Retry.from_int(max_retries) - self.config = {} - self.proxy_manager = {} - - super().__init__() - - self._pool_connections = pool_connections - self._pool_maxsize = pool_maxsize - self._pool_block = pool_block - - self.init_poolmanager(pool_connections, pool_maxsize, block=pool_block) - - def __getstate__(self): - return {attr: getattr(self, attr, None) for attr in self.__attrs__} - - def __setstate__(self, state): - # Can't handle by adding 'proxy_manager' to self.__attrs__ because - # self.poolmanager uses a lambda function, which isn't pickleable. - self.proxy_manager = {} - self.config = {} - - for attr, value in state.items(): - setattr(self, attr, value) - - self.init_poolmanager( - self._pool_connections, self._pool_maxsize, block=self._pool_block - ) - - def init_poolmanager( - self, connections, maxsize, block=DEFAULT_POOLBLOCK, **pool_kwargs - ): - """Initializes a urllib3 PoolManager. - - This method should not be called from user code, and is only - exposed for use when subclassing the - :class:`HTTPAdapter `. - - :param connections: The number of urllib3 connection pools to cache. - :param maxsize: The maximum number of connections to save in the pool. - :param block: Block when no free connections are available. - :param pool_kwargs: Extra keyword arguments used to initialize the Pool Manager. - """ - # save these values for pickling - self._pool_connections = connections - self._pool_maxsize = maxsize - self._pool_block = block - - self.poolmanager = PoolManager( - num_pools=connections, - maxsize=maxsize, - block=block, - **pool_kwargs, - ) - - def proxy_manager_for(self, proxy, **proxy_kwargs): - """Return urllib3 ProxyManager for the given proxy. - - This method should not be called from user code, and is only - exposed for use when subclassing the - :class:`HTTPAdapter `. - - :param proxy: The proxy to return a urllib3 ProxyManager for. - :param proxy_kwargs: Extra keyword arguments used to configure the Proxy Manager. - :returns: ProxyManager - :rtype: urllib3.ProxyManager - """ - if proxy in self.proxy_manager: - manager = self.proxy_manager[proxy] - elif proxy.lower().startswith("socks"): - username, password = get_auth_from_url(proxy) - manager = self.proxy_manager[proxy] = SOCKSProxyManager( - proxy, - username=username, - password=password, - num_pools=self._pool_connections, - maxsize=self._pool_maxsize, - block=self._pool_block, - **proxy_kwargs, - ) - else: - proxy_headers = self.proxy_headers(proxy) - manager = self.proxy_manager[proxy] = proxy_from_url( - proxy, - proxy_headers=proxy_headers, - num_pools=self._pool_connections, - maxsize=self._pool_maxsize, - block=self._pool_block, - **proxy_kwargs, - ) - - return manager - - def cert_verify(self, conn, url, verify, cert): - """Verify a SSL certificate. This method should not be called from user - code, and is only exposed for use when subclassing the - :class:`HTTPAdapter `. - - :param conn: The urllib3 connection object associated with the cert. - :param url: The requested URL. - :param verify: Either a boolean, in which case it controls whether we verify - the server's TLS certificate, or a string, in which case it must be a path - to a CA bundle to use - :param cert: The SSL certificate to verify. - """ - if url.lower().startswith("https") and verify: - - cert_loc = None - - # Allow self-specified cert location. - if verify is not True: - cert_loc = verify - - if not cert_loc: - cert_loc = extract_zipped_paths(DEFAULT_CA_BUNDLE_PATH) - - if not cert_loc or not os.path.exists(cert_loc): - raise OSError( - f"Could not find a suitable TLS CA certificate bundle, " - f"invalid path: {cert_loc}" - ) - - conn.cert_reqs = "CERT_REQUIRED" - - if not os.path.isdir(cert_loc): - conn.ca_certs = cert_loc - else: - conn.ca_cert_dir = cert_loc - else: - conn.cert_reqs = "CERT_NONE" - conn.ca_certs = None - conn.ca_cert_dir = None - - if cert: - if not isinstance(cert, basestring): - conn.cert_file = cert[0] - conn.key_file = cert[1] - else: - conn.cert_file = cert - conn.key_file = None - if conn.cert_file and not os.path.exists(conn.cert_file): - raise OSError( - f"Could not find the TLS certificate file, " - f"invalid path: {conn.cert_file}" - ) - if conn.key_file and not os.path.exists(conn.key_file): - raise OSError( - f"Could not find the TLS key file, invalid path: {conn.key_file}" - ) - - def build_response(self, req, resp): - """Builds a :class:`Response ` object from a urllib3 - response. This should not be called from user code, and is only exposed - for use when subclassing the - :class:`HTTPAdapter ` - - :param req: The :class:`PreparedRequest ` used to generate the response. - :param resp: The urllib3 response object. - :rtype: requests.Response - """ - response = Response() - - # Fallback to None if there's no status_code, for whatever reason. - response.status_code = getattr(resp, "status", None) - - # Make headers case-insensitive. - response.headers = CaseInsensitiveDict(getattr(resp, "headers", {})) - - # Set encoding. - response.encoding = get_encoding_from_headers(response.headers) - response.raw = resp - response.reason = response.raw.reason - - if isinstance(req.url, bytes): - response.url = req.url.decode("utf-8") - else: - response.url = req.url - - # Add new cookies from the server. - extract_cookies_to_jar(response.cookies, req, resp) - - # Give the Response some context. - response.request = req - response.connection = self - - return response - - def get_connection(self, url, proxies=None): - """Returns a urllib3 connection for the given URL. This should not be - called from user code, and is only exposed for use when subclassing the - :class:`HTTPAdapter `. - - :param url: The URL to connect to. - :param proxies: (optional) A Requests-style dictionary of proxies used on this request. - :rtype: urllib3.ConnectionPool - """ - proxy = select_proxy(url, proxies) - - if proxy: - proxy = prepend_scheme_if_needed(proxy, "http") - proxy_url = parse_url(proxy) - if not proxy_url.host: - raise InvalidProxyURL( - "Please check proxy URL. It is malformed " - "and could be missing the host." - ) - proxy_manager = self.proxy_manager_for(proxy) - conn = proxy_manager.connection_from_url(url) - else: - # Only scheme should be lower case - parsed = urlparse(url) - url = parsed.geturl() - conn = self.poolmanager.connection_from_url(url) - - return conn - - def close(self): - """Disposes of any internal state. - - Currently, this closes the PoolManager and any active ProxyManager, - which closes any pooled connections. - """ - self.poolmanager.clear() - for proxy in self.proxy_manager.values(): - proxy.clear() - - def request_url(self, request, proxies): - """Obtain the url to use when making the final request. - - If the message is being sent through a HTTP proxy, the full URL has to - be used. Otherwise, we should only use the path portion of the URL. - - This should not be called from user code, and is only exposed for use - when subclassing the - :class:`HTTPAdapter `. - - :param request: The :class:`PreparedRequest ` being sent. - :param proxies: A dictionary of schemes or schemes and hosts to proxy URLs. - :rtype: str - """ - proxy = select_proxy(request.url, proxies) - scheme = urlparse(request.url).scheme - - is_proxied_http_request = proxy and scheme != "https" - using_socks_proxy = False - if proxy: - proxy_scheme = urlparse(proxy).scheme.lower() - using_socks_proxy = proxy_scheme.startswith("socks") - - url = request.path_url - if is_proxied_http_request and not using_socks_proxy: - url = urldefragauth(request.url) - - return url - - def add_headers(self, request, **kwargs): - """Add any headers needed by the connection. As of v2.0 this does - nothing by default, but is left for overriding by users that subclass - the :class:`HTTPAdapter `. - - This should not be called from user code, and is only exposed for use - when subclassing the - :class:`HTTPAdapter `. - - :param request: The :class:`PreparedRequest ` to add headers to. - :param kwargs: The keyword arguments from the call to send(). - """ - pass - - def proxy_headers(self, proxy): - """Returns a dictionary of the headers to add to any request sent - through a proxy. This works with urllib3 magic to ensure that they are - correctly sent to the proxy, rather than in a tunnelled request if - CONNECT is being used. - - This should not be called from user code, and is only exposed for use - when subclassing the - :class:`HTTPAdapter `. - - :param proxy: The url of the proxy being used for this request. - :rtype: dict - """ - headers = {} - username, password = get_auth_from_url(proxy) - - if username: - headers["Proxy-Authorization"] = _basic_auth_str(username, password) - - return headers - - def send( - self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None - ): - """Sends PreparedRequest object. Returns Response object. - - :param request: The :class:`PreparedRequest ` being sent. - :param stream: (optional) Whether to stream the request content. - :param timeout: (optional) How long to wait for the server to send - data before giving up, as a float, or a :ref:`(connect timeout, - read timeout) ` tuple. - :type timeout: float or tuple or urllib3 Timeout object - :param verify: (optional) Either a boolean, in which case it controls whether - we verify the server's TLS certificate, or a string, in which case it - must be a path to a CA bundle to use - :param cert: (optional) Any user-provided SSL certificate to be trusted. - :param proxies: (optional) The proxies dictionary to apply to the request. - :rtype: requests.Response - """ - - try: - conn = self.get_connection(request.url, proxies) - except LocationValueError as e: - raise InvalidURL(e, request=request) - - self.cert_verify(conn, request.url, verify, cert) - url = self.request_url(request, proxies) - self.add_headers( - request, - stream=stream, - timeout=timeout, - verify=verify, - cert=cert, - proxies=proxies, - ) - - chunked = not (request.body is None or "Content-Length" in request.headers) - - if isinstance(timeout, tuple): - try: - connect, read = timeout - timeout = TimeoutSauce(connect=connect, read=read) - except ValueError: - raise ValueError( - f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " - f"or a single float to set both timeouts to the same value." - ) - elif isinstance(timeout, TimeoutSauce): - pass - else: - timeout = TimeoutSauce(connect=timeout, read=timeout) - - try: - resp = conn.urlopen( - method=request.method, - url=url, - body=request.body, - headers=request.headers, - redirect=False, - assert_same_host=False, - preload_content=False, - decode_content=False, - retries=self.max_retries, - timeout=timeout, - chunked=chunked, - ) - - except (ProtocolError, OSError) as err: - raise ConnectionError(err, request=request) - - except MaxRetryError as e: - if isinstance(e.reason, ConnectTimeoutError): - # TODO: Remove this in 3.0.0: see #2811 - if not isinstance(e.reason, NewConnectionError): - raise ConnectTimeout(e, request=request) - - if isinstance(e.reason, ResponseError): - raise RetryError(e, request=request) - - if isinstance(e.reason, _ProxyError): - raise ProxyError(e, request=request) - - if isinstance(e.reason, _SSLError): - # This branch is for urllib3 v1.22 and later. - raise SSLError(e, request=request) - - raise ConnectionError(e, request=request) - - except ClosedPoolError as e: - raise ConnectionError(e, request=request) - - except _ProxyError as e: - raise ProxyError(e) - - except (_SSLError, _HTTPError) as e: - if isinstance(e, _SSLError): - # This branch is for urllib3 versions earlier than v1.22 - raise SSLError(e, request=request) - elif isinstance(e, ReadTimeoutError): - raise ReadTimeout(e, request=request) - elif isinstance(e, _InvalidHeader): - raise InvalidHeader(e, request=request) - else: - raise - - return self.build_response(request, resp) diff --git a/Modules/requests/api.py b/Modules/requests/api.py deleted file mode 100644 index cd0b3ee..0000000 --- a/Modules/requests/api.py +++ /dev/null @@ -1,157 +0,0 @@ -""" -requests.api -~~~~~~~~~~~~ - -This module implements the Requests API. - -:copyright: (c) 2012 by Kenneth Reitz. -:license: Apache2, see LICENSE for more details. -""" - -from . import sessions - - -def request(method, url, **kwargs): - """Constructs and sends a :class:`Request `. - - :param method: method for the new :class:`Request` object: ``GET``, ``OPTIONS``, ``HEAD``, ``POST``, ``PUT``, ``PATCH``, or ``DELETE``. - :param url: URL for the new :class:`Request` object. - :param params: (optional) Dictionary, list of tuples or bytes to send - in the query string for the :class:`Request`. - :param data: (optional) Dictionary, list of tuples, bytes, or file-like - object to send in the body of the :class:`Request`. - :param json: (optional) A JSON serializable Python object to send in the body of the :class:`Request`. - :param headers: (optional) Dictionary of HTTP Headers to send with the :class:`Request`. - :param cookies: (optional) Dict or CookieJar object to send with the :class:`Request`. - :param files: (optional) Dictionary of ``'name': file-like-objects`` (or ``{'name': file-tuple}``) for multipart encoding upload. - ``file-tuple`` can be a 2-tuple ``('filename', fileobj)``, 3-tuple ``('filename', fileobj, 'content_type')`` - or a 4-tuple ``('filename', fileobj, 'content_type', custom_headers)``, where ``'content-type'`` is a string - defining the content type of the given file and ``custom_headers`` a dict-like object containing additional headers - to add for the file. - :param auth: (optional) Auth tuple to enable Basic/Digest/Custom HTTP Auth. - :param timeout: (optional) How many seconds to wait for the server to send data - before giving up, as a float, or a :ref:`(connect timeout, read - timeout) ` tuple. - :type timeout: float or tuple - :param allow_redirects: (optional) Boolean. Enable/disable GET/OPTIONS/POST/PUT/PATCH/DELETE/HEAD redirection. Defaults to ``True``. - :type allow_redirects: bool - :param proxies: (optional) Dictionary mapping protocol to the URL of the proxy. - :param verify: (optional) Either a boolean, in which case it controls whether we verify - the server's TLS certificate, or a string, in which case it must be a path - to a CA bundle to use. Defaults to ``True``. - :param stream: (optional) if ``False``, the response content will be immediately downloaded. - :param cert: (optional) if String, path to ssl client cert file (.pem). If Tuple, ('cert', 'key') pair. - :return: :class:`Response ` object - :rtype: requests.Response - - Usage:: - - >>> import requests - >>> req = requests.request('GET', 'https://httpbin.org/get') - >>> req - - """ - - # By using the 'with' statement we are sure the session is closed, thus we - # avoid leaving sockets open which can trigger a ResourceWarning in some - # cases, and look like a memory leak in others. - with sessions.Session() as session: - return session.request(method=method, url=url, **kwargs) - - -def get(url, params=None, **kwargs): - r"""Sends a GET request. - - :param url: URL for the new :class:`Request` object. - :param params: (optional) Dictionary, list of tuples or bytes to send - in the query string for the :class:`Request`. - :param \*\*kwargs: Optional arguments that ``request`` takes. - :return: :class:`Response ` object - :rtype: requests.Response - """ - - return request("get", url, params=params, **kwargs) - - -def options(url, **kwargs): - r"""Sends an OPTIONS request. - - :param url: URL for the new :class:`Request` object. - :param \*\*kwargs: Optional arguments that ``request`` takes. - :return: :class:`Response ` object - :rtype: requests.Response - """ - - return request("options", url, **kwargs) - - -def head(url, **kwargs): - r"""Sends a HEAD request. - - :param url: URL for the new :class:`Request` object. - :param \*\*kwargs: Optional arguments that ``request`` takes. If - `allow_redirects` is not provided, it will be set to `False` (as - opposed to the default :meth:`request` behavior). - :return: :class:`Response ` object - :rtype: requests.Response - """ - - kwargs.setdefault("allow_redirects", False) - return request("head", url, **kwargs) - - -def post(url, data=None, json=None, **kwargs): - r"""Sends a POST request. - - :param url: URL for the new :class:`Request` object. - :param data: (optional) Dictionary, list of tuples, bytes, or file-like - object to send in the body of the :class:`Request`. - :param json: (optional) A JSON serializable Python object to send in the body of the :class:`Request`. - :param \*\*kwargs: Optional arguments that ``request`` takes. - :return: :class:`Response ` object - :rtype: requests.Response - """ - - return request("post", url, data=data, json=json, **kwargs) - - -def put(url, data=None, **kwargs): - r"""Sends a PUT request. - - :param url: URL for the new :class:`Request` object. - :param data: (optional) Dictionary, list of tuples, bytes, or file-like - object to send in the body of the :class:`Request`. - :param json: (optional) A JSON serializable Python object to send in the body of the :class:`Request`. - :param \*\*kwargs: Optional arguments that ``request`` takes. - :return: :class:`Response ` object - :rtype: requests.Response - """ - - return request("put", url, data=data, **kwargs) - - -def patch(url, data=None, **kwargs): - r"""Sends a PATCH request. - - :param url: URL for the new :class:`Request` object. - :param data: (optional) Dictionary, list of tuples, bytes, or file-like - object to send in the body of the :class:`Request`. - :param json: (optional) A JSON serializable Python object to send in the body of the :class:`Request`. - :param \*\*kwargs: Optional arguments that ``request`` takes. - :return: :class:`Response ` object - :rtype: requests.Response - """ - - return request("patch", url, data=data, **kwargs) - - -def delete(url, **kwargs): - r"""Sends a DELETE request. - - :param url: URL for the new :class:`Request` object. - :param \*\*kwargs: Optional arguments that ``request`` takes. - :return: :class:`Response ` object - :rtype: requests.Response - """ - - return request("delete", url, **kwargs) diff --git a/Modules/requests/auth.py b/Modules/requests/auth.py deleted file mode 100644 index 9733686..0000000 --- a/Modules/requests/auth.py +++ /dev/null @@ -1,315 +0,0 @@ -""" -requests.auth -~~~~~~~~~~~~~ - -This module contains the authentication handlers for Requests. -""" - -import hashlib -import os -import re -import threading -import time -import warnings -from base64 import b64encode - -from ._internal_utils import to_native_string -from .compat import basestring, str, urlparse -from .cookies import extract_cookies_to_jar -from .utils import parse_dict_header - -CONTENT_TYPE_FORM_URLENCODED = "application/x-www-form-urlencoded" -CONTENT_TYPE_MULTI_PART = "multipart/form-data" - - -def _basic_auth_str(username, password): - """Returns a Basic Auth string.""" - - # "I want us to put a big-ol' comment on top of it that - # says that this behaviour is dumb but we need to preserve - # it because people are relying on it." - # - Lukasa - # - # These are here solely to maintain backwards compatibility - # for things like ints. This will be removed in 3.0.0. - if not isinstance(username, basestring): - warnings.warn( - "Non-string usernames will no longer be supported in Requests " - "3.0.0. Please convert the object you've passed in ({!r}) to " - "a string or bytes object in the near future to avoid " - "problems.".format(username), - category=DeprecationWarning, - ) - username = str(username) - - if not isinstance(password, basestring): - warnings.warn( - "Non-string passwords will no longer be supported in Requests " - "3.0.0. Please convert the object you've passed in ({!r}) to " - "a string or bytes object in the near future to avoid " - "problems.".format(type(password)), - category=DeprecationWarning, - ) - password = str(password) - # -- End Removal -- - - if isinstance(username, str): - username = username.encode("latin1") - - if isinstance(password, str): - password = password.encode("latin1") - - authstr = "Basic " + to_native_string( - b64encode(b":".join((username, password))).strip() - ) - - return authstr - - -class AuthBase: - """Base class that all auth implementations derive from""" - - def __call__(self, r): - raise NotImplementedError("Auth hooks must be callable.") - - -class HTTPBasicAuth(AuthBase): - """Attaches HTTP Basic Authentication to the given Request object.""" - - def __init__(self, username, password): - self.username = username - self.password = password - - def __eq__(self, other): - return all( - [ - self.username == getattr(other, "username", None), - self.password == getattr(other, "password", None), - ] - ) - - def __ne__(self, other): - return not self == other - - def __call__(self, r): - r.headers["Authorization"] = _basic_auth_str(self.username, self.password) - return r - - -class HTTPProxyAuth(HTTPBasicAuth): - """Attaches HTTP Proxy Authentication to a given Request object.""" - - def __call__(self, r): - r.headers["Proxy-Authorization"] = _basic_auth_str(self.username, self.password) - return r - - -class HTTPDigestAuth(AuthBase): - """Attaches HTTP Digest Authentication to the given Request object.""" - - def __init__(self, username, password): - self.username = username - self.password = password - # Keep state in per-thread local storage - self._thread_local = threading.local() - - def init_per_thread_state(self): - # Ensure state is initialized just once per-thread - if not hasattr(self._thread_local, "init"): - self._thread_local.init = True - self._thread_local.last_nonce = "" - self._thread_local.nonce_count = 0 - self._thread_local.chal = {} - self._thread_local.pos = None - self._thread_local.num_401_calls = None - - def build_digest_header(self, method, url): - """ - :rtype: str - """ - - realm = self._thread_local.chal["realm"] - nonce = self._thread_local.chal["nonce"] - qop = self._thread_local.chal.get("qop") - algorithm = self._thread_local.chal.get("algorithm") - opaque = self._thread_local.chal.get("opaque") - hash_utf8 = None - - if algorithm is None: - _algorithm = "MD5" - else: - _algorithm = algorithm.upper() - # lambdas assume digest modules are imported at the top level - if _algorithm == "MD5" or _algorithm == "MD5-SESS": - - def md5_utf8(x): - if isinstance(x, str): - x = x.encode("utf-8") - return hashlib.md5(x).hexdigest() - - hash_utf8 = md5_utf8 - elif _algorithm == "SHA": - - def sha_utf8(x): - if isinstance(x, str): - x = x.encode("utf-8") - return hashlib.sha1(x).hexdigest() - - hash_utf8 = sha_utf8 - elif _algorithm == "SHA-256": - - def sha256_utf8(x): - if isinstance(x, str): - x = x.encode("utf-8") - return hashlib.sha256(x).hexdigest() - - hash_utf8 = sha256_utf8 - elif _algorithm == "SHA-512": - - def sha512_utf8(x): - if isinstance(x, str): - x = x.encode("utf-8") - return hashlib.sha512(x).hexdigest() - - hash_utf8 = sha512_utf8 - - KD = lambda s, d: hash_utf8(f"{s}:{d}") # noqa:E731 - - if hash_utf8 is None: - return None - - # XXX not implemented yet - entdig = None - p_parsed = urlparse(url) - #: path is request-uri defined in RFC 2616 which should not be empty - path = p_parsed.path or "/" - if p_parsed.query: - path += f"?{p_parsed.query}" - - A1 = f"{self.username}:{realm}:{self.password}" - A2 = f"{method}:{path}" - - HA1 = hash_utf8(A1) - HA2 = hash_utf8(A2) - - if nonce == self._thread_local.last_nonce: - self._thread_local.nonce_count += 1 - else: - self._thread_local.nonce_count = 1 - ncvalue = f"{self._thread_local.nonce_count:08x}" - s = str(self._thread_local.nonce_count).encode("utf-8") - s += nonce.encode("utf-8") - s += time.ctime().encode("utf-8") - s += os.urandom(8) - - cnonce = hashlib.sha1(s).hexdigest()[:16] - if _algorithm == "MD5-SESS": - HA1 = hash_utf8(f"{HA1}:{nonce}:{cnonce}") - - if not qop: - respdig = KD(HA1, f"{nonce}:{HA2}") - elif qop == "auth" or "auth" in qop.split(","): - noncebit = f"{nonce}:{ncvalue}:{cnonce}:auth:{HA2}" - respdig = KD(HA1, noncebit) - else: - # XXX handle auth-int. - return None - - self._thread_local.last_nonce = nonce - - # XXX should the partial digests be encoded too? - base = ( - f'username="{self.username}", realm="{realm}", nonce="{nonce}", ' - f'uri="{path}", response="{respdig}"' - ) - if opaque: - base += f', opaque="{opaque}"' - if algorithm: - base += f', algorithm="{algorithm}"' - if entdig: - base += f', digest="{entdig}"' - if qop: - base += f', qop="auth", nc={ncvalue}, cnonce="{cnonce}"' - - return f"Digest {base}" - - def handle_redirect(self, r, **kwargs): - """Reset num_401_calls counter on redirects.""" - if r.is_redirect: - self._thread_local.num_401_calls = 1 - - def handle_401(self, r, **kwargs): - """ - Takes the given response and tries digest-auth, if needed. - - :rtype: requests.Response - """ - - # If response is not 4xx, do not auth - # See https://github.com/psf/requests/issues/3772 - if not 400 <= r.status_code < 500: - self._thread_local.num_401_calls = 1 - return r - - if self._thread_local.pos is not None: - # Rewind the file position indicator of the body to where - # it was to resend the request. - r.request.body.seek(self._thread_local.pos) - s_auth = r.headers.get("www-authenticate", "") - - if "digest" in s_auth.lower() and self._thread_local.num_401_calls < 2: - - self._thread_local.num_401_calls += 1 - pat = re.compile(r"digest ", flags=re.IGNORECASE) - self._thread_local.chal = parse_dict_header(pat.sub("", s_auth, count=1)) - - # Consume content and release the original connection - # to allow our new request to reuse the same one. - r.content - r.close() - prep = r.request.copy() - extract_cookies_to_jar(prep._cookies, r.request, r.raw) - prep.prepare_cookies(prep._cookies) - - prep.headers["Authorization"] = self.build_digest_header( - prep.method, prep.url - ) - _r = r.connection.send(prep, **kwargs) - _r.history.append(r) - _r.request = prep - - return _r - - self._thread_local.num_401_calls = 1 - return r - - def __call__(self, r): - # Initialize per-thread state, if needed - self.init_per_thread_state() - # If we have a saved nonce, skip the 401 - if self._thread_local.last_nonce: - r.headers["Authorization"] = self.build_digest_header(r.method, r.url) - try: - self._thread_local.pos = r.body.tell() - except AttributeError: - # In the case of HTTPDigestAuth being reused and the body of - # the previous request was a file-like object, pos has the - # file position of the previous body. Ensure it's set to - # None. - self._thread_local.pos = None - r.register_hook("response", self.handle_401) - r.register_hook("response", self.handle_redirect) - self._thread_local.num_401_calls = 1 - - return r - - def __eq__(self, other): - return all( - [ - self.username == getattr(other, "username", None), - self.password == getattr(other, "password", None), - ] - ) - - def __ne__(self, other): - return not self == other diff --git a/Modules/requests/certs.py b/Modules/requests/certs.py deleted file mode 100644 index be422c3..0000000 --- a/Modules/requests/certs.py +++ /dev/null @@ -1,17 +0,0 @@ -#!/usr/bin/env python - -""" -requests.certs -~~~~~~~~~~~~~~ - -This module returns the preferred default CA certificate bundle. There is -only one — the one from the certifi package. - -If you are packaging Requests, e.g., for a Linux distribution or a managed -environment, you can change the definition of where() to return a separately -packaged CA bundle. -""" -from certifi import where - -if __name__ == "__main__": - print(where()) diff --git a/Modules/requests/compat.py b/Modules/requests/compat.py deleted file mode 100644 index 6776163..0000000 --- a/Modules/requests/compat.py +++ /dev/null @@ -1,79 +0,0 @@ -""" -requests.compat -~~~~~~~~~~~~~~~ - -This module previously handled import compatibility issues -between Python 2 and Python 3. It remains for backwards -compatibility until the next major version. -""" - -try: - import chardet -except ImportError: - import charset_normalizer as chardet - -import sys - -# ------- -# Pythons -# ------- - -# Syntax sugar. -_ver = sys.version_info - -#: Python 2.x? -is_py2 = _ver[0] == 2 - -#: Python 3.x? -is_py3 = _ver[0] == 3 - -# json/simplejson module import resolution -has_simplejson = False -try: - import simplejson as json - - has_simplejson = True -except ImportError: - import json - -if has_simplejson: - from simplejson import JSONDecodeError -else: - from json import JSONDecodeError - -# Keep OrderedDict for backwards compatibility. -from collections import OrderedDict -from collections.abc import Callable, Mapping, MutableMapping -from http import cookiejar as cookielib -from http.cookies import Morsel -from io import StringIO - -# -------------- -# Legacy Imports -# -------------- -from urllib.parse import ( - quote, - quote_plus, - unquote, - unquote_plus, - urldefrag, - urlencode, - urljoin, - urlparse, - urlsplit, - urlunparse, -) -from urllib.request import ( - getproxies, - getproxies_environment, - parse_http_list, - proxy_bypass, - proxy_bypass_environment, -) - -builtin_str = str -str = str -bytes = bytes -basestring = (str, bytes) -numeric_types = (int, float) -integer_types = (int,) diff --git a/Modules/requests/cookies.py b/Modules/requests/cookies.py deleted file mode 100644 index bf54ab2..0000000 --- a/Modules/requests/cookies.py +++ /dev/null @@ -1,561 +0,0 @@ -""" -requests.cookies -~~~~~~~~~~~~~~~~ - -Compatibility code to be able to use `cookielib.CookieJar` with requests. - -requests.utils imports from here, so be careful with imports. -""" - -import calendar -import copy -import time - -from ._internal_utils import to_native_string -from .compat import Morsel, MutableMapping, cookielib, urlparse, urlunparse - -try: - import threading -except ImportError: - import dummy_threading as threading - - -class MockRequest: - """Wraps a `requests.Request` to mimic a `urllib2.Request`. - - The code in `cookielib.CookieJar` expects this interface in order to correctly - manage cookie policies, i.e., determine whether a cookie can be set, given the - domains of the request and the cookie. - - The original request object is read-only. The client is responsible for collecting - the new headers via `get_new_headers()` and interpreting them appropriately. You - probably want `get_cookie_header`, defined below. - """ - - def __init__(self, request): - self._r = request - self._new_headers = {} - self.type = urlparse(self._r.url).scheme - - def get_type(self): - return self.type - - def get_host(self): - return urlparse(self._r.url).netloc - - def get_origin_req_host(self): - return self.get_host() - - def get_full_url(self): - # Only return the response's URL if the user hadn't set the Host - # header - if not self._r.headers.get("Host"): - return self._r.url - # If they did set it, retrieve it and reconstruct the expected domain - host = to_native_string(self._r.headers["Host"], encoding="utf-8") - parsed = urlparse(self._r.url) - # Reconstruct the URL as we expect it - return urlunparse( - [ - parsed.scheme, - host, - parsed.path, - parsed.params, - parsed.query, - parsed.fragment, - ] - ) - - def is_unverifiable(self): - return True - - def has_header(self, name): - return name in self._r.headers or name in self._new_headers - - def get_header(self, name, default=None): - return self._r.headers.get(name, self._new_headers.get(name, default)) - - def add_header(self, key, val): - """cookielib has no legitimate use for this method; add it back if you find one.""" - raise NotImplementedError( - "Cookie headers should be added with add_unredirected_header()" - ) - - def add_unredirected_header(self, name, value): - self._new_headers[name] = value - - def get_new_headers(self): - return self._new_headers - - @property - def unverifiable(self): - return self.is_unverifiable() - - @property - def origin_req_host(self): - return self.get_origin_req_host() - - @property - def host(self): - return self.get_host() - - -class MockResponse: - """Wraps a `httplib.HTTPMessage` to mimic a `urllib.addinfourl`. - - ...what? Basically, expose the parsed HTTP headers from the server response - the way `cookielib` expects to see them. - """ - - def __init__(self, headers): - """Make a MockResponse for `cookielib` to read. - - :param headers: a httplib.HTTPMessage or analogous carrying the headers - """ - self._headers = headers - - def info(self): - return self._headers - - def getheaders(self, name): - self._headers.getheaders(name) - - -def extract_cookies_to_jar(jar, request, response): - """Extract the cookies from the response into a CookieJar. - - :param jar: cookielib.CookieJar (not necessarily a RequestsCookieJar) - :param request: our own requests.Request object - :param response: urllib3.HTTPResponse object - """ - if not (hasattr(response, "_original_response") and response._original_response): - return - # the _original_response field is the wrapped httplib.HTTPResponse object, - req = MockRequest(request) - # pull out the HTTPMessage with the headers and put it in the mock: - res = MockResponse(response._original_response.msg) - jar.extract_cookies(res, req) - - -def get_cookie_header(jar, request): - """ - Produce an appropriate Cookie header string to be sent with `request`, or None. - - :rtype: str - """ - r = MockRequest(request) - jar.add_cookie_header(r) - return r.get_new_headers().get("Cookie") - - -def remove_cookie_by_name(cookiejar, name, domain=None, path=None): - """Unsets a cookie by name, by default over all domains and paths. - - Wraps CookieJar.clear(), is O(n). - """ - clearables = [] - for cookie in cookiejar: - if cookie.name != name: - continue - if domain is not None and domain != cookie.domain: - continue - if path is not None and path != cookie.path: - continue - clearables.append((cookie.domain, cookie.path, cookie.name)) - - for domain, path, name in clearables: - cookiejar.clear(domain, path, name) - - -class CookieConflictError(RuntimeError): - """There are two cookies that meet the criteria specified in the cookie jar. - Use .get and .set and include domain and path args in order to be more specific. - """ - - -class RequestsCookieJar(cookielib.CookieJar, MutableMapping): - """Compatibility class; is a cookielib.CookieJar, but exposes a dict - interface. - - This is the CookieJar we create by default for requests and sessions that - don't specify one, since some clients may expect response.cookies and - session.cookies to support dict operations. - - Requests does not use the dict interface internally; it's just for - compatibility with external client code. All requests code should work - out of the box with externally provided instances of ``CookieJar``, e.g. - ``LWPCookieJar`` and ``FileCookieJar``. - - Unlike a regular CookieJar, this class is pickleable. - - .. warning:: dictionary operations that are normally O(1) may be O(n). - """ - - def get(self, name, default=None, domain=None, path=None): - """Dict-like get() that also supports optional domain and path args in - order to resolve naming collisions from using one cookie jar over - multiple domains. - - .. warning:: operation is O(n), not O(1). - """ - try: - return self._find_no_duplicates(name, domain, path) - except KeyError: - return default - - def set(self, name, value, **kwargs): - """Dict-like set() that also supports optional domain and path args in - order to resolve naming collisions from using one cookie jar over - multiple domains. - """ - # support client code that unsets cookies by assignment of a None value: - if value is None: - remove_cookie_by_name( - self, name, domain=kwargs.get("domain"), path=kwargs.get("path") - ) - return - - if isinstance(value, Morsel): - c = morsel_to_cookie(value) - else: - c = create_cookie(name, value, **kwargs) - self.set_cookie(c) - return c - - def iterkeys(self): - """Dict-like iterkeys() that returns an iterator of names of cookies - from the jar. - - .. seealso:: itervalues() and iteritems(). - """ - for cookie in iter(self): - yield cookie.name - - def keys(self): - """Dict-like keys() that returns a list of names of cookies from the - jar. - - .. seealso:: values() and items(). - """ - return list(self.iterkeys()) - - def itervalues(self): - """Dict-like itervalues() that returns an iterator of values of cookies - from the jar. - - .. seealso:: iterkeys() and iteritems(). - """ - for cookie in iter(self): - yield cookie.value - - def values(self): - """Dict-like values() that returns a list of values of cookies from the - jar. - - .. seealso:: keys() and items(). - """ - return list(self.itervalues()) - - def iteritems(self): - """Dict-like iteritems() that returns an iterator of name-value tuples - from the jar. - - .. seealso:: iterkeys() and itervalues(). - """ - for cookie in iter(self): - yield cookie.name, cookie.value - - def items(self): - """Dict-like items() that returns a list of name-value tuples from the - jar. Allows client-code to call ``dict(RequestsCookieJar)`` and get a - vanilla python dict of key value pairs. - - .. seealso:: keys() and values(). - """ - return list(self.iteritems()) - - def list_domains(self): - """Utility method to list all the domains in the jar.""" - domains = [] - for cookie in iter(self): - if cookie.domain not in domains: - domains.append(cookie.domain) - return domains - - def list_paths(self): - """Utility method to list all the paths in the jar.""" - paths = [] - for cookie in iter(self): - if cookie.path not in paths: - paths.append(cookie.path) - return paths - - def multiple_domains(self): - """Returns True if there are multiple domains in the jar. - Returns False otherwise. - - :rtype: bool - """ - domains = [] - for cookie in iter(self): - if cookie.domain is not None and cookie.domain in domains: - return True - domains.append(cookie.domain) - return False # there is only one domain in jar - - def get_dict(self, domain=None, path=None): - """Takes as an argument an optional domain and path and returns a plain - old Python dict of name-value pairs of cookies that meet the - requirements. - - :rtype: dict - """ - dictionary = {} - for cookie in iter(self): - if (domain is None or cookie.domain == domain) and ( - path is None or cookie.path == path - ): - dictionary[cookie.name] = cookie.value - return dictionary - - def __contains__(self, name): - try: - return super().__contains__(name) - except CookieConflictError: - return True - - def __getitem__(self, name): - """Dict-like __getitem__() for compatibility with client code. Throws - exception if there are more than one cookie with name. In that case, - use the more explicit get() method instead. - - .. warning:: operation is O(n), not O(1). - """ - return self._find_no_duplicates(name) - - def __setitem__(self, name, value): - """Dict-like __setitem__ for compatibility with client code. Throws - exception if there is already a cookie of that name in the jar. In that - case, use the more explicit set() method instead. - """ - self.set(name, value) - - def __delitem__(self, name): - """Deletes a cookie given a name. Wraps ``cookielib.CookieJar``'s - ``remove_cookie_by_name()``. - """ - remove_cookie_by_name(self, name) - - def set_cookie(self, cookie, *args, **kwargs): - if ( - hasattr(cookie.value, "startswith") - and cookie.value.startswith('"') - and cookie.value.endswith('"') - ): - cookie.value = cookie.value.replace('\\"', "") - return super().set_cookie(cookie, *args, **kwargs) - - def update(self, other): - """Updates this jar with cookies from another CookieJar or dict-like""" - if isinstance(other, cookielib.CookieJar): - for cookie in other: - self.set_cookie(copy.copy(cookie)) - else: - super().update(other) - - def _find(self, name, domain=None, path=None): - """Requests uses this method internally to get cookie values. - - If there are conflicting cookies, _find arbitrarily chooses one. - See _find_no_duplicates if you want an exception thrown if there are - conflicting cookies. - - :param name: a string containing name of cookie - :param domain: (optional) string containing domain of cookie - :param path: (optional) string containing path of cookie - :return: cookie.value - """ - for cookie in iter(self): - if cookie.name == name: - if domain is None or cookie.domain == domain: - if path is None or cookie.path == path: - return cookie.value - - raise KeyError(f"name={name!r}, domain={domain!r}, path={path!r}") - - def _find_no_duplicates(self, name, domain=None, path=None): - """Both ``__get_item__`` and ``get`` call this function: it's never - used elsewhere in Requests. - - :param name: a string containing name of cookie - :param domain: (optional) string containing domain of cookie - :param path: (optional) string containing path of cookie - :raises KeyError: if cookie is not found - :raises CookieConflictError: if there are multiple cookies - that match name and optionally domain and path - :return: cookie.value - """ - toReturn = None - for cookie in iter(self): - if cookie.name == name: - if domain is None or cookie.domain == domain: - if path is None or cookie.path == path: - if toReturn is not None: - # if there are multiple cookies that meet passed in criteria - raise CookieConflictError( - f"There are multiple cookies with name, {name!r}" - ) - # we will eventually return this as long as no cookie conflict - toReturn = cookie.value - - if toReturn: - return toReturn - raise KeyError(f"name={name!r}, domain={domain!r}, path={path!r}") - - def __getstate__(self): - """Unlike a normal CookieJar, this class is pickleable.""" - state = self.__dict__.copy() - # remove the unpickleable RLock object - state.pop("_cookies_lock") - return state - - def __setstate__(self, state): - """Unlike a normal CookieJar, this class is pickleable.""" - self.__dict__.update(state) - if "_cookies_lock" not in self.__dict__: - self._cookies_lock = threading.RLock() - - def copy(self): - """Return a copy of this RequestsCookieJar.""" - new_cj = RequestsCookieJar() - new_cj.set_policy(self.get_policy()) - new_cj.update(self) - return new_cj - - def get_policy(self): - """Return the CookiePolicy instance used.""" - return self._policy - - -def _copy_cookie_jar(jar): - if jar is None: - return None - - if hasattr(jar, "copy"): - # We're dealing with an instance of RequestsCookieJar - return jar.copy() - # We're dealing with a generic CookieJar instance - new_jar = copy.copy(jar) - new_jar.clear() - for cookie in jar: - new_jar.set_cookie(copy.copy(cookie)) - return new_jar - - -def create_cookie(name, value, **kwargs): - """Make a cookie from underspecified parameters. - - By default, the pair of `name` and `value` will be set for the domain '' - and sent on every request (this is sometimes called a "supercookie"). - """ - result = { - "version": 0, - "name": name, - "value": value, - "port": None, - "domain": "", - "path": "/", - "secure": False, - "expires": None, - "discard": True, - "comment": None, - "comment_url": None, - "rest": {"HttpOnly": None}, - "rfc2109": False, - } - - badargs = set(kwargs) - set(result) - if badargs: - raise TypeError( - f"create_cookie() got unexpected keyword arguments: {list(badargs)}" - ) - - result.update(kwargs) - result["port_specified"] = bool(result["port"]) - result["domain_specified"] = bool(result["domain"]) - result["domain_initial_dot"] = result["domain"].startswith(".") - result["path_specified"] = bool(result["path"]) - - return cookielib.Cookie(**result) - - -def morsel_to_cookie(morsel): - """Convert a Morsel object into a Cookie containing the one k/v pair.""" - - expires = None - if morsel["max-age"]: - try: - expires = int(time.time() + int(morsel["max-age"])) - except ValueError: - raise TypeError(f"max-age: {morsel['max-age']} must be integer") - elif morsel["expires"]: - time_template = "%a, %d-%b-%Y %H:%M:%S GMT" - expires = calendar.timegm(time.strptime(morsel["expires"], time_template)) - return create_cookie( - comment=morsel["comment"], - comment_url=bool(morsel["comment"]), - discard=False, - domain=morsel["domain"], - expires=expires, - name=morsel.key, - path=morsel["path"], - port=None, - rest={"HttpOnly": morsel["httponly"]}, - rfc2109=False, - secure=bool(morsel["secure"]), - value=morsel.value, - version=morsel["version"] or 0, - ) - - -def cookiejar_from_dict(cookie_dict, cookiejar=None, overwrite=True): - """Returns a CookieJar from a key/value dictionary. - - :param cookie_dict: Dict of key/values to insert into CookieJar. - :param cookiejar: (optional) A cookiejar to add the cookies to. - :param overwrite: (optional) If False, will not replace cookies - already in the jar with new ones. - :rtype: CookieJar - """ - if cookiejar is None: - cookiejar = RequestsCookieJar() - - if cookie_dict is not None: - names_from_jar = [cookie.name for cookie in cookiejar] - for name in cookie_dict: - if overwrite or (name not in names_from_jar): - cookiejar.set_cookie(create_cookie(name, cookie_dict[name])) - - return cookiejar - - -def merge_cookies(cookiejar, cookies): - """Add cookies to cookiejar and returns a merged CookieJar. - - :param cookiejar: CookieJar object to add the cookies to. - :param cookies: Dictionary or CookieJar object to be added. - :rtype: CookieJar - """ - if not isinstance(cookiejar, cookielib.CookieJar): - raise ValueError("You can only merge into CookieJar") - - if isinstance(cookies, dict): - cookiejar = cookiejar_from_dict(cookies, cookiejar=cookiejar, overwrite=False) - elif isinstance(cookies, cookielib.CookieJar): - try: - cookiejar.update(cookies) - except AttributeError: - for cookie_in_jar in cookies: - cookiejar.set_cookie(cookie_in_jar) - - return cookiejar diff --git a/Modules/requests/exceptions.py b/Modules/requests/exceptions.py deleted file mode 100644 index e1cedf8..0000000 --- a/Modules/requests/exceptions.py +++ /dev/null @@ -1,141 +0,0 @@ -""" -requests.exceptions -~~~~~~~~~~~~~~~~~~~ - -This module contains the set of Requests' exceptions. -""" -from urllib3.exceptions import HTTPError as BaseHTTPError - -from .compat import JSONDecodeError as CompatJSONDecodeError - - -class RequestException(IOError): - """There was an ambiguous exception that occurred while handling your - request. - """ - - def __init__(self, *args, **kwargs): - """Initialize RequestException with `request` and `response` objects.""" - response = kwargs.pop("response", None) - self.response = response - self.request = kwargs.pop("request", None) - if response is not None and not self.request and hasattr(response, "request"): - self.request = self.response.request - super().__init__(*args, **kwargs) - - -class InvalidJSONError(RequestException): - """A JSON error occurred.""" - - -class JSONDecodeError(InvalidJSONError, CompatJSONDecodeError): - """Couldn't decode the text into json""" - - def __init__(self, *args, **kwargs): - """ - Construct the JSONDecodeError instance first with all - args. Then use it's args to construct the IOError so that - the json specific args aren't used as IOError specific args - and the error message from JSONDecodeError is preserved. - """ - CompatJSONDecodeError.__init__(self, *args) - InvalidJSONError.__init__(self, *self.args, **kwargs) - - -class HTTPError(RequestException): - """An HTTP error occurred.""" - - -class ConnectionError(RequestException): - """A Connection error occurred.""" - - -class ProxyError(ConnectionError): - """A proxy error occurred.""" - - -class SSLError(ConnectionError): - """An SSL error occurred.""" - - -class Timeout(RequestException): - """The request timed out. - - Catching this error will catch both - :exc:`~requests.exceptions.ConnectTimeout` and - :exc:`~requests.exceptions.ReadTimeout` errors. - """ - - -class ConnectTimeout(ConnectionError, Timeout): - """The request timed out while trying to connect to the remote server. - - Requests that produced this error are safe to retry. - """ - - -class ReadTimeout(Timeout): - """The server did not send any data in the allotted amount of time.""" - - -class URLRequired(RequestException): - """A valid URL is required to make a request.""" - - -class TooManyRedirects(RequestException): - """Too many redirects.""" - - -class MissingSchema(RequestException, ValueError): - """The URL scheme (e.g. http or https) is missing.""" - - -class InvalidSchema(RequestException, ValueError): - """The URL scheme provided is either invalid or unsupported.""" - - -class InvalidURL(RequestException, ValueError): - """The URL provided was somehow invalid.""" - - -class InvalidHeader(RequestException, ValueError): - """The header value provided was somehow invalid.""" - - -class InvalidProxyURL(InvalidURL): - """The proxy URL provided is invalid.""" - - -class ChunkedEncodingError(RequestException): - """The server declared chunked encoding but sent an invalid chunk.""" - - -class ContentDecodingError(RequestException, BaseHTTPError): - """Failed to decode response content.""" - - -class StreamConsumedError(RequestException, TypeError): - """The content for this response was already consumed.""" - - -class RetryError(RequestException): - """Custom retries logic failed""" - - -class UnrewindableBodyError(RequestException): - """Requests encountered an error when trying to rewind a body.""" - - -# Warnings - - -class RequestsWarning(Warning): - """Base warning for Requests.""" - - -class FileModeWarning(RequestsWarning, DeprecationWarning): - """A file was opened in text mode, but Requests determined its binary length.""" - - -class RequestsDependencyWarning(RequestsWarning): - """An imported dependency doesn't match the expected version range.""" diff --git a/Modules/requests/help.py b/Modules/requests/help.py deleted file mode 100644 index 8fbcd65..0000000 --- a/Modules/requests/help.py +++ /dev/null @@ -1,134 +0,0 @@ -"""Module containing bug report helper(s).""" - -import json -import platform -import ssl -import sys - -import idna -import urllib3 - -from . import __version__ as requests_version - -try: - import charset_normalizer -except ImportError: - charset_normalizer = None - -try: - import chardet -except ImportError: - chardet = None - -try: - from urllib3.contrib import pyopenssl -except ImportError: - pyopenssl = None - OpenSSL = None - cryptography = None -else: - import cryptography - import OpenSSL - - -def _implementation(): - """Return a dict with the Python implementation and version. - - Provide both the name and the version of the Python implementation - currently running. For example, on CPython 3.10.3 it will return - {'name': 'CPython', 'version': '3.10.3'}. - - This function works best on CPython and PyPy: in particular, it probably - doesn't work for Jython or IronPython. Future investigation should be done - to work out the correct shape of the code for those platforms. - """ - implementation = platform.python_implementation() - - if implementation == "CPython": - implementation_version = platform.python_version() - elif implementation == "PyPy": - implementation_version = "{}.{}.{}".format( - sys.pypy_version_info.major, - sys.pypy_version_info.minor, - sys.pypy_version_info.micro, - ) - if sys.pypy_version_info.releaselevel != "final": - implementation_version = "".join( - [implementation_version, sys.pypy_version_info.releaselevel] - ) - elif implementation == "Jython": - implementation_version = platform.python_version() # Complete Guess - elif implementation == "IronPython": - implementation_version = platform.python_version() # Complete Guess - else: - implementation_version = "Unknown" - - return {"name": implementation, "version": implementation_version} - - -def info(): - """Generate information for a bug report.""" - try: - platform_info = { - "system": platform.system(), - "release": platform.release(), - } - except OSError: - platform_info = { - "system": "Unknown", - "release": "Unknown", - } - - implementation_info = _implementation() - urllib3_info = {"version": urllib3.__version__} - charset_normalizer_info = {"version": None} - chardet_info = {"version": None} - if charset_normalizer: - charset_normalizer_info = {"version": charset_normalizer.__version__} - if chardet: - chardet_info = {"version": chardet.__version__} - - pyopenssl_info = { - "version": None, - "openssl_version": "", - } - if OpenSSL: - pyopenssl_info = { - "version": OpenSSL.__version__, - "openssl_version": f"{OpenSSL.SSL.OPENSSL_VERSION_NUMBER:x}", - } - cryptography_info = { - "version": getattr(cryptography, "__version__", ""), - } - idna_info = { - "version": getattr(idna, "__version__", ""), - } - - system_ssl = ssl.OPENSSL_VERSION_NUMBER - system_ssl_info = {"version": f"{system_ssl:x}" if system_ssl is not None else ""} - - return { - "platform": platform_info, - "implementation": implementation_info, - "system_ssl": system_ssl_info, - "using_pyopenssl": pyopenssl is not None, - "using_charset_normalizer": chardet is None, - "pyOpenSSL": pyopenssl_info, - "urllib3": urllib3_info, - "chardet": chardet_info, - "charset_normalizer": charset_normalizer_info, - "cryptography": cryptography_info, - "idna": idna_info, - "requests": { - "version": requests_version, - }, - } - - -def main(): - """Pretty-print the bug information as JSON.""" - print(json.dumps(info(), sort_keys=True, indent=2)) - - -if __name__ == "__main__": - main() diff --git a/Modules/requests/hooks.py b/Modules/requests/hooks.py deleted file mode 100644 index d181ba2..0000000 --- a/Modules/requests/hooks.py +++ /dev/null @@ -1,33 +0,0 @@ -""" -requests.hooks -~~~~~~~~~~~~~~ - -This module provides the capabilities for the Requests hooks system. - -Available hooks: - -``response``: - The response generated from a Request. -""" -HOOKS = ["response"] - - -def default_hooks(): - return {event: [] for event in HOOKS} - - -# TODO: response is the only one - - -def dispatch_hook(key, hooks, hook_data, **kwargs): - """Dispatches a hook dictionary on a given piece of data.""" - hooks = hooks or {} - hooks = hooks.get(key) - if hooks: - if hasattr(hooks, "__call__"): - hooks = [hooks] - for hook in hooks: - _hook_data = hook(hook_data, **kwargs) - if _hook_data is not None: - hook_data = _hook_data - return hook_data diff --git a/Modules/requests/models.py b/Modules/requests/models.py deleted file mode 100644 index 617a413..0000000 --- a/Modules/requests/models.py +++ /dev/null @@ -1,1034 +0,0 @@ -""" -requests.models -~~~~~~~~~~~~~~~ - -This module contains the primary objects that power Requests. -""" - -import datetime - -# Import encoding now, to avoid implicit import later. -# Implicit import within threads may cause LookupError when standard library is in a ZIP, -# such as in Embedded Python. See https://github.com/psf/requests/issues/3578. -import encodings.idna # noqa: F401 -from io import UnsupportedOperation - -from urllib3.exceptions import ( - DecodeError, - LocationParseError, - ProtocolError, - ReadTimeoutError, - SSLError, -) -from urllib3.fields import RequestField -from urllib3.filepost import encode_multipart_formdata -from urllib3.util import parse_url - -from ._internal_utils import to_native_string, unicode_is_ascii -from .auth import HTTPBasicAuth -from .compat import ( - Callable, - JSONDecodeError, - Mapping, - basestring, - builtin_str, - chardet, - cookielib, -) -from .compat import json as complexjson -from .compat import urlencode, urlsplit, urlunparse -from .cookies import _copy_cookie_jar, cookiejar_from_dict, get_cookie_header -from .exceptions import ( - ChunkedEncodingError, - ConnectionError, - ContentDecodingError, - HTTPError, - InvalidJSONError, - InvalidURL, -) -from .exceptions import JSONDecodeError as RequestsJSONDecodeError -from .exceptions import MissingSchema -from .exceptions import SSLError as RequestsSSLError -from .exceptions import StreamConsumedError -from .hooks import default_hooks -from .status_codes import codes -from .structures import CaseInsensitiveDict -from .utils import ( - check_header_validity, - get_auth_from_url, - guess_filename, - guess_json_utf, - iter_slices, - parse_header_links, - requote_uri, - stream_decode_response_unicode, - super_len, - to_key_val_list, -) - -#: The set of HTTP status codes that indicate an automatically -#: processable redirect. -REDIRECT_STATI = ( - codes.moved, # 301 - codes.found, # 302 - codes.other, # 303 - codes.temporary_redirect, # 307 - codes.permanent_redirect, # 308 -) - -DEFAULT_REDIRECT_LIMIT = 30 -CONTENT_CHUNK_SIZE = 10 * 1024 -ITER_CHUNK_SIZE = 512 - - -class RequestEncodingMixin: - @property - def path_url(self): - """Build the path URL to use.""" - - url = [] - - p = urlsplit(self.url) - - path = p.path - if not path: - path = "/" - - url.append(path) - - query = p.query - if query: - url.append("?") - url.append(query) - - return "".join(url) - - @staticmethod - def _encode_params(data): - """Encode parameters in a piece of data. - - Will successfully encode parameters when passed as a dict or a list of - 2-tuples. Order is retained if data is a list of 2-tuples but arbitrary - if parameters are supplied as a dict. - """ - - if isinstance(data, (str, bytes)): - return data - elif hasattr(data, "read"): - return data - elif hasattr(data, "__iter__"): - result = [] - for k, vs in to_key_val_list(data): - if isinstance(vs, basestring) or not hasattr(vs, "__iter__"): - vs = [vs] - for v in vs: - if v is not None: - result.append( - ( - k.encode("utf-8") if isinstance(k, str) else k, - v.encode("utf-8") if isinstance(v, str) else v, - ) - ) - return urlencode(result, doseq=True) - else: - return data - - @staticmethod - def _encode_files(files, data): - """Build the body for a multipart/form-data request. - - Will successfully encode files when passed as a dict or a list of - tuples. Order is retained if data is a list of tuples but arbitrary - if parameters are supplied as a dict. - The tuples may be 2-tuples (filename, fileobj), 3-tuples (filename, fileobj, contentype) - or 4-tuples (filename, fileobj, contentype, custom_headers). - """ - if not files: - raise ValueError("Files must be provided.") - elif isinstance(data, basestring): - raise ValueError("Data must not be a string.") - - new_fields = [] - fields = to_key_val_list(data or {}) - files = to_key_val_list(files or {}) - - for field, val in fields: - if isinstance(val, basestring) or not hasattr(val, "__iter__"): - val = [val] - for v in val: - if v is not None: - # Don't call str() on bytestrings: in Py3 it all goes wrong. - if not isinstance(v, bytes): - v = str(v) - - new_fields.append( - ( - field.decode("utf-8") - if isinstance(field, bytes) - else field, - v.encode("utf-8") if isinstance(v, str) else v, - ) - ) - - for (k, v) in files: - # support for explicit filename - ft = None - fh = None - if isinstance(v, (tuple, list)): - if len(v) == 2: - fn, fp = v - elif len(v) == 3: - fn, fp, ft = v - else: - fn, fp, ft, fh = v - else: - fn = guess_filename(v) or k - fp = v - - if isinstance(fp, (str, bytes, bytearray)): - fdata = fp - elif hasattr(fp, "read"): - fdata = fp.read() - elif fp is None: - continue - else: - fdata = fp - - rf = RequestField(name=k, data=fdata, filename=fn, headers=fh) - rf.make_multipart(content_type=ft) - new_fields.append(rf) - - body, content_type = encode_multipart_formdata(new_fields) - - return body, content_type - - -class RequestHooksMixin: - def register_hook(self, event, hook): - """Properly register a hook.""" - - if event not in self.hooks: - raise ValueError(f'Unsupported event specified, with event name "{event}"') - - if isinstance(hook, Callable): - self.hooks[event].append(hook) - elif hasattr(hook, "__iter__"): - self.hooks[event].extend(h for h in hook if isinstance(h, Callable)) - - def deregister_hook(self, event, hook): - """Deregister a previously registered hook. - Returns True if the hook existed, False if not. - """ - - try: - self.hooks[event].remove(hook) - return True - except ValueError: - return False - - -class Request(RequestHooksMixin): - """A user-created :class:`Request ` object. - - Used to prepare a :class:`PreparedRequest `, which is sent to the server. - - :param method: HTTP method to use. - :param url: URL to send. - :param headers: dictionary of headers to send. - :param files: dictionary of {filename: fileobject} files to multipart upload. - :param data: the body to attach to the request. If a dictionary or - list of tuples ``[(key, value)]`` is provided, form-encoding will - take place. - :param json: json for the body to attach to the request (if files or data is not specified). - :param params: URL parameters to append to the URL. If a dictionary or - list of tuples ``[(key, value)]`` is provided, form-encoding will - take place. - :param auth: Auth handler or (user, pass) tuple. - :param cookies: dictionary or CookieJar of cookies to attach to this request. - :param hooks: dictionary of callback hooks, for internal usage. - - Usage:: - - >>> import requests - >>> req = requests.Request('GET', 'https://httpbin.org/get') - >>> req.prepare() - - """ - - def __init__( - self, - method=None, - url=None, - headers=None, - files=None, - data=None, - params=None, - auth=None, - cookies=None, - hooks=None, - json=None, - ): - - # Default empty dicts for dict params. - data = [] if data is None else data - files = [] if files is None else files - headers = {} if headers is None else headers - params = {} if params is None else params - hooks = {} if hooks is None else hooks - - self.hooks = default_hooks() - for (k, v) in list(hooks.items()): - self.register_hook(event=k, hook=v) - - self.method = method - self.url = url - self.headers = headers - self.files = files - self.data = data - self.json = json - self.params = params - self.auth = auth - self.cookies = cookies - - def __repr__(self): - return f"" - - def prepare(self): - """Constructs a :class:`PreparedRequest ` for transmission and returns it.""" - p = PreparedRequest() - p.prepare( - method=self.method, - url=self.url, - headers=self.headers, - files=self.files, - data=self.data, - json=self.json, - params=self.params, - auth=self.auth, - cookies=self.cookies, - hooks=self.hooks, - ) - return p - - -class PreparedRequest(RequestEncodingMixin, RequestHooksMixin): - """The fully mutable :class:`PreparedRequest ` object, - containing the exact bytes that will be sent to the server. - - Instances are generated from a :class:`Request ` object, and - should not be instantiated manually; doing so may produce undesirable - effects. - - Usage:: - - >>> import requests - >>> req = requests.Request('GET', 'https://httpbin.org/get') - >>> r = req.prepare() - >>> r - - - >>> s = requests.Session() - >>> s.send(r) - - """ - - def __init__(self): - #: HTTP verb to send to the server. - self.method = None - #: HTTP URL to send the request to. - self.url = None - #: dictionary of HTTP headers. - self.headers = None - # The `CookieJar` used to create the Cookie header will be stored here - # after prepare_cookies is called - self._cookies = None - #: request body to send to the server. - self.body = None - #: dictionary of callback hooks, for internal usage. - self.hooks = default_hooks() - #: integer denoting starting position of a readable file-like body. - self._body_position = None - - def prepare( - self, - method=None, - url=None, - headers=None, - files=None, - data=None, - params=None, - auth=None, - cookies=None, - hooks=None, - json=None, - ): - """Prepares the entire request with the given parameters.""" - - self.prepare_method(method) - self.prepare_url(url, params) - self.prepare_headers(headers) - self.prepare_cookies(cookies) - self.prepare_body(data, files, json) - self.prepare_auth(auth, url) - - # Note that prepare_auth must be last to enable authentication schemes - # such as OAuth to work on a fully prepared request. - - # This MUST go after prepare_auth. Authenticators could add a hook - self.prepare_hooks(hooks) - - def __repr__(self): - return f"" - - def copy(self): - p = PreparedRequest() - p.method = self.method - p.url = self.url - p.headers = self.headers.copy() if self.headers is not None else None - p._cookies = _copy_cookie_jar(self._cookies) - p.body = self.body - p.hooks = self.hooks - p._body_position = self._body_position - return p - - def prepare_method(self, method): - """Prepares the given HTTP method.""" - self.method = method - if self.method is not None: - self.method = to_native_string(self.method.upper()) - - @staticmethod - def _get_idna_encoded_host(host): - import idna - - try: - host = idna.encode(host, uts46=True).decode("utf-8") - except idna.IDNAError: - raise UnicodeError - return host - - def prepare_url(self, url, params): - """Prepares the given HTTP URL.""" - #: Accept objects that have string representations. - #: We're unable to blindly call unicode/str functions - #: as this will include the bytestring indicator (b'') - #: on python 3.x. - #: https://github.com/psf/requests/pull/2238 - if isinstance(url, bytes): - url = url.decode("utf8") - else: - url = str(url) - - # Remove leading whitespaces from url - url = url.lstrip() - - # Don't do any URL preparation for non-HTTP schemes like `mailto`, - # `data` etc to work around exceptions from `url_parse`, which - # handles RFC 3986 only. - if ":" in url and not url.lower().startswith("http"): - self.url = url - return - - # Support for unicode domain names and paths. - try: - scheme, auth, host, port, path, query, fragment = parse_url(url) - except LocationParseError as e: - raise InvalidURL(*e.args) - - if not scheme: - raise MissingSchema( - f"Invalid URL {url!r}: No scheme supplied. " - f"Perhaps you meant https://{url}?" - ) - - if not host: - raise InvalidURL(f"Invalid URL {url!r}: No host supplied") - - # In general, we want to try IDNA encoding the hostname if the string contains - # non-ASCII characters. This allows users to automatically get the correct IDNA - # behaviour. For strings containing only ASCII characters, we need to also verify - # it doesn't start with a wildcard (*), before allowing the unencoded hostname. - if not unicode_is_ascii(host): - try: - host = self._get_idna_encoded_host(host) - except UnicodeError: - raise InvalidURL("URL has an invalid label.") - elif host.startswith(("*", ".")): - raise InvalidURL("URL has an invalid label.") - - # Carefully reconstruct the network location - netloc = auth or "" - if netloc: - netloc += "@" - netloc += host - if port: - netloc += f":{port}" - - # Bare domains aren't valid URLs. - if not path: - path = "/" - - if isinstance(params, (str, bytes)): - params = to_native_string(params) - - enc_params = self._encode_params(params) - if enc_params: - if query: - query = f"{query}&{enc_params}" - else: - query = enc_params - - url = requote_uri(urlunparse([scheme, netloc, path, None, query, fragment])) - self.url = url - - def prepare_headers(self, headers): - """Prepares the given HTTP headers.""" - - self.headers = CaseInsensitiveDict() - if headers: - for header in headers.items(): - # Raise exception on invalid header value. - check_header_validity(header) - name, value = header - self.headers[to_native_string(name)] = value - - def prepare_body(self, data, files, json=None): - """Prepares the given HTTP body data.""" - - # Check if file, fo, generator, iterator. - # If not, run through normal process. - - # Nottin' on you. - body = None - content_type = None - - if not data and json is not None: - # urllib3 requires a bytes-like body. Python 2's json.dumps - # provides this natively, but Python 3 gives a Unicode string. - content_type = "application/json" - - try: - body = complexjson.dumps(json, allow_nan=False) - except ValueError as ve: - raise InvalidJSONError(ve, request=self) - - if not isinstance(body, bytes): - body = body.encode("utf-8") - - is_stream = all( - [ - hasattr(data, "__iter__"), - not isinstance(data, (basestring, list, tuple, Mapping)), - ] - ) - - if is_stream: - try: - length = super_len(data) - except (TypeError, AttributeError, UnsupportedOperation): - length = None - - body = data - - if getattr(body, "tell", None) is not None: - # Record the current file position before reading. - # This will allow us to rewind a file in the event - # of a redirect. - try: - self._body_position = body.tell() - except OSError: - # This differentiates from None, allowing us to catch - # a failed `tell()` later when trying to rewind the body - self._body_position = object() - - if files: - raise NotImplementedError( - "Streamed bodies and files are mutually exclusive." - ) - - if length: - self.headers["Content-Length"] = builtin_str(length) - else: - self.headers["Transfer-Encoding"] = "chunked" - else: - # Multi-part file uploads. - if files: - (body, content_type) = self._encode_files(files, data) - else: - if data: - body = self._encode_params(data) - if isinstance(data, basestring) or hasattr(data, "read"): - content_type = None - else: - content_type = "application/x-www-form-urlencoded" - - self.prepare_content_length(body) - - # Add content-type if it wasn't explicitly provided. - if content_type and ("content-type" not in self.headers): - self.headers["Content-Type"] = content_type - - self.body = body - - def prepare_content_length(self, body): - """Prepare Content-Length header based on request method and body""" - if body is not None: - length = super_len(body) - if length: - # If length exists, set it. Otherwise, we fallback - # to Transfer-Encoding: chunked. - self.headers["Content-Length"] = builtin_str(length) - elif ( - self.method not in ("GET", "HEAD") - and self.headers.get("Content-Length") is None - ): - # Set Content-Length to 0 for methods that can have a body - # but don't provide one. (i.e. not GET or HEAD) - self.headers["Content-Length"] = "0" - - def prepare_auth(self, auth, url=""): - """Prepares the given HTTP auth data.""" - - # If no Auth is explicitly provided, extract it from the URL first. - if auth is None: - url_auth = get_auth_from_url(self.url) - auth = url_auth if any(url_auth) else None - - if auth: - if isinstance(auth, tuple) and len(auth) == 2: - # special-case basic HTTP auth - auth = HTTPBasicAuth(*auth) - - # Allow auth to make its changes. - r = auth(self) - - # Update self to reflect the auth changes. - self.__dict__.update(r.__dict__) - - # Recompute Content-Length - self.prepare_content_length(self.body) - - def prepare_cookies(self, cookies): - """Prepares the given HTTP cookie data. - - This function eventually generates a ``Cookie`` header from the - given cookies using cookielib. Due to cookielib's design, the header - will not be regenerated if it already exists, meaning this function - can only be called once for the life of the - :class:`PreparedRequest ` object. Any subsequent calls - to ``prepare_cookies`` will have no actual effect, unless the "Cookie" - header is removed beforehand. - """ - if isinstance(cookies, cookielib.CookieJar): - self._cookies = cookies - else: - self._cookies = cookiejar_from_dict(cookies) - - cookie_header = get_cookie_header(self._cookies, self) - if cookie_header is not None: - self.headers["Cookie"] = cookie_header - - def prepare_hooks(self, hooks): - """Prepares the given hooks.""" - # hooks can be passed as None to the prepare method and to this - # method. To prevent iterating over None, simply use an empty list - # if hooks is False-y - hooks = hooks or [] - for event in hooks: - self.register_hook(event, hooks[event]) - - -class Response: - """The :class:`Response ` object, which contains a - server's response to an HTTP request. - """ - - __attrs__ = [ - "_content", - "status_code", - "headers", - "url", - "history", - "encoding", - "reason", - "cookies", - "elapsed", - "request", - ] - - def __init__(self): - self._content = False - self._content_consumed = False - self._next = None - - #: Integer Code of responded HTTP Status, e.g. 404 or 200. - self.status_code = None - - #: Case-insensitive Dictionary of Response Headers. - #: For example, ``headers['content-encoding']`` will return the - #: value of a ``'Content-Encoding'`` response header. - self.headers = CaseInsensitiveDict() - - #: File-like object representation of response (for advanced usage). - #: Use of ``raw`` requires that ``stream=True`` be set on the request. - #: This requirement does not apply for use internally to Requests. - self.raw = None - - #: Final URL location of Response. - self.url = None - - #: Encoding to decode with when accessing r.text. - self.encoding = None - - #: A list of :class:`Response ` objects from - #: the history of the Request. Any redirect responses will end - #: up here. The list is sorted from the oldest to the most recent request. - self.history = [] - - #: Textual reason of responded HTTP Status, e.g. "Not Found" or "OK". - self.reason = None - - #: A CookieJar of Cookies the server sent back. - self.cookies = cookiejar_from_dict({}) - - #: The amount of time elapsed between sending the request - #: and the arrival of the response (as a timedelta). - #: This property specifically measures the time taken between sending - #: the first byte of the request and finishing parsing the headers. It - #: is therefore unaffected by consuming the response content or the - #: value of the ``stream`` keyword argument. - self.elapsed = datetime.timedelta(0) - - #: The :class:`PreparedRequest ` object to which this - #: is a response. - self.request = None - - def __enter__(self): - return self - - def __exit__(self, *args): - self.close() - - def __getstate__(self): - # Consume everything; accessing the content attribute makes - # sure the content has been fully read. - if not self._content_consumed: - self.content - - return {attr: getattr(self, attr, None) for attr in self.__attrs__} - - def __setstate__(self, state): - for name, value in state.items(): - setattr(self, name, value) - - # pickled objects do not have .raw - setattr(self, "_content_consumed", True) - setattr(self, "raw", None) - - def __repr__(self): - return f"" - - def __bool__(self): - """Returns True if :attr:`status_code` is less than 400. - - This attribute checks if the status code of the response is between - 400 and 600 to see if there was a client error or a server error. If - the status code, is between 200 and 400, this will return True. This - is **not** a check to see if the response code is ``200 OK``. - """ - return self.ok - - def __nonzero__(self): - """Returns True if :attr:`status_code` is less than 400. - - This attribute checks if the status code of the response is between - 400 and 600 to see if there was a client error or a server error. If - the status code, is between 200 and 400, this will return True. This - is **not** a check to see if the response code is ``200 OK``. - """ - return self.ok - - def __iter__(self): - """Allows you to use a response as an iterator.""" - return self.iter_content(128) - - @property - def ok(self): - """Returns True if :attr:`status_code` is less than 400, False if not. - - This attribute checks if the status code of the response is between - 400 and 600 to see if there was a client error or a server error. If - the status code is between 200 and 400, this will return True. This - is **not** a check to see if the response code is ``200 OK``. - """ - try: - self.raise_for_status() - except HTTPError: - return False - return True - - @property - def is_redirect(self): - """True if this Response is a well-formed HTTP redirect that could have - been processed automatically (by :meth:`Session.resolve_redirects`). - """ - return "location" in self.headers and self.status_code in REDIRECT_STATI - - @property - def is_permanent_redirect(self): - """True if this Response one of the permanent versions of redirect.""" - return "location" in self.headers and self.status_code in ( - codes.moved_permanently, - codes.permanent_redirect, - ) - - @property - def next(self): - """Returns a PreparedRequest for the next request in a redirect chain, if there is one.""" - return self._next - - @property - def apparent_encoding(self): - """The apparent encoding, provided by the charset_normalizer or chardet libraries.""" - return chardet.detect(self.content)["encoding"] - - def iter_content(self, chunk_size=1, decode_unicode=False): - """Iterates over the response data. When stream=True is set on the - request, this avoids reading the content at once into memory for - large responses. The chunk size is the number of bytes it should - read into memory. This is not necessarily the length of each item - returned as decoding can take place. - - chunk_size must be of type int or None. A value of None will - function differently depending on the value of `stream`. - stream=True will read data as it arrives in whatever size the - chunks are received. If stream=False, data is returned as - a single chunk. - - If decode_unicode is True, content will be decoded using the best - available encoding based on the response. - """ - - def generate(): - # Special case for urllib3. - if hasattr(self.raw, "stream"): - try: - yield from self.raw.stream(chunk_size, decode_content=True) - except ProtocolError as e: - raise ChunkedEncodingError(e) - except DecodeError as e: - raise ContentDecodingError(e) - except ReadTimeoutError as e: - raise ConnectionError(e) - except SSLError as e: - raise RequestsSSLError(e) - else: - # Standard file-like object. - while True: - chunk = self.raw.read(chunk_size) - if not chunk: - break - yield chunk - - self._content_consumed = True - - if self._content_consumed and isinstance(self._content, bool): - raise StreamConsumedError() - elif chunk_size is not None and not isinstance(chunk_size, int): - raise TypeError( - f"chunk_size must be an int, it is instead a {type(chunk_size)}." - ) - # simulate reading small chunks of the content - reused_chunks = iter_slices(self._content, chunk_size) - - stream_chunks = generate() - - chunks = reused_chunks if self._content_consumed else stream_chunks - - if decode_unicode: - chunks = stream_decode_response_unicode(chunks, self) - - return chunks - - def iter_lines( - self, chunk_size=ITER_CHUNK_SIZE, decode_unicode=False, delimiter=None - ): - """Iterates over the response data, one line at a time. When - stream=True is set on the request, this avoids reading the - content at once into memory for large responses. - - .. note:: This method is not reentrant safe. - """ - - pending = None - - for chunk in self.iter_content( - chunk_size=chunk_size, decode_unicode=decode_unicode - ): - - if pending is not None: - chunk = pending + chunk - - if delimiter: - lines = chunk.split(delimiter) - else: - lines = chunk.splitlines() - - if lines and lines[-1] and chunk and lines[-1][-1] == chunk[-1]: - pending = lines.pop() - else: - pending = None - - yield from lines - - if pending is not None: - yield pending - - @property - def content(self): - """Content of the response, in bytes.""" - - if self._content is False: - # Read the contents. - if self._content_consumed: - raise RuntimeError("The content for this response was already consumed") - - if self.status_code == 0 or self.raw is None: - self._content = None - else: - self._content = b"".join(self.iter_content(CONTENT_CHUNK_SIZE)) or b"" - - self._content_consumed = True - # don't need to release the connection; that's been handled by urllib3 - # since we exhausted the data. - return self._content - - @property - def text(self): - """Content of the response, in unicode. - - If Response.encoding is None, encoding will be guessed using - ``charset_normalizer`` or ``chardet``. - - The encoding of the response content is determined based solely on HTTP - headers, following RFC 2616 to the letter. If you can take advantage of - non-HTTP knowledge to make a better guess at the encoding, you should - set ``r.encoding`` appropriately before accessing this property. - """ - - # Try charset from content-type - content = None - encoding = self.encoding - - if not self.content: - return "" - - # Fallback to auto-detected encoding. - if self.encoding is None: - encoding = self.apparent_encoding - - # Decode unicode from given encoding. - try: - content = str(self.content, encoding, errors="replace") - except (LookupError, TypeError): - # A LookupError is raised if the encoding was not found which could - # indicate a misspelling or similar mistake. - # - # A TypeError can be raised if encoding is None - # - # So we try blindly encoding. - content = str(self.content, errors="replace") - - return content - - def json(self, **kwargs): - r"""Returns the json-encoded content of a response, if any. - - :param \*\*kwargs: Optional arguments that ``json.loads`` takes. - :raises requests.exceptions.JSONDecodeError: If the response body does not - contain valid json. - """ - - if not self.encoding and self.content and len(self.content) > 3: - # No encoding set. JSON RFC 4627 section 3 states we should expect - # UTF-8, -16 or -32. Detect which one to use; If the detection or - # decoding fails, fall back to `self.text` (using charset_normalizer to make - # a best guess). - encoding = guess_json_utf(self.content) - if encoding is not None: - try: - return complexjson.loads(self.content.decode(encoding), **kwargs) - except UnicodeDecodeError: - # Wrong UTF codec detected; usually because it's not UTF-8 - # but some other 8-bit codec. This is an RFC violation, - # and the server didn't bother to tell us what codec *was* - # used. - pass - except JSONDecodeError as e: - raise RequestsJSONDecodeError(e.msg, e.doc, e.pos) - - try: - return complexjson.loads(self.text, **kwargs) - except JSONDecodeError as e: - # Catch JSON-related errors and raise as requests.JSONDecodeError - # This aliases json.JSONDecodeError and simplejson.JSONDecodeError - raise RequestsJSONDecodeError(e.msg, e.doc, e.pos) - - @property - def links(self): - """Returns the parsed header links of the response, if any.""" - - header = self.headers.get("link") - - resolved_links = {} - - if header: - links = parse_header_links(header) - - for link in links: - key = link.get("rel") or link.get("url") - resolved_links[key] = link - - return resolved_links - - def raise_for_status(self): - """Raises :class:`HTTPError`, if one occurred.""" - - http_error_msg = "" - if isinstance(self.reason, bytes): - # We attempt to decode utf-8 first because some servers - # choose to localize their reason strings. If the string - # isn't utf-8, we fall back to iso-8859-1 for all other - # encodings. (See PR #3538) - try: - reason = self.reason.decode("utf-8") - except UnicodeDecodeError: - reason = self.reason.decode("iso-8859-1") - else: - reason = self.reason - - if 400 <= self.status_code < 500: - http_error_msg = ( - f"{self.status_code} Client Error: {reason} for url: {self.url}" - ) - - elif 500 <= self.status_code < 600: - http_error_msg = ( - f"{self.status_code} Server Error: {reason} for url: {self.url}" - ) - - if http_error_msg: - raise HTTPError(http_error_msg, response=self) - - def close(self): - """Releases the connection back to the pool. Once this method has been - called the underlying ``raw`` object must not be accessed again. - - *Note: Should not normally need to be called explicitly.* - """ - if not self._content_consumed: - self.raw.close() - - release_conn = getattr(self.raw, "release_conn", None) - if release_conn is not None: - release_conn() diff --git a/Modules/requests/packages.py b/Modules/requests/packages.py deleted file mode 100644 index 77c45c9..0000000 --- a/Modules/requests/packages.py +++ /dev/null @@ -1,28 +0,0 @@ -import sys - -try: - import chardet -except ImportError: - import warnings - - import charset_normalizer as chardet - - warnings.filterwarnings("ignore", "Trying to detect", module="charset_normalizer") - -# This code exists for backwards compatibility reasons. -# I don't like it either. Just look the other way. :) - -for package in ("urllib3", "idna"): - locals()[package] = __import__(package) - # This traversal is apparently necessary such that the identities are - # preserved (requests.packages.urllib3.* is urllib3.*) - for mod in list(sys.modules): - if mod == package or mod.startswith(f"{package}."): - sys.modules[f"requests.packages.{mod}"] = sys.modules[mod] - -target = chardet.__name__ -for mod in list(sys.modules): - if mod == target or mod.startswith(f"{target}."): - target = target.replace(target, "chardet") - sys.modules[f"requests.packages.{target}"] = sys.modules[mod] -# Kinda cool, though, right? diff --git a/Modules/requests/sessions.py b/Modules/requests/sessions.py deleted file mode 100644 index dbcf2a7..0000000 --- a/Modules/requests/sessions.py +++ /dev/null @@ -1,833 +0,0 @@ -""" -requests.sessions -~~~~~~~~~~~~~~~~~ - -This module provides a Session object to manage and persist settings across -requests (cookies, auth, proxies). -""" -import os -import sys -import time -from collections import OrderedDict -from datetime import timedelta - -from ._internal_utils import to_native_string -from .adapters import HTTPAdapter -from .auth import _basic_auth_str -from .compat import Mapping, cookielib, urljoin, urlparse -from .cookies import ( - RequestsCookieJar, - cookiejar_from_dict, - extract_cookies_to_jar, - merge_cookies, -) -from .exceptions import ( - ChunkedEncodingError, - ContentDecodingError, - InvalidSchema, - TooManyRedirects, -) -from .hooks import default_hooks, dispatch_hook - -# formerly defined here, reexposed here for backward compatibility -from .models import ( # noqa: F401 - DEFAULT_REDIRECT_LIMIT, - REDIRECT_STATI, - PreparedRequest, - Request, -) -from .status_codes import codes -from .structures import CaseInsensitiveDict -from .utils import ( # noqa: F401 - DEFAULT_PORTS, - default_headers, - get_auth_from_url, - get_environ_proxies, - get_netrc_auth, - requote_uri, - resolve_proxies, - rewind_body, - should_bypass_proxies, - to_key_val_list, -) - -# Preferred clock, based on which one is more accurate on a given system. -if sys.platform == "win32": - preferred_clock = time.perf_counter -else: - preferred_clock = time.time - - -def merge_setting(request_setting, session_setting, dict_class=OrderedDict): - """Determines appropriate setting for a given request, taking into account - the explicit setting on that request, and the setting in the session. If a - setting is a dictionary, they will be merged together using `dict_class` - """ - - if session_setting is None: - return request_setting - - if request_setting is None: - return session_setting - - # Bypass if not a dictionary (e.g. verify) - if not ( - isinstance(session_setting, Mapping) and isinstance(request_setting, Mapping) - ): - return request_setting - - merged_setting = dict_class(to_key_val_list(session_setting)) - merged_setting.update(to_key_val_list(request_setting)) - - # Remove keys that are set to None. Extract keys first to avoid altering - # the dictionary during iteration. - none_keys = [k for (k, v) in merged_setting.items() if v is None] - for key in none_keys: - del merged_setting[key] - - return merged_setting - - -def merge_hooks(request_hooks, session_hooks, dict_class=OrderedDict): - """Properly merges both requests and session hooks. - - This is necessary because when request_hooks == {'response': []}, the - merge breaks Session hooks entirely. - """ - if session_hooks is None or session_hooks.get("response") == []: - return request_hooks - - if request_hooks is None or request_hooks.get("response") == []: - return session_hooks - - return merge_setting(request_hooks, session_hooks, dict_class) - - -class SessionRedirectMixin: - def get_redirect_target(self, resp): - """Receives a Response. Returns a redirect URI or ``None``""" - # Due to the nature of how requests processes redirects this method will - # be called at least once upon the original response and at least twice - # on each subsequent redirect response (if any). - # If a custom mixin is used to handle this logic, it may be advantageous - # to cache the redirect location onto the response object as a private - # attribute. - if resp.is_redirect: - location = resp.headers["location"] - # Currently the underlying http module on py3 decode headers - # in latin1, but empirical evidence suggests that latin1 is very - # rarely used with non-ASCII characters in HTTP headers. - # It is more likely to get UTF8 header rather than latin1. - # This causes incorrect handling of UTF8 encoded location headers. - # To solve this, we re-encode the location in latin1. - location = location.encode("latin1") - return to_native_string(location, "utf8") - return None - - def should_strip_auth(self, old_url, new_url): - """Decide whether Authorization header should be removed when redirecting""" - old_parsed = urlparse(old_url) - new_parsed = urlparse(new_url) - if old_parsed.hostname != new_parsed.hostname: - return True - # Special case: allow http -> https redirect when using the standard - # ports. This isn't specified by RFC 7235, but is kept to avoid - # breaking backwards compatibility with older versions of requests - # that allowed any redirects on the same host. - if ( - old_parsed.scheme == "http" - and old_parsed.port in (80, None) - and new_parsed.scheme == "https" - and new_parsed.port in (443, None) - ): - return False - - # Handle default port usage corresponding to scheme. - changed_port = old_parsed.port != new_parsed.port - changed_scheme = old_parsed.scheme != new_parsed.scheme - default_port = (DEFAULT_PORTS.get(old_parsed.scheme, None), None) - if ( - not changed_scheme - and old_parsed.port in default_port - and new_parsed.port in default_port - ): - return False - - # Standard case: root URI must match - return changed_port or changed_scheme - - def resolve_redirects( - self, - resp, - req, - stream=False, - timeout=None, - verify=True, - cert=None, - proxies=None, - yield_requests=False, - **adapter_kwargs, - ): - """Receives a Response. Returns a generator of Responses or Requests.""" - - hist = [] # keep track of history - - url = self.get_redirect_target(resp) - previous_fragment = urlparse(req.url).fragment - while url: - prepared_request = req.copy() - - # Update history and keep track of redirects. - # resp.history must ignore the original request in this loop - hist.append(resp) - resp.history = hist[1:] - - try: - resp.content # Consume socket so it can be released - except (ChunkedEncodingError, ContentDecodingError, RuntimeError): - resp.raw.read(decode_content=False) - - if len(resp.history) >= self.max_redirects: - raise TooManyRedirects( - f"Exceeded {self.max_redirects} redirects.", response=resp - ) - - # Release the connection back into the pool. - resp.close() - - # Handle redirection without scheme (see: RFC 1808 Section 4) - if url.startswith("//"): - parsed_rurl = urlparse(resp.url) - url = ":".join([to_native_string(parsed_rurl.scheme), url]) - - # Normalize url case and attach previous fragment if needed (RFC 7231 7.1.2) - parsed = urlparse(url) - if parsed.fragment == "" and previous_fragment: - parsed = parsed._replace(fragment=previous_fragment) - elif parsed.fragment: - previous_fragment = parsed.fragment - url = parsed.geturl() - - # Facilitate relative 'location' headers, as allowed by RFC 7231. - # (e.g. '/path/to/resource' instead of 'http://domain.tld/path/to/resource') - # Compliant with RFC3986, we percent encode the url. - if not parsed.netloc: - url = urljoin(resp.url, requote_uri(url)) - else: - url = requote_uri(url) - - prepared_request.url = to_native_string(url) - - self.rebuild_method(prepared_request, resp) - - # https://github.com/psf/requests/issues/1084 - if resp.status_code not in ( - codes.temporary_redirect, - codes.permanent_redirect, - ): - # https://github.com/psf/requests/issues/3490 - purged_headers = ("Content-Length", "Content-Type", "Transfer-Encoding") - for header in purged_headers: - prepared_request.headers.pop(header, None) - prepared_request.body = None - - headers = prepared_request.headers - headers.pop("Cookie", None) - - # Extract any cookies sent on the response to the cookiejar - # in the new request. Because we've mutated our copied prepared - # request, use the old one that we haven't yet touched. - extract_cookies_to_jar(prepared_request._cookies, req, resp.raw) - merge_cookies(prepared_request._cookies, self.cookies) - prepared_request.prepare_cookies(prepared_request._cookies) - - # Rebuild auth and proxy information. - proxies = self.rebuild_proxies(prepared_request, proxies) - self.rebuild_auth(prepared_request, resp) - - # A failed tell() sets `_body_position` to `object()`. This non-None - # value ensures `rewindable` will be True, allowing us to raise an - # UnrewindableBodyError, instead of hanging the connection. - rewindable = prepared_request._body_position is not None and ( - "Content-Length" in headers or "Transfer-Encoding" in headers - ) - - # Attempt to rewind consumed file-like object. - if rewindable: - rewind_body(prepared_request) - - # Override the original request. - req = prepared_request - - if yield_requests: - yield req - else: - - resp = self.send( - req, - stream=stream, - timeout=timeout, - verify=verify, - cert=cert, - proxies=proxies, - allow_redirects=False, - **adapter_kwargs, - ) - - extract_cookies_to_jar(self.cookies, prepared_request, resp.raw) - - # extract redirect url, if any, for the next loop - url = self.get_redirect_target(resp) - yield resp - - def rebuild_auth(self, prepared_request, response): - """When being redirected we may want to strip authentication from the - request to avoid leaking credentials. This method intelligently removes - and reapplies authentication where possible to avoid credential loss. - """ - headers = prepared_request.headers - url = prepared_request.url - - if "Authorization" in headers and self.should_strip_auth( - response.request.url, url - ): - # If we get redirected to a new host, we should strip out any - # authentication headers. - del headers["Authorization"] - - # .netrc might have more auth for us on our new host. - new_auth = get_netrc_auth(url) if self.trust_env else None - if new_auth is not None: - prepared_request.prepare_auth(new_auth) - - def rebuild_proxies(self, prepared_request, proxies): - """This method re-evaluates the proxy configuration by considering the - environment variables. If we are redirected to a URL covered by - NO_PROXY, we strip the proxy configuration. Otherwise, we set missing - proxy keys for this URL (in case they were stripped by a previous - redirect). - - This method also replaces the Proxy-Authorization header where - necessary. - - :rtype: dict - """ - headers = prepared_request.headers - scheme = urlparse(prepared_request.url).scheme - new_proxies = resolve_proxies(prepared_request, proxies, self.trust_env) - - if "Proxy-Authorization" in headers: - del headers["Proxy-Authorization"] - - try: - username, password = get_auth_from_url(new_proxies[scheme]) - except KeyError: - username, password = None, None - - # urllib3 handles proxy authorization for us in the standard adapter. - # Avoid appending this to TLS tunneled requests where it may be leaked. - if not scheme.startswith('https') and username and password: - headers["Proxy-Authorization"] = _basic_auth_str(username, password) - - return new_proxies - - def rebuild_method(self, prepared_request, response): - """When being redirected we may want to change the method of the request - based on certain specs or browser behavior. - """ - method = prepared_request.method - - # https://tools.ietf.org/html/rfc7231#section-6.4.4 - if response.status_code == codes.see_other and method != "HEAD": - method = "GET" - - # Do what the browsers do, despite standards... - # First, turn 302s into GETs. - if response.status_code == codes.found and method != "HEAD": - method = "GET" - - # Second, if a POST is responded to with a 301, turn it into a GET. - # This bizarre behaviour is explained in Issue 1704. - if response.status_code == codes.moved and method == "POST": - method = "GET" - - prepared_request.method = method - - -class Session(SessionRedirectMixin): - """A Requests session. - - Provides cookie persistence, connection-pooling, and configuration. - - Basic Usage:: - - >>> import requests - >>> s = requests.Session() - >>> s.get('https://httpbin.org/get') - - - Or as a context manager:: - - >>> with requests.Session() as s: - ... s.get('https://httpbin.org/get') - - """ - - __attrs__ = [ - "headers", - "cookies", - "auth", - "proxies", - "hooks", - "params", - "verify", - "cert", - "adapters", - "stream", - "trust_env", - "max_redirects", - ] - - def __init__(self): - - #: A case-insensitive dictionary of headers to be sent on each - #: :class:`Request ` sent from this - #: :class:`Session `. - self.headers = default_headers() - - #: Default Authentication tuple or object to attach to - #: :class:`Request `. - self.auth = None - - #: Dictionary mapping protocol or protocol and host to the URL of the proxy - #: (e.g. {'http': 'foo.bar:3128', 'http://host.name': 'foo.bar:4012'}) to - #: be used on each :class:`Request `. - self.proxies = {} - - #: Event-handling hooks. - self.hooks = default_hooks() - - #: Dictionary of querystring data to attach to each - #: :class:`Request `. The dictionary values may be lists for - #: representing multivalued query parameters. - self.params = {} - - #: Stream response content default. - self.stream = False - - #: SSL Verification default. - #: Defaults to `True`, requiring requests to verify the TLS certificate at the - #: remote end. - #: If verify is set to `False`, requests will accept any TLS certificate - #: presented by the server, and will ignore hostname mismatches and/or - #: expired certificates, which will make your application vulnerable to - #: man-in-the-middle (MitM) attacks. - #: Only set this to `False` for testing. - self.verify = True - - #: SSL client certificate default, if String, path to ssl client - #: cert file (.pem). If Tuple, ('cert', 'key') pair. - self.cert = None - - #: Maximum number of redirects allowed. If the request exceeds this - #: limit, a :class:`TooManyRedirects` exception is raised. - #: This defaults to requests.models.DEFAULT_REDIRECT_LIMIT, which is - #: 30. - self.max_redirects = DEFAULT_REDIRECT_LIMIT - - #: Trust environment settings for proxy configuration, default - #: authentication and similar. - self.trust_env = True - - #: A CookieJar containing all currently outstanding cookies set on this - #: session. By default it is a - #: :class:`RequestsCookieJar `, but - #: may be any other ``cookielib.CookieJar`` compatible object. - self.cookies = cookiejar_from_dict({}) - - # Default connection adapters. - self.adapters = OrderedDict() - self.mount("https://", HTTPAdapter()) - self.mount("http://", HTTPAdapter()) - - def __enter__(self): - return self - - def __exit__(self, *args): - self.close() - - def prepare_request(self, request): - """Constructs a :class:`PreparedRequest ` for - transmission and returns it. The :class:`PreparedRequest` has settings - merged from the :class:`Request ` instance and those of the - :class:`Session`. - - :param request: :class:`Request` instance to prepare with this - session's settings. - :rtype: requests.PreparedRequest - """ - cookies = request.cookies or {} - - # Bootstrap CookieJar. - if not isinstance(cookies, cookielib.CookieJar): - cookies = cookiejar_from_dict(cookies) - - # Merge with session cookies - merged_cookies = merge_cookies( - merge_cookies(RequestsCookieJar(), self.cookies), cookies - ) - - # Set environment's basic authentication if not explicitly set. - auth = request.auth - if self.trust_env and not auth and not self.auth: - auth = get_netrc_auth(request.url) - - p = PreparedRequest() - p.prepare( - method=request.method.upper(), - url=request.url, - files=request.files, - data=request.data, - json=request.json, - headers=merge_setting( - request.headers, self.headers, dict_class=CaseInsensitiveDict - ), - params=merge_setting(request.params, self.params), - auth=merge_setting(auth, self.auth), - cookies=merged_cookies, - hooks=merge_hooks(request.hooks, self.hooks), - ) - return p - - def request( - self, - method, - url, - params=None, - data=None, - headers=None, - cookies=None, - files=None, - auth=None, - timeout=None, - allow_redirects=True, - proxies=None, - hooks=None, - stream=None, - verify=None, - cert=None, - json=None, - ): - """Constructs a :class:`Request `, prepares it and sends it. - Returns :class:`Response ` object. - - :param method: method for the new :class:`Request` object. - :param url: URL for the new :class:`Request` object. - :param params: (optional) Dictionary or bytes to be sent in the query - string for the :class:`Request`. - :param data: (optional) Dictionary, list of tuples, bytes, or file-like - object to send in the body of the :class:`Request`. - :param json: (optional) json to send in the body of the - :class:`Request`. - :param headers: (optional) Dictionary of HTTP Headers to send with the - :class:`Request`. - :param cookies: (optional) Dict or CookieJar object to send with the - :class:`Request`. - :param files: (optional) Dictionary of ``'filename': file-like-objects`` - for multipart encoding upload. - :param auth: (optional) Auth tuple or callable to enable - Basic/Digest/Custom HTTP Auth. - :param timeout: (optional) How long to wait for the server to send - data before giving up, as a float, or a :ref:`(connect timeout, - read timeout) ` tuple. - :type timeout: float or tuple - :param allow_redirects: (optional) Set to True by default. - :type allow_redirects: bool - :param proxies: (optional) Dictionary mapping protocol or protocol and - hostname to the URL of the proxy. - :param stream: (optional) whether to immediately download the response - content. Defaults to ``False``. - :param verify: (optional) Either a boolean, in which case it controls whether we verify - the server's TLS certificate, or a string, in which case it must be a path - to a CA bundle to use. Defaults to ``True``. When set to - ``False``, requests will accept any TLS certificate presented by - the server, and will ignore hostname mismatches and/or expired - certificates, which will make your application vulnerable to - man-in-the-middle (MitM) attacks. Setting verify to ``False`` - may be useful during local development or testing. - :param cert: (optional) if String, path to ssl client cert file (.pem). - If Tuple, ('cert', 'key') pair. - :rtype: requests.Response - """ - # Create the Request. - req = Request( - method=method.upper(), - url=url, - headers=headers, - files=files, - data=data or {}, - json=json, - params=params or {}, - auth=auth, - cookies=cookies, - hooks=hooks, - ) - prep = self.prepare_request(req) - - proxies = proxies or {} - - settings = self.merge_environment_settings( - prep.url, proxies, stream, verify, cert - ) - - # Send the request. - send_kwargs = { - "timeout": timeout, - "allow_redirects": allow_redirects, - } - send_kwargs.update(settings) - resp = self.send(prep, **send_kwargs) - - return resp - - def get(self, url, **kwargs): - r"""Sends a GET request. Returns :class:`Response` object. - - :param url: URL for the new :class:`Request` object. - :param \*\*kwargs: Optional arguments that ``request`` takes. - :rtype: requests.Response - """ - - kwargs.setdefault("allow_redirects", True) - return self.request("GET", url, **kwargs) - - def options(self, url, **kwargs): - r"""Sends a OPTIONS request. Returns :class:`Response` object. - - :param url: URL for the new :class:`Request` object. - :param \*\*kwargs: Optional arguments that ``request`` takes. - :rtype: requests.Response - """ - - kwargs.setdefault("allow_redirects", True) - return self.request("OPTIONS", url, **kwargs) - - def head(self, url, **kwargs): - r"""Sends a HEAD request. Returns :class:`Response` object. - - :param url: URL for the new :class:`Request` object. - :param \*\*kwargs: Optional arguments that ``request`` takes. - :rtype: requests.Response - """ - - kwargs.setdefault("allow_redirects", False) - return self.request("HEAD", url, **kwargs) - - def post(self, url, data=None, json=None, **kwargs): - r"""Sends a POST request. Returns :class:`Response` object. - - :param url: URL for the new :class:`Request` object. - :param data: (optional) Dictionary, list of tuples, bytes, or file-like - object to send in the body of the :class:`Request`. - :param json: (optional) json to send in the body of the :class:`Request`. - :param \*\*kwargs: Optional arguments that ``request`` takes. - :rtype: requests.Response - """ - - return self.request("POST", url, data=data, json=json, **kwargs) - - def put(self, url, data=None, **kwargs): - r"""Sends a PUT request. Returns :class:`Response` object. - - :param url: URL for the new :class:`Request` object. - :param data: (optional) Dictionary, list of tuples, bytes, or file-like - object to send in the body of the :class:`Request`. - :param \*\*kwargs: Optional arguments that ``request`` takes. - :rtype: requests.Response - """ - - return self.request("PUT", url, data=data, **kwargs) - - def patch(self, url, data=None, **kwargs): - r"""Sends a PATCH request. Returns :class:`Response` object. - - :param url: URL for the new :class:`Request` object. - :param data: (optional) Dictionary, list of tuples, bytes, or file-like - object to send in the body of the :class:`Request`. - :param \*\*kwargs: Optional arguments that ``request`` takes. - :rtype: requests.Response - """ - - return self.request("PATCH", url, data=data, **kwargs) - - def delete(self, url, **kwargs): - r"""Sends a DELETE request. Returns :class:`Response` object. - - :param url: URL for the new :class:`Request` object. - :param \*\*kwargs: Optional arguments that ``request`` takes. - :rtype: requests.Response - """ - - return self.request("DELETE", url, **kwargs) - - def send(self, request, **kwargs): - """Send a given PreparedRequest. - - :rtype: requests.Response - """ - # Set defaults that the hooks can utilize to ensure they always have - # the correct parameters to reproduce the previous request. - kwargs.setdefault("stream", self.stream) - kwargs.setdefault("verify", self.verify) - kwargs.setdefault("cert", self.cert) - if "proxies" not in kwargs: - kwargs["proxies"] = resolve_proxies(request, self.proxies, self.trust_env) - - # It's possible that users might accidentally send a Request object. - # Guard against that specific failure case. - if isinstance(request, Request): - raise ValueError("You can only send PreparedRequests.") - - # Set up variables needed for resolve_redirects and dispatching of hooks - allow_redirects = kwargs.pop("allow_redirects", True) - stream = kwargs.get("stream") - hooks = request.hooks - - # Get the appropriate adapter to use - adapter = self.get_adapter(url=request.url) - - # Start time (approximately) of the request - start = preferred_clock() - - # Send the request - r = adapter.send(request, **kwargs) - - # Total elapsed time of the request (approximately) - elapsed = preferred_clock() - start - r.elapsed = timedelta(seconds=elapsed) - - # Response manipulation hooks - r = dispatch_hook("response", hooks, r, **kwargs) - - # Persist cookies - if r.history: - - # If the hooks create history then we want those cookies too - for resp in r.history: - extract_cookies_to_jar(self.cookies, resp.request, resp.raw) - - extract_cookies_to_jar(self.cookies, request, r.raw) - - # Resolve redirects if allowed. - if allow_redirects: - # Redirect resolving generator. - gen = self.resolve_redirects(r, request, **kwargs) - history = [resp for resp in gen] - else: - history = [] - - # Shuffle things around if there's history. - if history: - # Insert the first (original) request at the start - history.insert(0, r) - # Get the last request made - r = history.pop() - r.history = history - - # If redirects aren't being followed, store the response on the Request for Response.next(). - if not allow_redirects: - try: - r._next = next( - self.resolve_redirects(r, request, yield_requests=True, **kwargs) - ) - except StopIteration: - pass - - if not stream: - r.content - - return r - - def merge_environment_settings(self, url, proxies, stream, verify, cert): - """ - Check the environment and merge it with some settings. - - :rtype: dict - """ - # Gather clues from the surrounding environment. - if self.trust_env: - # Set environment's proxies. - no_proxy = proxies.get("no_proxy") if proxies is not None else None - env_proxies = get_environ_proxies(url, no_proxy=no_proxy) - for (k, v) in env_proxies.items(): - proxies.setdefault(k, v) - - # Look for requests environment configuration - # and be compatible with cURL. - if verify is True or verify is None: - verify = ( - os.environ.get("REQUESTS_CA_BUNDLE") - or os.environ.get("CURL_CA_BUNDLE") - or verify - ) - - # Merge all the kwargs. - proxies = merge_setting(proxies, self.proxies) - stream = merge_setting(stream, self.stream) - verify = merge_setting(verify, self.verify) - cert = merge_setting(cert, self.cert) - - return {"proxies": proxies, "stream": stream, "verify": verify, "cert": cert} - - def get_adapter(self, url): - """ - Returns the appropriate connection adapter for the given URL. - - :rtype: requests.adapters.BaseAdapter - """ - for (prefix, adapter) in self.adapters.items(): - - if url.lower().startswith(prefix.lower()): - return adapter - - # Nothing matches :-/ - raise InvalidSchema(f"No connection adapters were found for {url!r}") - - def close(self): - """Closes all adapters and as such the session""" - for v in self.adapters.values(): - v.close() - - def mount(self, prefix, adapter): - """Registers a connection adapter to a prefix. - - Adapters are sorted in descending order by prefix length. - """ - self.adapters[prefix] = adapter - keys_to_move = [k for k in self.adapters if len(k) < len(prefix)] - - for key in keys_to_move: - self.adapters[key] = self.adapters.pop(key) - - def __getstate__(self): - state = {attr: getattr(self, attr, None) for attr in self.__attrs__} - return state - - def __setstate__(self, state): - for attr, value in state.items(): - setattr(self, attr, value) - - -def session(): - """ - Returns a :class:`Session` for context-management. - - .. deprecated:: 1.0.0 - - This method has been deprecated since version 1.0.0 and is only kept for - backwards compatibility. New code should use :class:`~requests.sessions.Session` - to create a session. This may be removed at a future date. - - :rtype: Session - """ - return Session() diff --git a/Modules/requests/status_codes.py b/Modules/requests/status_codes.py deleted file mode 100644 index 4bd072b..0000000 --- a/Modules/requests/status_codes.py +++ /dev/null @@ -1,128 +0,0 @@ -r""" -The ``codes`` object defines a mapping from common names for HTTP statuses -to their numerical codes, accessible either as attributes or as dictionary -items. - -Example:: - - >>> import requests - >>> requests.codes['temporary_redirect'] - 307 - >>> requests.codes.teapot - 418 - >>> requests.codes['\o/'] - 200 - -Some codes have multiple names, and both upper- and lower-case versions of -the names are allowed. For example, ``codes.ok``, ``codes.OK``, and -``codes.okay`` all correspond to the HTTP status code 200. -""" - -from .structures import LookupDict - -_codes = { - # Informational. - 100: ("continue",), - 101: ("switching_protocols",), - 102: ("processing",), - 103: ("checkpoint",), - 122: ("uri_too_long", "request_uri_too_long"), - 200: ("ok", "okay", "all_ok", "all_okay", "all_good", "\\o/", "✓"), - 201: ("created",), - 202: ("accepted",), - 203: ("non_authoritative_info", "non_authoritative_information"), - 204: ("no_content",), - 205: ("reset_content", "reset"), - 206: ("partial_content", "partial"), - 207: ("multi_status", "multiple_status", "multi_stati", "multiple_stati"), - 208: ("already_reported",), - 226: ("im_used",), - # Redirection. - 300: ("multiple_choices",), - 301: ("moved_permanently", "moved", "\\o-"), - 302: ("found",), - 303: ("see_other", "other"), - 304: ("not_modified",), - 305: ("use_proxy",), - 306: ("switch_proxy",), - 307: ("temporary_redirect", "temporary_moved", "temporary"), - 308: ( - "permanent_redirect", - "resume_incomplete", - "resume", - ), # "resume" and "resume_incomplete" to be removed in 3.0 - # Client Error. - 400: ("bad_request", "bad"), - 401: ("unauthorized",), - 402: ("payment_required", "payment"), - 403: ("forbidden",), - 404: ("not_found", "-o-"), - 405: ("method_not_allowed", "not_allowed"), - 406: ("not_acceptable",), - 407: ("proxy_authentication_required", "proxy_auth", "proxy_authentication"), - 408: ("request_timeout", "timeout"), - 409: ("conflict",), - 410: ("gone",), - 411: ("length_required",), - 412: ("precondition_failed", "precondition"), - 413: ("request_entity_too_large",), - 414: ("request_uri_too_large",), - 415: ("unsupported_media_type", "unsupported_media", "media_type"), - 416: ( - "requested_range_not_satisfiable", - "requested_range", - "range_not_satisfiable", - ), - 417: ("expectation_failed",), - 418: ("im_a_teapot", "teapot", "i_am_a_teapot"), - 421: ("misdirected_request",), - 422: ("unprocessable_entity", "unprocessable"), - 423: ("locked",), - 424: ("failed_dependency", "dependency"), - 425: ("unordered_collection", "unordered"), - 426: ("upgrade_required", "upgrade"), - 428: ("precondition_required", "precondition"), - 429: ("too_many_requests", "too_many"), - 431: ("header_fields_too_large", "fields_too_large"), - 444: ("no_response", "none"), - 449: ("retry_with", "retry"), - 450: ("blocked_by_windows_parental_controls", "parental_controls"), - 451: ("unavailable_for_legal_reasons", "legal_reasons"), - 499: ("client_closed_request",), - # Server Error. - 500: ("internal_server_error", "server_error", "/o\\", "✗"), - 501: ("not_implemented",), - 502: ("bad_gateway",), - 503: ("service_unavailable", "unavailable"), - 504: ("gateway_timeout",), - 505: ("http_version_not_supported", "http_version"), - 506: ("variant_also_negotiates",), - 507: ("insufficient_storage",), - 509: ("bandwidth_limit_exceeded", "bandwidth"), - 510: ("not_extended",), - 511: ("network_authentication_required", "network_auth", "network_authentication"), -} - -codes = LookupDict(name="status_codes") - - -def _init(): - for code, titles in _codes.items(): - for title in titles: - setattr(codes, title, code) - if not title.startswith(("\\", "/")): - setattr(codes, title.upper(), code) - - def doc(code): - names = ", ".join(f"``{n}``" for n in _codes[code]) - return "* %d: %s" % (code, names) - - global __doc__ - __doc__ = ( - __doc__ + "\n" + "\n".join(doc(code) for code in sorted(_codes)) - if __doc__ is not None - else None - ) - - -_init() diff --git a/Modules/requests/structures.py b/Modules/requests/structures.py deleted file mode 100644 index 188e13e..0000000 --- a/Modules/requests/structures.py +++ /dev/null @@ -1,99 +0,0 @@ -""" -requests.structures -~~~~~~~~~~~~~~~~~~~ - -Data structures that power Requests. -""" - -from collections import OrderedDict - -from .compat import Mapping, MutableMapping - - -class CaseInsensitiveDict(MutableMapping): - """A case-insensitive ``dict``-like object. - - Implements all methods and operations of - ``MutableMapping`` as well as dict's ``copy``. Also - provides ``lower_items``. - - All keys are expected to be strings. The structure remembers the - case of the last key to be set, and ``iter(instance)``, - ``keys()``, ``items()``, ``iterkeys()``, and ``iteritems()`` - will contain case-sensitive keys. However, querying and contains - testing is case insensitive:: - - cid = CaseInsensitiveDict() - cid['Accept'] = 'application/json' - cid['aCCEPT'] == 'application/json' # True - list(cid) == ['Accept'] # True - - For example, ``headers['content-encoding']`` will return the - value of a ``'Content-Encoding'`` response header, regardless - of how the header name was originally stored. - - If the constructor, ``.update``, or equality comparison - operations are given keys that have equal ``.lower()``s, the - behavior is undefined. - """ - - def __init__(self, data=None, **kwargs): - self._store = OrderedDict() - if data is None: - data = {} - self.update(data, **kwargs) - - def __setitem__(self, key, value): - # Use the lowercased key for lookups, but store the actual - # key alongside the value. - self._store[key.lower()] = (key, value) - - def __getitem__(self, key): - return self._store[key.lower()][1] - - def __delitem__(self, key): - del self._store[key.lower()] - - def __iter__(self): - return (casedkey for casedkey, mappedvalue in self._store.values()) - - def __len__(self): - return len(self._store) - - def lower_items(self): - """Like iteritems(), but with all lowercase keys.""" - return ((lowerkey, keyval[1]) for (lowerkey, keyval) in self._store.items()) - - def __eq__(self, other): - if isinstance(other, Mapping): - other = CaseInsensitiveDict(other) - else: - return NotImplemented - # Compare insensitively - return dict(self.lower_items()) == dict(other.lower_items()) - - # Copy is required - def copy(self): - return CaseInsensitiveDict(self._store.values()) - - def __repr__(self): - return str(dict(self.items())) - - -class LookupDict(dict): - """Dictionary lookup object.""" - - def __init__(self, name=None): - self.name = name - super().__init__() - - def __repr__(self): - return f"" - - def __getitem__(self, key): - # We allow fall-through here, so values default to None - - return self.__dict__.get(key, None) - - def get(self, key, default=None): - return self.__dict__.get(key, default) diff --git a/Modules/requests/utils.py b/Modules/requests/utils.py deleted file mode 100644 index a367417..0000000 --- a/Modules/requests/utils.py +++ /dev/null @@ -1,1094 +0,0 @@ -""" -requests.utils -~~~~~~~~~~~~~~ - -This module provides utility functions that are used within Requests -that are also useful for external consumption. -""" - -import codecs -import contextlib -import io -import os -import re -import socket -import struct -import sys -import tempfile -import warnings -import zipfile -from collections import OrderedDict - -from urllib3.util import make_headers, parse_url - -from . import certs -from .__version__ import __version__ - -# to_native_string is unused here, but imported here for backwards compatibility -from ._internal_utils import ( # noqa: F401 - _HEADER_VALIDATORS_BYTE, - _HEADER_VALIDATORS_STR, - HEADER_VALIDATORS, - to_native_string, -) -from .compat import ( - Mapping, - basestring, - bytes, - getproxies, - getproxies_environment, - integer_types, -) -from .compat import parse_http_list as _parse_list_header -from .compat import ( - proxy_bypass, - proxy_bypass_environment, - quote, - str, - unquote, - urlparse, - urlunparse, -) -from .cookies import cookiejar_from_dict -from .exceptions import ( - FileModeWarning, - InvalidHeader, - InvalidURL, - UnrewindableBodyError, -) -from .structures import CaseInsensitiveDict - -NETRC_FILES = (".netrc", "_netrc") - -DEFAULT_CA_BUNDLE_PATH = certs.where() - -DEFAULT_PORTS = {"http": 80, "https": 443} - -# Ensure that ', ' is used to preserve previous delimiter behavior. -DEFAULT_ACCEPT_ENCODING = ", ".join( - re.split(r",\s*", make_headers(accept_encoding=True)["accept-encoding"]) -) - - -if sys.platform == "win32": - # provide a proxy_bypass version on Windows without DNS lookups - - def proxy_bypass_registry(host): - try: - import winreg - except ImportError: - return False - - try: - internetSettings = winreg.OpenKey( - winreg.HKEY_CURRENT_USER, - r"Software\Microsoft\Windows\CurrentVersion\Internet Settings", - ) - # ProxyEnable could be REG_SZ or REG_DWORD, normalizing it - proxyEnable = int(winreg.QueryValueEx(internetSettings, "ProxyEnable")[0]) - # ProxyOverride is almost always a string - proxyOverride = winreg.QueryValueEx(internetSettings, "ProxyOverride")[0] - except (OSError, ValueError): - return False - if not proxyEnable or not proxyOverride: - return False - - # make a check value list from the registry entry: replace the - # '' string by the localhost entry and the corresponding - # canonical entry. - proxyOverride = proxyOverride.split(";") - # now check if we match one of the registry values. - for test in proxyOverride: - if test == "": - if "." not in host: - return True - test = test.replace(".", r"\.") # mask dots - test = test.replace("*", r".*") # change glob sequence - test = test.replace("?", r".") # change glob char - if re.match(test, host, re.I): - return True - return False - - def proxy_bypass(host): # noqa - """Return True, if the host should be bypassed. - - Checks proxy settings gathered from the environment, if specified, - or the registry. - """ - if getproxies_environment(): - return proxy_bypass_environment(host) - else: - return proxy_bypass_registry(host) - - -def dict_to_sequence(d): - """Returns an internal sequence dictionary update.""" - - if hasattr(d, "items"): - d = d.items() - - return d - - -def super_len(o): - total_length = None - current_position = 0 - - if hasattr(o, "__len__"): - total_length = len(o) - - elif hasattr(o, "len"): - total_length = o.len - - elif hasattr(o, "fileno"): - try: - fileno = o.fileno() - except (io.UnsupportedOperation, AttributeError): - # AttributeError is a surprising exception, seeing as how we've just checked - # that `hasattr(o, 'fileno')`. It happens for objects obtained via - # `Tarfile.extractfile()`, per issue 5229. - pass - else: - total_length = os.fstat(fileno).st_size - - # Having used fstat to determine the file length, we need to - # confirm that this file was opened up in binary mode. - if "b" not in o.mode: - warnings.warn( - ( - "Requests has determined the content-length for this " - "request using the binary size of the file: however, the " - "file has been opened in text mode (i.e. without the 'b' " - "flag in the mode). This may lead to an incorrect " - "content-length. In Requests 3.0, support will be removed " - "for files in text mode." - ), - FileModeWarning, - ) - - if hasattr(o, "tell"): - try: - current_position = o.tell() - except OSError: - # This can happen in some weird situations, such as when the file - # is actually a special file descriptor like stdin. In this - # instance, we don't know what the length is, so set it to zero and - # let requests chunk it instead. - if total_length is not None: - current_position = total_length - else: - if hasattr(o, "seek") and total_length is None: - # StringIO and BytesIO have seek but no usable fileno - try: - # seek to end of file - o.seek(0, 2) - total_length = o.tell() - - # seek back to current position to support - # partially read file-like objects - o.seek(current_position or 0) - except OSError: - total_length = 0 - - if total_length is None: - total_length = 0 - - return max(0, total_length - current_position) - - -def get_netrc_auth(url, raise_errors=False): - """Returns the Requests tuple auth for a given url from netrc.""" - - netrc_file = os.environ.get("NETRC") - if netrc_file is not None: - netrc_locations = (netrc_file,) - else: - netrc_locations = (f"~/{f}" for f in NETRC_FILES) - - try: - from netrc import NetrcParseError, netrc - - netrc_path = None - - for f in netrc_locations: - try: - loc = os.path.expanduser(f) - except KeyError: - # os.path.expanduser can fail when $HOME is undefined and - # getpwuid fails. See https://bugs.python.org/issue20164 & - # https://github.com/psf/requests/issues/1846 - return - - if os.path.exists(loc): - netrc_path = loc - break - - # Abort early if there isn't one. - if netrc_path is None: - return - - ri = urlparse(url) - - # Strip port numbers from netloc. This weird `if...encode`` dance is - # used for Python 3.2, which doesn't support unicode literals. - splitstr = b":" - if isinstance(url, str): - splitstr = splitstr.decode("ascii") - host = ri.netloc.split(splitstr)[0] - - try: - _netrc = netrc(netrc_path).authenticators(host) - if _netrc: - # Return with login / password - login_i = 0 if _netrc[0] else 1 - return (_netrc[login_i], _netrc[2]) - except (NetrcParseError, OSError): - # If there was a parsing error or a permissions issue reading the file, - # we'll just skip netrc auth unless explicitly asked to raise errors. - if raise_errors: - raise - - # App Engine hackiness. - except (ImportError, AttributeError): - pass - - -def guess_filename(obj): - """Tries to guess the filename of the given object.""" - name = getattr(obj, "name", None) - if name and isinstance(name, basestring) and name[0] != "<" and name[-1] != ">": - return os.path.basename(name) - - -def extract_zipped_paths(path): - """Replace nonexistent paths that look like they refer to a member of a zip - archive with the location of an extracted copy of the target, or else - just return the provided path unchanged. - """ - if os.path.exists(path): - # this is already a valid path, no need to do anything further - return path - - # find the first valid part of the provided path and treat that as a zip archive - # assume the rest of the path is the name of a member in the archive - archive, member = os.path.split(path) - while archive and not os.path.exists(archive): - archive, prefix = os.path.split(archive) - if not prefix: - # If we don't check for an empty prefix after the split (in other words, archive remains unchanged after the split), - # we _can_ end up in an infinite loop on a rare corner case affecting a small number of users - break - member = "/".join([prefix, member]) - - if not zipfile.is_zipfile(archive): - return path - - zip_file = zipfile.ZipFile(archive) - if member not in zip_file.namelist(): - return path - - # we have a valid zip archive and a valid member of that archive - tmp = tempfile.gettempdir() - extracted_path = os.path.join(tmp, member.split("/")[-1]) - if not os.path.exists(extracted_path): - # use read + write to avoid the creating nested folders, we only want the file, avoids mkdir racing condition - with atomic_open(extracted_path) as file_handler: - file_handler.write(zip_file.read(member)) - return extracted_path - - -@contextlib.contextmanager -def atomic_open(filename): - """Write a file to the disk in an atomic fashion""" - tmp_descriptor, tmp_name = tempfile.mkstemp(dir=os.path.dirname(filename)) - try: - with os.fdopen(tmp_descriptor, "wb") as tmp_handler: - yield tmp_handler - os.replace(tmp_name, filename) - except BaseException: - os.remove(tmp_name) - raise - - -def from_key_val_list(value): - """Take an object and test to see if it can be represented as a - dictionary. Unless it can not be represented as such, return an - OrderedDict, e.g., - - :: - - >>> from_key_val_list([('key', 'val')]) - OrderedDict([('key', 'val')]) - >>> from_key_val_list('string') - Traceback (most recent call last): - ... - ValueError: cannot encode objects that are not 2-tuples - >>> from_key_val_list({'key': 'val'}) - OrderedDict([('key', 'val')]) - - :rtype: OrderedDict - """ - if value is None: - return None - - if isinstance(value, (str, bytes, bool, int)): - raise ValueError("cannot encode objects that are not 2-tuples") - - return OrderedDict(value) - - -def to_key_val_list(value): - """Take an object and test to see if it can be represented as a - dictionary. If it can be, return a list of tuples, e.g., - - :: - - >>> to_key_val_list([('key', 'val')]) - [('key', 'val')] - >>> to_key_val_list({'key': 'val'}) - [('key', 'val')] - >>> to_key_val_list('string') - Traceback (most recent call last): - ... - ValueError: cannot encode objects that are not 2-tuples - - :rtype: list - """ - if value is None: - return None - - if isinstance(value, (str, bytes, bool, int)): - raise ValueError("cannot encode objects that are not 2-tuples") - - if isinstance(value, Mapping): - value = value.items() - - return list(value) - - -# From mitsuhiko/werkzeug (used with permission). -def parse_list_header(value): - """Parse lists as described by RFC 2068 Section 2. - - In particular, parse comma-separated lists where the elements of - the list may include quoted-strings. A quoted-string could - contain a comma. A non-quoted string could have quotes in the - middle. Quotes are removed automatically after parsing. - - It basically works like :func:`parse_set_header` just that items - may appear multiple times and case sensitivity is preserved. - - The return value is a standard :class:`list`: - - >>> parse_list_header('token, "quoted value"') - ['token', 'quoted value'] - - To create a header from the :class:`list` again, use the - :func:`dump_header` function. - - :param value: a string with a list header. - :return: :class:`list` - :rtype: list - """ - result = [] - for item in _parse_list_header(value): - if item[:1] == item[-1:] == '"': - item = unquote_header_value(item[1:-1]) - result.append(item) - return result - - -# From mitsuhiko/werkzeug (used with permission). -def parse_dict_header(value): - """Parse lists of key, value pairs as described by RFC 2068 Section 2 and - convert them into a python dict: - - >>> d = parse_dict_header('foo="is a fish", bar="as well"') - >>> type(d) is dict - True - >>> sorted(d.items()) - [('bar', 'as well'), ('foo', 'is a fish')] - - If there is no value for a key it will be `None`: - - >>> parse_dict_header('key_without_value') - {'key_without_value': None} - - To create a header from the :class:`dict` again, use the - :func:`dump_header` function. - - :param value: a string with a dict header. - :return: :class:`dict` - :rtype: dict - """ - result = {} - for item in _parse_list_header(value): - if "=" not in item: - result[item] = None - continue - name, value = item.split("=", 1) - if value[:1] == value[-1:] == '"': - value = unquote_header_value(value[1:-1]) - result[name] = value - return result - - -# From mitsuhiko/werkzeug (used with permission). -def unquote_header_value(value, is_filename=False): - r"""Unquotes a header value. (Reversal of :func:`quote_header_value`). - This does not use the real unquoting but what browsers are actually - using for quoting. - - :param value: the header value to unquote. - :rtype: str - """ - if value and value[0] == value[-1] == '"': - # this is not the real unquoting, but fixing this so that the - # RFC is met will result in bugs with internet explorer and - # probably some other browsers as well. IE for example is - # uploading files with "C:\foo\bar.txt" as filename - value = value[1:-1] - - # if this is a filename and the starting characters look like - # a UNC path, then just return the value without quotes. Using the - # replace sequence below on a UNC path has the effect of turning - # the leading double slash into a single slash and then - # _fix_ie_filename() doesn't work correctly. See #458. - if not is_filename or value[:2] != "\\\\": - return value.replace("\\\\", "\\").replace('\\"', '"') - return value - - -def dict_from_cookiejar(cj): - """Returns a key/value dictionary from a CookieJar. - - :param cj: CookieJar object to extract cookies from. - :rtype: dict - """ - - cookie_dict = {} - - for cookie in cj: - cookie_dict[cookie.name] = cookie.value - - return cookie_dict - - -def add_dict_to_cookiejar(cj, cookie_dict): - """Returns a CookieJar from a key/value dictionary. - - :param cj: CookieJar to insert cookies into. - :param cookie_dict: Dict of key/values to insert into CookieJar. - :rtype: CookieJar - """ - - return cookiejar_from_dict(cookie_dict, cj) - - -def get_encodings_from_content(content): - """Returns encodings from given content string. - - :param content: bytestring to extract encodings from. - """ - warnings.warn( - ( - "In requests 3.0, get_encodings_from_content will be removed. For " - "more information, please see the discussion on issue #2266. (This" - " warning should only appear once.)" - ), - DeprecationWarning, - ) - - charset_re = re.compile(r']', flags=re.I) - pragma_re = re.compile(r']', flags=re.I) - xml_re = re.compile(r'^<\?xml.*?encoding=["\']*(.+?)["\'>]') - - return ( - charset_re.findall(content) - + pragma_re.findall(content) - + xml_re.findall(content) - ) - - -def _parse_content_type_header(header): - """Returns content type and parameters from given header - - :param header: string - :return: tuple containing content type and dictionary of - parameters - """ - - tokens = header.split(";") - content_type, params = tokens[0].strip(), tokens[1:] - params_dict = {} - items_to_strip = "\"' " - - for param in params: - param = param.strip() - if param: - key, value = param, True - index_of_equals = param.find("=") - if index_of_equals != -1: - key = param[:index_of_equals].strip(items_to_strip) - value = param[index_of_equals + 1 :].strip(items_to_strip) - params_dict[key.lower()] = value - return content_type, params_dict - - -def get_encoding_from_headers(headers): - """Returns encodings from given HTTP Header Dict. - - :param headers: dictionary to extract encoding from. - :rtype: str - """ - - content_type = headers.get("content-type") - - if not content_type: - return None - - content_type, params = _parse_content_type_header(content_type) - - if "charset" in params: - return params["charset"].strip("'\"") - - if "text" in content_type: - return "ISO-8859-1" - - if "application/json" in content_type: - # Assume UTF-8 based on RFC 4627: https://www.ietf.org/rfc/rfc4627.txt since the charset was unset - return "utf-8" - - -def stream_decode_response_unicode(iterator, r): - """Stream decodes an iterator.""" - - if r.encoding is None: - yield from iterator - return - - decoder = codecs.getincrementaldecoder(r.encoding)(errors="replace") - for chunk in iterator: - rv = decoder.decode(chunk) - if rv: - yield rv - rv = decoder.decode(b"", final=True) - if rv: - yield rv - - -def iter_slices(string, slice_length): - """Iterate over slices of a string.""" - pos = 0 - if slice_length is None or slice_length <= 0: - slice_length = len(string) - while pos < len(string): - yield string[pos : pos + slice_length] - pos += slice_length - - -def get_unicode_from_response(r): - """Returns the requested content back in unicode. - - :param r: Response object to get unicode content from. - - Tried: - - 1. charset from content-type - 2. fall back and replace all unicode characters - - :rtype: str - """ - warnings.warn( - ( - "In requests 3.0, get_unicode_from_response will be removed. For " - "more information, please see the discussion on issue #2266. (This" - " warning should only appear once.)" - ), - DeprecationWarning, - ) - - tried_encodings = [] - - # Try charset from content-type - encoding = get_encoding_from_headers(r.headers) - - if encoding: - try: - return str(r.content, encoding) - except UnicodeError: - tried_encodings.append(encoding) - - # Fall back: - try: - return str(r.content, encoding, errors="replace") - except TypeError: - return r.content - - -# The unreserved URI characters (RFC 3986) -UNRESERVED_SET = frozenset( - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + "0123456789-._~" -) - - -def unquote_unreserved(uri): - """Un-escape any percent-escape sequences in a URI that are unreserved - characters. This leaves all reserved, illegal and non-ASCII bytes encoded. - - :rtype: str - """ - parts = uri.split("%") - for i in range(1, len(parts)): - h = parts[i][0:2] - if len(h) == 2 and h.isalnum(): - try: - c = chr(int(h, 16)) - except ValueError: - raise InvalidURL(f"Invalid percent-escape sequence: '{h}'") - - if c in UNRESERVED_SET: - parts[i] = c + parts[i][2:] - else: - parts[i] = f"%{parts[i]}" - else: - parts[i] = f"%{parts[i]}" - return "".join(parts) - - -def requote_uri(uri): - """Re-quote the given URI. - - This function passes the given URI through an unquote/quote cycle to - ensure that it is fully and consistently quoted. - - :rtype: str - """ - safe_with_percent = "!#$%&'()*+,/:;=?@[]~" - safe_without_percent = "!#$&'()*+,/:;=?@[]~" - try: - # Unquote only the unreserved characters - # Then quote only illegal characters (do not quote reserved, - # unreserved, or '%') - return quote(unquote_unreserved(uri), safe=safe_with_percent) - except InvalidURL: - # We couldn't unquote the given URI, so let's try quoting it, but - # there may be unquoted '%'s in the URI. We need to make sure they're - # properly quoted so they do not cause issues elsewhere. - return quote(uri, safe=safe_without_percent) - - -def address_in_network(ip, net): - """This function allows you to check if an IP belongs to a network subnet - - Example: returns True if ip = 192.168.1.1 and net = 192.168.1.0/24 - returns False if ip = 192.168.1.1 and net = 192.168.100.0/24 - - :rtype: bool - """ - ipaddr = struct.unpack("=L", socket.inet_aton(ip))[0] - netaddr, bits = net.split("/") - netmask = struct.unpack("=L", socket.inet_aton(dotted_netmask(int(bits))))[0] - network = struct.unpack("=L", socket.inet_aton(netaddr))[0] & netmask - return (ipaddr & netmask) == (network & netmask) - - -def dotted_netmask(mask): - """Converts mask from /xx format to xxx.xxx.xxx.xxx - - Example: if mask is 24 function returns 255.255.255.0 - - :rtype: str - """ - bits = 0xFFFFFFFF ^ (1 << 32 - mask) - 1 - return socket.inet_ntoa(struct.pack(">I", bits)) - - -def is_ipv4_address(string_ip): - """ - :rtype: bool - """ - try: - socket.inet_aton(string_ip) - except OSError: - return False - return True - - -def is_valid_cidr(string_network): - """ - Very simple check of the cidr format in no_proxy variable. - - :rtype: bool - """ - if string_network.count("/") == 1: - try: - mask = int(string_network.split("/")[1]) - except ValueError: - return False - - if mask < 1 or mask > 32: - return False - - try: - socket.inet_aton(string_network.split("/")[0]) - except OSError: - return False - else: - return False - return True - - -@contextlib.contextmanager -def set_environ(env_name, value): - """Set the environment variable 'env_name' to 'value' - - Save previous value, yield, and then restore the previous value stored in - the environment variable 'env_name'. - - If 'value' is None, do nothing""" - value_changed = value is not None - if value_changed: - old_value = os.environ.get(env_name) - os.environ[env_name] = value - try: - yield - finally: - if value_changed: - if old_value is None: - del os.environ[env_name] - else: - os.environ[env_name] = old_value - - -def should_bypass_proxies(url, no_proxy): - """ - Returns whether we should bypass proxies or not. - - :rtype: bool - """ - # Prioritize lowercase environment variables over uppercase - # to keep a consistent behaviour with other http projects (curl, wget). - def get_proxy(key): - return os.environ.get(key) or os.environ.get(key.upper()) - - # First check whether no_proxy is defined. If it is, check that the URL - # we're getting isn't in the no_proxy list. - no_proxy_arg = no_proxy - if no_proxy is None: - no_proxy = get_proxy("no_proxy") - parsed = urlparse(url) - - if parsed.hostname is None: - # URLs don't always have hostnames, e.g. file:/// urls. - return True - - if no_proxy: - # We need to check whether we match here. We need to see if we match - # the end of the hostname, both with and without the port. - no_proxy = (host for host in no_proxy.replace(" ", "").split(",") if host) - - if is_ipv4_address(parsed.hostname): - for proxy_ip in no_proxy: - if is_valid_cidr(proxy_ip): - if address_in_network(parsed.hostname, proxy_ip): - return True - elif parsed.hostname == proxy_ip: - # If no_proxy ip was defined in plain IP notation instead of cidr notation & - # matches the IP of the index - return True - else: - host_with_port = parsed.hostname - if parsed.port: - host_with_port += f":{parsed.port}" - - for host in no_proxy: - if parsed.hostname.endswith(host) or host_with_port.endswith(host): - # The URL does match something in no_proxy, so we don't want - # to apply the proxies on this URL. - return True - - with set_environ("no_proxy", no_proxy_arg): - # parsed.hostname can be `None` in cases such as a file URI. - try: - bypass = proxy_bypass(parsed.hostname) - except (TypeError, socket.gaierror): - bypass = False - - if bypass: - return True - - return False - - -def get_environ_proxies(url, no_proxy=None): - """ - Return a dict of environment proxies. - - :rtype: dict - """ - if should_bypass_proxies(url, no_proxy=no_proxy): - return {} - else: - return getproxies() - - -def select_proxy(url, proxies): - """Select a proxy for the url, if applicable. - - :param url: The url being for the request - :param proxies: A dictionary of schemes or schemes and hosts to proxy URLs - """ - proxies = proxies or {} - urlparts = urlparse(url) - if urlparts.hostname is None: - return proxies.get(urlparts.scheme, proxies.get("all")) - - proxy_keys = [ - urlparts.scheme + "://" + urlparts.hostname, - urlparts.scheme, - "all://" + urlparts.hostname, - "all", - ] - proxy = None - for proxy_key in proxy_keys: - if proxy_key in proxies: - proxy = proxies[proxy_key] - break - - return proxy - - -def resolve_proxies(request, proxies, trust_env=True): - """This method takes proxy information from a request and configuration - input to resolve a mapping of target proxies. This will consider settings - such a NO_PROXY to strip proxy configurations. - - :param request: Request or PreparedRequest - :param proxies: A dictionary of schemes or schemes and hosts to proxy URLs - :param trust_env: Boolean declaring whether to trust environment configs - - :rtype: dict - """ - proxies = proxies if proxies is not None else {} - url = request.url - scheme = urlparse(url).scheme - no_proxy = proxies.get("no_proxy") - new_proxies = proxies.copy() - - if trust_env and not should_bypass_proxies(url, no_proxy=no_proxy): - environ_proxies = get_environ_proxies(url, no_proxy=no_proxy) - - proxy = environ_proxies.get(scheme, environ_proxies.get("all")) - - if proxy: - new_proxies.setdefault(scheme, proxy) - return new_proxies - - -def default_user_agent(name="python-requests"): - """ - Return a string representing the default user agent. - - :rtype: str - """ - return f"{name}/{__version__}" - - -def default_headers(): - """ - :rtype: requests.structures.CaseInsensitiveDict - """ - return CaseInsensitiveDict( - { - "User-Agent": default_user_agent(), - "Accept-Encoding": DEFAULT_ACCEPT_ENCODING, - "Accept": "*/*", - "Connection": "keep-alive", - } - ) - - -def parse_header_links(value): - """Return a list of parsed link headers proxies. - - i.e. Link: ; rel=front; type="image/jpeg",; rel=back;type="image/jpeg" - - :rtype: list - """ - - links = [] - - replace_chars = " '\"" - - value = value.strip(replace_chars) - if not value: - return links - - for val in re.split(", *<", value): - try: - url, params = val.split(";", 1) - except ValueError: - url, params = val, "" - - link = {"url": url.strip("<> '\"")} - - for param in params.split(";"): - try: - key, value = param.split("=") - except ValueError: - break - - link[key.strip(replace_chars)] = value.strip(replace_chars) - - links.append(link) - - return links - - -# Null bytes; no need to recreate these on each call to guess_json_utf -_null = "\x00".encode("ascii") # encoding to ASCII for Python 3 -_null2 = _null * 2 -_null3 = _null * 3 - - -def guess_json_utf(data): - """ - :rtype: str - """ - # JSON always starts with two ASCII characters, so detection is as - # easy as counting the nulls and from their location and count - # determine the encoding. Also detect a BOM, if present. - sample = data[:4] - if sample in (codecs.BOM_UTF32_LE, codecs.BOM_UTF32_BE): - return "utf-32" # BOM included - if sample[:3] == codecs.BOM_UTF8: - return "utf-8-sig" # BOM included, MS style (discouraged) - if sample[:2] in (codecs.BOM_UTF16_LE, codecs.BOM_UTF16_BE): - return "utf-16" # BOM included - nullcount = sample.count(_null) - if nullcount == 0: - return "utf-8" - if nullcount == 2: - if sample[::2] == _null2: # 1st and 3rd are null - return "utf-16-be" - if sample[1::2] == _null2: # 2nd and 4th are null - return "utf-16-le" - # Did not detect 2 valid UTF-16 ascii-range characters - if nullcount == 3: - if sample[:3] == _null3: - return "utf-32-be" - if sample[1:] == _null3: - return "utf-32-le" - # Did not detect a valid UTF-32 ascii-range character - return None - - -def prepend_scheme_if_needed(url, new_scheme): - """Given a URL that may or may not have a scheme, prepend the given scheme. - Does not replace a present scheme with the one provided as an argument. - - :rtype: str - """ - parsed = parse_url(url) - scheme, auth, host, port, path, query, fragment = parsed - - # A defect in urlparse determines that there isn't a netloc present in some - # urls. We previously assumed parsing was overly cautious, and swapped the - # netloc and path. Due to a lack of tests on the original defect, this is - # maintained with parse_url for backwards compatibility. - netloc = parsed.netloc - if not netloc: - netloc, path = path, netloc - - if auth: - # parse_url doesn't provide the netloc with auth - # so we'll add it ourselves. - netloc = "@".join([auth, netloc]) - if scheme is None: - scheme = new_scheme - if path is None: - path = "" - - return urlunparse((scheme, netloc, path, "", query, fragment)) - - -def get_auth_from_url(url): - """Given a url with authentication components, extract them into a tuple of - username,password. - - :rtype: (str,str) - """ - parsed = urlparse(url) - - try: - auth = (unquote(parsed.username), unquote(parsed.password)) - except (AttributeError, TypeError): - auth = ("", "") - - return auth - - -def check_header_validity(header): - """Verifies that header parts don't contain leading whitespace - reserved characters, or return characters. - - :param header: tuple, in the format (name, value). - """ - name, value = header - _validate_header_part(header, name, 0) - _validate_header_part(header, value, 1) - - -def _validate_header_part(header, header_part, header_validator_index): - if isinstance(header_part, str): - validator = _HEADER_VALIDATORS_STR[header_validator_index] - elif isinstance(header_part, bytes): - validator = _HEADER_VALIDATORS_BYTE[header_validator_index] - else: - raise InvalidHeader( - f"Header part ({header_part!r}) from {header} " - f"must be of type str or bytes, not {type(header_part)}" - ) - - if not validator.match(header_part): - header_kind = "name" if header_validator_index == 0 else "value" - raise InvalidHeader( - f"Invalid leading whitespace, reserved character(s), or return" - f"character(s) in header {header_kind}: {header_part!r}" - ) - - -def urldefragauth(url): - """ - Given a url remove the fragment and the authentication part. - - :rtype: str - """ - scheme, netloc, path, params, query, fragment = urlparse(url) - - # see func:`prepend_scheme_if_needed` - if not netloc: - netloc, path = path, netloc - - netloc = netloc.rsplit("@", 1)[-1] - - return urlunparse((scheme, netloc, path, params, query, "")) - - -def rewind_body(prepared_request): - """Move file pointer back to its recorded starting position - so it can be read again on redirect. - """ - body_seek = getattr(prepared_request.body, "seek", None) - if body_seek is not None and isinstance( - prepared_request._body_position, integer_types - ): - try: - body_seek(prepared_request._body_position) - except OSError: - raise UnrewindableBodyError( - "An error occurred when rewinding request body for redirect." - ) - else: - raise UnrewindableBodyError("Unable to rewind request body for redirect.")