$30 off During Our Annual Pro Sale. View Details »
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
Microservices rules: What good looks like
cer
PRO
0
1.1k
これだけで丸わかり!LangChain v1.0 アップデートまとめ
os1ma
6
1.7k
AIコードレビューがチームの"文脈"を 読めるようになるまで
marutaku
0
350
tparseでgo testの出力を見やすくする
utgwkk
1
190
AIコーディングエージェント(NotebookLM)
kondai24
0
170
AIコーディングエージェント(Manus)
kondai24
0
160
20 years of Symfony, what's next?
fabpot
2
350
ZOZOにおけるAI活用の現在 ~モバイルアプリ開発でのAI活用状況と事例~
zozotech
PRO
8
5.4k
開発に寄りそう自動テストの実現
goyoki
1
760
connect-python: convenient protobuf RPC for Python
anuraaga
0
380
30分でDoctrineの仕組みと使い方を完全にマスターする / phpconkagawa 2025 Doctrine
ttskch
3
800
C-Shared Buildで突破するAI Agent バックテストの壁
po3rin
0
380
Featured
See All Featured
Being A Developer After 40
akosma
91
590k
How to Think Like a Performance Engineer
csswizardry
28
2.4k
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
253
22k
Rebuilding a faster, lazier Slack
samanthasiow
84
9.3k
It's Worth the Effort
3n
187
29k
Faster Mobile Websites
deanohume
310
31k
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
162
15k
The Cost Of JavaScript in 2023
addyosmani
55
9.3k
Why You Should Never Use an ORM
jnunemaker
PRO
61
9.6k
We Have a Design System, Now What?
morganepeng
54
7.9k
Improving Core Web Vitals using Speculation Rules API
sergeychernyshev
21
1.3k
Measuring & Analyzing Core Web Vitals
bluesmoon
9
700
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