Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
The cobbler's children have no shoes, or buildi...
Search
Alex Gaynor
May 30, 2016
Programming
1
260
The cobbler's children have no shoes, or building better tools for ourselves
As delivered at PyCon 2016 in Portland, OR.
Alex Gaynor
May 30, 2016
Tweet
Share
More Decks by Alex Gaynor
See All by Alex Gaynor
Quantifying Memory Unsafety and Reactions to It
alex
0
93
Learning from Failure: Post-mortems
alex
2
290
Techniques for Debugging Hard Problems
alex
1
570
Building Communities with Code Review
alex
4
280
Documenting Domain Specific Knowledge
alex
1
380
Pickles are for Delis, not for Software
alex
0
360
Code Review in Open Source Software
alex
4
760
Why Ruby isn't slow
alex
10
3.8k
PyPy + Swift
alex
2
530
Other Decks in Programming
See All in Programming
2025年版 サーバーレス Web アプリケーションの作り方
hayatow
23
25k
SpecKitでどこまでできる? コストはどれくらい?
leveragestech
0
440
ソフトウェア設計の実践的な考え方
masuda220
PRO
2
290
Reduxモダナイズ 〜コードのモダン化を通して、将来のライブラリ移行に備える〜
pvcresin
2
660
Pull-Requestの内容を1クリックで動作確認可能にするワークフロー
natmark
1
420
ИИ-Агенты в каждый дом – Алексей Порядин, PythoNN
sobolevn
0
140
Advance Your Career with Open Source
ivargrimstad
0
260
高度なUI/UXこそHotwireで作ろう Kaigi on Rails 2025
naofumi
4
3.1k
エンジニアとして高みを目指す、 利益を生み出す設計の考え方 / design-for-profit
minodriven
23
11k
Introducing ReActionView: A new ActionView-Compatible ERB Engine @ Kaigi on Rails 2025, Tokyo, Japan
marcoroth
3
860
uniqueパッケージの内部実装を支えるweak pointerの話
magavel
0
880
CSC305 Lecture 03
javiergs
PRO
0
230
Featured
See All Featured
Intergalactic Javascript Robots from Outer Space
tanoku
273
27k
We Have a Design System, Now What?
morganepeng
53
7.8k
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
657
61k
Rails Girls Zürich Keynote
gr2m
95
14k
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
35
3.2k
Scaling GitHub
holman
463
140k
Six Lessons from altMBA
skipperchong
28
4k
Being A Developer After 40
akosma
91
590k
The Cost Of JavaScript in 2023
addyosmani
53
9k
Making the Leap to Tech Lead
cromwellryan
135
9.5k
Put a Button on it: Removing Barriers to Going Fast.
kastner
60
4k
Music & Morning Musume
bryan
46
6.8k
Transcript
The cobbler's children have no shoes, or building better tools
for ourselves Alex Gaynor - PyCon 2016
About me • Director of the Python Software Foundation •
Open source contributor • Django, PyPy, CPython, pyca/cryptography, etc. • Washington, D.C. resident • Bagel and deli enthusiast • US Digital Service employee
A short history of tools
$ git init
None
Code review
Deployment automation
Emerging trends
CI for PRs
Linting (flake8, bandit, flake8-import-order, etc.)
Coverage Tracking
livegrep.com
github.com/facebook/mention-bot
Workflow
Build more tailored tools
Automation > Process
APIs!
Issues • Create an issue • Add/remove labels • Add
a comment • Assign to someone
Pull requests • Send a PR • Assign a PR
• Add/remove labels • Leave a code review • Add a commit status
Examples
$ pip install github3.py
import github3 gh_client = github3.login( os.environ["GITHUB_USERNAME"], os.environ["GITHUB_PASSWORD"], )
repo = gh_client.repository("django", "django")
HTTPS certificate expiration
def get_expiration_date(host): ssl_context = ssl.create_default_context() with closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as sock:
sock = ssl_context.wrap_socket(sock, server_hostname=host) sock.connect((host, 443)) expiration = ssl.cert_time_to_seconds(sock.getpeercert()["notAfter"]) return datetime.datetime.fromtimestamp(expiration)
while True: for host in MY_DOMAINS: expiration = get_expiration_date(host) if
expiration - datetime.datetime.now() < CUTOFF: file_an_issue(gh_client, host, expiration) time.sleep(3600)
def file_an_issue(gh_client, host, expiration): gh_client.create_issue( "django", "django", "Cert expiring soon:
{}".format(host), "The cert for `{}` expires on {}, get a new one!".format( host, expiration ), "alex", labels=["ssl-cert"] )
Auto-labeling
Web hooks
def github_webhook(request): event = request.headers.get("X-Github-Event") if event != "pull_request": return
Response(status=200) body = json.load(request.stream) if body.get("action") not in {"opened", "reopened", "synchronize"}: return Response(status=200)
issue = repo.issue(body["number"]) pr = repo.pull_request(issue.number) changed_files = (f.filename for
f in pr.iter_files()) if "django/utils/crypto.py" in changed_files: issue.add_labels("security")
Other ideas
requirements.txt bumper
UI change reviewer
Github Web hook UI Reviewer Comment Screenshots
Approval process commit status
Thanks! Questions? https://github.com/alex https://speakerdeck.com/alex