레이블이 Python인 게시물을 표시합니다. 모든 게시물 표시
레이블이 Python인 게시물을 표시합니다. 모든 게시물 표시

uv pip

# https://github.com/astral-sh/uv 를 사용하면 pip,pipx,pyenv,virtualenv 등의 파이썬 툴들의 기능을 통합하고 사용할 수 있고 실행(설치등)도 빠르다.
# 참고로 pip 가 없을때 설치
# python -m ensurepip --upgrade
# python -m pip install --upgrade pip

# uv 설치
pip install uv
# 또는
brew install uv

# 이제 uv 만 붙여서 실행
# --system 은 필요시 설정
uv pip install {패키지명} --system

# 다음 스샷으로(왼쪽:pip, 오른쪽:uv pip) 여러 패키지를 한번에 설치(https://github.com/ysoftman/myenv/blob/master/installpip.sh) 해보면 속도 차이가 크다

# 프로젝트 생성하면 readme.md 부터 .git 등의 기본 파일이 생성된다.
uv init aaa

# 패키지를 추가하면 .venv 가상환경이 설정되고, 패키지 관리를 위한 uv.lock 파일이 생성된다.
uv add {패키지명}

# pyenv 부터 system path 등 설치된 모든 파이썬 버전을 확인할 수 있다.
uv python list

# 파이썬 3.12 버전 설치
uv python install 3.12

#####

# pipenv -> uv project 로 마이그레이션
# pipenv-uv-migrate 툴 설치
uv tool install pipenv-uv-migrate

# uv 프로젝트 생성(초기화, pyproject.toml 파일 생성)
uv init

# 마이그레이션(uv tool run -> uvx 로 대체 가능)
uv tool run pipenv-uv-migrate -f Pipfile -t pyproject.toml

# uv 가 인식하지 못하는 버전표현이 있으면 다음과 같은 에러가 발생한다.
InvalidSpecifier: Invalid specifier: '0.5.0'

# pipfile 에서 다음과 같이 변경하면 된다.
aaa-package = "0.5.0" --> "==0.5.0" 또는 "~=0.5.0" 등으로 변경

# uv [script] 섹션은 지원하지 않아 pipfile [scripts] 가 있다면 다음과 같이 스킵된다.
UserWarning: uv does not have the feature of task runner. migration of the scripts section will be skipped.
  self._migrate_scripts()

# lock 파일 생성
uv lock

# 싱크(venv로 패키지 설치)
uv sync

# venv 환경으로 실행
uv run mytest.py

pyenv install 3.12.0 error

# clang 버전
clang --version
Homebrew clang version 20.1.2
Target: arm64-apple-darwin24.4.0
Thread model: posix
InstalledDir: /opt/homebrew/Cellar/llvm/20.1.2/bin
Configuration file: /opt/homebrew/etc/clang/arm64-apple-darwin24.cfg

# mac 15.4 (24E248) 에서 pyenv 로 3.12.0 을 지우고 다시 설치 다음 에러가 발생했다.
# 참고로 3.11.0 은 설치가 잘 됐다.
pyenv install 3.12.0 -v
/Library/Developer/CommandLineTools/SDKs/MacOSX15.sdk/usr/include/assert.h:75:25: note: expanded from macro 'assert'

# -Wno-string-compare 옵션을 주면 된다고 해서 요렇게 다시 실행
env \
  CFLAGS="-Wno-string-compare" \
  pyenv install 3.12.0

# 이번엔 tcl 에러가 발생한다.
/opt/homebrew/Cellar/tcl-tk/9.0.1/include/tcl-tk/tclDecls.h:1797:36: note: passing argument to parameter 'argcPtr' here

# 찾아보니 tcl-tk 9 -> 8 버전으로 변경해야 된다고해서 8버전으로 다시 설치
brew uninstall tcl-tk
brew install tcl-tk@8

# 이제 빌드 된다.

python poetry

golang go.mod 로 패키지를 관리가 편한데 python 에선 venv 를 사용해
.venv/lib/python3.9/site-packages/ 등으로 버전별 패키지를 관리하는게 썩 맘에 들지 않았다.
python 진영에서도 공식은 아니지만 비슷한 pipenv, poetry 가 있다.
pipenv 는 속도와 성능도 그렇고 좀 지난 오픈소스고 최근에는 poetry poetry.lock 으로 정확한 버전 고정을 하는 기능과 성능등에서 앞선다.

poetry 는 setup.py, requirements.txt, setup.cfg, MANIFEST.in, Pipfile 기능을 pyproject.toml 하나로 관리한다.

# pip 설치
pip install poetry

# brew 로 설치
brew install poetry

# 쉘별 tab 자동환경 활성화 방법
 
# 현재 프로젝트의 의존성(패키지) 설치
poetry install

# 패키지 추가
poetry add 패키지명

# 패키지 제거
poetry remove 패키지명

# 패키지 정보
poetry show

# lock 파일 생성
poetry lock

#####

# pyproject.toml 작성시 poetry 방식(Poetry backend)
[tool.poetry]
name = "ysoftman_lemon"
version = "0.1.0"
description = "test package"
authors = ["ysoftman <ysoftman@gmail.com>"]
license = "MIT"
readme = "README.md"

[tool.poetry.dependencies]
python = ">=3.12"

[tool.poetry.scripts]
# ysoftman_lemon 으로 실행하기 위해서
# PyPI/Poetry wheel에서는 스크립트 이름에 하이픈(-) 금지
ysoftman_lemon = "ysoftman_lemon.main:main"

# tool.poetry.packages must be array
[[tool.poetry.packages]]
include = "ysoftman_lemon"

[build-system]
requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"

#####

# pyproject.toml 작성시 PEP621 project 방식(setuptools backend)
[project]
name = "ysoftman-lemon"
version = "0.1.0"
description = "test package"
license = { text = "MIT" }
authors = [{ name = "ysoftman", email = "ysoftman@gmail.com" }]
readme = "README.md"
requires-python = ">=3.12"
dependencies = []

[project.urls]
repository = "https://github.com/ysoftman/ysoftman-lemon"
homepage = "https://github.com/ysoftman/ysoftman-lemon"

[project.scripts]
my_package_cli = "lemon.main:main"

[build-system]
requires = ["setuptools>=61.0", "wheel"]
build-backend = "setuptools.build_meta"

pip install gcc error

# pip 설치 중 다음과 같은 에러가 발생했다.
pip install cryptography
... 
/opt/homebrew/bin/gcc-13 -fno-strict-overflow -Wsign-compare -DNDEBUG -g -O3 -Wall -I/opt/homebrew/opt/zlib -I/opt/homebrew/opt/zlib -DFFI_BUILDING=1 -DUSE__THREAD -DHAVE_SYNC_SYNCHRONIZE -I/Library/Developer/CommandLineTools/SDKs/MacOSX14.sdk/usr/include/ffi -I/Users/ysoftman/.pyenv/versions/3.12.0/include/python3.12 -c src/c/_cffi_backend.c -o build/temp.macosx-14.1-arm64-cpython-312/src/c/_cffi_backend.o -iwithsysroot/usr/include/ffi
...
gcc-13: error: unrecognized command-line option '-iwithsysroot/usr/include/ffi'

# 컴파일러를 clang 으로 변경하면 된다.
CC=clang pip install cryptography

# 참고로 python 환경을 보니 CC 가 gcc 로 설정되어 있었다.
# 예전 pyenv 로 python 설치시 clang 에 문제가 있어 gcc 로 변경해서 설치했던게 문제였다.
python -m sysconfig | rg 'CC = '
40:     CC = "/opt/homebrew/bin/gcc-13"
647:    LINKCC = "/opt/homebrew/bin/gcc-13"

old version ansible

# ansible playbook 이 jenkins job 에서 다음과 같은 에러가 발생했다.
Unsupported parameters for (dnf) module: sslverify Supported parameters include: 

# sslverify 는 ansible 2.13 에 추가되었다.
# 그런데 현재 사용하는 버전은 2.14 로 문제가 없어야 한다.
ansible --version
ansible [core 2.14.2]
  config file = /etc/ansible/ansible.cfg
  configured module search path = ['/home/ysoftman/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3.11/site-packages/ansible
  ansible collection location = /home/ysoftman/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/bin/ansible
  python version = 3.11.2 (main, Oct  5 2023, 16:06:03) [GCC 8.5.0 20210514 (Red Hat 8.5.0-18)] (/usr/bin/python3.11)
  jinja version = 3.1.2
  libyaml = True

# 확인 결과 jenkins job 의 script 에서 아래와 같이 python 3.8 버전을 우선하게 설정이 되어 있었고
# python-3.8 /bin 에 ansible 바이너리가 있었다.
export PATH="/home/ysoftman/Python-3.8.17/bin:${PATH}"
export PYTHON_PATH="/home/ysoftman/Python-3.8.17"

# 그래서 Python-3.8.17/bin/ansible-playbook 2.9 버전을 사용하게 되는게 문제였다.
ansible-playbook --version
ansible-playbook 2.9.22
  config file = /etc/ansible/ansible.cfg
  configured module search path = ['/home/ysoftman/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /home/ysoftman/Python-3.8.17/lib/python3.8/site-packages/ansible
  executable location = /home/ysoftman/Python-3.8.17/bin/ansible-playbook
  python version = 3.8.17 (default, Nov  2 2023, 17:16:07) [GCC 8.5.0 20210514 (Red Hat 8.5.0-18)]

# 정리
# 로컬에서는 최신 ansible 버전 기준으로 playbook을 작성했는데
# 배포시에는 python, ansible 을 고정된 버전으로 사용하고 있었음.

make python package

# python 패키지를 만들때 다음과 같이 하면 dist/xxx.tar.gz(os 따른 포맷)압축파일이 생성된다.
# 소스 배포판 패키지 만들기
python setup.py sdist

# 설치를 위해 압축 풀기
cd dist
tar zxvf xxx.tar.gz
cd xxx

# 설치
python setup.py install

# 또는 pip 로 현재 경로를 설치경로로 사용해서 설치
pip install -e .


##########


# egg -> wheel 로 대체돼 더이상 사용하지 않는다 !!!
# dist/xxx.egg(압축파일)로 패키지 만들도 압축 파일상태에서 설치할 수 도 있다.
# egg 패키지 생성
python setup.py bdist_egg

# 설치
cd dist
python -m easy_install xxx.egg


##########


# wheel (2013년 등장, egg 파일을 대체)
# 소스 배포판으로 만들면 설치를 위해 압축을 풀면 소스가 보인다.
# 압축을 풀때 소스대신 wheel(.whl) 파일로만 보이게 할 수 있다.
# 물론 설치하면 설치된 경로에는 소스파일이 있다.

# wheel 과 setuptools 패키지를 설치해야 한다.
pip install wheel setuptools

# wheel 패키지로 만들기
python setup.py bdist_wheel

# 설치
cd dist
pip install xxx.whl

python subprocess arg escape

# subprcoess shell=True 로 명령을 실행할때
# 경로 인자로 single quote(')등이 있을때 \'와 같이 별도 이스케이프 하지 않아야 한다.
# 하지만 ' " 동시에 있는경우 이스케이스 \ 자체도 이스케이프 필요
def exec_Command(command, shellopt):
    # shell 인자(기본값은 False)는 셸을 실행할 프로그램으로 사용할지를 지정합니다. shell이 True이면, args를 시퀀스가 아닌 문자열로 전달하는 것이 좋습니다.
    # POSIX에서 shell=True일 때, 셸의 기본값은 /bin/sh입니다. args가 문자열이면, 문자열은 셸을 통해 실행할 명령을 지정합니다. 이것은 문자열이 프롬프트에서 입력할 때와 똑같이 포맷되어야 한다는 것을 의미합니다. 예를 들어, 스페이스가 포함된 파일명을 인용하거나 역 슬래시 이스케이핑 하는 것을 포함합니다. args가 시퀀스이면, 첫 번째 항목이 명령 문자열을 지정하고, 추가 항목은 셸 자체에 대한 추가 인자로 처리됩니다. 즉, Popen은 다음과 동등한 것을 수행합니다:
    output = subprocess.Popen(
        command, shell=shellopt, stdout=subprocess.PIPE, stderr=subprocess.PIPE
    )
    stdout, stderr = output.communicate()
    print("[stdout]\n", stdout)
    print("[stderr]\n", stderr)

# ' " 동시에 있는경우 이스케이스 \ 자체도 이스케이프 필요
# bash -c "touch zzz\'s\ \\\"a.txt"
exec_Command(f"touch zzz\\'s\ \\\"a.txt", True)

# 테스트코드

python profiling tool py-spy

# py-spy 를 사용하면 파이썬 실행을 쉽게 프로파일링 해준다.

# python 실행이 끝아면 프로파일링 결과(.svg)가 브라우저로 열린다.
sudo py-spy record -o profile.svg -- python ysoftman.py

# top 은 function 의 처리시간 비율을 실시간으로 보여준다.
sudo py-spy top -- python ysoftman.py

python package dependency

# pip freeze 는 설치된 패키지를 나열하지만
pip freeze 

# 패키지들간의 의존성을 파악하려면 pipdeptree 를 사용하면 된다.
# python package dependency tree 설치 
pip install pipdeptree

# 패키지 의존성 파악
pipdeptree

# 실제 설치된 버전만 보는 경우
pipdeptree --freeze

# json 으로 표시
pipdeptree --json

# 특정 패키지(-p)의 의존성(-r) 보는 경우
pipdeptree -p setuptools -r

# 최상위 패키지만 보려면
pipdeptree | rg '^w+'

boto3 s3 업로드 후 파일 안보이는 문제

# python boto3 라이브러리를 이용해 s3 파일 업로드를 했는데
# 디렉토리는 생성됐지만 s3 파일이 존재하지 않는다.
# 확인해 보니 / 로 시작하는 path(key) 때문이었다.

...  생략 ...

path = f"/test/{filename}"
# / 로 시작하면 업로드 후 파일이 없는것으로 표시된다.
path = path.lstrip("/")

# upload to s3
client.upload_file(
    Filename=filename,
    Bucket=AWS_BUCKET,
    Key=path,
    Callback=lambda bytes_transferred: pbar.update(bytes_transferred),
)

# 테스트 코드 

python 패키지 이름 모를때 삭제하기

# /usr/local/bin/aaa 파이썬 프로그램을 실행할 수 있는데,
# pip 로 aaa 를 삭제하려고 하면 설치되지 않았다고 나온다.
pip uninstall aaa
WARNING: Skipping aaa as it is not installed.

# aaa 패키지를 정보를 보면 찾을 수 없다고 나온다.
pip show aaa
WARNING: Package(s) not found: aaa

# 원인은 실행파일 이름과 실제 패키지명이 달라서다.
# 삭제를 위해선 실제 패키지명을 알아야 하는데 pip 로 파악할 수 없었다.

# [패키지 설치 경로 찾아서 삭제하기]
# 우선 다음 스크립트를 실행해 python 패키지 모듈 경로를 파악한다.
cat << zzz | python | sed -e 's/\[//g' -e 's/\]//g' -e 's/,/\n/g'
import sys
print(sys.path)
zzz

# 보통 /usr/local/lib/python3.9/site-packages/ 같은 곳에서 
# aaa (실행파일명)으로 시작하는 파일을 찾아본다.
fd "^aaa" /usr/local/lib/python3.9/site-packages/
/usr/local/lib/python3.9/site-packages/aaa
/usr/local/lib/python3.9/site-packages/aaa-bbb
... 생략

# aaa-bbb 가 실제 패키지 이름인것을 유추해볼수 있다.
# aaa-bbb 소스 내에서 aaa 를 사용하는지 확인해본다.
# 이제 pip 로 삭제본다.
pip uninstall aaa-bbb

webdav chunked size

# python upload/download 시 tqdm 으로 progressbar 표시한다.
# download 는 resp=requests.get(... stream=True) 와 resp.iter_content 로 스트림으로 받는 있는 데이터 사이즈를 파악할 수 있다.
# upload 는 async 와 async with aiohttp.ClientSession() 를 사용해 표시한다.
# tqdm 참고
# 그런데 upload(aiohttp > seesion > put) 시 http://httpbin.org/put 는 동작되는데
# webdav(http의 확장으로 COPY, MOVE, MKCOL(mkdir), PROPFIND(조회) 등 파일관리 메소드들 제공) 서버(https://github.com/mar10/wsgidav)에서는
# 다음 코드에서 진행되지 않고 CPU 100%를 사용하는 문제가 발생했다.
# 이 상태에서 요청을 계속 하면 서버 행 상태가 된다.
buf = environ["wsgi.input"].readline()

# 관련해서 비슷한 이슈가 오래전에 있어 수정이 되었다.
# chunk 사이즈 명시를 누락하는것 rfc2616(https://datatracker.ietf.org/doc/html/rfc2616#section-3.6.1) 명세를 위한반것으로 예외케이스를 추가한것으로 보인다.

# 클라이언트에서 X_EXPECTED_ENTITY_LENGTH 로 전체보낼 크기를 명시하고
# User-Agent 를 Darwin 으로 명시한다.
headers = {}
# headers["X_EXPECTED_ENTITY_LENGTH"] = repr(os.fstat(fileobj.fileno()).st_size) # fileobject case
headers["X_EXPECTED_ENTITY_LENGTH"] = repr(os.path.getsize(filename))
headers["User-Agent"] = "Darwin"

# 이제 put 을 하면 webdav 의 _stream_data_chunked > Darwin 조건에 다음과 같이 버크 크기를 알수 있어 진행된다.
buf = environ.get("HTTP_X_EXPECTED_ENTITY_LENGTH", "0")

# aiohttp 는 기본 Agent 가 다음과 같았고,
Python/3.9 aiohttp/3.7.4.post0

# 별도 chunk 크기를 명시하는 것이 없다. 
# 암튼 mar10 의 wsgidav chunk put 처리에는 예외 케이스가 있어
# 위처럼 클라이언트를 수정하던 wsgidav 서버 조건을 수정해야 한다.

# 참고로 User-Agent 없이 X_EXPECTED_ENTITY_LENGTH 만 설정하면 좋을것 같아서 문의함

# 이것땜에 한참 고생함ㅠㅠ, 힘들게 원인 파악한 기념으로 개비스콘 짤 생성~ㅋ

fastapi 422 error

# fastapi(web framework for building APIs with Python 3.6+) 서버에 요청시 422 에러 발생 해결하기

# 다음과 같은 요청시
curl 'http://localhost:8000/path/lemon/ysoftman' \
  -H 'Origin: http://localhost:8000' \
  -H 'X-User-Token: abc123' \
  --data-raw '{"name":"ysoftman","desc":"test","spec":{"val1":100,"val2":"asdf"}}'

# 응답으로 422(Unprocessable Entity)가 발생하며 다음과 같은 응답 메시지를 받는 경우가 있다.
{"detail":[{"loc":["query","data"],"msg":"field required","type":"value_error.missing"}]}%

# fastapi route 함수에서 파라메터 타입이 잘못된거나 빠지면 발생한다.
# BaseModel 을 이용해 파라메터 타입을 명시하면 된다.
class SpecObject(BaseModel):
    val1: int
    val2: str

class YsoftmanData(BaseModel):
    name: str
    desc: str
    spec: SpecObject

@router.post("/path/{val1}/ysoftman")
def post_ysoftman(val1: str, data: YsoftmanData, x_user_token: str = Header(default=None)):

# 참고

python unused import

# python 작업시 오타등으로 의도하지 않은 패키지가 자동 import 되는 경우가 있다.
# 존재하지 않거나 사용하지 않는 패키지가 import 된 경우 찾기

# autoflake 사용
# pip3 install autoflake
# --remove-all-unused-imports 사용 안하는 import 부분 화면 출력
# --in-place 를 사용하면 화면 출력 대신 파일에 바로 적용
fd .py ./aaa | xargs autoflake --remove-all-unused-imports --in-place 

# pylint 사용
# pip3 install pylint
# W0611 (unused-import)
fd .py ./aaa | xargs pylint --disable="all" --enable="W0611"

# 추가로 vscode pylint 설정시
"python.linting.pylintEnabled": true,
"python.linting.pylintArgs": [
  "--disable=all",
  "--enable=W0611",
],

#####

# black - 포맷팅 중심으로 포맷팅만 볼때는 pylint 보다 빠르다.

# ruff - rust 로 lint, formatting 등의 기능으로 pylint, black 보다 빠르다.

# uv pip install --system pylint black
# pylint check(lint) -> ruff 로 대체
# pylint --disable="all" --enable="W0611" *.py
# black formatting -> ruff 로 대체
# black *.py

# ruff check and formatting
uv pip install --system ruff
ruff check *.py
ruff format *.py

vscode python no definition found

# vscode python 사용시 로컬 특정 경로의 패키지를 찾지 못해
# 모듈, 함수등에 'go to definition'(F12) 수행시 다음과 같이 찾을 수 없다고 나온다.

No Definition found for 'xxxxx'

# File > Save Workspace As... 로 워크스페이스 파일을 다음과 같이 생성하자. 
# ysoftman.code-workspace 내용
{
"folders": [
{
"path": "."
},
],
"settings": {
"python.envFile": "${workspaceFolder}/local.env",
}
}

# 그리고 local.env 파일에 생성하고 PYTHONPATH 에 찾지 못하는 패키지 경로를 설정한다.
PYTHONPATH=../my_custom_pkg1:../my_custom_pkg2:

# 이제 workspace file 로 열면 go to definition 이 동작한다.
code ./ysoftman.code-workspace

# 참고

pip config comment

# git+http 로 pip 패키지 설치시 dependencies 단계에서 진행이 되지 않는다.
pip install git+https://github.com/psf/black
Looking in indexes: https://pypi.org/simple, http://사설(extra-index-url),

... 생략 ...
  Installing build dependencies ... 

# 원인은 pip.conf 사설 extra-index-url 설정 때문이었다.
# pip install requests 와 같이 git+https 가 아닌 경우 
# --isolated (사용자 환경변수나 구성 무시)옵션을 사용하면 설치된다.
# pip install requests --isolated

# 해결방법1
# extra-index-url 주석처리하면 설치된다.
# 주석처리는 # 로 할 수 있다.
# pip config 파일 수정
pip config edit

# 해결방법2(삭제해도 되는 경우)
pip config unset global.extra-index-url

# 참고로 pip install 시 extra-index-url 은 추가만 되고 삭제나 무시돼는 옵션이 없다.
# 관련해서 이슈화되었지만 진행은 안되고 있다.

# 기타 config 관련 정보
# config 설정 리스트
pip config list

# config 파일 수정
pip config edit

# global > user > site 우선순위로 설정된다. 

ansible docker sdk for python 에러

# 다음과 같이 ansible 로 docker 처리를 하는 경우 
- name: ysoftman docker build
  docker_image:
    path: "/home/ysoftman/testdocker"
    name: "/ysofmtan/testdocker"
    tag: "test"
    state: build
    force: yes

# python 용 docker sdk 를 찾을 수 없다는 에러가 발생한다.
MSG:

Failed to import the required Python library (Docker SDK for Python: docker (Python >= 2.7) or docker-py (Python 2.6)) on xxxxx's Python /usr/bin/python. Please read module documentation and install in the appropriate location. If the required library is installed, but Ansible is using the wrong Python interpreter, please consult the documentation on ansible_python_interpreter, for example via `pip install docker` or `pip install docker-py` (Python 2.6). The error was: No module named parse

# python 2.7.5 이라
ansible --version | command grep python
  ansible python module location = /usr/lib/python2.7/site-packages/ansible
  python version = 2.7.5 (default, Nov 16 2020, 22:23:17) [GCC 4.8.5 20150623 (Red Hat 4.8.5-44)]

# docker 패키지를 설치했다.
sudo pip install docker

# 설치 확인
pip list | grep docker
10:docker (5.0.0)

# 설치해도 똑같은 에러가 발생한다.
# 혹시나 해서 docker-py 를 설치하면
sudo pip install docker-py

# 2개를(docker, docker-py)를 설치하면 안된다는 에러가 발생한다.
Cannot have both the docker-py and docker python modules (old and new version of Docker SDK for Python) installed together as they use the same namespace and cause a corrupt installation. Please uninstall both packages, and re-install only the docker-py or docker python module (for xxxxx's Python /usr/bin/python). It is recommended to install the docker module if no support for Python 2.6 is required. Please note that simply uninstalling one of the modules can leave the other module in a broken state.

# 둘다 지워 보자.
sudo pip uninstall docker docker-py

# 역시 위 첫번째 에러가 발생한다.
# 혹시나 해서 docker-py 만 설치해봤다.
sudo pip install docker-py

# 설치 확인
pip list | grep docker
10:docker-py (1.10.6)

# 에러가 발생 안한다. 뭐지? python 2.7 은 docker 패키지를 설치,
# python 2.6 은 docker-py 를 설치해야만 되는줄 알았는데,흠.

centos 최신 repo 반영하기

# docker등 CentOS 기본 버전에서는 최신 패키지 내용이 반영되어 있지 않다.
# CentOS:7 도커 이미지를 기반에서 nodejs(npm 사용하기 위해) 패키지를 설치할때
yum install -y nodejs

# 다음과 같이 사용 불가능한 패키지로 표시된다.
No package nodejs available

# 이 경우 https://ius.io/ 에서 제공하는 최신 패키지 리스트를 사용하면 된다.
# RHEL(Red Hat Enterprise Linux) 나 CentOS 에 최신 패키지 리스트 적용
# /etc/yum.repos.d/ius.repo 등이 생성된다.
yum install -y https://centos7.iuscommunity.org/ius-release.rpm

# ius 를 추가하면 centos 7 에서 yum 으로 python3 설치할 수 있다.
yum install -y python36u python36u-libs python36u-devel python36u-setuptools

matplotlib on wsl

# wsl(windows subsystem for linux) 에서 matplotlib 사용시
# 다음과 같이 그래프를 출력하는데
import matplotlib.pyplot as plt
plt.show()

# 다음과 같은 에러가 발생한다.
UserWarning: Matplotlib is currently using agg, which is a non-GUI backend, so cannot show the figure.

# 해결방법
# python3-tk 설치
sudo apt-get install python3-tk

# DISPLAY 환경변수 설정(.bashrc 에 추가하자)
export DISPLAY=localhost:0.0

# 윈도우용 xserver 설치 후
# xlaunch 앱 실행 -> multiple windows 선택 실행한다.
https://sourceforge.net/projects/vcxsrv/

# 이제 다시 실행하면 그래프 창을 볼 수 있다.

ansible jinja template list 유니코드 에러

# 문제
# ansible jinja template 파일에서 다음과 같이 리스트를 사용하는 경우
# default/main.yml
ysoftman_servers:
  service:
    - ysoftman1:9001
    - ysoftman2:9001

# templates/ysoftman.yml.j2
hosts : {{ ysoftman_servers[env] }}

# ansible 수행하면 다음과 같이 u(유니코드)문자가 붙어 설정 에러가 발생한다.
hosts: [u'ysoftman1:9001', u'ysoftman2:9001']

# 원인
# ansible 버전을 확인해 보면 python2 를 사용하고 있다.
# python2 에서는 유니코드를 표현하기 위해 u'글자' 형식으로 표현되는게 문제다.
ansible --version
ansible 2.8.5
  ... 생략 ...
  python version = 2.7.10 .. 생략

# 해결방법
# python3 기반의 ansible 을 새롭게 설치하자.
pip3 install ansible

# 또는 brew 삭제하고 재설지 설치
# 최근 brew 는 python3 이 기본이 되어 그냥 python 으로 표기된다.
# python2 는 python@2 로 표기해야 한다.
brew uninstall ansible
brew install ansible

# ansible with python3 으로 실행하면 u(유니코드) 표기를 사용하지 않는다.
ansible 2.8.5
  python version = 3.7.4

# 만약 python2 를 쓸수 밖에 없는 상황이라면 다음처럼 u를 제거할 수도 있다.
hosts: ["{{ ysoftman_servers[env].stdout_lines | list | join("\", \"") }}"]

Prev