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
92
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
370
Pickles are for Delis, not for Software
alex
0
350
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
Amazon Q CLI開発で学んだAIコーディングツールの使い方
licux
3
180
新世界の理解
koriym
0
130
マイコンでもRustのtestがしたい その2/KernelVM Tokyo 18
tnishinaga
2
2.3k
20250808_AIAgent勉強会_ClaudeCodeデータ分析の実運用〜競馬を題材に回収率100%の先を目指すメソッドとは〜
kkakeru
0
170
実践!App Intents対応
yuukiw00w
1
270
ライブ配信サービスの インフラのジレンマ -マルチクラウドに至ったワケ-
mirrativ
1
210
11年かかって やっとVibe Codingに 時代が追いつきましたね
yimajo
1
260
あのころの iPod を どうにか再生させたい
orumin
2
2.4k
Portapad紹介プレゼンテーション
gotoumakakeru
1
130
生成AI、実際どう? - ニーリーの場合
nealle
0
110
バイブコーディングの正体——AIエージェントはソフトウェア開発を変えるか?
stakaya
5
920
JetBrainsのAI機能の紹介 #jjug
yusuke
0
200
Featured
See All Featured
Embracing the Ebb and Flow
colly
86
4.8k
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
161
15k
We Have a Design System, Now What?
morganepeng
53
7.7k
Statistics for Hackers
jakevdp
799
220k
Scaling GitHub
holman
462
140k
GraphQLの誤解/rethinking-graphql
sonatard
71
11k
The Language of Interfaces
destraynor
158
25k
Large-scale JavaScript Application Architecture
addyosmani
512
110k
Connecting the Dots Between Site Speed, User Experience & Your Business [WebExpo 2025]
tammyeverts
8
460
YesSQL, Process and Tooling at Scale
rocio
173
14k
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
31
2.2k
Making the Leap to Tech Lead
cromwellryan
134
9.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