Skip to main content

nominal_api/conjure/endpoints/upload/api/
upload_service.rs

1use conjure_http::endpoint;
2/// The Upload Service manages file uploads to object storage.
3#[conjure_http::conjure_endpoints(
4    name = "UploadService",
5    use_legacy_error_serialization
6)]
7pub trait UploadService<#[request_body] I> {
8    /// Initiates a multipart upload to object storage.
9    /// Returns an uploadId that should be used with listParts, signPart, and completeMultipartUpload.
10    #[endpoint(
11        method = POST,
12        path = "/upload/v1/multipart-upload",
13        name = "initiateMultipartUpload",
14        produces = conjure_http::server::StdResponseSerializer
15    )]
16    fn initiate_multipart_upload(
17        &self,
18        #[auth]
19        auth_: conjure_object::BearerToken,
20        #[body(
21            deserializer = conjure_http::server::StdRequestDeserializer,
22            log_as = "uploadRequest"
23        )]
24        upload_request: super::super::super::super::objects::ingest::api::InitiateMultipartUploadRequest,
25    ) -> Result<
26        super::super::super::super::objects::ingest::api::InitiateMultipartUploadResponse,
27        conjure_http::private::Error,
28    >;
29    /// Lists the parts that have been uploaded for a given uploadId.
30    #[endpoint(
31        method = GET,
32        path = "/upload/v1/multipart-upload/{uploadId}",
33        name = "listParts",
34        produces = conjure_http::server::conjure::CollectionResponseSerializer
35    )]
36    fn list_parts(
37        &self,
38        #[auth]
39        auth_: conjure_object::BearerToken,
40        #[path(
41            name = "uploadId",
42            decoder = conjure_http::server::conjure::FromPlainDecoder,
43            log_as = "uploadId"
44        )]
45        upload_id: String,
46        #[query(name = "key", decoder = conjure_http::server::conjure::FromPlainDecoder)]
47        key: String,
48    ) -> Result<
49        Vec<super::super::super::super::objects::ingest::api::PartWithSize>,
50        conjure_http::private::Error,
51    >;
52    /// Signs an upload request for a single part.
53    /// Returns a URL that will execute the upload without further authentication.
54    #[endpoint(
55        method = POST,
56        path = "/upload/v1/multipart-upload/{uploadId}",
57        name = "signPart",
58        produces = conjure_http::server::StdResponseSerializer
59    )]
60    fn sign_part(
61        &self,
62        #[auth]
63        auth_: conjure_object::BearerToken,
64        #[path(
65            name = "uploadId",
66            decoder = conjure_http::server::conjure::FromPlainDecoder,
67            log_as = "uploadId"
68        )]
69        upload_id: String,
70        #[query(name = "key", decoder = conjure_http::server::conjure::FromPlainDecoder)]
71        key: String,
72        #[query(
73            name = "partNumber",
74            decoder = conjure_http::server::conjure::FromPlainDecoder,
75            log_as = "partNumber"
76        )]
77        part_number: i32,
78    ) -> Result<
79        super::super::super::super::objects::ingest::api::SignPartResponse,
80        conjure_http::private::Error,
81    >;
82    /// Completes a multipart upload to object storage.
83    /// This should be called after all parts have been uploaded.
84    /// Will throw EmptyMultipartUpload if there are 0 parts.
85    #[endpoint(
86        method = POST,
87        path = "/upload/v1/multipart-upload/{uploadId}/complete",
88        name = "completeMultipartUpload",
89        produces = conjure_http::server::StdResponseSerializer
90    )]
91    fn complete_multipart_upload(
92        &self,
93        #[auth]
94        auth_: conjure_object::BearerToken,
95        #[path(
96            name = "uploadId",
97            decoder = conjure_http::server::conjure::FromPlainDecoder,
98            log_as = "uploadId"
99        )]
100        upload_id: String,
101        #[query(name = "key", decoder = conjure_http::server::conjure::FromPlainDecoder)]
102        key: String,
103        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
104        parts: Vec<super::super::super::super::objects::ingest::api::Part>,
105    ) -> Result<
106        super::super::super::super::objects::ingest::api::CompleteMultipartUploadResponse,
107        conjure_http::private::Error,
108    >;
109    /// Aborts a multipart upload to S3.
110    /// Frees storage used by previously uploaded parts and prevents further uploads to the same uploadId.
111    #[endpoint(
112        method = POST,
113        path = "/upload/v1/multipart-upload/{uploadId}/abort",
114        name = "abortMultipartUpload"
115    )]
116    fn abort_multipart_upload(
117        &self,
118        #[auth]
119        auth_: conjure_object::BearerToken,
120        #[path(
121            name = "uploadId",
122            decoder = conjure_http::server::conjure::FromPlainDecoder,
123            log_as = "uploadId"
124        )]
125        upload_id: String,
126        #[query(name = "key", decoder = conjure_http::server::conjure::FromPlainDecoder)]
127        key: String,
128    ) -> Result<(), conjure_http::private::Error>;
129    /// Returns a short-lived signed GET URL for an object already in the uploads bucket.
130    /// Use this to hand a freshly-uploaded object's path to an external service (e.g. Dagger)
131    /// without giving that service any Scout credentials. The caller must be authorized to
132    /// read the workspace that owns the path (encoded as the first segment of the object key).
133    #[endpoint(
134        method = POST,
135        path = "/upload/v1/sign-download",
136        name = "signDownload",
137        produces = conjure_http::server::StdResponseSerializer
138    )]
139    fn sign_download(
140        &self,
141        #[auth]
142        auth_: conjure_object::BearerToken,
143        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
144        request: super::super::super::super::objects::ingest::api::SignDownloadRequest,
145    ) -> Result<
146        super::super::super::super::objects::ingest::api::SignDownloadResponse,
147        conjure_http::private::Error,
148    >;
149    /// Uploads a file to S3. Intended for smaller files.
150    #[endpoint(
151        method = POST,
152        path = "/upload/v1/upload-file",
153        name = "uploadFile",
154        produces = conjure_http::server::StdResponseSerializer
155    )]
156    fn upload_file(
157        &self,
158        #[auth]
159        auth_: conjure_object::BearerToken,
160        #[query(
161            name = "fileName",
162            decoder = conjure_http::server::conjure::FromPlainDecoder,
163            log_as = "fileName"
164        )]
165        file_name: String,
166        #[query(
167            name = "sizeBytes",
168            decoder = conjure_http::server::conjure::FromPlainOptionDecoder,
169            log_as = "sizeBytes"
170        )]
171        size_bytes: Option<conjure_object::SafeLong>,
172        #[query(
173            name = "workspace",
174            decoder = conjure_http::server::conjure::FromPlainOptionDecoder
175        )]
176        workspace: Option<conjure_object::ResourceIdentifier>,
177        #[body(deserializer = conjure_http::server::conjure::BinaryRequestDeserializer)]
178        body: I,
179    ) -> Result<String, conjure_http::private::Error>;
180}
181/// The Upload Service manages file uploads to object storage.
182#[conjure_http::conjure_endpoints(
183    name = "UploadService",
184    use_legacy_error_serialization
185)]
186pub trait AsyncUploadService<#[request_body] I> {
187    /// Initiates a multipart upload to object storage.
188    /// Returns an uploadId that should be used with listParts, signPart, and completeMultipartUpload.
189    #[endpoint(
190        method = POST,
191        path = "/upload/v1/multipart-upload",
192        name = "initiateMultipartUpload",
193        produces = conjure_http::server::StdResponseSerializer
194    )]
195    async fn initiate_multipart_upload(
196        &self,
197        #[auth]
198        auth_: conjure_object::BearerToken,
199        #[body(
200            deserializer = conjure_http::server::StdRequestDeserializer,
201            log_as = "uploadRequest"
202        )]
203        upload_request: super::super::super::super::objects::ingest::api::InitiateMultipartUploadRequest,
204    ) -> Result<
205        super::super::super::super::objects::ingest::api::InitiateMultipartUploadResponse,
206        conjure_http::private::Error,
207    >;
208    /// Lists the parts that have been uploaded for a given uploadId.
209    #[endpoint(
210        method = GET,
211        path = "/upload/v1/multipart-upload/{uploadId}",
212        name = "listParts",
213        produces = conjure_http::server::conjure::CollectionResponseSerializer
214    )]
215    async fn list_parts(
216        &self,
217        #[auth]
218        auth_: conjure_object::BearerToken,
219        #[path(
220            name = "uploadId",
221            decoder = conjure_http::server::conjure::FromPlainDecoder,
222            log_as = "uploadId"
223        )]
224        upload_id: String,
225        #[query(name = "key", decoder = conjure_http::server::conjure::FromPlainDecoder)]
226        key: String,
227    ) -> Result<
228        Vec<super::super::super::super::objects::ingest::api::PartWithSize>,
229        conjure_http::private::Error,
230    >;
231    /// Signs an upload request for a single part.
232    /// Returns a URL that will execute the upload without further authentication.
233    #[endpoint(
234        method = POST,
235        path = "/upload/v1/multipart-upload/{uploadId}",
236        name = "signPart",
237        produces = conjure_http::server::StdResponseSerializer
238    )]
239    async fn sign_part(
240        &self,
241        #[auth]
242        auth_: conjure_object::BearerToken,
243        #[path(
244            name = "uploadId",
245            decoder = conjure_http::server::conjure::FromPlainDecoder,
246            log_as = "uploadId"
247        )]
248        upload_id: String,
249        #[query(name = "key", decoder = conjure_http::server::conjure::FromPlainDecoder)]
250        key: String,
251        #[query(
252            name = "partNumber",
253            decoder = conjure_http::server::conjure::FromPlainDecoder,
254            log_as = "partNumber"
255        )]
256        part_number: i32,
257    ) -> Result<
258        super::super::super::super::objects::ingest::api::SignPartResponse,
259        conjure_http::private::Error,
260    >;
261    /// Completes a multipart upload to object storage.
262    /// This should be called after all parts have been uploaded.
263    /// Will throw EmptyMultipartUpload if there are 0 parts.
264    #[endpoint(
265        method = POST,
266        path = "/upload/v1/multipart-upload/{uploadId}/complete",
267        name = "completeMultipartUpload",
268        produces = conjure_http::server::StdResponseSerializer
269    )]
270    async fn complete_multipart_upload(
271        &self,
272        #[auth]
273        auth_: conjure_object::BearerToken,
274        #[path(
275            name = "uploadId",
276            decoder = conjure_http::server::conjure::FromPlainDecoder,
277            log_as = "uploadId"
278        )]
279        upload_id: String,
280        #[query(name = "key", decoder = conjure_http::server::conjure::FromPlainDecoder)]
281        key: String,
282        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
283        parts: Vec<super::super::super::super::objects::ingest::api::Part>,
284    ) -> Result<
285        super::super::super::super::objects::ingest::api::CompleteMultipartUploadResponse,
286        conjure_http::private::Error,
287    >;
288    /// Aborts a multipart upload to S3.
289    /// Frees storage used by previously uploaded parts and prevents further uploads to the same uploadId.
290    #[endpoint(
291        method = POST,
292        path = "/upload/v1/multipart-upload/{uploadId}/abort",
293        name = "abortMultipartUpload"
294    )]
295    async fn abort_multipart_upload(
296        &self,
297        #[auth]
298        auth_: conjure_object::BearerToken,
299        #[path(
300            name = "uploadId",
301            decoder = conjure_http::server::conjure::FromPlainDecoder,
302            log_as = "uploadId"
303        )]
304        upload_id: String,
305        #[query(name = "key", decoder = conjure_http::server::conjure::FromPlainDecoder)]
306        key: String,
307    ) -> Result<(), conjure_http::private::Error>;
308    /// Returns a short-lived signed GET URL for an object already in the uploads bucket.
309    /// Use this to hand a freshly-uploaded object's path to an external service (e.g. Dagger)
310    /// without giving that service any Scout credentials. The caller must be authorized to
311    /// read the workspace that owns the path (encoded as the first segment of the object key).
312    #[endpoint(
313        method = POST,
314        path = "/upload/v1/sign-download",
315        name = "signDownload",
316        produces = conjure_http::server::StdResponseSerializer
317    )]
318    async fn sign_download(
319        &self,
320        #[auth]
321        auth_: conjure_object::BearerToken,
322        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
323        request: super::super::super::super::objects::ingest::api::SignDownloadRequest,
324    ) -> Result<
325        super::super::super::super::objects::ingest::api::SignDownloadResponse,
326        conjure_http::private::Error,
327    >;
328    /// Uploads a file to S3. Intended for smaller files.
329    #[endpoint(
330        method = POST,
331        path = "/upload/v1/upload-file",
332        name = "uploadFile",
333        produces = conjure_http::server::StdResponseSerializer
334    )]
335    async fn upload_file(
336        &self,
337        #[auth]
338        auth_: conjure_object::BearerToken,
339        #[query(
340            name = "fileName",
341            decoder = conjure_http::server::conjure::FromPlainDecoder,
342            log_as = "fileName"
343        )]
344        file_name: String,
345        #[query(
346            name = "sizeBytes",
347            decoder = conjure_http::server::conjure::FromPlainOptionDecoder,
348            log_as = "sizeBytes"
349        )]
350        size_bytes: Option<conjure_object::SafeLong>,
351        #[query(
352            name = "workspace",
353            decoder = conjure_http::server::conjure::FromPlainOptionDecoder
354        )]
355        workspace: Option<conjure_object::ResourceIdentifier>,
356        #[body(deserializer = conjure_http::server::conjure::BinaryRequestDeserializer)]
357        body: I,
358    ) -> Result<String, conjure_http::private::Error>;
359}
360/// The Upload Service manages file uploads to object storage.
361#[conjure_http::conjure_endpoints(
362    name = "UploadService",
363    use_legacy_error_serialization,
364    local
365)]
366pub trait LocalAsyncUploadService<#[request_body] I> {
367    /// Initiates a multipart upload to object storage.
368    /// Returns an uploadId that should be used with listParts, signPart, and completeMultipartUpload.
369    #[endpoint(
370        method = POST,
371        path = "/upload/v1/multipart-upload",
372        name = "initiateMultipartUpload",
373        produces = conjure_http::server::StdResponseSerializer
374    )]
375    async fn initiate_multipart_upload(
376        &self,
377        #[auth]
378        auth_: conjure_object::BearerToken,
379        #[body(
380            deserializer = conjure_http::server::StdRequestDeserializer,
381            log_as = "uploadRequest"
382        )]
383        upload_request: super::super::super::super::objects::ingest::api::InitiateMultipartUploadRequest,
384    ) -> Result<
385        super::super::super::super::objects::ingest::api::InitiateMultipartUploadResponse,
386        conjure_http::private::Error,
387    >;
388    /// Lists the parts that have been uploaded for a given uploadId.
389    #[endpoint(
390        method = GET,
391        path = "/upload/v1/multipart-upload/{uploadId}",
392        name = "listParts",
393        produces = conjure_http::server::conjure::CollectionResponseSerializer
394    )]
395    async fn list_parts(
396        &self,
397        #[auth]
398        auth_: conjure_object::BearerToken,
399        #[path(
400            name = "uploadId",
401            decoder = conjure_http::server::conjure::FromPlainDecoder,
402            log_as = "uploadId"
403        )]
404        upload_id: String,
405        #[query(name = "key", decoder = conjure_http::server::conjure::FromPlainDecoder)]
406        key: String,
407    ) -> Result<
408        Vec<super::super::super::super::objects::ingest::api::PartWithSize>,
409        conjure_http::private::Error,
410    >;
411    /// Signs an upload request for a single part.
412    /// Returns a URL that will execute the upload without further authentication.
413    #[endpoint(
414        method = POST,
415        path = "/upload/v1/multipart-upload/{uploadId}",
416        name = "signPart",
417        produces = conjure_http::server::StdResponseSerializer
418    )]
419    async fn sign_part(
420        &self,
421        #[auth]
422        auth_: conjure_object::BearerToken,
423        #[path(
424            name = "uploadId",
425            decoder = conjure_http::server::conjure::FromPlainDecoder,
426            log_as = "uploadId"
427        )]
428        upload_id: String,
429        #[query(name = "key", decoder = conjure_http::server::conjure::FromPlainDecoder)]
430        key: String,
431        #[query(
432            name = "partNumber",
433            decoder = conjure_http::server::conjure::FromPlainDecoder,
434            log_as = "partNumber"
435        )]
436        part_number: i32,
437    ) -> Result<
438        super::super::super::super::objects::ingest::api::SignPartResponse,
439        conjure_http::private::Error,
440    >;
441    /// Completes a multipart upload to object storage.
442    /// This should be called after all parts have been uploaded.
443    /// Will throw EmptyMultipartUpload if there are 0 parts.
444    #[endpoint(
445        method = POST,
446        path = "/upload/v1/multipart-upload/{uploadId}/complete",
447        name = "completeMultipartUpload",
448        produces = conjure_http::server::StdResponseSerializer
449    )]
450    async fn complete_multipart_upload(
451        &self,
452        #[auth]
453        auth_: conjure_object::BearerToken,
454        #[path(
455            name = "uploadId",
456            decoder = conjure_http::server::conjure::FromPlainDecoder,
457            log_as = "uploadId"
458        )]
459        upload_id: String,
460        #[query(name = "key", decoder = conjure_http::server::conjure::FromPlainDecoder)]
461        key: String,
462        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
463        parts: Vec<super::super::super::super::objects::ingest::api::Part>,
464    ) -> Result<
465        super::super::super::super::objects::ingest::api::CompleteMultipartUploadResponse,
466        conjure_http::private::Error,
467    >;
468    /// Aborts a multipart upload to S3.
469    /// Frees storage used by previously uploaded parts and prevents further uploads to the same uploadId.
470    #[endpoint(
471        method = POST,
472        path = "/upload/v1/multipart-upload/{uploadId}/abort",
473        name = "abortMultipartUpload"
474    )]
475    async fn abort_multipart_upload(
476        &self,
477        #[auth]
478        auth_: conjure_object::BearerToken,
479        #[path(
480            name = "uploadId",
481            decoder = conjure_http::server::conjure::FromPlainDecoder,
482            log_as = "uploadId"
483        )]
484        upload_id: String,
485        #[query(name = "key", decoder = conjure_http::server::conjure::FromPlainDecoder)]
486        key: String,
487    ) -> Result<(), conjure_http::private::Error>;
488    /// Returns a short-lived signed GET URL for an object already in the uploads bucket.
489    /// Use this to hand a freshly-uploaded object's path to an external service (e.g. Dagger)
490    /// without giving that service any Scout credentials. The caller must be authorized to
491    /// read the workspace that owns the path (encoded as the first segment of the object key).
492    #[endpoint(
493        method = POST,
494        path = "/upload/v1/sign-download",
495        name = "signDownload",
496        produces = conjure_http::server::StdResponseSerializer
497    )]
498    async fn sign_download(
499        &self,
500        #[auth]
501        auth_: conjure_object::BearerToken,
502        #[body(deserializer = conjure_http::server::StdRequestDeserializer)]
503        request: super::super::super::super::objects::ingest::api::SignDownloadRequest,
504    ) -> Result<
505        super::super::super::super::objects::ingest::api::SignDownloadResponse,
506        conjure_http::private::Error,
507    >;
508    /// Uploads a file to S3. Intended for smaller files.
509    #[endpoint(
510        method = POST,
511        path = "/upload/v1/upload-file",
512        name = "uploadFile",
513        produces = conjure_http::server::StdResponseSerializer
514    )]
515    async fn upload_file(
516        &self,
517        #[auth]
518        auth_: conjure_object::BearerToken,
519        #[query(
520            name = "fileName",
521            decoder = conjure_http::server::conjure::FromPlainDecoder,
522            log_as = "fileName"
523        )]
524        file_name: String,
525        #[query(
526            name = "sizeBytes",
527            decoder = conjure_http::server::conjure::FromPlainOptionDecoder,
528            log_as = "sizeBytes"
529        )]
530        size_bytes: Option<conjure_object::SafeLong>,
531        #[query(
532            name = "workspace",
533            decoder = conjure_http::server::conjure::FromPlainOptionDecoder
534        )]
535        workspace: Option<conjure_object::ResourceIdentifier>,
536        #[body(deserializer = conjure_http::server::conjure::BinaryRequestDeserializer)]
537        body: I,
538    ) -> Result<String, conjure_http::private::Error>;
539}