ߊח
!3
라이브러리를 만드는 과정과 느꼈던 점
도움이 될만한 정보 공유
제가 만든 라이브러리 쓰세요
구현상의 문제를 이렇게 해결했고
발표 소개
Slide 4
Slide 4 text
!4
발표 소개 ⏩
보다보면 요런 이모지가 있습니다
Slide 5
Slide 5 text
!5
발표 소개
해당 슬라이드는 제 상황에 국한된 얘기니
깊게 보지 않으셔도 된다는 표시
⏩
Slide 6
Slide 6 text
!6
발표 소개
해당 슬라이드는 제 상황에 국한된 얘기니
깊게 보지 않으셔도 된다는 표시
⏩
= TMI
Slide 7
Slide 7 text
!7
Index
동기
01
구상
02
개발
03
관리
04
Slide 8
Slide 8 text
왜 만들었나
01
Slide 9
Slide 9 text
불편한 점을 개선시키기 위해
!9
01 동기
Slide 10
Slide 10 text
봇을 만든 내 코드가 제일 불편...
!10
01 동기 ⏩
Slide 11
Slide 11 text
자동응답 API 형식
!11
01 동기 ⏩
Slide 12
Slide 12 text
자동응답 API 형식
!12
01 동기
고유한 유저 키
⏩
Slide 13
Slide 13 text
자동응답 API 형식
!13
01 동기
"text" or "photo"
⏩
Slide 14
Slide 14 text
자동응답 API 형식
!14
01 동기
버튼 이름 or 유저 입력 텍스트 or 미디어 파일 URL
⏩
Slide 15
Slide 15 text
session, intent, context
!15
01 동기 ⏩
Slide 16
Slide 16 text
session, intent, context
!16
01 동기 ⏩
Slide 17
Slide 17 text
모든건 POST /message
!17
대부분의 봇 API가 그렇듯 앱이 알아서 처리해야하는 문맥
다만 callback등이 없고 오로지 content 뿐
01 동기 ⏩
Slide 18
Slide 18 text
그러다보니 만들어진건
!18
01 동기
분기 지옥
⏩
Slide 19
Slide 19 text
그러다보니 만들어진건
!19
01 동기 ⏩
Slide 20
Slide 20 text
그러다보니 만들어진건
!20
01 동기
분기의 분기의 분기
어디선가 들고있는 문맥
one magic function
⏩
Slide 21
Slide 21 text
!21
파이썬을 배우기 시작한지 반년
PEP8의 존재도 모름
01 동기 ⏩
Slide 22
Slide 22 text
라이브러리를 만들어 추상화하자!
!22
01 동기
Slide 23
Slide 23 text
무엇을 만드나
02
Slide 24
Slide 24 text
왜 불편한가 생각해보니
!24
02 구상
Slide 25
Slide 25 text
!25
성가신 JSON response 조합
복잡한 if-elif-else 구조
어려운 시나리오 추가
02 구상 ⏩
Slide 26
Slide 26 text
1. 복잡한 구조
!26
02 구상 ⏩
Slide 27
Slide 27 text
2. 어려운 시나리오 대응
!27
02 구상
유저한테 입력을 받은건지 버튼을 클릭한건지 구분할 수 없음
⏩
Slide 28
Slide 28 text
3. 성가신 response 조합
!28
02 구상 ⏩
Slide 29
Slide 29 text
3. 성가신 response 조합
!29
02 구상
3개 중 하나는 필수
있을수도 없을수도
없으면 주관식 입력
⏩
Slide 30
Slide 30 text
그냥 가짓수가 많구나 정도로만
!30
02 구상
Slide 31
Slide 31 text
그 다음 어떻게 사용하고 싶은지
!31
02 구상
Slide 32
Slide 32 text
!32
02 구상
Pythonic하게
명확한 시나리오 플로우
간편한 시나리오, Depth 추가
성가신 JSON response 조합
복잡한 if-elif-else 구조
어려운 시나리오 추가
⏩
Slide 33
Slide 33 text
코드로 상상하기
!33
02 구상
Slide 34
Slide 34 text
최종 컨셉
!34
02 구상 ⏩
Slide 35
Slide 35 text
최종 컨셉
!35
02 구상
상태 전이시 실행할 함수
like view function
chatter.route(request.json)
을 통해 트리거
⏩
Slide 36
Slide 36 text
최종 컨셉
!36
02 구상
데코레이터를 통한 플로우 등록
간단한 키워드 인자 이름
⏩
Slide 37
Slide 37 text
최종 컨셉
!37
02 구상
조합 가능한 response
⏩
Slide 38
Slide 38 text
정리된 주요 컨셉
!38
02 구상
Slide 39
Slide 39 text
!39
02 구상
Response 객체 조합
State rule 기반 라우팅
데코레이터를 통한 플로우 등록
Pythonic하게
명확한 시나리오 플로우
간편한 시나리오, Depth 추가
⏩
Slide 40
Slide 40 text
02 구상
마지막으로 이름 정하기
!40
이미 누가 선점한 chatterbox
→ 패키지 이름은 chatterbox.py지만
import chatterbox 할 수 있게
Slide 41
Slide 41 text
어떻게 만드나
03
Slide 42
Slide 42 text
!42
03 개발
01 setup.py
02 패키지 매니저
03 린트
04 테스트 & 커버리지
05 CI
06 커밋 메시지
07 TDD
08 표준 라이브러리
09 릴리즈와 태그
Slide 43
Slide 43 text
setup.py
!43
03 개발
Slide 44
Slide 44 text
setup.py
!44
ଵҊೞݶ જਸ kennethreitz/setup.py
03 개발
setup.py
Slide 45
Slide 45 text
setup.py
!45
03 개발
setup.py
Slide 46
Slide 46 text
setup.py
!46
03 개발
setup.py
Slide 47
Slide 47 text
setup.py
!47
03 개발
setup.py
Slide 48
Slide 48 text
setup.py - long_description
!48
Markdown Descriptions on PyPI
03 개발
setup.py
Slide 49
Slide 49 text
setup.py - long_description
!49
Markdown Descriptions on PyPI
03 개발
setup.py
Slide 50
Slide 50 text
setup.py - classifiers
!50
List of classifiers
03 개발
setup.py
Slide 51
Slide 51 text
setup.py - test
!51
03 개발
setup.py
Slide 52
Slide 52 text
Python 2 or 3
!52
Python 2를 지원할지 말지
Python 3이라면 어느버전부터 지원할지
각 마이너버전마다 새로 생긴 기능 파악하기
03 개발
setup.py
Slide 53
Slide 53 text
Python 2 or 3
!53
03 개발
setup.py
Slide 54
Slide 54 text
Python 3.4
New modules
asyncio
enum
pathlib
!54
03 개발
setup.py
Slide 55
Slide 55 text
Python 3.5
New syntax
async/await
a @ b
*, ** unpacking 동작 확장 (e.g. {'x': 1, **{'y': 2}})
New modules
typing
!55
03 개발
setup.py
Slide 56
Slide 56 text
Python 3.6
New syntax
F 문자열 포매팅 f'Answer is {value}'
변수 타입 힌팅
async 제네레이터
!56
03 개발
setup.py
Slide 57
Slide 57 text
패키지 매니저
!57
03 개발
Slide 58
Slide 58 text
Pipenv
!58
03 개발
패키지매니저
• Pipfile, Pipfile.lock을 통한 의존성 관리
• pipenv shell 로 가상환경 실행 (source venv/bin/activate)
• 로 호환성유지
• pipenv install --dev 로 개발에만 필요한 패키지 따로 관리
• 중요한건 라이브러리 의존성 명시와 컨트리뷰터를 위한다는 것
pipenv lock -r > requirements.txt
pipenv lock -dr > requirements-dev.txt
Slide 59
Slide 59 text
Pipenv
!59
03 개발
패키지매니저
• Pipfile, Pipfile.lock을 통한 의존성 관리
• pipenv shell 로 가상환경 실행 (source venv/bin/activate)
• 로 호환성유지
• pipenv install --dev 로 개발에만 필요한 패키지 따로 관리
• 중요한건 라이브러리 의존성 명시와 컨트리뷰터를 위한다는 것
pipenv lock -r > requirements.txt
pipenv lock -dr > requirements-dev.txt
Slide 60
Slide 60 text
Pipenv
!60
03 개발
패키지매니저
• Pipfile, Pipfile.lock을 통한 의존성 관리
• pipenv shell 로 가상환경 실행 (source venv/bin/activate)
• 로 호환성유지
• pipenv install --dev 로 개발에만 필요한 패키지 따로 관리
• 중요한건 라이브러리 의존성 명시와 컨트리뷰터를 위한다는 것
pipenv lock -r > requirements.txt
pipenv lock -dr > requirements-dev.txt
Slide 61
Slide 61 text
린트
!61
03 개발
Slide 62
Slide 62 text
!62
03 개발
린트
PEP8 준수
pylint, flake8 등의 린터를 통해 코드 품질 관리
isort, autopep8, yapf, black 등의 포매터를 통해
일관된 코드 스타일 보장
Slide 63
Slide 63 text
!63
03 개발
린트
isort
pylint
black
Slide 64
Slide 64 text
!64
03 개발
린트
isort
#
Slide 65
Slide 65 text
테스트 & 커버리지
!65
03 개발
Slide 66
Slide 66 text
03 개발
pytest
unittest + nose < pytest
간결하고 깔끔한 테스트 코드
읽기 쉬운 에러 리포트
fixture
플러그인
테스트
Slide 67
Slide 67 text
pytest
unittest + nose < pytest
간결하고 깔끔한 테스트 코드
읽기 쉬운 에러 리포트
fixture
플러그인
모든 unittest 코드는 pytest로 테스트 가능
03 개발
테스트
Slide 68
Slide 68 text
간결하고 깔끔한 테스트 코드
The cleaning hand of pytest
03 개발
테스트
Slide 69
Slide 69 text
간결하고 깔끔한 테스트 코드
The cleaning hand of pytest
일일이 기억해 사용해야 하는 assertXXX 패밀리
03 개발
테스트
Slide 70
Slide 70 text
간결하고 깔끔한 테스트 코드
The cleaning hand of pytest
setUp, tearDown 를 사용하면 더 차이나는 코드
일일이 기억해 사용해야 하는 assertXXX 패밀리
네이티브 문법을 활용해 가독성 확보
03 개발
테스트
Slide 71
Slide 71 text
읽기 쉬운 에러 리포트
03 개발
테스트
Slide 72
Slide 72 text
fixture와 플러그인
fixture와 pytest의 내장 기능을 통해 테스트 로직에 집중
03 개발
테스트
Slide 73
Slide 73 text
fixture와 플러그인
Pytest۽ Flask DB పझ ജ҃ ҳ୷ೞӝ
Python pytest fixture
Switching from nose to py.test at Mozilla
03 개발
테스트
Slide 74
Slide 74 text
tox & detox
03 개발
테스트
pyenv + tox로 다양한 파이썬 버전에서 테스팅
detox로 병렬적으로 더 빠르게
tox.ini를 잘 만들어두면 CI도 거저먹기
Slide 75
Slide 75 text
tox & detox
03 개발
테스트
3.4 / 3.5 / 3.6 버전에서 테스트 실행 가능
Slide 76
Slide 76 text
03 개발
커버리지
pytest-cov로 커버리지 리포트 생성
커버리지는 목표가 아닌 상태
Slide 77
Slide 77 text
03 개발
커버리지
• codecov, coveralls: CI에서 리포트를 업로드, Integration 활용
• PR이 커버리지를 어떻게 변화시키는지 알 수 있음
Slide 78
Slide 78 text
CI
(Continuous Integration)
!78
03 개발
Slide 79
Slide 79 text
!79
03 개발
CI
commit push 혹은 PR이 올라오면
travis의 리눅스 환경, appveyor의 윈도우 환경에서
tox를 통해 다양한 파이썬 버전에서
pytest와 pylint를 돌리고
성공/실패를 알려주고 coverage를 codecov에 리포트
Slide 80
Slide 80 text
!80
03 개발
CI
commit push 혹은 PR이 올라오면
travis의 리눅스 환경, appveyor의 윈도우 환경에서
tox를 통해 다양한 파이썬 버전에서
pytest와 pylint를 돌리고
성공/실패를 알려주고 coverage를 codecov에 리포트
Slide 81
Slide 81 text
!81
03 개발
CI
commit push 혹은 PR이 올라오면
travis의 리눅스 환경, appveyor의 윈도우 환경에서
tox를 통해 다양한 파이썬 버전에서
pytest와 pylint를 돌리고
성공/실패를 알려주고 coverage를 codecov에 리포트
Slide 82
Slide 82 text
!82
03 개발
CI
commit push 혹은 PR이 올라오면
travis의 리눅스 환경, appveyor의 윈도우 환경에서
tox를 통해 다양한 파이썬 버전에서
pytest와 pylint를 돌리고
성공/실패를 알려주고 coverage를 codecov에 리포트
Slide 83
Slide 83 text
!83
03 개발
CI
commit push 혹은 PR이 올라오면
travis의 리눅스 환경, appveyor의 윈도우 환경에서
tox를 통해 다양한 파이썬 버전에서
pytest와 pylint를 돌리고
성공/실패를 알려주고 coverage를 codecov에 리포트
Slide 84
Slide 84 text
!84
03 개발
CI
commit push 혹은 PR이 올라오면
travis의 리눅스 환경, appveyor의 윈도우 환경에서
tox를 통해 다양한 파이썬 버전에서
pytest와 pylint를 돌리고
성공/실패를 알려주고 coverage를 codecov에 리포트
Integration
!87
03 개발
01 setup.py
02 패키지 매니저
03 린트
04 테스트 & 커버리지
05 CI
06 커밋 메시지
07 TDD
08 표준 라이브러리
09 릴리즈와 태그
지금까지는 개발을 하기위한 환경이었다면
Slide 88
Slide 88 text
!88
03 개발
01 setup.py
02 패키지 매니저
03 린트
04 테스트 & 커버리지
05 CI
06 커밋 메시지
07 TDD
08 표준 라이브러리
09 릴리즈와 태그
지금부터는 개발을 더 잘 하기위한 이야기
Slide 89
Slide 89 text
커밋 메시지
!89
03 개발
Slide 90
Slide 90 text
!90
03 개발
커밋 메시지
requests-html
신경쓰지 않는 메인테이너도 있음
Slide 91
Slide 91 text
!91
03 개발
커밋 메시지
જ ழ ݫद ࢿߨ 1 2
Ӓ۞ա જ ழ ݫदח ࠄੋೠపب ب ؽ
Slide 92
Slide 92 text
!92
03 개발
커밋 메시지
⏩
chatterboxח Target: Description ഋध ࢎਊ
Action: Things ഋध, Write what I do э ഋधب оמ
Slide 93
Slide 93 text
TDD
(Test Driven Development)
!93
03 개발
Slide 94
Slide 94 text
!94
03 개발
TDD
• 라이브러리를 개발하는데 가장 추천하고 싶은 부분
• 테스트하지 않은 기능까지 완벽하게 돌아간다고 말할 순 없어도, 테
스트한 기능에 대한 걱정은 없어짐
• 세부 구현을 바꾸거나 최적화, 리팩토링 할 때도 걱정없이
• TDD가 만능은 아니다. 구현하다 기획이 바뀌고 후에 테스트를 고쳐
야 할 때도
• 처음 구상했던 Examples를 토대로 테스트를 먼저 구성하면 좋음
Slide 95
Slide 95 text
!95
03 개발
TDD
• 라이브러리를 개발하는데 가장 추천하고 싶은 부분
• 테스트하지 않은 기능까지 완벽하게 돌아간다고 말할 순 없어도, 테
스트한 기능에 대한 걱정은 없어짐
• 세부 구현을 바꾸거나 최적화, 리팩토링 할 때도 걱정없이
• TDD가 만능은 아니다. 구현하다 기획이 바뀌고 후에 테스트를 고쳐
야 할 때도
• 처음 구상했던 Examples를 토대로 테스트를 먼저 구성하면 좋음
Slide 96
Slide 96 text
!96
03 개발
TDD
• 라이브러리를 개발하는데 가장 추천하고 싶은 부분
• 테스트하지 않은 기능까지 완벽하게 돌아간다고 말할 순 없어도, 테
스트한 기능에 대한 걱정은 없어짐
• 세부 구현을 바꾸거나 최적화, 리팩토링 할 때도 걱정없이
• TDD가 만능은 아니다. 구현하다 기획이 바뀌고 후에 테스트를 고쳐
야 할 때도
• 처음 구상했던 Examples를 토대로 테스트를 먼저 구성하면 좋음
Slide 97
Slide 97 text
!97
03 개발
TDD
Red Green Refactor 과정
Slide 98
Slide 98 text
!98
03 개발
TDD
⏩
Slide 99
Slide 99 text
!99
03 개발
TDD
테스트 코드 또한 하나의 문서라는 생각으로
⏩
Slide 100
Slide 100 text
표준 라이브러리
!100
03 개발
Slide 101
Slide 101 text
!101
03 개발
표준 라이브러리
• 라이브러리를 제작할 때 도움이 되는 기본 라이브러리가 많이 있음
• functools: wraps, partial
• itertools: 뭔가 lazy하게 처리하고 싶을 때, sequence 객체를 다룰 때
• contextlib: sqlite cursor를 다룰 때, contextmanager
• collections: ChainMap, 3.4에서 dict unpacking이 필요할 때
• abc: ABCMeta, abstractmethod를 통해 인터페이스 제공
• pathlib: os.join, os.path가 필요없음
Slide 102
Slide 102 text
!102
03 개발
표준 라이브러리
데코레이터를 위한 functools.wraps
Slide 103
Slide 103 text
!103
03 개발
표준 라이브러리
⏩
특히 유용했던 itertools
Slide 104
Slide 104 text
!104
03 개발
표준 라이브러리
⏩
카카오톡 Response는
itertools & operator
Slide 105
Slide 105 text
!105
03 개발
표준 라이브러리
⏩
itertools & operator
3 종류의 message와
Slide 106
Slide 106 text
!106
03 개발
표준 라이브러리
⏩
itertools & operator
2 종류의 keyboard로 구성됨
Slide 107
Slide 107 text
!107
03 개발
표준 라이브러리
⏩
itertools & operator
2о keyboard
6о message
Text
Photo
Button
Text
Button
X
Slide 108
Slide 108 text
!108
03 개발
표준 라이브러리
⏩
itertools & operator
Slide 109
Slide 109 text
!109
03 개발
표준 라이브러리
⏩
itertools & operator
Slide 110
Slide 110 text
!110
03 개발
표준 라이브러리
⏩
itertools.combinations으로
하나일 때, 두개일 때, 모두 있을 때의 조합 생성
Slide 111
Slide 111 text
!111
03 개발
표준 라이브러리
⏩
itertools.chain으로 flatten하게
Slide 112
Slide 112 text
!112
03 개발
표준 라이브러리
⏩
각 메시지는 __add__를 오버라이드한 객체
Slide 113
Slide 113 text
!113
03 개발
표준 라이브러리
⏩
총 12개의 모든 조합 테스트
Slide 114
Slide 114 text
!114
03 개발
표준 라이브러리 관심사 분리를 위한 contextlib
context를 유지한채 관심사에 집중 가능
Slide 115
Slide 115 text
03 개발
표준 라이브러리 관심사 분리를 위한 contextlib
불필요한 코드를 줄일 수 있음
Slide 116
Slide 116 text
릴리즈와 태그
!116
03 개발
Slide 117
Slide 117 text
!117
03 개발
릴리즈와 태그
• 0.1.0 버전 릴리즈 → git tag v0.1.0
• 버저닝에 관한 내용은 잠시 뒤에
• setup.py의 version과 GitHub의 태그를 동일하게 관리
• changelog 적기 편함
Slide 118
Slide 118 text
!118
03 개발
릴리즈와 태그
태그를 기반으로한 diff → 편해진 체인지로그 작성
Slide 119
Slide 119 text
!119
03 개발
릴리즈와 태그
CHANGELOG.md로 관리
GitHub 릴리즈 페이지에 적기도
Slide 120
Slide 120 text
마지막 보너스: API 체크리스트
!120
03 개발
python.apichecklist.com
Slide 121
Slide 121 text
!121
03 개발
내 API는 간단한걸 쉽게 만들고
복잡한걸 가능케하며
잘못된건 불가능하게 한다
API 체크리스트
라이브러리
Slide 122
Slide 122 text
!122
03 개발
API 체크리스트
• 간결함 - README 샘플 코드, 보일러 플레이트 줄이기
• 일관성 - 네이밍 (단어 순서, 복수형), 통일된 빈 값
• 유연함 - 함수 분리, 추상화와 커스터마이징, Pythonic
• 안정성 - 빠른 실패
• 각 항목에 대한 예제는 사이트에서 확인 가능
Slide 123
Slide 123 text
책임을 지자
04
Slide 124
Slide 124 text
!124
04 관리
01 의미있는 버저닝
02 문서화
03 기여자를 위해
04 뱃지달기
05 README
06 이슈해결
07 개밥먹기
08 홍보
Slide 125
Slide 125 text
!125
04 관리
의미있는 버저닝
• Semantic versioning (e.g. Python 3.6.5)
• 라이브러리를 다 만들어도 버그 수정, 기능 추가 등의 업데이트는 항
상 존재
• 메이저 버전, 마이너 버전, 패치 버전으로 의미있는 버저닝을 하자
• break change가 있으면 메이저 버전, 새로운 기능추가는 마이너
버전, 버그 해결은 해치 버전 업데이트
• 사람들에게 충분히 받아들여지고 성숙했다고 생각될 때 1.0.0
Slide 126
Slide 126 text
!126
04 관리
의미있는 버저닝
• Semantic versioning (e.g. Python 3.6.5)
• 라이브러리를 다 만들어도 버그 수정, 기능 추가 등의 업데이트는 항
상 존재
• 메이저 버전, 마이너 버전, 패치 버전으로 의미있는 버저닝을 하자
• break change가 있으면 메이저 버전, 새로운 기능추가는 마이너
버전, 버그 해결은 해치 버전 업데이트
• 사람들에게 충분히 받아들여지고 성숙했다고 생각될 때 1.0.0
Slide 127
Slide 127 text
!127
04 관리
의미있는 버저닝
• Semantic versioning (e.g. Python 3.6.5)
• 라이브러리를 다 만들어도 버그 수정, 기능 추가 등의 업데이트는 항
상 존재
• 메이저 버전, 마이너 버전, 패치 버전으로 의미있는 버저닝을 하자
• break change가 있으면 메이저 버전, 새로운 기능추가는 마이너
버전, 버그 해결은 해치 버전 업데이트
• 사람들에게 충분히 받아들여지고 성숙했다고 생각될 때 1.0.0
Slide 128
Slide 128 text
!128
04 관리
의미있는 버저닝
• Calendar Versioning (e.g. Pipenv 2018.7.1)
• Ubuntu, pytz, PyCharm, certifi 등
• 릴리즈 사이클이 주기적이거나 (pip), outdated에 민감한 프로젝
트거나 (pytz, certifi), 크거나 포괄적인 프로젝트(Ubuntu,
Pipenv)라면 캘린더 버저닝을 고려
Slide 129
Slide 129 text
!129
04 관리
문서화
• 라이브러리를 사용할 개발자를 위한 문서화
• 나는 내 코드를 다 알지만 다른 사람은 그렇지 않음
• 이 라이브러리는 어떻게 사용해야하고 → Getting started
• 어떤 함수가 있고 파라미터로 어떤걸 받고 뭘 반환하고 → api reference
• sphinx와 read the docs로 문서 유지 (sphinx 첫걸음, 시작하기)
Slide 130
Slide 130 text
!130
04 관리
문서화
• 라이브러리를 사용할 개발자를 위한 문서화
• 나는 내 코드를 다 알지만 다른 사람은 그렇지 않음
• 이 라이브러리는 어떻게 사용해야하고 → Getting started
• 어떤 함수가 있고 파라미터로 어떤걸 받고 뭘 반환하고 → API Reference
• sphinx와 read the docs로 문서 유지 (sphinx 첫걸음, 시작하기)
Slide 131
Slide 131 text
!131
04 관리
문서화
• 라이브러리를 사용할 개발자를 위한 문서화
• 나는 내 코드를 다 알지만 다른 사람은 그렇지 않음
• 이 라이브러리는 어떻게 사용해야하고 → Getting started
• 어떤 함수가 있고 파라미터로 어떤걸 받고 뭘 반환하고 → API Reference
• sphinx와 read the docs로 문서 유지 (sphinx 첫걸음, 시작하기)
Slide 132
Slide 132 text
!132
04 관리
문서화
README에라도 유즈케이스, 샘플 코드를 적어놔야한다
doctoc로 자동 생성된 ToC
Slide 133
Slide 133 text
!133
04 관리
기여자를 위해
CONTRIBUTING.md
→ 기여를 위해 알리는 말. 테스트는 어떻게 할 수 있고 컨벤션은 이렇다
Slide 134
Slide 134 text
!134
04 관리
기여자를 위해
CONTRIBUTING.md
→ 기여를 위해 알리는 말. 테스트는 어떻게 할 수 있고 컨벤션은 이렇다
Slide 135
Slide 135 text
!135
04 관리
기여자를 위해
ISSUE_TEMPLATE.md
→ 업데이트로 디렉토리 형식도 지원
버그 리포트에 필요한 정보를 담게끔 유도
Slide 136
Slide 136 text
!136
04 관리
기여자를 위해
ISSUE_TEMPLATE.md
→ 업데이트로 디렉토리 형식도 지원
버그 리포트에 필요한 정보를 담게끔 유도
Slide 137
Slide 137 text
!137
04 관리
기여자를 위해
ISSUE_TEMPLATE.md
→ 업데이트로 디렉토리 형식도 지원
버그 리포트에 필요한 정보를 담게끔 유도
Slide 138
Slide 138 text
!138
04 관리
기여자를 위해
• PULL_REQUEST_TEMPLATE.md → 어떤 변경이 있는지, 체크리스트
로 빼먹은건 없는지 유도
• 프로젝트 최상위 위치에 .github 폴더를 만들어 관리
• 주석을 활용해 불필요한 설명이 노출되지 않도록
Slide 139
Slide 139 text
!139
04 관리
뱃지 달기
• CI: 빌드 상태
• 라이센스
• pypi 기준 라이브러리 버전: stable, unstable
• 지원되는 파이썬 버전
• 코드 커버리지: 이 라이브러리가 이만큼 건강하다
license
license MIT
MIT
build
build passing
passing
build
build passing
passing
pypi
pypi v0.2.4
v0.2.4
python
python 3.4, 3.5, 3.6
3.4, 3.5, 3.6
codecov
codecov 92%
92%
Slide 140
Slide 140 text
!140
04 관리
뱃지 달기
• CI: 빌드 상태
• 라이센스
• pypi 기준 라이브러리 버전: stable, unstable
• 지원되는 파이썬 버전
• 코드 커버리지: 이 라이브러리가 이만큼 건강하다
license
license MIT
MIT
build
build passing
passing
build
build passing
passing
pypi
pypi v0.2.4
v0.2.4
python
python 3.4, 3.5, 3.6
3.4, 3.5, 3.6
codecov
codecov 92%
92%
https://badgen.net
Slide 141
Slide 141 text
!141
04 관리
리드미
• 프로젝트의 대문
• 보통 MD, RST: 이제 pypi에서 Markdown도 지원됨
• 라이브러리의 현재 상태 - 뱃지
• 무엇을 위한 라이브러리인지, 설치 방법, 간단한 사용 사례, 문서
링크, 기여 방법
• 자세한 사용방법은 read the docs로 분리시키기
Slide 142
Slide 142 text
!142
04 관리
이슈해결
• 이슈가 있다는건 관심을 갖고 사용해주시는 분들이 있다는 의미
• 내가 발견하고 내가 수정할 버그더라도 이슈로 남겨두기
• 어떤 커밋을 통해 해결됐는지 명시 (커밋에 Close #4, Fix #3를
적어주면 자동으로 처리)
• 이슈를 올려주는 분들도 고마운 컨트리뷰터분들이라는 생각으로
Slide 143
Slide 143 text
!143
04 관리
개밥먹기
• 돌고돌아 드디어 원래 목적이었던 내 프로젝트에 내 라이브러리
사용하기 달성
• 해당 라이브러리로 개발된 프로젝트가 있다면 좀 더 신뢰할 수 있
고, 개발자 스스로도 지속적인 관심을 가질 수 있음
JungWinter/chef-hong
JungWinter/chatterbox
⏩
Slide 144
Slide 144 text
!144
04 관리
개밥먹기
JungWinter/chef-hong
JungWinter/chatterbox
기존에 있던 프로젝트를 unmaintained 처리
⏩
Slide 145
Slide 145 text
!145
04 관리
홍보
• chatterbox.py는 카카오톡 봇 라이브러리다 보니 국내 개발자가 타겟
• 페이스북 그룹, 개발자 사이트, 트위터 등
• 제작 경험을 공유하는 것 또한 좋은 홍보 방법 (저는 때를 놓쳤지만...)
• 글로벌 타겟이라면 hackernews, reddit, medium 등도 좋은 홍보 수단
이게 마지막입니다
Slide 146
Slide 146 text
마치며
Slide 147
Slide 147 text
!147
마치며
원래 목적을 달성했는가 → ✅
나만 쓰려고 만들기와 모두를 위해 만들기는 매우 달랐다
개발 자체보다 준비, 관리 등 다른 부분이 더 중요하다
문서화는 몰아서 하지말고 그때그때 해두자
Slide 148
Slide 148 text
!148
도움이 된 것들
- Go언어로 오픈소스 배송조회 서비스 만들기
- Tox, Travis 그리고 Codecov 로 오픈소스 생태계에 기여하기
- 파이썬에서 편하게 테스트 케이스 작성하기: pytest, Travis CI, Docker
- 정해진 데드라인