Loading...
Searching...
No Matches
mv_createfile.sas
Go to the documentation of this file.
1/**
2 @file
3 @brief Creates a file in SAS Drive using the API method
4 @details Creates a file in SAS Drive using the API interface.
5 If the parent folder does not exist, it is created.
6 The API approach is more flexible than using the filesrvc engine of the
7 filename statement, as it provides more options.
8
9 SAS docs: https://developer.sas.com/rest-apis/files/createNewFile
10
11 Usage:
12
13 filename myfile temp;
14 data _null_;
15 file myfile;
16 put 'something';
17 run;
18 %mv_createfile(path=/Public/temp,name=newfile.txt,inref=myfile)
19
20 The macro also supports find & replace (used by the SASjs Streaming App
21 build program). This allows one string to be replaced by another at the
22 point at which the file is created. This is done by passing in the NAMES of
23 the macro variables containing the values to be swapped, eg:
24
25 filename fref temp;
26 data _null_;
27 file fref;
28 put 'whenever life gets you down, Mrs Brown..';
29 run;
30 %let f=Mrs Brown;
31 %let r=just remember that you're standing on a planet that's evolving;
32 %mv_createfile(path=/Public,name=life.md,inref=fref,fin,swap=f r)
33
34
35 @param [in] path= The parent (SAS Drive) folder in which to create the file
36 @param [in] name= The name of the file to be created
37 @param [in] inref= The fileref pointing to the file to be uploaded
38 @param [in] intype= (BINARY) The type of the input data. Valid values:
39 @li BINARY File is copied byte for byte using the mp_binarycopy.sas macro.
40 @li BASE64 File will be first decoded using the mp_base64.sas macro, then
41 loaded byte by byte to SAS Drive.
42 @param [in] contentdisp= (attchment) Content Disposition. Example values:
43 @li inline
44 @li attachment
45 @param [in] ctype= (0) The actual MIME type of the file (if blank will be
46 determined based on file extension))
47 @param [in] access_token_var= The global macro variable to contain the access
48 token, if using authorization_code grant type.
49 @param [in] grant_type= (sas_services) Valid values are:
50 @li password
51 @li authorization_code
52 @li sas_services
53 @param [in] force= (YES) Will overwrite (delete / recreate) files by default.
54 Set to NO to abort if a file already exists in that location.
55 @param pin] swap= (0) Provide two macro variable NAMES that contain the values
56 to be swapped, eg swap=find replace (see also the example above)
57 @param [out] outds= (_null_) Output dataset with the uri of the new file
58
59 @param [in] mdebug= (0) Set to 1 to enable DEBUG messages
60
61 <h4> SAS Macros </h4>
62 @li mf_getplatform.sas
63 @li mf_getuniquefileref.sas
64 @li mf_getuniquename.sas
65 @li mf_isblank.sas
66 @li mf_mimetype.sas
67 @li mfv_getpathuri.sas
68 @li mp_abort.sas
69 @li mp_base64copy.sas
70 @li mp_replace.sas
71 @li mv_createfolder.sas
72
73 <h4> Related Macros</h4>
74 @li mv_createfile.sas
75
76**/
77
78%macro mv_createfile(path=
79 ,name=
80 ,inref=
81 ,intype=BINARY
82 ,contentdisp=attachment
83 ,ctype=0
84 ,access_token_var=ACCESS_TOKEN
85 ,grant_type=sas_services
86 ,mdebug=0
87 ,outds=_null_
88 ,force=YES
89 ,swap=0
90 );
91%local dbg;
92%if &mdebug=1 %then %do;
93 %put &sysmacroname entry vars:;
94 %put _local_;
95%end;
96%else %let dbg=*;
97
98%mp_abort(
99 iftrue=(&syscc ne 0),
100 msg=Cannot enter &sysmacroname with syscc=&syscc
101)
102
103%local oauth_bearer;
104%if &grant_type=detect %then %do;
105 %if %symexist(&access_token_var) %then %let grant_type=authorization_code;
106 %else %let grant_type=sas_services;
107%end;
108%if &grant_type=sas_services %then %do;
109 %let oauth_bearer=oauth_bearer=sas_services;
110 %let &access_token_var=;
111%end;
112
113%mp_abort(iftrue=(&grant_type ne authorization_code and &grant_type ne password
114 and &grant_type ne sas_services
115 )
116 ,mac=MV_CREATEFILE
117 ,msg=%str(Invalid value for grant_type: &grant_type)
118)
119
120%mp_abort(iftrue=(%mf_isblank(&path)=1 or %length(&path)=1)
121 ,mac=MV_CREATEFILE
122 ,msg=%str(path value must be provided)
123)
124%mp_abort(iftrue=(%mf_isblank(&name)=1 or %length(&name)=1)
125 ,mac=MV_CREATEFILE
126 ,msg=%str(name value with length >1 must be provided)
127)
128
129/* prep the source file */
130%local fref;
131%let fref=%mf_getuniquefileref();
132
133%if %upcase(&intype)=BINARY %then %let fref=&inref;
134%else %if %upcase(&intype)=BASE64 %then %do;
135 %mp_base64copy(inref=&inref, outref=&fref, action=DECODE)
136%end;
137%else %put %str(ERR)OR: invalid value for intype: &intype;
138
139%if "&swap" ne "0" %then %do;
140 %mp_replace("%sysfunc(pathname(&fref))"
141 ,findvar=%scan(&swap,1,%str( ))
142 ,replacevar=%scan(&swap,2,%str( ))
143 )
144%end;
145
146%if &mdebug=1 %then %do;
147 data _null_;
148 infile &fref lrecl=32767;
149 input;
150 put _infile_;
151 run;
152%end;
153
154options noquotelenmax;
155%local base_uri; /* location of rest apis */
156%let base_uri=%mf_getplatform(VIYARESTAPI);
157
158/* create folder if it does not already exist */
159%local folderds self_uri;
160%let folderds=%mf_getuniquename(prefix=folderds);
161%mv_createfolder(path=&path
162 ,access_token_var=&access_token_var
163 ,grant_type=&grant_type
164 ,mdebug=&mdebug
165 ,outds=&folderds
166)
167data _null_;
168 set &folderds;
169 call symputx('self_uri',self_uri,'l');
170run;
171
172/* abort or delete if file already exists */
173%let force=%upcase(&force);
174%local fileuri ;
175%let fileuri=%mfv_getpathuri(&path/&name);
176%mp_abort(iftrue=(%mf_isblank(&fileuri)=0 and &force ne YES)
177 ,mac=MV_CREATEFILE
178 ,msg=%str(File &path/&name already exists and force=&force)
179)
180%mp_abort(
181 iftrue=(&syscc ne 0),
182 mac=MV_CREATEFILE182
183 msg=syscc=&syscc after mfv_getpathuri
184)
185
186%if %mf_isblank(&fileuri)=0 and &force=YES %then %do;
187 proc http method="DELETE" url="&base_uri&fileuri" &oauth_bearer;
188 headers
189 %if &grant_type=authorization_code %then %do;
190 "Authorization"="Bearer &&&access_token_var"
191 %end;
192 "Accept"="*/*";
193 run;
194 %put &sysmacroname DELETE &base_uri&fileuri;
195 %if &SYS_PROCHTTP_STATUS_CODE ne 204 %then %do;
196 %put &=SYS_PROCHTTP_STATUS_CODE &=SYS_PROCHTTP_STATUS_PHRASE;
197 %end;
198%end;
199
200%local url mimetype ext;
201%let url=&base_uri/files/files?parentFolderUri=&self_uri;
202%let ext=%upcase(%scan(&name,-1,.));
203
204/* fetch job info */
205%local fname1;
206%let fname1=%mf_getuniquefileref();
207proc http method='POST' out=&fname1 &oauth_bearer in=&fref
208 %if "&ctype" = "0" %then %do;
209 %let mimetype=%mf_mimetype(&ext);
210 ct="&mimetype"
211 %end;
212 %else %do;
213 ct="&ctype"
214 %end;
215 %if "&ext"="HTML" or "&ext"="CSS" or "&ext"="JS" or "&ext"="PNG"
216 or "&ext"="SVG" %then %do;
217 url="&url%str(&)typeDefName=file";
218 %end;
219 %else %do;
220 url="&url";
221 %end;
222
223 headers "Accept"="application/json"
224 %if &grant_type=authorization_code %then %do;
225 "Authorization"="Bearer &&&access_token_var"
226 %end;
227 "Content-Disposition"=
228 %if "&ext"="SVG" or "&ext"="HTML" %then %do;
229 "filename=""&name"";"
230 %end;
231 %else %do;
232 "&contentdisp filename=""&name""; name=""&name"";"
233 %end;
234 ;
235run;
236%if &mdebug=1 %then %put &sysmacroname POST &=url
237 &=SYS_PROCHTTP_STATUS_CODE &=SYS_PROCHTTP_STATUS_PHRASE;
238%mp_abort(iftrue=(&SYS_PROCHTTP_STATUS_CODE ne 201)
239 ,mac=MV_CREATEFILE
240 ,msg=%str(&SYS_PROCHTTP_STATUS_CODE &SYS_PROCHTTP_STATUS_PHRASE)
241)
242%local libref2;
243%let libref2=%mf_getuniquelibref();
244libname &libref2 JSON fileref=&fname1;
245/* Grab the follow on link */
246data &outds;
247 set &libref2..links end=last;
248 if rel='createChild' then do;
249 call symputx('href',quote(cats("&base_uri",href)),'l');
250 &dbg put (_all_)(=);
251 end;
252run;
253
254%put &sysmacroname: %trim(&base_uri)%mfv_getpathuri(&path/&name);
255%put /SASJobExecution?_file=&path/&name;%put;
256
257%if &mdebug=0 %then %do;
258 /* clear refs */
259 filename &fname1 clear;
260 filename &fref clear;
261 libname &libref2 clear;
262%end;
263
264%mp_abort(
265 iftrue=(&syscc ne 0),
266 msg=Cannot leave &sysmacroname with syscc=&syscc
267)
268
269%mend mv_createfile;