반응형
반응형

TIOBE Index for June 2025

 

python

 

https://www.tiobe.com/tiobe-index/

 

TIOBE Index - TIOBE

Home » TIOBE Index TIOBE Index for June 2025 June Headline: Where is SQL going? SQL has a remarkable history in the TIOBE index. When the TIOBE index started in 2001, SQL was one of the 20 languages that were tracked. It was a serious top 10 player at tha

www.tiobe.com

 

반응형
반응형

[python] 파이썬 requirements.txt 처리

 

파이썬 프로젝트에서 requirements.txt 파일은 프로젝트가 의존하는 모든 외부 라이브러리(패키지)의 목록을 관리하는 데 사용되는 표준 방식입니다. 이 파일을 사용하면 개발 환경을 일관되게 유지하고, 다른 개발자나 배포 환경에서도 동일한 의존성을 쉽게 설치할 수 있습니다.


requirements.txt의 역할과 중요성

requirements.txt는 주로 다음과 같은 목적으로 사용됩니다:

  • 의존성 관리: 프로젝트에 필요한 모든 라이브러리와 그 버전을 명확하게 기록합니다.
  • 재현성 확보: 특정 시점의 개발 환경을 다른 컴퓨터나 환경에서도 정확하게 재현할 수 있게 합니다.
  • 협업 용이: 팀원들이 동일한 라이브러리 버전을 사용하여 개발할 수 있도록 도와 충돌을 방지합니다.
  • 배포 환경 설정: 애플리케이션을 서버나 컨테이너(Docker 등)에 배포할 때 필요한 의존성을 자동으로 설치할 수 있게 합니다.

requirements.txt 파일 생성 및 관리

1. 수동으로 파일 작성하기

가장 기본적인 방법은 필요한 라이브러리 이름을 직접 requirements.txt 파일에 한 줄에 하나씩 작성하는 것입니다. 특정 버전이나 최소 버전을 명시할 수도 있습니다.

 

# requirements.txt 예시
requests==2.31.0      # requests 라이브러리 버전 2.31.0 지정
beautifulsoup4>=4.9.3 # beautifulsoup4 라이브러리 버전 4.9.3 이상
pandas                # pandas 라이브러리 최신 버전 설치
numpy~=1.23.0         # numpy 라이브러리 1.23.x 버전 중 최신 설치 (1.23.0 <= version < 1.24.0)
  • ==: 정확한 버전 지정 (가장 안전하지만 유연성이 떨어짐)
  • >=: 최소 버전 지정
  • ~=: 호환 가능한 릴리스(Compatible release) 지정. ~=1.23.0은 1.23.0 이상 1.24.0 미만 버전을 의미합니다. 마이너 버전 업데이트는 허용하지만 메이저 버전 업데이트는 방지합니다.
  • 버전 지정이 없으면 pip는 항상 최신 버전을 설치합니다.

2. 현재 환경의 라이브러리 목록 내보내기

현재 파이썬 환경(가상 환경)에 설치된 모든 라이브러리 목록을 requirements.txt 파일로 자동 생성할 수 있습니다.

pip freeze > requirements.txt
  • 이 명령은 현재 환경에 설치된 모든 패키지와 그 정확한 버전을 requirements.txt 파일에 기록합니다.
  • 주의할 점은 프로젝트에 직접적으로 필요한 라이브러리뿐만 아니라, 그 라이브러리들이 의존하는 다른 라이브러리(하위 의존성)까지 모두 포함된다는 것입니다. 따라서 파일이 상당히 길어질 수 있습니다.
  • 팁: 새로운 프로젝트를 시작할 때는 깨끗한 가상 환경에서 필요한 라이브러리만 pip install로 설치하고, 개발이 완료될 시점에 pip freeze > requirements.txt를 실행하여 해당 프로젝트에 정확히 필요한 의존성만 기록하는 것이 좋습니다.

requirements.txt 파일 처리 (라이브러리 설치)

requirements.txt 파일에 명시된 모든 라이브러리를 설치하려면 다음 명령어를 사용합니다.

pip install -r requirements.txt

 

  • 이 명령은 requirements.txt 파일을 읽어 거기에 명시된 모든 라이브러리를 한 번에 다운로드하고 설치합니다.
  • 권장 사항: 항상 가상 환경(Virtual Environment) 내에서 이 작업을 수행하세요. 가상 환경을 사용하면 프로젝트별로 독립적인 의존성 관리가 가능하여 시스템 전체의 파이썬 환경과 충돌하는 것을 방지할 수 있습니다.
# 1. 가상 환경 생성 (처음 한 번만)
python -m venv my_project_env # 또는 conda create -n my_project_env python=3.9

# 2. 가상 환경 활성화
# Windows: .\my_project_env\Scripts\activate
# macOS/Linux: source my_project_env/bin/activate
# Conda: conda activate my_project_env

# 3. requirements.txt 파일이 있는 디렉토리로 이동
# cd /path/to/your/project

# 4. 라이브러리 설치
pip install -r requirements.txt

 

 

requirements.txt 관리 팁

  • 가상 환경 사용: 위에서 강조했듯이, 모든 파이썬 프로젝트는 전용 가상 환경 내에서 관리하는 것이 표준이자 가장 좋은 방법입니다.
  • 개발/배포 의존성 분리: 프로젝트 규모가 커지면 개발(테스트 프레임워크, 린터 등)에만 필요한 라이브러리와 실제 배포에 필요한 라이브러리를 분리하여 여러 개의 requirements 파일을 만들기도 합니다.
    • requirements.txt (배포용 필수 라이브러리)
    • requirements-dev.txt (개발용 라이브러리)
    • 설치할 때는 pip install -r requirements.txt -r requirements-dev.txt 와 같이 여러 파일을 지정할 수 있습니다.
  • 버전 고정의 장단점:
    • 장점: requests==2.31.0처럼 정확히 버전을 고정하면 다른 환경에서 설치할 때 버전에 따른 호환성 문제가 발생할 확률이 매우 낮아집니다.
    • 단점: 새롭게 발견된 버그 수정이나 보안 패치가 적용된 최신 버전의 이점을 누리기 어렵습니다.
  • 업데이트: 시간이 지나면서 라이브러리를 업데이트해야 할 경우, requirements.txt 파일의 버전을 직접 수정하거나, pip install --upgrade <package_name>으로 개별 패키지를 업데이트한 후 pip freeze > requirements.txt를 다시 실행하여 반영할 수 있습니다.

requirements.txt 파일은 파이썬 프로젝트의 건강한 생태계를 유지하는 데 필수적인 도구입니다.

 

 

 

반응형
반응형

[Python] 파이썬 python 데이터 처리 위한 기본 설치 라이브러리

 

1. Anaconda 설치  https://www.anaconda.com/download

 

pip install numpy pandas matplotlib seaborn scikit-learn

 

 

반응형
반응형

[python] List of running process using python

import psutil

def listProcesses():
    for proc in psutil.process_iter():
        try:
            pinfo = proc.as_dict(attrs=['pid', 'name'])
        except psutil.NoSuchProcess:
            pass
        else:
            print(pinfo)

반응형
반응형

[python] zimport - 수많은 python 패키지를 압축하여 관리 (github.com/waveware4ai)

 

python 패키지를 관리하다 보면 수많은 파일들이 부담스러울때 필요한 zimport 를 소개합니다.

소개

  • zimport는 Python의 표준 zipimport를 대체하고 개선한 도구입니다.
  • zimport는 zip-archives에서 Python 패키지를 로드하고 관리하는 데 사용됩니다. 즉, Java jar처럼 Python 패키지를 관리할 수 있습니다. 또한 동적 라이브러리(.dll, .pyd, .so) 로드도 지원합니다.
  • 이 도구를 만들고 저의 python 작업 디렉토리는 약 160gb, 수백만개 파일에서 80G 1만 개 수준으로 줄어 들었습니다.

주요기능

  • zip-archive에서 동적 라이브러리 로딩 지원(.pyd, .dll, .so, .dylib)
  • zip-archive에서 내부 read() 시에 Java의 getresource처럼 내부 파일(예: 환경 파일) 읽기 지원
  • 컴파일된 .pyc 파일 지원(name.cpython-version.pyc 및 pycache 폴더)

사용된기술

  • importlib, meta_path, path_hooks
  • function intercept (standard open, stat, read, ctypes.WinDLL, ctypes.CDLL 등)

사용환경

  • python win/linux/macosx 지원
  • python version 3.8~3.12 지원

사용방법

python -m pip install zimport
import zimport

  • lib/site-package 디렉토리에서 패키지를 한꺼번에 압축하고, sys.path 에 추가하기만 하면 정상적으로 작동합니다.
  • 물론, 시간의 여유가 되신다면 패키지별로 압축하여, java 의 jar 처럼 의존성에 따라서 패키지를 sys.path 에 추가해 주시면 됩니다.
  • 또한 한번 압축된 package 는 share 하여 쓸수 있기 때문에 하드디스크 공간의 낭비를 줄여줄수 있다고 생각합니다.

마지막으로

  • 소스는 github 에 공개하였으며 현재 버전은 0.1.4 입니다. 몇몇 package (예를들어 transformers) 아직 지원하지 안으며, torch, torchvision, numpy, pandas 와 같은 major 패키지는 이상없이 동작함을 확인하였습니다.

https://github.com/waveware4ai/zimport

  • 또한, portable python 과 아주 궁합이 잘맞습니다. 이것도 github 에 업로드 하였습니다. linux 버전은 직접 컴파일하였고, windows 버전은 embeded 를 개작하였습니다.

https://github.com/waveware4ai/PortablePython

  • 사용시 발생하는 버그나 문제점들은 리포팅해주시면 개선하도록 하겠습니다.

반응형
반응형

[python] 유튜브 자막 가져오기 

 

 

""" 유튜브 자막 가져오기 
    pip install youtube-transcript-api
    
    -- 최신 버전으로 업데이트
    pip install --upgrade youtube-transcript-api

    https://www.youtube.com/watch?v=XyljmT8dGA4
    
    자막있는 동영상 : https://www.youtube.com/watch?v=zRz9q8dPjC4
"""


from youtube_transcript_api import YouTubeTranscriptApi
# youtube_transcript_api._errors 에서 TooManyRequests를 제외하고 임포트합니다.
# TooManyRequests는 더 이상 직접 임포트할 수 없는 것으로 보입니다.
from youtube_transcript_api._errors import NoTranscriptFound, TranscriptsDisabled, VideoUnavailable

def get_youtube_transcript(video_id, languages=['ko', 'en']):
    """
    주어진 YouTube 동영상 ID와 언어 목록에 대해 자막을 가져옵니다.
    자동 생성 자막과 공식 자막을 모두 시도합니다.
    """
    try:
        # 우선 공식 자막을 시도
        transcript_list = YouTubeTranscriptApi.list_transcripts(video_id)

        # 사용 가능한 언어 목록에서 요청한 언어 중 하나를 찾아 가져옵니다.
        chosen_transcript = None
        for lang_code in languages:
            for transcript in transcript_list:
                if transcript.language_code == lang_code:
                    chosen_transcript = transcript
                    break
            if chosen_transcript:
                break

        if chosen_transcript:
            print(f"[{video_id}] {chosen_transcript.language} ({chosen_transcript.language_code}) 자막을 가져옵니다.")
            # fetch()는 이제 FetchedTranscript 객체를 반환하며, 이는 이터러블합니다.
            transcript_segments = chosen_transcript.fetch()
            return transcript_segments
        else:
            raise NoTranscriptFound(
                f"No suitable official transcript found for video {video_id} in languages {languages}.",
                video_id
            )

    except NoTranscriptFound:
        print(f"[{video_id}] 공식 자막을 찾을 수 없습니다. 자동 생성 자막을 시도합니다.")
        try:
            for lang_code in languages:
                try:
                    # get_transcript() 역시 이터러블한 객체를 반환하는 것으로 가정합니다.
                    transcript_segments = YouTubeTranscriptApi.get_transcript(video_id, languages=[lang_code], preserve_formatting=True)
                    print(f"[{video_id}] {lang_code} 자동 생성 자막을 가져왔습니다.")
                    return transcript_segments
                except NoTranscriptFound:
                    continue # 다음 언어로 시도
            print(f"[{video_id}] 요청된 언어 ({languages})로 자동 생성 자막도 찾을 수 없습니다.")
            return None # 적합한 자막을 찾지 못함
        except TranscriptsDisabled:
            print(f"[{video_id}] 이 동영상은 자막이 비활성화되어 있습니다.")
            return None
        except VideoUnavailable:
            print(f"[{video_id}] 동영상을 사용할 수 없거나 비공개/삭제되었습니다.")
            return None
        except Exception as e: # TooManyRequests를 포함한 모든 예외를 잡습니다.
            # 이 부분에서 TooManyRequests 에러를 포함하여 일반적인 오류를 처리합니다.
            print(f"[{video_id}] 자막을 가져오는 중 예기치 않은 오류가 발생했습니다: {e}")
            return None

    except TranscriptsDisabled:
        print(f"[{video_id}] 이 동영상은 자막이 비활성화되어 있습니다.")
        return None
    except VideoUnavailable:
        print(f"[{video_id}] 동영상을 사용할 수 없거나 비공개/삭제되었습니다.")
        return None
    except Exception as e: # TooManyRequests를 포함한 모든 예외를 잡습니다.
        # 이 부분에서 TooManyRequests 에러를 포함하여 일반적인 오류를 처리합니다.
        print(f"[{video_id}] 자막을 가져오는 중 예기치 않은 오류가 발생했습니다: {e}")
        return None


if __name__ == "__main__":
    # 예시 동영상 ID (실제 존재하는 동영상 ID로 변경해야 합니다)
    # 제가 추천해 드렸던 URL에서 ID를 추출했습니다.
    video_id_with_subtitle = "XyljmT8dGA4" # "모바일 유튜브 자동번역 한글자막 보는 방법"
    video_id_auto_caption = "XyljmT8dGA4" # 짧은 영상 (자동 생성 자막 가능성)
    #video_id_invalid = "invalid_video_id_123"
    video_id_invalid = "XyljmT8dGA4"

    print("--- 예제 1: 자막이 있는 동영상 ---")
    transcript_data = get_youtube_transcript(video_id_with_subtitle, languages=['ko', 'en'])
    if transcript_data:
        # segment.start, segment.duration, segment.text와 같이 속성으로 접근합니다.
        for i, segment in enumerate(transcript_data[:5]): # 슬라이싱은 여전히 가능해야 합니다.
            print(f"[{segment.start:.2f}-{segment.start + segment.duration:.2f}] {segment.text}")
        print(f"... (총 {len(list(transcript_data))}개 세그먼트)") # len()을 위해 list로 변환

        # 전체 자막 텍스트만 추출하고 싶다면:
        full_text = " ".join([segment.text for segment in transcript_data])
        print("\n--- 전체 자막 텍스트 (예제 1) ---")
        print(full_text[:500] + "...")
    else:
        print("자막을 가져오지 못했습니다.")

    print("\n--- 예제 2: 자동 생성 자막을 시도할 수 있는 동영상 ---")
    transcript_data_auto = get_youtube_transcript(video_id_auto_caption, languages=['en', 'ko'])
    if transcript_data_auto:
        for i, segment in enumerate(transcript_data_auto[:5]):
            print(f"[{segment.start:.2f}-{segment.start + segment.duration:.2f}] {segment.text}")
        print(f"... (총 {len(list(transcript_data_auto))}개 세그먼트)")
    else:
        print("자막을 가져오지 못했습니다.")

    print("\n--- 예제 3: 존재하지 않는 동영상 ID ---")
    transcript_data_invalid = get_youtube_transcript(video_id_invalid)
    if transcript_data_invalid:
        print("자막을 가져왔습니다.")
    else:
        print("자막을 가져오지 못했습니다.")
반응형

+ Recent posts