In Redshift, you can create a Python UDF with an arbitrary number of arguments but you have to pass the same number of arguments when you execute the function. The workaround for optional parameters would be passing nulls and setting the parameter to the default value at the beginning of the function body similar to this:
create function f_optional_test(a int, b int)
returns int
stable as $$
if b==None:
return 999 # set default
else:
return b
$$ language plpythonu;
select f_optional_test(1,2); -- returns 2
select f_optional_test(1,null); -- returns 999
Also, you can create multiple functions with the same name but different number of parameters, so the function that is selected for execution will be picked up by the database engine based on the number of parameters and their data type:
create function f_optional_test(a int)
returns int
stable as $$
return 999 # default for b
$$ language plpythonu;
select f_optional_test(1,2); -- returns 2
select f_optional_test(1); -- returns 999
It's up to you to choose whether you'd like to have a single function at the expense of passing nulls for default parameters or have optional parameters at the expense of maintaining two versions of the same function if there is one optional parameter (with more optional parameters and their variable order it's more complicated and the first option is obviously better).