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 ,
@@ -478,8 +481,19 @@ def _build_request(
478481 retries_taken : int = 0 ,
479482 ) -> httpx .Request :
480483 if log .isEnabledFor (logging .DEBUG ):
481- log .debug ("Request options: %s" , model_dump (options , exclude_unset = True ))
482-
484+ log .debug (
485+ "Request options: %s" ,
486+ model_dump (
487+ options ,
488+ exclude_unset = True ,
489+ # Pydantic v1 can't dump every type we support in content, so we exclude it for now.
490+ exclude = {
491+ "content" ,
492+ }
493+ if PYDANTIC_V1
494+ else {},
495+ ),
496+ )
483497 kwargs : dict [str , Any ] = {}
484498
485499 json_data = options .json_data
@@ -533,7 +547,13 @@ def _build_request(
533547 is_body_allowed = options .method .lower () != "get"
534548
535549 if is_body_allowed :
536- if isinstance (json_data , bytes ):
550+ if options .content is not None and json_data is not None :
551+ raise TypeError ("Passing both `content` and `json_data` is not supported" )
552+ if options .content is not None and files is not None :
553+ raise TypeError ("Passing both `content` and `files` is not supported" )
554+ if options .content is not None :
555+ kwargs ["content" ] = options .content
556+ elif isinstance (json_data , bytes ):
537557 kwargs ["content" ] = json_data
538558 else :
539559 kwargs ["json" ] = json_data if is_given (json_data ) else None
@@ -1209,6 +1229,7 @@ def post(
12091229 * ,
12101230 cast_to : Type [ResponseT ],
12111231 body : Body | None = None ,
1232+ content : BinaryTypes | None = None ,
12121233 options : RequestOptions = {},
12131234 files : RequestFiles | None = None ,
12141235 stream : Literal [False ] = False ,
@@ -1221,6 +1242,7 @@ def post(
12211242 * ,
12221243 cast_to : Type [ResponseT ],
12231244 body : Body | None = None ,
1245+ content : BinaryTypes | None = None ,
12241246 options : RequestOptions = {},
12251247 files : RequestFiles | None = None ,
12261248 stream : Literal [True ],
@@ -1234,6 +1256,7 @@ def post(
12341256 * ,
12351257 cast_to : Type [ResponseT ],
12361258 body : Body | None = None ,
1259+ content : BinaryTypes | None = None ,
12371260 options : RequestOptions = {},
12381261 files : RequestFiles | None = None ,
12391262 stream : bool ,
@@ -1246,13 +1269,25 @@ def post(
12461269 * ,
12471270 cast_to : Type [ResponseT ],
12481271 body : Body | None = None ,
1272+ content : BinaryTypes | None = None ,
12491273 options : RequestOptions = {},
12501274 files : RequestFiles | None = None ,
12511275 stream : bool = False ,
12521276 stream_cls : type [_StreamT ] | None = None ,
12531277 ) -> ResponseT | _StreamT :
1278+ if body is not None and content is not None :
1279+ raise TypeError ("Passing both `body` and `content` is not supported" )
1280+ if files is not None and content is not None :
1281+ raise TypeError ("Passing both `files` and `content` is not supported" )
1282+ if isinstance (body , bytes ):
1283+ warnings .warn (
1284+ "Passing raw bytes as `body` is deprecated and will be removed in a future version. "
1285+ "Please pass raw bytes via the `content` parameter instead." ,
1286+ DeprecationWarning ,
1287+ stacklevel = 2 ,
1288+ )
12541289 opts = FinalRequestOptions .construct (
1255- method = "post" , url = path , json_data = body , files = to_httpx_files (files ), ** options
1290+ method = "post" , url = path , json_data = body , content = content , files = to_httpx_files (files ), ** options
12561291 )
12571292 return cast (ResponseT , self .request (cast_to , opts , stream = stream , stream_cls = stream_cls ))
12581293
@@ -1262,11 +1297,23 @@ def patch(
12621297 * ,
12631298 cast_to : Type [ResponseT ],
12641299 body : Body | None = None ,
1300+ content : BinaryTypes | None = None ,
12651301 files : RequestFiles | None = None ,
12661302 options : RequestOptions = {},
12671303 ) -> ResponseT :
1304+ if body is not None and content is not None :
1305+ raise TypeError ("Passing both `body` and `content` is not supported" )
1306+ if files is not None and content is not None :
1307+ raise TypeError ("Passing both `files` and `content` is not supported" )
1308+ if isinstance (body , bytes ):
1309+ warnings .warn (
1310+ "Passing raw bytes as `body` is deprecated and will be removed in a future version. "
1311+ "Please pass raw bytes via the `content` parameter instead." ,
1312+ DeprecationWarning ,
1313+ stacklevel = 2 ,
1314+ )
12681315 opts = FinalRequestOptions .construct (
1269- method = "patch" , url = path , json_data = body , files = to_httpx_files (files ), ** options
1316+ method = "patch" , url = path , json_data = body , content = content , files = to_httpx_files (files ), ** options
12701317 )
12711318 return self .request (cast_to , opts )
12721319
@@ -1276,11 +1323,23 @@ def put(
12761323 * ,
12771324 cast_to : Type [ResponseT ],
12781325 body : Body | None = None ,
1326+ content : BinaryTypes | None = None ,
12791327 files : RequestFiles | None = None ,
12801328 options : RequestOptions = {},
12811329 ) -> ResponseT :
1330+ if body is not None and content is not None :
1331+ raise TypeError ("Passing both `body` and `content` is not supported" )
1332+ if files is not None and content is not None :
1333+ raise TypeError ("Passing both `files` and `content` is not supported" )
1334+ if isinstance (body , bytes ):
1335+ warnings .warn (
1336+ "Passing raw bytes as `body` is deprecated and will be removed in a future version. "
1337+ "Please pass raw bytes via the `content` parameter instead." ,
1338+ DeprecationWarning ,
1339+ stacklevel = 2 ,
1340+ )
12821341 opts = FinalRequestOptions .construct (
1283- method = "put" , url = path , json_data = body , files = to_httpx_files (files ), ** options
1342+ method = "put" , url = path , json_data = body , content = content , files = to_httpx_files (files ), ** options
12841343 )
12851344 return self .request (cast_to , opts )
12861345
@@ -1290,9 +1349,19 @@ def delete(
12901349 * ,
12911350 cast_to : Type [ResponseT ],
12921351 body : Body | None = None ,
1352+ content : BinaryTypes | None = None ,
12931353 options : RequestOptions = {},
12941354 ) -> ResponseT :
1295- opts = FinalRequestOptions .construct (method = "delete" , url = path , json_data = body , ** options )
1355+ if body is not None and content is not None :
1356+ raise TypeError ("Passing both `body` and `content` is not supported" )
1357+ if isinstance (body , bytes ):
1358+ warnings .warn (
1359+ "Passing raw bytes as `body` is deprecated and will be removed in a future version. "
1360+ "Please pass raw bytes via the `content` parameter instead." ,
1361+ DeprecationWarning ,
1362+ stacklevel = 2 ,
1363+ )
1364+ opts = FinalRequestOptions .construct (method = "delete" , url = path , json_data = body , content = content , ** options )
12961365 return self .request (cast_to , opts )
12971366
12981367 def get_api_list (
@@ -1746,6 +1815,7 @@ async def post(
17461815 * ,
17471816 cast_to : Type [ResponseT ],
17481817 body : Body | None = None ,
1818+ content : AsyncBinaryTypes | None = None ,
17491819 files : RequestFiles | None = None ,
17501820 options : RequestOptions = {},
17511821 stream : Literal [False ] = False ,
@@ -1758,6 +1828,7 @@ async def post(
17581828 * ,
17591829 cast_to : Type [ResponseT ],
17601830 body : Body | None = None ,
1831+ content : AsyncBinaryTypes | None = None ,
17611832 files : RequestFiles | None = None ,
17621833 options : RequestOptions = {},
17631834 stream : Literal [True ],
@@ -1771,6 +1842,7 @@ async def post(
17711842 * ,
17721843 cast_to : Type [ResponseT ],
17731844 body : Body | None = None ,
1845+ content : AsyncBinaryTypes | None = None ,
17741846 files : RequestFiles | None = None ,
17751847 options : RequestOptions = {},
17761848 stream : bool ,
@@ -1783,13 +1855,25 @@ async def post(
17831855 * ,
17841856 cast_to : Type [ResponseT ],
17851857 body : Body | None = None ,
1858+ content : AsyncBinaryTypes | None = None ,
17861859 files : RequestFiles | None = None ,
17871860 options : RequestOptions = {},
17881861 stream : bool = False ,
17891862 stream_cls : type [_AsyncStreamT ] | None = None ,
17901863 ) -> ResponseT | _AsyncStreamT :
1864+ if body is not None and content is not None :
1865+ raise TypeError ("Passing both `body` and `content` is not supported" )
1866+ if files is not None and content is not None :
1867+ raise TypeError ("Passing both `files` and `content` is not supported" )
1868+ if isinstance (body , bytes ):
1869+ warnings .warn (
1870+ "Passing raw bytes as `body` is deprecated and will be removed in a future version. "
1871+ "Please pass raw bytes via the `content` parameter instead." ,
1872+ DeprecationWarning ,
1873+ stacklevel = 2 ,
1874+ )
17911875 opts = FinalRequestOptions .construct (
1792- method = "post" , url = path , json_data = body , files = await async_to_httpx_files (files ), ** options
1876+ method = "post" , url = path , json_data = body , content = content , files = await async_to_httpx_files (files ), ** options
17931877 )
17941878 return await self .request (cast_to , opts , stream = stream , stream_cls = stream_cls )
17951879
@@ -1799,11 +1883,28 @@ async def patch(
17991883 * ,
18001884 cast_to : Type [ResponseT ],
18011885 body : Body | None = None ,
1886+ content : AsyncBinaryTypes | None = None ,
18021887 files : RequestFiles | None = None ,
18031888 options : RequestOptions = {},
18041889 ) -> ResponseT :
1890+ if body is not None and content is not None :
1891+ raise TypeError ("Passing both `body` and `content` is not supported" )
1892+ if files is not None and content is not None :
1893+ raise TypeError ("Passing both `files` and `content` is not supported" )
1894+ if isinstance (body , bytes ):
1895+ warnings .warn (
1896+ "Passing raw bytes as `body` is deprecated and will be removed in a future version. "
1897+ "Please pass raw bytes via the `content` parameter instead." ,
1898+ DeprecationWarning ,
1899+ stacklevel = 2 ,
1900+ )
18051901 opts = FinalRequestOptions .construct (
1806- method = "patch" , url = path , json_data = body , files = await async_to_httpx_files (files ), ** options
1902+ method = "patch" ,
1903+ url = path ,
1904+ json_data = body ,
1905+ content = content ,
1906+ files = await async_to_httpx_files (files ),
1907+ ** options ,
18071908 )
18081909 return await self .request (cast_to , opts )
18091910
@@ -1813,11 +1914,23 @@ async def put(
18131914 * ,
18141915 cast_to : Type [ResponseT ],
18151916 body : Body | None = None ,
1917+ content : AsyncBinaryTypes | None = None ,
18161918 files : RequestFiles | None = None ,
18171919 options : RequestOptions = {},
18181920 ) -> ResponseT :
1921+ if body is not None and content is not None :
1922+ raise TypeError ("Passing both `body` and `content` is not supported" )
1923+ if files is not None and content is not None :
1924+ raise TypeError ("Passing both `files` and `content` is not supported" )
1925+ if isinstance (body , bytes ):
1926+ warnings .warn (
1927+ "Passing raw bytes as `body` is deprecated and will be removed in a future version. "
1928+ "Please pass raw bytes via the `content` parameter instead." ,
1929+ DeprecationWarning ,
1930+ stacklevel = 2 ,
1931+ )
18191932 opts = FinalRequestOptions .construct (
1820- method = "put" , url = path , json_data = body , files = await async_to_httpx_files (files ), ** options
1933+ method = "put" , url = path , json_data = body , content = content , files = await async_to_httpx_files (files ), ** options
18211934 )
18221935 return await self .request (cast_to , opts )
18231936
@@ -1827,9 +1940,19 @@ async def delete(
18271940 * ,
18281941 cast_to : Type [ResponseT ],
18291942 body : Body | None = None ,
1943+ content : AsyncBinaryTypes | None = None ,
18301944 options : RequestOptions = {},
18311945 ) -> ResponseT :
1832- opts = FinalRequestOptions .construct (method = "delete" , url = path , json_data = body , ** options )
1946+ if body is not None and content is not None :
1947+ raise TypeError ("Passing both `body` and `content` is not supported" )
1948+ if isinstance (body , bytes ):
1949+ warnings .warn (
1950+ "Passing raw bytes as `body` is deprecated and will be removed in a future version. "
1951+ "Please pass raw bytes via the `content` parameter instead." ,
1952+ DeprecationWarning ,
1953+ stacklevel = 2 ,
1954+ )
1955+ opts = FinalRequestOptions .construct (method = "delete" , url = path , json_data = body , content = content , ** options )
18331956 return await self .request (cast_to , opts )
18341957
18351958 def get_api_list (
0 commit comments