kinto 20.0.0__tar.gz → 20.4.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of kinto might be problematic. Click here for more details.

Files changed (396) hide show
  1. {kinto-20.0.0 → kinto-20.4.0}/PKG-INFO +3 -2
  2. {kinto-20.0.0 → kinto-20.4.0}/constraints.txt +5 -5
  3. {kinto-20.0.0 → kinto-20.4.0}/docs/api/1.x/history.rst +18 -0
  4. {kinto-20.0.0 → kinto-20.4.0}/docs/configuration/settings.rst +13 -0
  5. {kinto-20.0.0 → kinto-20.4.0}/docs/requirements.txt +1 -1
  6. {kinto-20.0.0 → kinto-20.4.0}/kinto/config/kinto.tpl +5 -2
  7. {kinto-20.0.0 → kinto-20.4.0}/kinto/core/__init__.py +14 -0
  8. {kinto-20.0.0 → kinto-20.4.0}/kinto/core/initialization.py +5 -2
  9. {kinto-20.0.0 → kinto-20.4.0}/kinto/core/storage/__init__.py +15 -0
  10. {kinto-20.0.0 → kinto-20.4.0}/kinto/core/storage/memory.py +20 -3
  11. {kinto-20.0.0 → kinto-20.4.0}/kinto/core/storage/postgresql/__init__.py +31 -1
  12. kinto-20.4.0/kinto/core/storage/postgresql/migrations/migration_022_023.sql +5 -0
  13. {kinto-20.0.0 → kinto-20.4.0}/kinto/core/storage/postgresql/schema.sql +3 -2
  14. {kinto-20.0.0 → kinto-20.4.0}/kinto/core/storage/testing.py +41 -1
  15. kinto-20.4.0/kinto/plugins/admin/VERSION +1 -0
  16. kinto-20.4.0/kinto/plugins/admin/build/VERSION +1 -0
  17. kinto-20.0.0/kinto/plugins/admin/build/assets/index-Bq62Gei8.js → kinto-20.4.0/kinto/plugins/admin/build/assets/index-CylsivYB.js +66 -66
  18. {kinto-20.0.0 → kinto-20.4.0}/kinto/plugins/admin/build/index.html +1 -1
  19. {kinto-20.0.0 → kinto-20.4.0}/kinto/plugins/history/__init__.py +10 -0
  20. {kinto-20.0.0 → kinto-20.4.0}/kinto/plugins/history/listener.py +68 -5
  21. {kinto-20.0.0 → kinto-20.4.0}/kinto.egg-info/PKG-INFO +3 -2
  22. {kinto-20.0.0 → kinto-20.4.0}/kinto.egg-info/SOURCES.txt +2 -1
  23. {kinto-20.0.0 → kinto-20.4.0}/tests/core/test_logging.py +25 -1
  24. {kinto-20.0.0 → kinto-20.4.0}/tests/core/test_storage.py +1 -0
  25. {kinto-20.0.0 → kinto-20.4.0}/tests/plugins/test_history.py +146 -0
  26. {kinto-20.0.0 → kinto-20.4.0}/tests/test_configuration/test.ini +5 -2
  27. kinto-20.0.0/kinto/plugins/admin/VERSION +0 -1
  28. kinto-20.0.0/kinto/plugins/admin/build/VERSION +0 -1
  29. {kinto-20.0.0 → kinto-20.4.0}/.dockerignore +0 -0
  30. {kinto-20.0.0 → kinto-20.4.0}/.github/CODE_OF_CONDUCT.md +0 -0
  31. {kinto-20.0.0 → kinto-20.4.0}/.github/CONTRIBUTING.md +0 -0
  32. {kinto-20.0.0 → kinto-20.4.0}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  33. {kinto-20.0.0 → kinto-20.4.0}/.github/dependabot.yml +0 -0
  34. {kinto-20.0.0 → kinto-20.4.0}/.github/release.yml +0 -0
  35. {kinto-20.0.0 → kinto-20.4.0}/.github/workflows/labels.yaml +0 -0
  36. {kinto-20.0.0 → kinto-20.4.0}/.github/workflows/publish.yml +0 -0
  37. {kinto-20.0.0 → kinto-20.4.0}/.github/workflows/scheduled.yml +0 -0
  38. {kinto-20.0.0 → kinto-20.4.0}/.github/workflows/test.yml +0 -0
  39. {kinto-20.0.0 → kinto-20.4.0}/.gitignore +0 -0
  40. {kinto-20.0.0 → kinto-20.4.0}/.readthedocs.yaml +0 -0
  41. {kinto-20.0.0 → kinto-20.4.0}/CHANGELOG.rst +0 -0
  42. {kinto-20.0.0 → kinto-20.4.0}/CONTRIBUTORS.rst +0 -0
  43. {kinto-20.0.0 → kinto-20.4.0}/Dockerfile +0 -0
  44. {kinto-20.0.0 → kinto-20.4.0}/LICENSE +0 -0
  45. {kinto-20.0.0 → kinto-20.4.0}/Makefile +0 -0
  46. {kinto-20.0.0 → kinto-20.4.0}/README.rst +0 -0
  47. {kinto-20.0.0 → kinto-20.4.0}/SECURITY.md +0 -0
  48. {kinto-20.0.0 → kinto-20.4.0}/SUPPORT.md +0 -0
  49. {kinto-20.0.0 → kinto-20.4.0}/app.wsgi +0 -0
  50. {kinto-20.0.0 → kinto-20.4.0}/constraints.in +0 -0
  51. {kinto-20.0.0 → kinto-20.4.0}/docker-compose.yml +0 -0
  52. {kinto-20.0.0 → kinto-20.4.0}/docs/_static/piwik.js +0 -0
  53. {kinto-20.0.0 → kinto-20.4.0}/docs/_static/theme_overrides.css +0 -0
  54. {kinto-20.0.0 → kinto-20.4.0}/docs/_templates/footer.html +0 -0
  55. {kinto-20.0.0 → kinto-20.4.0}/docs/_templates/indexcontent.html +0 -0
  56. {kinto-20.0.0 → kinto-20.4.0}/docs/_templates/layout.html +0 -0
  57. {kinto-20.0.0 → kinto-20.4.0}/docs/api/1.x/_details-delete-list.rst +0 -0
  58. {kinto-20.0.0 → kinto-20.4.0}/docs/api/1.x/_details-delete-object.rst +0 -0
  59. {kinto-20.0.0 → kinto-20.4.0}/docs/api/1.x/_details-get-list.rst +0 -0
  60. {kinto-20.0.0 → kinto-20.4.0}/docs/api/1.x/_details-get-object.rst +0 -0
  61. {kinto-20.0.0 → kinto-20.4.0}/docs/api/1.x/_details-head-list.rst +0 -0
  62. {kinto-20.0.0 → kinto-20.4.0}/docs/api/1.x/_details-patch-object.rst +0 -0
  63. {kinto-20.0.0 → kinto-20.4.0}/docs/api/1.x/_details-post-list.rst +0 -0
  64. {kinto-20.0.0 → kinto-20.4.0}/docs/api/1.x/_details-put-object.rst +0 -0
  65. {kinto-20.0.0 → kinto-20.4.0}/docs/api/1.x/_status-delete-list.rst +0 -0
  66. {kinto-20.0.0 → kinto-20.4.0}/docs/api/1.x/_status-delete-object.rst +0 -0
  67. {kinto-20.0.0 → kinto-20.4.0}/docs/api/1.x/_status-get-list.rst +0 -0
  68. {kinto-20.0.0 → kinto-20.4.0}/docs/api/1.x/_status-get-object.rst +0 -0
  69. {kinto-20.0.0 → kinto-20.4.0}/docs/api/1.x/_status-patch-object.rst +0 -0
  70. {kinto-20.0.0 → kinto-20.4.0}/docs/api/1.x/_status-post-list.rst +0 -0
  71. {kinto-20.0.0 → kinto-20.4.0}/docs/api/1.x/_status-put-object.rst +0 -0
  72. {kinto-20.0.0 → kinto-20.4.0}/docs/api/1.x/accounts.rst +0 -0
  73. {kinto-20.0.0 → kinto-20.4.0}/docs/api/1.x/admin.rst +0 -0
  74. {kinto-20.0.0 → kinto-20.4.0}/docs/api/1.x/authentication.rst +0 -0
  75. {kinto-20.0.0 → kinto-20.4.0}/docs/api/1.x/backoff.rst +0 -0
  76. {kinto-20.0.0 → kinto-20.4.0}/docs/api/1.x/batch.rst +0 -0
  77. {kinto-20.0.0 → kinto-20.4.0}/docs/api/1.x/buckets.rst +0 -0
  78. {kinto-20.0.0 → kinto-20.4.0}/docs/api/1.x/collections.rst +0 -0
  79. {kinto-20.0.0 → kinto-20.4.0}/docs/api/1.x/deprecation.rst +0 -0
  80. {kinto-20.0.0 → kinto-20.4.0}/docs/api/1.x/errors.rst +0 -0
  81. {kinto-20.0.0 → kinto-20.4.0}/docs/api/1.x/filtering.rst +0 -0
  82. {kinto-20.0.0 → kinto-20.4.0}/docs/api/1.x/flush.rst +0 -0
  83. {kinto-20.0.0 → kinto-20.4.0}/docs/api/1.x/groups.rst +0 -0
  84. {kinto-20.0.0 → kinto-20.4.0}/docs/api/1.x/index.rst +0 -0
  85. {kinto-20.0.0 → kinto-20.4.0}/docs/api/1.x/openapi.rst +0 -0
  86. {kinto-20.0.0 → kinto-20.4.0}/docs/api/1.x/openid.rst +0 -0
  87. {kinto-20.0.0 → kinto-20.4.0}/docs/api/1.x/pagination.rst +0 -0
  88. {kinto-20.0.0 → kinto-20.4.0}/docs/api/1.x/permissions.rst +0 -0
  89. {kinto-20.0.0 → kinto-20.4.0}/docs/api/1.x/records.rst +0 -0
  90. {kinto-20.0.0 → kinto-20.4.0}/docs/api/1.x/selecting_fields.rst +0 -0
  91. {kinto-20.0.0 → kinto-20.4.0}/docs/api/1.x/sorting.rst +0 -0
  92. {kinto-20.0.0 → kinto-20.4.0}/docs/api/1.x/timestamps.rst +0 -0
  93. {kinto-20.0.0 → kinto-20.4.0}/docs/api/1.x/utilities.rst +0 -0
  94. {kinto-20.0.0 → kinto-20.4.0}/docs/api/index.rst +0 -0
  95. {kinto-20.0.0 → kinto-20.4.0}/docs/api/versioning.rst +0 -0
  96. {kinto-20.0.0 → kinto-20.4.0}/docs/changelog.rst +0 -0
  97. {kinto-20.0.0 → kinto-20.4.0}/docs/commandline.rst +0 -0
  98. {kinto-20.0.0 → kinto-20.4.0}/docs/community.rst +0 -0
  99. {kinto-20.0.0 → kinto-20.4.0}/docs/concepts.rst +0 -0
  100. {kinto-20.0.0 → kinto-20.4.0}/docs/conf.py +0 -0
  101. {kinto-20.0.0 → kinto-20.4.0}/docs/configuration/good-practices.rst +0 -0
  102. {kinto-20.0.0 → kinto-20.4.0}/docs/configuration/index.rst +0 -0
  103. {kinto-20.0.0 → kinto-20.4.0}/docs/configuration/production.rst +0 -0
  104. {kinto-20.0.0 → kinto-20.4.0}/docs/core/_static/theme_overrides.css +0 -0
  105. {kinto-20.0.0 → kinto-20.4.0}/docs/core/api.rst +0 -0
  106. {kinto-20.0.0 → kinto-20.4.0}/docs/core/cache.rst +0 -0
  107. {kinto-20.0.0 → kinto-20.4.0}/docs/core/decorators.rst +0 -0
  108. {kinto-20.0.0 → kinto-20.4.0}/docs/core/errors.rst +0 -0
  109. {kinto-20.0.0 → kinto-20.4.0}/docs/core/glossary.rst +0 -0
  110. {kinto-20.0.0 → kinto-20.4.0}/docs/core/images/cliquet-base.png +0 -0
  111. {kinto-20.0.0 → kinto-20.4.0}/docs/core/images/cliquet-mozilla.png +0 -0
  112. {kinto-20.0.0 → kinto-20.4.0}/docs/core/index.rst +0 -0
  113. {kinto-20.0.0 → kinto-20.4.0}/docs/core/notifications.rst +0 -0
  114. {kinto-20.0.0 → kinto-20.4.0}/docs/core/permission.rst +0 -0
  115. {kinto-20.0.0 → kinto-20.4.0}/docs/core/quickstart.rst +0 -0
  116. {kinto-20.0.0 → kinto-20.4.0}/docs/core/rationale.rst +0 -0
  117. {kinto-20.0.0 → kinto-20.4.0}/docs/core/resource.rst +0 -0
  118. {kinto-20.0.0 → kinto-20.4.0}/docs/core/storage.rst +0 -0
  119. {kinto-20.0.0 → kinto-20.4.0}/docs/core/testing.rst +0 -0
  120. {kinto-20.0.0 → kinto-20.4.0}/docs/core/utils.rst +0 -0
  121. {kinto-20.0.0 → kinto-20.4.0}/docs/core/viewsets.rst +0 -0
  122. {kinto-20.0.0 → kinto-20.4.0}/docs/faq.rst +0 -0
  123. {kinto-20.0.0 → kinto-20.4.0}/docs/images/alwaysdata-button.svg +0 -0
  124. {kinto-20.0.0 → kinto-20.4.0}/docs/images/architecture.svg +0 -0
  125. {kinto-20.0.0 → kinto-20.4.0}/docs/images/color-formatter.png +0 -0
  126. {kinto-20.0.0 → kinto-20.4.0}/docs/images/concepts-general.png +0 -0
  127. {kinto-20.0.0 → kinto-20.4.0}/docs/images/concepts-permissions.png +0 -0
  128. {kinto-20.0.0 → kinto-20.4.0}/docs/images/heroku-button.png +0 -0
  129. {kinto-20.0.0 → kinto-20.4.0}/docs/images/kinto-logo.png +0 -0
  130. {kinto-20.0.0 → kinto-20.4.0}/docs/images/kinto-logo.svg +0 -0
  131. {kinto-20.0.0 → kinto-20.4.0}/docs/images/logo-admin.svg +0 -0
  132. {kinto-20.0.0 → kinto-20.4.0}/docs/images/logo-attachment.svg +0 -0
  133. {kinto-20.0.0 → kinto-20.4.0}/docs/images/logo-community.svg +0 -0
  134. {kinto-20.0.0 → kinto-20.4.0}/docs/images/logo-history.svg +0 -0
  135. {kinto-20.0.0 → kinto-20.4.0}/docs/images/logo-javascript.svg +0 -0
  136. {kinto-20.0.0 → kinto-20.4.0}/docs/images/logo-jsonschema.svg +0 -0
  137. {kinto-20.0.0 → kinto-20.4.0}/docs/images/logo-multiapps.svg +0 -0
  138. {kinto-20.0.0 → kinto-20.4.0}/docs/images/logo-permissions.svg +0 -0
  139. {kinto-20.0.0 → kinto-20.4.0}/docs/images/logo-python.svg +0 -0
  140. {kinto-20.0.0 → kinto-20.4.0}/docs/images/logo-selfhostable.svg +0 -0
  141. {kinto-20.0.0 → kinto-20.4.0}/docs/images/logo-synchronisation.svg +0 -0
  142. {kinto-20.0.0 → kinto-20.4.0}/docs/images/overview-deployonce-selfhost.png +0 -0
  143. {kinto-20.0.0 → kinto-20.4.0}/docs/images/overview-features.png +0 -0
  144. {kinto-20.0.0 → kinto-20.4.0}/docs/images/overview-synchronisation.png +0 -0
  145. {kinto-20.0.0 → kinto-20.4.0}/docs/images/overview-use-cases.png +0 -0
  146. {kinto-20.0.0 → kinto-20.4.0}/docs/images/scalingo-button.svg +0 -0
  147. {kinto-20.0.0 → kinto-20.4.0}/docs/images/screenshot-kinto-admin-1.png +0 -0
  148. {kinto-20.0.0 → kinto-20.4.0}/docs/images/screenshot-kinto-admin-2.png +0 -0
  149. {kinto-20.0.0 → kinto-20.4.0}/docs/images/screenshot-kinto-admin-3.png +0 -0
  150. {kinto-20.0.0 → kinto-20.4.0}/docs/images/screenshot-kinto-admin-4.png +0 -0
  151. {kinto-20.0.0 → kinto-20.4.0}/docs/images/sequence-storage.png +0 -0
  152. {kinto-20.0.0 → kinto-20.4.0}/docs/images/sync-both.svg +0 -0
  153. {kinto-20.0.0 → kinto-20.4.0}/docs/images/sync-newest.svg +0 -0
  154. {kinto-20.0.0 → kinto-20.4.0}/docs/images/sync-oldest.svg +0 -0
  155. {kinto-20.0.0 → kinto-20.4.0}/docs/index.rst +0 -0
  156. {kinto-20.0.0 → kinto-20.4.0}/docs/kinto-admin.rst +0 -0
  157. {kinto-20.0.0 → kinto-20.4.0}/docs/overview.rst +0 -0
  158. {kinto-20.0.0 → kinto-20.4.0}/docs/troubleshooting.rst +0 -0
  159. {kinto-20.0.0 → kinto-20.4.0}/docs/tutorials/custom-id-generator.rst +0 -0
  160. {kinto-20.0.0 → kinto-20.4.0}/docs/tutorials/first-steps.rst +0 -0
  161. {kinto-20.0.0 → kinto-20.4.0}/docs/tutorials/index.rst +0 -0
  162. {kinto-20.0.0 → kinto-20.4.0}/docs/tutorials/install.rst +0 -0
  163. {kinto-20.0.0 → kinto-20.4.0}/docs/tutorials/notifications-custom.rst +0 -0
  164. {kinto-20.0.0 → kinto-20.4.0}/docs/tutorials/permission-setups.rst +0 -0
  165. {kinto-20.0.0 → kinto-20.4.0}/docs/tutorials/permissions.rst +0 -0
  166. {kinto-20.0.0 → kinto-20.4.0}/docs/tutorials/synchronisation.rst +0 -0
  167. {kinto-20.0.0 → kinto-20.4.0}/docs/tutorials/write-plugin.rst +0 -0
  168. {kinto-20.0.0 → kinto-20.4.0}/kinto/__init__.py +0 -0
  169. {kinto-20.0.0 → kinto-20.4.0}/kinto/__main__.py +0 -0
  170. {kinto-20.0.0 → kinto-20.4.0}/kinto/authorization.py +0 -0
  171. {kinto-20.0.0 → kinto-20.4.0}/kinto/config/__init__.py +0 -0
  172. {kinto-20.0.0 → kinto-20.4.0}/kinto/contribute.json +0 -0
  173. {kinto-20.0.0 → kinto-20.4.0}/kinto/core/authentication.py +0 -0
  174. {kinto-20.0.0 → kinto-20.4.0}/kinto/core/authorization.py +0 -0
  175. {kinto-20.0.0 → kinto-20.4.0}/kinto/core/cache/__init__.py +0 -0
  176. {kinto-20.0.0 → kinto-20.4.0}/kinto/core/cache/memcached.py +0 -0
  177. {kinto-20.0.0 → kinto-20.4.0}/kinto/core/cache/memory.py +0 -0
  178. {kinto-20.0.0 → kinto-20.4.0}/kinto/core/cache/postgresql/__init__.py +0 -0
  179. {kinto-20.0.0 → kinto-20.4.0}/kinto/core/cache/postgresql/schema.sql +0 -0
  180. {kinto-20.0.0 → kinto-20.4.0}/kinto/core/cache/testing.py +0 -0
  181. {kinto-20.0.0 → kinto-20.4.0}/kinto/core/cornice/__init__.py +0 -0
  182. {kinto-20.0.0 → kinto-20.4.0}/kinto/core/cornice/cors.py +0 -0
  183. {kinto-20.0.0 → kinto-20.4.0}/kinto/core/cornice/errors.py +0 -0
  184. {kinto-20.0.0 → kinto-20.4.0}/kinto/core/cornice/pyramidhook.py +0 -0
  185. {kinto-20.0.0 → kinto-20.4.0}/kinto/core/cornice/renderer.py +0 -0
  186. {kinto-20.0.0 → kinto-20.4.0}/kinto/core/cornice/resource.py +0 -0
  187. {kinto-20.0.0 → kinto-20.4.0}/kinto/core/cornice/service.py +0 -0
  188. {kinto-20.0.0 → kinto-20.4.0}/kinto/core/cornice/util.py +0 -0
  189. {kinto-20.0.0 → kinto-20.4.0}/kinto/core/cornice/validators/__init__.py +0 -0
  190. {kinto-20.0.0 → kinto-20.4.0}/kinto/core/cornice/validators/_colander.py +0 -0
  191. {kinto-20.0.0 → kinto-20.4.0}/kinto/core/cornice/validators/_marshmallow.py +0 -0
  192. {kinto-20.0.0 → kinto-20.4.0}/kinto/core/cornice_swagger/__init__.py +0 -0
  193. {kinto-20.0.0 → kinto-20.4.0}/kinto/core/cornice_swagger/converters/__init__.py +0 -0
  194. {kinto-20.0.0 → kinto-20.4.0}/kinto/core/cornice_swagger/converters/exceptions.py +0 -0
  195. {kinto-20.0.0 → kinto-20.4.0}/kinto/core/cornice_swagger/converters/parameters.py +0 -0
  196. {kinto-20.0.0 → kinto-20.4.0}/kinto/core/cornice_swagger/converters/schema.py +0 -0
  197. {kinto-20.0.0 → kinto-20.4.0}/kinto/core/cornice_swagger/swagger.py +0 -0
  198. {kinto-20.0.0 → kinto-20.4.0}/kinto/core/cornice_swagger/templates/index.html +0 -0
  199. {kinto-20.0.0 → kinto-20.4.0}/kinto/core/cornice_swagger/templates/index_script_template.html +0 -0
  200. {kinto-20.0.0 → kinto-20.4.0}/kinto/core/cornice_swagger/util.py +0 -0
  201. {kinto-20.0.0 → kinto-20.4.0}/kinto/core/cornice_swagger/views.py +0 -0
  202. {kinto-20.0.0 → kinto-20.4.0}/kinto/core/decorators.py +0 -0
  203. {kinto-20.0.0 → kinto-20.4.0}/kinto/core/errors.py +0 -0
  204. {kinto-20.0.0 → kinto-20.4.0}/kinto/core/events.py +0 -0
  205. {kinto-20.0.0 → kinto-20.4.0}/kinto/core/listeners/__init__.py +0 -0
  206. {kinto-20.0.0 → kinto-20.4.0}/kinto/core/metrics.py +0 -0
  207. {kinto-20.0.0 → kinto-20.4.0}/kinto/core/openapi.py +0 -0
  208. {kinto-20.0.0 → kinto-20.4.0}/kinto/core/permission/__init__.py +0 -0
  209. {kinto-20.0.0 → kinto-20.4.0}/kinto/core/permission/memory.py +0 -0
  210. {kinto-20.0.0 → kinto-20.4.0}/kinto/core/permission/postgresql/__init__.py +0 -0
  211. {kinto-20.0.0 → kinto-20.4.0}/kinto/core/permission/postgresql/migrations/migration_001_002.sql +0 -0
  212. {kinto-20.0.0 → kinto-20.4.0}/kinto/core/permission/postgresql/schema.sql +0 -0
  213. {kinto-20.0.0 → kinto-20.4.0}/kinto/core/permission/testing.py +0 -0
  214. {kinto-20.0.0 → kinto-20.4.0}/kinto/core/resource/__init__.py +0 -0
  215. {kinto-20.0.0 → kinto-20.4.0}/kinto/core/resource/model.py +0 -0
  216. {kinto-20.0.0 → kinto-20.4.0}/kinto/core/resource/schema.py +0 -0
  217. {kinto-20.0.0 → kinto-20.4.0}/kinto/core/resource/viewset.py +0 -0
  218. {kinto-20.0.0 → kinto-20.4.0}/kinto/core/schema.py +0 -0
  219. {kinto-20.0.0 → kinto-20.4.0}/kinto/core/scripts.py +0 -0
  220. {kinto-20.0.0 → kinto-20.4.0}/kinto/core/statsd.py +0 -0
  221. {kinto-20.0.0 → kinto-20.4.0}/kinto/core/storage/exceptions.py +0 -0
  222. {kinto-20.0.0 → kinto-20.4.0}/kinto/core/storage/generators.py +0 -0
  223. {kinto-20.0.0 → kinto-20.4.0}/kinto/core/storage/postgresql/client.py +0 -0
  224. {kinto-20.0.0 → kinto-20.4.0}/kinto/core/storage/postgresql/migrations/migration_001_002.sql +0 -0
  225. {kinto-20.0.0 → kinto-20.4.0}/kinto/core/storage/postgresql/migrations/migration_002_003.sql +0 -0
  226. {kinto-20.0.0 → kinto-20.4.0}/kinto/core/storage/postgresql/migrations/migration_003_004.sql +0 -0
  227. {kinto-20.0.0 → kinto-20.4.0}/kinto/core/storage/postgresql/migrations/migration_004_005.sql +0 -0
  228. {kinto-20.0.0 → kinto-20.4.0}/kinto/core/storage/postgresql/migrations/migration_005_006.sql +0 -0
  229. {kinto-20.0.0 → kinto-20.4.0}/kinto/core/storage/postgresql/migrations/migration_006_007.sql +0 -0
  230. {kinto-20.0.0 → kinto-20.4.0}/kinto/core/storage/postgresql/migrations/migration_007_008.sql +0 -0
  231. {kinto-20.0.0 → kinto-20.4.0}/kinto/core/storage/postgresql/migrations/migration_008_009.sql +0 -0
  232. {kinto-20.0.0 → kinto-20.4.0}/kinto/core/storage/postgresql/migrations/migration_009_010.sql +0 -0
  233. {kinto-20.0.0 → kinto-20.4.0}/kinto/core/storage/postgresql/migrations/migration_010_011.sql +0 -0
  234. {kinto-20.0.0 → kinto-20.4.0}/kinto/core/storage/postgresql/migrations/migration_011_012.sql +0 -0
  235. {kinto-20.0.0 → kinto-20.4.0}/kinto/core/storage/postgresql/migrations/migration_012_013.sql +0 -0
  236. {kinto-20.0.0 → kinto-20.4.0}/kinto/core/storage/postgresql/migrations/migration_013_014.sql +0 -0
  237. {kinto-20.0.0 → kinto-20.4.0}/kinto/core/storage/postgresql/migrations/migration_014_015.sql +0 -0
  238. {kinto-20.0.0 → kinto-20.4.0}/kinto/core/storage/postgresql/migrations/migration_015_016.sql +0 -0
  239. {kinto-20.0.0 → kinto-20.4.0}/kinto/core/storage/postgresql/migrations/migration_016_017.sql +0 -0
  240. {kinto-20.0.0 → kinto-20.4.0}/kinto/core/storage/postgresql/migrations/migration_017_018.sql +0 -0
  241. {kinto-20.0.0 → kinto-20.4.0}/kinto/core/storage/postgresql/migrations/migration_018_019.sql +0 -0
  242. {kinto-20.0.0 → kinto-20.4.0}/kinto/core/storage/postgresql/migrations/migration_019_020.sql +0 -0
  243. {kinto-20.0.0 → kinto-20.4.0}/kinto/core/storage/postgresql/migrations/migration_020_021.sql +0 -0
  244. {kinto-20.0.0 → kinto-20.4.0}/kinto/core/storage/postgresql/migrations/migration_021_022.sql +0 -0
  245. {kinto-20.0.0 → kinto-20.4.0}/kinto/core/storage/postgresql/migrator.py +0 -0
  246. {kinto-20.0.0 → kinto-20.4.0}/kinto/core/storage/postgresql/pool.py +0 -0
  247. {kinto-20.0.0 → kinto-20.4.0}/kinto/core/storage/utils.py +0 -0
  248. {kinto-20.0.0 → kinto-20.4.0}/kinto/core/testing.py +0 -0
  249. {kinto-20.0.0 → kinto-20.4.0}/kinto/core/utils.py +0 -0
  250. {kinto-20.0.0 → kinto-20.4.0}/kinto/core/views/__init__.py +0 -0
  251. {kinto-20.0.0 → kinto-20.4.0}/kinto/core/views/batch.py +0 -0
  252. {kinto-20.0.0 → kinto-20.4.0}/kinto/core/views/errors.py +0 -0
  253. {kinto-20.0.0 → kinto-20.4.0}/kinto/core/views/heartbeat.py +0 -0
  254. {kinto-20.0.0 → kinto-20.4.0}/kinto/core/views/hello.py +0 -0
  255. {kinto-20.0.0 → kinto-20.4.0}/kinto/core/views/openapi.py +0 -0
  256. {kinto-20.0.0 → kinto-20.4.0}/kinto/core/views/version.py +0 -0
  257. {kinto-20.0.0 → kinto-20.4.0}/kinto/events.py +0 -0
  258. {kinto-20.0.0 → kinto-20.4.0}/kinto/plugins/__init__.py +0 -0
  259. {kinto-20.0.0 → kinto-20.4.0}/kinto/plugins/accounts/__init__.py +0 -0
  260. {kinto-20.0.0 → kinto-20.4.0}/kinto/plugins/accounts/authentication.py +0 -0
  261. {kinto-20.0.0 → kinto-20.4.0}/kinto/plugins/accounts/scripts.py +0 -0
  262. {kinto-20.0.0 → kinto-20.4.0}/kinto/plugins/accounts/utils.py +0 -0
  263. {kinto-20.0.0 → kinto-20.4.0}/kinto/plugins/accounts/views.py +0 -0
  264. {kinto-20.0.0 → kinto-20.4.0}/kinto/plugins/admin/README.md +0 -0
  265. {kinto-20.0.0 → kinto-20.4.0}/kinto/plugins/admin/__init__.py +0 -0
  266. {kinto-20.0.0 → kinto-20.4.0}/kinto/plugins/admin/build/assets/asn1-EdZsLKOL.js +0 -0
  267. {kinto-20.0.0 → kinto-20.4.0}/kinto/plugins/admin/build/assets/clojure-BMjYHr_A.js +0 -0
  268. {kinto-20.0.0 → kinto-20.4.0}/kinto/plugins/admin/build/assets/css-BnMrqG3P.js +0 -0
  269. {kinto-20.0.0 → kinto-20.4.0}/kinto/plugins/admin/build/assets/index-Cs7JVwIg.css +0 -0
  270. {kinto-20.0.0 → kinto-20.4.0}/kinto/plugins/admin/build/assets/javascript-qCveANmP.js +0 -0
  271. {kinto-20.0.0 → kinto-20.4.0}/kinto/plugins/admin/build/assets/logo-VBRiKSPX.png +0 -0
  272. {kinto-20.0.0 → kinto-20.4.0}/kinto/plugins/admin/build/assets/mllike-CXdrOF99.js +0 -0
  273. {kinto-20.0.0 → kinto-20.4.0}/kinto/plugins/admin/build/assets/python-BuPzkPfP.js +0 -0
  274. {kinto-20.0.0 → kinto-20.4.0}/kinto/plugins/admin/build/assets/rpm-CTu-6PCP.js +0 -0
  275. {kinto-20.0.0 → kinto-20.4.0}/kinto/plugins/admin/build/assets/sql-D0XecflT.js +0 -0
  276. {kinto-20.0.0 → kinto-20.4.0}/kinto/plugins/admin/build/assets/ttcn-cfg-B9xdYoR4.js +0 -0
  277. {kinto-20.0.0 → kinto-20.4.0}/kinto/plugins/admin/public/help.html +0 -0
  278. {kinto-20.0.0 → kinto-20.4.0}/kinto/plugins/admin/views.py +0 -0
  279. {kinto-20.0.0 → kinto-20.4.0}/kinto/plugins/default_bucket/__init__.py +0 -0
  280. {kinto-20.0.0 → kinto-20.4.0}/kinto/plugins/flush.py +0 -0
  281. {kinto-20.0.0 → kinto-20.4.0}/kinto/plugins/history/views.py +0 -0
  282. {kinto-20.0.0 → kinto-20.4.0}/kinto/plugins/openid/__init__.py +0 -0
  283. {kinto-20.0.0 → kinto-20.4.0}/kinto/plugins/openid/utils.py +0 -0
  284. {kinto-20.0.0 → kinto-20.4.0}/kinto/plugins/openid/views.py +0 -0
  285. {kinto-20.0.0 → kinto-20.4.0}/kinto/plugins/prometheus.py +0 -0
  286. {kinto-20.0.0 → kinto-20.4.0}/kinto/plugins/statsd.py +0 -0
  287. {kinto-20.0.0 → kinto-20.4.0}/kinto/schema_validation.py +0 -0
  288. {kinto-20.0.0 → kinto-20.4.0}/kinto/views/__init__.py +0 -0
  289. {kinto-20.0.0 → kinto-20.4.0}/kinto/views/admin.py +0 -0
  290. {kinto-20.0.0 → kinto-20.4.0}/kinto/views/buckets.py +0 -0
  291. {kinto-20.0.0 → kinto-20.4.0}/kinto/views/collections.py +0 -0
  292. {kinto-20.0.0 → kinto-20.4.0}/kinto/views/contribute.py +0 -0
  293. {kinto-20.0.0 → kinto-20.4.0}/kinto/views/groups.py +0 -0
  294. {kinto-20.0.0 → kinto-20.4.0}/kinto/views/permissions.py +0 -0
  295. {kinto-20.0.0 → kinto-20.4.0}/kinto/views/records.py +0 -0
  296. {kinto-20.0.0 → kinto-20.4.0}/kinto.egg-info/dependency_links.txt +0 -0
  297. {kinto-20.0.0 → kinto-20.4.0}/kinto.egg-info/entry_points.txt +0 -0
  298. {kinto-20.0.0 → kinto-20.4.0}/kinto.egg-info/requires.txt +0 -0
  299. {kinto-20.0.0 → kinto-20.4.0}/kinto.egg-info/top_level.txt +0 -0
  300. {kinto-20.0.0 → kinto-20.4.0}/pyproject.toml +0 -0
  301. {kinto-20.0.0 → kinto-20.4.0}/scripts/pull-kinto-admin.sh +0 -0
  302. {kinto-20.0.0 → kinto-20.4.0}/setup.cfg +0 -0
  303. {kinto-20.0.0 → kinto-20.4.0}/tests/__init__.py +0 -0
  304. {kinto-20.0.0 → kinto-20.4.0}/tests/browser.ini +0 -0
  305. {kinto-20.0.0 → kinto-20.4.0}/tests/browser.py +0 -0
  306. {kinto-20.0.0 → kinto-20.4.0}/tests/core/__init__.py +0 -0
  307. {kinto-20.0.0 → kinto-20.4.0}/tests/core/listeners.py +0 -0
  308. {kinto-20.0.0 → kinto-20.4.0}/tests/core/resource/__init__.py +0 -0
  309. {kinto-20.0.0 → kinto-20.4.0}/tests/core/resource/test_base.py +0 -0
  310. {kinto-20.0.0 → kinto-20.4.0}/tests/core/resource/test_cache_expires.py +0 -0
  311. {kinto-20.0.0 → kinto-20.4.0}/tests/core/resource/test_events.py +0 -0
  312. {kinto-20.0.0 → kinto-20.4.0}/tests/core/resource/test_filter.py +0 -0
  313. {kinto-20.0.0 → kinto-20.4.0}/tests/core/resource/test_model.py +0 -0
  314. {kinto-20.0.0 → kinto-20.4.0}/tests/core/resource/test_object.py +0 -0
  315. {kinto-20.0.0 → kinto-20.4.0}/tests/core/resource/test_object_permissions.py +0 -0
  316. {kinto-20.0.0 → kinto-20.4.0}/tests/core/resource/test_pagination.py +0 -0
  317. {kinto-20.0.0 → kinto-20.4.0}/tests/core/resource/test_partial_response.py +0 -0
  318. {kinto-20.0.0 → kinto-20.4.0}/tests/core/resource/test_preconditions.py +0 -0
  319. {kinto-20.0.0 → kinto-20.4.0}/tests/core/resource/test_schema.py +0 -0
  320. {kinto-20.0.0 → kinto-20.4.0}/tests/core/resource/test_sort.py +0 -0
  321. {kinto-20.0.0 → kinto-20.4.0}/tests/core/resource/test_sync.py +0 -0
  322. {kinto-20.0.0 → kinto-20.4.0}/tests/core/resource/test_views.py +0 -0
  323. {kinto-20.0.0 → kinto-20.4.0}/tests/core/resource/test_views_cors.py +0 -0
  324. {kinto-20.0.0 → kinto-20.4.0}/tests/core/resource/test_viewset.py +0 -0
  325. {kinto-20.0.0 → kinto-20.4.0}/tests/core/schema/postgresql-permission-1.sql +0 -0
  326. {kinto-20.0.0 → kinto-20.4.0}/tests/core/schema/postgresql-storage-1.6.sql +0 -0
  327. {kinto-20.0.0 → kinto-20.4.0}/tests/core/schema/postgresql-storage-11.sql +0 -0
  328. {kinto-20.0.0 → kinto-20.4.0}/tests/core/support.py +0 -0
  329. {kinto-20.0.0 → kinto-20.4.0}/tests/core/test_authentication.py +0 -0
  330. {kinto-20.0.0 → kinto-20.4.0}/tests/core/test_authorization.py +0 -0
  331. {kinto-20.0.0 → kinto-20.4.0}/tests/core/test_cache.py +0 -0
  332. {kinto-20.0.0 → kinto-20.4.0}/tests/core/test_decorators.py +0 -0
  333. {kinto-20.0.0 → kinto-20.4.0}/tests/core/test_deprecation.py +0 -0
  334. {kinto-20.0.0 → kinto-20.4.0}/tests/core/test_errors.py +0 -0
  335. {kinto-20.0.0 → kinto-20.4.0}/tests/core/test_initialization.py +0 -0
  336. {kinto-20.0.0 → kinto-20.4.0}/tests/core/test_listeners.py +0 -0
  337. {kinto-20.0.0 → kinto-20.4.0}/tests/core/test_metrics.py +0 -0
  338. {kinto-20.0.0 → kinto-20.4.0}/tests/core/test_openapi.py +0 -0
  339. {kinto-20.0.0 → kinto-20.4.0}/tests/core/test_permission.py +0 -0
  340. {kinto-20.0.0 → kinto-20.4.0}/tests/core/test_schema.py +0 -0
  341. {kinto-20.0.0 → kinto-20.4.0}/tests/core/test_scripts.py +0 -0
  342. {kinto-20.0.0 → kinto-20.4.0}/tests/core/test_storage_migrations.py +0 -0
  343. {kinto-20.0.0 → kinto-20.4.0}/tests/core/test_storage_pool.py +0 -0
  344. {kinto-20.0.0 → kinto-20.4.0}/tests/core/test_utils.py +0 -0
  345. {kinto-20.0.0 → kinto-20.4.0}/tests/core/test_views_batch.py +0 -0
  346. {kinto-20.0.0 → kinto-20.4.0}/tests/core/test_views_errors.py +0 -0
  347. {kinto-20.0.0 → kinto-20.4.0}/tests/core/test_views_heartbeat.py +0 -0
  348. {kinto-20.0.0 → kinto-20.4.0}/tests/core/test_views_hello.py +0 -0
  349. {kinto-20.0.0 → kinto-20.4.0}/tests/core/test_views_openapi.py +0 -0
  350. {kinto-20.0.0 → kinto-20.4.0}/tests/core/test_views_postgresql.py +0 -0
  351. {kinto-20.0.0 → kinto-20.4.0}/tests/core/test_views_transaction.py +0 -0
  352. {kinto-20.0.0 → kinto-20.4.0}/tests/core/testapp/__init__.py +0 -0
  353. {kinto-20.0.0 → kinto-20.4.0}/tests/core/testapp/static/index.html +0 -0
  354. {kinto-20.0.0 → kinto-20.4.0}/tests/core/testapp/views.py +0 -0
  355. {kinto-20.0.0 → kinto-20.4.0}/tests/core/testplugin/__init__.py +0 -0
  356. {kinto-20.0.0 → kinto-20.4.0}/tests/functional.ini +0 -0
  357. {kinto-20.0.0 → kinto-20.4.0}/tests/functional.py +0 -0
  358. {kinto-20.0.0 → kinto-20.4.0}/tests/openapi/__init__.py +0 -0
  359. {kinto-20.0.0 → kinto-20.4.0}/tests/openapi/support.py +0 -0
  360. {kinto-20.0.0 → kinto-20.4.0}/tests/openapi/test_plugins.py +0 -0
  361. {kinto-20.0.0 → kinto-20.4.0}/tests/openapi/test_resources.py +0 -0
  362. {kinto-20.0.0 → kinto-20.4.0}/tests/openapi/test_responses_buckets.py +0 -0
  363. {kinto-20.0.0 → kinto-20.4.0}/tests/openapi/test_responses_collections.py +0 -0
  364. {kinto-20.0.0 → kinto-20.4.0}/tests/openapi/test_responses_errors.py +0 -0
  365. {kinto-20.0.0 → kinto-20.4.0}/tests/openapi/test_responses_groups.py +0 -0
  366. {kinto-20.0.0 → kinto-20.4.0}/tests/openapi/test_responses_records.py +0 -0
  367. {kinto-20.0.0 → kinto-20.4.0}/tests/openapi/test_validation.py +0 -0
  368. {kinto-20.0.0 → kinto-20.4.0}/tests/plugins/__init__.py +0 -0
  369. {kinto-20.0.0 → kinto-20.4.0}/tests/plugins/test_accounts.py +0 -0
  370. {kinto-20.0.0 → kinto-20.4.0}/tests/plugins/test_admin.py +0 -0
  371. {kinto-20.0.0 → kinto-20.4.0}/tests/plugins/test_default_bucket.py +0 -0
  372. {kinto-20.0.0 → kinto-20.4.0}/tests/plugins/test_flush.py +0 -0
  373. {kinto-20.0.0 → kinto-20.4.0}/tests/plugins/test_openid.py +0 -0
  374. {kinto-20.0.0 → kinto-20.4.0}/tests/plugins/test_prometheus.py +0 -0
  375. {kinto-20.0.0 → kinto-20.4.0}/tests/plugins/test_statsd.py +0 -0
  376. {kinto-20.0.0 → kinto-20.4.0}/tests/support.py +0 -0
  377. {kinto-20.0.0 → kinto-20.4.0}/tests/test_authorization.py +0 -0
  378. {kinto-20.0.0 → kinto-20.4.0}/tests/test_config.py +0 -0
  379. {kinto-20.0.0 → kinto-20.4.0}/tests/test_init.py +0 -0
  380. {kinto-20.0.0 → kinto-20.4.0}/tests/test_main.py +0 -0
  381. {kinto-20.0.0 → kinto-20.4.0}/tests/test_views_admin.py +0 -0
  382. {kinto-20.0.0 → kinto-20.4.0}/tests/test_views_buckets.py +0 -0
  383. {kinto-20.0.0 → kinto-20.4.0}/tests/test_views_collections.py +0 -0
  384. {kinto-20.0.0 → kinto-20.4.0}/tests/test_views_collections_cache.py +0 -0
  385. {kinto-20.0.0 → kinto-20.4.0}/tests/test_views_contribute.py +0 -0
  386. {kinto-20.0.0 → kinto-20.4.0}/tests/test_views_disable_default.py +0 -0
  387. {kinto-20.0.0 → kinto-20.4.0}/tests/test_views_groups.py +0 -0
  388. {kinto-20.0.0 → kinto-20.4.0}/tests/test_views_hello.py +0 -0
  389. {kinto-20.0.0 → kinto-20.4.0}/tests/test_views_metrics.py +0 -0
  390. {kinto-20.0.0 → kinto-20.4.0}/tests/test_views_objects_permissions.py +0 -0
  391. {kinto-20.0.0 → kinto-20.4.0}/tests/test_views_permissions.py +0 -0
  392. {kinto-20.0.0 → kinto-20.4.0}/tests/test_views_records.py +0 -0
  393. {kinto-20.0.0 → kinto-20.4.0}/tests/test_views_schema_collection.py +0 -0
  394. {kinto-20.0.0 → kinto-20.4.0}/tests/test_views_schema_group.py +0 -0
  395. {kinto-20.0.0 → kinto-20.4.0}/tests/test_views_schema_record.py +0 -0
  396. {kinto-20.0.0 → kinto-20.4.0}/tests/test_views_version.py +0 -0
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.2
1
+ Metadata-Version: 2.4
2
2
  Name: kinto
3
- Version: 20.0.0
3
+ Version: 20.4.0
4
4
  Summary: Kinto Web Service - Store, Sync, Share, and Self-Host.
5
5
  Author-email: Mozilla Services <developers@kinto-storage.org>
6
6
  License: Copyright 2012 - Mozilla Foundation
@@ -70,6 +70,7 @@ Provides-Extra: dev
70
70
  Requires-Dist: build; extra == "dev"
71
71
  Requires-Dist: ruff; extra == "dev"
72
72
  Requires-Dist: twine; extra == "dev"
73
+ Dynamic: license-file
73
74
 
74
75
  Kinto
75
76
  =====
@@ -73,7 +73,7 @@ markupsafe==2.1.4
73
73
  # via werkzeug
74
74
  msgpack==1.0.7
75
75
  # via bravado-core
76
- newrelic==10.6.0
76
+ newrelic==10.8.1
77
77
  # via -r constraints.in
78
78
  packaging==23.2
79
79
  # via
@@ -88,7 +88,7 @@ plaster==1.1.2
88
88
  # pyramid
89
89
  plaster-pastedeploy==1.0.1
90
90
  # via pyramid
91
- playwright==1.50.0
91
+ playwright==1.51.0
92
92
  # via -r constraints.in
93
93
  pluggy==1.5.0
94
94
  # via pytest
@@ -116,7 +116,7 @@ pytest==8.3.5
116
116
  # pytest-cov
117
117
  pytest-cache==1.0
118
118
  # via -r constraints.in
119
- pytest-cov==6.0.0
119
+ pytest-cov==6.1.1
120
120
  # via -r constraints.in
121
121
  python-dateutil==2.9.0.post0
122
122
  # via
@@ -149,7 +149,7 @@ rpds-py==0.17.1
149
149
  # via
150
150
  # jsonschema
151
151
  # referencing
152
- ruff==0.9.9
152
+ ruff==0.11.4
153
153
  # via -r constraints.in
154
154
  sentry-sdk==2.8.0
155
155
  # via -r constraints.in
@@ -162,7 +162,7 @@ six==1.16.0
162
162
  # rfc3339-validator
163
163
  soupsieve==2.5
164
164
  # via beautifulsoup4
165
- sqlalchemy==2.0.38
165
+ sqlalchemy==2.0.40
166
166
  # via
167
167
  # -r constraints.in
168
168
  # sentry-sdk
@@ -195,3 +195,21 @@ It is possible to exclude certain resources from being tracked by history using
195
195
 
196
196
  kinto.history.exclude_resources = /buckets/preview
197
197
  /buckets/signed/collections/certificates
198
+
199
+ Or certain users:
200
+
201
+ .. code-block:: ini
202
+
203
+ kinto.history.exclude_user_ids = account:quicksuggest
204
+
205
+ In order to limit the size of the history length of each resource:
206
+
207
+ .. code-block:: ini
208
+
209
+ kinto.history.auto_trim_max_count = 100
210
+
211
+ In order to limit the size of the history length of each resource only for certain users:
212
+
213
+ .. code-block:: ini
214
+
215
+ kinto.history.auto_trim_user_ids = account:quicksuggest
@@ -456,6 +456,19 @@ Example output:
456
456
  {"Pid": 19240, "Type": "root", "Timestamp": 1489067817834153984, "Severity": 4, "Hostname": "pluo", "Logger": "%", "EnvVersion": "2.0", "Fields": {"perm": "read", "userid": "ldap:john@corp.com", "message": "Permission not granted.", "uri": "/buckets/123"}}
457
457
 
458
458
 
459
+ Request IDs
460
+ :::::::::::
461
+
462
+ In order to add requests IDs to log messages, set the provided handler:
463
+
464
+ .. code-block:: ini
465
+
466
+ [handler_console]
467
+ class = kinto.core.StreamHandlerWithRequestID
468
+
469
+ It will read the value from the ``X-Request-Id`` request header if present, or generate a random string when the request is received otherwise.
470
+
471
+
459
472
  .. _handling-exceptions-with-sentry:
460
473
 
461
474
  Handling exceptions with Sentry
@@ -8,4 +8,4 @@ mock==5.2.0
8
8
  webtest==3.0.4
9
9
  pyramid==2.0.2
10
10
  python-rapidjson==1.20
11
- SQLAlchemy==2.0.38
11
+ SQLAlchemy==2.0.40
@@ -245,7 +245,7 @@ keys = root, kinto
245
245
  keys = console
246
246
 
247
247
  [formatters]
248
- keys = color
248
+ keys = color, json
249
249
 
250
250
  [logger_root]
251
251
  level = INFO
@@ -258,10 +258,13 @@ qualname = kinto
258
258
  propagate = 0
259
259
 
260
260
  [handler_console]
261
- class = StreamHandler
261
+ class = kinto.core.StreamHandlerWithRequestID
262
262
  args = (sys.stderr,)
263
263
  level = NOTSET
264
264
  formatter = color
265
265
 
266
266
  [formatter_color]
267
267
  class = logging_color_formatter.ColorFormatter
268
+
269
+ [formatter_json]
270
+ class = kinto.core.JsonLogFormatter
@@ -151,6 +151,20 @@ class JsonLogFormatter(dockerflow_logging.JsonLogFormatter):
151
151
  self.logger_name = logger_name
152
152
 
153
153
 
154
+ class StreamHandlerWithRequestID(logging.StreamHandler):
155
+ """
156
+ A custom StreamHandler that adds the Dockerflow's `RequestIdLogFilter`.
157
+
158
+ Defining a custom handler seems to be the only way to bypass the fact that
159
+ ``logging.config.fileConfig()`` does not load filters from ``.ini`` files.
160
+ """
161
+
162
+ def __init__(self, *args, **kwargs):
163
+ super().__init__(*args, **kwargs)
164
+ filter_ = dockerflow_logging.RequestIdLogFilter()
165
+ self.addFilter(filter_)
166
+
167
+
154
168
  def get_user_info(request):
155
169
  # Default user info (shown in hello view for example).
156
170
  user_info = {"id": request.prefixed_userid, "principals": request.prefixed_principals}
@@ -4,9 +4,9 @@ import re
4
4
  import urllib.parse
5
5
  import warnings
6
6
  from datetime import datetime
7
- from secrets import token_hex
8
7
 
9
8
  from dateutil import parser as dateparser
9
+ from dockerflow.logging import get_or_generate_request_id, request_id_context
10
10
  from pyramid.events import ApplicationCreated, NewRequest, NewResponse
11
11
  from pyramid.exceptions import ConfigurationError
12
12
  from pyramid.httpexceptions import (
@@ -374,12 +374,15 @@ def setup_logging(config):
374
374
  message="Invalid URL path.",
375
375
  )
376
376
 
377
+ rid = get_or_generate_request_id(headers=request.headers)
378
+ request_id_context.set(rid)
379
+
377
380
  request.log_context(
378
381
  agent=request.headers.get("User-Agent"),
379
382
  path=request_path,
380
383
  method=request.method,
381
384
  lang=request.headers.get("Accept-Language"),
382
- rid=request.headers.get("X-Request-Id", token_hex(16)),
385
+ rid=rid,
383
386
  errno=0,
384
387
  )
385
388
  qs = dict(errors.request_GET(request))
@@ -87,6 +87,21 @@ class StorageBase:
87
87
  """
88
88
  raise NotImplementedError
89
89
 
90
+ def all_resources_timestamps(self, resource_name):
91
+ """Get the highest timestamp of every objects in this `resource_name` for
92
+ each `parent_id`.
93
+
94
+ .. note::
95
+
96
+ This should take deleted objects into account.
97
+
98
+ :param str resource_name: the resource name.
99
+
100
+ :returns: the latest timestamp of the resource by `parent_id`.
101
+ :rtype: dict[str, int]
102
+ """
103
+ raise NotImplementedError
104
+
90
105
  def create(
91
106
  self,
92
107
  resource_name,
@@ -153,6 +153,10 @@ class Storage(MemoryBasedStorage):
153
153
  raise exceptions.ReadonlyError(message=error_msg)
154
154
  return self.bump_and_store_timestamp(resource_name, parent_id)
155
155
 
156
+ @synchronized
157
+ def all_resources_timestamps(self, resource_name):
158
+ return {k: v[resource_name] for k, v in self._timestamps.items() if resource_name in v}
159
+
156
160
  def bump_and_store_timestamp(
157
161
  self, resource_name, parent_id, obj=None, modified_field=None, last_modified=None
158
162
  ):
@@ -284,13 +288,26 @@ class Storage(MemoryBasedStorage):
284
288
  modified_field=DEFAULT_MODIFIED_FIELD,
285
289
  ):
286
290
  parent_id_match = re.compile(parent_id.replace("*", ".*"))
287
- by_parent_id = {
291
+
292
+ timestamps_by_parent_id = {
288
293
  pid: resources
289
- for pid, resources in self._cemetery.items()
294
+ for pid, resources in self._timestamps.items()
290
295
  if parent_id_match.match(pid)
291
296
  }
297
+ if resource_name is not None:
298
+ for pid, resources in timestamps_by_parent_id.items():
299
+ del self._timestamps[pid][resource_name]
300
+ else:
301
+ for pid, resources in timestamps_by_parent_id.items():
302
+ del self._timestamps[pid]
303
+
292
304
  num_deleted = 0
293
- for pid, resources in by_parent_id.items():
305
+ tombstones_by_parent_id = {
306
+ pid: resources
307
+ for pid, resources in self._cemetery.items()
308
+ if parent_id_match.match(pid)
309
+ }
310
+ for pid, resources in tombstones_by_parent_id.items():
294
311
  if resource_name is not None:
295
312
  resources = {resource_name: resources[resource_name]}
296
313
  for resource, resource_objects in resources.items():
@@ -79,7 +79,7 @@ class Storage(StorageBase, MigratorMixin):
79
79
 
80
80
  # MigratorMixin attributes.
81
81
  name = "storage"
82
- schema_version = 22
82
+ schema_version = 23
83
83
  schema_file = os.path.join(HERE, "schema.sql")
84
84
  migrations_directory = os.path.join(HERE, "migrations")
85
85
 
@@ -247,6 +247,36 @@ class Storage(StorageBase, MigratorMixin):
247
247
 
248
248
  return obj.last_epoch
249
249
 
250
+ def all_resources_timestamps(self, resource_name):
251
+ query = """
252
+ WITH existing_timestamps AS (
253
+ -- Timestamp of latest object by parent_id.
254
+ (
255
+ SELECT parent_id, MAX(last_modified) AS last_modified
256
+ FROM objects
257
+ WHERE resource_name = :resource_name
258
+ GROUP BY parent_id
259
+ )
260
+ -- Timestamp of resources without sub-objects.
261
+ UNION
262
+ (
263
+ SELECT parent_id, last_modified
264
+ FROM timestamps
265
+ WHERE resource_name = :resource_name
266
+ )
267
+ )
268
+ SELECT parent_id, MAX(as_epoch(last_modified)) AS last_modified
269
+ FROM existing_timestamps
270
+ GROUP BY parent_id
271
+ ORDER BY last_modified DESC
272
+ """
273
+ with self.client.connect(readonly=True) as conn:
274
+ result = conn.execute(sa.text(query), dict(resource_name=resource_name))
275
+ rows = result.fetchmany(self._max_fetch_size + 1)
276
+
277
+ results = {r[0]: r[1] for r in rows}
278
+ return results
279
+
250
280
  @deprecate_kwargs({"collection_id": "resource_name", "record": "obj"})
251
281
  def create(
252
282
  self,
@@ -0,0 +1,5 @@
1
+ CREATE INDEX IF NOT EXISTS idx_objects_resource_name_parent_id_deleted
2
+ ON objects(resource_name, parent_id, deleted);
3
+
4
+ -- Bump storage schema version.
5
+ INSERT INTO metadata (name, value) VALUES ('storage_schema_version', '23');
@@ -47,7 +47,8 @@ CREATE UNIQUE INDEX IF NOT EXISTS idx_objects_parent_id_resource_name_last_modif
47
47
  ON objects(parent_id, resource_name, last_modified DESC);
48
48
  CREATE INDEX IF NOT EXISTS idx_objects_last_modified_epoch
49
49
  ON objects(as_epoch(last_modified));
50
-
50
+ CREATE INDEX IF NOT EXISTS idx_objects_resource_name_parent_id_deleted
51
+ ON objects(resource_name, parent_id, deleted);
51
52
 
52
53
  CREATE TABLE IF NOT EXISTS timestamps (
53
54
  parent_id TEXT NOT NULL COLLATE "C",
@@ -131,4 +132,4 @@ INSERT INTO metadata (name, value) VALUES ('created_at', NOW()::TEXT);
131
132
 
132
133
  -- Set storage schema version.
133
134
  -- Should match ``kinto.core.storage.postgresql.PostgreSQL.schema_version``
134
- INSERT INTO metadata (name, value) VALUES ('storage_schema_version', '22');
135
+ INSERT INTO metadata (name, value) VALUES ('storage_schema_version', '23');
@@ -783,6 +783,39 @@ class TimestampsTest:
783
783
  after = self.storage.resource_timestamp(**self.storage_kw)
784
784
  self.assertTrue(before < after)
785
785
 
786
+ def test_all_timestamps_by_parent_id(self):
787
+ self.storage.create(obj={"id": "main"}, resource_name="bucket", parent_id="")
788
+ self.storage.create(obj={"id": "cid1"}, resource_name="collection", parent_id="/main")
789
+ self.storage.create(obj={"id": "cid2"}, resource_name="collection", parent_id="/main")
790
+ self.storage.create(obj={}, resource_name="record", parent_id="/main/cid2")
791
+ self.storage.create(obj={}, resource_name="record", parent_id="/main/cid2")
792
+
793
+ self.assertEqual(
794
+ {
795
+ "": self.storage.resource_timestamp(resource_name="bucket", parent_id=""),
796
+ },
797
+ self.storage.all_resources_timestamps(resource_name="bucket"),
798
+ )
799
+ self.assertEqual(
800
+ {
801
+ "/main": self.storage.resource_timestamp(
802
+ resource_name="collection", parent_id="/main"
803
+ ),
804
+ },
805
+ self.storage.all_resources_timestamps(resource_name="collection"),
806
+ )
807
+ self.assertEqual(
808
+ {
809
+ "/main/cid1": self.storage.resource_timestamp(
810
+ resource_name="record", parent_id="/main/cid1"
811
+ ),
812
+ "/main/cid2": self.storage.resource_timestamp(
813
+ resource_name="record", parent_id="/main/cid2"
814
+ ),
815
+ },
816
+ self.storage.all_resources_timestamps(resource_name="record"),
817
+ )
818
+
786
819
  @skip_if_ci
787
820
  def test_timestamps_are_unique(self): # pragma: no cover
788
821
  obtained = []
@@ -1263,6 +1296,9 @@ class DeletedObjectsTest:
1263
1296
  self.create_object(parent_id="/abc/a", resource_name="c")
1264
1297
  self.create_object(parent_id="/efg", resource_name="c")
1265
1298
 
1299
+ all_timestamps = self.storage.all_resources_timestamps(resource_name="c")
1300
+ self.assertEqual(set(all_timestamps.keys()), {"/abc/a", "/efg"})
1301
+
1266
1302
  before1 = self.storage.resource_timestamp(parent_id="/abc/a", resource_name="c")
1267
1303
  # Different parent_id with object.
1268
1304
  before2 = self.storage.resource_timestamp(parent_id="/efg", resource_name="c")
@@ -1272,11 +1308,15 @@ class DeletedObjectsTest:
1272
1308
  self.storage.delete_all(parent_id="/abc/*", resource_name=None, with_deleted=False)
1273
1309
  self.storage.purge_deleted(parent_id="/abc/*", resource_name=None)
1274
1310
 
1311
+ all_timestamps = self.storage.all_resources_timestamps(resource_name="c")
1312
+ self.assertEqual(set(all_timestamps.keys()), {"/efg", "/ijk"})
1313
+
1314
+ time.sleep(0.002) # make sure we don't recreate timestamps at same msec.
1275
1315
  after1 = self.storage.resource_timestamp(parent_id="/abc/a", resource_name="c")
1276
1316
  after2 = self.storage.resource_timestamp(parent_id="/efg", resource_name="c")
1277
1317
  after3 = self.storage.resource_timestamp(parent_id="/ijk", resource_name="c")
1278
1318
 
1279
- self.assertNotEqual(before1, after1)
1319
+ self.assertNotEqual(before1, after1) # timestamp was removed, it will differ.
1280
1320
  self.assertEqual(before2, after2)
1281
1321
  self.assertEqual(before3, after3)
1282
1322
 
@@ -0,0 +1 @@
1
+ 3.7.1
@@ -0,0 +1 @@
1
+ 3.7.1