udata 9.1.2.dev30355__py2.py3-none-any.whl → 9.1.2.dev30382__py2.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 udata might be problematic. Click here for more details.

Files changed (425) hide show
  1. tasks/__init__.py +109 -107
  2. tasks/helpers.py +18 -18
  3. udata/__init__.py +4 -4
  4. udata/admin/views.py +5 -5
  5. udata/api/__init__.py +135 -124
  6. udata/api/commands.py +45 -37
  7. udata/api/errors.py +5 -4
  8. udata/api/fields.py +23 -21
  9. udata/api/oauth2.py +55 -74
  10. udata/api/parsers.py +15 -15
  11. udata/api/signals.py +1 -1
  12. udata/api_fields.py +137 -89
  13. udata/app.py +56 -54
  14. udata/assets.py +5 -5
  15. udata/auth/__init__.py +37 -26
  16. udata/auth/forms.py +23 -15
  17. udata/auth/helpers.py +1 -1
  18. udata/auth/mails.py +3 -3
  19. udata/auth/password_validation.py +19 -15
  20. udata/auth/views.py +94 -68
  21. udata/commands/__init__.py +71 -69
  22. udata/commands/cache.py +7 -7
  23. udata/commands/db.py +201 -140
  24. udata/commands/dcat.py +36 -30
  25. udata/commands/fixtures.py +100 -84
  26. udata/commands/images.py +21 -20
  27. udata/commands/info.py +17 -20
  28. udata/commands/init.py +10 -10
  29. udata/commands/purge.py +12 -13
  30. udata/commands/serve.py +41 -29
  31. udata/commands/static.py +16 -18
  32. udata/commands/test.py +20 -20
  33. udata/commands/tests/fixtures.py +26 -24
  34. udata/commands/worker.py +31 -33
  35. udata/core/__init__.py +12 -12
  36. udata/core/activity/__init__.py +0 -1
  37. udata/core/activity/api.py +59 -49
  38. udata/core/activity/models.py +28 -26
  39. udata/core/activity/signals.py +1 -1
  40. udata/core/activity/tasks.py +16 -10
  41. udata/core/badges/api.py +6 -6
  42. udata/core/badges/commands.py +14 -13
  43. udata/core/badges/fields.py +8 -5
  44. udata/core/badges/forms.py +7 -4
  45. udata/core/badges/models.py +16 -31
  46. udata/core/badges/permissions.py +1 -3
  47. udata/core/badges/signals.py +2 -2
  48. udata/core/badges/tasks.py +3 -2
  49. udata/core/badges/tests/test_commands.py +10 -10
  50. udata/core/badges/tests/test_model.py +24 -31
  51. udata/core/contact_point/api.py +19 -18
  52. udata/core/contact_point/api_fields.py +21 -14
  53. udata/core/contact_point/factories.py +2 -2
  54. udata/core/contact_point/forms.py +7 -6
  55. udata/core/contact_point/models.py +3 -5
  56. udata/core/dataservices/api.py +26 -21
  57. udata/core/dataservices/factories.py +13 -11
  58. udata/core/dataservices/models.py +35 -40
  59. udata/core/dataservices/permissions.py +4 -4
  60. udata/core/dataservices/rdf.py +40 -17
  61. udata/core/dataservices/tasks.py +4 -3
  62. udata/core/dataset/actions.py +10 -10
  63. udata/core/dataset/activities.py +21 -23
  64. udata/core/dataset/api.py +321 -298
  65. udata/core/dataset/api_fields.py +443 -271
  66. udata/core/dataset/apiv2.py +305 -229
  67. udata/core/dataset/commands.py +38 -36
  68. udata/core/dataset/constants.py +61 -54
  69. udata/core/dataset/csv.py +70 -74
  70. udata/core/dataset/events.py +39 -32
  71. udata/core/dataset/exceptions.py +8 -4
  72. udata/core/dataset/factories.py +57 -65
  73. udata/core/dataset/forms.py +87 -63
  74. udata/core/dataset/models.py +336 -280
  75. udata/core/dataset/permissions.py +9 -6
  76. udata/core/dataset/preview.py +15 -17
  77. udata/core/dataset/rdf.py +156 -122
  78. udata/core/dataset/search.py +92 -77
  79. udata/core/dataset/signals.py +1 -1
  80. udata/core/dataset/tasks.py +63 -54
  81. udata/core/discussions/actions.py +5 -5
  82. udata/core/discussions/api.py +124 -120
  83. udata/core/discussions/factories.py +2 -2
  84. udata/core/discussions/forms.py +9 -7
  85. udata/core/discussions/metrics.py +1 -3
  86. udata/core/discussions/models.py +25 -24
  87. udata/core/discussions/notifications.py +18 -14
  88. udata/core/discussions/permissions.py +3 -3
  89. udata/core/discussions/signals.py +4 -4
  90. udata/core/discussions/tasks.py +24 -28
  91. udata/core/followers/api.py +32 -33
  92. udata/core/followers/models.py +9 -9
  93. udata/core/followers/signals.py +3 -3
  94. udata/core/jobs/actions.py +7 -7
  95. udata/core/jobs/api.py +99 -92
  96. udata/core/jobs/commands.py +48 -49
  97. udata/core/jobs/forms.py +11 -11
  98. udata/core/jobs/models.py +6 -6
  99. udata/core/metrics/__init__.py +2 -2
  100. udata/core/metrics/commands.py +34 -30
  101. udata/core/metrics/models.py +2 -4
  102. udata/core/metrics/signals.py +1 -1
  103. udata/core/metrics/tasks.py +3 -3
  104. udata/core/organization/activities.py +12 -15
  105. udata/core/organization/api.py +167 -174
  106. udata/core/organization/api_fields.py +183 -124
  107. udata/core/organization/apiv2.py +32 -32
  108. udata/core/organization/commands.py +20 -22
  109. udata/core/organization/constants.py +11 -11
  110. udata/core/organization/csv.py +17 -15
  111. udata/core/organization/factories.py +8 -11
  112. udata/core/organization/forms.py +32 -26
  113. udata/core/organization/metrics.py +2 -1
  114. udata/core/organization/models.py +87 -67
  115. udata/core/organization/notifications.py +18 -14
  116. udata/core/organization/permissions.py +10 -11
  117. udata/core/organization/rdf.py +14 -14
  118. udata/core/organization/search.py +30 -28
  119. udata/core/organization/signals.py +7 -7
  120. udata/core/organization/tasks.py +42 -61
  121. udata/core/owned.py +38 -27
  122. udata/core/post/api.py +82 -81
  123. udata/core/post/constants.py +8 -5
  124. udata/core/post/factories.py +4 -4
  125. udata/core/post/forms.py +13 -14
  126. udata/core/post/models.py +20 -22
  127. udata/core/post/tests/test_api.py +30 -32
  128. udata/core/reports/api.py +8 -7
  129. udata/core/reports/constants.py +1 -3
  130. udata/core/reports/models.py +10 -10
  131. udata/core/reuse/activities.py +15 -19
  132. udata/core/reuse/api.py +123 -126
  133. udata/core/reuse/api_fields.py +120 -85
  134. udata/core/reuse/apiv2.py +11 -10
  135. udata/core/reuse/constants.py +23 -23
  136. udata/core/reuse/csv.py +18 -18
  137. udata/core/reuse/factories.py +5 -9
  138. udata/core/reuse/forms.py +24 -21
  139. udata/core/reuse/models.py +55 -51
  140. udata/core/reuse/permissions.py +2 -2
  141. udata/core/reuse/search.py +49 -46
  142. udata/core/reuse/signals.py +1 -1
  143. udata/core/reuse/tasks.py +4 -5
  144. udata/core/site/api.py +47 -50
  145. udata/core/site/factories.py +2 -2
  146. udata/core/site/forms.py +4 -5
  147. udata/core/site/models.py +94 -63
  148. udata/core/site/rdf.py +14 -14
  149. udata/core/spam/api.py +16 -9
  150. udata/core/spam/constants.py +4 -4
  151. udata/core/spam/fields.py +13 -7
  152. udata/core/spam/models.py +27 -20
  153. udata/core/spam/signals.py +1 -1
  154. udata/core/spam/tests/test_spam.py +6 -5
  155. udata/core/spatial/api.py +72 -80
  156. udata/core/spatial/api_fields.py +73 -58
  157. udata/core/spatial/commands.py +67 -64
  158. udata/core/spatial/constants.py +3 -3
  159. udata/core/spatial/factories.py +37 -54
  160. udata/core/spatial/forms.py +27 -26
  161. udata/core/spatial/geoids.py +17 -17
  162. udata/core/spatial/models.py +43 -47
  163. udata/core/spatial/tasks.py +2 -1
  164. udata/core/spatial/tests/test_api.py +115 -130
  165. udata/core/spatial/tests/test_fields.py +74 -77
  166. udata/core/spatial/tests/test_geoid.py +22 -22
  167. udata/core/spatial/tests/test_models.py +5 -7
  168. udata/core/spatial/translations.py +16 -16
  169. udata/core/storages/__init__.py +16 -18
  170. udata/core/storages/api.py +66 -64
  171. udata/core/storages/tasks.py +7 -7
  172. udata/core/storages/utils.py +15 -15
  173. udata/core/storages/views.py +5 -6
  174. udata/core/tags/api.py +17 -14
  175. udata/core/tags/csv.py +4 -4
  176. udata/core/tags/models.py +8 -5
  177. udata/core/tags/tasks.py +11 -13
  178. udata/core/tags/views.py +4 -4
  179. udata/core/topic/api.py +84 -73
  180. udata/core/topic/apiv2.py +157 -127
  181. udata/core/topic/factories.py +3 -4
  182. udata/core/topic/forms.py +12 -14
  183. udata/core/topic/models.py +14 -19
  184. udata/core/topic/parsers.py +26 -26
  185. udata/core/user/activities.py +30 -29
  186. udata/core/user/api.py +151 -152
  187. udata/core/user/api_fields.py +132 -100
  188. udata/core/user/apiv2.py +7 -7
  189. udata/core/user/commands.py +38 -38
  190. udata/core/user/factories.py +8 -9
  191. udata/core/user/forms.py +14 -11
  192. udata/core/user/metrics.py +2 -2
  193. udata/core/user/models.py +68 -69
  194. udata/core/user/permissions.py +4 -5
  195. udata/core/user/rdf.py +7 -8
  196. udata/core/user/tasks.py +2 -2
  197. udata/core/user/tests/test_user_model.py +24 -16
  198. udata/db/tasks.py +2 -1
  199. udata/entrypoints.py +35 -31
  200. udata/errors.py +2 -1
  201. udata/event/values.py +6 -6
  202. udata/factories.py +2 -2
  203. udata/features/identicon/api.py +5 -6
  204. udata/features/identicon/backends.py +48 -55
  205. udata/features/identicon/tests/test_backends.py +4 -5
  206. udata/features/notifications/__init__.py +0 -1
  207. udata/features/notifications/actions.py +9 -9
  208. udata/features/notifications/api.py +17 -13
  209. udata/features/territories/__init__.py +12 -10
  210. udata/features/territories/api.py +14 -15
  211. udata/features/territories/models.py +23 -28
  212. udata/features/transfer/actions.py +8 -11
  213. udata/features/transfer/api.py +84 -77
  214. udata/features/transfer/factories.py +2 -1
  215. udata/features/transfer/models.py +11 -12
  216. udata/features/transfer/notifications.py +19 -15
  217. udata/features/transfer/permissions.py +5 -5
  218. udata/forms/__init__.py +5 -2
  219. udata/forms/fields.py +164 -172
  220. udata/forms/validators.py +19 -22
  221. udata/forms/widgets.py +9 -13
  222. udata/frontend/__init__.py +31 -26
  223. udata/frontend/csv.py +68 -58
  224. udata/frontend/markdown.py +40 -44
  225. udata/harvest/actions.py +89 -77
  226. udata/harvest/api.py +294 -238
  227. udata/harvest/backends/__init__.py +4 -4
  228. udata/harvest/backends/base.py +128 -111
  229. udata/harvest/backends/dcat.py +80 -66
  230. udata/harvest/commands.py +56 -60
  231. udata/harvest/csv.py +8 -8
  232. udata/harvest/exceptions.py +6 -3
  233. udata/harvest/filters.py +24 -23
  234. udata/harvest/forms.py +27 -28
  235. udata/harvest/models.py +88 -80
  236. udata/harvest/notifications.py +15 -10
  237. udata/harvest/signals.py +13 -13
  238. udata/harvest/tasks.py +11 -10
  239. udata/harvest/tests/factories.py +23 -24
  240. udata/harvest/tests/test_actions.py +136 -166
  241. udata/harvest/tests/test_api.py +220 -214
  242. udata/harvest/tests/test_base_backend.py +117 -112
  243. udata/harvest/tests/test_dcat_backend.py +380 -308
  244. udata/harvest/tests/test_filters.py +33 -22
  245. udata/harvest/tests/test_models.py +11 -14
  246. udata/harvest/tests/test_notifications.py +6 -7
  247. udata/harvest/tests/test_tasks.py +7 -6
  248. udata/i18n.py +237 -78
  249. udata/linkchecker/backends.py +5 -11
  250. udata/linkchecker/checker.py +23 -22
  251. udata/linkchecker/commands.py +4 -6
  252. udata/linkchecker/models.py +6 -6
  253. udata/linkchecker/tasks.py +18 -20
  254. udata/mail.py +21 -21
  255. udata/migrations/2020-07-24-remove-s-from-scope-oauth.py +9 -8
  256. udata/migrations/2020-08-24-add-fs-filename.py +9 -8
  257. udata/migrations/2020-09-28-update-reuses-datasets-metrics.py +5 -4
  258. udata/migrations/2020-10-16-migrate-ods-resources.py +9 -10
  259. udata/migrations/2021-04-08-update-schema-with-new-structure.py +8 -7
  260. udata/migrations/2021-05-27-fix-default-schema-name.py +7 -6
  261. udata/migrations/2021-07-05-remove-unused-badges.py +17 -15
  262. udata/migrations/2021-07-07-update-schema-for-community-resources.py +7 -6
  263. udata/migrations/2021-08-17-follow-integrity.py +5 -4
  264. udata/migrations/2021-08-17-harvest-integrity.py +13 -12
  265. udata/migrations/2021-08-17-oauth2client-integrity.py +5 -4
  266. udata/migrations/2021-08-17-transfer-integrity.py +5 -4
  267. udata/migrations/2021-08-17-users-integrity.py +9 -8
  268. udata/migrations/2021-12-14-reuse-topics.py +7 -6
  269. udata/migrations/2022-04-21-improve-extension-detection.py +8 -7
  270. udata/migrations/2022-09-22-clean-inactive-harvest-datasets.py +16 -14
  271. udata/migrations/2022-10-10-add-fs_uniquifier-to-user-model.py +6 -6
  272. udata/migrations/2022-10-10-migrate-harvest-extras.py +36 -26
  273. udata/migrations/2023-02-08-rename-internal-dates.py +46 -28
  274. udata/migrations/2024-01-29-fix-reuse-and-dataset-with-private-None.py +10 -8
  275. udata/migrations/2024-03-22-migrate-activity-kwargs-to-extras.py +6 -4
  276. udata/migrations/2024-06-11-fix-reuse-datasets-references.py +7 -6
  277. udata/migrations/__init__.py +123 -105
  278. udata/models/__init__.py +4 -4
  279. udata/mongo/__init__.py +13 -11
  280. udata/mongo/badges_field.py +3 -2
  281. udata/mongo/datetime_fields.py +13 -12
  282. udata/mongo/document.py +17 -16
  283. udata/mongo/engine.py +15 -16
  284. udata/mongo/errors.py +2 -1
  285. udata/mongo/extras_fields.py +30 -20
  286. udata/mongo/queryset.py +12 -12
  287. udata/mongo/slug_fields.py +38 -28
  288. udata/mongo/taglist_field.py +1 -2
  289. udata/mongo/url_field.py +5 -5
  290. udata/mongo/uuid_fields.py +4 -3
  291. udata/notifications/__init__.py +1 -1
  292. udata/notifications/mattermost.py +10 -9
  293. udata/rdf.py +167 -188
  294. udata/routing.py +40 -45
  295. udata/search/__init__.py +18 -19
  296. udata/search/adapter.py +17 -16
  297. udata/search/commands.py +44 -51
  298. udata/search/fields.py +13 -20
  299. udata/search/query.py +23 -18
  300. udata/search/result.py +9 -10
  301. udata/sentry.py +21 -19
  302. udata/settings.py +262 -198
  303. udata/sitemap.py +8 -6
  304. udata/static/chunks/{11.e9b9ca1f3e03d4020377.js → 11.52e531c19f8de80c00cf.js} +3 -3
  305. udata/static/chunks/{11.e9b9ca1f3e03d4020377.js.map → 11.52e531c19f8de80c00cf.js.map} +1 -1
  306. udata/static/chunks/{13.038c0d9aa0dfa0181c4b.js → 13.c3343a7f1070061c0e10.js} +2 -2
  307. udata/static/chunks/{13.038c0d9aa0dfa0181c4b.js.map → 13.c3343a7f1070061c0e10.js.map} +1 -1
  308. udata/static/chunks/{16.0baa2b64a74a2dcde25c.js → 16.8fa42440ad75ca172e6d.js} +2 -2
  309. udata/static/chunks/{16.0baa2b64a74a2dcde25c.js.map → 16.8fa42440ad75ca172e6d.js.map} +1 -1
  310. udata/static/chunks/{19.350a9f150b074b4ecefa.js → 19.9c6c8412729cd6d59cfa.js} +3 -3
  311. udata/static/chunks/{19.350a9f150b074b4ecefa.js.map → 19.9c6c8412729cd6d59cfa.js.map} +1 -1
  312. udata/static/chunks/{5.6ebbce2b9b3e696d3da5.js → 5.71d15c2e4f21feee2a9a.js} +3 -3
  313. udata/static/chunks/{5.6ebbce2b9b3e696d3da5.js.map → 5.71d15c2e4f21feee2a9a.js.map} +1 -1
  314. udata/static/chunks/{6.d8a5f7b017bcbd083641.js → 6.9139dc098b8ea640b890.js} +3 -3
  315. udata/static/chunks/{6.d8a5f7b017bcbd083641.js.map → 6.9139dc098b8ea640b890.js.map} +1 -1
  316. udata/static/common.js +1 -1
  317. udata/static/common.js.map +1 -1
  318. udata/storage/s3.py +20 -13
  319. udata/tags.py +4 -5
  320. udata/tasks.py +43 -42
  321. udata/tests/__init__.py +9 -6
  322. udata/tests/api/__init__.py +5 -6
  323. udata/tests/api/test_auth_api.py +395 -321
  324. udata/tests/api/test_base_api.py +31 -33
  325. udata/tests/api/test_contact_points.py +7 -9
  326. udata/tests/api/test_dataservices_api.py +211 -158
  327. udata/tests/api/test_datasets_api.py +823 -812
  328. udata/tests/api/test_follow_api.py +13 -15
  329. udata/tests/api/test_me_api.py +95 -112
  330. udata/tests/api/test_organizations_api.py +301 -339
  331. udata/tests/api/test_reports_api.py +35 -25
  332. udata/tests/api/test_reuses_api.py +134 -139
  333. udata/tests/api/test_swagger.py +5 -5
  334. udata/tests/api/test_tags_api.py +18 -25
  335. udata/tests/api/test_topics_api.py +94 -94
  336. udata/tests/api/test_transfer_api.py +53 -48
  337. udata/tests/api/test_user_api.py +128 -141
  338. udata/tests/apiv2/test_datasets.py +290 -198
  339. udata/tests/apiv2/test_me_api.py +10 -11
  340. udata/tests/apiv2/test_organizations.py +56 -74
  341. udata/tests/apiv2/test_swagger.py +5 -5
  342. udata/tests/apiv2/test_topics.py +69 -87
  343. udata/tests/cli/test_cli_base.py +8 -8
  344. udata/tests/cli/test_db_cli.py +21 -19
  345. udata/tests/dataservice/test_dataservice_tasks.py +8 -12
  346. udata/tests/dataset/test_csv_adapter.py +44 -35
  347. udata/tests/dataset/test_dataset_actions.py +2 -3
  348. udata/tests/dataset/test_dataset_commands.py +7 -8
  349. udata/tests/dataset/test_dataset_events.py +36 -29
  350. udata/tests/dataset/test_dataset_model.py +224 -217
  351. udata/tests/dataset/test_dataset_rdf.py +142 -131
  352. udata/tests/dataset/test_dataset_tasks.py +15 -15
  353. udata/tests/dataset/test_resource_preview.py +10 -13
  354. udata/tests/features/territories/__init__.py +9 -13
  355. udata/tests/features/territories/test_territories_api.py +71 -91
  356. udata/tests/forms/test_basic_fields.py +7 -7
  357. udata/tests/forms/test_current_user_field.py +39 -66
  358. udata/tests/forms/test_daterange_field.py +31 -39
  359. udata/tests/forms/test_dict_field.py +28 -26
  360. udata/tests/forms/test_extras_fields.py +102 -76
  361. udata/tests/forms/test_form_field.py +8 -8
  362. udata/tests/forms/test_image_field.py +33 -26
  363. udata/tests/forms/test_model_field.py +134 -123
  364. udata/tests/forms/test_model_list_field.py +7 -7
  365. udata/tests/forms/test_nested_model_list_field.py +117 -79
  366. udata/tests/forms/test_publish_as_field.py +36 -65
  367. udata/tests/forms/test_reference_field.py +34 -53
  368. udata/tests/forms/test_user_forms.py +23 -21
  369. udata/tests/forms/test_uuid_field.py +6 -10
  370. udata/tests/frontend/__init__.py +9 -6
  371. udata/tests/frontend/test_auth.py +7 -6
  372. udata/tests/frontend/test_csv.py +81 -96
  373. udata/tests/frontend/test_hooks.py +43 -43
  374. udata/tests/frontend/test_markdown.py +211 -191
  375. udata/tests/helpers.py +32 -37
  376. udata/tests/models.py +2 -2
  377. udata/tests/organization/test_csv_adapter.py +21 -16
  378. udata/tests/organization/test_notifications.py +11 -18
  379. udata/tests/organization/test_organization_model.py +13 -13
  380. udata/tests/organization/test_organization_rdf.py +29 -22
  381. udata/tests/organization/test_organization_tasks.py +16 -17
  382. udata/tests/plugin.py +76 -73
  383. udata/tests/reuse/test_reuse_model.py +21 -21
  384. udata/tests/reuse/test_reuse_task.py +11 -13
  385. udata/tests/search/__init__.py +11 -12
  386. udata/tests/search/test_adapter.py +60 -70
  387. udata/tests/search/test_query.py +16 -16
  388. udata/tests/search/test_results.py +10 -7
  389. udata/tests/site/test_site_api.py +11 -16
  390. udata/tests/site/test_site_metrics.py +20 -30
  391. udata/tests/site/test_site_model.py +4 -5
  392. udata/tests/site/test_site_rdf.py +94 -78
  393. udata/tests/test_activity.py +17 -17
  394. udata/tests/test_discussions.py +292 -299
  395. udata/tests/test_i18n.py +37 -40
  396. udata/tests/test_linkchecker.py +91 -85
  397. udata/tests/test_mail.py +13 -17
  398. udata/tests/test_migrations.py +219 -180
  399. udata/tests/test_model.py +164 -157
  400. udata/tests/test_notifications.py +17 -17
  401. udata/tests/test_owned.py +14 -14
  402. udata/tests/test_rdf.py +25 -23
  403. udata/tests/test_routing.py +89 -93
  404. udata/tests/test_storages.py +137 -128
  405. udata/tests/test_tags.py +44 -46
  406. udata/tests/test_topics.py +7 -7
  407. udata/tests/test_transfer.py +42 -49
  408. udata/tests/test_uris.py +160 -161
  409. udata/tests/test_utils.py +79 -71
  410. udata/tests/user/test_user_rdf.py +5 -9
  411. udata/tests/workers/test_jobs_commands.py +57 -58
  412. udata/tests/workers/test_tasks_routing.py +23 -29
  413. udata/tests/workers/test_workers_api.py +125 -131
  414. udata/tests/workers/test_workers_helpers.py +6 -6
  415. udata/tracking.py +4 -6
  416. udata/uris.py +45 -46
  417. udata/utils.py +68 -66
  418. udata/wsgi.py +1 -1
  419. {udata-9.1.2.dev30355.dist-info → udata-9.1.2.dev30382.dist-info}/METADATA +3 -2
  420. udata-9.1.2.dev30382.dist-info/RECORD +704 -0
  421. udata-9.1.2.dev30355.dist-info/RECORD +0 -704
  422. {udata-9.1.2.dev30355.dist-info → udata-9.1.2.dev30382.dist-info}/LICENSE +0 -0
  423. {udata-9.1.2.dev30355.dist-info → udata-9.1.2.dev30382.dist-info}/WHEEL +0 -0
  424. {udata-9.1.2.dev30355.dist-info → udata-9.1.2.dev30382.dist-info}/entry_points.txt +0 -0
  425. {udata-9.1.2.dev30355.dist-info → udata-9.1.2.dev30382.dist-info}/top_level.txt +0 -0
udata/tests/plugin.py CHANGED
@@ -1,14 +1,13 @@
1
- import pytest
2
1
  import shlex
3
-
4
2
  from contextlib import contextmanager
5
3
  from urllib.parse import urlparse
6
4
 
7
- from flask import json, template_rendered, url_for, current_app
5
+ import pytest
6
+ from flask import current_app, json, template_rendered, url_for
8
7
  from flask.testing import FlaskClient
8
+ from flask_principal import Identity, identity_changed
9
9
  from lxml import etree
10
10
  from werkzeug.urls import url_encode
11
- from flask_principal import Identity, identity_changed
12
11
 
13
12
  from udata import settings
14
13
  from udata.app import create_app
@@ -20,10 +19,10 @@ from .helpers import assert200, assert_command_ok
20
19
 
21
20
  class TestClient(FlaskClient):
22
21
  def _build_url(self, url, kwargs):
23
- if 'qs' not in kwargs:
22
+ if "qs" not in kwargs:
24
23
  return url
25
- qs = kwargs.pop('qs')
26
- return '?'.join([url, url_encode(qs)])
24
+ qs = kwargs.pop("qs")
25
+ return "?".join([url, url_encode(qs)])
27
26
 
28
27
  def get(self, url, **kwargs):
29
28
  url = self._build_url(url, kwargs)
@@ -46,18 +45,18 @@ class TestClient(FlaskClient):
46
45
  with self.session_transaction() as session:
47
46
  # Since flask-security-too 4.0.0, the user.fs_uniquifier is used instead of user.id for auth
48
47
  user_id = getattr(user, current_app.login_manager.id_attribute)()
49
- session['user_id'] = user_id
50
- session['_fresh'] = True
51
- session['_id'] = current_app.login_manager._session_identifier_generator()
48
+ session["user_id"] = user_id
49
+ session["_fresh"] = True
50
+ session["_id"] = current_app.login_manager._session_identifier_generator()
52
51
  current_app.login_manager._update_request_context_with_user(user)
53
52
  identity_changed.send(current_app._get_current_object(), identity=Identity(user.id))
54
53
  return user
55
54
 
56
55
  def logout(self):
57
56
  with self.session_transaction() as session:
58
- del session['user_id']
59
- del session['_fresh']
60
- del session['_id']
57
+ del session["user_id"]
58
+ del session["_fresh"]
59
+ del session["_id"]
61
60
 
62
61
 
63
62
  @pytest.fixture
@@ -70,57 +69,58 @@ def app(request):
70
69
 
71
70
  @pytest.fixture(autouse=True)
72
71
  def _load_frontend(request, _configure_application):
73
- '''
72
+ """
74
73
  Use `pytest.mark.frontend` to specify that frontend/api should be loaded
75
74
  Pass an optionnal list of modules as parameter to restrict loaded modules.
76
75
 
77
76
  Handle backward compatibility with Class.modules attribute too
78
- '''
79
- if 'app' not in request.fixturenames:
77
+ """
78
+ if "app" not in request.fixturenames:
80
79
  return
81
80
 
82
- app = request.getfixturevalue('app')
83
- marker = request.node.get_closest_marker('frontend')
81
+ app = request.getfixturevalue("app")
82
+ marker = request.node.get_closest_marker("frontend")
84
83
  modules = set(marker.args[0] if marker and marker.args else [])
85
- if getattr(request.cls, 'modules', None):
84
+ if getattr(request.cls, "modules", None):
86
85
  modules |= set(request.cls.modules)
87
86
 
88
- if marker or hasattr(request.cls, 'modules'):
89
- from udata import frontend, api
87
+ if marker or hasattr(request.cls, "modules"):
88
+ from udata import api, frontend
89
+
90
90
  api.init_app(app)
91
91
  frontend.init_app(app, modules)
92
92
 
93
93
 
94
94
  @pytest.fixture
95
95
  def client(app):
96
- '''
96
+ """
97
97
  Fixes https://github.com/pytest-dev/pytest-flask/issues/42
98
- '''
98
+ """
99
99
  return app.test_client()
100
100
 
101
101
 
102
102
  def get_settings(request):
103
- '''
103
+ """
104
104
  Extract settings from the current test request
105
- '''
106
- marker = request.node.get_closest_marker('settings')
105
+ """
106
+ marker = request.node.get_closest_marker("settings")
107
107
  if marker:
108
108
  return marker.args[0]
109
- _settings = getattr(request.cls, 'settings', settings.Testing)
109
+ _settings = getattr(request.cls, "settings", settings.Testing)
110
110
  # apply the options(plugins) marker from pytest_flask as soon as app is created
111
111
  # https://github.com/pytest-dev/pytest-flask/blob/a62ea18cb0fe89e3f3911192ab9ea4f9b12f8a16/pytest_flask/plugin.py#L126
112
112
  # this lets us have default settings for plugins applied while testing
113
- plugins = getattr(_settings, 'PLUGINS', [])
114
- for options in request.node.iter_markers('options'):
115
- option = options.kwargs.get('plugins', []) or options.kwargs.get('PLUGINS', [])
113
+ plugins = getattr(_settings, "PLUGINS", [])
114
+ for options in request.node.iter_markers("options"):
115
+ option = options.kwargs.get("plugins", []) or options.kwargs.get("PLUGINS", [])
116
116
  plugins += option
117
- setattr(_settings, 'PLUGINS', plugins)
117
+ setattr(_settings, "PLUGINS", plugins)
118
118
  return _settings
119
119
 
120
120
 
121
121
  def drop_db(app):
122
- '''Clear the database'''
123
- parsed_url = urlparse(app.config['MONGODB_HOST'])
122
+ """Clear the database"""
123
+ parsed_url = urlparse(app.config["MONGODB_HOST"])
124
124
 
125
125
  # drop the leading /
126
126
  db_name = parsed_url.path[1:]
@@ -133,19 +133,20 @@ def clean_db(app):
133
133
  yield
134
134
 
135
135
 
136
- @pytest.fixture(name='db')
136
+ @pytest.fixture(name="db")
137
137
  def raw_db(app, clean_db):
138
- '''Access to raw PyMongo DB client'''
138
+ """Access to raw PyMongo DB client"""
139
139
  from mongoengine.connection import get_db
140
+
140
141
  yield get_db()
141
142
  drop_db(app)
142
143
 
143
144
 
144
145
  @pytest.fixture
145
146
  def enable_resource_event(app):
146
- '''Enable resource event'''
147
- app.config['PUBLISH_ON_RESOURCE_EVENTS'] = True
148
- app.config['RESOURCES_ANALYSER_URI'] = 'http://local.dev'
147
+ """Enable resource event"""
148
+ app.config["PUBLISH_ON_RESOURCE_EVENTS"] = True
149
+ app.config["RESOURCES_ANALYSER_URI"] = "http://local.dev"
149
150
 
150
151
 
151
152
  class ApiClient(object):
@@ -165,42 +166,42 @@ class ApiClient(object):
165
166
  yield self._user
166
167
 
167
168
  def perform(self, verb, url, **kwargs):
168
- headers = kwargs.pop('headers', {})
169
- headers['Content-Type'] = 'application/json'
169
+ headers = kwargs.pop("headers", {})
170
+ headers["Content-Type"] = "application/json"
170
171
 
171
- data = kwargs.get('data')
172
+ data = kwargs.get("data")
172
173
  if data is not None:
173
174
  data = json.dumps(data)
174
- headers['Content-Length'] = len(data)
175
- kwargs['data'] = data
175
+ headers["Content-Length"] = len(data)
176
+ kwargs["data"] = data
176
177
 
177
178
  if self._user:
178
- headers['X-API-KEY'] = kwargs.get('X-API-KEY', self._user.apikey)
179
+ headers["X-API-KEY"] = kwargs.get("X-API-KEY", self._user.apikey)
179
180
 
180
- kwargs['headers'] = headers
181
+ kwargs["headers"] = headers
181
182
  method = getattr(self.client, verb)
182
183
  return method(url, **kwargs)
183
184
 
184
185
  def get(self, url, *args, **kwargs):
185
- return self.perform('get', url, *args, **kwargs)
186
+ return self.perform("get", url, *args, **kwargs)
186
187
 
187
188
  def post(self, url, data=None, json=True, *args, **kwargs):
188
189
  if not json:
189
190
  return self.client.post(url, data or {}, *args, **kwargs)
190
- return self.perform('post', url, data=data or {}, *args, **kwargs)
191
+ return self.perform("post", url, data=data or {}, *args, **kwargs)
191
192
 
192
193
  def put(self, url, data=None, json=True, *args, **kwargs):
193
194
  if not json:
194
195
  return self.client.put(url, data or {}, *args, **kwargs)
195
- return self.perform('put', url, data=data or {}, *args, **kwargs)
196
+ return self.perform("put", url, data=data or {}, *args, **kwargs)
196
197
 
197
198
  def patch(self, url, data=None, json=True, *args, **kwargs):
198
199
  if not json:
199
200
  return self.client.patch(url, data or {}, *args, **kwargs)
200
- return self.perform('patch', url, data=data or {}, *args, **kwargs)
201
+ return self.perform("patch", url, data=data or {}, *args, **kwargs)
201
202
 
202
203
  def delete(self, url, data=None, *args, **kwargs):
203
- return self.perform('delete', url, data=data or {}, *args, **kwargs)
204
+ return self.perform("delete", url, data=data or {}, *args, **kwargs)
204
205
 
205
206
 
206
207
  @pytest.fixture
@@ -209,17 +210,16 @@ def api(client):
209
210
  return api_client
210
211
 
211
212
 
212
- @pytest.fixture(name='cli')
213
+ @pytest.fixture(name="cli")
213
214
  def cli_fixture(app):
214
-
215
215
  def mock_runner(*args, **kwargs):
216
216
  from udata.commands import cli
217
217
 
218
- if len(args) == 1 and ' ' in args[0]:
218
+ if len(args) == 1 and " " in args[0]:
219
219
  args = shlex.split(args[0])
220
220
  runner = app.test_cli_runner()
221
221
  result = runner.invoke(cli, args, catch_exceptions=False)
222
- if kwargs.get('check', True):
222
+ if kwargs.get("check", True):
223
223
  assert_command_ok(result)
224
224
  return result
225
225
 
@@ -228,20 +228,20 @@ def cli_fixture(app):
228
228
 
229
229
  @pytest.fixture
230
230
  def instance_path(app, tmpdir):
231
- '''Use temporary application instance_path'''
231
+ """Use temporary application instance_path"""
232
232
  from udata.core import storages
233
233
  from udata.core.storages.views import blueprint
234
234
 
235
235
  app.instance_path = str(tmpdir)
236
- app.config['FS_ROOT'] = str(tmpdir / 'fs')
236
+ app.config["FS_ROOT"] = str(tmpdir / "fs")
237
237
  # Force local storage:
238
- for s in 'resources', 'avatars', 'logos', 'images', 'chunks', 'tmp':
239
- key = '{0}_FS_{{0}}'.format(s.upper())
240
- app.config[key.format('BACKEND')] = 'local'
241
- app.config.pop(key.format('ROOT'), None)
238
+ for s in "resources", "avatars", "logos", "images", "chunks", "tmp":
239
+ key = "{0}_FS_{{0}}".format(s.upper())
240
+ app.config[key.format("BACKEND")] = "local"
241
+ app.config.pop(key.format("ROOT"), None)
242
242
 
243
243
  storages.init_app(app)
244
- app.register_blueprint(blueprint, name='test-storage')
244
+ app.register_blueprint(blueprint, name="test-storage")
245
245
 
246
246
  return tmpdir
247
247
 
@@ -277,8 +277,9 @@ class TemplateRecorder:
277
277
 
278
278
  used_templates.append(template)
279
279
 
280
- msg = 'Template %s not used. Templates were used: %s' % (
281
- name, ' '.join(repr(used_templates))
280
+ msg = "Template %s not used. Templates were used: %s" % (
281
+ name,
282
+ " ".join(repr(used_templates)),
282
283
  )
283
284
  raise AssertionError(msg)
284
285
 
@@ -305,6 +306,7 @@ def templates():
305
306
  @pytest.fixture
306
307
  def httpretty():
307
308
  import httpretty
309
+
308
310
  httpretty.reset()
309
311
  httpretty.enable()
310
312
  yield httpretty
@@ -313,8 +315,9 @@ def httpretty():
313
315
 
314
316
  @pytest.fixture
315
317
  def rmock():
316
- '''A requests-mock fixture'''
318
+ """A requests-mock fixture"""
317
319
  import requests_mock
320
+
318
321
  with requests_mock.Mocker() as m:
319
322
  m.ANY = requests_mock.ANY
320
323
  yield m
@@ -322,7 +325,7 @@ def rmock():
322
325
 
323
326
  class SitemapClient:
324
327
  # Needed for lxml XPath not supporting default namespace
325
- NAMESPACES = {'s': 'http://www.sitemaps.org/schemas/sitemap/0.9'}
328
+ NAMESPACES = {"s": "http://www.sitemaps.org/schemas/sitemap/0.9"}
326
329
  MISMATCH = 'URL "{0}" {1} mismatch: expected "{2}" found "{3}"'
327
330
 
328
331
  def __init__(self, client):
@@ -330,8 +333,8 @@ class SitemapClient:
330
333
  self._sitemap = None
331
334
 
332
335
  def fetch(self, secure=False):
333
- base_url = '{0}://local.test'.format('https' if secure else 'http')
334
- response = self.client.get('sitemap.xml', base_url=base_url)
336
+ base_url = "{0}://local.test".format("https" if secure else "http")
337
+ response = self.client.get("sitemap.xml", base_url=base_url)
335
338
  assert200(response)
336
339
  self._sitemap = etree.fromstring(response.data)
337
340
  return self._sitemap
@@ -346,21 +349,21 @@ class SitemapClient:
346
349
  return result[0] if result else None
347
350
 
348
351
  def assert_url(self, url, priority, changefreq):
349
- '''
352
+ """
350
353
  Check than a URL is present in the sitemap
351
354
  with given `priority` and `changefreq`
352
- '''
355
+ """
353
356
  __tracebackhide__ = True
354
- r = url.xpath('s:priority', namespaces=self.NAMESPACES)
357
+ r = url.xpath("s:priority", namespaces=self.NAMESPACES)
355
358
  assert len(r) == 1, 'URL "{0}" should have one priority'.format(url)
356
359
  found = r[0].text
357
- msg = self.MISMATCH.format(url, 'priority', priority, found)
360
+ msg = self.MISMATCH.format(url, "priority", priority, found)
358
361
  assert found == str(priority), msg
359
362
 
360
- r = url.xpath('s:changefreq', namespaces=self.NAMESPACES)
363
+ r = url.xpath("s:changefreq", namespaces=self.NAMESPACES)
361
364
  assert len(r) == 1, 'URL "{0}" should have one changefreq'.format(url)
362
365
  found = r[0].text
363
- msg = self.MISMATCH.format(url, 'changefreq', changefreq, found)
366
+ msg = self.MISMATCH.format(url, "changefreq", changefreq, found)
364
367
  assert found == changefreq, msg
365
368
 
366
369
 
@@ -1,17 +1,16 @@
1
1
  from datetime import datetime
2
2
 
3
- from udata.models import Reuse
4
-
5
3
  from udata.core.dataset import tasks as dataset_tasks
4
+ from udata.core.dataset.factories import DatasetFactory
5
+ from udata.core.discussions.factories import DiscussionFactory
6
6
  from udata.core.organization.factories import OrganizationFactory
7
7
  from udata.core.reuse.factories import ReuseFactory, VisibleReuseFactory
8
- from udata.core.dataset.factories import DatasetFactory
9
8
  from udata.core.user.factories import UserFactory
10
- from udata.core.discussions.factories import DiscussionFactory
11
9
  from udata.i18n import gettext as _
10
+ from udata.models import Reuse
12
11
  from udata.tests.helpers import assert_emit
13
12
 
14
- from .. import TestCase, DBTestMixin
13
+ from .. import DBTestMixin, TestCase
15
14
 
16
15
 
17
16
  class ReuseModelTest(TestCase, DBTestMixin):
@@ -39,8 +38,10 @@ class ReuseModelTest(TestCase, DBTestMixin):
39
38
  user = UserFactory()
40
39
  org = OrganizationFactory()
41
40
  reuses = [ReuseFactory(owner=user), ReuseFactory(organization=org)]
42
- excluded = [ReuseFactory(owner=UserFactory()),
43
- ReuseFactory(organization=OrganizationFactory())]
41
+ excluded = [
42
+ ReuseFactory(owner=UserFactory()),
43
+ ReuseFactory(organization=OrganizationFactory()),
44
+ ]
44
45
 
45
46
  result = Reuse.objects.owned_by(org, user)
46
47
 
@@ -53,10 +54,10 @@ class ReuseModelTest(TestCase, DBTestMixin):
53
54
 
54
55
  def test_tags_normalized(self):
55
56
  user = UserFactory()
56
- tags = [' one another!', ' one another!', 'This IS a "tag"…']
57
+ tags = [" one another!", " one another!", 'This IS a "tag"…']
57
58
  reuse = ReuseFactory(owner=user, tags=tags)
58
59
  self.assertEqual(len(reuse.tags), 2)
59
- self.assertEqual(reuse.tags[1], 'this-is-a-tag')
60
+ self.assertEqual(reuse.tags[1], "this-is-a-tag")
60
61
 
61
62
  def test_send_on_delete(self):
62
63
  reuse = ReuseFactory()
@@ -72,18 +73,18 @@ class ReuseModelTest(TestCase, DBTestMixin):
72
73
  reuse.count_datasets()
73
74
  reuse.count_discussions()
74
75
 
75
- assert reuse.get_metrics()['datasets'] == 1
76
- assert reuse.get_metrics()['discussions'] == 1
76
+ assert reuse.get_metrics()["datasets"] == 1
77
+ assert reuse.get_metrics()["discussions"] == 1
77
78
 
78
79
  with assert_emit(Reuse.on_update):
79
80
  reuse.datasets.append(dataset)
80
81
  reuse.save()
81
82
 
82
83
  reuse.count_datasets()
83
- assert reuse.get_metrics()['datasets'] == 2
84
+ assert reuse.get_metrics()["datasets"] == 2
84
85
 
85
86
  dataset.count_reuses()
86
- assert dataset.get_metrics()['reuses'] == 1
87
+ assert dataset.get_metrics()["reuses"] == 1
87
88
 
88
89
  with assert_emit(Reuse.on_update):
89
90
  reuse.datasets.remove(dataset)
@@ -91,17 +92,17 @@ class ReuseModelTest(TestCase, DBTestMixin):
91
92
 
92
93
  dataset_tasks.update_datasets_reuses_metrics()
93
94
  dataset.reload()
94
- assert dataset.get_metrics()['reuses'] == 0
95
+ assert dataset.get_metrics()["reuses"] == 0
95
96
 
96
97
  def test_reuse_type(self):
97
- reuse = ReuseFactory(type='api')
98
- self.assertEqual(reuse.type, 'api')
99
- self.assertEqual(reuse.type_label, 'API')
98
+ reuse = ReuseFactory(type="api")
99
+ self.assertEqual(reuse.type, "api")
100
+ self.assertEqual(reuse.type_label, "API")
100
101
 
101
102
  def test_reuse_topic(self):
102
- reuse = ReuseFactory(topic='health')
103
- self.assertEqual(reuse.topic, 'health')
104
- self.assertEqual(reuse.topic_label, _('Health'))
103
+ reuse = ReuseFactory(topic="health")
104
+ self.assertEqual(reuse.topic, "health")
105
+ self.assertEqual(reuse.topic_label, _("Health"))
105
106
 
106
107
  def test_reuse_without_private(self):
107
108
  reuse = ReuseFactory()
@@ -114,4 +115,3 @@ class ReuseModelTest(TestCase, DBTestMixin):
114
115
  reuse.private = True
115
116
  reuse.save()
116
117
  self.assertEqual(reuse.private, True)
117
-
@@ -1,31 +1,29 @@
1
1
  from flask import url_for
2
2
 
3
- from udata.tests.api import APITestCase
4
-
5
3
  from udata.core import storages
6
- from udata.tests.helpers import create_test_image
7
- from udata.models import Reuse, Transfer
8
- from udata.core.user.factories import AdminFactory, UserFactory
9
- from udata.core.reuse.factories import ReuseFactory
10
4
  from udata.core.reuse import tasks
5
+ from udata.core.reuse.factories import ReuseFactory
6
+ from udata.core.user.factories import AdminFactory, UserFactory
7
+ from udata.models import Reuse, Transfer
8
+ from udata.tests.api import APITestCase
9
+ from udata.tests.helpers import create_test_image
11
10
 
12
11
 
13
12
  class ReuseTasksTest(APITestCase):
14
13
  def test_purge_reuses(self):
15
- reuse = ReuseFactory(title='test-reuse')
14
+ reuse = ReuseFactory(title="test-reuse")
16
15
 
17
16
  # Upload reuse's image
18
17
  file = create_test_image()
19
18
  user = AdminFactory()
20
19
  self.login(user)
21
20
  response = self.post(
22
- url_for('api.reuse_image', reuse=reuse),
23
- {'file': (file, 'test.png')},
24
- json=False)
21
+ url_for("api.reuse_image", reuse=reuse), {"file": (file, "test.png")}, json=False
22
+ )
25
23
  self.assert200(response)
26
24
 
27
25
  # Delete reuse
28
- response = self.delete(url_for('api.reuse', reuse=reuse))
26
+ response = self.delete(url_for("api.reuse", reuse=reuse))
29
27
  self.assert204(response)
30
28
 
31
29
  user = UserFactory()
@@ -33,7 +31,7 @@ class ReuseTasksTest(APITestCase):
33
31
  owner=user,
34
32
  recipient=user,
35
33
  subject=reuse,
36
- comment='comment',
34
+ comment="comment",
37
35
  )
38
36
 
39
37
  tasks.purge_reuses()
@@ -43,5 +41,5 @@ class ReuseTasksTest(APITestCase):
43
41
  # Check reuse's image is deleted
44
42
  self.assertEqual(list(storages.images.list_files()), [])
45
43
 
46
- deleted_reuse = Reuse.objects(title='test-reuse').first()
44
+ deleted_reuse = Reuse.objects(title="test-reuse").first()
47
45
  self.assertIsNone(deleted_reuse)
@@ -1,15 +1,14 @@
1
1
  import factory
2
-
3
2
  from factory.mongoengine import MongoEngineFactory
4
3
 
5
4
  from udata import search
6
5
  from udata.mongo import db
7
6
 
8
-
9
7
  #############################################################################
10
8
  # Fake object for testing #
11
9
  #############################################################################
12
10
 
11
+
13
12
  class FakeSearchable(db.Document):
14
13
  title = db.StringField()
15
14
  description = db.StringField()
@@ -17,7 +16,7 @@ class FakeSearchable(db.Document):
17
16
  other = db.ListField(db.StringField())
18
17
  indexable = db.BooleanField(default=True)
19
18
 
20
- meta = {'allow_inheritance': True}
19
+ meta = {"allow_inheritance": True}
21
20
 
22
21
  def __unicode__(self):
23
22
  return self.title
@@ -26,11 +25,11 @@ class FakeSearchable(db.Document):
26
25
  return self.title
27
26
 
28
27
  def __html__(self):
29
- return '<span>{0}</span>'.format(self.title)
28
+ return "<span>{0}</span>".format(self.title)
30
29
 
31
30
 
32
31
  class FakeFactory(MongoEngineFactory):
33
- title = factory.Faker('sentence')
32
+ title = factory.Faker("sentence")
34
33
 
35
34
  class Meta:
36
35
  model = FakeSearchable
@@ -39,14 +38,14 @@ class FakeFactory(MongoEngineFactory):
39
38
  @search.register
40
39
  class FakeSearch(search.ModelSearchAdapter):
41
40
  model = FakeSearchable
42
- search_url = 'mock://test.com/fakeable/'
41
+ search_url = "mock://test.com/fakeable/"
43
42
  filters = {
44
- 'tag': search.Filter(),
45
- 'other': search.Filter(),
43
+ "tag": search.Filter(),
44
+ "other": search.Filter(),
46
45
  }
47
46
  sorts = {
48
- 'title': 'title.raw',
49
- 'description': 'description.raw',
47
+ "title": "title.raw",
48
+ "description": "description.raw",
50
49
  }
51
50
 
52
51
  @classmethod
@@ -56,6 +55,6 @@ class FakeSearch(search.ModelSearchAdapter):
56
55
  @classmethod
57
56
  def serialize(cls, fake):
58
57
  return {
59
- 'title': fake.title,
60
- 'description': fake.description,
58
+ "title": fake.title,
59
+ "description": fake.description,
61
60
  }