kinto 18.1.0__py3-none-any.whl → 20.4.0__py3-none-any.whl

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 (91) hide show
  1. kinto/__init__.py +1 -0
  2. kinto/__main__.py +1 -19
  3. kinto/config/kinto.tpl +5 -15
  4. kinto/contribute.json +27 -0
  5. kinto/core/__init__.py +21 -8
  6. kinto/core/cornice/__init__.py +93 -0
  7. kinto/core/cornice/cors.py +144 -0
  8. kinto/core/cornice/errors.py +40 -0
  9. kinto/core/cornice/pyramidhook.py +373 -0
  10. kinto/core/cornice/renderer.py +89 -0
  11. kinto/core/cornice/resource.py +205 -0
  12. kinto/core/cornice/service.py +641 -0
  13. kinto/core/cornice/util.py +138 -0
  14. kinto/core/cornice/validators/__init__.py +94 -0
  15. kinto/core/cornice/validators/_colander.py +142 -0
  16. kinto/core/cornice/validators/_marshmallow.py +182 -0
  17. kinto/core/cornice_swagger/__init__.py +92 -0
  18. kinto/core/cornice_swagger/converters/__init__.py +21 -0
  19. kinto/core/cornice_swagger/converters/exceptions.py +6 -0
  20. kinto/core/cornice_swagger/converters/parameters.py +90 -0
  21. kinto/core/cornice_swagger/converters/schema.py +249 -0
  22. kinto/core/cornice_swagger/swagger.py +725 -0
  23. kinto/core/cornice_swagger/templates/index.html +73 -0
  24. kinto/core/cornice_swagger/templates/index_script_template.html +21 -0
  25. kinto/core/cornice_swagger/util.py +42 -0
  26. kinto/core/cornice_swagger/views.py +78 -0
  27. kinto/core/errors.py +6 -4
  28. kinto/core/initialization.py +129 -59
  29. kinto/core/metrics.py +93 -0
  30. kinto/core/openapi.py +2 -3
  31. kinto/core/permission/memory.py +3 -2
  32. kinto/core/permission/postgresql/__init__.py +9 -9
  33. kinto/core/permission/testing.py +6 -0
  34. kinto/core/resource/__init__.py +9 -4
  35. kinto/core/resource/schema.py +1 -2
  36. kinto/core/resource/viewset.py +1 -1
  37. kinto/core/statsd.py +1 -63
  38. kinto/core/storage/__init__.py +15 -0
  39. kinto/core/storage/memory.py +20 -3
  40. kinto/core/storage/postgresql/__init__.py +31 -1
  41. kinto/core/storage/postgresql/client.py +2 -2
  42. kinto/core/storage/postgresql/migrations/migration_022_023.sql +5 -0
  43. kinto/core/storage/postgresql/pool.py +1 -1
  44. kinto/core/storage/postgresql/schema.sql +3 -2
  45. kinto/core/storage/testing.py +41 -1
  46. kinto/core/testing.py +6 -2
  47. kinto/core/utils.py +14 -4
  48. kinto/core/views/batch.py +1 -1
  49. kinto/core/views/errors.py +4 -3
  50. kinto/core/views/openapi.py +1 -1
  51. kinto/plugins/accounts/__init__.py +3 -21
  52. kinto/plugins/accounts/authentication.py +8 -54
  53. kinto/plugins/accounts/utils.py +0 -133
  54. kinto/plugins/accounts/{views/__init__.py → views.py} +7 -62
  55. kinto/plugins/admin/VERSION +1 -1
  56. kinto/plugins/admin/build/VERSION +1 -0
  57. kinto/plugins/admin/build/assets/asn1-EdZsLKOL.js +1 -0
  58. kinto/plugins/admin/build/assets/clojure-BMjYHr_A.js +1 -0
  59. kinto/plugins/admin/build/assets/css-BnMrqG3P.js +1 -0
  60. kinto/plugins/admin/build/assets/index-Cs7JVwIg.css +6 -0
  61. kinto/plugins/admin/build/assets/index-CylsivYB.js +165 -0
  62. kinto/plugins/admin/build/assets/javascript-qCveANmP.js +1 -0
  63. kinto/plugins/admin/build/assets/logo-VBRiKSPX.png +0 -0
  64. kinto/plugins/admin/build/assets/mllike-CXdrOF99.js +1 -0
  65. kinto/plugins/admin/build/assets/python-BuPzkPfP.js +1 -0
  66. kinto/plugins/admin/build/assets/rpm-CTu-6PCP.js +1 -0
  67. kinto/plugins/admin/build/assets/sql-D0XecflT.js +1 -0
  68. kinto/plugins/admin/build/assets/ttcn-cfg-B9xdYoR4.js +1 -0
  69. kinto/plugins/admin/build/index.html +18 -0
  70. kinto/plugins/default_bucket/__init__.py +1 -2
  71. kinto/plugins/flush.py +2 -2
  72. kinto/plugins/history/__init__.py +15 -6
  73. kinto/plugins/history/listener.py +68 -5
  74. kinto/plugins/openid/views.py +1 -1
  75. kinto/plugins/prometheus.py +203 -0
  76. kinto/plugins/statsd.py +78 -0
  77. kinto/views/contribute.py +14 -13
  78. {kinto-18.1.0.dist-info → kinto-20.4.0.dist-info}/METADATA +31 -32
  79. kinto-20.4.0.dist-info/RECORD +149 -0
  80. {kinto-18.1.0.dist-info → kinto-20.4.0.dist-info}/WHEEL +1 -1
  81. kinto/plugins/accounts/mails.py +0 -96
  82. kinto/plugins/accounts/views/validation.py +0 -136
  83. kinto/plugins/quotas/__init__.py +0 -22
  84. kinto/plugins/quotas/listener.py +0 -226
  85. kinto/plugins/quotas/scripts.py +0 -80
  86. kinto/plugins/quotas/utils.py +0 -7
  87. kinto/scripts.py +0 -41
  88. kinto-18.1.0.dist-info/RECORD +0 -116
  89. {kinto-18.1.0.dist-info → kinto-20.4.0.dist-info}/entry_points.txt +0 -0
  90. {kinto-18.1.0.dist-info → kinto-20.4.0.dist-info/licenses}/LICENSE +0 -0
  91. {kinto-18.1.0.dist-info → kinto-20.4.0.dist-info}/top_level.txt +0 -0
@@ -1,226 +0,0 @@
1
- import copy
2
-
3
- from pyramid.httpexceptions import HTTPInsufficientStorage
4
-
5
- from kinto.core.errors import ERRORS, http_error
6
- from kinto.core.storage.exceptions import ObjectNotFoundError
7
- from kinto.core.utils import instance_uri
8
-
9
- from .utils import record_size
10
-
11
-
12
- QUOTA_RESOURCE_NAME = "quota"
13
- BUCKET_QUOTA_OBJECT_ID = "bucket_info"
14
- COLLECTION_QUOTA_OBJECT_ID = "collection_info"
15
-
16
-
17
- def raise_insufficient_storage(message):
18
- raise http_error(HTTPInsufficientStorage(), errno=ERRORS.FORBIDDEN.value, message=message)
19
-
20
-
21
- def get_bucket_settings(settings, bucket_id, name):
22
- return settings.get(
23
- # Bucket specific
24
- f"quotas.bucket_{bucket_id}_{name}",
25
- # Global to all buckets
26
- settings.get(f"quotas.bucket_{name}", None),
27
- )
28
-
29
-
30
- def get_collection_settings(settings, bucket_id, collection_id, name):
31
- return settings.get(
32
- # Specific for a given bucket collection
33
- f"quotas.collection_{bucket_id}_{collection_id}_{name}",
34
- # Specific to given bucket collections
35
- settings.get(
36
- f"quotas.collection_{bucket_id}_{name}",
37
- # Global to all buckets collections
38
- settings.get(f"quotas.collection_{name}", None),
39
- ),
40
- )
41
-
42
-
43
- def on_resource_changed(event):
44
- """
45
- Everytime an object is created/changed/deleted, we update the
46
- bucket counters.
47
-
48
- If a new object exceeds the quotas, we reject the request.
49
- """
50
- payload = event.payload
51
- action = payload["action"]
52
- resource_name = payload["resource_name"]
53
-
54
- if action == "delete" and resource_name == "bucket":
55
- # Deleting a bucket already deletes everything underneath (including
56
- # quotas info). See kinto/views/bucket.
57
- return
58
-
59
- settings = event.request.registry.settings
60
-
61
- event_uri = payload["uri"]
62
- bucket_id = payload["bucket_id"]
63
- bucket_uri = instance_uri(event.request, "bucket", id=bucket_id)
64
- collection_id = None
65
- collection_uri = None
66
- if "collection_id" in payload:
67
- collection_id = payload["collection_id"]
68
- collection_uri = instance_uri(
69
- event.request, "collection", bucket_id=bucket_id, id=collection_id
70
- )
71
-
72
- bucket_max_bytes = get_bucket_settings(settings, bucket_id, "max_bytes")
73
- bucket_max_items = get_bucket_settings(settings, bucket_id, "max_items")
74
- bucket_max_bytes_per_item = get_bucket_settings(settings, bucket_id, "max_bytes_per_item")
75
- collection_max_bytes = get_collection_settings(settings, bucket_id, collection_id, "max_bytes")
76
- collection_max_items = get_collection_settings(settings, bucket_id, collection_id, "max_items")
77
- collection_max_bytes_per_item = get_collection_settings(
78
- settings, bucket_id, collection_id, "max_bytes_per_item"
79
- )
80
-
81
- max_bytes_per_item = collection_max_bytes_per_item or bucket_max_bytes_per_item
82
-
83
- storage = event.request.registry.storage
84
-
85
- targets = []
86
- for impacted in event.impacted_objects:
87
- target = impacted["new" if action != "delete" else "old"]
88
- # On POST .../records, the URI does not contain the newly created
89
- # record id.
90
- obj_id = target["id"]
91
- parts = event_uri.split("/")
92
- if resource_name in parts[-1]:
93
- parts.append(obj_id)
94
- else:
95
- # Make sure the id is correct on grouped events.
96
- parts[-1] = obj_id
97
- uri = "/".join(parts)
98
-
99
- old = impacted.get("old", {})
100
- new = impacted.get("new", {})
101
-
102
- targets.append((uri, obj_id, old, new))
103
-
104
- try:
105
- bucket_info = copy.deepcopy(
106
- storage.get(
107
- parent_id=bucket_uri,
108
- resource_name=QUOTA_RESOURCE_NAME,
109
- object_id=BUCKET_QUOTA_OBJECT_ID,
110
- )
111
- )
112
- except ObjectNotFoundError:
113
- bucket_info = {"collection_count": 0, "record_count": 0, "storage_size": 0}
114
-
115
- collection_info = {"record_count": 0, "storage_size": 0}
116
- if collection_id:
117
- try:
118
- collection_info = copy.deepcopy(
119
- storage.get(
120
- parent_id=collection_uri,
121
- resource_name=QUOTA_RESOURCE_NAME,
122
- object_id=COLLECTION_QUOTA_OBJECT_ID,
123
- )
124
- )
125
- except ObjectNotFoundError:
126
- pass
127
-
128
- # Update the bucket quotas values for each impacted record.
129
- for uri, obj_id, old, new in targets:
130
- old_size = record_size(old)
131
- new_size = record_size(new)
132
-
133
- if max_bytes_per_item is not None and action != "delete":
134
- if new_size > max_bytes_per_item:
135
- message = f'Maximum bytes per object exceeded " "({new_size} > {max_bytes_per_item} Bytes.'
136
- raise_insufficient_storage(message)
137
-
138
- if action == "create":
139
- bucket_info["storage_size"] += new_size
140
- if resource_name == "collection":
141
- bucket_info["collection_count"] += 1
142
- collection_info["storage_size"] += new_size
143
- if resource_name == "record":
144
- bucket_info["record_count"] += 1
145
- collection_info["record_count"] += 1
146
- collection_info["storage_size"] += new_size
147
- elif action == "update":
148
- bucket_info["storage_size"] -= old_size
149
- bucket_info["storage_size"] += new_size
150
- if resource_name in ("collection", "record"):
151
- collection_info["storage_size"] -= old_size
152
- collection_info["storage_size"] += new_size
153
- else: # action == 'delete':
154
- bucket_info["storage_size"] -= old_size
155
- if resource_name == "collection":
156
- collection_uri = uri
157
- bucket_info["collection_count"] -= 1
158
- # When we delete the collection all the records in it
159
- # are deleted without notification.
160
- collection_records = storage.list_all(
161
- resource_name="record", parent_id=collection_uri
162
- )
163
- for r in collection_records:
164
- old_record_size = record_size(r)
165
- bucket_info["record_count"] -= 1
166
- bucket_info["storage_size"] -= old_record_size
167
- collection_info["record_count"] -= 1
168
- collection_info["storage_size"] -= old_record_size
169
- collection_info["storage_size"] -= old_size
170
-
171
- if resource_name == "record":
172
- bucket_info["record_count"] -= 1
173
- collection_info["record_count"] -= 1
174
- collection_info["storage_size"] -= old_size
175
-
176
- if bucket_max_bytes is not None:
177
- if bucket_info["storage_size"] > bucket_max_bytes:
178
- message = (
179
- "Bucket maximum total size exceeded "
180
- f"({bucket_info['storage_size']} > {bucket_max_bytes} Bytes). "
181
- )
182
- raise_insufficient_storage(message)
183
-
184
- if bucket_max_items is not None:
185
- if bucket_info["record_count"] > bucket_max_items:
186
- message = (
187
- "Bucket maximum number of objects exceeded "
188
- f"({bucket_info['record_count']} > {bucket_max_items} objects)."
189
- )
190
- raise_insufficient_storage(message)
191
-
192
- if collection_max_bytes is not None:
193
- if collection_info["storage_size"] > collection_max_bytes:
194
- message = (
195
- "Collection maximum size exceeded "
196
- f"({collection_info['storage_size']} > {collection_max_bytes} Bytes)."
197
- )
198
- raise_insufficient_storage(message)
199
-
200
- if collection_max_items is not None:
201
- if collection_info["record_count"] > collection_max_items:
202
- message = (
203
- "Collection maximum number of objects exceeded "
204
- f"({collection_info['record_count']} > {collection_max_items} objects)."
205
- )
206
- raise_insufficient_storage(message)
207
-
208
- storage.update(
209
- parent_id=bucket_uri,
210
- resource_name=QUOTA_RESOURCE_NAME,
211
- object_id=BUCKET_QUOTA_OBJECT_ID,
212
- obj=bucket_info,
213
- )
214
-
215
- if collection_id:
216
- if action == "delete" and resource_name == "collection":
217
- # Deleting a collection already deletes everything underneath
218
- # (including quotas info). See kinto/views/collection.
219
- return
220
- else:
221
- storage.update(
222
- parent_id=collection_uri,
223
- resource_name=QUOTA_RESOURCE_NAME,
224
- object_id=COLLECTION_QUOTA_OBJECT_ID,
225
- obj=collection_info,
226
- )
@@ -1,80 +0,0 @@
1
- """
2
- kinto.plugins.quotas.scripts: scripts to maintain quotas and fix them when they're broken
3
- """
4
-
5
- import logging
6
-
7
- from kinto.core.storage import Sort
8
- from kinto.core.storage.utils import paginated
9
-
10
- from .listener import BUCKET_QUOTA_OBJECT_ID, COLLECTION_QUOTA_OBJECT_ID
11
- from .utils import record_size
12
-
13
-
14
- logger = logging.getLogger(__name__)
15
-
16
- OLDEST_FIRST = Sort("last_modified", 1)
17
-
18
-
19
- def rebuild_quotas(storage, dry_run=False):
20
- for bucket in paginated(storage, resource_name="bucket", parent_id="", sorting=[OLDEST_FIRST]):
21
- bucket_id = bucket["id"]
22
- bucket_path = f"/buckets/{bucket['id']}"
23
- bucket_collection_count = 0
24
- bucket_record_count = 0
25
- bucket_storage_size = record_size(bucket)
26
-
27
- for collection in paginated(
28
- storage, resource_name="collection", parent_id=bucket_path, sorting=[OLDEST_FIRST]
29
- ):
30
- collection_info = rebuild_quotas_collection(storage, bucket_id, collection, dry_run)
31
- (collection_record_count, collection_storage_size) = collection_info
32
- bucket_collection_count += 1
33
- bucket_record_count += collection_record_count
34
- bucket_storage_size += collection_storage_size
35
-
36
- bucket_record = {
37
- "record_count": bucket_record_count,
38
- "storage_size": bucket_storage_size,
39
- "collection_count": bucket_collection_count,
40
- }
41
- if not dry_run:
42
- storage.update(
43
- resource_name="quota",
44
- parent_id=bucket_path,
45
- object_id=BUCKET_QUOTA_OBJECT_ID,
46
- obj=bucket_record,
47
- )
48
-
49
- logger.info(
50
- f"Bucket {bucket_id}. Final size: {bucket_collection_count} collections, {bucket_record_count} records, {bucket_storage_size} bytes."
51
- )
52
-
53
-
54
- def rebuild_quotas_collection(storage, bucket_id, collection, dry_run=False):
55
- """Helper method for rebuild_quotas that updates a single collection."""
56
- collection_id = collection["id"]
57
- collection_record_count = 0
58
- collection_storage_size = record_size(collection)
59
- collection_uri = f"/buckets/{bucket_id}/collections/{collection_id}"
60
- for record in paginated(
61
- storage, resource_name="record", parent_id=collection_uri, sorting=[OLDEST_FIRST]
62
- ):
63
- collection_record_count += 1
64
- collection_storage_size += record_size(record)
65
-
66
- logger.info(
67
- f"Bucket {bucket_id}, collection {collection_id}. Final size: {collection_record_count} records, {collection_storage_size} bytes."
68
- )
69
- new_quota_info = {
70
- "record_count": collection_record_count,
71
- "storage_size": collection_storage_size,
72
- }
73
- if not dry_run:
74
- storage.update(
75
- resource_name="quota",
76
- parent_id=collection_uri,
77
- object_id=COLLECTION_QUOTA_OBJECT_ID,
78
- obj=new_quota_info,
79
- )
80
- return (collection_record_count, collection_storage_size)
@@ -1,7 +0,0 @@
1
- import json
2
-
3
-
4
- def record_size(record):
5
- # We cannot use rapidjson here, since the `separator` option is not available.
6
- canonical_json = json.dumps(record, sort_keys=True, separators=(",", ":"))
7
- return len(canonical_json)
kinto/scripts.py DELETED
@@ -1,41 +0,0 @@
1
- import logging
2
-
3
- import transaction as current_transaction
4
- from pyramid.settings import asbool
5
-
6
- from kinto.plugins.quotas import scripts as quotas
7
-
8
-
9
- logger = logging.getLogger(__name__)
10
-
11
-
12
- def rebuild_quotas(env, dry_run=False):
13
- """Administrative command to rebuild quota usage information.
14
-
15
- This command recomputes the amount of space used by all
16
- collections and all buckets and updates the quota objects in the
17
- storage backend to their correct values. This can be useful when
18
- cleaning up after a bug like e.g.
19
- https://github.com/Kinto/kinto/issues/1226.
20
- """
21
- registry = env["registry"]
22
- settings = registry.settings
23
- readonly_mode = asbool(settings.get("readonly", False))
24
-
25
- # FIXME: readonly_mode is not meant to be a "maintenance mode" but
26
- # rather used with a database user that has read-only permissions.
27
- # If we ever introduce a maintenance mode, we should maybe enforce
28
- # it here.
29
- if readonly_mode:
30
- message = "Cannot rebuild quotas while in readonly mode."
31
- logger.error(message)
32
- return 41
33
-
34
- if "kinto.plugins.quotas" not in settings["includes"]:
35
- message = "Cannot rebuild quotas when quotas plugin is not installed."
36
- logger.error(message)
37
- return 42
38
-
39
- quotas.rebuild_quotas(registry.storage, dry_run=dry_run)
40
- current_transaction.commit()
41
- return 0
@@ -1,116 +0,0 @@
1
- kinto/__init__.py,sha256=k-5mQkyT74syTtI5ynX24Sl3ai7Y5XXFLvqOtvMMlNE,3210
2
- kinto/__main__.py,sha256=NwDbI5RpBU8u7v49kDLolzvbN4cXm3LY26EY6JZOEEU,7831
3
- kinto/authorization.py,sha256=i3ttdPTFGzE9CqUQmfC4rR_6dDZJu0jWJMLGl_jFzIE,4919
4
- kinto/events.py,sha256=NMPvKUdbi25aYHhu9svzQsrEZMa9nyO4mtuMZC5871Q,85
5
- kinto/schema_validation.py,sha256=mtAmnl5HwiUsjS2gU8MKH4lkZ1380A5wZht-w9s5X7M,5306
6
- kinto/scripts.py,sha256=oM8ggBofYVoVhxrbdfzwIO0AOwR6Z2NJ2RqH9op1_lg,1370
7
- kinto/config/__init__.py,sha256=av8W0utmjheueFqrjTYEDk_vbpm3XYdHcqv5lppNR4k,2131
8
- kinto/config/kinto.tpl,sha256=kdA2RuR8gEpZGJp6VkKqMShQ0CfHDM0gjUttSPeaT7s,8753
9
- kinto/core/__init__.py,sha256=OpIPeRMatnxWqFUOB_ho4Tar7zfFX-I6URf0T13JP7g,8125
10
- kinto/core/authentication.py,sha256=HLA0kREC3GMEsrIsHsQYjVNztYfAF01kb8-pLboByFs,1527
11
- kinto/core/authorization.py,sha256=GywY25KEzuSSAI709dFHDfdLnKxy3SLEYGwW5FkQ7Qc,13212
12
- kinto/core/decorators.py,sha256=3SAPWXlyPNUSICZ9mz04bcN-UdbnDuFOtU0bQHHzLis,2178
13
- kinto/core/errors.py,sha256=fxOLR4lImwHp26hhxxaqk6uW0U7v2Jb6f4sgAcRPRu8,8854
14
- kinto/core/events.py,sha256=SYpXgKMtVjiD9fwYJA2Omdom9yA3nBqi9btdvU1I_nc,10345
15
- kinto/core/initialization.py,sha256=0JBlj3DfgVzlaFAEXSYjLqfGhmH_eOIlP1MqtMcq8M8,23442
16
- kinto/core/openapi.py,sha256=bPHRCVmdZsJCsKm8BId02Q2Wz8etF1xL7Z9rU9JDx5k,3855
17
- kinto/core/schema.py,sha256=d5L5TQynRYJPkZ8Mu2X7F72xEh6SKDbrHK1CNTdOf2E,3646
18
- kinto/core/scripts.py,sha256=5HSq5QAuin7HuU6icNYkPisny-4JpcdBvjf8X4JImrE,978
19
- kinto/core/statsd.py,sha256=Z2TDo31gPqIwcyFC3Z_qZM8fPy9PSRmcwEMhAtiZMGM,1942
20
- kinto/core/testing.py,sha256=K77Lxfp6naMXGqiXlajglO-QA0SrZQ37RUgsi1jLb8k,5748
21
- kinto/core/utils.py,sha256=jfP6k63xHNAzbhNkDd9V8YlMzblTyh-ENScETfdW-k0,16772
22
- kinto/core/cache/__init__.py,sha256=NJT_39WFTuUd-OHuVqgoQTQUYv5zS9PIc3W_Kq9tabc,2726
23
- kinto/core/cache/memcached.py,sha256=WuYyq6-QykRNryLA_bKdeGAY_Hvwq0c1ejS_8G94cY4,2914
24
- kinto/core/cache/memory.py,sha256=603vuyV5nKxsmUlkVxZFZWKPAbxMSTQKqkpqK4ttFas,2748
25
- kinto/core/cache/testing.py,sha256=KVNz1tVYv_A33HF66SObM1WTgOx1UY47MuwPsaaQRag,6980
26
- kinto/core/cache/postgresql/__init__.py,sha256=04OetGaxI89XAHUhtrNtRyipsZTe0bn_ZjoUQms_3VA,6026
27
- kinto/core/cache/postgresql/schema.sql,sha256=a-6lbhqzlNMcig7DCGQ_ULP-Z5nzhNWrZWCpaHTiJPw,503
28
- kinto/core/listeners/__init__.py,sha256=mBBo0LxNOjL8h8IqRweG1sY_G142FAakhimzKcgQBDQ,203
29
- kinto/core/permission/__init__.py,sha256=RoI8UJYl3X8ZmuUfVGC8QH1g4EGNrRknUao97D3jKRE,7331
30
- kinto/core/permission/memory.py,sha256=GJWw70HAwDT29YZOt8eL7Q_q9LGI83SUAGJbxTCr7qA,6113
31
- kinto/core/permission/testing.py,sha256=EcfqwkbqJuW3Bzx0QEYNq-Rbgu4AqvLDx90s79LxhDY,22017
32
- kinto/core/permission/postgresql/__init__.py,sha256=546ut-LAdQ__eBhClAxj9Pc2oOkHfl2dBhJZSyIvDuI,18254
33
- kinto/core/permission/postgresql/schema.sql,sha256=BlKJNC-omDVF9REaWCTsfKgXupFrmCBX8ZvN4sqTWUU,1344
34
- kinto/core/permission/postgresql/migrations/migration_001_002.sql,sha256=ey5rDVQfStVStWpyTJn2fmQP5WSA34HhO99PapcgH1k,681
35
- kinto/core/resource/__init__.py,sha256=qUYhZ-rWRDU7if9VBL9yWF4xKTxVobP2JbVF9vZvsEc,50527
36
- kinto/core/resource/model.py,sha256=xjZ6shnhelXCdWvgw6yeOWXodxiKMm9iyDqLTk0i8Bs,15626
37
- kinto/core/resource/schema.py,sha256=z5ZhuPcNydByinaSNwTHe0xXCgJvwQcVFwFT0YNSjaQ,16141
38
- kinto/core/resource/viewset.py,sha256=3Uck_7Fp1lIDunDoAU6yDzswBr3ZDSPn16sIckRHdko,7602
39
- kinto/core/storage/__init__.py,sha256=EiGmwovOzB3j_d3pgQCgsVyoe0_Op9Ylgo2MfZW7Ugo,13258
40
- kinto/core/storage/exceptions.py,sha256=o10f7LohwyCHOTlR-dOdnB4us_MdCGOJUxZO8HZ3Akc,1304
41
- kinto/core/storage/generators.py,sha256=rxWN9hOfOsB-PLeryhPGO-aE670sivr3LFRIExImpxc,1829
42
- kinto/core/storage/memory.py,sha256=Mf_cre6QP_nZnKNc5DgwFSJAkx_ycTd8wvFFszqANKs,19222
43
- kinto/core/storage/testing.py,sha256=i7FGzELcmayYu-VFNC_9nBd8QbOGhg53qouFdyhX9yY,76527
44
- kinto/core/storage/utils.py,sha256=BHpohIKVOCtURjRbUT7O5AEhIKfSEFv-pfgRzq8Q5zs,1082
45
- kinto/core/storage/postgresql/__init__.py,sha256=gRtC0W3FVtXQNEF_K2qzzKUk-kbD18rnj6vya6tRg8A,39107
46
- kinto/core/storage/postgresql/client.py,sha256=EsfMzg2afKU3uqYPSF2t1MvmIviccI1HmkTOndbotYE,4276
47
- kinto/core/storage/postgresql/migrator.py,sha256=MQ_5aSrDi9-s2wlyyFyfhYP6HreCXjtlJzBI4b85u1I,3524
48
- kinto/core/storage/postgresql/pool.py,sha256=P0m8A55WhkxrrpygHpA0wOl4prkzpSiUnlG0GjIp4P8,2198
49
- kinto/core/storage/postgresql/schema.sql,sha256=4q0NpjaX2GoiuGNnIVpMVuox9vQHGhh64qE4Z4a2FdQ,4095
50
- kinto/core/storage/postgresql/migrations/migration_001_002.sql,sha256=GVJIs8MGmZEyp1i0KjsmGKv1pLlBRckn0EWX6Kl6uQE,428
51
- kinto/core/storage/postgresql/migrations/migration_002_003.sql,sha256=zlSZpG_2L-wd8KXh3szmbYtoGjAOOwy2gH7RFMUd61w,1203
52
- kinto/core/storage/postgresql/migrations/migration_003_004.sql,sha256=OZSbH6Yt1PA2zba8iQWIguaTsnn3v7bFF-rbg2_teXY,530
53
- kinto/core/storage/postgresql/migrations/migration_004_005.sql,sha256=3VzFzj5y7quywYN-j6OE8xwYvB84O33YeeTF7QYXFOA,603
54
- kinto/core/storage/postgresql/migrations/migration_005_006.sql,sha256=NE1fdI1grEqnXZOiO714vME-TQo2UKVuxeUvplEKCUg,354
55
- kinto/core/storage/postgresql/migrations/migration_006_007.sql,sha256=anpEkjSCJ6uXaDr_krei1ZY_1TIbxBW9iF5JsPDT4sw,2352
56
- kinto/core/storage/postgresql/migrations/migration_007_008.sql,sha256=7SQpJRjD-44tuBYbXL0mGg3ugUhh7tlRpQiv98JeY-k,2011
57
- kinto/core/storage/postgresql/migrations/migration_008_009.sql,sha256=UnMmGLf3mYNmfYMfStzWS4oeHWRTCEpqvMD9a60aHTg,1224
58
- kinto/core/storage/postgresql/migrations/migration_009_010.sql,sha256=Wzczz3J2sjPUfcG7iP2nEuASU9Qrx97IYHiCfrTvYeA,2843
59
- kinto/core/storage/postgresql/migrations/migration_010_011.sql,sha256=zQS3GMgZNJEmHtaW1uH8hVP5IVQ9lU9Gpk6tzfYb_cs,484
60
- kinto/core/storage/postgresql/migrations/migration_011_012.sql,sha256=YcpZcO68d4wPF3b5e-PWljV3F9LACe1o2uEKmDOnxHo,304
61
- kinto/core/storage/postgresql/migrations/migration_012_013.sql,sha256=MOnGjfQVIucs3A3eOBRZ0mdgS9NY-KZDdQ8Eu2FjPdI,2389
62
- kinto/core/storage/postgresql/migrations/migration_013_014.sql,sha256=cyDg2EpAwvbfaOXJbuxiJz_ofwl2pN6lix8Yrd3pbys,482
63
- kinto/core/storage/postgresql/migrations/migration_014_015.sql,sha256=U2LtXV-oo8aozeeUIm2D62ujPHj29KuQ0JSYbJ3t1Iw,2992
64
- kinto/core/storage/postgresql/migrations/migration_015_016.sql,sha256=gacFTc1zpmbkkbSCqpn12lySeMyYT-4_g4L6bSqHOFw,176
65
- kinto/core/storage/postgresql/migrations/migration_016_017.sql,sha256=B0QFDuvcp8hKXY5xjOVy58vl0OO9LLnZdJQxBuyrLus,2476
66
- kinto/core/storage/postgresql/migrations/migration_017_018.sql,sha256=n_BGQ-btSoTjmznHd0yypxoGcSJ7wWkORrLqlhUuVPI,993
67
- kinto/core/storage/postgresql/migrations/migration_018_019.sql,sha256=XK6ex2jwQQLXgxjhy5bXF4H2Zt9nV_K4dehmvePd30k,346
68
- kinto/core/storage/postgresql/migrations/migration_019_020.sql,sha256=yDQDdzU65cgctKIeo1YqMrFi7aU2VGdBhVUpVQAQOgM,306
69
- kinto/core/storage/postgresql/migrations/migration_020_021.sql,sha256=cEgfGNDLH3RyLswxy9YZazZtOvidxNsi57z7SGR8VsQ,2369
70
- kinto/core/storage/postgresql/migrations/migration_021_022.sql,sha256=MUIAfgbBDQLy8JfklEs6ekK93nr1buVRtmBAHaaMXug,1993
71
- kinto/core/views/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
72
- kinto/core/views/batch.py,sha256=t6mKtxlJq6URXyIdGEXQQ2hpjsjaWLnUWUsP5O6QaLs,5646
73
- kinto/core/views/errors.py,sha256=6qmrmyaAbwSAaZUZvkKzGAepU5Sbec7vhiZSZkPDMAo,5973
74
- kinto/core/views/heartbeat.py,sha256=qidZ7fTvuPoJMo7miDnclAm_WsbgqubzsARrv9aCo5U,3336
75
- kinto/core/views/hello.py,sha256=tTjJ2PHKPnmLL41cwF6e0AzPhm4WmojIc0VWHcZNOgI,1961
76
- kinto/core/views/openapi.py,sha256=YZ7akBoMqmiu0b4AOxlupHU01_kQEHtmzPxJq_iS79Y,947
77
- kinto/core/views/version.py,sha256=-m5G_o0oHTpCgrtfFrHFve6Zqw_gs_szT0Bd8jnNmD4,1419
78
- kinto/plugins/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
79
- kinto/plugins/flush.py,sha256=HnKJ6-oDo-NMSjdZskqZ09aMnFM-LJHW9vIw4VIyvcI,812
80
- kinto/plugins/accounts/__init__.py,sha256=LUyPfIWIn-HtpmyKO8wAxY9oFsgeYgbMHFmNOcns7rY,4365
81
- kinto/plugins/accounts/authentication.py,sha256=h7l_KezC8os4sKN1bz3RKEwXwYTYAs21DRzzU9na_U0,3742
82
- kinto/plugins/accounts/mails.py,sha256=vfb80INjDIJqC1JkPhcwGXlVWjvXhazxA_pnckmOOdo,3481
83
- kinto/plugins/accounts/scripts.py,sha256=_LNkSpFprOMGHFKkRmmOqK31uoQW28yttPQztmfUt5Q,2001
84
- kinto/plugins/accounts/utils.py,sha256=_IDsQEthJLFjdJ1be-KTxkbiZV-1Xrsfv4nOvdvF05Y,5376
85
- kinto/plugins/accounts/views/__init__.py,sha256=QpwvsTYci71oRfww8PB2g_6ROrpdvx5s1iA1lN2hCjA,7443
86
- kinto/plugins/accounts/views/validation.py,sha256=2KpK0ghDK5WJfUh9pc1t1ptWFf7_bnKDau5tG0wjQwU,4631
87
- kinto/plugins/admin/README.md,sha256=3a9inoO2IHH5aST3xZp_km3ddupHZqadWrQjOQifBRk,105
88
- kinto/plugins/admin/VERSION,sha256=22W3tlP3wzosH5_TgfX74ImjifBjVngxeFuvSy4Ul-k,6
89
- kinto/plugins/admin/__init__.py,sha256=057R3q_S4CFiUuqwMIFkyu4prMBnUVc1eo8OUAPeJBs,1327
90
- kinto/plugins/admin/views.py,sha256=NHQncNB-32ytP03o-ZqisbYEoK7L2QcaK7RBuh0akwg,1338
91
- kinto/plugins/admin/public/help.html,sha256=1hol7z5Sv0Xn3mYyEfPQWFOsrR24htlKhmnGA3rH8fs,958
92
- kinto/plugins/default_bucket/__init__.py,sha256=Q0frXXJPzFqoPCOjK5OpJZhaz5nCAeR2KwKAP7ltW_U,7287
93
- kinto/plugins/history/__init__.py,sha256=xlti7gR4NojR8hIb24is0iVf0QJD645PPkVEQpsQl2w,1096
94
- kinto/plugins/history/listener.py,sha256=Tq5ZHpIOIzQs9yPXA1exEftPoYCuFQJvgxbaIb6XBrM,5033
95
- kinto/plugins/history/views.py,sha256=NoBP-S7epeH5TLZZbIqfBmwMA2KaWmxP7lqPAS11BTU,2293
96
- kinto/plugins/openid/__init__.py,sha256=1Iv5SCa6vwEvoJkmGd45-TYm_mxz2okFj6u2VTNuVrk,4863
97
- kinto/plugins/openid/utils.py,sha256=n3KGS-ogXR2sg6j4QtdPe_DtEsqD7AGVT2K7vhl8yE8,273
98
- kinto/plugins/openid/views.py,sha256=RVUlS_Ov26NM8SFlrIlpm7ev9OuaMlJTtPA6pUi6ngk,6508
99
- kinto/plugins/quotas/__init__.py,sha256=g_ar8oHXnD3pIifgQoHkcTMNepDvCZ65SfpGwXIyTlU,697
100
- kinto/plugins/quotas/listener.py,sha256=WKKaCNRJw8XoIfnJb3S0ogYhzAo28RcfLE-MzP6Cs2U,8564
101
- kinto/plugins/quotas/scripts.py,sha256=a3KuzUwtCp_yu78yqr3XdbaHvZyBcUy6o_keNtsuU-M,2941
102
- kinto/plugins/quotas/utils.py,sha256=BE5bBPrG0BV9Qbcv6-r8WsV7KC6aIJlFeOR4O5tS248,232
103
- kinto/views/__init__.py,sha256=mItMqadROvEieXtxm0AoDReH3PwxOlM4rzECPCQfK_s,1187
104
- kinto/views/admin.py,sha256=m4JKApzUUQNmmbHOfoc2n0CK01OrNiho21nYW_f5zlo,7439
105
- kinto/views/buckets.py,sha256=3dc5cURZEP4vPKfk3f9W3BDbloG3QZ2lefhIoo-BiSQ,1868
106
- kinto/views/collections.py,sha256=KrqJuje88er1VS2mtspMnXU6eYeZQTqUw0zB1ova9Bo,2206
107
- kinto/views/contribute.py,sha256=NEDr2g1HhVwcMBg0qHEZDmWVJ1V31WsM8cRs0Vm6hfc,1180
108
- kinto/views/groups.py,sha256=jOq5fX0-4lwZE8k1q5HME2tU7x9052rtBPF7YqcJ-Qg,3181
109
- kinto/views/permissions.py,sha256=F0_eKx201WyLonXJ5vLdGKa9RcFKjvAihrEEhU1JuLw,9069
110
- kinto/views/records.py,sha256=lYfACW2L8qcQoyYBD5IX-fTPjFWmGp7GjHq_U4InlyE,5037
111
- kinto-18.1.0.dist-info/LICENSE,sha256=oNEIMTuTJzppR5ZEyi86yvvtSagveMYXTYFn56zF0Uk,561
112
- kinto-18.1.0.dist-info/METADATA,sha256=AFR_VIGbFeNWt-Oqblldp3yp7sjFUVMmERIR9vMlZiA,8812
113
- kinto-18.1.0.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
114
- kinto-18.1.0.dist-info/entry_points.txt,sha256=3KlqBWPKY81mrCe_oX0I5s1cRO7Q53nCLbnVr5P9LH4,85
115
- kinto-18.1.0.dist-info/top_level.txt,sha256=EG_YmbZL6FAug9VwopG7JtF9SvH_r0DEnFp-3twPPys,6
116
- kinto-18.1.0.dist-info/RECORD,,