본문 바로가기
Streamlit

Streamlit - 사이드바, 유저에게 파일 받기

by 하니__ 2024. 4. 24.
def save_uploaded_file(directory, file) :

    import os
    if not os.path.exists(directory) :
        os.makedirs(directory)

    with open(os.path.join(directory,file.name), 'wb') as f: # write binary
        f.write(file.getbuffer())
        
    return st.info(f"{file.name}이 {directory}에 저장 되었습니다.")

파일 업로드 및 저장을 위한 함수를 먼저 만들어준다

함수가 출력 되면

if not os.path.exists(directory) :
    os.makedirs(directory)

를 통해 디렉토리가 있는지 확인후 없으면 디렉토리를 만들고

with open(os.path.join(directory,file.name), 'wb') as f: # write binary
    f.write(file.getbuffer())

를 통해 해당 디렉토리에 들어가

파일이 존재한다면 파일을 저장하고

return st.info(f"{file.name}이 {directory}에 저장 되었습니다.")

을 통해서 저장이 완료됐다는것을 메세지로 알린다

 

 

 

사이드바 만들기
def main() :

    st.title('파일 업로드 프로젝트')
    sidebar_menu = ['이미지파일 업로드','csv파일 업로드','About']
    
    
    choice = st.sidebar.selectbox('메뉴', sidebar_menu)

.sidebar.selectbox(  ) 함수를 이용하여

사이드바에 셀렉트박스를 만든다

 

 

이렇게 형성 된다

 

 

if choice == sidebar_menu[0]:
        st.subheader('이미지 파일 업로드')
        file = st.file_uploader('이미지 파일 선택하세요',type = ['png','jpg','jpeg','webp'])
        
        if file is not None : # 유저가 올린 파일이 있을때만
            print(file.name) # 이 프린트 함수들은
            print(file.size) # 웹 화면에는 보이지않는
            print(file.type) # 개발자의 터미널에만 찍히는 디버깅용이다
            
            # 파일을 서버에 저장하기 위해서는 먼저
            # 파일 이름을 유니크하게 만들어서 바꿔줘야 한다
            # 현재 시간과 유저의 아이디를 조합하여 만드는게 실무에서 가장 많이 사용
            current_time = datetime.now()
            print(current_time.isoformat().replace(':' , '_') + '.png')
            
            new_filename = current_time.isoformat().replace(':' , '_') + '.png'
            file.name = new_filename
            
            save_uploaded_file('image', file) # 저장하라
            st.image(file)
if choice == sidebar_menu[0]:
        st.subheader('이미지 파일 업로드')
        file = st.file_uploader('이미지 파일 선택하세요',type = ['png','jpg','jpeg','webp'])

if 조건문

위에서 사이드바 메뉴를 선택하는것을 choice로 저장했기에

사이드바메뉴 0번을 눌렀다면~ 이라고 해석되며

즉, 이미지 파일 업로드를 눌렀다면 으로 인식이 되고

서브헤더를 이용하여 텍스트가 나오고

파일업로더를 이용하여 png,jpg,jpeg,webp 파일만을 받을 수 있는 업로드 창이 생기게 된다

이후

current_time = datetime.now()
            
new_filename = current_time.isoformat().replace(':' , '_') + '.png'
file.name = new_filename
            
save_uploaded_file('image', file) # 저장하라
st.image(file)

 

그림을 저장할때에 여러사람이 같은 이름으로 저장한 파일을 업로드 하면

덮어씌워지면서 파일이 변형이 되는것을 막고자

업로드 될때에 현재 시간으로 파일이름을 변환한다

 

그 과정은

우선 현재 시간을 나타내는 datetime.now( )를 current_time으로 변수 저장 후

iso포맷으로 나타내게 함과 동시에 시간에 : 콜론으로 찍히는것을 _ 언더바로 나오게 변환

그리고 파일이름에 png가 찍히도록 + 해준다

그리고 그것을 새로운 파일 이름이 되도록 변수저장 해준다

 

이후

파일을 저장할때 이름이 변환되어 저장되며,

위에서 리턴되게 만들었던 저장이 완료되었다는 메세지와 함께

저장한 사진을 보여준다

 

 

 

 

 

CSV 파일을 저장할때는 어떨까

 

    elif choice == sidebar_menu[1]:
        st.subheader('CSV 파일 업로드')
        file = st.file_uploader('CSV 파일 선택하세요', type = 'csv')
        
        if file is not None : # 파일이 있으면 위와같이 파일명을 유니크하게 만들어 저장하라
            current_time = datetime.now()
            new_filename = current_time.isoformat().replace( ':' , '_') + '.csv'
            file.name = new_filename
            
            save_uploaded_file('data' , file)
            
            st.dataframe(pd.read_csv(file))

 

순서는 똑같다 다만 달라진것은

type이 csv만을 받는다는 것과

이미지파일은 이미지폴더에 저장되고

csv 파일은 data폴더에 저장되도록 설정했다는것 정도

똑같이 파일이 저장되면

데이터프레임의 모습이 보여지도록 만들었다