DASHBOARD APP 개발/Streamlit Library

Streamlit 기본 lib : Web화면에서 이미지, csv 파일 업로드 하기

신강희 2024. 5. 7. 15:55
728x90

< Web 화면에서 이미지, csv 파일 업로드 하기 >

# 기본적으로 모든 코드들은

def main() :
if __name__ == '__main__' :
    main()

ㄴ 이 기본형식 안에서 쓰여저야 실행된다. 혹시 실행이 되지 않을경우 하단에 마무리 코드를 적지 않았는지 확인!

 

# 웹 화면에 실행 확인은 생성한 파일명이나 혹은 연동한 app을 서버로 실행하여야 함.

# 터미널을 cmd로 열어 & streamli lit run 실행시킬서버명칭.py 로 실행후 always rerun 후 확인

 

< app7.py 로 작성 >

# 파일을 업로드 하는 방법
# 이미지 파일 업로드 , csv 파일 업로드

import streamlit as st
 
# 현재시간을 가져와서 유니크한 파일명 만드는데 사용하기 위한 라이브러리
from datetime import datetime
import pandas as pd
from PIL import Image

ㄴ 우선 임포트

 

# 디렉토리 정보와, 파일을 알려주면,
# 해당 디렉토리에 파일을 저장하는 함수.
def save_uploaded_file(directory, file):
    # 1. 디렉토리가 있는지 확인하여, 없으면 디렉토리부터 만든다.
    import os
    if not os.path.exists(directory) :
        os.makedirs(directory)
    # 2. 디렉토리가 존재하면, 파일을 저장한다.
    with open(os.path.join(directory, file.name), 'wb') as f:
        f.write(file.getbuffer())
    # 3. 저장이 완료되면, 유저한테 알린다.
    return st.success(f"{file.name}{directory}에 저장되었습니다.")

ㄴ 함수는 우선 os 모듈을 임포트하여 디렉토리를 확인하고 만든다.

ㄴ os.path.exists(directory)를 사용하여 주어진 디렉토리가 이미 존재하는지 확인하고, 존재하지 않으면 os.makedirs(directory)를 사용하여 디렉토리를 만든다.

ㄴ 파일을 저장하기 위해 open() 함수를 사용하고, 여기서 'wb'는 파일을 바이너리 쓰기 모드로 열겠다는 것을 의미

ㄴ file.getbuffer()를 사용하여 업로드된 파일의 내용을 읽고, 해당 내용을 새로 만든 파일에 사용한다.

ㄴ 마지막으로 저장이 완료되면, st.success()를 사용하여 사용자에게 파일이 성공적으로 저장되었다는 메시지 출력

 

def main() :
    # 사이드바 만들기
    st.title('파일 업로드 프로젝트')
    # 프론트/백앤드 코딩부터는 유지보수가 중요하기때문에 가독성을 좋게 하는게좋다. 수정할 부분이 적도록
    menu = ['이미지파일 업로드', 'csv 업로드', 'About']
   
    choice = st.sidebar.selectbox('메뉴', menu)

ㄴ 유저가 어떤 파일을 올릴지 선택하도록 사이드바로 생성

 

    # 그러므로 같은값을 변수안에 데이터로 적기보다 변수 위치로 하면 실제 menu안에 수정내용이 있더라도 해당 코드는 수정할 필요가 없다.
    if choice == menu[0] :
        st.subheader('이미지 파일 업로드!')

        file = st.file_uploader('이미지 파일 선택하세요.', type= ['jpg', 'png', 'jpeg'])

        # 유저가 올린 파일이 있을때만, 서버에 저장한다.
        if file is not None :
            print(file.name)
            print(file.size)
            print(file.type)

            # 파일을 서버에 저장하기 위해서는 먼저!
            # 파일 이름을 유니크하게 만들어서 바꿔줘야 한다.
            # 현재시간과 유저의 아이디를 조합해서 만드는게 실무에서 가장 많이 사용
            current_time = datetime.now()
            print( current_time.isoformat().replace(':', '_') + '.jpg' )
            new_filename = current_time.isoformat().replace(':', '_') + '.jpg'
            file.name = new_filename
            save_uploaded_file('image', file)

            st.image(file, use_column_width=True)

ㄴ 파일 형식은 대중적으로 쓰이는 타입을 모두 적어주면 좋다.

ㄴ 파일 이름을 현재 시간으로 유니크하게 설정하여 만드는 이유는 동일한 이미지 명칭을 가지고 있는 파일을 여러 유저가 동시에 올릴수도 있기 때문, 그럴 경우 현재시간으로 초단위까지 계산하여 적용하면 중복이미지로 오류가 날일이 없다.

 

# 임의의 이미지 파일 업로드

ㄴ 실제 저장되는것 확인

 

elif choice == menu[1] :

        st.subheader('CSV 파일 업로드')
        file = st.file_uploader('CSV 파일 선택하세요.', type='csv')

        if file is not None :

            # 파일명을 유니크하게 만들어서 저장한다.
            current_time = datetime.now()

            print( current_time.isoformat().replace(':','_') + '.csv' )

            new_filename = current_time.isoformat().replace(':','_') + '.csv'

            file.name = new_filename

            save_uploaded_file('data', file)

            st.dataframe( pd.read_csv(file) )
           
    elif choice == menu[2] :
        st.subheader('파일 업로드 프로젝트 입니다.')

 

# 실제 업로드

ㄴ 현재 날짜와 시간으로 저장된것 확인

 

### app7.py 전체 코드 ###

# 파일을 업로드 하는 방법
# 이미지 파일 업로드 , csv 파일 업로드

import streamlit as st
# 현재시간을 가져와서 유니크한 파일명 만드는데 사용하기 위한 라이브러리
from datetime import datetime
import pandas as pd

from PIL import Image

# 디렉토리 정보와, 파일을 알려주면,
# 해당 디렉토리에 파일을 저장하는 함수.
def save_uploaded_file(directory, file):
    # 1. 디렉토리가 있는지 확인하여, 없으면 디렉토리부터 만든다.
    import os
    if not os.path.exists(directory) :
        os.makedirs(directory)
    # 2. 디렉토리가 존재하면, 파일을 저장한다.
    with open(os.path.join(directory, file.name), 'wb') as f:
        f.write(file.getbuffer())
    # 3. 저장이 완료되면, 유저한테 알린다.
    return st.success(f"{file.name}{directory}에 저장되었습니다.")


def main() :
    # 사이드바 만들기
    st.title('파일 업로드 프로젝트')
    # 프론트/백앤드 코딩부터는 유지보수가 중요하기때문에 가독성을 좋게 하는게좋다. 수정할 부분이 적도록
    menu = ['이미지파일 업로드', 'csv 업로드', 'About']
   
    choice = st.sidebar.selectbox('메뉴', menu)

    print(choice)
    # 그러므로 같은값을 변수안에 데이터로 적기보다 변수 위치로 하면 실제 menu안에 수정내용이 있더라도 해당 코드는 수정할 필요가 없다.
    if choice == menu[0] :
        st.subheader('이미지 파일 업로드!')

        file = st.file_uploader('이미지 파일 선택하세요.', type= ['jpg', 'png', 'jpeg'])

        # 유저가 올린 파일이 있을때만, 서버에 저장한다.
        if file is not None :
            print(file.name)
            print(file.size)
            print(file.type)

            # 파일을 서버에 저장하기 위해서는 먼저!
            # 파일 이름을 유니크하게 만들어서 바꿔줘야 한다.
            # 현재시간과 유저의 아이디를 조합해서 만드는게 실무에서 가장 많이 사용
            current_time = datetime.now()
            print( current_time.isoformat().replace(':', '_') + '.jpg' )
            new_filename = current_time.isoformat().replace(':', '_') + '.jpg'
            file.name = new_filename
            save_uploaded_file('image', file)

            st.image(file, use_column_width=True)

    elif choice == menu[1] :

        st.subheader('CSV 파일 업로드')
        file = st.file_uploader('CSV 파일 선택하세요.', type='csv')

        if file is not None :

            # 파일명을 유니크하게 만들어서 저장한다.
            current_time = datetime.now()

            print( current_time.isoformat().replace(':','_') + '.csv' )

            new_filename = current_time.isoformat().replace(':','_') + '.csv'

            file.name = new_filename

            save_uploaded_file('data', file)

            st.dataframe( pd.read_csv(file) )
           
    elif choice == menu[2] :
        st.subheader('파일 업로드 프로젝트 입니다.')

if __name__ == '__main__' :
    main()

 

다음 게시글로 계속

반응형