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
93
Learning from Failure: Post-mortems
alex
2
290
Techniques for Debugging Hard Problems
alex
1
580
Building Communities with Code Review
alex
4
280
Documenting Domain Specific Knowledge
alex
1
380
Pickles are for Delis, not for Software
alex
0
360
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
育てるアーキテクチャ:戦い抜くPythonマイクロサービスの設計と進化戦略
fujidomoe
1
150
The Past, Present, and Future of Enterprise Java
ivargrimstad
0
140
Goで実践するドメイン駆動開発 AIと歩み始めた新規プロダクト開発の現在地
imkaoru
4
650
uniqueパッケージの内部実装を支えるweak pointerの話
magavel
0
920
Breaking Up with Big ViewModels — Without Breaking Your Architecture (droidcon Berlin 2025)
steliosf
PRO
1
330
Web Components で実現する Hotwire とフロントエンドフレームワークの橋渡し / Bridging with Web Components
da1chi
3
1.9k
XP, Testing and ninja testing ZOZ5
m_seki
3
310
そのpreloadは必要?見過ごされたpreloadが技術的負債として爆発した日
mugitti9
2
3k
Reduxモダナイズ 〜コードのモダン化を通して、将来のライブラリ移行に備える〜
pvcresin
2
690
プログラマのための作曲入門
cheebow
0
540
CSC305 Lecture 02
javiergs
PRO
1
260
高度なUI/UXこそHotwireで作ろう Kaigi on Rails 2025
naofumi
4
3.5k
Featured
See All Featured
Why Our Code Smells
bkeepers
PRO
339
57k
Designing for Performance
lara
610
69k
BBQ
matthewcrist
89
9.8k
Building an army of robots
kneath
306
46k
The Straight Up "How To Draw Better" Workshop
denniskardys
237
140k
Reflections from 52 weeks, 52 projects
jeffersonlam
352
21k
Testing 201, or: Great Expectations
jmmastey
45
7.7k
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
45
2.5k
Done Done
chrislema
185
16k
Embracing the Ebb and Flow
colly
88
4.8k
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
PRO
23
1.5k
The MySQL Ecosystem @ GitHub 2015
samlambert
251
13k
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