Upgrade to PRO for Only $50/Year—Limited-Time Offer! 🔥
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
270
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
110
Learning from Failure: Post-mortems
alex
2
300
Techniques for Debugging Hard Problems
alex
1
610
Building Communities with Code Review
alex
4
300
Documenting Domain Specific Knowledge
alex
1
390
Pickles are for Delis, not for Software
alex
0
440
Code Review in Open Source Software
alex
4
780
Why Ruby isn't slow
alex
10
3.8k
PyPy + Swift
alex
2
540
Other Decks in Programming
See All in Programming
Developing static sites with Ruby
okuramasafumi
0
270
안드로이드 9년차 개발자, 프론트엔드 주니어로 커리어 리셋하기
maryang
1
110
手軽に積ん読を増やすには?/読みたい本と付き合うには?
o0h
PRO
1
170
Full-Cycle Reactivity in Angular: SignalStore mit Signal Forms und Resources
manfredsteyer
PRO
0
210
Go コードベースの構成と AI コンテキスト定義
andpad
0
120
【CA.ai #3】Google ADKを活用したAI Agent開発と運用知見
harappa80
0
300
AIエンジニアリングのご紹介 / Introduction to AI Engineering
rkaga
5
2k
sbt 2
xuwei_k
0
270
ViewファーストなRailsアプリ開発のたのしさ
sugiwe
0
450
AIコーディングエージェント(NotebookLM)
kondai24
0
180
connect-python: convenient protobuf RPC for Python
anuraaga
0
400
配送計画の均等化機能を提供する取り組みについて(⽩⾦鉱業 Meetup Vol.21@六本⽊(数理最適化編))
izu_nori
0
150
Featured
See All Featured
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
35
2.3k
Navigating Team Friction
lara
191
16k
Speed Design
sergeychernyshev
33
1.4k
The Illustrated Children's Guide to Kubernetes
chrisshort
51
51k
YesSQL, Process and Tooling at Scale
rocio
174
15k
Thoughts on Productivity
jonyablonski
73
5k
RailsConf 2023
tenderlove
30
1.3k
What’s in a name? Adding method to the madness
productmarketing
PRO
24
3.8k
How to Think Like a Performance Engineer
csswizardry
28
2.4k
Building Better People: How to give real-time feedback that sticks.
wjessup
370
20k
Building a Scalable Design System with Sketch
lauravandoore
463
34k
The World Runs on Bad Software
bkeepers
PRO
72
12k
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