django-pfx 1.2.dev32__tar.gz → 1.2.dev36__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. {django-pfx-1.2.dev32 → django-pfx-1.2.dev36}/PKG-INFO +1 -1
  2. {django-pfx-1.2.dev32 → django-pfx-1.2.dev36}/django_pfx.egg-info/PKG-INFO +1 -1
  3. {django-pfx-1.2.dev32 → django-pfx-1.2.dev36}/django_pfx.egg-info/SOURCES.txt +4 -0
  4. {django-pfx-1.2.dev32 → django-pfx-1.2.dev36}/django_pfx.egg-info/requires.txt +1 -0
  5. django-pfx-1.2.dev36/pfx/pfxcore/default_settings.py +9 -0
  6. django-pfx-1.2.dev36/pfx/pfxcore/management/commands/makeapidoc.py +33 -0
  7. {django-pfx-1.2.dev32 → django-pfx-1.2.dev36}/pfx/pfxcore/settings.py +2 -2
  8. {django-pfx-1.2.dev32 → django-pfx-1.2.dev36}/pfx/pfxcore/views/rest_views.py +8 -2
  9. {django-pfx-1.2.dev32 → django-pfx-1.2.dev36}/requirements.txt +1 -0
  10. {django-pfx-1.2.dev32 → django-pfx-1.2.dev36}/setup.cfg +1 -0
  11. django-pfx-1.2.dev36/tests/__init__.py +0 -0
  12. django-pfx-1.2.dev36/tests/settings/__init__.py +0 -0
  13. {django-pfx-1.2.dev32 → django-pfx-1.2.dev36}/tests/tests/__init__.py +1 -0
  14. django-pfx-1.2.dev36/tests/tests/test_api_doc.py +47 -0
  15. django-pfx-1.2.dev32/pfx/pfxcore/default_settings.py +0 -8
  16. {django-pfx-1.2.dev32 → django-pfx-1.2.dev36}/.gitignore +0 -0
  17. {django-pfx-1.2.dev32 → django-pfx-1.2.dev36}/.gitlab-ci.yml +0 -0
  18. {django-pfx-1.2.dev32 → django-pfx-1.2.dev36}/.pre-commit-config.yaml +0 -0
  19. {django-pfx-1.2.dev32 → django-pfx-1.2.dev36}/LICENSE +0 -0
  20. {django-pfx-1.2.dev32 → django-pfx-1.2.dev36}/MANIFEST.in +0 -0
  21. {django-pfx-1.2.dev32 → django-pfx-1.2.dev36}/README.md +0 -0
  22. {django-pfx-1.2.dev32 → django-pfx-1.2.dev36}/django_pfx.egg-info/dependency_links.txt +0 -0
  23. {django-pfx-1.2.dev32 → django-pfx-1.2.dev36}/django_pfx.egg-info/top_level.txt +0 -0
  24. {django-pfx-1.2.dev32 → django-pfx-1.2.dev36}/img/pfx.png +0 -0
  25. {django-pfx-1.2.dev32 → django-pfx-1.2.dev36}/img/pfx.svg +0 -0
  26. {django-pfx-1.2.dev32 → django-pfx-1.2.dev36}/pfx/__init__.py +0 -0
  27. {django-pfx-1.2.dev32 → django-pfx-1.2.dev36}/pfx/pfxcore/__init__.py +0 -0
  28. {django-pfx-1.2.dev32 → django-pfx-1.2.dev36}/pfx/pfxcore/apps.py +0 -0
  29. {django-pfx-1.2.dev32 → django-pfx-1.2.dev36}/pfx/pfxcore/decorator/__init__.py +0 -0
  30. {django-pfx-1.2.dev32 → django-pfx-1.2.dev36}/pfx/pfxcore/decorator/rest.py +0 -0
  31. {django-pfx-1.2.dev32 → django-pfx-1.2.dev36}/pfx/pfxcore/exceptions.py +0 -0
  32. {django-pfx-1.2.dev32 → django-pfx-1.2.dev36}/pfx/pfxcore/fields.py +0 -0
  33. {django-pfx-1.2.dev32 → django-pfx-1.2.dev36}/pfx/pfxcore/http/__init__.py +0 -0
  34. {django-pfx-1.2.dev32 → django-pfx-1.2.dev36}/pfx/pfxcore/http/json_response.py +0 -0
  35. {django-pfx-1.2.dev32 → django-pfx-1.2.dev36}/pfx/pfxcore/locale/fr/LC_MESSAGES/django.mo +0 -0
  36. {django-pfx-1.2.dev32 → django-pfx-1.2.dev36}/pfx/pfxcore/locale/fr/LC_MESSAGES/django.po +0 -0
  37. {django-pfx-1.2.dev32/pfx/pfxcore/serializers → django-pfx-1.2.dev36/pfx/pfxcore/management}/__init__.py +0 -0
  38. {django-pfx-1.2.dev32/tests → django-pfx-1.2.dev36/pfx/pfxcore/management/commands}/__init__.py +0 -0
  39. {django-pfx-1.2.dev32 → django-pfx-1.2.dev36}/pfx/pfxcore/middleware/__init__.py +0 -0
  40. {django-pfx-1.2.dev32 → django-pfx-1.2.dev36}/pfx/pfxcore/middleware/authentication.py +0 -0
  41. {django-pfx-1.2.dev32 → django-pfx-1.2.dev36}/pfx/pfxcore/middleware/locale.py +0 -0
  42. {django-pfx-1.2.dev32 → django-pfx-1.2.dev36}/pfx/pfxcore/models/__init__.py +0 -0
  43. {django-pfx-1.2.dev32 → django-pfx-1.2.dev36}/pfx/pfxcore/models/cache_mixins.py +0 -0
  44. {django-pfx-1.2.dev32 → django-pfx-1.2.dev36}/pfx/pfxcore/models/not_null_fields.py +0 -0
  45. {django-pfx-1.2.dev32 → django-pfx-1.2.dev36}/pfx/pfxcore/models/pfx_models.py +0 -0
  46. {django-pfx-1.2.dev32 → django-pfx-1.2.dev36}/pfx/pfxcore/models/user_filtered_queryset_mixin.py +0 -0
  47. {django-pfx-1.2.dev32/tests/settings → django-pfx-1.2.dev36/pfx/pfxcore/serializers}/__init__.py +0 -0
  48. {django-pfx-1.2.dev32 → django-pfx-1.2.dev36}/pfx/pfxcore/serializers/json.py +0 -0
  49. {django-pfx-1.2.dev32 → django-pfx-1.2.dev36}/pfx/pfxcore/shortcuts.py +0 -0
  50. {django-pfx-1.2.dev32 → django-pfx-1.2.dev36}/pfx/pfxcore/storage/__init__.py +0 -0
  51. {django-pfx-1.2.dev32 → django-pfx-1.2.dev36}/pfx/pfxcore/storage/s3_storage.py +0 -0
  52. {django-pfx-1.2.dev32 → django-pfx-1.2.dev36}/pfx/pfxcore/templates/registration/password_reset_email.txt +0 -0
  53. {django-pfx-1.2.dev32 → django-pfx-1.2.dev36}/pfx/pfxcore/templates/registration/password_reset_subject.txt +0 -0
  54. {django-pfx-1.2.dev32 → django-pfx-1.2.dev36}/pfx/pfxcore/templates/registration/welcome_email.txt +0 -0
  55. {django-pfx-1.2.dev32 → django-pfx-1.2.dev36}/pfx/pfxcore/templates/registration/welcome_subject.txt +0 -0
  56. {django-pfx-1.2.dev32 → django-pfx-1.2.dev36}/pfx/pfxcore/test.py +0 -0
  57. {django-pfx-1.2.dev32 → django-pfx-1.2.dev36}/pfx/pfxcore/urls.py +0 -0
  58. {django-pfx-1.2.dev32 → django-pfx-1.2.dev36}/pfx/pfxcore/views/__init__.py +0 -0
  59. {django-pfx-1.2.dev32 → django-pfx-1.2.dev36}/pfx/pfxcore/views/authentication_views.py +0 -0
  60. {django-pfx-1.2.dev32 → django-pfx-1.2.dev36}/pfx/pfxcore/views/fields.py +0 -0
  61. {django-pfx-1.2.dev32 → django-pfx-1.2.dev36}/pfx/pfxcore/views/filters_views.py +0 -0
  62. {django-pfx-1.2.dev32 → django-pfx-1.2.dev36}/pfx/pfxcore/views/locale_views.py +0 -0
  63. {django-pfx-1.2.dev32 → django-pfx-1.2.dev36}/pyproject.toml +0 -0
  64. {django-pfx-1.2.dev32 → django-pfx-1.2.dev36}/runtest.py +0 -0
  65. {django-pfx-1.2.dev32 → django-pfx-1.2.dev36}/setup.py +0 -0
  66. {django-pfx-1.2.dev32 → django-pfx-1.2.dev36}/tests/models.py +0 -0
  67. {django-pfx-1.2.dev32 → django-pfx-1.2.dev36}/tests/settings/ci.py +0 -0
  68. {django-pfx-1.2.dev32 → django-pfx-1.2.dev36}/tests/settings/common.py +0 -0
  69. {django-pfx-1.2.dev32 → django-pfx-1.2.dev36}/tests/settings/dev.py +0 -0
  70. {django-pfx-1.2.dev32 → django-pfx-1.2.dev36}/tests/settings/dev_custom_example.py +0 -0
  71. {django-pfx-1.2.dev32 → django-pfx-1.2.dev36}/tests/settings/dev_default.py +0 -0
  72. {django-pfx-1.2.dev32 → django-pfx-1.2.dev36}/tests/tests/basic_api_errors.py +0 -0
  73. {django-pfx-1.2.dev32 → django-pfx-1.2.dev36}/tests/tests/basic_api_test.py +0 -0
  74. {django-pfx-1.2.dev32 → django-pfx-1.2.dev36}/tests/tests/test_auth_api.py +0 -0
  75. {django-pfx-1.2.dev32 → django-pfx-1.2.dev36}/tests/tests/test_cache.py +0 -0
  76. {django-pfx-1.2.dev32 → django-pfx-1.2.dev36}/tests/tests/test_fields.py +0 -0
  77. {django-pfx-1.2.dev32 → django-pfx-1.2.dev36}/tests/tests/test_filters.py +0 -0
  78. {django-pfx-1.2.dev32 → django-pfx-1.2.dev36}/tests/tests/test_locale_api.py +0 -0
  79. {django-pfx-1.2.dev32 → django-pfx-1.2.dev36}/tests/tests/test_perm_tests.py +0 -0
  80. {django-pfx-1.2.dev32 → django-pfx-1.2.dev36}/tests/tests/test_perms_api.py +0 -0
  81. {django-pfx-1.2.dev32 → django-pfx-1.2.dev36}/tests/tests/test_shortcuts.py +0 -0
  82. {django-pfx-1.2.dev32 → django-pfx-1.2.dev36}/tests/tests/test_timezone_middleware.py +0 -0
  83. {django-pfx-1.2.dev32 → django-pfx-1.2.dev36}/tests/tests/test_tools.py +0 -0
  84. {django-pfx-1.2.dev32 → django-pfx-1.2.dev36}/tests/tests/test_user_queryset.py +0 -0
  85. {django-pfx-1.2.dev32 → django-pfx-1.2.dev36}/tests/tests/test_view_decorators.py +0 -0
  86. {django-pfx-1.2.dev32 → django-pfx-1.2.dev36}/tests/tests/test_view_fields.py +0 -0
  87. {django-pfx-1.2.dev32 → django-pfx-1.2.dev36}/tests/urls.py +0 -0
  88. {django-pfx-1.2.dev32 → django-pfx-1.2.dev36}/tests/views.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: django-pfx
3
- Version: 1.2.dev32
3
+ Version: 1.2.dev36
4
4
  Summary: Django PFX is a toolkit to build web APIs dedicated to be used by React progressive web app.
5
5
  Author: Hervé Martinet
6
6
  Author-email: herve.martinet@gmail.com
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: django-pfx
3
- Version: 1.2.dev32
3
+ Version: 1.2.dev36
4
4
  Summary: Django PFX is a toolkit to build web APIs dedicated to be used by React progressive web app.
5
5
  Author: Hervé Martinet
6
6
  Author-email: herve.martinet@gmail.com
@@ -32,6 +32,9 @@ pfx/pfxcore/http/__init__.py
32
32
  pfx/pfxcore/http/json_response.py
33
33
  pfx/pfxcore/locale/fr/LC_MESSAGES/django.mo
34
34
  pfx/pfxcore/locale/fr/LC_MESSAGES/django.po
35
+ pfx/pfxcore/management/__init__.py
36
+ pfx/pfxcore/management/commands/__init__.py
37
+ pfx/pfxcore/management/commands/makeapidoc.py
35
38
  pfx/pfxcore/middleware/__init__.py
36
39
  pfx/pfxcore/middleware/authentication.py
37
40
  pfx/pfxcore/middleware/locale.py
@@ -67,6 +70,7 @@ tests/settings/dev_default.py
67
70
  tests/tests/__init__.py
68
71
  tests/tests/basic_api_errors.py
69
72
  tests/tests/basic_api_test.py
73
+ tests/tests/test_api_doc.py
70
74
  tests/tests/test_auth_api.py
71
75
  tests/tests/test_cache.py
72
76
  tests/tests/test_fields.py
@@ -4,3 +4,4 @@ django_json_widget
4
4
  pyjwt>=2.1
5
5
  Babel
6
6
  boto3
7
+ apispec
@@ -0,0 +1,9 @@
1
+ PFX_TOKEN_SHORT_VALIDITY = {'hours': 12}
2
+ PFX_TOKEN_LONG_VALIDITY = {'days': 30}
3
+
4
+ PFX_COOKIE_DOMAIN = None
5
+ PFX_COOKIE_SECURE = True
6
+ PFX_COOKIE_SAMESITE = 'None'
7
+
8
+ PFX_OPENAPI_PATH = "doc/api/openapi.json"
9
+ PFX_OPENAPI_TEMPLATE = {}
@@ -0,0 +1,33 @@
1
+ import json
2
+ from pathlib import Path
3
+
4
+ from django.core.management.base import BaseCommand
5
+
6
+ from apispec import APISpec
7
+
8
+ from pfx.pfxcore.settings import PFXSettings
9
+
10
+ settings = PFXSettings()
11
+ DEFAULT_TEMPLATE = dict(
12
+ title="PFX API",
13
+ version="1.0.0",
14
+ openapi_version="3.0.2")
15
+
16
+
17
+ def get_spec():
18
+ return APISpec(**{**DEFAULT_TEMPLATE, **settings.PFX_OPENAPI_TEMPLATE})
19
+
20
+
21
+ class Command(BaseCommand):
22
+ help = 'Generate OpenAPI documentation'
23
+
24
+ def handle(self, *args, **options):
25
+ spec = get_spec()
26
+
27
+ path = Path(settings.PFX_OPENAPI_PATH)
28
+ path.parent.mkdir(parents=True, exist_ok=True)
29
+ with open(path, "w") as outfile:
30
+ json.dump(spec.to_dict(), outfile, indent=2)
31
+
32
+ self.stdout.write(self.style.SUCCESS(
33
+ f"OpenAPI documentation generated: {path}"))
@@ -1,6 +1,6 @@
1
1
  from django.conf import settings
2
2
 
3
- from .default_settings import default_settings
3
+ from . import default_settings
4
4
 
5
5
 
6
6
  class PFXSettings:
@@ -8,4 +8,4 @@ class PFXSettings:
8
8
  try:
9
9
  return getattr(settings, attr)
10
10
  except AttributeError:
11
- return default_settings[attr]
11
+ return getattr(default_settings, attr)
@@ -551,7 +551,7 @@ class BaseRestView(SecuredRestViewMixin, View):
551
551
  process, path.lstrip('/').split('/'))
552
552
 
553
553
  @classmethod
554
- def as_urlpatterns(cls):
554
+ def get_urls(cls, as_pattern=False):
555
555
  def fullpath(p2):
556
556
  return f'{cls.rest_view_path}{p2}'.lstrip('/')
557
557
 
@@ -568,11 +568,17 @@ class BaseRestView(SecuredRestViewMixin, View):
568
568
  "you cannot set different priority for same path")
569
569
  methods['priority'] = m.rest_api_priority
570
570
  return [
571
- path(fullpath(p), cls.as_view(pfx_methods=ms))
571
+ path(fullpath(p), cls.as_view(pfx_methods=ms)) if as_pattern
572
+ else dict(path=fullpath(p), methods={
573
+ k: v for k, v in ms.items() if k != 'priority'})
572
574
  for p, ms in sorted(
573
575
  paths.items(), key=lambda e: cls._path_order(*e),
574
576
  reverse=True)]
575
577
 
578
+ @classmethod
579
+ def as_urlpatterns(cls):
580
+ return cls.get_urls(as_pattern=True)
581
+
576
582
 
577
583
  class RestView(
578
584
  ListRestViewMixin,
@@ -10,3 +10,4 @@ pyjwt>=2.1
10
10
  boto3
11
11
  build
12
12
  freezegun
13
+ apispec
@@ -35,6 +35,7 @@ install_requires =
35
35
  pyjwt>=2.1
36
36
  Babel
37
37
  boto3
38
+ apispec
38
39
 
39
40
  [options.packages.find]
40
41
  exclude =
File without changes
File without changes
@@ -1,5 +1,6 @@
1
1
  from .basic_api_errors import BasicAPIErrorTest
2
2
  from .basic_api_test import BasicAPITest
3
+ from .test_api_doc import ApiDocTest
3
4
  from .test_auth_api import AuthAPITest
4
5
  from .test_cache import TestCache
5
6
  from .test_fields import FieldsTest
@@ -0,0 +1,47 @@
1
+ from django.test import TestCase, override_settings
2
+
3
+ from pfx.pfxcore.management.commands.makeapidoc import get_spec
4
+ from pfx.pfxcore.test import TestAssertMixin
5
+ from tests.views import AuthorRestView
6
+
7
+
8
+ class ApiDocTest(TestAssertMixin, TestCase):
9
+ def test_default_generation(self):
10
+ spec = get_spec().to_dict()
11
+ self.assertEqual(spec['openapi'], "3.0.2")
12
+ info = spec['info']
13
+ self.assertEqual(info['title'], "PFX API")
14
+ self.assertEqual(info['version'], "1.0.0")
15
+
16
+ @override_settings(PFX_OPENAPI_TEMPLATE=dict(
17
+ title="MyAPI",
18
+ info=dict(description="A test API")))
19
+ def test_default_customized_generation(self):
20
+ spec = get_spec().to_dict()
21
+ self.assertEqual(spec['openapi'], "3.0.2")
22
+ info = spec['info']
23
+ self.assertEqual(info['title'], "MyAPI")
24
+ self.assertEqual(info['version'], "1.0.0")
25
+ self.assertEqual(info['description'], "A test API")
26
+
27
+ def test_view_get_urls(self):
28
+ def get_methods(url, p):
29
+ return next(filter(lambda u: u['path'] == p, urls))['methods']
30
+
31
+ urls = AuthorRestView.get_urls()
32
+
33
+ # Methods from RestView
34
+ self.assertEqual(
35
+ get_methods(urls, 'authors'),
36
+ dict(get='get_list', post='post'))
37
+ self.assertEqual(
38
+ get_methods(urls, 'authors/<int:id>'),
39
+ dict(delete='delete', get='get', put='put'))
40
+ # A method from SlugDetailRestViewMixin
41
+ self.assertEqual(
42
+ get_methods(urls, 'authors/slug/<slug:slug>'),
43
+ dict(get='get_by_slug'))
44
+ # A method from AuthorRestView itself
45
+ self.assertEqual(
46
+ get_methods(urls, 'authors/cache/<int:id>'),
47
+ dict(get='cache_get'))
@@ -1,8 +0,0 @@
1
- default_settings = dict(
2
- PFX_TOKEN_SHORT_VALIDITY={'hours': 12},
3
- PFX_TOKEN_LONG_VALIDITY={'days': 30},
4
-
5
- PFX_COOKIE_DOMAIN=None,
6
- PFX_COOKIE_SECURE=True,
7
- PFX_COOKIE_SAMESITE='None',
8
- )
File without changes
File without changes
File without changes