commonground-api-common 2.2.0__py3-none-any.whl → 2.3.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.
Files changed (45) hide show
  1. commonground_api_common-2.2.0.data/scripts/patch_content_types → commonground_api_common-2.3.0.data/scripts/generate_schema +2 -4
  2. {commonground_api_common-2.2.0.dist-info → commonground_api_common-2.3.0.dist-info}/METADATA +10 -3
  3. {commonground_api_common-2.2.0.dist-info → commonground_api_common-2.3.0.dist-info}/RECORD +25 -38
  4. {commonground_api_common-2.2.0.dist-info → commonground_api_common-2.3.0.dist-info}/WHEEL +1 -1
  5. vng_api_common/__init__.py +1 -1
  6. vng_api_common/api/views.py +1 -0
  7. vng_api_common/apps.py +43 -26
  8. vng_api_common/audittrails/utils.py +44 -0
  9. vng_api_common/conf/api.py +33 -45
  10. vng_api_common/contrib/setup_configuration/models.py +14 -0
  11. vng_api_common/contrib/setup_configuration/steps.py +24 -1
  12. vng_api_common/extensions/file.py +26 -0
  13. vng_api_common/extensions/gegevensgroep.py +16 -0
  14. vng_api_common/extensions/geojson.py +270 -0
  15. vng_api_common/extensions/hyperlink.py +37 -0
  16. vng_api_common/extensions/polymorphic.py +68 -0
  17. vng_api_common/extensions/query.py +20 -0
  18. vng_api_common/filters.py +0 -1
  19. vng_api_common/generators.py +12 -113
  20. vng_api_common/notifications/api/views.py +3 -3
  21. vng_api_common/oas.py +6 -7
  22. vng_api_common/schema.py +414 -158
  23. vng_api_common/views.py +1 -1
  24. commonground_api_common-2.2.0.data/scripts/generate_schema +0 -39
  25. commonground_api_common-2.2.0.data/scripts/use_external_components +0 -16
  26. vng_api_common/inspectors/cache.py +0 -57
  27. vng_api_common/inspectors/fields.py +0 -126
  28. vng_api_common/inspectors/files.py +0 -121
  29. vng_api_common/inspectors/geojson.py +0 -360
  30. vng_api_common/inspectors/polymorphic.py +0 -72
  31. vng_api_common/inspectors/query.py +0 -91
  32. vng_api_common/inspectors/utils.py +0 -40
  33. vng_api_common/inspectors/view.py +0 -547
  34. vng_api_common/management/__init__.py +0 -0
  35. vng_api_common/management/commands/__init__.py +0 -0
  36. vng_api_common/management/commands/generate_autorisaties.py +0 -43
  37. vng_api_common/management/commands/generate_notificaties.py +0 -40
  38. vng_api_common/management/commands/generate_swagger.py +0 -197
  39. vng_api_common/management/commands/patch_error_contenttypes.py +0 -61
  40. vng_api_common/management/commands/use_external_components.py +0 -94
  41. vng_api_common/templates/vng_api_common/api_schema_to_markdown_table.md +0 -16
  42. vng_api_common/templates/vng_api_common/autorisaties.md +0 -15
  43. vng_api_common/templates/vng_api_common/notificaties.md +0 -24
  44. {commonground_api_common-2.2.0.dist-info → commonground_api_common-2.3.0.dist-info}/top_level.txt +0 -0
  45. /vng_api_common/{inspectors → extensions}/__init__.py +0 -0
@@ -9,7 +9,5 @@ if [[ -z "$VIRTUAL_ENV" ]]; then
9
9
  exit 1
10
10
  fi
11
11
 
12
- source_file=${1:-./src/openapi.yaml}
13
- manage=${MANAGE:-src/manage.py}
14
-
15
- python $manage patch_error_contenttypes $source_file
12
+ echo "generate schema"
13
+ src/manage.py spectacular --file src/openapi.yaml --validate
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.2
2
2
  Name: commonground-api-common
3
- Version: 2.2.0
3
+ Version: 2.3.0
4
4
  Summary: Commonground API tooling
5
5
  Home-page: https://github.com/maykinmedia/commonground-api-common
6
6
  Author: Maykin Media, VNG-Realisatie
@@ -25,8 +25,8 @@ Requires-Dist: django-solo
25
25
  Requires-Dist: djangorestframework>=3.15.0
26
26
  Requires-Dist: djangorestframework_camel_case>=1.2.0
27
27
  Requires-Dist: django-rest-framework-condition
28
- Requires-Dist: drf-yasg>=1.20.0
29
28
  Requires-Dist: drf-nested-routers>=0.94.1
29
+ Requires-Dist: drf-spectacular
30
30
  Requires-Dist: iso-639
31
31
  Requires-Dist: isodate
32
32
  Requires-Dist: notifications-api-common>=0.3.1
@@ -40,10 +40,15 @@ Requires-Dist: ape-pie
40
40
  Provides-Extra: markdown-docs
41
41
  Requires-Dist: django-markup<=1.3; extra == "markdown-docs"
42
42
  Requires-Dist: markdown; extra == "markdown-docs"
43
+ Provides-Extra: djangorestframework-gis
44
+ Requires-Dist: djangorestframework-gis>=1.0; extra == "djangorestframework-gis"
45
+ Provides-Extra: drf-extra-fields
46
+ Requires-Dist: drf-extra-fields>=3.7.0; extra == "drf-extra-fields"
43
47
  Provides-Extra: tests
44
48
  Requires-Dist: psycopg2; extra == "tests"
45
49
  Requires-Dist: pytest; extra == "tests"
46
50
  Requires-Dist: pytest-django; extra == "tests"
51
+ Requires-Dist: pytest-dotenv; extra == "tests"
47
52
  Requires-Dist: pytest-factoryboy; extra == "tests"
48
53
  Requires-Dist: tox; extra == "tests"
49
54
  Requires-Dist: isort; extra == "tests"
@@ -51,6 +56,8 @@ Requires-Dist: black; extra == "tests"
51
56
  Requires-Dist: requests-mock; extra == "tests"
52
57
  Requires-Dist: freezegun; extra == "tests"
53
58
  Requires-Dist: zgw-consumers-oas; extra == "tests"
59
+ Requires-Dist: djangorestframework-gis; extra == "tests"
60
+ Requires-Dist: drf-extra-fields; extra == "tests"
54
61
  Provides-Extra: testutils
55
62
  Requires-Dist: zgw-consumers-oas; extra == "testutils"
56
63
  Provides-Extra: setup-configuration
@@ -1,9 +1,7 @@
1
- commonground_api_common-2.2.0.data/scripts/generate_schema,sha256=UKhznmbHX1zUjPx8G3XtxUPQiqnyd3TOIXs27Tnjl7U,952
2
- commonground_api_common-2.2.0.data/scripts/patch_content_types,sha256=dpGpYrZOZe8O5CHWd0F0QnP6Wk_7lK6DyuVZpBPr4mY,319
3
- commonground_api_common-2.2.0.data/scripts/use_external_components,sha256=xvvbngO2aDUagVXv4xRUqPaVtH_eOaVMWLQ8lyAPhEA,369
4
- vng_api_common/__init__.py,sha256=DKk-1b-rZsJFxFi1JoJ7TmEvIEQ0rf-C9HAZWwvjuM0,22
1
+ commonground_api_common-2.3.0.data/scripts/generate_schema,sha256=OpKgzlFc_uzA3TVW_vHSYXAD_feLaCdTEnkWjIcxVzA,280
2
+ vng_api_common/__init__.py,sha256=CpK8IH_dCUAwg9tqv7zm9FxbBFkxCnED1JUiRe7cftU,22
5
3
  vng_api_common/admin.py,sha256=iFtUPGf-ha0I-bXgq8QIFrP23Kzk_H3FlgAjt0U-ip0,259
6
- vng_api_common/apps.py,sha256=wOQuxUImMpH39R0JrDdCZp5ADaUM8jU8vFPFW9froSs,3458
4
+ vng_api_common/apps.py,sha256=14vSvFX2H6alME95uOK9aL5TIWI3reiOW86Qa9kmhNw,3610
7
5
  vng_api_common/checks.py,sha256=tOyfV7MMLGh4anrd_W30LvJCxiyQ4sFs1mGd9mtrEc0,1175
8
6
  vng_api_common/choices.py,sha256=dboFRoM34GpRUpxB9WexexccopcQSogu1QIyY4B9ACY,541
9
7
  vng_api_common/client.py,sha256=HNLc86RwczAudPBDgH_zQncE19OUaLyhSnacQRxJO0c,1972
@@ -15,19 +13,19 @@ vng_api_common/doc.py,sha256=a4Wm6Y-Va-tBsLwZFjPX_oA4PppkDR4wpIiw9q7NLd4,1167
15
13
  vng_api_common/exception_handling.py,sha256=Z8Si1-GPWaTtsgaFI_zLOvlnLVLM8jqfgFIimX8eo-8,4759
16
14
  vng_api_common/exceptions.py,sha256=7Qk5dlETjoQjZeGRKei4PkeLACLoZOMrMiuyi-yn6Kk,615
17
15
  vng_api_common/fields.py,sha256=1911m0CKEU-5-2t_h5P-D2YjC8BGosx8t8FQ-SGfgFw,6335
18
- vng_api_common/filters.py,sha256=77m9s3V6woMqE7uOQoqzit7w1AQpWcGqZozzQFdKAYs,5681
16
+ vng_api_common/filters.py,sha256=oPivwrES1BQgSUg1jD9hJab7dyoO3VbZDVbbRRiW2SQ,5618
19
17
  vng_api_common/filtersets.py,sha256=Ioarp5t_cz6Hf3iIcP2Rc0D7tGYhcMQPVdIJJ2dvtv8,867
20
- vng_api_common/generators.py,sha256=tD7ZyyFgCQ3KiktpBFtn5YiVdl3jioGxzyvkEZFYdQQ,4911
18
+ vng_api_common/generators.py,sha256=88yQN5-vRFUegfzQcsZtlpbtQyn_zZQwvs20OidPK7M,1239
21
19
  vng_api_common/geo.py,sha256=AZbrw0rwGYOmaSUk8JJSkx-4_tVrfT_cgggh9omRwhU,1862
22
20
  vng_api_common/middleware.py,sha256=2DRw0hPpvUMqwoH1Ze8S7tDB16lmj4Bnd6vN5ijkGM8,875
23
21
  vng_api_common/mocks.py,sha256=0sELLs-uy2ndu29m5P6FN_p1ehNhYv7IoRayYPs379Y,6200
24
22
  vng_api_common/models.py,sha256=3WgpCWQpkCOrMCtqp7EbnP681II43Sg_cch8ZOm4EcU,1707
25
- vng_api_common/oas.py,sha256=v_M_nsPRk12VF4lFa3Kw2c-wUThfY8PJ6JlEgeUhz9E,2618
23
+ vng_api_common/oas.py,sha256=ATqqNM7zkDMoK3E-cxNh_c65n6YCrP96KxCFYfkEVK0,2523
26
24
  vng_api_common/pagination.py,sha256=sI6VJ5AHDBhtNRQ8OFrD2heQK-NxaL_6n73ijiqWDLc,255
27
25
  vng_api_common/permissions.py,sha256=ayDxk9Wt8j0yO57FhZ8XaRkPET4lAqd8SSw3m4o3EGs,7562
28
26
  vng_api_common/polymorphism.py,sha256=N-x39pG2unD4N0ZbxFvuhE8ibPaJ0eKeqfvAJW3NnEU,6623
29
27
  vng_api_common/routers.py,sha256=hEnhBulkgMM-7W_lYaykKTgTBj3-avl7DGsR9P7BbTU,1897
30
- vng_api_common/schema.py,sha256=1Bt9dH67AOLpfPNF7Q4IH1cXJeaIevSamZQzJ8DJ7ks,6144
28
+ vng_api_common/schema.py,sha256=axs2Q8IXwpHNd5WscQg5xOErL6bWhP8WFItTt4xCFO4,16305
31
29
  vng_api_common/scopes.py,sha256=PGs6CkXorAAdWXGFY1bSy-jmsPn122Njen9aFFOpFIQ,2351
32
30
  vng_api_common/search.py,sha256=yehS6boCOk1JXLCqAMU-B62hWtbTBSf_WKIVGPgp0Mg,1045
33
31
  vng_api_common/serializers.py,sha256=7_7IotlRfVb0woe6Wy79l_el3sPzrSY8-bfiYLbEUqs,10162
@@ -35,18 +33,19 @@ vng_api_common/urls.py,sha256=9IWHYLlEIIHNaZ_Zq02qNQ2HJpETb7o-89r7yBM_tQs,270
35
33
  vng_api_common/utils.py,sha256=zrtpssOA-NcJHhAlxioBiXeY3G2R_uf0l8oWkDD_EiE,8511
36
34
  vng_api_common/validators.py,sha256=Y1OQrmnH3U01hnCizWc_xjpSSGUWKlwiFxeHHGCThpI,11012
37
35
  vng_api_common/version.py,sha256=yJV9_yTM7Qnzg0zGNkJQkN9Uai3I_ZUkcyseJRPRk5I,129
38
- vng_api_common/views.py,sha256=trsAZjyZt0PRaZOCDvjMJ5xTz4Ic0u4M73k0K_2qS4o,7620
36
+ vng_api_common/views.py,sha256=VnvlpDmzBeSkDB9a-pBUkqBncKO7TT-6bY5zbYP4QOk,7607
39
37
  vng_api_common/viewsets.py,sha256=z5pzvSymFiiuCjP_-uuW-3OJKZY_psPAt8fWeWySU0c,2278
40
38
  vng_api_common/api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
41
39
  vng_api_common/api/permissions.py,sha256=okbwiscxlAtbQWTCRDLL2reOxgj0rRDZeDcrtXAYq00,739
42
40
  vng_api_common/api/serializers.py,sha256=F1od8SZxgIlGVTSd_x5eTxacL6x8HbNn35O9z1zjio4,213
43
41
  vng_api_common/api/urls.py,sha256=Ei-bpoGhZQvcSYx9dY_vh3ESYDaSt0Uqlr6fS0MU46M,167
44
- vng_api_common/api/views.py,sha256=m9wbLVb4oPX-LJWor9oHkZCfxIJjNqpVG43aXeyQ2j4,491
42
+ vng_api_common/api/views.py,sha256=qtgcSFg5oXdaELFT70g6jGkVmBhCcsVoKoItOroi02k,513
45
43
  vng_api_common/audittrails/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
46
44
  vng_api_common/audittrails/admin.py,sha256=mrRK9KhvFlRWcmsq-DM9cJdwtpBUciMa4DvtEIYfirQ,301
47
45
  vng_api_common/audittrails/apps.py,sha256=eM4RMMgqXq_Hm1Il-dUlO0rtXJVP0DgAFQBW25epzdw,111
48
46
  vng_api_common/audittrails/audits.py,sha256=44_vry_9XPZoyKUJeMhhf4xr0OsCndgzGGxRqa65_d0,337
49
47
  vng_api_common/audittrails/models.py,sha256=O1GhyJlZaDYPTwKcZE45J2Fl1q02BGtYciu-QdjzBsQ,3596
48
+ vng_api_common/audittrails/utils.py,sha256=fhDQ-iaSGE8mWkcE9LXySI_pYfn7Xpao-n1m699h_hk,1316
50
49
  vng_api_common/audittrails/viewsets.py,sha256=K0AMPHYU6w_Z1cAww_itzfHjeqzZhIAi1m3cUHcXp30,8105
51
50
  vng_api_common/audittrails/api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
52
51
  vng_api_common/audittrails/api/scopes.py,sha256=fL3PlX284g-mGFlcIzc2UWcyFBNZI6apnnhbFulZN2I,206
@@ -106,31 +105,22 @@ vng_api_common/caching/models.py,sha256=RroS9HFiKNXDV59Odh0x8BO8Az8E81v4gwuprF1A
106
105
  vng_api_common/caching/registry.py,sha256=mY1r99x7m0DQ1BN9lZF2zMjFj_oDNq7urxDkOH7-8Yg,6205
107
106
  vng_api_common/caching/signals.py,sha256=78ej5cVan-JpNHKzZNAfs0m2ON_TXKphe8ZKtP-6FVY,4615
108
107
  vng_api_common/conf/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
109
- vng_api_common/conf/api.py,sha256=bRc488POvBdKeaKVit7s1_LFP-BRLpETmTzcQ6JD614,4372
108
+ vng_api_common/conf/api.py,sha256=Lx3Kk7S7mKxeaUr0dm6jbKrEh4WI2gye4i7QxN2x69E,3150
110
109
  vng_api_common/contrib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
111
110
  vng_api_common/contrib/setup_configuration/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
112
- vng_api_common/contrib/setup_configuration/models.py,sha256=ijV_pGQNCqMrw-XJESlfBbPNHpCBOrLOVqGQQm45Fec,490
113
- vng_api_common/contrib/setup_configuration/steps.py,sha256=OyTiyNatz-ZVgCAX_4h1cm0meVP4faACdLLNmvlpLuM,807
111
+ vng_api_common/contrib/setup_configuration/models.py,sha256=ztev7KDGW0ESLl6jSuLx0tlNV58IOL3ibYEfVmjfv2Y,920
112
+ vng_api_common/contrib/setup_configuration/steps.py,sha256=3jYRdHFlPq5zR-T-SPYTDp_Aipy0JK1HaJFrSgH4Vd0,1680
114
113
  vng_api_common/db/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
115
114
  vng_api_common/db/operations.py,sha256=3vj9zD4EntMSmYsNGN1pRDjAcVM68MESDdoAk9wl0U0,3333
116
- vng_api_common/inspectors/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
117
- vng_api_common/inspectors/cache.py,sha256=6h2ckYd6RGxluPhdXZbxehOQNsb5yrWTMiLknTbZx-E,1890
118
- vng_api_common/inspectors/fields.py,sha256=XgD6K-KKzWVbxKb0kG92bNOsqLuuS_ywjidP359VWDU,3980
119
- vng_api_common/inspectors/files.py,sha256=kedBFCLS0H8lopVgIa7SpBrwXgk6E7Hd8xZT65P0TOE,4385
120
- vng_api_common/inspectors/geojson.py,sha256=Vs6PsY5hY_zlkEko-5nvj_QIO0UKuoSlu2ONpW5Z65s,12575
121
- vng_api_common/inspectors/polymorphic.py,sha256=4U_wjmcBwWCbTPvd0ojFCdmtuyJShy7ORChO2JqKjvs,2627
122
- vng_api_common/inspectors/query.py,sha256=pl_M84BCtgVtBbc_5YtmsImU8c416hYOuDTo91ApFX4,3802
123
- vng_api_common/inspectors/utils.py,sha256=uLyB_Giw7B2flMiBB_HwCpxOs-QcTUIHjHkE0xUmPfo,1481
124
- vng_api_common/inspectors/view.py,sha256=f28MFNqHUE3LSWgYHuJB2PwjRszIAqPU_fBk75Utl3w,20425
115
+ vng_api_common/extensions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
116
+ vng_api_common/extensions/file.py,sha256=tvOiSYbu0CrVKefgO_nOj1af1L0JjShec3VkR-i-IWE,950
117
+ vng_api_common/extensions/gegevensgroep.py,sha256=mfwXpQ8Zq8Tevv_bt28OZqv8a9u6L3yJEKQqXerKzBI,518
118
+ vng_api_common/extensions/geojson.py,sha256=mVqry8F7RQm0YIK3m5scazePB7KprffQy02RNA1FOIE,9217
119
+ vng_api_common/extensions/hyperlink.py,sha256=jadfiQ2vdJ78q-dXo3YOuDgv54zZWm8Y0nzg21aB_HE,1360
120
+ vng_api_common/extensions/polymorphic.py,sha256=Hjzn1VAx3E0Eafb7NctkNQuDYJeh6ln0KHgVNRjHG1s,2768
121
+ vng_api_common/extensions/query.py,sha256=mXxv2aiyP-kHmXUrszHqxEKhAedUugwVJZljQ5nPLcY,585
125
122
  vng_api_common/locale/nl/LC_MESSAGES/django.mo,sha256=w1sFqpNIcpHWbNOFpKjVUmA3idit-Q1SH2wE5h0nXPU,6211
126
123
  vng_api_common/locale/nl/LC_MESSAGES/django.po,sha256=UVAmaSTntaUC73IY4rAN-iT3FoIpLSh4bj-8DyqcwPw,19495
127
- vng_api_common/management/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
128
- vng_api_common/management/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
129
- vng_api_common/management/commands/generate_autorisaties.py,sha256=kMaZQo6e6vCXA9y0e6P2PlxObyjHMyNynRcM4WtzVZI,1130
130
- vng_api_common/management/commands/generate_notificaties.py,sha256=0p7CkLkQo-BeV2IljGv0rcRNw2aWY_HwlvybjggZ_gs,1090
131
- vng_api_common/management/commands/generate_swagger.py,sha256=DyRRSDMFEZeXSJp_PWiMc6vYFK3GPEO4WIRWZV-tlm0,6120
132
- vng_api_common/management/commands/patch_error_contenttypes.py,sha256=xyFIQ4JRutLZCTcLrWqon0FDeAJCw1bkVg4jM8-EM24,2025
133
- vng_api_common/management/commands/use_external_components.py,sha256=FLkhZ5jAIZoAXQWwxqu4yT94LiBJ4GRr6g4ZRp7b_Eg,2936
134
124
  vng_api_common/migrations/0001_initial.py,sha256=frE83rux6uVHK4v-1fsb_1C00TBQQ6koFBA3DoVPHmk,895
135
125
  vng_api_common/migrations/0002_apicredential.py,sha256=AYgkLMizI0g-Ogth8j_FVJHTDDI3bWzQgZzuQeABzaU,1083
136
126
  vng_api_common/migrations/0003_auto_20190417_1145.py,sha256=0ABqDggAdjmZxhSsLrMb2ZBwTcR1BOWo1Tn8StfiG0A,1001
@@ -143,7 +133,7 @@ vng_api_common/notifications/apps.py,sha256=7grk1hxQn5usAWV-sWATmNJ4TwSvT3izXVvV
143
133
  vng_api_common/notifications/handlers.py,sha256=xjuE_qn5h4gbRNGMsTaCTrHIjXTBcF8na6oMURGAuUU,2089
144
134
  vng_api_common/notifications/api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
145
135
  vng_api_common/notifications/api/urls.py,sha256=c1T_6tuRpgN0V80Xg_ehZzGGlF1FNMmHdBEPAjR736I,164
146
- vng_api_common/notifications/api/views.py,sha256=EvppqaANutuOIrkNepavmzFTX6fxo32c6l5c6DKHe8k,2326
136
+ vng_api_common/notifications/api/views.py,sha256=DmeDAJCY-jlwTNZ_YwBSjud04x2ZzAcKMNgCib93IAg,2313
147
137
  vng_api_common/notifications/migrations/0001_initial.py,sha256=zEIVIB--6FStaTl3r9GCXxHL1cSCWRO3T90rEpJr3hY,3049
148
138
  vng_api_common/notifications/migrations/0002_subscription__subscription.py,sha256=eqaj6-FAl7vuCswdvin9Lf8nzjP8U6WqVQO4opNKKCc,550
149
139
  vng_api_common/notifications/migrations/0003_auto_20190319_1048.py,sha256=C-ccYUwQPNCjTctpDDFhnQbm_OcpAlTjYQbEuiEi-ys,987
@@ -178,11 +168,8 @@ vng_api_common/static/vng_api_common/libs/fontawesome/webfonts/fa-solid-900.svg,
178
168
  vng_api_common/static/vng_api_common/libs/fontawesome/webfonts/fa-solid-900.ttf,sha256=elj3Qf9TmvlHmP9WHJGOWEHX5hZOkMvle-_exKFvak4,186444
179
169
  vng_api_common/static/vng_api_common/libs/fontawesome/webfonts/fa-solid-900.woff,sha256=IEZK67_1TMF3dkl85BEsM3SlSzj3ul9Y7sEhdBSdZ0I,96256
180
170
  vng_api_common/static/vng_api_common/libs/fontawesome/webfonts/fa-solid-900.woff2,sha256=8YxIaoAXXPAv7g4FwrSs2GwEzbrs7GHB75H5IFCbXv4,74256
181
- vng_api_common/templates/vng_api_common/api_schema_to_markdown_table.md,sha256=XKs4D32SC4HRdths3jdeloqwfLi3hO2DuLsFDv6-25w,598
182
- vng_api_common/templates/vng_api_common/autorisaties.md,sha256=yGZVwIQwyJ3W3-LqHHUm6vwdSiAxVovtH5WYJVPktvs,402
183
171
  vng_api_common/templates/vng_api_common/index.html,sha256=jZyzxHnZABoTxNFPKbUJGoU6ZJuSeuM8xt2fVr7-hSw,1684
184
172
  vng_api_common/templates/vng_api_common/master.html,sha256=p7xZSpuTaf0cyKU31N5o_1BWwiwEZhLxvte60KMo5v8,3417
185
- vng_api_common/templates/vng_api_common/notificaties.md,sha256=VNQz_CtYGDw24QJxdfkUfOvHvgv9__O072gmQCqh_Pg,856
186
173
  vng_api_common/templates/vng_api_common/view_config.html,sha256=_8OhafH-Y3b_gOl3GukqYbh2G7XXizUdaOrudGWa36U,881
187
174
  vng_api_common/templates/vng_api_common/admin/base_site.html,sha256=mMr_9L7dugHEvULZE0CB18mKdeXs92oPLi1CDgXyqnw,1739
188
175
  vng_api_common/templates/vng_api_common/includes/kanalen_card.html,sha256=jPKpms8cP4MZaHO7_NgBJEhFvvBsGQ3s23x1EUxSw5c,330
@@ -195,7 +182,7 @@ vng_api_common/tests/auth.py,sha256=IKDWTEFv4Bign4F70-ibsFcnJqRxEJaXvqaPQJWa1xY,
195
182
  vng_api_common/tests/caching.py,sha256=zfIw5cRRvO9cekHZZKfRqZc8cx5IfJUYNmcH6cuIMg4,624
196
183
  vng_api_common/tests/schema.py,sha256=WDvifDQQiKqIpQijpeQ7rYkFroJmuPuHe7zNhl1Bigk,2293
197
184
  vng_api_common/tests/urls.py,sha256=PFrYzQbBC0TFPMEn3uPhcBG0IQs9JsEPqckicJT1UA4,2159
198
- commonground_api_common-2.2.0.dist-info/METADATA,sha256=d8TrvWW0ZJTppBzWC6tTB8LRqjwsQAFC7kjuOUWbL9M,6614
199
- commonground_api_common-2.2.0.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
200
- commonground_api_common-2.2.0.dist-info/top_level.txt,sha256=vPismc83zPzWXTmlNCCwfDlFV9iygJYxNJW5iDjKTgw,15
201
- commonground_api_common-2.2.0.dist-info/RECORD,,
185
+ commonground_api_common-2.3.0.dist-info/METADATA,sha256=Ke1dE5k_UQ-0ZdksTJ9aBp_AxOy0ZZh3OxtgTn5AS4k,6988
186
+ commonground_api_common-2.3.0.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
187
+ commonground_api_common-2.3.0.dist-info/top_level.txt,sha256=vPismc83zPzWXTmlNCCwfDlFV9iygJYxNJW5iDjKTgw,15
188
+ commonground_api_common-2.3.0.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.6.0)
2
+ Generator: setuptools (75.8.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1 +1 @@
1
- __version__ = "2.2.0"
1
+ __version__ = "2.3.0"
@@ -7,6 +7,7 @@ from .serializers import JWTSecretSerializer
7
7
 
8
8
 
9
9
  class CreateJWTSecretView(CreateAPIView):
10
+ action = "create"
10
11
  swagger_schema = None
11
12
 
12
13
  model = JWTSecret
vng_api_common/apps.py CHANGED
@@ -1,14 +1,10 @@
1
+ import logging
2
+
1
3
  from django.apps import AppConfig
2
4
  from django.db import models
3
5
  from django.forms.fields import CharField
4
6
  from django.utils.translation import gettext_lazy as _
5
7
 
6
- from drf_yasg import openapi
7
- from drf_yasg.inspectors.field import (
8
- basic_type_info,
9
- model_field_to_basic_type,
10
- serializer_field_to_basic_type,
11
- )
12
8
  from rest_framework import serializers
13
9
 
14
10
  from . import fields
@@ -25,6 +21,8 @@ except ImportError:
25
21
  # is collected somewhere so there's precedent
26
22
  FORMAT_DURATION = "duration"
27
23
 
24
+ logger = logging.getLogger(__name__)
25
+
28
26
 
29
27
  class CommonGroundAPICommonConfig(AppConfig):
30
28
  name = "vng_api_common"
@@ -32,36 +30,21 @@ class CommonGroundAPICommonConfig(AppConfig):
32
30
 
33
31
  def ready(self):
34
32
  from . import checks # noqa
33
+ from . import schema # noqa
35
34
  from .caching import signals # noqa
35
+ from .extensions import gegevensgroep, hyperlink, polymorphic, query # noqa
36
36
 
37
- patch_duration_type()
38
37
  register_serializer_field()
39
38
  set_custom_hyperlinkedmodelserializer_field()
40
39
  set_charfield_error_messages()
41
40
  ensure_text_choice_descriptions(TextChoicesWithDescriptions)
42
-
43
-
44
- def patch_duration_type():
45
- def _patch(basic_types, _field_cls, format=None):
46
- for index, (field_cls, basic_type) in enumerate(basic_types):
47
- if field_cls is _field_cls:
48
- basic_types[index] = (_field_cls, (openapi.TYPE_STRING, format))
49
- break
50
-
51
- _patch(model_field_to_basic_type, models.DurationField, FORMAT_DURATION)
52
- _patch(basic_type_info, models.DurationField, FORMAT_DURATION)
53
- _patch(serializer_field_to_basic_type, serializers.DurationField, FORMAT_DURATION)
54
- _patch(basic_type_info, serializers.DurationField, FORMAT_DURATION)
55
-
56
- # best-effort support for relativedeltafield
57
- if RelativeDeltaField is not None:
58
- _patch(model_field_to_basic_type, RelativeDeltaField, FORMAT_DURATION)
59
- _patch(basic_type_info, RelativeDeltaField, FORMAT_DURATION)
41
+ register_geojson_field_extension()
42
+ register_base64_field_extension()
60
43
 
61
44
 
62
45
  def register_serializer_field():
63
46
  mapping = serializers.ModelSerializer.serializer_field_mapping
64
- mapping[models.fields.DurationField] = DurationField
47
+ mapping[models.DurationField] = DurationField
65
48
  mapping[fields.DaysDurationField] = DurationField
66
49
 
67
50
  if RelativeDeltaField is not None:
@@ -97,3 +80,37 @@ def ensure_text_choice_descriptions(text_choice_class):
97
80
 
98
81
  for cls in text_choice_class.__subclasses__():
99
82
  ensure_text_choice_descriptions(cls)
83
+
84
+
85
+ def register_geojson_field_extension() -> None:
86
+ """
87
+ register GeoJSONGeometry extension only if rest_framework_gis is
88
+ installed
89
+ """
90
+ try:
91
+ from rest_framework_gis.fields import GeometryField # noqa
92
+ except ImportError:
93
+ logger.debug(
94
+ "Could not import djangorestframework-gis, skipping "
95
+ "GeometryFieldExtension registration."
96
+ )
97
+ return
98
+
99
+ from .extensions import geojson # noqa
100
+
101
+
102
+ def register_base64_field_extension() -> None:
103
+ """
104
+ register Base64FileFileFieldExtension extension only if drf_extra_fields is
105
+ installed
106
+ """
107
+ try:
108
+ from drf_extra_fields.fields import Base64FileField # noqa
109
+ except ImportError:
110
+ logger.debug(
111
+ "Could not import drf-extra-fields, skipping "
112
+ "Base64FileFileFieldExtension registration."
113
+ )
114
+ return
115
+
116
+ from .extensions import file # noqa
@@ -0,0 +1,44 @@
1
+ import inspect
2
+ import logging
3
+
4
+ from django.apps import apps
5
+
6
+ from rest_framework import viewsets
7
+
8
+ logger = logging.getLogger(__name__)
9
+
10
+
11
+ AUDIT_TRAIL_ENABLED = apps.is_installed("vng_api_common.audittrails")
12
+
13
+
14
+ def _view_supports_audittrail(view: viewsets.ViewSet) -> bool:
15
+ # moved from vng_api_common.inspectors
16
+ if not AUDIT_TRAIL_ENABLED:
17
+ return False
18
+
19
+ if not hasattr(view, "action"):
20
+ logger.debug("Could not determine view action for view %r", view)
21
+ return False
22
+
23
+ # local imports, since you get errors if you try to import non-installed app
24
+ # models
25
+ from vng_api_common.audittrails.viewsets import AuditTrailMixin
26
+
27
+ relevant_bases = [
28
+ base for base in view.__class__.__bases__ if issubclass(base, AuditTrailMixin)
29
+ ]
30
+ if not relevant_bases:
31
+ return False
32
+
33
+ # check if the view action is listed in any of the audit trail mixins
34
+ action = view.action
35
+ if action == "partial_update": # partial update is self.update(partial=True)
36
+ action = "update"
37
+
38
+ # if the current view action is not provided by any of the audit trail
39
+ # related bases, then it's not audit trail enabled
40
+ action_in_audit_bases = any(
41
+ action in dict(inspect.getmembers(base)) for base in relevant_bases
42
+ )
43
+
44
+ return action_in_audit_bases
@@ -1,7 +1,7 @@
1
1
  __all__ = [
2
2
  "API_VERSION",
3
3
  "BASE_REST_FRAMEWORK",
4
- "BASE_SWAGGER_SETTINGS",
4
+ "BASE_SPECTACULAR_SETTINGS",
5
5
  "COMMON_SPEC",
6
6
  "LINK_FETCHER",
7
7
  "GEMMA_URL_TEMPLATE",
@@ -12,43 +12,30 @@ __all__ = [
12
12
  "NOTIFICATIONS_KANAAL",
13
13
  "NOTIFICATIONS_DISABLED",
14
14
  "JWT_LEEWAY",
15
+ "SECURITY_DEFINITION_NAME",
15
16
  "COMMONGROUND_API_COMMON_GET_DOMAIN",
17
+ "JWT_SPECTACULAR_SETTINGS",
16
18
  ]
17
19
 
18
20
  API_VERSION = "1.0.0-rc1" # semantic version
19
21
 
22
+ SECURITY_DEFINITION_NAME = "JWT-Claims"
23
+
20
24
  BASE_REST_FRAMEWORK = {
25
+ "DEFAULT_SCHEMA_CLASS": "vng_api_common.schema.AutoSchema",
21
26
  "DEFAULT_RENDERER_CLASSES": (
22
27
  "djangorestframework_camel_case.render.CamelCaseJSONRenderer",
23
28
  ),
24
29
  "DEFAULT_PARSER_CLASSES": (
25
30
  "djangorestframework_camel_case.parser.CamelCaseJSONParser",
26
31
  ),
27
- "DEFAULT_AUTHENTICATION_CLASSES": (
28
- # 'oauth2_provider.contrib.rest_framework.OAuth2Authentication',
29
- # 'rest_framework.authentication.SessionAuthentication',
30
- # 'rest_framework.authentication.BasicAuthentication'
31
- ),
32
32
  # there is no authentication of 'end-users', only authorization (via JWT)
33
33
  # of applications
34
34
  "DEFAULT_AUTHENTICATION_CLASSES": (),
35
- # 'DEFAULT_PERMISSION_CLASSES': (
36
- # 'oauth2_provider.contrib.rest_framework.TokenHasReadWriteScope',
37
- # # 'rest_framework.permissions.IsAuthenticated',
38
- # # 'rest_framework.permissions.AllowAny',
39
- # ),
40
35
  "DEFAULT_VERSIONING_CLASS": "rest_framework.versioning.URLPathVersioning",
41
- #
42
- # # Generic view behavior
43
- # 'DEFAULT_PAGINATION_CLASS': 'ztc.api.utils.pagination.HALPagination',
44
- "DEFAULT_FILTER_BACKENDS": (
45
- "vng_api_common.filters.Backend",
46
- # 'rest_framework.filters.SearchFilter',
47
- # 'rest_framework.filters.OrderingFilter',
48
- ),
36
+ "DEFAULT_FILTER_BACKENDS": ("vng_api_common.filters.Backend",),
49
37
  #
50
38
  # # Filtering
51
- # 'SEARCH_PARAM': 'zoek', # 'search',
52
39
  "ORDERING_PARAM": "ordering", # 'ordering',
53
40
  #
54
41
  # Versioning
@@ -60,34 +47,35 @@ BASE_REST_FRAMEWORK = {
60
47
  "EXCEPTION_HANDLER": "vng_api_common.views.exception_handler",
61
48
  "TEST_REQUEST_DEFAULT_FORMAT": "json",
62
49
  }
63
-
64
- BASE_SWAGGER_SETTINGS = {
50
+ BASE_SPECTACULAR_SETTINGS = {
65
51
  "DEFAULT_GENERATOR_CLASS": "vng_api_common.generators.OpenAPISchemaGenerator",
66
- "DEFAULT_AUTO_SCHEMA_CLASS": "vng_api_common.inspectors.view.AutoSchema",
67
- "DEFAULT_INFO": "must.be.overridden",
68
- "DEFAULT_FIELD_INSPECTORS": (
69
- # GeometryFieldInspector has external dependencies, and is opt-in
70
- # 'vng_api_common.inspectors.geojson.GeometryFieldInspector',
71
- "vng_api_common.inspectors.fields.HyperlinkedIdentityFieldInspector",
72
- "vng_api_common.inspectors.fields.ReadOnlyFieldInspector",
73
- "vng_api_common.inspectors.polymorphic.PolymorphicSerializerInspector",
74
- "vng_api_common.inspectors.fields.GegevensGroepInspector",
75
- "drf_yasg.inspectors.CamelCaseJSONFilter",
76
- "drf_yasg.inspectors.RecursiveFieldInspector",
77
- "drf_yasg.inspectors.ReferencingSerializerInspector",
78
- "drf_yasg.inspectors.ChoiceFieldInspector",
79
- "drf_yasg.inspectors.FileFieldInspector",
80
- "drf_yasg.inspectors.DictFieldInspector",
81
- "drf_yasg.inspectors.JSONFieldInspector",
82
- "drf_yasg.inspectors.HiddenFieldInspector",
83
- "drf_yasg.inspectors.RelatedFieldInspector",
84
- "drf_yasg.inspectors.SerializerMethodFieldInspector",
85
- "drf_yasg.inspectors.SimpleFieldInspector",
86
- "drf_yasg.inspectors.StringDefaultFieldInspector",
87
- ),
88
- "DEFAULT_FILTER_INSPECTORS": ("vng_api_common.inspectors.query.FilterInspector",),
52
+ "SERVE_INCLUDE_SCHEMA": False,
53
+ "POSTPROCESSING_HOOKS": [
54
+ "drf_spectacular.hooks.postprocess_schema_enums",
55
+ "drf_spectacular.contrib.djangorestframework_camel_case.camelize_serializer_fields",
56
+ ],
57
+ "SCHEMA_PATH_PREFIX": "/api/v1",
58
+ }
59
+
60
+ # add to SPECTACULAR_SETTINGS if you are using the AuthMiddleware
61
+ JWT_SPECTACULAR_SETTINGS = {
62
+ "APPEND_COMPONENTS": {
63
+ "securitySchemes": {
64
+ SECURITY_DEFINITION_NAME: {
65
+ "type": "http",
66
+ "bearerFormat": "JWT",
67
+ "scheme": "bearer",
68
+ }
69
+ },
70
+ },
71
+ "SECURITY": [
72
+ {
73
+ SECURITY_DEFINITION_NAME: [],
74
+ }
75
+ ],
89
76
  }
90
77
 
78
+
91
79
  REDOC_SETTINGS = {"EXPAND_RESPONSES": "200,201", "SPEC_URL": "openapi.json"}
92
80
 
93
81
  # See: https://github.com/Rebilly/ReDoc#redoc-options-object
@@ -1,6 +1,7 @@
1
1
  from django_setup_configuration.models import ConfigurationModel
2
2
  from pydantic import Field
3
3
 
4
+ from vng_api_common.authorizations.models import Applicatie
4
5
  from vng_api_common.models import JWTSecret
5
6
 
6
7
 
@@ -16,3 +17,16 @@ class SingleJWTSecretConfigurationModel(ConfigurationModel):
16
17
 
17
18
  class JWTSecretsConfigurationModel(ConfigurationModel):
18
19
  items: list[SingleJWTSecretConfigurationModel] = Field(default_factory=list)
20
+
21
+
22
+ class SingleApplicatieConfigurationModel(ConfigurationModel):
23
+ client_ids: list[str]
24
+
25
+ class Meta:
26
+ django_model_refs = {
27
+ Applicatie: ["uuid", "client_ids", "label", "heeft_alle_autorisaties"]
28
+ }
29
+
30
+
31
+ class ApplicatieConfigurationModel(ConfigurationModel):
32
+ items: list[SingleApplicatieConfigurationModel] = Field(default_factory=list)
@@ -1,8 +1,9 @@
1
1
  from django_setup_configuration.configuration import BaseConfigurationStep
2
2
 
3
+ from vng_api_common.authorizations.models import Applicatie
3
4
  from vng_api_common.models import JWTSecret
4
5
 
5
- from .models import JWTSecretsConfigurationModel
6
+ from .models import ApplicatieConfigurationModel, JWTSecretsConfigurationModel
6
7
 
7
8
 
8
9
  class JWTSecretsConfigurationStep(BaseConfigurationStep[JWTSecretsConfigurationModel]):
@@ -21,3 +22,25 @@ class JWTSecretsConfigurationStep(BaseConfigurationStep[JWTSecretsConfigurationM
21
22
  identifier=config.identifier,
22
23
  defaults={"secret": config.secret},
23
24
  )
25
+
26
+
27
+ class ApplicatieConfigurationStep(BaseConfigurationStep[ApplicatieConfigurationModel]):
28
+ """
29
+ Configure Applicatie used for authorization
30
+ """
31
+
32
+ verbose_name = "Configuration to create applicaties"
33
+ config_model = ApplicatieConfigurationModel
34
+ namespace = "vng_api_common_applicaties"
35
+ enable_setting = "vng_api_common_applicaties_config_enable"
36
+
37
+ def execute(self, model: ApplicatieConfigurationModel):
38
+ for config in model.items:
39
+ Applicatie.objects.update_or_create(
40
+ uuid=config.uuid,
41
+ defaults={
42
+ "client_ids": config.client_ids,
43
+ "label": config.label,
44
+ "heeft_alle_autorisaties": config.heeft_alle_autorisaties,
45
+ },
46
+ )
@@ -0,0 +1,26 @@
1
+ from django.utils.translation import gettext_lazy as _
2
+
3
+ from drf_spectacular.extensions import OpenApiSerializerFieldExtension
4
+ from drf_spectacular.openapi import OpenApiTypes
5
+ from drf_spectacular.plumbing import build_basic_type
6
+
7
+
8
+ class Base64FileFileFieldExtension(OpenApiSerializerFieldExtension):
9
+ target_class = "drf_extra_fields.fields.Base64FileField"
10
+ match_subclasses = True
11
+
12
+ def map_serializer_field(self, auto_schema, direction):
13
+ base64_schema = {
14
+ **build_basic_type(OpenApiTypes.BYTE),
15
+ "description": _("Base64 encoded binary content."),
16
+ }
17
+
18
+ uri_schema = {
19
+ **build_basic_type(OpenApiTypes.URI),
20
+ "description": _("Download URL of the binary content."),
21
+ }
22
+
23
+ if direction == "request":
24
+ return base64_schema
25
+ elif direction == "response":
26
+ return uri_schema if not self.target.represent_in_base64 else base64_schema
@@ -0,0 +1,16 @@
1
+ from drf_spectacular.extensions import OpenApiSerializerExtension
2
+ from drf_spectacular.openapi import AutoSchema
3
+
4
+
5
+ class GegevensGroepFieldExtension(OpenApiSerializerExtension):
6
+ target_class = "vng_api_common.serializers.GegevensGroepSerializer"
7
+ match_subclasses = True
8
+
9
+ def map_serializer(self, auto_schema: AutoSchema, direction):
10
+ schema = auto_schema._map_serializer(
11
+ self.target, direction, bypass_extensions=True
12
+ )
13
+
14
+ del schema["description"]
15
+
16
+ return schema