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
290
1
Share
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
More Decks by Alex Gaynor
See All by Alex Gaynor
Quantifying Memory Unsafety and Reactions to It
alex
0
140
Learning from Failure: Post-mortems
alex
2
320
Techniques for Debugging Hard Problems
alex
1
640
Building Communities with Code Review
alex
4
330
Documenting Domain Specific Knowledge
alex
1
420
Pickles are for Delis, not for Software
alex
0
520
Code Review in Open Source Software
alex
4
800
Why Ruby isn't slow
alex
10
3.8k
PyPy + Swift
alex
2
560
Other Decks in Programming
See All in Programming
Kubernetes上でAgentを動かすための最新動向と押さえるべき概念まとめ
sotamaki0421
3
500
セグメントとターゲットを意識するプロポーザルの書き方 〜採択の鍵は、誰に刺すかを見極めるマーケティング戦略にある〜
m3m0r7
PRO
0
540
AI-DLC Deep Dive
yuukiyo
8
4k
Cache-moi si tu peux : patterns et pièges du cache en production - Devoxx France 2026 - Conférence
slecache
0
240
アクセシビリティ試験の"その後"を仕組み化する
yuuumiravy
0
150
Vibe NLP for Applied NLP
inesmontani
PRO
0
430
Claude Code × Gemini × Ebitengine ゲーム制作素人WebエンジニアがGoでゲームを作った話
webzawa
0
140
ドメインイベントでビジネスロジックを解きほぐす #phpcon_odawara
kajitack
3
770
mruby on C#: From VM Implementation to Game Scripting (RubyKaigi 2026)
hadashia
2
370
HTML-Aware ERB: The Path to Reactive Rendering @ RubyKaigi 2026, Hakodate, Japan
marcoroth
0
130
2026_04_15_量子計算をパズルとして解く
hideakitakechi
0
110
Kingdom of the Machine
yui_knk
2
280
Featured
See All Featured
The SEO identity crisis: Don't let AI make you average
varn
0
440
Stop Working from a Prison Cell
hatefulcrawdad
274
21k
Taking LLMs out of the black box: A practical guide to human-in-the-loop distillation
inesmontani
PRO
3
2.1k
From Legacy to Launchpad: Building Startup-Ready Communities
dugsong
0
200
End of SEO as We Know It (SMX Advanced Version)
ipullrank
3
4.1k
Building AI with AI
inesmontani
PRO
1
900
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
122
21k
Put a Button on it: Removing Barriers to Going Fast.
kastner
60
4.2k
JAMstack: Web Apps at Ludicrous Speed - All Things Open 2022
reverentgeek
1
420
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
32
2.8k
Stewardship and Sustainability of Urban and Community Forests
pwiseman
0
180
Reflections from 52 weeks, 52 projects
jeffersonlam
356
21k
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