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
290
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
130
Learning from Failure: Post-mortems
alex
2
310
Techniques for Debugging Hard Problems
alex
1
630
Building Communities with Code Review
alex
4
330
Documenting Domain Specific Knowledge
alex
1
420
Pickles are for Delis, not for Software
alex
0
500
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
CSC307 Lecture 13
javiergs
PRO
0
310
「やめとこ」がなくなった — 1月にZennを始めて22本書いた AI共創開発のリアル
atani14
0
360
DevinとClaude Code、SREの現場で使い倒してみた件
karia
1
990
メタプログラミングで実現する「コードを仕様にする」仕組み/nikkei-tech-talk43
nikkei_engineer_recruiting
0
170
Takumiから考えるSecurity_Maturity_Model.pdf
gessy0129
1
130
朝日新聞のデジタル版を支えるGoバックエンド ー価値ある情報をいち早く確実にお届けするために
junkiishida
1
740
Codex の「自走力」を高める
yorifuji
0
1.1k
NOT A HOTEL - 建築や人と融合し、自由を創り出すソフトウェア
not_a_hokuts
2
930
Rails Girls Tokyo 18th GMO Pepabo Sponsor Talk
yutokyokutyo
0
220
Cyrius ーLinux非依存にコンテナをネイティブ実行する専用OSー
n4mlz
0
110
今、アーキテクトとして 品質保証にどう関わるか
nealle
0
210
The Past, Present, and Future of Enterprise Java
ivargrimstad
0
350
Featured
See All Featured
How STYLIGHT went responsive
nonsquared
100
6k
The Curse of the Amulet
leimatthew05
1
9.7k
How Fast Is Fast Enough? [PerfNow 2025]
tammyeverts
3
480
SEO for Brand Visibility & Recognition
aleyda
0
4.3k
How to Think Like a Performance Engineer
csswizardry
28
2.5k
The Spectacular Lies of Maps
axbom
PRO
1
600
Color Theory Basics | Prateek | Gurzu
gurzu
0
240
The Straight Up "How To Draw Better" Workshop
denniskardys
239
140k
How to build an LLM SEO readiness audit: a practical framework
nmsamuel
1
670
The Art of Programming - Codeland 2020
erikaheidi
57
14k
Lightning Talk: Beautiful Slides for Beginners
inesmontani
PRO
1
470
[RailsConf 2023] Rails as a piece of cake
palkan
59
6.4k
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