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/routing.py CHANGED
@@ -1,21 +1,22 @@
1
- from bson import ObjectId
2
1
  from uuid import UUID
3
2
 
4
- from flask import request, redirect, url_for
3
+ from bson import ObjectId
4
+ from flask import redirect, request, url_for
5
5
  from mongoengine.errors import InvalidQueryError, ValidationError
6
6
  from werkzeug.exceptions import NotFound
7
7
  from werkzeug.routing import BaseConverter, PathConverter
8
8
  from werkzeug.urls import url_quote
9
9
 
10
10
  from udata import models
11
- from udata.mongo import db
12
- from udata.core.spatial.models import GeoZone
13
11
  from udata.core.dataservices.models import Dataservice
12
+ from udata.core.spatial.models import GeoZone
14
13
  from udata.i18n import ISO_639_1_CODES
14
+ from udata.mongo import db
15
15
 
16
16
 
17
17
  class LazyRedirect(object):
18
- '''Store location for lazy redirections'''
18
+ """Store location for lazy redirections"""
19
+
19
20
  def __init__(self, arg):
20
21
  self.arg = arg
21
22
 
@@ -23,25 +24,23 @@ class LazyRedirect(object):
23
24
  class LanguagePrefixConverter(BaseConverter):
24
25
  def __init__(self, map):
25
26
  super(LanguagePrefixConverter, self).__init__(map)
26
- self.regex = '(?:%s)' % '|'.join(ISO_639_1_CODES)
27
+ self.regex = "(?:%s)" % "|".join(ISO_639_1_CODES)
27
28
 
28
29
 
29
30
  class ListConverter(BaseConverter):
30
31
  def to_python(self, value):
31
- return value.split(',')
32
+ return value.split(",")
32
33
 
33
34
  def to_url(self, values):
34
- return ','.join(super(ListConverter, self).to_url(value)
35
- for value in values)
35
+ return ",".join(super(ListConverter, self).to_url(value) for value in values)
36
36
 
37
37
 
38
38
  class PathListConverter(PathConverter):
39
39
  def to_python(self, value):
40
- return value.split(',')
40
+ return value.split(",")
41
41
 
42
42
  def to_url(self, values):
43
- return ','.join(super(PathListConverter, self).to_url(value)
44
- for value in values)
43
+ return ",".join(super(PathListConverter, self).to_url(value) for value in values)
45
44
 
46
45
 
47
46
  class UUIDConverter(BaseConverter):
@@ -53,7 +52,7 @@ class UUIDConverter(BaseConverter):
53
52
 
54
53
 
55
54
  class ModelConverter(BaseConverter):
56
- '''
55
+ """
57
56
  A base class helper for model helper.
58
57
 
59
58
  Allow to give model or slug or ObjectId as parameter to url_for().
@@ -66,13 +65,13 @@ class ModelConverter(BaseConverter):
66
65
  * fetch by id
67
66
  * fetch by slug
68
67
  * raise 404
69
- '''
68
+ """
70
69
 
71
70
  model = None
72
71
 
73
72
  @property
74
73
  def has_slug(self):
75
- return hasattr(self.model, 'slug') and isinstance(self.model.slug, db.SlugField)
74
+ return hasattr(self.model, "slug") and isinstance(self.model.slug, db.SlugField)
76
75
 
77
76
  @property
78
77
  def has_redirected_slug(self):
@@ -110,9 +109,9 @@ class ModelConverter(BaseConverter):
110
109
  return self.quote(obj)
111
110
  elif isinstance(obj, (ObjectId, UUID)):
112
111
  return str(obj)
113
- elif getattr(obj, 'slug', None):
112
+ elif getattr(obj, "slug", None):
114
113
  return self.quote(obj.slug)
115
- elif getattr(obj, 'id', None):
114
+ elif getattr(obj, "id", None):
116
115
  return str(obj.id)
117
116
  else:
118
117
  raise ValueError('Unable to serialize "%s" to url' % obj)
@@ -155,7 +154,7 @@ class ContactPointConverter(ModelConverter):
155
154
 
156
155
 
157
156
  class TerritoryConverter(PathConverter):
158
- DEFAULT_PREFIX = 'fr' # TODO: make it a setting parameter
157
+ DEFAULT_PREFIX = "fr" # TODO: make it a setting parameter
159
158
 
160
159
  def to_python(self, value):
161
160
  """
@@ -166,10 +165,10 @@ class TerritoryConverter(PathConverter):
166
165
 
167
166
  Note that the slug is not significative but cannot be omitted.
168
167
  """
169
- if '/' not in value:
168
+ if "/" not in value:
170
169
  return NotFound()
171
170
 
172
- level, code = value.split('/')[:2] # Ignore optional slug
171
+ level, code = value.split("/")[:2] # Ignore optional slug
173
172
 
174
173
  geoid = GeoZone.SEPARATOR.join([level, code])
175
174
  zone = GeoZone.objects.resolve(geoid)
@@ -186,27 +185,23 @@ class TerritoryConverter(PathConverter):
186
185
  """
187
186
  Reconstruct the URL from level name, code or datagouv id and slug.
188
187
  """
189
- level_name = getattr(obj, 'level_name', None)
188
+ level_name = getattr(obj, "level_name", None)
190
189
  if not level_name:
191
190
  raise ValueError('Unable to serialize "%s" to url' % obj)
192
191
 
193
- code = getattr(obj, 'code', None)
194
- slug = getattr(obj, 'slug', None)
192
+ code = getattr(obj, "code", None)
193
+ slug = getattr(obj, "slug", None)
195
194
  if code and slug:
196
- return '{level_name}/{code}/{slug}'.format(
197
- level_name=level_name,
198
- code=code,
199
- slug=slug
200
- )
195
+ return "{level_name}/{code}/{slug}".format(level_name=level_name, code=code, slug=slug)
201
196
  else:
202
197
  raise ValueError('Unable to serialize "%s" to url' % obj)
203
198
 
204
199
 
205
200
  def lazy_raise_or_redirect():
206
- '''
201
+ """
207
202
  Raise exception lazily to ensure request.endpoint is set
208
203
  Also perform redirect if needed
209
- '''
204
+ """
210
205
  if not request.view_args:
211
206
  return
212
207
  for name, value in request.view_args.items():
@@ -217,22 +212,22 @@ def lazy_raise_or_redirect():
217
212
  new_args = request.view_args
218
213
  new_args[name] = value.arg
219
214
  new_url = url_for(request.endpoint, **new_args)
220
- return redirect(new_url, code=204 if request.method == 'OPTIONS' else 308)
215
+ return redirect(new_url, code=204 if request.method == "OPTIONS" else 308)
221
216
 
222
217
 
223
218
  def init_app(app):
224
219
  app.before_request(lazy_raise_or_redirect)
225
- app.url_map.converters['lang'] = LanguagePrefixConverter
226
- app.url_map.converters['list'] = ListConverter
227
- app.url_map.converters['pathlist'] = PathListConverter
228
- app.url_map.converters['uuid'] = UUIDConverter
229
- app.url_map.converters['dataset'] = DatasetConverter
230
- app.url_map.converters['dataservice'] = DataserviceConverter
231
- app.url_map.converters['crid'] = CommunityResourceConverter
232
- app.url_map.converters['org'] = OrganizationConverter
233
- app.url_map.converters['reuse'] = ReuseConverter
234
- app.url_map.converters['user'] = UserConverter
235
- app.url_map.converters['topic'] = TopicConverter
236
- app.url_map.converters['post'] = PostConverter
237
- app.url_map.converters['territory'] = TerritoryConverter
238
- app.url_map.converters['contact_point'] = ContactPointConverter
220
+ app.url_map.converters["lang"] = LanguagePrefixConverter
221
+ app.url_map.converters["list"] = ListConverter
222
+ app.url_map.converters["pathlist"] = PathListConverter
223
+ app.url_map.converters["uuid"] = UUIDConverter
224
+ app.url_map.converters["dataset"] = DatasetConverter
225
+ app.url_map.converters["dataservice"] = DataserviceConverter
226
+ app.url_map.converters["crid"] = CommunityResourceConverter
227
+ app.url_map.converters["org"] = OrganizationConverter
228
+ app.url_map.converters["reuse"] = ReuseConverter
229
+ app.url_map.converters["user"] = UserConverter
230
+ app.url_map.converters["topic"] = TopicConverter
231
+ app.url_map.converters["post"] = PostConverter
232
+ app.url_map.converters["territory"] = TerritoryConverter
233
+ app.url_map.converters["contact_point"] = ContactPointConverter
udata/search/__init__.py CHANGED
@@ -1,40 +1,39 @@
1
1
  import logging
2
+
2
3
  import requests
3
- import udata.event # noqa
4
- # Import udata event in order for datasets event hooks to be executed
5
4
 
5
+ # Import udata event in order for datasets event hooks to be executed
6
6
  from flask import current_app
7
- from mongoengine.signals import post_save, post_delete
7
+ from mongoengine.signals import post_delete, post_save
8
8
 
9
+ import udata.event # noqa
9
10
  from udata.mongo import db
10
- from udata.tasks import task, as_task_param
11
+ from udata.tasks import as_task_param, task
11
12
 
12
13
  log = logging.getLogger(__name__)
13
14
 
14
15
  adapter_catalog = {}
15
16
 
16
17
 
17
- @task(route='high.search')
18
+ @task(route="high.search")
18
19
  def reindex(classname, id):
19
- if not current_app.config['SEARCH_SERVICE_API_URL']:
20
+ if not current_app.config["SEARCH_SERVICE_API_URL"]:
20
21
  return
21
22
  model = db.resolve_model(classname)
22
23
  obj = model.objects.get(pk=id)
23
24
  adapter_class = adapter_catalog.get(model)
24
25
  document = adapter_class.serialize(obj)
25
26
  if adapter_class.is_indexable(obj):
26
- log.info('Indexing %s (%s)', model.__name__, obj.id)
27
+ log.info("Indexing %s (%s)", model.__name__, obj.id)
27
28
  url = f"{current_app.config['SEARCH_SERVICE_API_URL']}{adapter_class.search_url}index"
28
29
  try:
29
- payload = {
30
- 'document': document
31
- }
30
+ payload = {"document": document}
32
31
  r = requests.post(url, json=payload)
33
32
  r.raise_for_status()
34
33
  except Exception:
35
34
  log.exception('Unable to index/unindex %s "%s"', model.__name__, str(obj.id))
36
35
  else:
37
- log.info('Unindexing %s (%s)', model.__name__, obj.id)
36
+ log.info("Unindexing %s (%s)", model.__name__, obj.id)
38
37
  url = f"{current_app.config['SEARCH_SERVICE_API_URL']}{adapter_class.search_url}{str(obj.id)}/unindex"
39
38
  try:
40
39
  r = requests.delete(url)
@@ -46,13 +45,13 @@ def reindex(classname, id):
46
45
  log.exception('Unable to index/unindex %s "%s"', model.__name__, str(obj.id))
47
46
 
48
47
 
49
- @task(route='high.search')
48
+ @task(route="high.search")
50
49
  def unindex(classname, id):
51
- if not current_app.config['SEARCH_SERVICE_API_URL']:
50
+ if not current_app.config["SEARCH_SERVICE_API_URL"]:
52
51
  return
53
52
  model = db.resolve_model(classname)
54
53
  adapter_class = adapter_catalog.get(model)
55
- log.info('Unindexing %s (%s)', model.__name__, id)
54
+ log.info("Unindexing %s (%s)", model.__name__, id)
56
55
  try:
57
56
  url = f"{current_app.config['SEARCH_SERVICE_API_URL']}{adapter_class.search_url}/{str(id)}/unindex"
58
57
  r = requests.delete(url)
@@ -65,19 +64,19 @@ def unindex(classname, id):
65
64
 
66
65
 
67
66
  def reindex_model_on_save(sender, document, **kwargs):
68
- '''(Re/Un)Index Mongo document on post_save'''
69
- if current_app.config.get('AUTO_INDEX') and current_app.config['SEARCH_SERVICE_API_URL']:
67
+ """(Re/Un)Index Mongo document on post_save"""
68
+ if current_app.config.get("AUTO_INDEX") and current_app.config["SEARCH_SERVICE_API_URL"]:
70
69
  reindex.delay(*as_task_param(document))
71
70
 
72
71
 
73
72
  def unindex_model_on_delete(sender, document, **kwargs):
74
- '''Unindex Mongo document on post_delete'''
75
- if current_app.config.get('AUTO_INDEX') and current_app.config['SEARCH_SERVICE_API_URL']:
73
+ """Unindex Mongo document on post_delete"""
74
+ if current_app.config.get("AUTO_INDEX") and current_app.config["SEARCH_SERVICE_API_URL"]:
76
75
  unindex.delay(*as_task_param(document))
77
76
 
78
77
 
79
78
  def register(adapter):
80
- '''Register a search adapter'''
79
+ """Register a search adapter"""
81
80
  # register the class in the catalog
82
81
  if adapter.model and adapter.model not in adapter_catalog:
83
82
  adapter_catalog[adapter.model] = adapter
udata/search/adapter.py CHANGED
@@ -1,13 +1,15 @@
1
1
  import logging
2
+
2
3
  from flask_restx.reqparse import RequestParser
3
- from udata.search.query import SearchQuery
4
4
 
5
+ from udata.search.query import SearchQuery
5
6
 
6
7
  log = logging.getLogger(__name__)
7
8
 
8
9
 
9
10
  class ModelSearchAdapter:
10
11
  """This class allow to describe and customize the search behavior."""
12
+
11
13
  model = None
12
14
  sorts = None
13
15
  search_url = None
@@ -18,7 +20,7 @@ class ModelSearchAdapter:
18
20
  """By default use the ``to_dict`` method
19
21
  and exclude ``_id``, ``_cls`` and ``owner`` fields
20
22
  """
21
- return document.to_dict(exclude=('_id', '_cls', 'owner'))
23
+ return document.to_dict(exclude=("_id", "_cls", "owner"))
22
24
 
23
25
  @classmethod
24
26
  def is_indexable(cls, document):
@@ -28,40 +30,39 @@ class ModelSearchAdapter:
28
30
  def as_request_parser(cls, paginate=True):
29
31
  parser = RequestParser()
30
32
  # q parameter
31
- parser.add_argument('q', type=str, location='args',
32
- help='The search query')
33
+ parser.add_argument("q", type=str, location="args", help="The search query")
33
34
  # Add filters arguments
34
35
  for name, type in cls.filters.items():
35
36
  kwargs = type.as_request_parser_kwargs()
36
- parser.add_argument(name, location='args', **kwargs)
37
+ parser.add_argument(name, location="args", **kwargs)
37
38
  # Sort arguments
38
39
  keys = list(cls.sorts)
39
- choices = keys + ['-' + k for k in keys]
40
- help_msg = 'The field (and direction) on which sorting apply'
41
- parser.add_argument('sort', type=str, location='args', choices=choices,
42
- help=help_msg)
40
+ choices = keys + ["-" + k for k in keys]
41
+ help_msg = "The field (and direction) on which sorting apply"
42
+ parser.add_argument("sort", type=str, location="args", choices=choices, help=help_msg)
43
43
  if paginate:
44
- parser.add_argument('page', type=int, location='args',
45
- default=1, help='The page to display')
46
- parser.add_argument('page_size', type=int, location='args',
47
- default=20, help='The page size')
44
+ parser.add_argument(
45
+ "page", type=int, location="args", default=1, help="The page to display"
46
+ )
47
+ parser.add_argument(
48
+ "page_size", type=int, location="args", default=20, help="The page size"
49
+ )
48
50
  return parser
49
51
 
50
52
  @classmethod
51
53
  def parse_sort(cls, sort):
52
54
  if sort:
53
- if sort.startswith('-'):
55
+ if sort.startswith("-"):
54
56
  # Keyerror because of the '-' character in front of the argument.
55
57
  # It is removed to find the value in dict and added back.
56
58
  arg_sort = sort[1:]
57
- sort = '-' + cls.sorts[arg_sort]
59
+ sort = "-" + cls.sorts[arg_sort]
58
60
  else:
59
61
  sort = cls.sorts[sort]
60
62
  return sort
61
63
 
62
64
  @classmethod
63
65
  def temp_search(cls):
64
-
65
66
  class TempSearch(SearchQuery):
66
67
  adapter = cls
67
68
  model = cls.model
udata/search/commands.py CHANGED
@@ -1,40 +1,39 @@
1
- from datetime import datetime
2
- from flask import current_app
3
1
  import logging
4
2
  import sys
5
- import requests
3
+ from datetime import datetime
6
4
 
7
5
  import click
6
+ import requests
7
+ from flask import current_app
8
8
 
9
9
  from udata.commands import cli
10
10
  from udata.search import adapter_catalog
11
11
 
12
-
13
12
  log = logging.getLogger(__name__)
14
13
 
15
14
 
16
- @cli.group('search')
15
+ @cli.group("search")
17
16
  def grp():
18
- '''Search/Indexation related operations'''
17
+ """Search/Indexation related operations"""
19
18
  pass
20
19
 
21
20
 
22
- TIMESTAMP_FORMAT = '%Y-%m-%d-%H-%M'
21
+ TIMESTAMP_FORMAT = "%Y-%m-%d-%H-%M"
23
22
 
24
23
 
25
24
  def default_index_suffix_name(now):
26
- '''Build a time based index suffix name'''
25
+ """Build a time based index suffix name"""
27
26
  return now.strftime(TIMESTAMP_FORMAT)
28
27
 
29
28
 
30
29
  def iter_adapters():
31
- '''Iter over adapter in predictable way'''
30
+ """Iter over adapter in predictable way"""
32
31
  adapters = adapter_catalog.values()
33
32
  return sorted(adapters, key=lambda a: a.model.__name__)
34
33
 
35
34
 
36
35
  def iter_qs(qs, adapter):
37
- '''Safely iterate over a DB QuerySet yielding a tuple (indexability, serialized documents)'''
36
+ """Safely iterate over a DB QuerySet yielding a tuple (indexability, serialized documents)"""
38
37
  for obj in qs.no_cache().timeout(False):
39
38
  indexable = adapter.is_indexable(obj)
40
39
  try:
@@ -42,28 +41,25 @@ def iter_qs(qs, adapter):
42
41
  yield indexable, doc
43
42
  except Exception as e:
44
43
  model = adapter.model.__name__
45
- log.error('Unable to index %s "%s": %s', model, str(obj.id),
46
- str(e), exc_info=True)
44
+ log.error('Unable to index %s "%s": %s', model, str(obj.id), str(e), exc_info=True)
47
45
 
48
46
 
49
47
  def index_model(adapter, start, reindex=False, from_datetime=None):
50
- '''Index or unindex all objects given a model'''
48
+ """Index or unindex all objects given a model"""
51
49
  model = adapter.model
52
- search_service_url = current_app.config['SEARCH_SERVICE_API_URL']
53
- log.info('Indexing %s objects', model.__name__)
50
+ search_service_url = current_app.config["SEARCH_SERVICE_API_URL"]
51
+ log.info("Indexing %s objects", model.__name__)
54
52
  qs = model.objects
55
53
  if from_datetime:
56
- date_property = ('last_modified_internal'
57
- if model.__name__.lower() in ['dataset']
58
- else 'last_modified')
59
- qs = qs.filter(**{f'{date_property}__gte': from_datetime})
54
+ date_property = (
55
+ "last_modified_internal" if model.__name__.lower() in ["dataset"] else "last_modified"
56
+ )
57
+ qs = qs.filter(**{f"{date_property}__gte": from_datetime})
60
58
  model_name = adapter.model.__name__.lower()
61
59
  index_name = model_name
62
60
  if reindex:
63
- index_name += '-' + default_index_suffix_name(start)
64
- payload = {
65
- 'index': index_name
66
- }
61
+ index_name += "-" + default_index_suffix_name(start)
62
+ payload = {"index": index_name}
67
63
  url = f"{search_service_url}/create-index"
68
64
  r = requests.post(url, json=payload)
69
65
  r.raise_for_status()
@@ -73,10 +69,7 @@ def index_model(adapter, start, reindex=False, from_datetime=None):
73
69
  with requests.Session() as session:
74
70
  try:
75
71
  if indexable:
76
- payload = {
77
- 'document': doc,
78
- 'index': index_name
79
- }
72
+ payload = {"document": doc, "index": index_name}
80
73
  url = f"{search_service_url}/{model_name}s/index"
81
74
  r = session.post(url, json=payload)
82
75
  r.raise_for_status()
@@ -88,46 +81,46 @@ def index_model(adapter, start, reindex=False, from_datetime=None):
88
81
  else:
89
82
  continue
90
83
  except Exception as e:
91
- log.error('Unable to index %s "%s": %s', model, str(doc['id']),
92
- str(e), exc_info=True)
84
+ log.error(
85
+ 'Unable to index %s "%s": %s', model, str(doc["id"]), str(e), exc_info=True
86
+ )
93
87
 
94
88
 
95
89
  def finalize_reindex(models, start):
96
90
  try:
97
91
  url = f"{current_app.config['SEARCH_SERVICE_API_URL']}/set-index-alias"
98
- payload = {
99
- 'index_suffix_name': default_index_suffix_name(start),
100
- 'indices': models
101
- }
92
+ payload = {"index_suffix_name": default_index_suffix_name(start), "indices": models}
102
93
  r = requests.post(url, json=payload)
103
94
  r.raise_for_status()
104
95
  except Exception:
105
- log.exception(f'Unable to set alias for index')
96
+ log.exception(f"Unable to set alias for index")
106
97
 
107
98
  modified_since_reindex = 0
108
99
  for adapter in iter_adapters():
109
100
  if not models or adapter.model.__name__.lower() in models:
110
- date_property = ('last_modified_internal'
111
- if adapter.model.__name__.lower() in ['dataset']
112
- else 'last_modified')
101
+ date_property = (
102
+ "last_modified_internal"
103
+ if adapter.model.__name__.lower() in ["dataset"]
104
+ else "last_modified"
105
+ )
113
106
  modified_since_reindex += adapter.model.objects(
114
- **{f'{date_property}__gte': start}
107
+ **{f"{date_property}__gte": start}
115
108
  ).count()
116
109
 
117
110
  log.warning(
118
- f'{modified_since_reindex} documents have been modified since reindexation start. '
119
- f'After having set the appropriate alias, you can index last changes since the '
120
- f'beginning of the indexation. Example, you can run:\n'
121
- f'`udata search index -f {default_index_suffix_name(start)}`'
111
+ f"{modified_since_reindex} documents have been modified since reindexation start. "
112
+ f"After having set the appropriate alias, you can index last changes since the "
113
+ f"beginning of the indexation. Example, you can run:\n"
114
+ f"`udata search index -f {default_index_suffix_name(start)}`"
122
115
  )
123
116
 
124
117
 
125
118
  @grp.command()
126
- @click.argument('models', nargs=-1, metavar='[<model> ...]')
127
- @click.option('-r', '--reindex', default=False, type=bool)
128
- @click.option('-f', '--from_datetime', type=str)
119
+ @click.argument("models", nargs=-1, metavar="[<model> ...]")
120
+ @click.option("-r", "--reindex", default=False, type=bool)
121
+ @click.option("-f", "--from_datetime", type=str)
129
122
  def index(models=None, reindex=True, from_datetime=None):
130
- '''
123
+ """
131
124
  Initialize or rebuild the search index
132
125
 
133
126
  Models to reindex can optionally be specified as arguments.
@@ -136,9 +129,9 @@ def index(models=None, reindex=True, from_datetime=None):
136
129
  If reindex is true, indexation will be made on a new index and unindexable documents ignored.
137
130
 
138
131
  If from_datetime is specified, only models modified since this datetime will be indexed.
139
- '''
140
- if not current_app.config['SEARCH_SERVICE_API_URL']:
141
- log.error('Missing URL for search service')
132
+ """
133
+ if not current_app.config["SEARCH_SERVICE_API_URL"]:
134
+ log.error("Missing URL for search service")
142
135
  sys.exit(-1)
143
136
 
144
137
  start = datetime.utcnow()
@@ -146,10 +139,10 @@ def index(models=None, reindex=True, from_datetime=None):
146
139
  from_datetime = datetime.strptime(from_datetime, TIMESTAMP_FORMAT)
147
140
 
148
141
  doc_types_names = [m.__name__.lower() for m in adapter_catalog.keys()]
149
- models = [model.lower().rstrip('s') for model in (models or [])]
142
+ models = [model.lower().rstrip("s") for model in (models or [])]
150
143
  for model in models:
151
144
  if model not in doc_types_names:
152
- log.error('Unknown model %s', model)
145
+ log.error("Unknown model %s", model)
153
146
  sys.exit(-1)
154
147
 
155
148
  for adapter in iter_adapters():
udata/search/fields.py CHANGED
@@ -2,39 +2,36 @@ import logging
2
2
  import re
3
3
 
4
4
  from bson.objectid import ObjectId
5
-
6
5
  from flask_restx import inputs
7
6
 
8
7
  from udata.utils import clean_string
9
8
 
10
9
  log = logging.getLogger(__name__)
11
10
 
12
- __all__ = (
13
- 'BoolFilter', 'ModelTermsFilter', 'TemporalCoverageFilter', 'Filter'
14
- )
11
+ __all__ = ("BoolFilter", "ModelTermsFilter", "TemporalCoverageFilter", "Filter")
15
12
 
16
13
 
17
- ES_NUM_FAILURES = '-Infinity', 'Infinity', 'NaN', None
14
+ ES_NUM_FAILURES = "-Infinity", "Infinity", "NaN", None
18
15
 
19
- RE_TIME_COVERAGE = re.compile(r'\d{4}-\d{2}-\d{2}-\d{4}-\d{2}-\d{2}')
16
+ RE_TIME_COVERAGE = re.compile(r"\d{4}-\d{2}-\d{2}-\d{4}-\d{2}-\d{2}")
20
17
 
21
- OR_SEPARATOR = '|'
18
+ OR_SEPARATOR = "|"
22
19
 
23
20
 
24
21
  class Filter:
25
22
  @staticmethod
26
23
  def as_request_parser_kwargs():
27
- return {'type': clean_string}
24
+ return {"type": clean_string}
28
25
 
29
26
 
30
27
  class BoolFilter(Filter):
31
28
  @staticmethod
32
29
  def as_request_parser_kwargs():
33
- return {'type': inputs.boolean}
30
+ return {"type": inputs.boolean}
34
31
 
35
32
 
36
33
  class ModelTermsFilter(Filter):
37
- def __init__(self, model, field_name='id'):
34
+ def __init__(self, model, field_name="id"):
38
35
  self.model = model
39
36
  self.field_name = field_name
40
37
 
@@ -46,10 +43,7 @@ class ModelTermsFilter(Filter):
46
43
  if isinstance(value, ObjectId):
47
44
  return value
48
45
  try:
49
- return [
50
- self.model_field.to_mongo(v)
51
- for v in value.split(OR_SEPARATOR)
52
- ]
46
+ return [self.model_field.to_mongo(v) for v in value.split(OR_SEPARATOR)]
53
47
  except Exception:
54
48
  raise ValueError('"{0}" is not valid identifier'.format(value))
55
49
 
@@ -57,8 +51,7 @@ class ModelTermsFilter(Filter):
57
51
  class TemporalCoverageFilter(Filter):
58
52
  @classmethod
59
53
  def validate_parameter(cls, value):
60
- if not isinstance(value, str) \
61
- or not RE_TIME_COVERAGE.match(value):
54
+ if not isinstance(value, str) or not RE_TIME_COVERAGE.match(value):
62
55
  msg = '"{0}" does not match YYYY-MM-DD-YYYY-MM-DD'.format(value)
63
56
  raise ValueError(msg)
64
57
  return value
@@ -66,8 +59,8 @@ class TemporalCoverageFilter(Filter):
66
59
  @classmethod
67
60
  def as_request_parser_kwargs(cls):
68
61
  return {
69
- 'type': cls.validate_parameter,
70
- 'help': 'A date range expressed as start-end '
71
- 'where both dates are in iso format '
72
- '(ie. YYYY-MM-DD-YYYY-MM-DD)'
62
+ "type": cls.validate_parameter,
63
+ "help": "A date range expressed as start-end "
64
+ "where both dates are in iso format "
65
+ "(ie. YYYY-MM-DD-YYYY-MM-DD)",
73
66
  }