hosted-files.rst 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. ************
  2. Hosted files
  3. ************
  4. Some resources published by lazr.restful are externally hosted files
  5. that can have binary representations. lazr.restfulclient gives you
  6. access to these resources.
  7. >>> from lazr.restfulclient.tests.example import CookbookWebServiceClient
  8. >>> service = CookbookWebServiceClient()
  9. An example of a hosted binary file is the cover of a
  10. cookbook. "Everyday Greens" starts off with no cover.
  11. >>> greens = service.cookbooks['Everyday Greens']
  12. >>> cover = greens.cover
  13. >>> sorted(dir(cover))
  14. [..., 'open']
  15. >>> cover.open()
  16. Traceback (most recent call last):
  17. ...
  18. NotFound: HTTP Error 404: Not Found
  19. ...
  20. You can open a hosted file for write access and write to it as though
  21. it were a file on disk.
  22. >>> image = "Pretend this is an image."
  23. >>> len(image)
  24. 25
  25. >>> file_handle = cover.open("w", "image/png", "a-cover.png")
  26. >>> file_handle.content_type
  27. 'image/png'
  28. >>> file_handle.filename
  29. 'a-cover.png'
  30. >>> print file_handle.last_modified
  31. None
  32. >>> file_handle.write(image)
  33. >>> file_handle.close()
  34. Once it exists on the server, you can open a hosted file for read
  35. access and read it.
  36. >>> file_handle = cover.open()
  37. >>> file_handle.content_type
  38. 'image/png'
  39. >>> file_handle.filename
  40. '0'
  41. >>> last_modified = file_handle.last_modified
  42. >>> last_modified is None
  43. False
  44. >>> len(file_handle.read())
  45. 25
  46. Note that the filename is '0', not 'a-cover.png'. The filename from
  47. the server is implementation-dependent and may not have anything to do
  48. with the filename the client sent. If the server implementation uses
  49. lazr.librarian, it will serve files with the originally uploaded
  50. filename, but the example web service uses its own, simpler
  51. implementation which serves the file's ID as the filename.
  52. Modifying a file will change its 'last_modified' attribute.
  53. >>> file_handle = cover.open("w", "image/png", "another-cover.png")
  54. >>> file_handle.write(image)
  55. >>> file_handle.close()
  56. >>> file_handle = cover.open()
  57. >>> file_handle.filename
  58. '1'
  59. >>> last_modified_2 = file_handle.last_modified
  60. >>> last_modified == last_modified_2
  61. False
  62. Once a file exists, it can be deleted.
  63. >>> cover.delete()
  64. >>> cover.open()
  65. Traceback (most recent call last):
  66. ...
  67. NotFound: HTTP Error 404: Not Found
  68. ...
  69. Comparing hosted files
  70. ----------------------
  71. Two hosted file objects are the same if they point to the same
  72. server-side resource.
  73. >>> cover = service.cookbooks['Everyday Greens'].cover
  74. >>> cover_2 = service.cookbooks['Everyday Greens'].cover
  75. >>> cover == cover_2
  76. True
  77. >>> other_cover = service.cookbooks['The Joy of Cooking'].cover
  78. >>> cover == other_cover
  79. False
  80. A hosted file can be compared to None, but the comparison never succeeds.
  81. >>> cover == None
  82. False
  83. Error handling
  84. --------------
  85. The only access modes supported are 'r' and 'w'.
  86. >>> cover.open("r+")
  87. Traceback (most recent call last):
  88. ...
  89. ValueError: Invalid mode. Supported modes are: r, w
  90. When opening a file for write access, you must specify the
  91. content_type argument.
  92. >>> cover.open("w")
  93. Traceback (most recent call last):
  94. ...
  95. ValueError: Files opened for write access must specify content_type.
  96. >>> cover.open("w", "image/png")
  97. Traceback (most recent call last):
  98. ...
  99. ValueError: Files opened for write access must specify filename.
  100. When opening a file for read access, you must *not* specify the
  101. content_type or filename arguments--they come from the server.
  102. >>> cover.open("r", "image/png")
  103. Traceback (most recent call last):
  104. ...
  105. ValueError: Files opened for read access can't specify content_type.
  106. >>> cover.open("r", filename="foo.png")
  107. Traceback (most recent call last):
  108. ...
  109. ValueError: Files opened for read access can't specify filename.
  110. Caching
  111. -------
  112. Hosted file resources implement the normal server-side caching
  113. mechanism.
  114. >>> file_handle = cover.open("w", "image/png", "image.png")
  115. >>> file_handle.write(image)
  116. >>> file_handle.close()
  117. >>> import httplib2
  118. >>> httplib2.debuglevel = 1
  119. >>> service = CookbookWebServiceClient()
  120. send: ...
  121. >>> cover = service.cookbooks['Everyday Greens'].cover
  122. send: ...
  123. The first request for a file retrieves the file from the server.
  124. >>> len(cover.open().read())
  125. send: ...
  126. reply: '...303 See Other...
  127. reply: '...200 Ok...
  128. 25
  129. The second request retrieves the file from the cache.
  130. >>> len(cover.open().read())
  131. send: ...
  132. reply: '...303 See Other...
  133. reply: '...304 Not Modified...
  134. 25
  135. Finally, some cleanup code that deletes the cover.
  136. >>> cover.delete()
  137. send: 'DELETE...
  138. reply: '...200...
  139. >>> httplib2.debuglevel = 0