@@ -189,35 +189,43 @@ def get_signed_smart_cdn_url(
189189 - workspace (str): Workspace slug
190190 - template (str): Template slug or template ID
191191 - input (str): Input value that is provided as ${fields.input} in the template
192- - url_params (Optional[dict]): Additional parameters for the URL query string
192+ - url_params (Optional[dict]): Additional parameters for the URL query string. Values can be strings, numbers, booleans or arrays thereof.
193193 - expires_in (Optional[int]): Expiration time of signature in milliseconds. Defaults to 1 hour.
194194
195195 :Returns:
196196 str: The signed Smart CDN URL
197+
198+ :Raises:
199+ ValueError: If url_params contains values that are not strings, numbers, booleans or arrays
197200 """
198201 workspace_slug = quote_plus (workspace )
199202 template_slug = quote_plus (template )
200203 input_field = quote_plus (input )
201204
202- # Convert url_params values to strings
203- params = {}
205+ params = []
204206 if url_params :
205- params .update ({k : str (v ) for k , v in url_params .items ()})
207+ for k , v in url_params .items ():
208+ if isinstance (v , (str , int , float , bool )):
209+ params .append ((k , str (v )))
210+ elif isinstance (v , (list , tuple )):
211+ params .append ((k , [str (vv ) for vv in v ]))
212+ else :
213+ raise ValueError (f"URL parameter values must be strings, numbers, booleans or arrays. Got { type (v )} for { k } " )
206214
207- params [ "auth_key" ] = self .auth_key
208- params [ "exp" ] = str (int (time .time () * 1000 ) + expires_in )
215+ params . append (( "auth_key" , self .auth_key ))
216+ params . append (( "exp" , str (int (time .time () * 1000 ) + expires_in )) )
209217
210- # Sort params alphabetically
211- sorted_params = dict ( sorted (params . items ()) )
212- query_string = urlencode (sorted_params )
218+ # Sort params alphabetically by key
219+ sorted_params = sorted (params , key = lambda x : x [ 0 ] )
220+ query_string = urlencode (sorted_params , doseq = True )
213221
214222 string_to_sign = f"{ workspace_slug } /{ template_slug } /{ input_field } ?{ query_string } "
215223 algorithm = "sha256"
216224
217- signature = hmac .new (
225+ signature = algorithm + ":" + hmac .new (
218226 self .auth_secret .encode ("utf-8" ),
219227 string_to_sign .encode ("utf-8" ),
220228 hashlib .sha256
221229 ).hexdigest ()
222230
223- return f"https://{ workspace_slug } .tlcdn.com/{ template_slug } /{ input_field } ?{ query_string } &sig={ algorithm } : { signature } "
231+ return f"https://{ workspace_slug } .tlcdn.com/{ template_slug } /{ input_field } ?{ query_string } &sig={ quote_plus ( signature ) } "
0 commit comments