devpi-server 6.17.0__tar.gz → 6.19.0__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 (145) hide show
  1. {devpi_server-6.17.0 → devpi_server-6.19.0}/.flake8 +0 -1
  2. {devpi_server-6.17.0 → devpi_server-6.19.0}/CHANGELOG +60 -0
  3. {devpi_server-6.17.0 → devpi_server-6.19.0}/CHANGELOG.short.rst +60 -48
  4. {devpi_server-6.17.0 → devpi_server-6.19.0}/PKG-INFO +62 -49
  5. devpi_server-6.19.0/devpi_server/__init__.py +1 -0
  6. {devpi_server-6.17.0 → devpi_server-6.19.0}/devpi_server/__main__.py +1 -0
  7. {devpi_server-6.17.0 → devpi_server-6.19.0}/devpi_server/auth.py +23 -11
  8. devpi_server-6.19.0/devpi_server/compat.py +35 -0
  9. {devpi_server-6.17.0 → devpi_server-6.19.0}/devpi_server/config.py +152 -53
  10. {devpi_server-6.17.0 → devpi_server-6.19.0}/devpi_server/exceptions.py +10 -4
  11. {devpi_server-6.17.0 → devpi_server-6.19.0}/devpi_server/filestore.py +144 -59
  12. devpi_server-6.19.0/devpi_server/filestore_db.py +82 -0
  13. devpi_server-6.19.0/devpi_server/filestore_fs.py +178 -0
  14. devpi_server-6.19.0/devpi_server/filestore_fs_base.py +329 -0
  15. devpi_server-6.19.0/devpi_server/filestore_hash_hl.py +232 -0
  16. {devpi_server-6.17.0 → devpi_server-6.19.0}/devpi_server/fileutil.py +30 -18
  17. {devpi_server-6.17.0 → devpi_server-6.19.0}/devpi_server/fsck.py +9 -10
  18. {devpi_server-6.17.0 → devpi_server-6.19.0}/devpi_server/genconfig.py +21 -18
  19. {devpi_server-6.17.0 → devpi_server-6.19.0}/devpi_server/hookspecs.py +9 -0
  20. devpi_server-6.19.0/devpi_server/htmlpage.py +73 -0
  21. {devpi_server-6.17.0 → devpi_server-6.19.0}/devpi_server/httpclient.py +37 -18
  22. {devpi_server-6.17.0 → devpi_server-6.19.0}/devpi_server/importexport.py +147 -113
  23. devpi_server-6.19.0/devpi_server/interfaces.py +569 -0
  24. {devpi_server-6.17.0 → devpi_server-6.19.0}/devpi_server/keyfs.py +201 -39
  25. {devpi_server-6.17.0 → devpi_server-6.19.0}/devpi_server/keyfs_sqlite.py +43 -21
  26. devpi_server-6.19.0/devpi_server/keyfs_sqlite_fs.py +47 -0
  27. devpi_server-6.19.0/devpi_server/keyfs_types.py +302 -0
  28. {devpi_server-6.17.0 → devpi_server-6.19.0}/devpi_server/main.py +37 -33
  29. {devpi_server-6.17.0 → devpi_server-6.19.0}/devpi_server/mirror.py +265 -130
  30. {devpi_server-6.17.0 → devpi_server-6.19.0}/devpi_server/model.py +322 -164
  31. {devpi_server-6.17.0 → devpi_server-6.19.0}/devpi_server/mythread.py +1 -0
  32. devpi_server-6.19.0/devpi_server/normalized.py +29 -0
  33. {devpi_server-6.17.0 → devpi_server-6.19.0}/devpi_server/readonly.py +35 -10
  34. {devpi_server-6.17.0 → devpi_server-6.19.0}/devpi_server/replica.py +248 -90
  35. {devpi_server-6.17.0 → devpi_server-6.19.0}/devpi_server/sizeof.py +13 -6
  36. {devpi_server-6.17.0 → devpi_server-6.19.0}/devpi_server/view_auth.py +16 -10
  37. {devpi_server-6.17.0 → devpi_server-6.19.0}/devpi_server/views.py +91 -43
  38. {devpi_server-6.17.0 → devpi_server-6.19.0}/devpi_server.egg-info/PKG-INFO +62 -49
  39. {devpi_server-6.17.0 → devpi_server-6.19.0}/devpi_server.egg-info/SOURCES.txt +7 -3
  40. {devpi_server-6.17.0 → devpi_server-6.19.0}/devpi_server.egg-info/entry_points.txt +0 -3
  41. {devpi_server-6.17.0 → devpi_server-6.19.0}/devpi_server.egg-info/requires.txt +3 -0
  42. {devpi_server-6.17.0 → devpi_server-6.19.0}/mypy.ini +59 -25
  43. {devpi_server-6.17.0 → devpi_server-6.19.0}/pyproject.toml +8 -128
  44. devpi_server-6.19.0/pytest_devpi_server/__init__.py +11 -0
  45. devpi_server-6.19.0/test_devpi_server/example.py +25 -0
  46. {devpi_server-6.17.0 → devpi_server-6.19.0}/test_devpi_server/functional.py +65 -6
  47. {devpi_server-6.17.0 → devpi_server-6.19.0}/test_devpi_server/plugin.py +193 -72
  48. {devpi_server-6.17.0 → devpi_server-6.19.0}/test_devpi_server/simpypi.py +9 -1
  49. {devpi_server-6.17.0 → devpi_server-6.19.0}/test_devpi_server/test_auth.py +56 -1
  50. {devpi_server-6.17.0 → devpi_server-6.19.0}/test_devpi_server/test_config.py +35 -3
  51. {devpi_server-6.17.0 → devpi_server-6.19.0}/test_devpi_server/test_conftest.py +1 -0
  52. {devpi_server-6.17.0 → devpi_server-6.19.0}/test_devpi_server/test_filestore.py +121 -49
  53. devpi_server-6.19.0/test_devpi_server/test_filestore_fs.py +180 -0
  54. {devpi_server-6.17.0 → devpi_server-6.19.0}/test_devpi_server/test_importexport.py +69 -37
  55. {devpi_server-6.17.0 → devpi_server-6.19.0}/test_devpi_server/test_keyfs.py +123 -49
  56. {devpi_server-6.17.0 → devpi_server-6.19.0}/test_devpi_server/test_log.py +6 -5
  57. {devpi_server-6.17.0 → devpi_server-6.19.0}/test_devpi_server/test_main.py +9 -6
  58. {devpi_server-6.17.0 → devpi_server-6.19.0}/test_devpi_server/test_mirror.py +140 -35
  59. {devpi_server-6.17.0 → devpi_server-6.19.0}/test_devpi_server/test_mirror_no_project_list.py +4 -2
  60. {devpi_server-6.17.0 → devpi_server-6.19.0}/test_devpi_server/test_model.py +156 -74
  61. {devpi_server-6.17.0 → devpi_server-6.19.0}/test_devpi_server/test_mythread.py +0 -1
  62. {devpi_server-6.17.0 → devpi_server-6.19.0}/test_devpi_server/test_permissions.py +6 -1
  63. {devpi_server-6.17.0 → devpi_server-6.19.0}/test_devpi_server/test_replica.py +160 -41
  64. devpi_server-6.19.0/test_devpi_server/test_replica_functional.py +180 -0
  65. {devpi_server-6.17.0 → devpi_server-6.19.0}/test_devpi_server/test_stage_customizer.py +21 -6
  66. {devpi_server-6.17.0 → devpi_server-6.19.0}/test_devpi_server/test_view_auth.py +3 -0
  67. {devpi_server-6.17.0 → devpi_server-6.19.0}/test_devpi_server/test_views.py +53 -26
  68. {devpi_server-6.17.0 → devpi_server-6.19.0}/test_devpi_server/test_views_patch.py +55 -0
  69. {devpi_server-6.17.0 → devpi_server-6.19.0}/test_devpi_server/test_views_status.py +6 -2
  70. {devpi_server-6.17.0 → devpi_server-6.19.0}/tox.ini +16 -3
  71. devpi_server-6.17.0/devpi_server/__init__.py +0 -1
  72. devpi_server-6.17.0/devpi_server/filestore_fs.py +0 -136
  73. devpi_server-6.17.0/devpi_server/interfaces.py +0 -289
  74. devpi_server-6.17.0/devpi_server/keyfs_sqlite_fs.py +0 -227
  75. devpi_server-6.17.0/devpi_server/keyfs_types.py +0 -144
  76. devpi_server-6.17.0/devpi_server/vendor/_pip.py +0 -152
  77. devpi_server-6.17.0/pytest_devpi_server/__init__.py +0 -4
  78. devpi_server-6.17.0/test_devpi_server/__init__.py +0 -0
  79. devpi_server-6.17.0/test_devpi_server/example.py +0 -22
  80. devpi_server-6.17.0/test_devpi_server/test_keyfs_sqlite_fs.py +0 -71
  81. devpi_server-6.17.0/test_devpi_server/test_replica_functional.py +0 -98
  82. {devpi_server-6.17.0 → devpi_server-6.19.0}/LICENSE +0 -0
  83. {devpi_server-6.17.0 → devpi_server-6.19.0}/MANIFEST.in +0 -0
  84. {devpi_server-6.17.0 → devpi_server-6.19.0}/README.rst +0 -0
  85. {devpi_server-6.17.0 → devpi_server-6.19.0}/devpi_server/auth_basic.py +0 -0
  86. {devpi_server-6.17.0 → devpi_server-6.19.0}/devpi_server/auth_devpi.py +0 -0
  87. {devpi_server-6.17.0 → devpi_server-6.19.0}/devpi_server/cfg/__init__.py +0 -0
  88. {devpi_server-6.17.0 → devpi_server-6.19.0}/devpi_server/cfg/crontab.template +0 -0
  89. {devpi_server-6.17.0 → devpi_server-6.19.0}/devpi_server/cfg/devpi.service.template +0 -0
  90. {devpi_server-6.17.0 → devpi_server-6.19.0}/devpi_server/cfg/launchd-macos.txt.template +0 -0
  91. {devpi_server-6.17.0 → devpi_server-6.19.0}/devpi_server/cfg/nginx-devpi-caching-http.conf.template +0 -0
  92. {devpi_server-6.17.0 → devpi_server-6.19.0}/devpi_server/cfg/nginx-devpi-caching-location.conf.template +0 -0
  93. {devpi_server-6.17.0 → devpi_server-6.19.0}/devpi_server/cfg/nginx-devpi-caching-proxy.conf.template +0 -0
  94. {devpi_server-6.17.0 → devpi_server-6.19.0}/devpi_server/cfg/nginx-devpi-caching-server.conf.template +0 -0
  95. {devpi_server-6.17.0 → devpi_server-6.19.0}/devpi_server/cfg/nginx-devpi.conf.template +0 -0
  96. {devpi_server-6.17.0 → devpi_server-6.19.0}/devpi_server/cfg/supervisor-devpi.conf.template +0 -0
  97. {devpi_server-6.17.0 → devpi_server-6.19.0}/devpi_server/cfg/supervisord.conf.template +0 -0
  98. {devpi_server-6.17.0 → devpi_server-6.19.0}/devpi_server/cfg/windows-service.txt.template +0 -0
  99. {devpi_server-6.17.0 → devpi_server-6.19.0}/devpi_server/init.py +0 -0
  100. {devpi_server-6.17.0 → devpi_server-6.19.0}/devpi_server/log.py +0 -0
  101. {devpi_server-6.17.0 → devpi_server-6.19.0}/devpi_server/markers.py +0 -0
  102. {devpi_server-6.17.0 → devpi_server-6.19.0}/devpi_server/middleware.py +0 -0
  103. {devpi_server-6.17.0 → devpi_server-6.19.0}/devpi_server/passwd.py +0 -0
  104. {devpi_server-6.17.0 → devpi_server-6.19.0}/devpi_server/py.typed +0 -0
  105. {devpi_server-6.17.0 → devpi_server-6.19.0}/devpi_server.egg-info/dependency_links.txt +0 -0
  106. {devpi_server-6.17.0 → devpi_server-6.19.0}/devpi_server.egg-info/top_level.txt +0 -0
  107. {devpi_server-6.17.0 → devpi_server-6.19.0}/setup.cfg +0 -0
  108. {devpi_server-6.17.0/devpi_server/vendor → devpi_server-6.19.0/test_devpi_server}/__init__.py +0 -0
  109. {devpi_server-6.17.0 → devpi_server-6.19.0}/test_devpi_server/conftest.py +0 -0
  110. {devpi_server-6.17.0 → devpi_server-6.19.0}/test_devpi_server/importexportdata/badindexname/dataindex.json +0 -0
  111. {devpi_server-6.17.0 → devpi_server-6.19.0}/test_devpi_server/importexportdata/badusername/dataindex.json +0 -0
  112. {devpi_server-6.17.0 → devpi_server-6.19.0}/test_devpi_server/importexportdata/basescycle/dataindex.json +0 -0
  113. {devpi_server-6.17.0 → devpi_server-6.19.0}/test_devpi_server/importexportdata/createdmodified/dataindex.json +0 -0
  114. {devpi_server-6.17.0 → devpi_server-6.19.0}/test_devpi_server/importexportdata/deletedbase/dataindex.json +0 -0
  115. {devpi_server-6.17.0 → devpi_server-6.19.0}/test_devpi_server/importexportdata/mirrordata/dataindex.json +0 -0
  116. {devpi_server-6.17.0 → devpi_server-6.19.0}/test_devpi_server/importexportdata/mirrordata/root/pypi/dddttt/0.1.dev1/dddttt-0.1.dev1.tar.gz +0 -0
  117. {devpi_server-6.17.0 → devpi_server-6.19.0}/test_devpi_server/importexportdata/modifiedpypi/dataindex.json +0 -0
  118. {devpi_server-6.17.0 → devpi_server-6.19.0}/test_devpi_server/importexportdata/nocreatedmodified/dataindex.json +0 -0
  119. {devpi_server-6.17.0 → devpi_server-6.19.0}/test_devpi_server/importexportdata/normalization/dataindex.json +0 -0
  120. {devpi_server-6.17.0 → devpi_server-6.19.0}/test_devpi_server/importexportdata/normalization/root/dev/hello.pkg/hello.pkg-1.0.tar.gz +0 -0
  121. {devpi_server-6.17.0 → devpi_server-6.19.0}/test_devpi_server/importexportdata/normalization_merge/dataindex.json +0 -0
  122. {devpi_server-6.17.0 → devpi_server-6.19.0}/test_devpi_server/importexportdata/normalization_merge/root/dev/hello-pkg/hello.pkg-1.1.tar.gz +0 -0
  123. {devpi_server-6.17.0 → devpi_server-6.19.0}/test_devpi_server/importexportdata/normalization_merge/root/dev/hello.pkg/hello.pkg-1.0.tar.gz +0 -0
  124. {devpi_server-6.17.0 → devpi_server-6.19.0}/test_devpi_server/importexportdata/norootpypi/dataindex.json +0 -0
  125. {devpi_server-6.17.0 → devpi_server-6.19.0}/test_devpi_server/importexportdata/nouser/dataindex.json +0 -0
  126. {devpi_server-6.17.0 → devpi_server-6.19.0}/test_devpi_server/importexportdata/removedindexplugin/dataindex.json +0 -0
  127. {devpi_server-6.17.0 → devpi_server-6.19.0}/test_devpi_server/importexportdata/removedindexplugin/user/dev/pkg/pkg-1.0.tar.gz +0 -0
  128. {devpi_server-6.17.0 → devpi_server-6.19.0}/test_devpi_server/importexportdata/toxresult_naming_scheme/dataindex.json +0 -0
  129. {devpi_server-6.17.0 → devpi_server-6.19.0}/test_devpi_server/importexportdata/toxresult_naming_scheme/root/dev/hello/0.9/hello-0.9.tar.gz +0 -0
  130. {devpi_server-6.17.0 → devpi_server-6.19.0}/test_devpi_server/importexportdata/toxresult_naming_scheme/root/dev/hello/sha256=ed7002b439e9ac845f22357d822bac1444730fbdb6016d3ec9432297b9ec9f73/hello-0.9.tar.gz.toxresult0 +0 -0
  131. {devpi_server-6.17.0 → devpi_server-6.19.0}/test_devpi_server/importexportdata/toxresult_upload_default/dataindex.json +0 -0
  132. {devpi_server-6.17.0 → devpi_server-6.19.0}/test_devpi_server/py.typed +0 -0
  133. {devpi_server-6.17.0 → devpi_server-6.19.0}/test_devpi_server/reqmock.py +0 -0
  134. {devpi_server-6.17.0 → devpi_server-6.19.0}/test_devpi_server/test_authcheck.py +0 -0
  135. {devpi_server-6.17.0 → devpi_server-6.19.0}/test_devpi_server/test_fileutil.py +1 -1
  136. {devpi_server-6.17.0 → devpi_server-6.19.0}/test_devpi_server/test_fsck.py +0 -0
  137. {devpi_server-6.17.0 → devpi_server-6.19.0}/test_devpi_server/test_genconfig.py +1 -1
  138. {devpi_server-6.17.0 → devpi_server-6.19.0}/test_devpi_server/test_nginx.py +0 -0
  139. {devpi_server-6.17.0 → devpi_server-6.19.0}/test_devpi_server/test_nginx_replica.py +3 -3
  140. {devpi_server-6.17.0 → devpi_server-6.19.0}/test_devpi_server/test_readonly.py +0 -0
  141. {devpi_server-6.17.0 → devpi_server-6.19.0}/test_devpi_server/test_streaming.py +0 -0
  142. {devpi_server-6.17.0 → devpi_server-6.19.0}/test_devpi_server/test_streaming_nginx.py +1 -1
  143. {devpi_server-6.17.0 → devpi_server-6.19.0}/test_devpi_server/test_streaming_replica.py +1 -1
  144. {devpi_server-6.17.0 → devpi_server-6.19.0}/test_devpi_server/test_streaming_replica_nginx.py +1 -1
  145. {devpi_server-6.17.0 → devpi_server-6.19.0}/test_devpi_server/test_views_push_external.py +0 -0
@@ -3,7 +3,6 @@
3
3
  ignore = E203,E501,E704,E741,W503
4
4
  per-file-ignores =
5
5
  plugin.py:E127,E128,E231
6
- importexport.py:E127
7
6
  model.py:E128,E231
8
7
  test_importexport.py:E121
9
8
  test*.py:E126,E127,E128,E225,E226,E231,E251
@@ -2,6 +2,66 @@
2
2
 
3
3
  .. towncrier release notes start
4
4
 
5
+ 6.19.0 (2026-02-06)
6
+ ===================
7
+
8
+ Features
9
+ --------
10
+
11
+ - Add ``--autocreate-users`` server option.
12
+ Automatically creates users that don't exist in devpi, but have successfully authenticated via an authentication plugin.
13
+ A typical example of when to enable this would be when authenticating via an LDAP directory.
14
+ Automatically created users do not have passwords, and have no password hash to prevent local authentication.
15
+
16
+ - Add ``replica-files-in-sync-at``, ``replica-init-queue-finished-at`` and ``replica-metadata-in-sync-at`` to status view, the existing ``replica-in-sync-at`` is now a combination of all three instead of just metadata.
17
+
18
+ - Warn when an unknown option is found in config file to detect typos. Be aware that some commands don't use all the options, that is why this only warns instead of exiting.
19
+
20
+ - Add new ``devpiserver_user_created`` hook which can be used to create default indexes or other setup for newly created users.
21
+
22
+ Bug Fixes
23
+ ---------
24
+
25
+ - Fix ``+status`` json encoding errors by making sure the ``FatalResponse.url`` attribute is a string.
26
+
27
+ - Ignore existing unknown index options from uninstalled plugins when patching other options with ``+=`` and ``-=``.
28
+
29
+ - Fix removal with ``-=`` of index options with default values from ``devpiserver_indexconfig_defaults`` hooks.
30
+
31
+ - Fix #1110: a list for the ``listen`` option in a config file stopped working in 6.18.0.
32
+
33
+
34
+ 6.18.0 (2026-01-27)
35
+ ===================
36
+
37
+ Features
38
+ --------
39
+
40
+ - Store all available hashes of files.
41
+
42
+ - Validate hashes of all files during devpi-import, not only releases.
43
+
44
+ Bug Fixes
45
+ ---------
46
+
47
+ - Apply argparse transformations on values read from config file or environment.
48
+
49
+ - Restore Python and platform info in user agent string after switch to httpx.
50
+
51
+ - Remove all database entries on project deletion instead of only emptying them.
52
+
53
+ - Fix error at end of replica streaming caused by changed behavior from switch to httpx.
54
+
55
+ - Fix #1102: The data stream was cut off after 64k when proxying from replica to primary after switching to httpx.
56
+
57
+ - Fix #1107: retry file downloads if there has been an error during download.
58
+
59
+ Other Changes
60
+ -------------
61
+
62
+ - The filenames of some exported doczip files change due to normalization of the project name caused by changing the internals during export to allow ``--hard-links`` to work.
63
+
64
+
5
65
  6.17.0 (2025-08-27)
6
66
  ===================
7
67
 
@@ -9,6 +9,66 @@ Changelog
9
9
 
10
10
  .. towncrier release notes start
11
11
 
12
+ 6.19.0 (2026-02-06)
13
+ ===================
14
+
15
+ Features
16
+ --------
17
+
18
+ - Add ``--autocreate-users`` server option.
19
+ Automatically creates users that don't exist in devpi, but have successfully authenticated via an authentication plugin.
20
+ A typical example of when to enable this would be when authenticating via an LDAP directory.
21
+ Automatically created users do not have passwords, and have no password hash to prevent local authentication.
22
+
23
+ - Add ``replica-files-in-sync-at``, ``replica-init-queue-finished-at`` and ``replica-metadata-in-sync-at`` to status view, the existing ``replica-in-sync-at`` is now a combination of all three instead of just metadata.
24
+
25
+ - Warn when an unknown option is found in config file to detect typos. Be aware that some commands don't use all the options, that is why this only warns instead of exiting.
26
+
27
+ - Add new ``devpiserver_user_created`` hook which can be used to create default indexes or other setup for newly created users.
28
+
29
+ Bug Fixes
30
+ ---------
31
+
32
+ - Fix ``+status`` json encoding errors by making sure the ``FatalResponse.url`` attribute is a string.
33
+
34
+ - Ignore existing unknown index options from uninstalled plugins when patching other options with ``+=`` and ``-=``.
35
+
36
+ - Fix removal with ``-=`` of index options with default values from ``devpiserver_indexconfig_defaults`` hooks.
37
+
38
+ - Fix #1110: a list for the ``listen`` option in a config file stopped working in 6.18.0.
39
+
40
+
41
+ 6.18.0 (2026-01-27)
42
+ ===================
43
+
44
+ Features
45
+ --------
46
+
47
+ - Store all available hashes of files.
48
+
49
+ - Validate hashes of all files during devpi-import, not only releases.
50
+
51
+ Bug Fixes
52
+ ---------
53
+
54
+ - Apply argparse transformations on values read from config file or environment.
55
+
56
+ - Restore Python and platform info in user agent string after switch to httpx.
57
+
58
+ - Remove all database entries on project deletion instead of only emptying them.
59
+
60
+ - Fix error at end of replica streaming caused by changed behavior from switch to httpx.
61
+
62
+ - Fix #1102: The data stream was cut off after 64k when proxying from replica to primary after switching to httpx.
63
+
64
+ - Fix #1107: retry file downloads if there has been an error during download.
65
+
66
+ Other Changes
67
+ -------------
68
+
69
+ - The filenames of some exported doczip files change due to normalization of the project name caused by changing the internals during export to allow ``--hard-links`` to work.
70
+
71
+
12
72
  6.17.0 (2025-08-27)
13
73
  ===================
14
74
 
@@ -86,51 +146,3 @@ Features
86
146
 
87
147
  - Add ``--connection-limit`` option to devpi-server passed on to waitress.
88
148
 
89
-
90
- 6.14.0 (2024-10-16)
91
- ===================
92
-
93
- Features
94
- --------
95
-
96
- - Allow pushing of versions which only have documentation and no releases.
97
-
98
- - Allow pushing of release files only with no documentation. Requires devpi-client 7.2.0.
99
-
100
- - Allow pushing of documentation only with no release files. Requires devpi-client 7.2.0.
101
-
102
- Bug Fixes
103
- ---------
104
-
105
- - No longer automatically "register" a project when pushing releases to PyPI. The reply changed from HTTP status 410 to 400 breaking the upload. With devpi-client 7.2.0 there is a ``--register-project`` option if it is still required for some other package registry.
106
-
107
-
108
- 6.13.0 (2024-09-19)
109
- ===================
110
-
111
- Deprecations and Removals
112
- -------------------------
113
-
114
- - Remove/Deprecate "master" related terminology in favor of "primary".
115
- Usage related changes are the switch to ``--primary-url`` instead of ``--master-url`` and ``--role=primary`` instead of ``--role=master``.
116
- Using the old terms will now output warnings.
117
- The ``+status`` API has additional fields and the ``role`` field content will change with 7.0.0.
118
-
119
- Features
120
- --------
121
-
122
- - Enable logging command line options for all commands.
123
-
124
- - Added support uv pip as an installer.
125
-
126
- Bug Fixes
127
- ---------
128
-
129
- - Don't report on lagging event processing while replicating.
130
-
131
- - Report primary serial correctly with streaming replication.
132
-
133
- - Don't store file data in memory when fetching a release while pushing from a mirror.
134
-
135
- - Only warn about replica not being in sync instead of fatal status while still replicating.
136
-
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: devpi-server
3
- Version: 6.17.0
3
+ Version: 6.19.0
4
4
  Summary: devpi-server: reliable, private, and pypi.org caching server
5
5
  Maintainer-email: Florian Schulze <mail@pyfidelity.com>
6
6
  License-Expression: MIT
@@ -42,6 +42,7 @@ Requires-Dist: pluggy<2.0,>=0.6.0
42
42
  Requires-Dist: py>=1.4.23
43
43
  Requires-Dist: pyramid>=2
44
44
  Requires-Dist: repoze.lru>=0.6
45
+ Requires-Dist: strenum; python_version < "3.11"
45
46
  Requires-Dist: strictyaml
46
47
  Requires-Dist: waitress>=1.0.1
47
48
  Requires-Dist: ruamel.yaml
@@ -121,6 +122,66 @@ Changelog
121
122
 
122
123
  .. towncrier release notes start
123
124
 
125
+ 6.19.0 (2026-02-06)
126
+ ===================
127
+
128
+ Features
129
+ --------
130
+
131
+ - Add ``--autocreate-users`` server option.
132
+ Automatically creates users that don't exist in devpi, but have successfully authenticated via an authentication plugin.
133
+ A typical example of when to enable this would be when authenticating via an LDAP directory.
134
+ Automatically created users do not have passwords, and have no password hash to prevent local authentication.
135
+
136
+ - Add ``replica-files-in-sync-at``, ``replica-init-queue-finished-at`` and ``replica-metadata-in-sync-at`` to status view, the existing ``replica-in-sync-at`` is now a combination of all three instead of just metadata.
137
+
138
+ - Warn when an unknown option is found in config file to detect typos. Be aware that some commands don't use all the options, that is why this only warns instead of exiting.
139
+
140
+ - Add new ``devpiserver_user_created`` hook which can be used to create default indexes or other setup for newly created users.
141
+
142
+ Bug Fixes
143
+ ---------
144
+
145
+ - Fix ``+status`` json encoding errors by making sure the ``FatalResponse.url`` attribute is a string.
146
+
147
+ - Ignore existing unknown index options from uninstalled plugins when patching other options with ``+=`` and ``-=``.
148
+
149
+ - Fix removal with ``-=`` of index options with default values from ``devpiserver_indexconfig_defaults`` hooks.
150
+
151
+ - Fix #1110: a list for the ``listen`` option in a config file stopped working in 6.18.0.
152
+
153
+
154
+ 6.18.0 (2026-01-27)
155
+ ===================
156
+
157
+ Features
158
+ --------
159
+
160
+ - Store all available hashes of files.
161
+
162
+ - Validate hashes of all files during devpi-import, not only releases.
163
+
164
+ Bug Fixes
165
+ ---------
166
+
167
+ - Apply argparse transformations on values read from config file or environment.
168
+
169
+ - Restore Python and platform info in user agent string after switch to httpx.
170
+
171
+ - Remove all database entries on project deletion instead of only emptying them.
172
+
173
+ - Fix error at end of replica streaming caused by changed behavior from switch to httpx.
174
+
175
+ - Fix #1102: The data stream was cut off after 64k when proxying from replica to primary after switching to httpx.
176
+
177
+ - Fix #1107: retry file downloads if there has been an error during download.
178
+
179
+ Other Changes
180
+ -------------
181
+
182
+ - The filenames of some exported doczip files change due to normalization of the project name caused by changing the internals during export to allow ``--hard-links`` to work.
183
+
184
+
124
185
  6.17.0 (2025-08-27)
125
186
  ===================
126
187
 
@@ -198,51 +259,3 @@ Features
198
259
 
199
260
  - Add ``--connection-limit`` option to devpi-server passed on to waitress.
200
261
 
201
-
202
- 6.14.0 (2024-10-16)
203
- ===================
204
-
205
- Features
206
- --------
207
-
208
- - Allow pushing of versions which only have documentation and no releases.
209
-
210
- - Allow pushing of release files only with no documentation. Requires devpi-client 7.2.0.
211
-
212
- - Allow pushing of documentation only with no release files. Requires devpi-client 7.2.0.
213
-
214
- Bug Fixes
215
- ---------
216
-
217
- - No longer automatically "register" a project when pushing releases to PyPI. The reply changed from HTTP status 410 to 400 breaking the upload. With devpi-client 7.2.0 there is a ``--register-project`` option if it is still required for some other package registry.
218
-
219
-
220
- 6.13.0 (2024-09-19)
221
- ===================
222
-
223
- Deprecations and Removals
224
- -------------------------
225
-
226
- - Remove/Deprecate "master" related terminology in favor of "primary".
227
- Usage related changes are the switch to ``--primary-url`` instead of ``--master-url`` and ``--role=primary`` instead of ``--role=master``.
228
- Using the old terms will now output warnings.
229
- The ``+status`` API has additional fields and the ``role`` field content will change with 7.0.0.
230
-
231
- Features
232
- --------
233
-
234
- - Enable logging command line options for all commands.
235
-
236
- - Added support uv pip as an installer.
237
-
238
- Bug Fixes
239
- ---------
240
-
241
- - Don't report on lagging event processing while replicating.
242
-
243
- - Report primary serial correctly with streaming replication.
244
-
245
- - Don't store file data in memory when fetching a release while pushing from a mirror.
246
-
247
- - Only warn about replica not being in sync instead of fatal status while still replicating.
248
-
@@ -0,0 +1 @@
1
+ __version__ = "6.19.0"
@@ -1,4 +1,5 @@
1
1
  import devpi_server.main
2
2
 
3
+
3
4
  if __name__ == "__main__":
4
5
  devpi_server.main.main()
@@ -24,6 +24,7 @@ class Auth:
24
24
  self.serializer = itsdangerous.TimedSerializer(secret)
25
25
  self.hook = xom.config.hook.devpiserver_auth_request
26
26
  self.legacy_hook = xom.config.hook.devpiserver_auth_user
27
+ self.autocreate_users = xom.config.autocreate_users
27
28
 
28
29
  @property
29
30
  def model(self):
@@ -55,18 +56,27 @@ class Auth:
55
56
  return dict(status="ok", groups=sorted(
56
57
  set(itertools.chain.from_iterable(groups))))
57
58
 
58
- def _validate(self, authuser, authpassword, request=None):
59
- """ Validates user credentials.
60
-
61
- If authentication plugins are installed, they will be queried.
59
+ def _autocreate_user(self, authuser):
60
+ if self.model.get_user(authuser) is None:
61
+ # Autocreated users will be authenticated via plugin, and so no
62
+ # valid password should be stored.
63
+ self.model.create_user(authuser, password=None)
64
+ threadlog.debug("automatically created user %r", authuser)
62
65
 
63
- If no user can be found, returns None.
64
- If the credentials are wrong, returns False.
65
- On success a list of group names the user is member of will be
66
- returned. If the plugins don't return any groups, then the list
67
- will be empty.
68
- The 'root' user is always authenticated with the devpi-server
69
- credentials, never by plugins.
66
+ def _validate(self, authuser, authpassword, request=None):
67
+ """Validates user credentials.
68
+
69
+ If authentication plugins are installed, they will be queried.
70
+
71
+ If no user can be found, returns None.
72
+ If the credentials are wrong, returns False.
73
+ On success a list of group names the user is member of will be
74
+ returned. If the plugins don't return any groups, then the list
75
+ will be empty.
76
+ If autocreate-users is enabled, the new user is created, if it
77
+ doesn't already exist.
78
+ The 'root' user is always authenticated with the devpi-server
79
+ credentials, never by plugins.
70
80
  """
71
81
  user = self.model.get_user(authuser)
72
82
  is_root = authuser == 'root'
@@ -77,6 +87,8 @@ class Auth:
77
87
  if result is not None:
78
88
  if result["status"] != "ok":
79
89
  return dict(status="reject")
90
+ if self.autocreate_users:
91
+ self._autocreate_user(authuser)
80
92
  # plugins may never return from_user_object
81
93
  result.pop('from_user_object', None)
82
94
  return result
@@ -0,0 +1,35 @@
1
+ try:
2
+ from enum import StrEnum
3
+ except ImportError:
4
+ from strenum import StrEnum # noqa: F401
5
+ from tempfile import SpooledTemporaryFile
6
+
7
+
8
+ # before Python 3.11 some methods were missing
9
+ if not hasattr(SpooledTemporaryFile, "readable"):
10
+
11
+ def readable(self):
12
+ return self._file.readable()
13
+
14
+ SpooledTemporaryFile.readable = readable # type: ignore[method-assign]
15
+
16
+ if not hasattr(SpooledTemporaryFile, "readinto"):
17
+
18
+ def readinto(self, buffer):
19
+ return self._file.readinto(buffer)
20
+
21
+ SpooledTemporaryFile.readinto = readinto # type: ignore[attr-defined]
22
+
23
+ if not hasattr(SpooledTemporaryFile, "seekable"):
24
+
25
+ def seekable(self):
26
+ return self._file.seekable()
27
+
28
+ SpooledTemporaryFile.seekable = seekable # type: ignore[method-assign]
29
+
30
+ if not hasattr(SpooledTemporaryFile, "writable"):
31
+
32
+ def writable(self):
33
+ return self._file.writable()
34
+
35
+ SpooledTemporaryFile.writable = writable # type: ignore[method-assign]