@@ -1352,7 +1352,7 @@ def _endpoint_to_url(
13521352
13531353 def _download_file_to_stream (
13541354 self ,
1355- url : str ,
1355+ endpoint : str ,
13561356 stream : StreamType ,
13571357 chunk_size : int ,
13581358 progress : TransferProgress ,
@@ -1367,7 +1367,11 @@ def _download_file_to_stream(
13671367 else :
13681368 get_func = self ._session_functions_mapping [RequestTypes .get ]
13691369
1370+ url = self ._endpoint_to_url (endpoint , use_rest = False )
1371+ progress .set_source_url (url )
1372+
13701373 retries = self .get_default_max_retries ()
1374+ api_prepended = False
13711375 for attempt in range (retries ):
13721376 # Continue in download
13731377 offset = progress .get_transferred_size ()
@@ -1376,6 +1380,18 @@ def _download_file_to_stream(
13761380
13771381 try :
13781382 with get_func (url , ** kwargs ) as response :
1383+ # Auto-fix missing 'api/'
1384+ if response .status_code == 405 and not api_prepended :
1385+ api_prepended = True
1386+ if (
1387+ not endpoint .startswith (self ._base_url )
1388+ and not endpoint .startswith ("api/" )
1389+ ):
1390+ url = self ._endpoint_to_url (
1391+ endpoint , use_rest = True
1392+ )
1393+ progress .set_destination_url (url )
1394+ continue
13791395 response .raise_for_status ()
13801396 if progress .get_content_size () is None :
13811397 progress .set_content_size (
@@ -1395,6 +1411,12 @@ def _download_file_to_stream(
13951411 raise
13961412 progress .next_attempt ()
13971413
1414+ if api_prepended :
1415+ self .log .warning (
1416+ f"Auto-fixed endpoint '{ endpoint } ' -> 'api/{ endpoint } '."
1417+ " Please fix the endpoit passed to the function."
1418+ )
1419+
13981420 def download_file_to_stream (
13991421 self ,
14001422 endpoint : str ,
@@ -1427,17 +1449,14 @@ def download_file_to_stream(
14271449 if not chunk_size :
14281450 chunk_size = self .default_download_chunk_size
14291451
1430- url = self ._endpoint_to_url (endpoint , use_rest = False )
1431-
14321452 if progress is None :
14331453 progress = TransferProgress ()
14341454
1435- progress .set_source_url (url )
14361455 progress .set_started ()
14371456
14381457 try :
14391458 self ._download_file_to_stream (
1440- url , stream , chunk_size , progress
1459+ endpoint , stream , chunk_size , progress
14411460 )
14421461
14431462 except Exception as exc :
@@ -1585,13 +1604,7 @@ def _upload_chunks_iter(
15851604 bytes: Chunk of file.
15861605
15871606 """
1588- # Get size of file
1589- file_stream .seek (0 , io .SEEK_END )
1590- size = file_stream .tell ()
15911607 file_stream .seek (0 )
1592- # Set content size to progress object
1593- progress .set_content_size (size )
1594-
15951608 while True :
15961609 chunk = file_stream .read (chunk_size )
15971610 if not chunk :
@@ -1601,7 +1614,7 @@ def _upload_chunks_iter(
16011614
16021615 def _upload_file (
16031616 self ,
1604- url : str ,
1617+ endpoint : str ,
16051618 stream : StreamType ,
16061619 progress : TransferProgress ,
16071620 request_type : Optional [RequestType ] = None ,
@@ -1611,7 +1624,7 @@ def _upload_file(
16111624 """Upload file to server.
16121625
16131626 Args:
1614- url (str): Url where file will be uploaded .
1627+ endpoint (str): Endpoint used to upload .
16151628 stream (StreamType): File stream.
16161629 progress (TransferProgress): Object that gives ability to track
16171630 progress.
@@ -1629,6 +1642,10 @@ def _upload_file(
16291642 if request_type is None :
16301643 request_type = RequestTypes .put
16311644
1645+ endpoint = endpoint .lstrip ("/" )
1646+ url = self ._endpoint_to_url (endpoint , use_rest = False )
1647+ progress .set_destination_url (url )
1648+
16321649 if self ._session is None :
16331650 headers = kwargs .setdefault ("headers" , {})
16341651 for key , value in self .get_headers ().items ():
@@ -1643,6 +1660,14 @@ def _upload_file(
16431660
16441661 retries = self .get_default_max_retries ()
16451662 response = None
1663+
1664+ # Get size of file
1665+ stream .seek (0 , io .SEEK_END )
1666+ size = stream .tell ()
1667+ # Set content size to progress object
1668+ progress .set_content_size (size )
1669+
1670+ api_prepended = False
16461671 for attempt in range (retries ):
16471672 try :
16481673 response = post_func (
@@ -1652,6 +1677,16 @@ def _upload_file(
16521677 ),
16531678 ** kwargs
16541679 )
1680+ # Auto-fix missing 'api/'
1681+ if response .status_code == 405 and not api_prepended :
1682+ api_prepended = True
1683+ if (
1684+ not endpoint .startswith (self ._base_url )
1685+ and not endpoint .startswith ("api/" )
1686+ ):
1687+ url = self ._endpoint_to_url (endpoint , use_rest = True )
1688+ progress .set_destination_url (url )
1689+ continue
16551690 break
16561691
16571692 except (
@@ -1664,6 +1699,11 @@ def _upload_file(
16641699 progress .reset_transferred ()
16651700
16661701 response .raise_for_status ()
1702+ if api_prepended :
1703+ self .log .warning (
1704+ f"Auto-fixed endpoint '{ endpoint } ' -> 'api/{ endpoint } '."
1705+ " Please fix the endpoit passed to the function."
1706+ )
16671707 return response
16681708
16691709 def upload_file_from_stream (
@@ -1694,19 +1734,20 @@ def upload_file_from_stream(
16941734 requests.Response: Response object
16951735
16961736 """
1697- url = self ._endpoint_to_url (endpoint )
1698-
16991737 # Create dummy object so the function does not have to check
17001738 # 'progress' variable everywhere
17011739 if progress is None :
17021740 progress = TransferProgress ()
17031741
1704- progress .set_destination_url (url )
17051742 progress .set_started ()
17061743
17071744 try :
17081745 return self ._upload_file (
1709- url , stream , progress , request_type , ** kwargs
1746+ endpoint ,
1747+ stream ,
1748+ progress ,
1749+ request_type ,
1750+ ** kwargs
17101751 )
17111752
17121753 except Exception as exc :
@@ -1751,7 +1792,11 @@ def upload_file(
17511792
17521793 with open (filepath , "rb" ) as stream :
17531794 return self .upload_file_from_stream (
1754- endpoint , stream , progress , request_type , ** kwargs
1795+ endpoint ,
1796+ stream ,
1797+ progress ,
1798+ request_type ,
1799+ ** kwargs
17551800 )
17561801
17571802 def upload_reviewable (
@@ -1813,7 +1858,7 @@ def upload_reviewable(
18131858
18141859 query = prepare_query_string ({"label" : label or None })
18151860 endpoint = (
1816- f"/projects/{ project_name } "
1861+ f"api /projects/{ project_name } "
18171862 f"/versions/{ version_id } /reviewables{ query } "
18181863 )
18191864 return self .upload_file (
0 commit comments