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
250
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
91
Learning from Failure: Post-mortems
alex
2
290
Techniques for Debugging Hard Problems
alex
1
560
Building Communities with Code Review
alex
4
270
Documenting Domain Specific Knowledge
alex
1
360
Pickles are for Delis, not for Software
alex
0
340
Code Review in Open Source Software
alex
4
750
Why Ruby isn't slow
alex
10
3.8k
PyPy + Swift
alex
2
520
Other Decks in Programming
See All in Programming
Composerが「依存解決」のためにどんな工夫をしているか #phpcon
o0h
PRO
1
240
Enterprise Web App. Development (2): Version Control Tool Training Ver. 5.1
knakagawa
1
120
PHPで始める振る舞い駆動開発(Behaviour-Driven Development)
ohmori_yusuke
2
230
Select API from Kotlin Coroutine
jmatsu
1
190
『自分のデータだけ見せたい!』を叶える──Laravel × Casbin で複雑権限をスッキリ解きほぐす 25 分
akitotsukahara
1
580
ニーリーにおけるプロダクトエンジニア
nealle
0
600
AIコーディング道場勉強会#2 君(エンジニア)たちはどう生きるか
misakiotb
1
250
データの民主化を支える、透明性のあるデータ利活用への挑戦 2025-06-25 Database Engineering Meetup#7
y_ken
0
320
Blazing Fast UI Development with Compose Hot Reload (droidcon New York 2025)
zsmb
1
250
なんとなくわかった気になるブロックテーマ入門/contents.nagoya 2025 6.28
chiilog
1
230
Bytecode Manipulation 으로 생산성 높이기
bigstark
2
380
20250613-SSKMvol.15
diostray
0
100
Featured
See All Featured
A designer walks into a library…
pauljervisheath
207
24k
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
357
30k
Rebuilding a faster, lazier Slack
samanthasiow
82
9.1k
Fireside Chat
paigeccino
37
3.5k
Cheating the UX When There Is Nothing More to Optimize - PixelPioneers
stephaniewalter
281
13k
Producing Creativity
orderedlist
PRO
346
40k
実際に使うSQLの書き方 徹底解説 / pgcon21j-tutorial
soudai
PRO
181
53k
Raft: Consensus for Rubyists
vanstee
140
7k
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
229
22k
Building a Scalable Design System with Sketch
lauravandoore
462
33k
Typedesign – Prime Four
hannesfritz
42
2.7k
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
34
3k
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