Post

SK네트웍스 Family AI 캠프 1기 18주차 회고

SK Networks AI Camp

Main image

Weekly 회고 - 18주차

:warning: 포스트를 읽기 전에..
이 포스트는 SK네트웍스 Family AI 캠프를 다니면서 느낀 개인적인 생각을 정리한 포스트입니다.
배운 내용이나 스킬셋에 대한 설명은 별도로 작성하지 않았기 때문에, 그에 대한 정보는 다른 포스트를 참고해주세요!

:thumbsup:Liked

SK 네트웍스 Family AI 캠프 18주차 회고록입니다.
벌써 18주차 회고록을 쓰다니.. 시간이 정말 빠르네요!
이번 주엔 연세대학교에서 진행했던 취업박람회를 다녀왔습니다.
LG, 삼성, KT 등 여러 기업들이 원하는 인재 상에 대한 설명을 자세히 들었습니다.
준비할 게 정말 많다는 생각이 들기도 했는데, 생각보다 캠프에서 배운 것과 프로젝트 내용들이 기업에서 원하는 모습과 유사하다는 생각도 들어서 한편으로는 마음이 편하기도 했습니다!:grin:
이제 곧 최종 프로젝트인데 마지막까지 최선을 다해서 성공적으로 취업하고 싶습니다.


:books:Learned

이번 주는 AWS S3를 이용하여 웹페이지에서 파일을 업로드하고 다운받는 방법에 대해 배웠습니다.

image

LLM 프로젝트 때 논문 분석하는 웹 애플리케이션 서비스를 개발하고자 하는데, 해당 서비스 운영하려면 파일 업로드 기능과 업로드된 파일을 백엔드에서 다운받아 사용할 수 있어야 될 것 같아서 강사님께 별도로 부탁드렸습니다.
우선 Vue Frontend에서 아래와 같이 작성하여 파일을 선택하고 업로드 할 수 있도록 합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
<template>
    <div>
        <input type="file" @change="onFileChange" />
        <button @click="uploadFile">Upload</button>
        <button @click="listFiles">List Files</button>
        <div v-if="uploading">Uploading...</div>
        <div v-if="uploadSuccess">Upload Success! URL: </div>
        <div v-if="uploadError">Upload Error: </div>
        <ul v-if="fileList.length">
            <li v-for="file in fileList" :key="file.Key"></li>
        </ul>
    </div>
</template>

<script lang="ts">
import { defineComponent } from 'vue';
import { s3Client, env } from "@/utility/awsFileS3Config";
import { PutObjectCommand, ListObjectsCommand, DeleteObjectCommand, GetObjectCommand, PutObjectAclCommand, ObjectCannedACL } from '@aws-sdk/client-s3';

export default defineComponent({
    data() {
        return {
            selectedFile: null as File | null,
            uploading: false,
            uploadSuccess: false,
            uploadError: null as string | null,
            uploadedFileURL: '',
            fileList: [] as Array<{ Key: string }>,
            fileKey: ''
        };
    },
    methods: {
        onFileChange(event: Event) {
            const input = event.target as HTMLInputElement;
            if (input.files && input.files.length > 0) {
                this.selectedFile = input.files[0];
            }
        },
        async uploadFile() {
            if (!this.selectedFile) {
                alert('Please select a file first.');
                return;
            }

            this.uploading = true;
            this.uploadSuccess = false;
            this.uploadError = null;

            const params = {
                Bucket: 'text-chat-programmers-bucket',
                Key: this.selectedFile!.name,
                Body: this.selectedFile,
                ACL: 'private' as ObjectCannedACL
            };

            try {
                console.log('Uploading file with params:', params); // 디버깅 정보 추가
                const data = await s3Client.send(new PutObjectCommand(params));
                this.uploading = false;
                this.uploadSuccess = true;
                this.uploadedFileURL = `https://${params.Bucket}.s3.${env.s3.AWS_REGION}.amazonaws.com/${params.Key}`;
                this.fileKey = params.Key;
                console.log('File uploaded successfully:', data);
            } catch (err) {
                this.uploading = false;
                this.uploadError = (err as Error).message;
                console.error('Error uploading file:', err);
            }
        },
        async listFiles() {
            const params = {
                Bucket: 'text-chat-programmers-bucket'
            };

            try {
                const data = await s3Client.send(new ListObjectsCommand(params));
                this.fileList = data.Contents as Array<{ Key: string }>;
                console.log('Files listed successfully:', data);
            } catch (err) {
                console.error('Error listing files:', err);
            }
        },
        async deleteFile(key: string) {
            const params = {
                Bucket: 'text-chat-programmers-bucket',
                Key: key
            };

            try {
                const data = await s3Client.send(new DeleteObjectCommand(params));
                console.log('File deleted successfully:', data);
            } catch (err) {
                console.error('Error deleting file:', err);
            }
        },
        async getFile(key: string) {
            const params = {
                Bucket: 'text-chat-programmers-bucket',
                Key: key
            };

            try {
                const data = await s3Client.send(new GetObjectCommand(params));
                console.log('File retrieved successfully:', data);
            } catch (err) {
                console.error('Error getting file:', err);
            }
        },
        async setFileAcl() {
            const params = {
                Bucket: 'text-chat-programmers-bucket',
                Key: this.fileKey,
                ACL: 'public-read' as ObjectCannedACL
            };

            try {
                const data = await s3Client.send(new PutObjectAclCommand(params));
                console.log('ACL set successfully:', data);
            } catch (err) {
                console.error('Error setting ACL:', err);
            }
        }
    }
});
</script>

<style scoped>
/* 스타일 정의 */
</style>

그 후 업로드한 파일을 백엔드에서 아래와 같이 작성하여 다운로드 받습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
async def downloadFileFromS3(self, fileKey):
    aws_access_key_id = os.getenv('AWS_ACCESS_KEY_ID')
    aws_secret_access_key = os.getenv('AWS_SECRET_ACCESS_KEY')
    region_name = os.getenv('AWS_REGION')
    bucket_name = os.getenv('BUCKET_NAME')

    s3 = boto3.client(
        's3',
        aws_access_key_id=aws_access_key_id,
        aws_secret_access_key=aws_secret_access_key,
        region_name=region_name
    )

    if not os.path.exists(os.path.join(os.getcwd(), self.DOWNLOAD_PATH)):
        os.mkdir(os.path.join(os.getcwd(), self.DOWNLOAD_PATH))

    downloadedFileName = os.path.join(os.path.join(os.getcwd(), self.DOWNLOAD_PATH), fileKey)

    # 파일 다운로드 실행
    s3.download_file(bucket_name, fileKey, downloadedFileName)

    print(f"File downloaded to {downloadedFileName}")

이 부분을 프로젝트에 붙인다면 다음과 같이 사용할 것 같습니다. 우선 사용자가 웹에 PDF 형식의 논문을 업로드합니다. 그 후 DLLS에서 논문을 내려받고 텍스트로 변환하도록 합니다.
텍스트를 전처리하고 RAG를 사용하기 위해 벡터로 변환합니다.
해당 벡터를 참조하여 LLM 모델이 사용자의 질문에 올바른 답변을 생성하도록 합니다.


:face_with_spiral_eyes:Lacked

이번 주는 취업 고민이 많았습니다.:sob:
수업 이외에 이것 저것 준비할 것이 많아서 수업에 집중을 못한 것 같습니다.
이번 달에 이력서 제출 할 곳이 많은데 이력서 마무리되는대로 다시 화이팅해보겠습니다!:fire:


:thought_balloon:Longed for

최종 프로젝트 팀 및 멘토님이 결정되었습니다!
멘토님 피드백을 최대한 반영해서 성공적인 서비스를 구축해보도록 하겠습니다.
다들 마지막까지 화이팅하세요!

This post is licensed under CC BY 4.0 by the author.