99import inspect
1010import logging
1111import platform
12+ import warnings
1213import email .utils
1314from types import TracebackType
1415from random import random
5152 ResponseT ,
5253 AnyMapping ,
5354 PostParser ,
55+ BinaryTypes ,
5456 RequestFiles ,
5557 HttpxSendArgs ,
5658 RequestOptions ,
59+ AsyncBinaryTypes ,
5760 HttpxRequestFiles ,
5861 ModelBuilderProtocol ,
5962 not_given ,
@@ -479,8 +482,19 @@ def _build_request(
479482 retries_taken : int = 0 ,
480483 ) -> httpx .Request :
481484 if log .isEnabledFor (logging .DEBUG ):
482- log .debug ("Request options: %s" , model_dump (options , exclude_unset = True ))
483-
485+ log .debug (
486+ "Request options: %s" ,
487+ model_dump (
488+ options ,
489+ exclude_unset = True ,
490+ # Pydantic v1 can't dump every type we support in content, so we exclude it for now.
491+ exclude = {
492+ "content" ,
493+ }
494+ if PYDANTIC_V1
495+ else {},
496+ ),
497+ )
484498 kwargs : dict [str , Any ] = {}
485499
486500 json_data = options .json_data
@@ -534,7 +548,13 @@ def _build_request(
534548 is_body_allowed = options .method .lower () != "get"
535549
536550 if is_body_allowed :
537- if isinstance (json_data , bytes ):
551+ if options .content is not None and json_data is not None :
552+ raise TypeError ("Passing both `content` and `json_data` is not supported" )
553+ if options .content is not None and files is not None :
554+ raise TypeError ("Passing both `content` and `files` is not supported" )
555+ if options .content is not None :
556+ kwargs ["content" ] = options .content
557+ elif isinstance (json_data , bytes ):
538558 kwargs ["content" ] = json_data
539559 else :
540560 kwargs ["json" ] = json_data if is_given (json_data ) else None
@@ -1211,6 +1231,7 @@ def post(
12111231 * ,
12121232 cast_to : Type [ResponseT ],
12131233 body : Body | None = None ,
1234+ content : BinaryTypes | None = None ,
12141235 options : RequestOptions = {},
12151236 files : RequestFiles | None = None ,
12161237 stream : Literal [False ] = False ,
@@ -1223,6 +1244,7 @@ def post(
12231244 * ,
12241245 cast_to : Type [ResponseT ],
12251246 body : Body | None = None ,
1247+ content : BinaryTypes | None = None ,
12261248 options : RequestOptions = {},
12271249 files : RequestFiles | None = None ,
12281250 stream : Literal [True ],
@@ -1236,6 +1258,7 @@ def post(
12361258 * ,
12371259 cast_to : Type [ResponseT ],
12381260 body : Body | None = None ,
1261+ content : BinaryTypes | None = None ,
12391262 options : RequestOptions = {},
12401263 files : RequestFiles | None = None ,
12411264 stream : bool ,
@@ -1248,13 +1271,25 @@ def post(
12481271 * ,
12491272 cast_to : Type [ResponseT ],
12501273 body : Body | None = None ,
1274+ content : BinaryTypes | None = None ,
12511275 options : RequestOptions = {},
12521276 files : RequestFiles | None = None ,
12531277 stream : bool = False ,
12541278 stream_cls : type [_StreamT ] | None = None ,
12551279 ) -> ResponseT | _StreamT :
1280+ if body is not None and content is not None :
1281+ raise TypeError ("Passing both `body` and `content` is not supported" )
1282+ if files is not None and content is not None :
1283+ raise TypeError ("Passing both `files` and `content` is not supported" )
1284+ if isinstance (body , bytes ):
1285+ warnings .warn (
1286+ "Passing raw bytes as `body` is deprecated and will be removed in a future version. "
1287+ "Please pass raw bytes via the `content` parameter instead." ,
1288+ DeprecationWarning ,
1289+ stacklevel = 2 ,
1290+ )
12561291 opts = FinalRequestOptions .construct (
1257- method = "post" , url = path , json_data = body , files = to_httpx_files (files ), ** options
1292+ method = "post" , url = path , json_data = body , content = content , files = to_httpx_files (files ), ** options
12581293 )
12591294 return cast (ResponseT , self .request (cast_to , opts , stream = stream , stream_cls = stream_cls ))
12601295
@@ -1264,11 +1299,23 @@ def patch(
12641299 * ,
12651300 cast_to : Type [ResponseT ],
12661301 body : Body | None = None ,
1302+ content : BinaryTypes | None = None ,
12671303 files : RequestFiles | None = None ,
12681304 options : RequestOptions = {},
12691305 ) -> ResponseT :
1306+ if body is not None and content is not None :
1307+ raise TypeError ("Passing both `body` and `content` is not supported" )
1308+ if files is not None and content is not None :
1309+ raise TypeError ("Passing both `files` and `content` is not supported" )
1310+ if isinstance (body , bytes ):
1311+ warnings .warn (
1312+ "Passing raw bytes as `body` is deprecated and will be removed in a future version. "
1313+ "Please pass raw bytes via the `content` parameter instead." ,
1314+ DeprecationWarning ,
1315+ stacklevel = 2 ,
1316+ )
12701317 opts = FinalRequestOptions .construct (
1271- method = "patch" , url = path , json_data = body , files = to_httpx_files (files ), ** options
1318+ method = "patch" , url = path , json_data = body , content = content , files = to_httpx_files (files ), ** options
12721319 )
12731320 return self .request (cast_to , opts )
12741321
@@ -1278,11 +1325,23 @@ def put(
12781325 * ,
12791326 cast_to : Type [ResponseT ],
12801327 body : Body | None = None ,
1328+ content : BinaryTypes | None = None ,
12811329 files : RequestFiles | None = None ,
12821330 options : RequestOptions = {},
12831331 ) -> ResponseT :
1332+ if body is not None and content is not None :
1333+ raise TypeError ("Passing both `body` and `content` is not supported" )
1334+ if files is not None and content is not None :
1335+ raise TypeError ("Passing both `files` and `content` is not supported" )
1336+ if isinstance (body , bytes ):
1337+ warnings .warn (
1338+ "Passing raw bytes as `body` is deprecated and will be removed in a future version. "
1339+ "Please pass raw bytes via the `content` parameter instead." ,
1340+ DeprecationWarning ,
1341+ stacklevel = 2 ,
1342+ )
12841343 opts = FinalRequestOptions .construct (
1285- method = "put" , url = path , json_data = body , files = to_httpx_files (files ), ** options
1344+ method = "put" , url = path , json_data = body , content = content , files = to_httpx_files (files ), ** options
12861345 )
12871346 return self .request (cast_to , opts )
12881347
@@ -1292,9 +1351,19 @@ def delete(
12921351 * ,
12931352 cast_to : Type [ResponseT ],
12941353 body : Body | None = None ,
1354+ content : BinaryTypes | None = None ,
12951355 options : RequestOptions = {},
12961356 ) -> ResponseT :
1297- opts = FinalRequestOptions .construct (method = "delete" , url = path , json_data = body , ** options )
1357+ if body is not None and content is not None :
1358+ raise TypeError ("Passing both `body` and `content` is not supported" )
1359+ if isinstance (body , bytes ):
1360+ warnings .warn (
1361+ "Passing raw bytes as `body` is deprecated and will be removed in a future version. "
1362+ "Please pass raw bytes via the `content` parameter instead." ,
1363+ DeprecationWarning ,
1364+ stacklevel = 2 ,
1365+ )
1366+ opts = FinalRequestOptions .construct (method = "delete" , url = path , json_data = body , content = content , ** options )
12981367 return self .request (cast_to , opts )
12991368
13001369 def get_api_list (
@@ -1749,6 +1818,7 @@ async def post(
17491818 * ,
17501819 cast_to : Type [ResponseT ],
17511820 body : Body | None = None ,
1821+ content : AsyncBinaryTypes | None = None ,
17521822 files : RequestFiles | None = None ,
17531823 options : RequestOptions = {},
17541824 stream : Literal [False ] = False ,
@@ -1761,6 +1831,7 @@ async def post(
17611831 * ,
17621832 cast_to : Type [ResponseT ],
17631833 body : Body | None = None ,
1834+ content : AsyncBinaryTypes | None = None ,
17641835 files : RequestFiles | None = None ,
17651836 options : RequestOptions = {},
17661837 stream : Literal [True ],
@@ -1774,6 +1845,7 @@ async def post(
17741845 * ,
17751846 cast_to : Type [ResponseT ],
17761847 body : Body | None = None ,
1848+ content : AsyncBinaryTypes | None = None ,
17771849 files : RequestFiles | None = None ,
17781850 options : RequestOptions = {},
17791851 stream : bool ,
@@ -1786,13 +1858,25 @@ async def post(
17861858 * ,
17871859 cast_to : Type [ResponseT ],
17881860 body : Body | None = None ,
1861+ content : AsyncBinaryTypes | None = None ,
17891862 files : RequestFiles | None = None ,
17901863 options : RequestOptions = {},
17911864 stream : bool = False ,
17921865 stream_cls : type [_AsyncStreamT ] | None = None ,
17931866 ) -> ResponseT | _AsyncStreamT :
1867+ if body is not None and content is not None :
1868+ raise TypeError ("Passing both `body` and `content` is not supported" )
1869+ if files is not None and content is not None :
1870+ raise TypeError ("Passing both `files` and `content` is not supported" )
1871+ if isinstance (body , bytes ):
1872+ warnings .warn (
1873+ "Passing raw bytes as `body` is deprecated and will be removed in a future version. "
1874+ "Please pass raw bytes via the `content` parameter instead." ,
1875+ DeprecationWarning ,
1876+ stacklevel = 2 ,
1877+ )
17941878 opts = FinalRequestOptions .construct (
1795- method = "post" , url = path , json_data = body , files = await async_to_httpx_files (files ), ** options
1879+ method = "post" , url = path , json_data = body , content = content , files = await async_to_httpx_files (files ), ** options
17961880 )
17971881 return await self .request (cast_to , opts , stream = stream , stream_cls = stream_cls )
17981882
@@ -1802,11 +1886,28 @@ async def patch(
18021886 * ,
18031887 cast_to : Type [ResponseT ],
18041888 body : Body | None = None ,
1889+ content : AsyncBinaryTypes | None = None ,
18051890 files : RequestFiles | None = None ,
18061891 options : RequestOptions = {},
18071892 ) -> ResponseT :
1893+ if body is not None and content is not None :
1894+ raise TypeError ("Passing both `body` and `content` is not supported" )
1895+ if files is not None and content is not None :
1896+ raise TypeError ("Passing both `files` and `content` is not supported" )
1897+ if isinstance (body , bytes ):
1898+ warnings .warn (
1899+ "Passing raw bytes as `body` is deprecated and will be removed in a future version. "
1900+ "Please pass raw bytes via the `content` parameter instead." ,
1901+ DeprecationWarning ,
1902+ stacklevel = 2 ,
1903+ )
18081904 opts = FinalRequestOptions .construct (
1809- method = "patch" , url = path , json_data = body , files = await async_to_httpx_files (files ), ** options
1905+ method = "patch" ,
1906+ url = path ,
1907+ json_data = body ,
1908+ content = content ,
1909+ files = await async_to_httpx_files (files ),
1910+ ** options ,
18101911 )
18111912 return await self .request (cast_to , opts )
18121913
@@ -1816,11 +1917,23 @@ async def put(
18161917 * ,
18171918 cast_to : Type [ResponseT ],
18181919 body : Body | None = None ,
1920+ content : AsyncBinaryTypes | None = None ,
18191921 files : RequestFiles | None = None ,
18201922 options : RequestOptions = {},
18211923 ) -> ResponseT :
1924+ if body is not None and content is not None :
1925+ raise TypeError ("Passing both `body` and `content` is not supported" )
1926+ if files is not None and content is not None :
1927+ raise TypeError ("Passing both `files` and `content` is not supported" )
1928+ if isinstance (body , bytes ):
1929+ warnings .warn (
1930+ "Passing raw bytes as `body` is deprecated and will be removed in a future version. "
1931+ "Please pass raw bytes via the `content` parameter instead." ,
1932+ DeprecationWarning ,
1933+ stacklevel = 2 ,
1934+ )
18221935 opts = FinalRequestOptions .construct (
1823- method = "put" , url = path , json_data = body , files = await async_to_httpx_files (files ), ** options
1936+ method = "put" , url = path , json_data = body , content = content , files = await async_to_httpx_files (files ), ** options
18241937 )
18251938 return await self .request (cast_to , opts )
18261939
@@ -1830,9 +1943,19 @@ async def delete(
18301943 * ,
18311944 cast_to : Type [ResponseT ],
18321945 body : Body | None = None ,
1946+ content : AsyncBinaryTypes | None = None ,
18331947 options : RequestOptions = {},
18341948 ) -> ResponseT :
1835- opts = FinalRequestOptions .construct (method = "delete" , url = path , json_data = body , ** options )
1949+ if body is not None and content is not None :
1950+ raise TypeError ("Passing both `body` and `content` is not supported" )
1951+ if isinstance (body , bytes ):
1952+ warnings .warn (
1953+ "Passing raw bytes as `body` is deprecated and will be removed in a future version. "
1954+ "Please pass raw bytes via the `content` parameter instead." ,
1955+ DeprecationWarning ,
1956+ stacklevel = 2 ,
1957+ )
1958+ opts = FinalRequestOptions .construct (method = "delete" , url = path , json_data = body , content = content , ** options )
18361959 return await self .request (cast_to , opts )
18371960
18381961 def get_api_list (
0 commit comments