proper 0.1.dev3__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.
- proper-0.2/PKG-INFO +131 -0
- {proper-0.1.dev3 → proper-0.2}/README.md +7 -9
- proper-0.2/pyproject.toml +222 -0
- proper-0.2/setup.cfg +4 -0
- proper-0.2/src/blueprints/app/[[ app_name ]]/__init__.py +5 -0
- proper-0.2/src/blueprints/app/[[ app_name ]]/app.py +8 -0
- proper-0.2/src/blueprints/app/[[ app_name ]]/cl/__init__.tt.py +5 -0
- proper-0.2/src/blueprints/app/[[ app_name ]]/config/app.tt.py +52 -0
- proper-0.2/src/blueprints/app/[[ app_name ]]/config/database.tt.py +40 -0
- proper-0.2/src/blueprints/app/[[ app_name ]]/config/session.py +13 -0
- proper-0.2/src/blueprints/app/[[ app_name ]]/config/storage.py +8 -0
- proper-0.2/src/blueprints/app/[[ app_name ]]/initializers/1_app.tt.py +25 -0
- proper-0.2/src/blueprints/app/[[ app_name ]]/initializers/2_database.py +22 -0
- proper-0.2/src/blueprints/app/[[ app_name ]]/initializers/__init__.py +10 -0
- proper-0.2/src/blueprints/app/[[ app_name ]]/initializers/error_handlers.py +15 -0
- proper-0.2/src/blueprints/app/[[ app_name ]]/mailers/mailer.py +11 -0
- proper-0.2/src/blueprints/app/[[ app_name ]]/models/__init__.py +5 -0
- proper-0.2/src/blueprints/app/[[ app_name ]]/models/base.py +20 -0
- {proper-0.1.dev3/blueprints/project/db/migrations → proper-0.2/src/blueprints/app/[[ app_name ]]/models/concerns}/__init__.py +0 -0
- proper-0.2/src/blueprints/app/[[ app_name ]]/models/concerns/timestamped.tt.py +14 -0
- proper-0.2/src/blueprints/app/[[ app_name ]]/routes.py +37 -0
- proper-0.2/src/blueprints/app/[[ app_name ]]/views/__init__.py +23 -0
- proper-0.2/src/blueprints/app/[[ app_name ]]/views/app.tt.py +13 -0
- proper-0.1.dev3/blueprints/project/db/seeds.py → proper-0.2/src/blueprints/app/[[ app_name ]]/views/concerns/__init__.py +0 -0
- proper-0.2/src/blueprints/app/[[ app_name ]]/views/concerns/db_connection.tt.py +12 -0
- proper-0.2/src/blueprints/app/[[ app_name ]]/views/concerns/security_headers.py +26 -0
- proper-0.2/src/blueprints/app/[[ app_name ]]/views/page.py +12 -0
- {proper-0.1.dev3/blueprints/project → proper-0.2/src/blueprints/app}/tests/conftest.py +1 -0
- proper-0.2/src/blueprints/app/wsgi.tt.py +1 -0
- proper-0.2/src/blueprints/auth/[[ app_name ]]/app.append.py +1 -0
- proper-0.2/src/blueprints/auth/[[ app_name ]]/cl/__init__.append.py +3 -0
- proper-0.2/src/blueprints/auth/[[ app_name ]]/cl/auth.tt.py +57 -0
- proper-0.2/src/blueprints/auth/[[ app_name ]]/config/app.append.py +2 -0
- proper-0.2/src/blueprints/auth/[[ app_name ]]/config/auth.py +6 -0
- proper-0.2/src/blueprints/auth/[[ app_name ]]/mailers/auth.py +28 -0
- proper-0.2/src/blueprints/auth/[[ app_name ]]/models/__init__.append.py +1 -0
- proper-0.2/src/blueprints/auth/[[ app_name ]]/models/concerns/authenticable.tt.py +134 -0
- proper-0.2/src/blueprints/auth/[[ app_name ]]/models/user.py +10 -0
- proper-0.2/src/blueprints/auth/[[ app_name ]]/views/app.append.py +13 -0
- proper-0.2/src/blueprints/auth/[[ app_name ]]/views/app.prepend.py +4 -0
- proper-0.2/src/blueprints/auth/[[ app_name ]]/views/concerns/load_user.tt.py +37 -0
- proper-0.2/src/blueprints/auth/[[ app_name ]]/views/concerns/require_login.tt.py +20 -0
- proper-0.2/src/blueprints/auth/[[ app_name ]]/views/password/__init__.py +1 -0
- proper-0.2/src/blueprints/auth/[[ app_name ]]/views/password/forms.py +34 -0
- {proper-0.1.dev3/blueprints/project/[[ app_name ]]/controllers/auth → proper-0.2/src/blueprints/auth/[[ app_name ]]/views/password}/pwned.py +4 -5
- proper-0.2/src/blueprints/auth/[[ app_name ]]/views/password/reset.tt.py +61 -0
- proper-0.2/src/blueprints/auth/[[ app_name ]]/views/password/validators.tt.py +48 -0
- proper-0.2/src/blueprints/auth/[[ app_name ]]/views/session/__init__.py +1 -0
- proper-0.2/src/blueprints/auth/[[ app_name ]]/views/session/forms.tt.py +28 -0
- proper-0.2/src/blueprints/auth/[[ app_name ]]/views/session/session.tt.py +36 -0
- proper-0.2/src/blueprints/auth/routes.tt.py +9 -0
- proper-0.2/src/blueprints/i18n/[[ app_name ]]/initializers/i18n.py +5 -0
- proper-0.2/src/blueprints/i18n/[[ app_name ]]/views/app.prepend.py +1 -0
- proper-0.2/src/blueprints/i18n/[[ app_name ]]/views/concerns/set_locale.tt.py +25 -0
- proper-0.2/src/blueprints/model/[[ app_name ]]/models/[[ singular_snake ]].tt.py +9 -0
- proper-0.2/src/blueprints/model/[[ app_name ]]/models/__init__.append.py +1 -0
- proper-0.2/src/blueprints/resource/[[ app_name ]]/views/[[ view_snake ]]/[[ view_snake ]].tt.py +139 -0
- proper-0.2/src/blueprints/resource/[[ app_name ]]/views/[[ view_snake ]]/__init__.tt.py +1 -0
- proper-0.2/src/blueprints/resource/[[ app_name ]]/views/[[ view_snake ]]/forms.tt.py +17 -0
- proper-0.2/src/blueprints/resource/routes.tt.py +9 -0
- proper-0.2/src/blueprints/storage/[[ app_name ]]/config/app.append.py +3 -0
- proper-0.2/src/blueprints/storage/[[ app_name ]]/config/storage.py +48 -0
- proper-0.2/src/blueprints/storage/[[ app_name ]]/models/__init__.append.py +1 -0
- proper-0.2/src/blueprints/storage/[[ app_name ]]/models/attachment.py +8 -0
- proper-0.2/src/blueprints/storage/[[ app_name ]]/views/storage.tt.py +15 -0
- proper-0.2/src/blueprints/storage/routes.tt.py +5 -0
- proper-0.2/src/blueprints/view/[[ app_name ]]/views/[[ plural_snake ]].tt.py +9 -0
- proper-0.2/src/blueprints/view/routes.tt.py +5 -0
- proper-0.2/src/proper/__init__.py +19 -0
- proper-0.2/src/proper/auth/__init__.py +2 -0
- {proper-0.1.dev3/proper → proper-0.2/src/proper/auth}/auth.py +150 -132
- proper-0.2/src/proper/auth/install.py +54 -0
- proper-0.2/src/proper/cache/__init__.py +2 -0
- proper-0.2/src/proper/cache/base.py +28 -0
- proper-0.2/src/proper/cache/sqlite_cache.py +159 -0
- proper-0.2/src/proper/cl/__init__.py +25 -0
- proper-0.2/src/proper/cl/app_cl.py +149 -0
- proper-0.2/src/proper/cl/db_cl.py +66 -0
- proper-0.2/src/proper/cl/proper_cl.py +17 -0
- proper-0.2/src/proper/concerns/__init__.py +2 -0
- proper-0.2/src/proper/concerns/request_forgery_protection.py +143 -0
- proper-0.2/src/proper/concerns/session.py +81 -0
- proper-0.2/src/proper/constants.py +15 -0
- proper-0.2/src/proper/core/__init__.py +1 -0
- proper-0.2/src/proper/core/app.py +471 -0
- proper-0.2/src/proper/core/app_test.py +293 -0
- proper-0.2/src/proper/core/config.py +102 -0
- proper-0.2/src/proper/core/error_handlers.py +155 -0
- {proper-0.1.dev3/proper/middleware → proper-0.2/src/proper/core/pipeline}/__init__.py +0 -2
- proper-0.2/src/proper/core/pipeline/dispatch.py +27 -0
- proper-0.2/src/proper/core/pipeline/head.py +22 -0
- proper-0.2/src/proper/core/pipeline/match.py +27 -0
- proper-0.2/src/proper/core/pipeline/method_override.py +40 -0
- proper-0.2/src/proper/core/pipeline/redirect.py +26 -0
- proper-0.2/src/proper/current.py +12 -0
- {proper-0.1.dev3 → proper-0.2/src}/proper/errors.py +142 -32
- proper-0.2/src/proper/generators/__init__.py +4 -0
- proper-0.2/src/proper/generators/app.py +90 -0
- proper-0.2/src/proper/generators/model.py +204 -0
- proper-0.2/src/proper/generators/resource.py +223 -0
- proper-0.2/src/proper/generators/view.py +68 -0
- proper-0.2/src/proper/helpers/__init__.py +16 -0
- {proper-0.1.dev3 → proper-0.2/src}/proper/helpers/digestor.py +8 -6
- proper-0.2/src/proper/helpers/dotdict.py +70 -0
- proper-0.2/src/proper/helpers/http.py +72 -0
- proper-0.2/src/proper/helpers/jsonplus.py +43 -0
- proper-0.2/src/proper/helpers/mixins.py +23 -0
- proper-0.2/src/proper/helpers/multidict.py +163 -0
- proper-0.2/src/proper/helpers/proxy.py +82 -0
- proper-0.2/src/proper/helpers/render.py +339 -0
- proper-0.2/src/proper/helpers/server.py +64 -0
- proper-0.2/src/proper/helpers/utils.py +241 -0
- proper-0.2/src/proper/i18n/__init__.py +2 -0
- proper-0.2/src/proper/i18n/i18n.py +341 -0
- proper-0.2/src/proper/i18n/install.py +55 -0
- proper-0.2/src/proper/i18n/plural_rules.py +1545 -0
- proper-0.2/src/proper/i18n/reader.py +81 -0
- proper-0.2/src/proper/request/__init__.py +2 -0
- proper-0.2/src/proper/request/forwarded.py +121 -0
- proper-0.2/src/proper/request/headers.py +544 -0
- proper-0.2/src/proper/request/make_env.py +50 -0
- proper-0.2/src/proper/request/multipart.py +429 -0
- proper-0.2/src/proper/request/parse_form.py +168 -0
- proper-0.2/src/proper/request/request.py +333 -0
- proper-0.2/src/proper/response/__init__.py +1 -0
- proper-0.2/src/proper/response/cookies.py +262 -0
- proper-0.2/src/proper/response/file_wrapper.py +58 -0
- proper-0.2/src/proper/response/flash_dict.py +46 -0
- proper-0.2/src/proper/response/headers.py +609 -0
- proper-0.2/src/proper/response/response.py +315 -0
- {proper-0.1.dev3 → proper-0.2/src}/proper/router/__init__.py +1 -1
- proper-0.2/src/proper/router/resource.py +157 -0
- proper-0.2/src/proper/router/route.py +950 -0
- {proper-0.1.dev3 → proper-0.2/src}/proper/router/router.py +55 -23
- {proper-0.1.dev3 → proper-0.2/src}/proper/router/scope.py +32 -11
- proper-0.2/src/proper/router/static.py +108 -0
- proper-0.2/src/proper/status.py +210 -0
- proper-0.2/src/proper/storage/__init__.py +3 -0
- proper-0.2/src/proper/storage/attachment.py +98 -0
- proper-0.2/src/proper/storage/install.py +47 -0
- proper-0.2/src/proper/storage/services/__init__.py +1 -0
- proper-0.2/src/proper/storage/services/disk.py +46 -0
- proper-0.2/src/proper/storage/services/service.py +27 -0
- proper-0.2/src/proper/storage/storage.py +108 -0
- proper-0.2/src/proper/storage/types.py +18 -0
- proper-0.2/src/proper/types.py +13 -0
- proper-0.2/src/proper/view.py +190 -0
- proper-0.2/src/proper.egg-info/PKG-INFO +131 -0
- proper-0.2/src/proper.egg-info/SOURCES.txt +160 -0
- proper-0.2/src/proper.egg-info/entry_points.txt +2 -0
- proper-0.2/src/proper.egg-info/requires.txt +26 -0
- proper-0.2/src/proper.egg-info/top_level.txt +2 -0
- proper-0.2/tests/test_e2e_errors.py +202 -0
- proper-0.2/tests/test_e2e_hello.py +52 -0
- proper-0.2/tests/test_e2e_middleware.py +74 -0
- proper-0.2/tests/test_e2e_response.py +108 -0
- proper-0.2/tests/test_e2e_router.py +136 -0
- proper-0.1.dev3/MANIFEST.in +0 -4
- proper-0.1.dev3/PKG-INFO +0 -87
- proper-0.1.dev3/blueprints/controller/[[ app_name ]]/controllers/[[ snake_name ]].py.tmpl +0 -9
- proper-0.1.dev3/blueprints/controller/[[ app_name ]]/controllers/__init__.py.append +0 -1
- proper-0.1.dev3/blueprints/controller/routes.py.tmpl +0 -5
- proper-0.1.dev3/blueprints/controller/template.html.jinja.tmpl +0 -6
- proper-0.1.dev3/blueprints/migration/db/migrations/[[ dt ]]_[[ snake_name ]].py.tmpl +0 -40
- proper-0.1.dev3/blueprints/model/[[ app_name ]]/models/[[ snake_name ]].py.tmpl +0 -5
- proper-0.1.dev3/blueprints/model/[[ app_name ]]/models/__init__.py.append +0 -1
- proper-0.1.dev3/blueprints/project/.gitignore +0 -3
- proper-0.1.dev3/blueprints/project/.vscode/settings.json +0 -3
- proper-0.1.dev3/blueprints/project/Makefile.tmpl +0 -59
- proper-0.1.dev3/blueprints/project/Procfile.dev +0 -4
- proper-0.1.dev3/blueprints/project/README.md.tmpl +0 -4
- proper-0.1.dev3/blueprints/project/[[ app_name ]]/__init__.py +0 -1
- proper-0.1.dev3/blueprints/project/[[ app_name ]]/adapters/__init__.py +0 -3
- proper-0.1.dev3/blueprints/project/[[ app_name ]]/adapters/mailer_adapter.py +0 -15
- proper-0.1.dev3/blueprints/project/[[ app_name ]]/adapters/redis_adapter.py +0 -8
- proper-0.1.dev3/blueprints/project/[[ app_name ]]/app.py.tmpl +0 -6
- proper-0.1.dev3/blueprints/project/[[ app_name ]]/config/__init__.py +0 -47
- proper-0.1.dev3/blueprints/project/[[ app_name ]]/config/development.py.tmpl +0 -2
- proper-0.1.dev3/blueprints/project/[[ app_name ]]/config/production.py.tmpl +0 -18
- proper-0.1.dev3/blueprints/project/[[ app_name ]]/config/shared.py.tmpl +0 -57
- proper-0.1.dev3/blueprints/project/[[ app_name ]]/config/staging.py.tmpl +0 -2
- proper-0.1.dev3/blueprints/project/[[ app_name ]]/config/testing.py.tmpl +0 -6
- proper-0.1.dev3/blueprints/project/[[ app_name ]]/controllers/__init__.py +0 -4
- proper-0.1.dev3/blueprints/project/[[ app_name ]]/controllers/application.py +0 -79
- proper-0.1.dev3/blueprints/project/[[ app_name ]]/controllers/auth/__init__.py.tmpl +0 -79
- proper-0.1.dev3/blueprints/project/[[ app_name ]]/controllers/auth/forms.py +0 -26
- proper-0.1.dev3/blueprints/project/[[ app_name ]]/controllers/auth/validators.py.tmpl +0 -45
- proper-0.1.dev3/blueprints/project/[[ app_name ]]/controllers/pages.py +0 -12
- proper-0.1.dev3/blueprints/project/[[ app_name ]]/jobs/__init__.py +0 -17
- proper-0.1.dev3/blueprints/project/[[ app_name ]]/jobs/emails.py +0 -11
- proper-0.1.dev3/blueprints/project/[[ app_name ]]/mailers/auth.py +0 -32
- proper-0.1.dev3/blueprints/project/[[ app_name ]]/main.py +0 -29
- proper-0.1.dev3/blueprints/project/[[ app_name ]]/manage.py +0 -115
- proper-0.1.dev3/blueprints/project/[[ app_name ]]/models/__init__.py +0 -5
- proper-0.1.dev3/blueprints/project/[[ app_name ]]/models/base.py +0 -19
- proper-0.1.dev3/blueprints/project/[[ app_name ]]/models/mixins/__init__.py +0 -2
- proper-0.1.dev3/blueprints/project/[[ app_name ]]/models/mixins/authenticable.py.tmpl +0 -106
- proper-0.1.dev3/blueprints/project/[[ app_name ]]/models/mixins/representable.py +0 -33
- proper-0.1.dev3/blueprints/project/[[ app_name ]]/models/user.py +0 -10
- proper-0.1.dev3/blueprints/project/[[ app_name ]]/routes.py.tmpl +0 -35
- proper-0.1.dev3/blueprints/project/[[ app_name ]]/templates/_flashes.html.jinja +0 -13
- proper-0.1.dev3/blueprints/project/[[ app_name ]]/templates/auth/password_change.html.jinja +0 -51
- proper-0.1.dev3/blueprints/project/[[ app_name ]]/templates/auth/reset.html.jinja +0 -41
- proper-0.1.dev3/blueprints/project/[[ app_name ]]/templates/auth/reset_invalid.html.jinja +0 -17
- proper-0.1.dev3/blueprints/project/[[ app_name ]]/templates/auth/reset_sent.html.jinja +0 -20
- proper-0.1.dev3/blueprints/project/[[ app_name ]]/templates/auth/sign_in.html.jinja +0 -56
- proper-0.1.dev3/blueprints/project/[[ app_name ]]/templates/emails/password_reset.html.jinja +0 -14
- proper-0.1.dev3/blueprints/project/[[ app_name ]]/templates/layouts/application.html.jinja +0 -17
- proper-0.1.dev3/blueprints/project/[[ app_name ]]/templates/layouts/auth.html.jinja +0 -18
- proper-0.1.dev3/blueprints/project/[[ app_name ]]/templates/layouts/email.html.jinja +0 -12
- proper-0.1.dev3/blueprints/project/[[ app_name ]]/templates/pages/error.html.jinja +0 -13
- proper-0.1.dev3/blueprints/project/[[ app_name ]]/templates/pages/index.html.jinja +0 -9
- proper-0.1.dev3/blueprints/project/[[ app_name ]]/templates/pages/not_found.html.jinja +0 -15
- proper-0.1.dev3/blueprints/project/[[ app_name ]]/workers.py +0 -20
- proper-0.1.dev3/blueprints/project/bin/manage.tmpl +0 -5
- proper-0.1.dev3/blueprints/project/bin/run +0 -3
- proper-0.1.dev3/blueprints/project/bin/workers.tmpl +0 -5
- proper-0.1.dev3/blueprints/project/db/migrations/[[ datestamp ]]_create_users.py.tmpl +0 -20
- proper-0.1.dev3/blueprints/project/requirements/dev-requirements.txt +0 -13
- proper-0.1.dev3/blueprints/project/requirements/prod-requirements.txt +0 -4
- proper-0.1.dev3/blueprints/project/requirements/requirements.txt +0 -13
- proper-0.1.dev3/blueprints/project/setup.cfg.tmpl +0 -49
- proper-0.1.dev3/blueprints/project/setup.py +0 -1
- proper-0.1.dev3/blueprints/project/static/.eslintrc.js +0 -38
- proper-0.1.dev3/blueprints/project/static/package.json +0 -27
- proper-0.1.dev3/blueprints/project/static/postcss.config.js +0 -13
- proper-0.1.dev3/blueprints/project/static/public/apple-touch-icon.png +0 -0
- proper-0.1.dev3/blueprints/project/static/public/favicon.ico +0 -0
- proper-0.1.dev3/blueprints/project/static/public/favicon.svg +0 -1
- proper-0.1.dev3/blueprints/project/static/public/fonts/.keep +0 -0
- proper-0.1.dev3/blueprints/project/static/public/google-touch-icon.png +0 -0
- proper-0.1.dev3/blueprints/project/static/public/humans.txt +0 -1
- proper-0.1.dev3/blueprints/project/static/public/images/.keep +0 -0
- proper-0.1.dev3/blueprints/project/static/public/js/.keep +0 -0
- proper-0.1.dev3/blueprints/project/static/public/robots.txt +0 -2
- proper-0.1.dev3/blueprints/project/static/src/css/_base.css +0 -8
- proper-0.1.dev3/blueprints/project/static/src/css/_components.css +0 -1
- proper-0.1.dev3/blueprints/project/static/src/css/_fonts.css +0 -1
- proper-0.1.dev3/blueprints/project/static/src/css/_forms.css +0 -100
- proper-0.1.dev3/blueprints/project/static/src/css/_utilities.css +0 -2
- proper-0.1.dev3/blueprints/project/static/src/css/common.css +0 -4
- proper-0.1.dev3/blueprints/project/static/src/css/email.css +0 -3
- proper-0.1.dev3/blueprints/project/static/src/js/scripts.js +0 -0
- proper-0.1.dev3/blueprints/project/static/tailwind.config.js.tmpl +0 -10
- proper-0.1.dev3/blueprints/project/static/webpack.config.js +0 -17
- proper-0.1.dev3/blueprints/project/uwsgi-dev.ini +0 -12
- proper-0.1.dev3/blueprints/project/wsgi.py.tmpl +0 -4
- proper-0.1.dev3/blueprints/resource/[[ app_name ]]/controllers/[[ snake_name ]].py.tmpl +0 -38
- proper-0.1.dev3/blueprints/resource/[[ app_name ]]/controllers/__init__.py.append +0 -1
- proper-0.1.dev3/blueprints/resource/[[ app_name ]]/templates/[[ snake_name ]]/edit.html.jinja +0 -6
- proper-0.1.dev3/blueprints/resource/[[ app_name ]]/templates/[[ snake_name ]]/index.html.jinja +0 -6
- proper-0.1.dev3/blueprints/resource/[[ app_name ]]/templates/[[ snake_name ]]/new.html.jinja +0 -6
- proper-0.1.dev3/blueprints/resource/[[ app_name ]]/templates/[[ snake_name ]]/show.html.jinja +0 -6
- proper-0.1.dev3/blueprints/resource/routes.py.tmpl +0 -5
- proper-0.1.dev3/proper/__init__.py +0 -9
- proper-0.1.dev3/proper/app/__init__.py +0 -1
- proper-0.1.dev3/proper/app/app.py +0 -99
- proper-0.1.dev3/proper/app/cli.py +0 -110
- proper-0.1.dev3/proper/app/default_config.py +0 -37
- proper-0.1.dev3/proper/app/error_handlers.py +0 -103
- proper-0.1.dev3/proper/app/errors_mixin.py +0 -91
- proper-0.1.dev3/proper/app/setup_mixin.py +0 -170
- proper-0.1.dev3/proper/app/templates/_context.html.jinja +0 -61
- proper-0.1.dev3/proper/app/templates/_debug-styles.css +0 -100
- proper-0.1.dev3/proper/app/templates/_prism.css +0 -228
- proper-0.1.dev3/proper/app/templates/_prism.js +0 -4
- proper-0.1.dev3/proper/app/templates/debug-error.html.jinja +0 -14
- proper-0.1.dev3/proper/app/templates/debug-not-found.html.jinja +0 -61
- proper-0.1.dev3/proper/app/templates/fallback-error.html +0 -41
- proper-0.1.dev3/proper/app/templates/fallback-forbidden.html +0 -54
- proper-0.1.dev3/proper/app/templates/fallback-not-found.html +0 -42
- proper-0.1.dev3/proper/app/templates/layout.html.jinja +0 -21
- proper-0.1.dev3/proper/cli.py +0 -37
- proper-0.1.dev3/proper/constants.py +0 -12
- proper-0.1.dev3/proper/controller/__init__.py +0 -1
- proper-0.1.dev3/proper/controller/base_channel.py +0 -26
- proper-0.1.dev3/proper/controller/base_controller.py +0 -71
- proper-0.1.dev3/proper/generators/__init__.py +0 -5
- proper-0.1.dev3/proper/generators/controller.py +0 -56
- proper-0.1.dev3/proper/generators/mailer.py +0 -13
- proper-0.1.dev3/proper/generators/migration.py +0 -181
- proper-0.1.dev3/proper/generators/model.py +0 -42
- proper-0.1.dev3/proper/generators/project.py +0 -93
- proper-0.1.dev3/proper/generators/resource.py +0 -81
- proper-0.1.dev3/proper/helpers/__init__.py +0 -12
- proper-0.1.dev3/proper/helpers/cookies.py +0 -161
- proper-0.1.dev3/proper/helpers/dot.py +0 -98
- proper-0.1.dev3/proper/helpers/encoding.py +0 -25
- proper-0.1.dev3/proper/helpers/frozendict.py +0 -56
- proper-0.1.dev3/proper/helpers/headersdict.py +0 -13
- proper-0.1.dev3/proper/helpers/iterable.py +0 -8
- proper-0.1.dev3/proper/helpers/multidict.py +0 -122
- proper-0.1.dev3/proper/helpers/paginator.py +0 -338
- proper-0.1.dev3/proper/helpers/render.py +0 -214
- proper-0.1.dev3/proper/helpers/serializer.py +0 -40
- proper-0.1.dev3/proper/helpers/slugify.py +0 -69
- proper-0.1.dev3/proper/local.py +0 -63
- proper-0.1.dev3/proper/middleware/README.md +0 -7
- proper-0.1.dev3/proper/middleware/dispatch.py +0 -46
- proper-0.1.dev3/proper/middleware/head.py +0 -19
- proper-0.1.dev3/proper/middleware/match.py +0 -18
- proper-0.1.dev3/proper/middleware/method_override.py +0 -30
- proper-0.1.dev3/proper/middleware/protect_from_forgery.py +0 -72
- proper-0.1.dev3/proper/middleware/redirect.py +0 -18
- proper-0.1.dev3/proper/middleware/session.py +0 -64
- proper-0.1.dev3/proper/parsers/__init__.py +0 -5
- proper-0.1.dev3/proper/parsers/parse_comma_separated.py +0 -13
- proper-0.1.dev3/proper/parsers/parse_cookies.py +0 -25
- proper-0.1.dev3/proper/parsers/parse_form_data.py +0 -125
- proper-0.1.dev3/proper/parsers/parse_http_date.py +0 -15
- proper-0.1.dev3/proper/parsers/parse_query_string.py +0 -46
- proper-0.1.dev3/proper/request.py +0 -384
- proper-0.1.dev3/proper/response.py +0 -350
- proper-0.1.dev3/proper/router/base.py +0 -158
- proper-0.1.dev3/proper/router/resource.py +0 -118
- proper-0.1.dev3/proper/router/route.py +0 -179
- proper-0.1.dev3/proper/server.py +0 -39
- proper-0.1.dev3/proper/static.py +0 -152
- proper-0.1.dev3/proper/status.py +0 -209
- proper-0.1.dev3/proper.egg-info/PKG-INFO +0 -87
- proper-0.1.dev3/proper.egg-info/SOURCES.txt +0 -185
- proper-0.1.dev3/proper.egg-info/entry_points.txt +0 -3
- proper-0.1.dev3/proper.egg-info/requires.txt +0 -28
- proper-0.1.dev3/proper.egg-info/top_level.txt +0 -1
- proper-0.1.dev3/setup.cfg +0 -100
- proper-0.1.dev3/setup.py +0 -5
- {proper-0.1.dev3 → proper-0.2}/MIT-LICENSE +0 -0
- {proper-0.1.dev3/blueprints/project/db → proper-0.2/src/blueprints/app/[[ app_name ]]/config}/__init__.py +0 -0
- {proper-0.1.dev3/blueprints/project → proper-0.2/src/blueprints/app}/[[ app_name ]]/mailers/__init__.py +0 -0
- /proper-0.1.dev3/blueprints/project/static/public/css/.keep → /proper-0.2/src/proper/py.typed +0 -0
- {proper-0.1.dev3 → 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
|
+

|
|
@@ -7,7 +7,7 @@ A web framework optimized for programmer happiness.
|
|
|
7
7
|
|
|
8
8
|
### Requirements
|
|
9
9
|
|
|
10
|
-
- Python 3.
|
|
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
|
|
65
|
-
- Class-based
|
|
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
|
|
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
|
+

|
|
@@ -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,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,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
|
|
File without changes
|
|
@@ -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)
|