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
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
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
430
Pickles are for Delis, not for Software
alex
0
520
Code Review in Open Source Software
alex
4
810
Why Ruby isn't slow
alex
10
3.8k
PyPy + Swift
alex
2
570
Other Decks in Programming
See All in Programming
AI時代のエンジニアリングの原則 / Engineering Principles in the AI Era
haru860
0
1.1k
20年以上続くプロダクトでも使い続けられる静的解析ツールを求めて
matsuo_atsushi
0
140
Terraform言語の静的解析 / static analysis of Terraform language
wata727
1
140
エラー処理の温故知新 / history of error handling technic
ryotanakaya
7
1.9k
t *testing.T は どこからやってくるの?
otakakot
1
920
KMP × Kotlin 2.3 - How Android Got Slower While iOS Builds Improved by 47%
rio432
0
160
The Past, Present, and Future of Enterprise Java
ivargrimstad
0
560
Import assertionsが消えた日~ECMAScriptの仕様はどう決まり、なぜ覆るのか~
bicstone
2
180
Programming with a DJ Controller — not vibe coding
m_seki
3
810
AIを導入する前にやるべきこと
negima
2
340
開発とはなにか、Essenceカーネルで見えるもの
ukin0k0
0
110
UaaL×Androidアプリのメモリ計測 — Memory Profilerの先へ
rio432
0
140
Featured
See All Featured
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
31
2.8k
BBQ
matthewcrist
89
10k
The World Runs on Bad Software
bkeepers
PRO
72
12k
The innovator’s Mindset - Leading Through an Era of Exponential Change - McGill University 2025
jdejongh
PRO
1
170
Building the Perfect Custom Keyboard
takai
2
750
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
234
17k
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
47
8.1k
Typedesign – Prime Four
hannesfritz
42
3k
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
254
22k
Effective software design: The role of men in debugging patriarchy in IT @ Voxxed Days AMS
baasie
0
340
Designing Experiences People Love
moore
143
24k
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
28
3.5k
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