Poetic APIs

download Poetic APIs

If you can't read please download the document

  • date post

    14-May-2015
  • Category

    Sports

  • view

    1.232
  • download

    1

Embed Size (px)

description

API design is one of the most difficult areas of programming. Besides solving your immediate problem, you must also accomodate unknown future ones—and fit nicely into other people's brains. Let's explore how to do this without a time machine, considering compactness, orthogonality, consistency, safety, coupling, state handling, and the messy interface with human cognition, all illustrated with practical examples—and gruesome mistakes—from several popular Python libraries.

Transcript of Poetic APIs

  • 1.Poetic APIs by Erik Rose A poet is, before anything else, a person who is passionately in love with language.W. H. Auden

2. Poetic APIs by Erik Rose programmer ^ A poet is, before anything else, a person who is passionately in love with language.W. H. Auden 3. Language is the best way of getting ideasfrom one head into another without surgery. Mark Twain 4. Oh! Everything has a name! 5. The window became a dierent thing byhaving a symbol attached to it. 6. Inventing Language Any fool can write code that a computer can understand.Good programmers write code that humans can understand. Martin Fowler 7. req = urllib2.Request(gh_url)password_manager = urllib2.HTTPPasswordMgrWithDefaultRealm()password_manager.add_password(None, https://api.github.com, user, pass)auth_manager = urllib2.HTTPBasicAuthHandler(password_manager)opener = urllib2.build_opener(auth_manager)urllib2.install_opener(opener)handler = urllib2.urlopen(req)print handler.getcode() 8. req = urllib2.Request(gh_url)password_manager = urllib2.HTTPPasswordMgrWithDefaultRealm()password_manager.add_password(None, https://api.github.com, user, pass)auth_manager = urllib2.HTTPBasicAuthHandler(password_manager)opener = urllib2.build_opener(auth_manager)urllib2.install_opener(opener)handler = urllib2.urlopen(req)print handler.getcode()r = requests.get(https://api.github.com, auth=(user, pass))print r.status_code 9. Dont Be AnArchitecture AstronautIts hard to make predictions, especially about the future. Robert Storm Petersen 10. The best libraries are extracted, not invented. 11. def terminal_codes(self, stream):capabilities = [bold, sc, rc, sgr0, el]if hasattr(stream, fileno) and isatty(stream.fileno()):# Explicit args make setupterm() work even when -s is passed:setupterm(None, stream.fileno()) # so things like tigetstr() workcodes = dict((x, tigetstr(x)) for x in capabilities)cup = tigetstr(cup)codes[cup] = lambda line, column: tparm(cup, line, column)else:# If youre crazy enough to pipe this to a file or something,# dont output terminal codes:codes = defaultdict(lambda: , cup=lambda line, column: )return codes...self._codes = terminal_codes(stdout)...class AtLine(object):def __enter__(self):"""Save position and move to progress bar, col 1."""self.stream.write(self._codes[sc]) # save positionself.stream.write(self._codes[cup](self.line, 0))def __exit__(self, type, value, tb):self.stream.write(self._codes[rc]) # restore position...print self._codes[bold] + results + self._codes[sgr0] 12. Tasks 13. TasksPrint some text with formatting. 14. TasksPrint some text with formatting.Print some text at a location, then snap back. 15. Language Constructs 16. Language ConstructsFunctions, arguments, keyword arguments 17. Language ConstructsFunctions, arguments, keyword argumentsDecorators 18. Language ConstructsFunctions, arguments, keyword argumentsDecorators Context managers 19. Language Constructs Functions, arguments, keyword arguments Decorators Context managersClasses (really more of an implementation detail) 20. Language Constructs Functions, arguments, keyword arguments Decorators Context managersClasses (really more of an implementation detail)Patterns, Protocols, Interfaces, and Conventions 21. Language Constructs Functions, arguments, keyword arguments Decorators Context managersClasses (really more of an implementation detail)Patterns, Protocols, Interfaces, and ConventionsSequences 22. Language Constructs Functions, arguments, keyword arguments Decorators Context managersClasses (really more of an implementation detail)Patterns, Protocols, Interfaces, and ConventionsSequences Iterators 23. Language Constructs Functions, arguments, keyword arguments Decorators Context managersClasses (really more of an implementation detail)Patterns, Protocols, Interfaces, and ConventionsSequences IteratorsMappings 24. ConsistencyThink like a wise man, but communicate in the language of the people. William Butler Yeats 25. get(key, default)is better thanfetch(default, key) 26. TasksPrint some text at a location, then snap back.Print some text with formatting. 27. TasksPrint some text at a location, then snap back.Print some text with formatting.print_at(Hello world, 10, 2)with location(10, 2):print Hello worldfor thing in range(10):print thing 28. TasksPrint some text at a location, then snap back.Print some text with formatting.print_formatted(Hello world, red, bold)print color(Hello world, red, bold)print color(Hello world)print red(bold(Hello) + world)print codes[red] + codes[bold] + Hello world + codes[normal]print {t.red}Hi{t.bold}Mom{t.normal}.format(t=terminal)print terminal.red_bold + Hello world + terminal.normal 29. TasksPrint some text at a location, then snap back.Print some text with formatting.print_formatted(Hello world, red, bold)print color(Hello world, red, bold)print color(Hello world)print red(bold(Hello) + world)print codes[red] + codes[bold] + Hello world + codes[normal]print {t.red}Hi{t.bold}Mom{t.normal}.format(t=terminal)print terminal.red_bold + Hello world + terminal.normal 30. TasksPrint some text at a location, then snap back.Print some text with formatting.print_formatted(Hello world, red, bold)print color(Hello world, red, bold)print color(Hello world)print red(bold(Hello) + world)print codes[red] + codes[bold] + Hello world + codes[normal]print {t.red}Hi{t.bold}Mom{t.normal}.format(t=terminal)print terminal.red_bold + Hello world + terminal.normal 31. TasksPrint some text at a location, then snap back.Print some text with formatting.print_formatted(Hello world, red, bold)print color(Hello world, red, bold)print color(Hello world)print red(bold(Hello) + world)print codes[red] + codes[bold] + Hello world + codes[normal]print {t.red}Hi{t.bold}Mom{t.normal}.format(t=terminal)print terminal.red_bold + Hello world + terminal.normal 32. from blessings import Terminalt = Terminal()print t.red_bold + Hello world + t.normalprint t.red_on_white + Hello world + t.normalprint t.underline_red_on_green + Hello world + t.normal 33. from blessings import Terminalt = Terminal()print t.red_bold + Hello world + t.normalprint t.red_on_white + Hello world + t.normalprint t.underline_red_on_green + Hello world + t.normalArticle.objects.filter(tag__in=[color_red, color_blue])Article.objects.filter(tag__contains=color) 34. Consistency warning signs 35. Consistencywarning signsFrequent references to your docs or source 36. Consistencywarning signsFrequent references to your docs or source Feeling syntactically clever 37. BrevityThe finest language is mostly made upof simple, unimposing words. George Eliot 38. from blessings import Terminalterm = Terminal()print term.bold + I am bold! + term.normal 39. from blessings import Terminalterm = Terminal()print term.bold + I am bold! + term.normalprint term.bold(I am bold!) 40. from blessings import Terminalterm = Terminal()print term.bold + I am bold! + term.normalprint term.bold(I am bold!)print {t.bold}Very {t.red}emphasized{t.normal}.format(t=term) 41. Brevity warning signs 42. Brevitywarning signsCopying and pasting when writing against your API 43. Brevitywarning signsCopying and pasting when writing against your APITyping something irrelevant while grumblingWhy cant it just assume the obvious thing? 44. Composability Perfection is achieved not when there is nothing left to add but when there is nothing left to take away. Antoine de Saint-Exupery 45. print_formatted(Hello world, red, bold) 46. print_formatted(Hello world, red, bold)print_formatted(Hello world, red, bold, out=some_file) 47. print_formatted(Hello world, red, bold)print_formatted(Hello world, red, bold, out=some_file)print formatted(Hello world, red, bold) 48. Composabiltywarning signs 49. Composabilty warning signs Classes with lots of state 50. Composabiltywarning signs Classes with lots of stateclass ElasticSearch(object):"""An object which manages connections to elasticsearch and acts as ago-between for API calls to it""" def index(self, index, doc_type, doc, id=None, force_insert=False, query_params=None): """Put a typed JSON document into a specific index to make it searchable.""" def search(self, query, **kwargs): """Execute a search query against one or more indices and get back search hits.""" def more_like_this(self, index, doc_type, id, mlt_fields, body=, query_params=None): """Execute a "more like this" search query against one or more fields and get back search hits.""". . . 51. Composabilty warning signs Classes with lots of stateclass ElasticSearch(object):""" class PenaltyBox(object):An object which manages connections to elasticsearch and acts as a """A thread-safe bucket of servers (or other things) that may havego-between for API calls to it""" downtime."""def index(self, index, doc_type, doc, id=None, force_insert=False,query_params=None): def get(self):"""Put a typed JSON document into a specific index server and a bool indicating whether it was from the """Return a random to make itsearchable.""" dead list."""def search(self, query, **kwargs): mark_dead(self, server): def"""Execute a search query against one or more indices and get wont search """Guarantee that this server back be returned again until a period ofhits.""" time has passed, unless all servers are dead."""def more_like_this(self, index, def mark_live(self, server): doc_type, id, mlt_fields, body=, query_params=None):"""Execute a "more like this" search query against one or dead list to and live one.""""""Move a server from the more fields theget back search hits.""". . . 52. Composabilty warning signsClasses with lots of state Deep inheritance hierarchies 53. Composabilty warning signsClasses with lots of state Deep inheritance hierarchies Violations of the Law of Demeter 54. Composabilty warning signsClasses with lots of state Deep inheritance hierarchies Violations of the Law of Demeter Mocking in tests 55. Composabiltywarning signs Classes with lots of stateDeep inheritance hierarchiesViolations of the Law of DemeterMocking in testsprint_forma