[Streamlit] 파일 업로드 | 모듈화

원준·2023년 5월 26일
0

Streamlit

목록 보기
11/13
post-custom-banner

Main 코드 간략화

  • Main의 코드들이 유지보수를 하는데 있어서 코드가 길어 수정하기가 쉽지 않는 문제가 생기는데, 이걸 방지 하기 위해 특정 행동 코드들을 모듈로 변화해 함수화 시키는 것이 좋다.
  • 모듈화 시킬 코드

이미지 업로드 모듈화

  • 이미지 업로드 하는 코드들을 모아서 새롭게 만든 .py의 함수에 넣는다.

    # app8_image.py 만듦
    import streamlit as st
    from datetime import datetime
    from app8_folder.app8_utills import save_uploaded_file
    # 파일 업로드 함수
    # 디렉토리 이름, 파일을 주면 해당 디렉토리에 파일을 저장해주는 함수
    
    def run_app8_image():
        st.subheader('이미지 파일 업로드')
    
      img_file = st.file_uploader('이미지를 업로드 하세요.', type=['png', 'jpg', 'jpeg'])
      if img_file is not None: # 파일이 없는 경우는 실행 하지 않음
    
          # 유저가 올린 파일을,
          # 서버에서 처리하기 위해서(유니크하게) 
          # 파일명을 현재 시간 조합으로 만든다. 
          current_time = datetime.now()
          print(current_time)
          print(current_time.isoformat().replace(':', "_") + '.jpg') #문자열로 만들어 달라
          # 파일 명에 특정 특수문자가 들어가면 만들수 없다.
          filename = current_time.isoformat().replace(':', "_") + '.jpg'
          img_file.name = filename
    
          save_uploaded_file('image', img_file)
    
          st.image(f'image/{img_file.name}')
    # main()으로 돌아가는 app8.py import 및 함수 추가
    from app8_folder.app8_image import run_app8_image
    
    # main() 변경
    if choice == menu[0]:
          run_app8_image() # 해당 함수를 추가한다.
  • 해당 방법을 사용하는데 있어서 1가지 문제점이 있는데, CSV업로드 파일 모듈을 만들때 파일을 저장하는 함수또한 중복되어서 사용되다보니 같은 코드를 적어야하는 일이 많아 진다.

    • 이를 해결하기 위해 파일을 저장하는 함수도 파일로 만들어 모듈화 시키는 것이 좋다.
    # app8_utills.py 로 만든다.
    # app8_utills.py
    import streamlit as st
    import os
    
    # 파일 업로드 함수가 계속해서 반복되다보니 파일로 만들어서 작성한다.
    def save_uploaded_file(directory, file):
        # 1. 저장할 디렉토리(폴더) 있는지 확인
        #   없다면 디렉토리를 먼저 만든다.
        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())
        return st.success('파일 업로드 성공!')
    # app8_image.py 파일에 import를 추가한다.
    from app8_folder.app8_utills import save_uploaded_file

CSV 업로드 모듈화

  • 이미지 업로드 모듈화 처럼 똑같은 방법으로 만들어 주면된다.

    # app8_csv.py를 만든다.
     import streamlit as st
     from datetime import datetime
     import pandas as pd
    
     from app8_folder.app8_utills import save_uploaded_file
    
     def run_app8_csv():
         st.subheader('csv 파일 업로드 ')
    
         csv_file = st.file_uploader('CSV 파일 업로드', type=['csv'])
    
         print(csv_file)
         if csv_file is not None:
             current_time = datetime.now()
             filename = current_time.isoformat().replace(':', '_') + '.csv'
    
             csv_file.name = filename
    
             save_uploaded_file('csv', csv_file)
    
             # csv를 보여주기 위해 pandas 데이터 프레임으로 만들어야한다.
             df = pd.read_csv('csv/'+filename)
             st.dataframe(df)
    # 만든 csv 파일 모듈화를 app8.py의 import
    from app8_folder.app8_csv import run_app8_csv
    
    # main()에 해당 하는 함수를 넣으면 완성이다.
    elif choice == menu[1]:
           run_app8_csv()

완성 경로, 코드

  • about에는 따로 아무것도 없다.

1. app8.py

import streamlit as st # 프레임 워크

from app8_folder.app8_image import run_app8_image
from app8_folder.app8_csv import run_app8_csv
from app8_folder.app8_about import run_app8_about

# 기본 형식
def main():
    st.title('앱 데시보드')

    menu = ['이미지 업로드', 'csv 업로드', 'About']

    choice = st.sidebar.selectbox('메뉴', menu)
    
    if choice == menu[0]:
        run_app8_image()

    elif choice == menu[1]:
        run_app8_csv()

    else :
        run_app8_about()

if __name__ == '__main__':
    main()

2. app8_image.py

import streamlit as st
from datetime import datetime
from app8_folder.app8_utills import save_uploaded_file
# 파일 업로드 함수
# 디렉토리 이름, 파일을 주면 해당 디렉토리에 파일을 저장해주는 함수

def run_app8_image():
    st.subheader('이미지 파일 업로드')

    img_file = st.file_uploader('이미지를 업로드 하세요.', type=['png', 'jpg', 'jpeg'])
    if img_file is not None: # 파일이 없는 경우는 실행 하지 않음
        print(type(img_file))
        print(img_file.name)
        print(img_file.size)
        print(img_file.type)

        # 유저가 올린 파일을,
        # 서버에서 처리하기 위해서(유니크하게) 
        # 파일명을 현재 시간 조합으로 만든다. 
        current_time = datetime.now()
        print(current_time)
        print(current_time.isoformat().replace(':', "_") + '.jpg') #문자열로 만들어 달라
        # 파일 명에 특정 특수문자가 들어가면 만들수 없다.
        filename = current_time.isoformat().replace(':', "_") + '.jpg'
        img_file.name = filename

        save_uploaded_file('image', img_file)

        st.image(f'image/{img_file.name}')

3. app8_csv.py

import streamlit as st
from datetime import datetime
import pandas as pd

from app8_folder.app8_utills import save_uploaded_file

def run_app8_csv():
    st.subheader('csv 파일 업로드 ')

    csv_file = st.file_uploader('CSV 파일 업로드', type=['csv'])

    print(csv_file)
    if csv_file is not None:
        current_time = datetime.now()
        filename = current_time.isoformat().replace(':', '_') + '.csv'

        csv_file.name = filename

        save_uploaded_file('csv', csv_file)

        # csv를 보여주기 위해 pandas 데이터 프레임으로 만들어야한다.
        df = pd.read_csv('csv/'+filename)
        st.dataframe(df)

4. app8_utills.py

import streamlit as st
import os


# 파일 업로드 함수가 계속해서 반복되다보니 파일로 만들어서 작성한다.
def save_uploaded_file(directory, file):
    # 1. 저장할 디렉토리(폴더) 있는지 확인
    #   없다면 디렉토리를 먼저 만든다.
    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())
    return st.success('파일 업로드 성공!')
profile
공부해보자
post-custom-banner

0개의 댓글