W
Wasp-lang•2mo ago
cmilazzo

s3 integration to existing project

Hi there. I created a project that initially didn't have a need for S3, so it was left out. However, now I need to add the ability to upload files and store them. The tutorials for S3 seem to all assume the libraries are there from the start. Is there a way to add file upload support to an existing project? #đŸ™‹questions #aws #fileupload
7 Replies
kapa.ai
kapa.ai•2mo ago
Hi @cmilazzo. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- Yes, you can add file upload support to your existing project using AWS S3. Here are the steps you can follow: 1. First, go to S3 and set up a bucket and IAM user, then add these entries to your .env.server file.
AWS_S3_IAM_ACCESS_KEY=
AWS_S3_IAM_SECRET_KEY=
AWS_S3_FILES_BUCKET=
AWS_S3_REGION=
AWS_S3_IAM_ACCESS_KEY=
AWS_S3_IAM_SECRET_KEY=
AWS_S3_FILES_BUCKET=
AWS_S3_REGION=
2. Add the AWS SDK to your list of dependencies.
dependencies: [
...
("aws-sdk", "^2.1294.0"),
...
]
dependencies: [
...
("aws-sdk", "^2.1294.0"),
...
]
3. In your front end, set up the functions for downloading and uploading files.
const handleUploadFile = async () => {
...
let data = await getUploadFileSignedURL(...);
// key is the identifier of the file in S3
const { uploadUrl, key } = data;
// upload the actual file using the signed URL, newFile here is the file selected in the form
await axios.put(uploadUrl, newFile);
// store the key as a field of a file entity for later retrieval
...
}
const handleUploadFile = async () => {
...
let data = await getUploadFileSignedURL(...);
// key is the identifier of the file in S3
const { uploadUrl, key } = data;
// upload the actual file using the signed URL, newFile here is the file selected in the form
await axios.put(uploadUrl, newFile);
// store the key as a field of a file entity for later retrieval
...
}
4. For downloading files, you can use a similar function.
const handleDownloadFile = async (file) => {
...
let downloadUrl = await getDownloadFileSignedURL(...);
// ignore my ugly code below, its a workaround I had to do due to how I had setup my UI
var link = document.createElement("a");
link.download = file.filename;
link.href = downloadUrl;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
...
}
const handleDownloadFile = async (file) => {
...
let downloadUrl = await getDownloadFileSignedURL(...);
// ignore my ugly code below, its a workaround I had to do due to how I had setup my UI
var link = document.createElement("a");
link.download = file.filename;
link.href = downloadUrl;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
...
}
5. If you are generating files on the server (reports, images etc.) and need to store them, you can use the @aws-sdk/client-s3 library.
import { S3Client, PutObjectCommand } from "@aws-sdk/client-s3";

const S3 = new S3Client({
region: "auto",
endpoint: process.env.R2_BUCKET_URL,
credentials: {
accessKeyId: process.env.R2_ACCESS_TOKEN!,
secretAccessKey: process.env.R2_SECRET_TOKEN!,
},
});
const upload = await S3.send(
new PutObjectCommand({
Bucket: "<bucket_name>",
Key: key,
Body: response.data,
// If uploading images for example
ContentType: "image/png",
})
);
import { S3Client, PutObjectCommand } from "@aws-sdk/client-s3";

const S3 = new S3Client({
region: "auto",
endpoint: process.env.R2_BUCKET_URL,
credentials: {
accessKeyId: process.env.R2_ACCESS_TOKEN!,
secretAccessKey: process.env.R2_SECRET_TOKEN!,
},
});
const upload = await S3.send(
new PutObjectCommand({
Bucket: "<bucket_name>",
Key: key,
Body: response.data,
// If uploading images for example
ContentType: "image/png",
})
);
Please note that you might need to adjust the code snippets to fit your project's structure and requirements. For more details, you can refer to the Github Issue (https://github.com/wasp-lang/wasp/issues/494) where these steps were discussed. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ---------------------- Sorry @cmilazzo, I seem to be having a bit of trouble. Don't worry though, I've pinged my support and they will try to fix me up! :technologist: Perhaps try again in 15mins?
cmilazzo
cmilazzoOP•2mo ago
can you give more detail on the handleUploadFileSignedURL function call in the example?
Filip
Filip•2mo ago
Hey @cmilazzo, I see that the bot is talking about how to set up S3 on AWS, which is a little beside the point. Let me try to answer instead. What do you mean by being left out? Did you delete the s3-related functionality? If so, just copy what you need from the repo (for example, this file) and follow the tutorial on the site: https://docs.opensaas.sh/guides/file-uploading/#using-aws-s3 Let me know if you run into any roadblocks
cmilazzo
cmilazzoOP•2mo ago
Hey @sodic. Thanks for the hint. I actually generated my starting point using the AI, and it never included any of the S3 libraries. I just copied them from the repo as you suggested. It would be wonderful to have a way to add entire libraries like this (may a command line addition for wasp?) if you discover you need them after a project is under way. For example, I don't have any of the Stripe libraries in my project now, but in the future I might want to add them and it'd be wonderful to have all the config and the libraries added automatically....
Filip
Filip•2mo ago
Oh, I see, you used mage to generate the pap, not OpenSaas. Glad you got it working Yes, that's a good idea, adding official recipes. We've already had it on the roadmap for quite some time, but I can't for the life of me find the issue that talks about them now. @martinsos How did we call these things (boilerplate code that user can add with a command)? I thought it was recipes, but I can't find the issue. Can you find it?
miho
miho•2mo ago
We've already had it on the roadmap for quite some time, but I can't for the life of me find the issue that talks about them now.
We even had a PR in progress at some point, but didn't merge it due to some blockers IIRC. Great idea that we should implement!
martinsos
martinsos•2mo ago
Right here is the stuck PR https://github.com/wasp-lang/wasp/pull/1453 ! I also couldn't find the issue though. Tricky thing with this is that it can be hard to add such funcionality to the project that might have changed somewhat, but still, it is interesting to explore. I think full stack modules also might be possible solution to stuff like this (also future feature)
Want results from more Discord servers?
Add your server