proper 0.1.dev4__tar.gz → 0.2__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 (412) hide show
  1. proper-0.2/PKG-INFO +131 -0
  2. {proper-0.1.dev4 → proper-0.2}/README.md +7 -9
  3. proper-0.2/pyproject.toml +222 -0
  4. proper-0.2/setup.cfg +4 -0
  5. proper-0.2/src/blueprints/app/[[ app_name ]]/__init__.py +5 -0
  6. proper-0.2/src/blueprints/app/[[ app_name ]]/app.py +8 -0
  7. proper-0.2/src/blueprints/app/[[ app_name ]]/cl/__init__.tt.py +5 -0
  8. proper-0.2/src/blueprints/app/[[ app_name ]]/config/app.tt.py +52 -0
  9. proper-0.2/src/blueprints/app/[[ app_name ]]/config/database.tt.py +40 -0
  10. proper-0.2/src/blueprints/app/[[ app_name ]]/config/session.py +13 -0
  11. proper-0.2/src/blueprints/app/[[ app_name ]]/config/storage.py +8 -0
  12. proper-0.2/src/blueprints/app/[[ app_name ]]/initializers/1_app.tt.py +25 -0
  13. proper-0.2/src/blueprints/app/[[ app_name ]]/initializers/2_database.py +22 -0
  14. proper-0.2/src/blueprints/app/[[ app_name ]]/initializers/__init__.py +10 -0
  15. proper-0.2/src/blueprints/app/[[ app_name ]]/initializers/error_handlers.py +15 -0
  16. proper-0.2/src/blueprints/app/[[ app_name ]]/mailers/mailer.py +11 -0
  17. proper-0.2/src/blueprints/app/[[ app_name ]]/models/__init__.py +5 -0
  18. proper-0.2/src/blueprints/app/[[ app_name ]]/models/base.py +20 -0
  19. {proper-0.1.dev4/blueprints/project/[[ app_name ]]/services → proper-0.2/src/blueprints/app/[[ app_name ]]/models/concerns}/__init__.py +0 -0
  20. proper-0.2/src/blueprints/app/[[ app_name ]]/models/concerns/timestamped.tt.py +14 -0
  21. proper-0.2/src/blueprints/app/[[ app_name ]]/routes.py +37 -0
  22. proper-0.2/src/blueprints/app/[[ app_name ]]/views/__init__.py +23 -0
  23. proper-0.2/src/blueprints/app/[[ app_name ]]/views/app.tt.py +13 -0
  24. {proper-0.1.dev4/blueprints/project/db/migrations → proper-0.2/src/blueprints/app/[[ app_name ]]/views/concerns}/__init__.py +0 -0
  25. proper-0.2/src/blueprints/app/[[ app_name ]]/views/concerns/db_connection.tt.py +12 -0
  26. proper-0.2/src/blueprints/app/[[ app_name ]]/views/concerns/security_headers.py +26 -0
  27. proper-0.2/src/blueprints/app/[[ app_name ]]/views/page.py +12 -0
  28. {proper-0.1.dev4/blueprints/project → proper-0.2/src/blueprints/app}/tests/conftest.py +1 -0
  29. proper-0.2/src/blueprints/app/wsgi.tt.py +1 -0
  30. proper-0.2/src/blueprints/auth/[[ app_name ]]/app.append.py +1 -0
  31. proper-0.2/src/blueprints/auth/[[ app_name ]]/cl/__init__.append.py +3 -0
  32. proper-0.2/src/blueprints/auth/[[ app_name ]]/cl/auth.tt.py +57 -0
  33. proper-0.2/src/blueprints/auth/[[ app_name ]]/config/app.append.py +2 -0
  34. proper-0.2/src/blueprints/auth/[[ app_name ]]/config/auth.py +6 -0
  35. proper-0.2/src/blueprints/auth/[[ app_name ]]/mailers/auth.py +28 -0
  36. proper-0.2/src/blueprints/auth/[[ app_name ]]/models/__init__.append.py +1 -0
  37. proper-0.2/src/blueprints/auth/[[ app_name ]]/models/concerns/authenticable.tt.py +134 -0
  38. proper-0.2/src/blueprints/auth/[[ app_name ]]/models/user.py +10 -0
  39. proper-0.2/src/blueprints/auth/[[ app_name ]]/views/app.append.py +13 -0
  40. proper-0.2/src/blueprints/auth/[[ app_name ]]/views/app.prepend.py +4 -0
  41. proper-0.2/src/blueprints/auth/[[ app_name ]]/views/concerns/load_user.tt.py +37 -0
  42. proper-0.2/src/blueprints/auth/[[ app_name ]]/views/concerns/require_login.tt.py +20 -0
  43. proper-0.2/src/blueprints/auth/[[ app_name ]]/views/password/__init__.py +1 -0
  44. proper-0.2/src/blueprints/auth/[[ app_name ]]/views/password/forms.py +34 -0
  45. {proper-0.1.dev4/blueprints/project/[[ app_name ]]/controllers/forms → proper-0.2/src/blueprints/auth/[[ app_name ]]/views/password}/pwned.py +3 -3
  46. proper-0.2/src/blueprints/auth/[[ app_name ]]/views/password/reset.tt.py +61 -0
  47. proper-0.2/src/blueprints/auth/[[ app_name ]]/views/password/validators.tt.py +48 -0
  48. proper-0.2/src/blueprints/auth/[[ app_name ]]/views/session/__init__.py +1 -0
  49. proper-0.2/src/blueprints/auth/[[ app_name ]]/views/session/forms.tt.py +28 -0
  50. proper-0.2/src/blueprints/auth/[[ app_name ]]/views/session/session.tt.py +36 -0
  51. proper-0.2/src/blueprints/auth/routes.tt.py +9 -0
  52. proper-0.2/src/blueprints/i18n/[[ app_name ]]/initializers/i18n.py +5 -0
  53. proper-0.2/src/blueprints/i18n/[[ app_name ]]/views/app.prepend.py +1 -0
  54. proper-0.2/src/blueprints/i18n/[[ app_name ]]/views/concerns/set_locale.tt.py +25 -0
  55. proper-0.2/src/blueprints/model/[[ app_name ]]/models/[[ singular_snake ]].tt.py +9 -0
  56. proper-0.2/src/blueprints/model/[[ app_name ]]/models/__init__.append.py +1 -0
  57. proper-0.2/src/blueprints/resource/[[ app_name ]]/views/[[ view_snake ]]/[[ view_snake ]].tt.py +139 -0
  58. proper-0.2/src/blueprints/resource/[[ app_name ]]/views/[[ view_snake ]]/__init__.tt.py +1 -0
  59. proper-0.2/src/blueprints/resource/[[ app_name ]]/views/[[ view_snake ]]/forms.tt.py +17 -0
  60. proper-0.2/src/blueprints/resource/routes.tt.py +9 -0
  61. proper-0.2/src/blueprints/storage/[[ app_name ]]/config/app.append.py +3 -0
  62. proper-0.2/src/blueprints/storage/[[ app_name ]]/config/storage.py +48 -0
  63. proper-0.2/src/blueprints/storage/[[ app_name ]]/models/__init__.append.py +1 -0
  64. proper-0.2/src/blueprints/storage/[[ app_name ]]/models/attachment.py +8 -0
  65. proper-0.2/src/blueprints/storage/[[ app_name ]]/views/storage.tt.py +15 -0
  66. proper-0.2/src/blueprints/storage/routes.tt.py +5 -0
  67. proper-0.2/src/blueprints/view/[[ app_name ]]/views/[[ plural_snake ]].tt.py +9 -0
  68. proper-0.2/src/blueprints/view/routes.tt.py +5 -0
  69. proper-0.2/src/proper/__init__.py +19 -0
  70. proper-0.2/src/proper/auth/__init__.py +2 -0
  71. {proper-0.1.dev4/proper → proper-0.2/src/proper/auth}/auth.py +150 -132
  72. proper-0.2/src/proper/auth/install.py +54 -0
  73. proper-0.2/src/proper/cache/__init__.py +2 -0
  74. proper-0.2/src/proper/cache/base.py +28 -0
  75. proper-0.2/src/proper/cache/sqlite_cache.py +159 -0
  76. proper-0.2/src/proper/cl/__init__.py +25 -0
  77. proper-0.2/src/proper/cl/app_cl.py +149 -0
  78. proper-0.2/src/proper/cl/db_cl.py +66 -0
  79. proper-0.2/src/proper/cl/proper_cl.py +17 -0
  80. proper-0.2/src/proper/concerns/__init__.py +2 -0
  81. proper-0.2/src/proper/concerns/request_forgery_protection.py +143 -0
  82. proper-0.2/src/proper/concerns/session.py +81 -0
  83. proper-0.2/src/proper/constants.py +15 -0
  84. proper-0.2/src/proper/core/__init__.py +1 -0
  85. proper-0.2/src/proper/core/app.py +471 -0
  86. proper-0.2/src/proper/core/app_test.py +293 -0
  87. proper-0.2/src/proper/core/config.py +102 -0
  88. proper-0.2/src/proper/core/error_handlers.py +155 -0
  89. {proper-0.1.dev4/proper/middleware → proper-0.2/src/proper/core/pipeline}/__init__.py +0 -2
  90. proper-0.2/src/proper/core/pipeline/dispatch.py +27 -0
  91. proper-0.2/src/proper/core/pipeline/head.py +22 -0
  92. proper-0.2/src/proper/core/pipeline/match.py +27 -0
  93. proper-0.2/src/proper/core/pipeline/method_override.py +40 -0
  94. proper-0.2/src/proper/core/pipeline/redirect.py +26 -0
  95. proper-0.2/src/proper/current.py +12 -0
  96. {proper-0.1.dev4 → proper-0.2/src}/proper/errors.py +142 -32
  97. proper-0.2/src/proper/generators/__init__.py +4 -0
  98. proper-0.2/src/proper/generators/app.py +90 -0
  99. proper-0.2/src/proper/generators/model.py +204 -0
  100. proper-0.2/src/proper/generators/resource.py +223 -0
  101. proper-0.2/src/proper/generators/view.py +68 -0
  102. proper-0.2/src/proper/helpers/__init__.py +16 -0
  103. {proper-0.1.dev4 → proper-0.2/src}/proper/helpers/digestor.py +8 -6
  104. proper-0.2/src/proper/helpers/dotdict.py +70 -0
  105. proper-0.2/src/proper/helpers/http.py +72 -0
  106. proper-0.2/src/proper/helpers/jsonplus.py +43 -0
  107. proper-0.2/src/proper/helpers/mixins.py +23 -0
  108. proper-0.2/src/proper/helpers/multidict.py +163 -0
  109. proper-0.2/src/proper/helpers/proxy.py +82 -0
  110. proper-0.2/src/proper/helpers/render.py +339 -0
  111. proper-0.2/src/proper/helpers/server.py +64 -0
  112. proper-0.2/src/proper/helpers/utils.py +241 -0
  113. proper-0.2/src/proper/i18n/__init__.py +2 -0
  114. proper-0.2/src/proper/i18n/i18n.py +341 -0
  115. proper-0.2/src/proper/i18n/install.py +55 -0
  116. proper-0.2/src/proper/i18n/plural_rules.py +1545 -0
  117. proper-0.2/src/proper/i18n/reader.py +81 -0
  118. proper-0.2/src/proper/request/__init__.py +2 -0
  119. proper-0.2/src/proper/request/forwarded.py +121 -0
  120. proper-0.2/src/proper/request/headers.py +544 -0
  121. proper-0.2/src/proper/request/make_env.py +50 -0
  122. proper-0.2/src/proper/request/multipart.py +429 -0
  123. proper-0.2/src/proper/request/parse_form.py +168 -0
  124. proper-0.2/src/proper/request/request.py +333 -0
  125. proper-0.2/src/proper/response/__init__.py +1 -0
  126. proper-0.2/src/proper/response/cookies.py +262 -0
  127. proper-0.2/src/proper/response/file_wrapper.py +58 -0
  128. proper-0.2/src/proper/response/flash_dict.py +46 -0
  129. proper-0.2/src/proper/response/headers.py +609 -0
  130. proper-0.2/src/proper/response/response.py +315 -0
  131. {proper-0.1.dev4 → proper-0.2/src}/proper/router/__init__.py +1 -1
  132. proper-0.2/src/proper/router/resource.py +157 -0
  133. proper-0.2/src/proper/router/route.py +950 -0
  134. {proper-0.1.dev4 → proper-0.2/src}/proper/router/router.py +55 -23
  135. {proper-0.1.dev4 → proper-0.2/src}/proper/router/scope.py +32 -11
  136. proper-0.2/src/proper/router/static.py +108 -0
  137. proper-0.2/src/proper/status.py +210 -0
  138. proper-0.2/src/proper/storage/__init__.py +3 -0
  139. proper-0.2/src/proper/storage/attachment.py +98 -0
  140. proper-0.2/src/proper/storage/install.py +47 -0
  141. proper-0.2/src/proper/storage/services/__init__.py +1 -0
  142. proper-0.2/src/proper/storage/services/disk.py +46 -0
  143. proper-0.2/src/proper/storage/services/service.py +27 -0
  144. proper-0.2/src/proper/storage/storage.py +108 -0
  145. proper-0.2/src/proper/storage/types.py +18 -0
  146. proper-0.2/src/proper/types.py +13 -0
  147. proper-0.2/src/proper/view.py +190 -0
  148. proper-0.2/src/proper.egg-info/PKG-INFO +131 -0
  149. proper-0.2/src/proper.egg-info/SOURCES.txt +160 -0
  150. proper-0.2/src/proper.egg-info/entry_points.txt +2 -0
  151. proper-0.2/src/proper.egg-info/requires.txt +26 -0
  152. proper-0.2/src/proper.egg-info/top_level.txt +2 -0
  153. proper-0.2/tests/test_e2e_errors.py +202 -0
  154. proper-0.2/tests/test_e2e_hello.py +52 -0
  155. proper-0.2/tests/test_e2e_middleware.py +74 -0
  156. proper-0.2/tests/test_e2e_response.py +108 -0
  157. proper-0.2/tests/test_e2e_router.py +136 -0
  158. proper-0.1.dev4/MANIFEST.in +0 -4
  159. proper-0.1.dev4/PKG-INFO +0 -87
  160. proper-0.1.dev4/blueprints/.DS_Store +0 -0
  161. proper-0.1.dev4/blueprints/controller/[[ app_name ]]/controllers/[[ snake_name ]].tmpl.py +0 -9
  162. proper-0.1.dev4/blueprints/controller/[[ app_name ]]/controllers/__init__.append.py +0 -1
  163. proper-0.1.dev4/blueprints/controller/routes.tmpl.py +0 -5
  164. proper-0.1.dev4/blueprints/controller/template.tmpl.html.jinja +0 -6
  165. proper-0.1.dev4/blueprints/model/[[ app_name ]]/models/[[ snake_name ]].tmpl.py +0 -11
  166. proper-0.1.dev4/blueprints/model/[[ app_name ]]/models/__init__.append.py +0 -1
  167. proper-0.1.dev4/blueprints/project/.DS_Store +0 -0
  168. proper-0.1.dev4/blueprints/project/Dockerfile.tmpl +0 -15
  169. proper-0.1.dev4/blueprints/project/Makefile.tmpl +0 -32
  170. proper-0.1.dev4/blueprints/project/README.tmpl.md +0 -36
  171. proper-0.1.dev4/blueprints/project/[[ app_name ]]/.DS_Store +0 -0
  172. proper-0.1.dev4/blueprints/project/[[ app_name ]]/__init__.py +0 -1
  173. proper-0.1.dev4/blueprints/project/[[ app_name ]]/app.tmpl.py +0 -14
  174. proper-0.1.dev4/blueprints/project/[[ app_name ]]/config/__init__.py +0 -37
  175. proper-0.1.dev4/blueprints/project/[[ app_name ]]/config/__pycache__/__init__.cpython-39.pyc +0 -0
  176. proper-0.1.dev4/blueprints/project/[[ app_name ]]/config/__pycache__/development.cpython-39.pyc +0 -0
  177. proper-0.1.dev4/blueprints/project/[[ app_name ]]/config/__pycache__/production.cpython-39.pyc +0 -0
  178. proper-0.1.dev4/blueprints/project/[[ app_name ]]/config/__pycache__/shared.cpython-39.pyc +0 -0
  179. proper-0.1.dev4/blueprints/project/[[ app_name ]]/config/__pycache__/staging.cpython-39.pyc +0 -0
  180. proper-0.1.dev4/blueprints/project/[[ app_name ]]/config/__pycache__/testing.cpython-39.pyc +0 -0
  181. proper-0.1.dev4/blueprints/project/[[ app_name ]]/config/development.tmpl.py +0 -12
  182. proper-0.1.dev4/blueprints/project/[[ app_name ]]/config/production.py +0 -10
  183. proper-0.1.dev4/blueprints/project/[[ app_name ]]/config/shared.tmpl.py +0 -27
  184. proper-0.1.dev4/blueprints/project/[[ app_name ]]/config/staging.py +0 -4
  185. proper-0.1.dev4/blueprints/project/[[ app_name ]]/config/testing.tmpl.py +0 -10
  186. proper-0.1.dev4/blueprints/project/[[ app_name ]]/controllers/.DS_Store +0 -0
  187. proper-0.1.dev4/blueprints/project/[[ app_name ]]/controllers/__init__.py +0 -4
  188. proper-0.1.dev4/blueprints/project/[[ app_name ]]/controllers/application.py +0 -81
  189. proper-0.1.dev4/blueprints/project/[[ app_name ]]/controllers/auth.py +0 -85
  190. proper-0.1.dev4/blueprints/project/[[ app_name ]]/controllers/forms/auth.tmpl.py +0 -63
  191. proper-0.1.dev4/blueprints/project/[[ app_name ]]/controllers/pages.py +0 -12
  192. proper-0.1.dev4/blueprints/project/[[ app_name ]]/mailers/__pycache__/__init__.cpython-39.pyc +0 -0
  193. proper-0.1.dev4/blueprints/project/[[ app_name ]]/mailers/__pycache__/auth.cpython-39.pyc +0 -0
  194. proper-0.1.dev4/blueprints/project/[[ app_name ]]/mailers/auth.py +0 -28
  195. proper-0.1.dev4/blueprints/project/[[ app_name ]]/main.py +0 -28
  196. proper-0.1.dev4/blueprints/project/[[ app_name ]]/models/__init__.py +0 -4
  197. proper-0.1.dev4/blueprints/project/[[ app_name ]]/models/__pycache__/__init__.cpython-39.pyc +0 -0
  198. proper-0.1.dev4/blueprints/project/[[ app_name ]]/models/__pycache__/base.cpython-39.pyc +0 -0
  199. proper-0.1.dev4/blueprints/project/[[ app_name ]]/models/__pycache__/post.cpython-39.pyc +0 -0
  200. proper-0.1.dev4/blueprints/project/[[ app_name ]]/models/__pycache__/relation.cpython-39.pyc +0 -0
  201. proper-0.1.dev4/blueprints/project/[[ app_name ]]/models/__pycache__/topic.cpython-39.pyc +0 -0
  202. proper-0.1.dev4/blueprints/project/[[ app_name ]]/models/__pycache__/user.cpython-39.pyc +0 -0
  203. proper-0.1.dev4/blueprints/project/[[ app_name ]]/models/base.py +0 -25
  204. proper-0.1.dev4/blueprints/project/[[ app_name ]]/models/mixins/__init__.py +0 -2
  205. proper-0.1.dev4/blueprints/project/[[ app_name ]]/models/mixins/__pycache__/__init__.cpython-39.pyc +0 -0
  206. proper-0.1.dev4/blueprints/project/[[ app_name ]]/models/mixins/__pycache__/authenticable.cpython-39.pyc +0 -0
  207. proper-0.1.dev4/blueprints/project/[[ app_name ]]/models/mixins/__pycache__/timestamped.cpython-39.pyc +0 -0
  208. proper-0.1.dev4/blueprints/project/[[ app_name ]]/models/mixins/authenticable.tmpl.py +0 -47
  209. proper-0.1.dev4/blueprints/project/[[ app_name ]]/models/mixins/timestamped.py +0 -19
  210. proper-0.1.dev4/blueprints/project/[[ app_name ]]/models/user.py +0 -8
  211. proper-0.1.dev4/blueprints/project/[[ app_name ]]/routes.py +0 -34
  212. proper-0.1.dev4/blueprints/project/[[ app_name ]]/services/__pycache__/__init__.cpython-39.pyc +0 -0
  213. proper-0.1.dev4/blueprints/project/[[ app_name ]]/services/__pycache__/auth_services.cpython-39.pyc +0 -0
  214. proper-0.1.dev4/blueprints/project/[[ app_name ]]/services/__pycache__/posts_services.cpython-39.pyc +0 -0
  215. proper-0.1.dev4/blueprints/project/[[ app_name ]]/services/auth_services.py +0 -64
  216. proper-0.1.dev4/blueprints/project/[[ app_name ]]/templates/.DS_Store +0 -0
  217. proper-0.1.dev4/blueprints/project/[[ app_name ]]/templates/auth/password_change.html.jinja +0 -51
  218. proper-0.1.dev4/blueprints/project/[[ app_name ]]/templates/auth/reset.html.jinja +0 -41
  219. proper-0.1.dev4/blueprints/project/[[ app_name ]]/templates/auth/reset_invalid.html.jinja +0 -17
  220. proper-0.1.dev4/blueprints/project/[[ app_name ]]/templates/auth/reset_sent.html.jinja +0 -20
  221. proper-0.1.dev4/blueprints/project/[[ app_name ]]/templates/auth/sign_in.html.jinja +0 -56
  222. proper-0.1.dev4/blueprints/project/[[ app_name ]]/templates/common/Button.html.jinja +0 -9
  223. proper-0.1.dev4/blueprints/project/[[ app_name ]]/templates/emails/password_reset.html.jinja +0 -14
  224. proper-0.1.dev4/blueprints/project/[[ app_name ]]/templates/layouts/application.html.jinja +0 -17
  225. proper-0.1.dev4/blueprints/project/[[ app_name ]]/templates/layouts/auth.html.jinja +0 -19
  226. proper-0.1.dev4/blueprints/project/[[ app_name ]]/templates/layouts/email.html.jinja +0 -12
  227. proper-0.1.dev4/blueprints/project/[[ app_name ]]/templates/pages/error.html.jinja +0 -22
  228. proper-0.1.dev4/blueprints/project/[[ app_name ]]/templates/pages/index.html.jinja +0 -5
  229. proper-0.1.dev4/blueprints/project/[[ app_name ]]/templates/pages/not_found.html.jinja +0 -24
  230. proper-0.1.dev4/blueprints/project/db/.DS_Store +0 -0
  231. proper-0.1.dev4/blueprints/project/db/migrations/script.py.mako +0 -24
  232. proper-0.1.dev4/blueprints/project/deploy/nginx.tmpl.conf +0 -46
  233. proper-0.1.dev4/blueprints/project/deploy/uwsgi.tmpl.ini +0 -23
  234. proper-0.1.dev4/blueprints/project/docker-compose.tmpl.yml +0 -22
  235. proper-0.1.dev4/blueprints/project/logs/.keep +0 -0
  236. proper-0.1.dev4/blueprints/project/manage.tmpl.py +0 -43
  237. proper-0.1.dev4/blueprints/project/requirements/dev-requirements.ini +0 -3
  238. proper-0.1.dev4/blueprints/project/requirements/prod-requirements.ini +0 -2
  239. proper-0.1.dev4/blueprints/project/requirements/requirements.ini +0 -8
  240. proper-0.1.dev4/blueprints/project/requirements/test-requirements.ini +0 -6
  241. proper-0.1.dev4/blueprints/project/setup.py +0 -1
  242. proper-0.1.dev4/blueprints/project/setup.tmpl.cfg +0 -47
  243. proper-0.1.dev4/blueprints/project/static/.DS_Store +0 -0
  244. proper-0.1.dev4/blueprints/project/static/.eslintrc.js +0 -38
  245. proper-0.1.dev4/blueprints/project/static/package.json +0 -26
  246. proper-0.1.dev4/blueprints/project/static/postcss.config.js +0 -12
  247. proper-0.1.dev4/blueprints/project/static/public/css/.keep +0 -0
  248. proper-0.1.dev4/blueprints/project/static/public/favicon.ico +0 -0
  249. proper-0.1.dev4/blueprints/project/static/public/fonts/.keep +0 -0
  250. proper-0.1.dev4/blueprints/project/static/public/humans.txt +0 -0
  251. proper-0.1.dev4/blueprints/project/static/public/images/.keep +0 -0
  252. proper-0.1.dev4/blueprints/project/static/public/js/.keep +0 -0
  253. proper-0.1.dev4/blueprints/project/static/public/robots.txt +0 -2
  254. proper-0.1.dev4/blueprints/project/static/public/vendor/.keep +0 -0
  255. proper-0.1.dev4/blueprints/project/static/src/css/_base.css +0 -4
  256. proper-0.1.dev4/blueprints/project/static/src/css/_buttons.css +0 -74
  257. proper-0.1.dev4/blueprints/project/static/src/css/_components.css +0 -12
  258. proper-0.1.dev4/blueprints/project/static/src/css/_forms.css +0 -100
  259. proper-0.1.dev4/blueprints/project/static/src/css/_utilities.css +0 -2
  260. proper-0.1.dev4/blueprints/project/static/src/css/email.css +0 -3
  261. proper-0.1.dev4/blueprints/project/static/src/css/styles.css +0 -3
  262. proper-0.1.dev4/blueprints/project/static/src/js/scripts.js +0 -0
  263. proper-0.1.dev4/blueprints/project/static/tailwind.config.tmpl.js +0 -9
  264. proper-0.1.dev4/blueprints/project/static/webpack.config.js +0 -16
  265. proper-0.1.dev4/blueprints/project/uwsgi-dev.ini +0 -18
  266. proper-0.1.dev4/blueprints/project/wsgi.tmpl.py +0 -4
  267. proper-0.1.dev4/blueprints/resource/[[ app_name ]]/controllers/[[ snake_name ]].tmpl.py +0 -14
  268. proper-0.1.dev4/blueprints/resource/[[ app_name ]]/controllers/__init__.append.py +0 -1
  269. proper-0.1.dev4/blueprints/resource/[[ app_name ]]/templates/[[ snake_name ]]/edit.html.jinja +0 -6
  270. proper-0.1.dev4/blueprints/resource/[[ app_name ]]/templates/[[ snake_name ]]/index.html.jinja +0 -6
  271. proper-0.1.dev4/blueprints/resource/[[ app_name ]]/templates/[[ snake_name ]]/new.html.jinja +0 -6
  272. proper-0.1.dev4/blueprints/resource/[[ app_name ]]/templates/[[ snake_name ]]/show.html.jinja +0 -6
  273. proper-0.1.dev4/blueprints/resource/routes.tmpl.py +0 -5
  274. proper-0.1.dev4/proper/.DS_Store +0 -0
  275. proper-0.1.dev4/proper/__init__.py +0 -8
  276. proper-0.1.dev4/proper/__pycache__/__init__.cpython-39.pyc +0 -0
  277. proper-0.1.dev4/proper/__pycache__/auth.cpython-39.pyc +0 -0
  278. proper-0.1.dev4/proper/__pycache__/constants.cpython-39.pyc +0 -0
  279. proper-0.1.dev4/proper/__pycache__/errors.cpython-39.pyc +0 -0
  280. proper-0.1.dev4/proper/__pycache__/local.cpython-39.pyc +0 -0
  281. proper-0.1.dev4/proper/__pycache__/request.cpython-39.pyc +0 -0
  282. proper-0.1.dev4/proper/__pycache__/response.cpython-39.pyc +0 -0
  283. proper-0.1.dev4/proper/__pycache__/static.cpython-39.pyc +0 -0
  284. proper-0.1.dev4/proper/__pycache__/status.cpython-39.pyc +0 -0
  285. proper-0.1.dev4/proper/app/__init__.py +0 -1
  286. proper-0.1.dev4/proper/app/__pycache__/__init__.cpython-39.pyc +0 -0
  287. proper-0.1.dev4/proper/app/__pycache__/app.cpython-39.pyc +0 -0
  288. proper-0.1.dev4/proper/app/__pycache__/cli.cpython-39.pyc +0 -0
  289. proper-0.1.dev4/proper/app/__pycache__/cli_run.cpython-39.pyc +0 -0
  290. proper-0.1.dev4/proper/app/__pycache__/default_config.cpython-39.pyc +0 -0
  291. proper-0.1.dev4/proper/app/__pycache__/error_handlers.cpython-39.pyc +0 -0
  292. proper-0.1.dev4/proper/app/__pycache__/errors_mixin.cpython-39.pyc +0 -0
  293. proper-0.1.dev4/proper/app/__pycache__/setup_mixin.cpython-39.pyc +0 -0
  294. proper-0.1.dev4/proper/app/app.py +0 -99
  295. proper-0.1.dev4/proper/app/cli.py +0 -123
  296. proper-0.1.dev4/proper/app/cli_run.py +0 -52
  297. proper-0.1.dev4/proper/app/default_config.py +0 -37
  298. proper-0.1.dev4/proper/app/error_handlers.py +0 -103
  299. proper-0.1.dev4/proper/app/errors_mixin.py +0 -91
  300. proper-0.1.dev4/proper/app/setup_mixin.py +0 -170
  301. proper-0.1.dev4/proper/app/templates/_context.html.jinja +0 -61
  302. proper-0.1.dev4/proper/app/templates/_debug-styles.css +0 -100
  303. proper-0.1.dev4/proper/app/templates/_prism.css +0 -228
  304. proper-0.1.dev4/proper/app/templates/_prism.js +0 -4
  305. proper-0.1.dev4/proper/app/templates/debug-error.html.jinja +0 -14
  306. proper-0.1.dev4/proper/app/templates/debug-not-found.html.jinja +0 -61
  307. proper-0.1.dev4/proper/app/templates/fallback-error.html +0 -41
  308. proper-0.1.dev4/proper/app/templates/fallback-forbidden.html +0 -54
  309. proper-0.1.dev4/proper/app/templates/fallback-not-found.html +0 -42
  310. proper-0.1.dev4/proper/app/templates/layout.html.jinja +0 -21
  311. proper-0.1.dev4/proper/cli/__init__.py +0 -33
  312. proper-0.1.dev4/proper/cli/__pycache__/__init__.cpython-39.pyc +0 -0
  313. proper-0.1.dev4/proper/cli/__pycache__/welcome.cpython-39.pyc +0 -0
  314. proper-0.1.dev4/proper/cli/welcome.py +0 -44
  315. proper-0.1.dev4/proper/constants.py +0 -12
  316. proper-0.1.dev4/proper/controller/__init__.py +0 -1
  317. proper-0.1.dev4/proper/controller/__pycache__/__init__.cpython-39.pyc +0 -0
  318. proper-0.1.dev4/proper/controller/__pycache__/base_channel.cpython-39.pyc +0 -0
  319. proper-0.1.dev4/proper/controller/__pycache__/base_controller.cpython-39.pyc +0 -0
  320. proper-0.1.dev4/proper/controller/base_channel.py +0 -26
  321. proper-0.1.dev4/proper/controller/base_controller.py +0 -71
  322. proper-0.1.dev4/proper/generators/__init__.py +0 -4
  323. proper-0.1.dev4/proper/generators/__pycache__/__init__.cpython-39.pyc +0 -0
  324. proper-0.1.dev4/proper/generators/__pycache__/controller.cpython-39.pyc +0 -0
  325. proper-0.1.dev4/proper/generators/__pycache__/mailer.cpython-39.pyc +0 -0
  326. proper-0.1.dev4/proper/generators/__pycache__/model.cpython-39.pyc +0 -0
  327. proper-0.1.dev4/proper/generators/__pycache__/project.cpython-39.pyc +0 -0
  328. proper-0.1.dev4/proper/generators/__pycache__/resource.cpython-39.pyc +0 -0
  329. proper-0.1.dev4/proper/generators/controller.py +0 -56
  330. proper-0.1.dev4/proper/generators/mailer.py +0 -13
  331. proper-0.1.dev4/proper/generators/model.py +0 -245
  332. proper-0.1.dev4/proper/generators/project.py +0 -92
  333. proper-0.1.dev4/proper/generators/resource.py +0 -81
  334. proper-0.1.dev4/proper/helpers/__init__.py +0 -12
  335. proper-0.1.dev4/proper/helpers/__pycache__/__init__.cpython-39.pyc +0 -0
  336. proper-0.1.dev4/proper/helpers/__pycache__/cookies.cpython-39.pyc +0 -0
  337. proper-0.1.dev4/proper/helpers/__pycache__/digestor.cpython-39.pyc +0 -0
  338. proper-0.1.dev4/proper/helpers/__pycache__/dot.cpython-39.pyc +0 -0
  339. proper-0.1.dev4/proper/helpers/__pycache__/encoding.cpython-39.pyc +0 -0
  340. proper-0.1.dev4/proper/helpers/__pycache__/frozendict.cpython-39.pyc +0 -0
  341. proper-0.1.dev4/proper/helpers/__pycache__/headersdict.cpython-39.pyc +0 -0
  342. proper-0.1.dev4/proper/helpers/__pycache__/iterable.cpython-39.pyc +0 -0
  343. proper-0.1.dev4/proper/helpers/__pycache__/multidict.cpython-39.pyc +0 -0
  344. proper-0.1.dev4/proper/helpers/__pycache__/paginator.cpython-39.pyc +0 -0
  345. proper-0.1.dev4/proper/helpers/__pycache__/render.cpython-39.pyc +0 -0
  346. proper-0.1.dev4/proper/helpers/__pycache__/serializer.cpython-39.pyc +0 -0
  347. proper-0.1.dev4/proper/helpers/__pycache__/slugify.cpython-39.pyc +0 -0
  348. proper-0.1.dev4/proper/helpers/cookies.py +0 -161
  349. proper-0.1.dev4/proper/helpers/dot.py +0 -98
  350. proper-0.1.dev4/proper/helpers/encoding.py +0 -25
  351. proper-0.1.dev4/proper/helpers/frozendict.py +0 -56
  352. proper-0.1.dev4/proper/helpers/headersdict.py +0 -13
  353. proper-0.1.dev4/proper/helpers/iterable.py +0 -8
  354. proper-0.1.dev4/proper/helpers/multidict.py +0 -122
  355. proper-0.1.dev4/proper/helpers/paginator.py +0 -338
  356. proper-0.1.dev4/proper/helpers/render.py +0 -216
  357. proper-0.1.dev4/proper/helpers/serializer.py +0 -40
  358. proper-0.1.dev4/proper/helpers/slugify.py +0 -72
  359. proper-0.1.dev4/proper/local.py +0 -63
  360. proper-0.1.dev4/proper/middleware/README.md +0 -7
  361. proper-0.1.dev4/proper/middleware/__pycache__/__init__.cpython-39.pyc +0 -0
  362. proper-0.1.dev4/proper/middleware/__pycache__/dispatch.cpython-39.pyc +0 -0
  363. proper-0.1.dev4/proper/middleware/__pycache__/head.cpython-39.pyc +0 -0
  364. proper-0.1.dev4/proper/middleware/__pycache__/match.cpython-39.pyc +0 -0
  365. proper-0.1.dev4/proper/middleware/__pycache__/method_override.cpython-39.pyc +0 -0
  366. proper-0.1.dev4/proper/middleware/__pycache__/protect_from_forgery.cpython-39.pyc +0 -0
  367. proper-0.1.dev4/proper/middleware/__pycache__/redirect.cpython-39.pyc +0 -0
  368. proper-0.1.dev4/proper/middleware/__pycache__/session.cpython-39.pyc +0 -0
  369. proper-0.1.dev4/proper/middleware/dispatch.py +0 -46
  370. proper-0.1.dev4/proper/middleware/head.py +0 -19
  371. proper-0.1.dev4/proper/middleware/match.py +0 -18
  372. proper-0.1.dev4/proper/middleware/method_override.py +0 -30
  373. proper-0.1.dev4/proper/middleware/protect_from_forgery.py +0 -72
  374. proper-0.1.dev4/proper/middleware/redirect.py +0 -18
  375. proper-0.1.dev4/proper/middleware/session.py +0 -64
  376. proper-0.1.dev4/proper/parsers/__init__.py +0 -5
  377. proper-0.1.dev4/proper/parsers/__pycache__/__init__.cpython-39.pyc +0 -0
  378. proper-0.1.dev4/proper/parsers/__pycache__/parse_comma_separated.cpython-39.pyc +0 -0
  379. proper-0.1.dev4/proper/parsers/__pycache__/parse_cookies.cpython-39.pyc +0 -0
  380. proper-0.1.dev4/proper/parsers/__pycache__/parse_form_data.cpython-39.pyc +0 -0
  381. proper-0.1.dev4/proper/parsers/__pycache__/parse_http_date.cpython-39.pyc +0 -0
  382. proper-0.1.dev4/proper/parsers/__pycache__/parse_query_string.cpython-39.pyc +0 -0
  383. proper-0.1.dev4/proper/parsers/parse_comma_separated.py +0 -13
  384. proper-0.1.dev4/proper/parsers/parse_cookies.py +0 -25
  385. proper-0.1.dev4/proper/parsers/parse_form_data.py +0 -125
  386. proper-0.1.dev4/proper/parsers/parse_http_date.py +0 -15
  387. proper-0.1.dev4/proper/parsers/parse_query_string.py +0 -46
  388. proper-0.1.dev4/proper/request.py +0 -384
  389. proper-0.1.dev4/proper/response.py +0 -350
  390. proper-0.1.dev4/proper/router/__pycache__/__init__.cpython-39.pyc +0 -0
  391. proper-0.1.dev4/proper/router/__pycache__/base.cpython-39.pyc +0 -0
  392. proper-0.1.dev4/proper/router/__pycache__/resource.cpython-39.pyc +0 -0
  393. proper-0.1.dev4/proper/router/__pycache__/route.cpython-39.pyc +0 -0
  394. proper-0.1.dev4/proper/router/__pycache__/router.cpython-39.pyc +0 -0
  395. proper-0.1.dev4/proper/router/__pycache__/scope.cpython-39.pyc +0 -0
  396. proper-0.1.dev4/proper/router/base.py +0 -158
  397. proper-0.1.dev4/proper/router/resource.py +0 -118
  398. proper-0.1.dev4/proper/router/route.py +0 -179
  399. proper-0.1.dev4/proper/static.py +0 -149
  400. proper-0.1.dev4/proper/status.py +0 -209
  401. proper-0.1.dev4/proper.egg-info/PKG-INFO +0 -87
  402. proper-0.1.dev4/proper.egg-info/SOURCES.txt +0 -266
  403. proper-0.1.dev4/proper.egg-info/entry_points.txt +0 -3
  404. proper-0.1.dev4/proper.egg-info/requires.txt +0 -27
  405. proper-0.1.dev4/proper.egg-info/top_level.txt +0 -1
  406. proper-0.1.dev4/setup.cfg +0 -99
  407. proper-0.1.dev4/setup.py +0 -5
  408. {proper-0.1.dev4 → proper-0.2}/MIT-LICENSE +0 -0
  409. {proper-0.1.dev4/blueprints/project/[[ app_name ]]/controllers/forms → proper-0.2/src/blueprints/app/[[ app_name ]]/config}/__init__.py +0 -0
  410. {proper-0.1.dev4/blueprints/project → proper-0.2/src/blueprints/app}/[[ app_name ]]/mailers/__init__.py +0 -0
  411. /proper-0.1.dev4/blueprints/project/.well-known/.keep → /proper-0.2/src/proper/py.typed +0 -0
  412. {proper-0.1.dev4 → proper-0.2/src}/proper.egg-info/dependency_links.txt +0 -0
proper-0.2/PKG-INFO ADDED
@@ -0,0 +1,131 @@
1
+ Metadata-Version: 2.1
2
+ Name: proper
3
+ Version: 0.2
4
+ Summary: A web framework optimized for programmer happiness
5
+ Author-email: Juan-Pablo Scaletti <juanpablo@jpscaletti.com>
6
+ License: Copyright (c) 2019 Juan-Pablo Scaletti
7
+
8
+ Permission is hereby granted, free of charge, to any person obtaining
9
+ a copy of this software and associated documentation files (the
10
+ "Software"), to deal in the Software without restriction, including
11
+ without limitation the rights to use, copy, modify, merge, publish,
12
+ distribute, sublicense, and/or sell copies of the Software, and to
13
+ permit persons to whom the Software is furnished to do so, subject to
14
+ the following conditions:
15
+
16
+ The above copyright notice and this permission notice shall be
17
+ included in all copies or substantial portions of the Software.
18
+
19
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
23
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
24
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
25
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26
+
27
+ Project-URL: homepage, https://proper.scaletti.dev/
28
+ Project-URL: repository, https://github.com/jpsca/proper
29
+ Project-URL: documentation, https://proper.scaletti.dev/
30
+ Classifier: Development Status :: 4 - Beta
31
+ Classifier: Environment :: Web Environment
32
+ Classifier: Intended Audience :: Developers
33
+ Classifier: License :: OSI Approved :: MIT License
34
+ Classifier: Programming Language :: Python :: 3 :: Only
35
+ Classifier: Programming Language :: Python :: 3.10
36
+ Classifier: Programming Language :: Python :: 3.11
37
+ Classifier: Programming Language :: Python :: 3.12
38
+ Classifier: Typing :: Typed
39
+ Requires-Python: >=3.10
40
+ Description-Content-Type: text/markdown
41
+ Requires-Dist: inflection>=0.5.1
42
+ Requires-Dist: isort>=5.0
43
+ Requires-Dist: itsdangerous>=1.1
44
+ Requires-Dist: jinjax>=0.30
45
+ Requires-Dist: mailshake
46
+ Requires-Dist: markupsafe>=2.0
47
+ Requires-Dist: passlib>=1.7
48
+ Requires-Dist: peewee>=3.15
49
+ Requires-Dist: peewee-migrate<2,>=1.12.1
50
+ Requires-Dist: proper-cli>=1.2
51
+ Requires-Dist: tomlkit>=0.12.4
52
+ Requires-Dist: traceback-with-variables==2.0.4
53
+ Requires-Dist: uwsgi>=2.0
54
+ Provides-Extra: dev
55
+ Requires-Dist: ipdb>=0.13; extra == "dev"
56
+ Requires-Dist: pyright>=1.1; extra == "dev"
57
+ Requires-Dist: pre-commit; extra == "dev"
58
+ Requires-Dist: ruff>=0.2.0; extra == "dev"
59
+ Provides-Extra: test
60
+ Requires-Dist: pytest>=7.2; extra == "test"
61
+ Requires-Dist: pytest-cov; extra == "test"
62
+ Requires-Dist: tox; extra == "test"
63
+ Requires-Dist: image-processing-egg; extra == "test"
64
+ Requires-Dist: poyo; extra == "test"
65
+
66
+ > :warning: WARNING: This is a work in progress. It doesn't have documentation. Do NOT use it.
67
+
68
+ # Proper
69
+
70
+ A web framework optimized for programmer happiness.
71
+
72
+
73
+ ### Requirements
74
+
75
+ - Python 3.10+
76
+
77
+
78
+ ### Installation
79
+
80
+ pip install proper
81
+
82
+
83
+ ## Design principles
84
+
85
+ - "Convention over configuration".
86
+
87
+ - No globals.
88
+ When you need a shared object, pass it arround.
89
+
90
+ - Optimize for the 95%.
91
+ Don't compromise the usability of the common cases to keep consistency
92
+ with the edge cases.
93
+
94
+ - Code redability is important.
95
+
96
+ - App-code over framework-code
97
+ Because app code is infintely configurable without dirty hacks.
98
+
99
+ - "Everyone is an adult here".
100
+ Run with scissors if you must.
101
+
102
+ - Regular WSGI is great.
103
+
104
+
105
+ # Sources of inspirations
106
+
107
+ ## From Elixir/Phoenix
108
+
109
+ ### App-code over framework-code.
110
+
111
+ You can make it clean and straightforward or you can make it configurable.
112
+ But if you put the code in the application, thanks to a standarized project skeleton,
113
+ you can have both!
114
+
115
+
116
+ ## From Ruby/Rails
117
+
118
+ ### Convention over configuration.
119
+
120
+ ### Optimize for developer happiness.
121
+
122
+ ### The application code must be beatiful.
123
+
124
+ - Empty class-based views that works!
125
+ - Class-based views allows several tricks that make the experience much better:
126
+ - A configurable and plugganle render and view functions.
127
+ - Class based views a-la Django, but simpler and completely obvious because is your application code (see (App-code over framework-code)
128
+ - Saving context varaibles in your view instance looks much cleaner that building a dictionary and manually calling render and the end of each view.
129
+
130
+
131
+ ![Visualization of the codebase](./diagram.svg)
@@ -7,7 +7,7 @@ A web framework optimized for programmer happiness.
7
7
 
8
8
  ### Requirements
9
9
 
10
- - Python 3.6+
10
+ - Python 3.10+
11
11
 
12
12
 
13
13
  ### Installation
@@ -41,11 +41,6 @@ A web framework optimized for programmer happiness.
41
41
 
42
42
  ## From Elixir/Phoenix
43
43
 
44
- ### Pipelines in the routes.
45
-
46
- You don't need to have a framework for APIs and other for full-fletched apps, you can just deactivate cookie sessions, flash messages and other things yoi don't need for specific sections of your sites.
47
- And is super easy to add things too like admin-only sections just by composing multiple pipelines, after all, there are just lists of callables.
48
-
49
44
  ### App-code over framework-code.
50
45
 
51
46
  You can make it clean and straightforward or you can make it configurable.
@@ -61,8 +56,11 @@ you can have both!
61
56
 
62
57
  ### The application code must be beatiful.
63
58
 
64
- - Empty class-based controllers that works!
65
- - Class-based controllers allows several tricks that make the experience much better:
59
+ - Empty class-based views that works!
60
+ - Class-based views allows several tricks that make the experience much better:
66
61
  - A configurable and plugganle render and view functions.
67
62
  - Class based views a-la Django, but simpler and completely obvious because is your application code (see (App-code over framework-code)
68
- - Saving context varaibles in your controller instance looks much cleaner that building a dictionary and manually calling render and the end of each controller.
63
+ - Saving context varaibles in your view instance looks much cleaner that building a dictionary and manually calling render and the end of each view.
64
+
65
+
66
+ ![Visualization of the codebase](./diagram.svg)
@@ -0,0 +1,222 @@
1
+ [build-system]
2
+ requires = ["setuptools"]
3
+
4
+
5
+ [project]
6
+ name = "proper"
7
+ version = "0.2"
8
+ description = "A web framework optimized for programmer happiness"
9
+ authors = [
10
+ {name = "Juan-Pablo Scaletti", email = "juanpablo@jpscaletti.com"},
11
+ ]
12
+ license = { "file" = "MIT-LICENSE" }
13
+ readme = "README.md"
14
+ requires-python = ">=3.10"
15
+ classifiers = [
16
+ "Development Status :: 4 - Beta",
17
+ "Environment :: Web Environment",
18
+ "Intended Audience :: Developers",
19
+ "License :: OSI Approved :: MIT License",
20
+ "Programming Language :: Python :: 3 :: Only",
21
+ "Programming Language :: Python :: 3.10",
22
+ "Programming Language :: Python :: 3.11",
23
+ "Programming Language :: Python :: 3.12",
24
+ "Typing :: Typed",
25
+ ]
26
+ dependencies = [
27
+ "inflection >= 0.5.1",
28
+ "isort >= 5.0",
29
+ "itsdangerous >= 1.1",
30
+ "jinjax >= 0.30",
31
+ "mailshake",
32
+ "markupsafe >= 2.0",
33
+ "passlib >= 1.7",
34
+ "peewee >= 3.15",
35
+ "peewee-migrate >= 1.12.1, < 2",
36
+ "proper-cli >= 1.2",
37
+ "tomlkit >= 0.12.4",
38
+ "traceback-with-variables == 2.0.4",
39
+ "uwsgi >= 2.0",
40
+ ]
41
+
42
+
43
+ [project.optional-dependencies]
44
+ dev = [
45
+ "ipdb >= 0.13",
46
+ "pyright >= 1.1",
47
+ "pre-commit",
48
+ "ruff >= 0.2.0",
49
+ ]
50
+ test = [
51
+ "pytest >= 7.2",
52
+ "pytest-cov",
53
+ "tox",
54
+ # To test installable frameworks
55
+ "image-processing-egg",
56
+ "poyo",
57
+ ]
58
+
59
+
60
+ [project.urls]
61
+ homepage = "https://proper.scaletti.dev/"
62
+ repository = "https://github.com/jpsca/proper"
63
+ documentation = "https://proper.scaletti.dev/"
64
+
65
+
66
+ [project.scripts]
67
+ proper = "proper.cl:run"
68
+
69
+
70
+ [tool.setuptools.packages.find]
71
+ where = ["src"]
72
+
73
+
74
+ [tool.setuptools.package-data]
75
+ proper = [
76
+ "src/blueprints/*",
77
+ "src/core/templates/*",
78
+ ]
79
+
80
+
81
+ [tool.coverage.run]
82
+ branch = true
83
+
84
+
85
+ [tool.coverage.report]
86
+ exclude_lines = [
87
+ "pragma: no cover",
88
+ "TYPE_CHECKING",
89
+ "def __repr__",
90
+ "def __str__",
91
+ "raise AssertionError",
92
+ "raise NotImplementedError",
93
+ "if __name__ == .__main__.:"
94
+ ]
95
+ omit = [
96
+ "src/blueprints/*",
97
+ "src/proper/app_test.py",
98
+ "src/proper/cl/*",
99
+ "src/proper/storage/*", # TODO
100
+ ]
101
+
102
+
103
+ [tool.coverage.html]
104
+ directory = "covreport"
105
+
106
+
107
+ [tool.pyright]
108
+ include = ["src"]
109
+ exclude = [
110
+ "**/node_modules",
111
+ "**/__pycache__",
112
+ "**/tests",
113
+ ]
114
+ ignore = ["src/blueprints"]
115
+ reportPrivateImportUsage = false
116
+ reportWildcardImportFromLibrary = false
117
+
118
+
119
+ [tool.pytest.ini_options]
120
+ addopts = "--doctest-modules"
121
+
122
+
123
+ [tool.tox]
124
+ legacy_tox_ini = """
125
+ [tox]
126
+ skipsdist = True
127
+ envlist = py310,py311,py312
128
+
129
+ [testenv]
130
+ skip_install = true
131
+ commands =
132
+ pip install -U uv
133
+ uv pip install requirements-text.txt
134
+ pytest -x src/proper tests
135
+ """
136
+
137
+
138
+ [tool.ruff]
139
+ line-length = 90
140
+ indent-width = 4
141
+ target-version = "py311"
142
+
143
+ exclude = [
144
+ ".*",
145
+ "_build",
146
+ "build",
147
+ "covreport",
148
+ "dist",
149
+ "src/blueprints/*",
150
+ ]
151
+ include = ["*.py"]
152
+
153
+
154
+ [tool.ruff.format]
155
+ # Like Black, use double quotes for strings.
156
+ quote-style = "double"
157
+
158
+ # Like Black, indent with spaces, rather than tabs.
159
+ indent-style = "space"
160
+
161
+ # Like Black, respect magic trailing commas.
162
+ skip-magic-trailing-comma = false
163
+
164
+ # Like Black, automatically detect the appropriate line ending.
165
+ line-ending = "auto"
166
+
167
+ # Enable auto-formatting of code examples in docstrings. Markdown,
168
+ # reStructuredText code/literal blocks and doctests are all supported.
169
+ #
170
+ # This is currently disabled by default, but it is planned for this
171
+ # to be opt-out in the future.
172
+ docstring-code-format = false
173
+
174
+ # Set the line length limit used when formatting code snippets in
175
+ # docstrings.
176
+ #
177
+ # This only has an effect when the `docstring-code-format` setting is
178
+ # enabled.
179
+ docstring-code-line-length = "dynamic"
180
+
181
+
182
+ [tool.ruff.lint]
183
+ fixable = ["ALL"]
184
+
185
+ ignore = [
186
+ # x is too complex
187
+ "C901",
188
+ # whitespace before ':'
189
+ "E203",
190
+ "E501",
191
+ # x defined from star imports
192
+ "F405",
193
+ # line break before binary operator
194
+ "W505",
195
+ "W605",
196
+ ]
197
+ select = [
198
+ # bugbear
199
+ "B",
200
+ # mccabe"", comprehensions, commas
201
+ "C",
202
+ # pycodestyle errors
203
+ "E",
204
+ # pyflakes
205
+ "F",
206
+ # logging format
207
+ "G",
208
+ # imports
209
+ "I",
210
+ # quotes
211
+ "Q",
212
+ # pycodestyle warnings
213
+ "W",
214
+ ]
215
+
216
+
217
+ [tool.ruff.lint.isort]
218
+ known-first-party = ["proper"]
219
+ known-local-folder = ["src/proper"]
220
+
221
+ # Use two line after imports.
222
+ lines-after-imports = 2
proper-0.2/setup.cfg ADDED
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,5 @@
1
+ # The order of these imports is important
2
+ from . import app # noqa
3
+ from . import initializers # noqa
4
+ from . import routes # noqa
5
+ from . import models # noqa
@@ -0,0 +1,8 @@
1
+ from proper import App
2
+
3
+
4
+ app = App(__name__)
5
+ config = app.config
6
+
7
+ if app.catalog:
8
+ app.catalog.add_folder(app.components_path / "common")
@@ -0,0 +1,5 @@
1
+ from [[ app_name ]].app import app
2
+
3
+
4
+ class AppCL(app.CL):
5
+ """Custom commands for this application"""
@@ -0,0 +1,52 @@
1
+ from proper import env, DEV, PROD
2
+
3
+ from .database import * # noqa
4
+ from .session import * # noqa
5
+ from .storage import * # noqa
6
+
7
+
8
+ DEBUG: bool = env == DEV
9
+
10
+ if env == PROD:
11
+ HOST: str = "https://YOUR-DOMAIN.com"
12
+ else:
13
+ HOST: str = "http://127.0.0.1:2300"
14
+
15
+ # List of secret keys, **OLDEST TO NEWEST**.
16
+ # Every key in the list is valid, so you can periodically generate a new key
17
+ # and remove the oldest one to add and extra layer of mitigation
18
+ # against a improbable discovery of the current secret key
19
+ if env == PROD:
20
+ SECRET_KEYS: list[str] = [
21
+ "..."
22
+ ]
23
+ else:
24
+ SECRET_KEYS: list[str] = [
25
+ "---- This is a not-secret-secret_key just for development ----"
26
+ ]
27
+
28
+ # Turn off to let debugging WSGI middleware handle exceptions.
29
+ CATCH_ALL_ERRORS: bool = True
30
+
31
+ # Limits the total content length (in bytes).
32
+ # Raises a RequestEntityTooLarge exception if this value is exceeded.
33
+ MAX_CONTENT_LENGTH: int = 2**23 # 8 MB
34
+
35
+ # Limits the content length (in bytes) of the query string.
36
+ # Raises a RequestEntityTooLarge or an UriTooLong if this value is exceeded.
37
+ MAX_QUERY_SIZE: int = 2**20 # 1 MB
38
+
39
+
40
+ COMPONENTS_FOLDER = "components"
41
+ COMPONENTS_URL = "/components"
42
+
43
+ # The name of the header to use to return a file
44
+ # so the proxy or web-server does it instead of our application.
45
+ # Lighttpd uses "X-Sendfile" while NGINX uses "X-Accel-Redirect"
46
+ if env == PROD:
47
+ STATIC_X_SENDFILE_HEADER = "X-Accel-Redirect"
48
+ else:
49
+ STATIC_X_SENDFILE_HEADER = ""
50
+
51
+
52
+ MAILER_DEFAULT_FROM = "hello@example.com"
@@ -0,0 +1,40 @@
1
+ import os
2
+
3
+ from proper import DEV, PROD, env
4
+
5
+
6
+ DATABASE_ENGINES = {
7
+ "sqlite": {
8
+ "type": "playhouse.sqlite_ext.SqliteExtDatabase",
9
+ "database": "db/sqlite.db",
10
+ },
11
+ "postgres": {
12
+ "type": "playhouse.postgres_ext.PostgresqlExtDatabase",
13
+ "database": os.getenv("DB_NAME", "[[ app_name ]]"),
14
+ "host": os.getenv("DB_HOST", "127.0.0.1"),
15
+ "port": int(os.getenv("DB_PORT", 5432)),
16
+ "user": os.getenv("DB_USER", "root"),
17
+ "password": os.getenv("DB_PASSWORD", ""),
18
+ # The connection is managed in a concern of the view,
19
+ # and on the `on_teardown` and `on_error` hooks
20
+ "autoconnect": False,
21
+ },
22
+ "maria": {
23
+ "type": "peewee.MySQLDatabase",
24
+ "database": os.getenv("DB_NAME", "[[ app_name ]]"),
25
+ "host": os.getenv("DB_HOST", "127.0.0.1"),
26
+ "port": int(os.getenv("DB_PORT", 3306)),
27
+ "user": os.getenv("DB_USER", "root"),
28
+ "password": os.getenv("DB_PASSWORD", ""),
29
+ # The connection is managed iin a concern of the view,
30
+ # and on the `on_teardown` and `on_error` hooks
31
+ "autoconnect": False
32
+ },
33
+ }
34
+
35
+ if env == PROD:
36
+ DATABASE: str = "postgres"
37
+ elif env == DEV:
38
+ DATABASE: str = "sqlite"
39
+ else:
40
+ DATABASE: str = "sqlite"
@@ -0,0 +1,13 @@
1
+ from datetime import timedelta
2
+
3
+ from proper import PROD, env
4
+
5
+
6
+ SESSION_LIFETIME: int = int(timedelta(days=30).total_seconds())
7
+ SESSION_COOKIE_NAME: str = "_session"
8
+ SESSION_COOKIE_DOMAIN: str | None = None
9
+ SESSION_COOKIE_PATH: str = "/"
10
+ SESSION_COOKIE_HTTPONLY: bool = True
11
+ SESSION_COOKIE_SECURE: bool = env == PROD
12
+ # "Lax", "Strict", or None
13
+ SESSION_COOKIE_SAMESITE: bool = False
@@ -0,0 +1,8 @@
1
+ import os
2
+
3
+
4
+ REDIS_HOST: str = os.getenv("REDIS_HOST", "127.0.0.1")
5
+ REDIS_PORT: int = int(os.getenv("REDIS_PORT", 6379))
6
+ REDIS_USER: str | None = os.getenv("REDIS_USER")
7
+ REDIS_PASSWORD: str | None = os.getenv("REDIS_PASSWORD")
8
+ REDIS_DB: int = int(os.getenv("REDIS_DB", 0))
@@ -0,0 +1,25 @@
1
+ import subprocess
2
+ import sys
3
+
4
+ from [[ app_name ]].app import app
5
+ from [[ app_name ]].cl import AppCL
6
+
7
+
8
+ app.CL = AppCL
9
+
10
+
11
+ @app.on_dev_start
12
+ def compile_tailwind():
13
+ from pytailwindcss import get_bin_path
14
+
15
+ cmd = [
16
+ str(get_bin_path()),
17
+ "-i",
18
+ "static_src/css/app.css",
19
+ "-o",
20
+ "static/css/app.css",
21
+ "--watch",
22
+ ]
23
+ scmd = " ".join(cmd)
24
+ print("Running",f'"{scmd}"')
25
+ subprocess.Popen(cmd, stdout=sys.stdout, stderr=sys.stderr)
@@ -0,0 +1,22 @@
1
+ from importlib import import_module
2
+
3
+ from ..app import app, config
4
+
5
+
6
+ db_config = config.DATABASE_ENGINES[config.DATABASE].copy()
7
+ mod_name, cls_name = db_config.pop("type").rsplit(".", 1)
8
+ mod = import_module(mod_name)
9
+ Cls = getattr(mod, cls_name)
10
+ app.db = Cls(**db_config)
11
+
12
+
13
+ @app.on_error
14
+ def on_error():
15
+ if app.db and not app.db.is_closed():
16
+ app.db.rollback()
17
+
18
+
19
+ @app.on_teardown
20
+ def on_teardown():
21
+ if app.db and not app.db.is_closed():
22
+ app.db.close()
@@ -0,0 +1,10 @@
1
+ """Import all the modules in this folder."""
2
+ from importlib import import_module
3
+ from pathlib import Path
4
+ from pkgutil import iter_modules
5
+
6
+
7
+ # iterate through the modules in the current package
8
+ package_dir = str(Path(__file__).resolve().parent)
9
+ for (_, module_name, __) in iter_modules([package_dir]):
10
+ import_module(f"{__name__}.{module_name}")
@@ -0,0 +1,15 @@
1
+ import proper
2
+
3
+ from ..app import app
4
+ from ..views.page import Page
5
+
6
+
7
+ # You can call your own views for handling any kind of exception, not
8
+ # only HTTP exceptions but custom ones or even native Python exceptions
9
+ # like `ValueError` or a catch-all Exception.
10
+ #
11
+ # If `app.config.DEBUG = True`, this also will create test routes
12
+ # (based on the name of the exception class) to preview those pages
13
+ # so you can test their design.
14
+ app.error_handler(proper.errors.NotFound, Page.not_found) # /_not_found
15
+ app.error_handler(Exception, Page.error) # /_exception
@@ -0,0 +1,11 @@
1
+ from mailshake import ToConsoleMailer
2
+
3
+ from ..app import config
4
+
5
+
6
+ mailer = ToConsoleMailer()
7
+
8
+
9
+ def send_email(to, subject, **kw):
10
+ kw.setdefault("from_email", config.MAILER_DEFAULT_FROM)
11
+ mailer.send(to=to, subject=subject, **kw)
@@ -0,0 +1,5 @@
1
+ """
2
+ Import here all the models you want to be detected for migrations
3
+ You can also do `from .your_model import * #noqa` here
4
+ and, in your model file, use `__all__` to define what to import
5
+ """
@@ -0,0 +1,20 @@
1
+ import inflection
2
+ import peewee as pw
3
+
4
+ from ..app import app
5
+
6
+
7
+ def make_table_name(cls):
8
+ return inflection.tableize(cls.__name__)
9
+
10
+
11
+ class BaseModel(pw.Model):
12
+ class Meta:
13
+ database = app.db
14
+ table_function = make_table_name
15
+
16
+
17
+ class BaseMixin(pw.Model):
18
+ class Meta:
19
+ database = app.db
20
+ table_function = make_table_name
@@ -0,0 +1,14 @@
1
+ from datetime import datetime
2
+
3
+ import peewee as pw
4
+
5
+ from [[ app_name ]].models.base import BaseMixin
6
+
7
+
8
+ class Timestamped(BaseMixin):
9
+ created_at = pw.DateTimeField(default=datetime.utcnow, null=True)
10
+ updated_at = pw.DateTimeField(default=datetime.utcnow, null=True)
11
+
12
+ def update(self, *args, **kwargs):
13
+ self.updated_at = datetime.utcnow()
14
+ return super().update(*args, **kwargs)