1- # SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
1+ # SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
22# SPDX-License-Identifier: Apache-2.0
33"""Classes to work with ESP Component Registry"""
44
5- import os
65import typing as t
76from functools import wraps
7+ from pathlib import Path
88from ssl import SSLEOFError
99
1010from requests_toolbelt import MultipartEncoder , MultipartEncoderMonitor
@@ -112,30 +112,50 @@ def revoke_current_token(self, request: t.Callable) -> None:
112112 """Revoke current token"""
113113 request ('delete' , ['tokens' , 'current' ])
114114
115- def _upload_version_to_endpoint (self , request , file_path , endpoint , callback = None ):
116- with open (file_path , 'rb' ) as file :
117- filename = os .path .basename (file_path )
118-
119- encoder = MultipartEncoder ({'file' : (filename , file , 'application/octet-stream' )})
120- headers = {'Content-Type' : encoder .content_type }
121- data = MultipartEncoderMonitor (encoder , callback )
115+ def _upload_version_to_endpoint (
116+ self , request , file_path , example_file_path , endpoint , callback = None
117+ ):
118+ version_archive_file_handler = open (file_path , 'rb' )
119+ file_handlers = [version_archive_file_handler ]
120+ files = {
121+ 'file' : (Path (file_path ).name , version_archive_file_handler , 'application/octet-stream' )
122+ }
123+
124+ # Handling of example archives defined in the manifest
125+ if example_file_path :
126+ example_archive_file_handler = open (example_file_path , 'rb' )
127+ file_handlers .append (example_archive_file_handler )
128+ files ['example_file' ] = (
129+ Path (example_file_path ).name ,
130+ example_archive_file_handler ,
131+ 'application/octet-stream' ,
132+ )
122133
123- try :
124- return request (
125- 'post' ,
126- endpoint ,
127- data = data ,
128- headers = headers ,
129- schema = VersionUpload ,
130- timeout = UPLOAD_COMPONENT_TIMEOUT ,
131- )['job_id' ]
132- # Python 3.10+ can't process 413 error - https://github.com/urllib3/urllib3/issues/2733
133- except (SSLEOFError , ContentTooLargeError ):
134- raise APIClientError (
135- 'The component archive exceeds the maximum allowed size. Please consider '
136- 'excluding unnecessary files from your component. If you think your component '
137- 'should be uploaded as it is, please contact [email protected] ' 138- )
134+ # Encode the archives into a multipart form
135+ encoder = MultipartEncoder (files )
136+ headers = {'Content-Type' : encoder .content_type }
137+ data = MultipartEncoderMonitor (encoder , callback )
138+
139+ try :
140+ req = request (
141+ 'post' ,
142+ endpoint ,
143+ data = data ,
144+ headers = headers ,
145+ schema = VersionUpload ,
146+ timeout = UPLOAD_COMPONENT_TIMEOUT ,
147+ )
148+ for file_handler in file_handlers :
149+ file_handler .close ()
150+
151+ return req ['job_id' ]
152+ # Python 3.10+ can't process 413 error - https://github.com/urllib3/urllib3/issues/2733
153+ except (SSLEOFError , ContentTooLargeError ):
154+ raise APIClientError (
155+ 'The component archive exceeds the maximum allowed size. Please consider '
156+ 'excluding unnecessary files from your component. If you think your component '
157+ 'should be uploaded as it is, please contact [email protected] ' 158+ )
139159
140160 @_request
141161 def get_component_response (
@@ -147,18 +167,21 @@ def get_component_response(
147167
148168 @auth_required
149169 @_request
150- def upload_version (self , request , component_name , file_path , callback = None ):
170+ def upload_version (
171+ self , request , component_name , file_path , example_file_path = None , callback = None
172+ ):
151173 return self ._upload_version_to_endpoint (
152174 request ,
153175 file_path ,
176+ example_file_path ,
154177 ['components' , component_name .lower (), 'versions' ],
155178 callback ,
156179 )
157180
158181 @_request
159- def validate_version (self , request , file_path , callback = None ):
182+ def validate_version (self , request , file_path , example_file_path = None , callback = None ):
160183 return self ._upload_version_to_endpoint (
161- request , file_path , ['components' , 'validate' ], callback
184+ request , file_path , example_file_path , ['components' , 'validate' ], callback
162185 )
163186
164187 @auth_required
0 commit comments