From 01af126c3de93900b86bd57e9494e5c5f1493e18 Mon Sep 17 00:00:00 2001 From: Michael Kennedy Date: Tue, 30 Jul 2019 08:18:11 -0700 Subject: [PATCH 01/44] Pre-create db folder for users, fixes #4 --- app/ch09_sqlalchemy/starter/pypi_org/db/placeholder.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 app/ch09_sqlalchemy/starter/pypi_org/db/placeholder.txt diff --git a/app/ch09_sqlalchemy/starter/pypi_org/db/placeholder.txt b/app/ch09_sqlalchemy/starter/pypi_org/db/placeholder.txt new file mode 100644 index 00000000..f7c55980 --- /dev/null +++ b/app/ch09_sqlalchemy/starter/pypi_org/db/placeholder.txt @@ -0,0 +1 @@ +Just here so git will create this folder. \ No newline at end of file From 4bef5a89cddfccb7634d3ac2b2caabb9ef1ccc19 Mon Sep 17 00:00:00 2001 From: Tim Phillips Date: Thu, 5 Sep 2019 20:58:10 -0400 Subject: [PATCH 02/44] Update view_modifiers.py I get an import error when trying to import `werkzeug.wrappers.response` but works fine with `werkzeug.wrappers` --- .../final/pypi_org/infrastructure/view_modifiers.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/ch12-forms/final/pypi_org/infrastructure/view_modifiers.py b/app/ch12-forms/final/pypi_org/infrastructure/view_modifiers.py index 82ce5baf..a8d228d1 100644 --- a/app/ch12-forms/final/pypi_org/infrastructure/view_modifiers.py +++ b/app/ch12-forms/final/pypi_org/infrastructure/view_modifiers.py @@ -1,7 +1,7 @@ from functools import wraps import flask -import werkzeug.wrappers.response +import werkzeug.wrappers def response(*, mimetype: str = None, template_file: str = None): @@ -13,7 +13,7 @@ def view_method(*args, **kwargs): response_val = f(*args, **kwargs) if isinstance(response_val, flask.Response): return response_val - if isinstance(response_val, werkzeug.wrappers.response.Response): + if isinstance(response_val, werkzeug.wrappers.Response): return response_val if isinstance(response_val, dict): From 0e593fe685bc38c919b2df0ec33ad67c31dc1c06 Mon Sep 17 00:00:00 2001 From: Michael Kennedy Date: Tue, 10 Sep 2019 18:49:24 -0700 Subject: [PATCH 03/44] Local project for this part of the code. --- .../final/.idea/dataSources.local.xml | 6 ++++- .../final/.idea/flask-html-forms.iml | 2 +- .../inspectionProfiles/Project_Default.xml | 24 +++++++++++++++++++ app/ch12-forms/final/.idea/misc.xml | 2 +- 4 files changed, 31 insertions(+), 3 deletions(-) create mode 100644 app/ch12-forms/final/.idea/inspectionProfiles/Project_Default.xml diff --git a/app/ch12-forms/final/.idea/dataSources.local.xml b/app/ch12-forms/final/.idea/dataSources.local.xml index 94233bb2..298cdef1 100644 --- a/app/ch12-forms/final/.idea/dataSources.local.xml +++ b/app/ch12-forms/final/.idea/dataSources.local.xml @@ -7,7 +7,11 @@ false - *:@ + + + + + \ No newline at end of file diff --git a/app/ch12-forms/final/.idea/flask-html-forms.iml b/app/ch12-forms/final/.idea/flask-html-forms.iml index 7401e3f0..776f1339 100644 --- a/app/ch12-forms/final/.idea/flask-html-forms.iml +++ b/app/ch12-forms/final/.idea/flask-html-forms.iml @@ -4,7 +4,7 @@ - + diff --git a/app/ch12-forms/final/.idea/inspectionProfiles/Project_Default.xml b/app/ch12-forms/final/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 00000000..274983bd --- /dev/null +++ b/app/ch12-forms/final/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,24 @@ + + + + \ No newline at end of file diff --git a/app/ch12-forms/final/.idea/misc.xml b/app/ch12-forms/final/.idea/misc.xml index 09f951f2..4b1ba25d 100644 --- a/app/ch12-forms/final/.idea/misc.xml +++ b/app/ch12-forms/final/.idea/misc.xml @@ -3,5 +3,5 @@ - + \ No newline at end of file From 19a72d9aad3ab41629bb7d614744c8311f75a823 Mon Sep 17 00:00:00 2001 From: FEsmondeWhite <35807628+FEsmondeWhite@users.noreply.github.com> Date: Tue, 24 Sep 2019 20:41:57 -0400 Subject: [PATCH 04/44] Fix Exception that will occur later in course. Exception will occur at time 4:15 in the video "User input and HTML forms: Getting the submitted values" of course "Building data-driven web apps with Flask and SQLAlchemy". This exception happens because the flask.redirect() returns a werkzeug.wrappers.response.Response. The inserted condition will check for this response and return the redirect correctly. This fix likely needs to be added to other versions in the course files. For more info, see email to Michael titled "please help: Exception in course 'building data-driven web apps...'" dated Sep 24, 2019, 1:48 PM. --- .../final/pypi_org/infrastructure/view_modifiers.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/ch05_jinja_templates/final/pypi_org/infrastructure/view_modifiers.py b/app/ch05_jinja_templates/final/pypi_org/infrastructure/view_modifiers.py index 5bb6c178..307df851 100644 --- a/app/ch05_jinja_templates/final/pypi_org/infrastructure/view_modifiers.py +++ b/app/ch05_jinja_templates/final/pypi_org/infrastructure/view_modifiers.py @@ -10,6 +10,10 @@ def response_inner(f): @wraps(f) def view_method(*args, **kwargs): response_val = f(*args, **kwargs) + + if isinstance(response_val, werkzeug.wrappers.response.Response): + return response_val + if isinstance(response_val, flask.Response): return response_val From 5fc6cd49626364a5fc2f004242a6eae7f2bfec9b Mon Sep 17 00:00:00 2001 From: turova <595999+turova@users.noreply.github.com> Date: Sat, 28 Sep 2019 14:15:39 -0400 Subject: [PATCH 05/44] Add missing werkzeug import --- .../final/pypi_org/infrastructure/view_modifiers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/ch05_jinja_templates/final/pypi_org/infrastructure/view_modifiers.py b/app/ch05_jinja_templates/final/pypi_org/infrastructure/view_modifiers.py index 307df851..79f8dcf6 100644 --- a/app/ch05_jinja_templates/final/pypi_org/infrastructure/view_modifiers.py +++ b/app/ch05_jinja_templates/final/pypi_org/infrastructure/view_modifiers.py @@ -1,5 +1,5 @@ from functools import wraps - +import werkzeug import flask From 68bf1f3f0ff8a6b67754cb70b835f1ac3c7ce9fd Mon Sep 17 00:00:00 2001 From: Michael Kennedy Date: Thu, 10 Oct 2019 13:48:30 -0700 Subject: [PATCH 06/44] Expected dictionary got response error, fixes #8 --- .../final/pypi_org/infrastructure/view_modifiers.py | 6 ++++-- .../final/pypi_org/infrastructure/view_modifiers.py | 6 ++++++ .../starter/pypi_org/infrastructure/view_modifiers.py | 6 ++++++ .../final/pypi_org/infrastructure/view_modifiers.py | 6 ++++++ .../starter/pypi_org/infrastructure/view_modifiers.py | 6 ++++++ .../final/pypi_org/infrastructure/view_modifiers.py | 6 ++++++ .../starter/pypi_org/infrastructure/view_modifiers.py | 6 ++++++ .../final/pypi_org/infrastructure/view_modifiers.py | 6 ++++++ .../starter/pypi_org/infrastructure/view_modifiers.py | 6 ++++++ .../final/pypi_org/infrastructure/view_modifiers.py | 7 +++++++ .../starter/pypi_org/infrastructure/view_modifiers.py | 6 ++++++ .../final/pypi_org/infrastructure/view_modifiers.py | 7 +++++-- .../starter/pypi_org/infrastructure/view_modifiers.py | 6 ++++++ .../final/pypi_org/infrastructure/view_modifiers.py | 9 ++++++--- .../starter/pypi_org/infrastructure/view_modifiers.py | 9 ++++++--- .../final/pypi_org/infrastructure/view_modifiers.py | 9 ++++++--- .../starter/pypi_org/infrastructure/view_modifiers.py | 9 ++++++--- .../final/pypi_org/infrastructure/view_modifiers.py | 9 ++++++--- app/ch15_deploy/final/requirements.txt | 3 +-- .../starter/pypi_org/infrastructure/view_modifiers.py | 9 ++++++--- .../final/pypi_org/infrastructure/view_modifiers.py | 9 ++++++--- .../starter/pypi_org/infrastructure/view_modifiers.py | 9 ++++++--- 22 files changed, 125 insertions(+), 30 deletions(-) diff --git a/app/ch05_jinja_templates/final/pypi_org/infrastructure/view_modifiers.py b/app/ch05_jinja_templates/final/pypi_org/infrastructure/view_modifiers.py index 307df851..0978163e 100644 --- a/app/ch05_jinja_templates/final/pypi_org/infrastructure/view_modifiers.py +++ b/app/ch05_jinja_templates/final/pypi_org/infrastructure/view_modifiers.py @@ -1,6 +1,8 @@ from functools import wraps import flask +import werkzeug +import werkzeug.wrappers def response(*, mimetype: str = None, template_file: str = None): @@ -11,9 +13,9 @@ def response_inner(f): def view_method(*args, **kwargs): response_val = f(*args, **kwargs) - if isinstance(response_val, werkzeug.wrappers.response.Response): + if isinstance(response_val, werkzeug.wrappers.Response): return response_val - + if isinstance(response_val, flask.Response): return response_val diff --git a/app/ch06_routing/final/pypi_org/infrastructure/view_modifiers.py b/app/ch06_routing/final/pypi_org/infrastructure/view_modifiers.py index 5bb6c178..0978163e 100644 --- a/app/ch06_routing/final/pypi_org/infrastructure/view_modifiers.py +++ b/app/ch06_routing/final/pypi_org/infrastructure/view_modifiers.py @@ -1,6 +1,8 @@ from functools import wraps import flask +import werkzeug +import werkzeug.wrappers def response(*, mimetype: str = None, template_file: str = None): @@ -10,6 +12,10 @@ def response_inner(f): @wraps(f) def view_method(*args, **kwargs): response_val = f(*args, **kwargs) + + if isinstance(response_val, werkzeug.wrappers.Response): + return response_val + if isinstance(response_val, flask.Response): return response_val diff --git a/app/ch06_routing/starter/pypi_org/infrastructure/view_modifiers.py b/app/ch06_routing/starter/pypi_org/infrastructure/view_modifiers.py index 5bb6c178..0978163e 100644 --- a/app/ch06_routing/starter/pypi_org/infrastructure/view_modifiers.py +++ b/app/ch06_routing/starter/pypi_org/infrastructure/view_modifiers.py @@ -1,6 +1,8 @@ from functools import wraps import flask +import werkzeug +import werkzeug.wrappers def response(*, mimetype: str = None, template_file: str = None): @@ -10,6 +12,10 @@ def response_inner(f): @wraps(f) def view_method(*args, **kwargs): response_val = f(*args, **kwargs) + + if isinstance(response_val, werkzeug.wrappers.Response): + return response_val + if isinstance(response_val, flask.Response): return response_val diff --git a/app/ch08_adding_our_design/final/pypi_org/infrastructure/view_modifiers.py b/app/ch08_adding_our_design/final/pypi_org/infrastructure/view_modifiers.py index 5bb6c178..0978163e 100644 --- a/app/ch08_adding_our_design/final/pypi_org/infrastructure/view_modifiers.py +++ b/app/ch08_adding_our_design/final/pypi_org/infrastructure/view_modifiers.py @@ -1,6 +1,8 @@ from functools import wraps import flask +import werkzeug +import werkzeug.wrappers def response(*, mimetype: str = None, template_file: str = None): @@ -10,6 +12,10 @@ def response_inner(f): @wraps(f) def view_method(*args, **kwargs): response_val = f(*args, **kwargs) + + if isinstance(response_val, werkzeug.wrappers.Response): + return response_val + if isinstance(response_val, flask.Response): return response_val diff --git a/app/ch08_adding_our_design/starter/pypi_org/infrastructure/view_modifiers.py b/app/ch08_adding_our_design/starter/pypi_org/infrastructure/view_modifiers.py index 5bb6c178..0978163e 100644 --- a/app/ch08_adding_our_design/starter/pypi_org/infrastructure/view_modifiers.py +++ b/app/ch08_adding_our_design/starter/pypi_org/infrastructure/view_modifiers.py @@ -1,6 +1,8 @@ from functools import wraps import flask +import werkzeug +import werkzeug.wrappers def response(*, mimetype: str = None, template_file: str = None): @@ -10,6 +12,10 @@ def response_inner(f): @wraps(f) def view_method(*args, **kwargs): response_val = f(*args, **kwargs) + + if isinstance(response_val, werkzeug.wrappers.Response): + return response_val + if isinstance(response_val, flask.Response): return response_val diff --git a/app/ch09_sqlalchemy/final/pypi_org/infrastructure/view_modifiers.py b/app/ch09_sqlalchemy/final/pypi_org/infrastructure/view_modifiers.py index 5bb6c178..0978163e 100644 --- a/app/ch09_sqlalchemy/final/pypi_org/infrastructure/view_modifiers.py +++ b/app/ch09_sqlalchemy/final/pypi_org/infrastructure/view_modifiers.py @@ -1,6 +1,8 @@ from functools import wraps import flask +import werkzeug +import werkzeug.wrappers def response(*, mimetype: str = None, template_file: str = None): @@ -10,6 +12,10 @@ def response_inner(f): @wraps(f) def view_method(*args, **kwargs): response_val = f(*args, **kwargs) + + if isinstance(response_val, werkzeug.wrappers.Response): + return response_val + if isinstance(response_val, flask.Response): return response_val diff --git a/app/ch09_sqlalchemy/starter/pypi_org/infrastructure/view_modifiers.py b/app/ch09_sqlalchemy/starter/pypi_org/infrastructure/view_modifiers.py index 5bb6c178..0978163e 100644 --- a/app/ch09_sqlalchemy/starter/pypi_org/infrastructure/view_modifiers.py +++ b/app/ch09_sqlalchemy/starter/pypi_org/infrastructure/view_modifiers.py @@ -1,6 +1,8 @@ from functools import wraps import flask +import werkzeug +import werkzeug.wrappers def response(*, mimetype: str = None, template_file: str = None): @@ -10,6 +12,10 @@ def response_inner(f): @wraps(f) def view_method(*args, **kwargs): response_val = f(*args, **kwargs) + + if isinstance(response_val, werkzeug.wrappers.Response): + return response_val + if isinstance(response_val, flask.Response): return response_val diff --git a/app/ch10_using_sqlachemy/final/pypi_org/infrastructure/view_modifiers.py b/app/ch10_using_sqlachemy/final/pypi_org/infrastructure/view_modifiers.py index 5bb6c178..0978163e 100644 --- a/app/ch10_using_sqlachemy/final/pypi_org/infrastructure/view_modifiers.py +++ b/app/ch10_using_sqlachemy/final/pypi_org/infrastructure/view_modifiers.py @@ -1,6 +1,8 @@ from functools import wraps import flask +import werkzeug +import werkzeug.wrappers def response(*, mimetype: str = None, template_file: str = None): @@ -10,6 +12,10 @@ def response_inner(f): @wraps(f) def view_method(*args, **kwargs): response_val = f(*args, **kwargs) + + if isinstance(response_val, werkzeug.wrappers.Response): + return response_val + if isinstance(response_val, flask.Response): return response_val diff --git a/app/ch10_using_sqlachemy/starter/pypi_org/infrastructure/view_modifiers.py b/app/ch10_using_sqlachemy/starter/pypi_org/infrastructure/view_modifiers.py index 5bb6c178..0978163e 100644 --- a/app/ch10_using_sqlachemy/starter/pypi_org/infrastructure/view_modifiers.py +++ b/app/ch10_using_sqlachemy/starter/pypi_org/infrastructure/view_modifiers.py @@ -1,6 +1,8 @@ from functools import wraps import flask +import werkzeug +import werkzeug.wrappers def response(*, mimetype: str = None, template_file: str = None): @@ -10,6 +12,10 @@ def response_inner(f): @wraps(f) def view_method(*args, **kwargs): response_val = f(*args, **kwargs) + + if isinstance(response_val, werkzeug.wrappers.Response): + return response_val + if isinstance(response_val, flask.Response): return response_val diff --git a/app/ch11_migrations/final/pypi_org/infrastructure/view_modifiers.py b/app/ch11_migrations/final/pypi_org/infrastructure/view_modifiers.py index 5bb6c178..0c0941eb 100644 --- a/app/ch11_migrations/final/pypi_org/infrastructure/view_modifiers.py +++ b/app/ch11_migrations/final/pypi_org/infrastructure/view_modifiers.py @@ -1,6 +1,8 @@ from functools import wraps import flask +import werkzeug +import werkzeug.wrappers def response(*, mimetype: str = None, template_file: str = None): @@ -10,6 +12,10 @@ def response_inner(f): @wraps(f) def view_method(*args, **kwargs): response_val = f(*args, **kwargs) + + if isinstance(response_val, werkzeug.wrappers.Response): + return response_val + if isinstance(response_val, flask.Response): return response_val @@ -36,6 +42,7 @@ def view_method(*args, **kwargs): return response_inner + # # def template(template_file: str = None): # def template_inner(f): diff --git a/app/ch11_migrations/starter/pypi_org/infrastructure/view_modifiers.py b/app/ch11_migrations/starter/pypi_org/infrastructure/view_modifiers.py index 5bb6c178..0978163e 100644 --- a/app/ch11_migrations/starter/pypi_org/infrastructure/view_modifiers.py +++ b/app/ch11_migrations/starter/pypi_org/infrastructure/view_modifiers.py @@ -1,6 +1,8 @@ from functools import wraps import flask +import werkzeug +import werkzeug.wrappers def response(*, mimetype: str = None, template_file: str = None): @@ -10,6 +12,10 @@ def response_inner(f): @wraps(f) def view_method(*args, **kwargs): response_val = f(*args, **kwargs) + + if isinstance(response_val, werkzeug.wrappers.Response): + return response_val + if isinstance(response_val, flask.Response): return response_val diff --git a/app/ch12-forms/final/pypi_org/infrastructure/view_modifiers.py b/app/ch12-forms/final/pypi_org/infrastructure/view_modifiers.py index a8d228d1..0978163e 100644 --- a/app/ch12-forms/final/pypi_org/infrastructure/view_modifiers.py +++ b/app/ch12-forms/final/pypi_org/infrastructure/view_modifiers.py @@ -1,6 +1,7 @@ from functools import wraps import flask +import werkzeug import werkzeug.wrappers @@ -11,11 +12,13 @@ def response_inner(f): @wraps(f) def view_method(*args, **kwargs): response_val = f(*args, **kwargs) - if isinstance(response_val, flask.Response): - return response_val + if isinstance(response_val, werkzeug.wrappers.Response): return response_val + if isinstance(response_val, flask.Response): + return response_val + if isinstance(response_val, dict): model = dict(response_val) else: diff --git a/app/ch12-forms/starter/pypi_org/infrastructure/view_modifiers.py b/app/ch12-forms/starter/pypi_org/infrastructure/view_modifiers.py index 5bb6c178..0978163e 100644 --- a/app/ch12-forms/starter/pypi_org/infrastructure/view_modifiers.py +++ b/app/ch12-forms/starter/pypi_org/infrastructure/view_modifiers.py @@ -1,6 +1,8 @@ from functools import wraps import flask +import werkzeug +import werkzeug.wrappers def response(*, mimetype: str = None, template_file: str = None): @@ -10,6 +12,10 @@ def response_inner(f): @wraps(f) def view_method(*args, **kwargs): response_val = f(*args, **kwargs) + + if isinstance(response_val, werkzeug.wrappers.Response): + return response_val + if isinstance(response_val, flask.Response): return response_val diff --git a/app/ch13-validation/final/pypi_org/infrastructure/view_modifiers.py b/app/ch13-validation/final/pypi_org/infrastructure/view_modifiers.py index 82ce5baf..0978163e 100644 --- a/app/ch13-validation/final/pypi_org/infrastructure/view_modifiers.py +++ b/app/ch13-validation/final/pypi_org/infrastructure/view_modifiers.py @@ -1,7 +1,8 @@ from functools import wraps import flask -import werkzeug.wrappers.response +import werkzeug +import werkzeug.wrappers def response(*, mimetype: str = None, template_file: str = None): @@ -11,9 +12,11 @@ def response_inner(f): @wraps(f) def view_method(*args, **kwargs): response_val = f(*args, **kwargs) - if isinstance(response_val, flask.Response): + + if isinstance(response_val, werkzeug.wrappers.Response): return response_val - if isinstance(response_val, werkzeug.wrappers.response.Response): + + if isinstance(response_val, flask.Response): return response_val if isinstance(response_val, dict): diff --git a/app/ch13-validation/starter/pypi_org/infrastructure/view_modifiers.py b/app/ch13-validation/starter/pypi_org/infrastructure/view_modifiers.py index 82ce5baf..0978163e 100644 --- a/app/ch13-validation/starter/pypi_org/infrastructure/view_modifiers.py +++ b/app/ch13-validation/starter/pypi_org/infrastructure/view_modifiers.py @@ -1,7 +1,8 @@ from functools import wraps import flask -import werkzeug.wrappers.response +import werkzeug +import werkzeug.wrappers def response(*, mimetype: str = None, template_file: str = None): @@ -11,9 +12,11 @@ def response_inner(f): @wraps(f) def view_method(*args, **kwargs): response_val = f(*args, **kwargs) - if isinstance(response_val, flask.Response): + + if isinstance(response_val, werkzeug.wrappers.Response): return response_val - if isinstance(response_val, werkzeug.wrappers.response.Response): + + if isinstance(response_val, flask.Response): return response_val if isinstance(response_val, dict): diff --git a/app/ch14_testing/final/pypi_org/infrastructure/view_modifiers.py b/app/ch14_testing/final/pypi_org/infrastructure/view_modifiers.py index 82ce5baf..0978163e 100644 --- a/app/ch14_testing/final/pypi_org/infrastructure/view_modifiers.py +++ b/app/ch14_testing/final/pypi_org/infrastructure/view_modifiers.py @@ -1,7 +1,8 @@ from functools import wraps import flask -import werkzeug.wrappers.response +import werkzeug +import werkzeug.wrappers def response(*, mimetype: str = None, template_file: str = None): @@ -11,9 +12,11 @@ def response_inner(f): @wraps(f) def view_method(*args, **kwargs): response_val = f(*args, **kwargs) - if isinstance(response_val, flask.Response): + + if isinstance(response_val, werkzeug.wrappers.Response): return response_val - if isinstance(response_val, werkzeug.wrappers.response.Response): + + if isinstance(response_val, flask.Response): return response_val if isinstance(response_val, dict): diff --git a/app/ch14_testing/starter/pypi_org/infrastructure/view_modifiers.py b/app/ch14_testing/starter/pypi_org/infrastructure/view_modifiers.py index 82ce5baf..0978163e 100644 --- a/app/ch14_testing/starter/pypi_org/infrastructure/view_modifiers.py +++ b/app/ch14_testing/starter/pypi_org/infrastructure/view_modifiers.py @@ -1,7 +1,8 @@ from functools import wraps import flask -import werkzeug.wrappers.response +import werkzeug +import werkzeug.wrappers def response(*, mimetype: str = None, template_file: str = None): @@ -11,9 +12,11 @@ def response_inner(f): @wraps(f) def view_method(*args, **kwargs): response_val = f(*args, **kwargs) - if isinstance(response_val, flask.Response): + + if isinstance(response_val, werkzeug.wrappers.Response): return response_val - if isinstance(response_val, werkzeug.wrappers.response.Response): + + if isinstance(response_val, flask.Response): return response_val if isinstance(response_val, dict): diff --git a/app/ch15_deploy/final/pypi_org/infrastructure/view_modifiers.py b/app/ch15_deploy/final/pypi_org/infrastructure/view_modifiers.py index 82ce5baf..0978163e 100644 --- a/app/ch15_deploy/final/pypi_org/infrastructure/view_modifiers.py +++ b/app/ch15_deploy/final/pypi_org/infrastructure/view_modifiers.py @@ -1,7 +1,8 @@ from functools import wraps import flask -import werkzeug.wrappers.response +import werkzeug +import werkzeug.wrappers def response(*, mimetype: str = None, template_file: str = None): @@ -11,9 +12,11 @@ def response_inner(f): @wraps(f) def view_method(*args, **kwargs): response_val = f(*args, **kwargs) - if isinstance(response_val, flask.Response): + + if isinstance(response_val, werkzeug.wrappers.Response): return response_val - if isinstance(response_val, werkzeug.wrappers.response.Response): + + if isinstance(response_val, flask.Response): return response_val if isinstance(response_val, dict): diff --git a/app/ch15_deploy/final/requirements.txt b/app/ch15_deploy/final/requirements.txt index e10973d8..e8ba36b0 100644 --- a/app/ch15_deploy/final/requirements.txt +++ b/app/ch15_deploy/final/requirements.txt @@ -1,8 +1,7 @@ -werkzeug flask +werkzeug sqlalchemy progressbar2 python-dateutil passlib - diff --git a/app/ch15_deploy/starter/pypi_org/infrastructure/view_modifiers.py b/app/ch15_deploy/starter/pypi_org/infrastructure/view_modifiers.py index 82ce5baf..0978163e 100644 --- a/app/ch15_deploy/starter/pypi_org/infrastructure/view_modifiers.py +++ b/app/ch15_deploy/starter/pypi_org/infrastructure/view_modifiers.py @@ -1,7 +1,8 @@ from functools import wraps import flask -import werkzeug.wrappers.response +import werkzeug +import werkzeug.wrappers def response(*, mimetype: str = None, template_file: str = None): @@ -11,9 +12,11 @@ def response_inner(f): @wraps(f) def view_method(*args, **kwargs): response_val = f(*args, **kwargs) - if isinstance(response_val, flask.Response): + + if isinstance(response_val, werkzeug.wrappers.Response): return response_val - if isinstance(response_val, werkzeug.wrappers.response.Response): + + if isinstance(response_val, flask.Response): return response_val if isinstance(response_val, dict): diff --git a/app/ch16_mongodb/final/pypi_org/infrastructure/view_modifiers.py b/app/ch16_mongodb/final/pypi_org/infrastructure/view_modifiers.py index 82ce5baf..0978163e 100644 --- a/app/ch16_mongodb/final/pypi_org/infrastructure/view_modifiers.py +++ b/app/ch16_mongodb/final/pypi_org/infrastructure/view_modifiers.py @@ -1,7 +1,8 @@ from functools import wraps import flask -import werkzeug.wrappers.response +import werkzeug +import werkzeug.wrappers def response(*, mimetype: str = None, template_file: str = None): @@ -11,9 +12,11 @@ def response_inner(f): @wraps(f) def view_method(*args, **kwargs): response_val = f(*args, **kwargs) - if isinstance(response_val, flask.Response): + + if isinstance(response_val, werkzeug.wrappers.Response): return response_val - if isinstance(response_val, werkzeug.wrappers.response.Response): + + if isinstance(response_val, flask.Response): return response_val if isinstance(response_val, dict): diff --git a/app/ch16_mongodb/starter/pypi_org/infrastructure/view_modifiers.py b/app/ch16_mongodb/starter/pypi_org/infrastructure/view_modifiers.py index 82ce5baf..0978163e 100644 --- a/app/ch16_mongodb/starter/pypi_org/infrastructure/view_modifiers.py +++ b/app/ch16_mongodb/starter/pypi_org/infrastructure/view_modifiers.py @@ -1,7 +1,8 @@ from functools import wraps import flask -import werkzeug.wrappers.response +import werkzeug +import werkzeug.wrappers def response(*, mimetype: str = None, template_file: str = None): @@ -11,9 +12,11 @@ def response_inner(f): @wraps(f) def view_method(*args, **kwargs): response_val = f(*args, **kwargs) - if isinstance(response_val, flask.Response): + + if isinstance(response_val, werkzeug.wrappers.Response): return response_val - if isinstance(response_val, werkzeug.wrappers.response.Response): + + if isinstance(response_val, flask.Response): return response_val if isinstance(response_val, dict): From d6d5e28f03b9dd2b8f3cc69a029f8bc45994c988 Mon Sep 17 00:00:00 2001 From: Michael Kennedy Date: Thu, 10 Oct 2019 13:50:13 -0700 Subject: [PATCH 07/44] List does't not have attribute lower() error on requestdict, fixes #9 --- .../pypi_org/infrastructure/request_dict.py | 16 ++++++++++++++-- .../final/pypi_org/bin/load_data.py | 8 +------- .../pypi_org/infrastructure/request_dict.py | 16 ++++++++++++++-- .../pypi_org/infrastructure/request_dict.py | 16 ++++++++++++++-- .../pypi_org/infrastructure/request_dict.py | 16 ++++++++++++++-- .../pypi_org/infrastructure/request_dict.py | 16 ++++++++++++++-- .../pypi_org/infrastructure/request_dict.py | 16 ++++++++++++++-- .../pypi_org/infrastructure/request_dict.py | 16 ++++++++++++++-- .../pypi_org/infrastructure/request_dict.py | 16 ++++++++++++++-- .../pypi_org/infrastructure/request_dict.py | 16 ++++++++++++++-- 10 files changed, 127 insertions(+), 25 deletions(-) diff --git a/app/ch12-forms/final/pypi_org/infrastructure/request_dict.py b/app/ch12-forms/final/pypi_org/infrastructure/request_dict.py index 495fd979..d7ab10de 100644 --- a/app/ch12-forms/final/pypi_org/infrastructure/request_dict.py +++ b/app/ch12-forms/final/pypi_org/infrastructure/request_dict.py @@ -1,4 +1,5 @@ import flask +from werkzeug.datastructures import MultiDict class RequestDictionary(dict): @@ -13,10 +14,21 @@ def __getattr__(self, key): def create(default_val=None, **route_args) -> RequestDictionary: request = flask.request + # Adding this retro actively. Some folks are experiencing issues where they + # are getting a list rather than plain dict. I think it's from multiple + # entries in the multidict. This should fix it. + args = request.args + if isinstance(request.args, MultiDict): + args = request.args.to_dict() + + form = request.form + if isinstance(request.args, MultiDict): + form = request.form.to_dict() + data = { - **request.args, # The key/value pairs in the URL query string + **args, # The key/value pairs in the URL query string **request.headers, # Header values - **request.form, # The key/value pairs in the body, from a HTML post form + **form, # The key/value pairs in the body, from a HTML post form **route_args # And additional arguments the method access, if they want them merged. } diff --git a/app/ch13-validation/final/pypi_org/bin/load_data.py b/app/ch13-validation/final/pypi_org/bin/load_data.py index 15237f18..277a48f8 100644 --- a/app/ch13-validation/final/pypi_org/bin/load_data.py +++ b/app/ch13-validation/final/pypi_org/bin/load_data.py @@ -10,6 +10,7 @@ sys.path.insert(0, os.path.abspath(os.path.join( os.path.dirname(__file__), "..", ".."))) +from pypi_org.bin.load_data import try_int import pypi_org.data.db_session as db_session from pypi_org.data.languages import ProgrammingLanguage from pypi_org.data.licenses import License @@ -339,13 +340,6 @@ def make_version_num(version_text): return major, minor, build -def try_int(text) -> int: - try: - return int(text) - except: - return 0 - - def init_db(): top_folder = os.path.dirname(__file__) rel_file = os.path.join('..', 'db', 'pypi.sqlite') diff --git a/app/ch13-validation/final/pypi_org/infrastructure/request_dict.py b/app/ch13-validation/final/pypi_org/infrastructure/request_dict.py index 495fd979..d7ab10de 100644 --- a/app/ch13-validation/final/pypi_org/infrastructure/request_dict.py +++ b/app/ch13-validation/final/pypi_org/infrastructure/request_dict.py @@ -1,4 +1,5 @@ import flask +from werkzeug.datastructures import MultiDict class RequestDictionary(dict): @@ -13,10 +14,21 @@ def __getattr__(self, key): def create(default_val=None, **route_args) -> RequestDictionary: request = flask.request + # Adding this retro actively. Some folks are experiencing issues where they + # are getting a list rather than plain dict. I think it's from multiple + # entries in the multidict. This should fix it. + args = request.args + if isinstance(request.args, MultiDict): + args = request.args.to_dict() + + form = request.form + if isinstance(request.args, MultiDict): + form = request.form.to_dict() + data = { - **request.args, # The key/value pairs in the URL query string + **args, # The key/value pairs in the URL query string **request.headers, # Header values - **request.form, # The key/value pairs in the body, from a HTML post form + **form, # The key/value pairs in the body, from a HTML post form **route_args # And additional arguments the method access, if they want them merged. } diff --git a/app/ch13-validation/starter/pypi_org/infrastructure/request_dict.py b/app/ch13-validation/starter/pypi_org/infrastructure/request_dict.py index 495fd979..d7ab10de 100644 --- a/app/ch13-validation/starter/pypi_org/infrastructure/request_dict.py +++ b/app/ch13-validation/starter/pypi_org/infrastructure/request_dict.py @@ -1,4 +1,5 @@ import flask +from werkzeug.datastructures import MultiDict class RequestDictionary(dict): @@ -13,10 +14,21 @@ def __getattr__(self, key): def create(default_val=None, **route_args) -> RequestDictionary: request = flask.request + # Adding this retro actively. Some folks are experiencing issues where they + # are getting a list rather than plain dict. I think it's from multiple + # entries in the multidict. This should fix it. + args = request.args + if isinstance(request.args, MultiDict): + args = request.args.to_dict() + + form = request.form + if isinstance(request.args, MultiDict): + form = request.form.to_dict() + data = { - **request.args, # The key/value pairs in the URL query string + **args, # The key/value pairs in the URL query string **request.headers, # Header values - **request.form, # The key/value pairs in the body, from a HTML post form + **form, # The key/value pairs in the body, from a HTML post form **route_args # And additional arguments the method access, if they want them merged. } diff --git a/app/ch14_testing/final/pypi_org/infrastructure/request_dict.py b/app/ch14_testing/final/pypi_org/infrastructure/request_dict.py index 495fd979..d7ab10de 100644 --- a/app/ch14_testing/final/pypi_org/infrastructure/request_dict.py +++ b/app/ch14_testing/final/pypi_org/infrastructure/request_dict.py @@ -1,4 +1,5 @@ import flask +from werkzeug.datastructures import MultiDict class RequestDictionary(dict): @@ -13,10 +14,21 @@ def __getattr__(self, key): def create(default_val=None, **route_args) -> RequestDictionary: request = flask.request + # Adding this retro actively. Some folks are experiencing issues where they + # are getting a list rather than plain dict. I think it's from multiple + # entries in the multidict. This should fix it. + args = request.args + if isinstance(request.args, MultiDict): + args = request.args.to_dict() + + form = request.form + if isinstance(request.args, MultiDict): + form = request.form.to_dict() + data = { - **request.args, # The key/value pairs in the URL query string + **args, # The key/value pairs in the URL query string **request.headers, # Header values - **request.form, # The key/value pairs in the body, from a HTML post form + **form, # The key/value pairs in the body, from a HTML post form **route_args # And additional arguments the method access, if they want them merged. } diff --git a/app/ch14_testing/starter/pypi_org/infrastructure/request_dict.py b/app/ch14_testing/starter/pypi_org/infrastructure/request_dict.py index 495fd979..d7ab10de 100644 --- a/app/ch14_testing/starter/pypi_org/infrastructure/request_dict.py +++ b/app/ch14_testing/starter/pypi_org/infrastructure/request_dict.py @@ -1,4 +1,5 @@ import flask +from werkzeug.datastructures import MultiDict class RequestDictionary(dict): @@ -13,10 +14,21 @@ def __getattr__(self, key): def create(default_val=None, **route_args) -> RequestDictionary: request = flask.request + # Adding this retro actively. Some folks are experiencing issues where they + # are getting a list rather than plain dict. I think it's from multiple + # entries in the multidict. This should fix it. + args = request.args + if isinstance(request.args, MultiDict): + args = request.args.to_dict() + + form = request.form + if isinstance(request.args, MultiDict): + form = request.form.to_dict() + data = { - **request.args, # The key/value pairs in the URL query string + **args, # The key/value pairs in the URL query string **request.headers, # Header values - **request.form, # The key/value pairs in the body, from a HTML post form + **form, # The key/value pairs in the body, from a HTML post form **route_args # And additional arguments the method access, if they want them merged. } diff --git a/app/ch15_deploy/final/pypi_org/infrastructure/request_dict.py b/app/ch15_deploy/final/pypi_org/infrastructure/request_dict.py index 495fd979..d7ab10de 100644 --- a/app/ch15_deploy/final/pypi_org/infrastructure/request_dict.py +++ b/app/ch15_deploy/final/pypi_org/infrastructure/request_dict.py @@ -1,4 +1,5 @@ import flask +from werkzeug.datastructures import MultiDict class RequestDictionary(dict): @@ -13,10 +14,21 @@ def __getattr__(self, key): def create(default_val=None, **route_args) -> RequestDictionary: request = flask.request + # Adding this retro actively. Some folks are experiencing issues where they + # are getting a list rather than plain dict. I think it's from multiple + # entries in the multidict. This should fix it. + args = request.args + if isinstance(request.args, MultiDict): + args = request.args.to_dict() + + form = request.form + if isinstance(request.args, MultiDict): + form = request.form.to_dict() + data = { - **request.args, # The key/value pairs in the URL query string + **args, # The key/value pairs in the URL query string **request.headers, # Header values - **request.form, # The key/value pairs in the body, from a HTML post form + **form, # The key/value pairs in the body, from a HTML post form **route_args # And additional arguments the method access, if they want them merged. } diff --git a/app/ch15_deploy/starter/pypi_org/infrastructure/request_dict.py b/app/ch15_deploy/starter/pypi_org/infrastructure/request_dict.py index 495fd979..d7ab10de 100644 --- a/app/ch15_deploy/starter/pypi_org/infrastructure/request_dict.py +++ b/app/ch15_deploy/starter/pypi_org/infrastructure/request_dict.py @@ -1,4 +1,5 @@ import flask +from werkzeug.datastructures import MultiDict class RequestDictionary(dict): @@ -13,10 +14,21 @@ def __getattr__(self, key): def create(default_val=None, **route_args) -> RequestDictionary: request = flask.request + # Adding this retro actively. Some folks are experiencing issues where they + # are getting a list rather than plain dict. I think it's from multiple + # entries in the multidict. This should fix it. + args = request.args + if isinstance(request.args, MultiDict): + args = request.args.to_dict() + + form = request.form + if isinstance(request.args, MultiDict): + form = request.form.to_dict() + data = { - **request.args, # The key/value pairs in the URL query string + **args, # The key/value pairs in the URL query string **request.headers, # Header values - **request.form, # The key/value pairs in the body, from a HTML post form + **form, # The key/value pairs in the body, from a HTML post form **route_args # And additional arguments the method access, if they want them merged. } diff --git a/app/ch16_mongodb/final/pypi_org/infrastructure/request_dict.py b/app/ch16_mongodb/final/pypi_org/infrastructure/request_dict.py index 495fd979..d7ab10de 100644 --- a/app/ch16_mongodb/final/pypi_org/infrastructure/request_dict.py +++ b/app/ch16_mongodb/final/pypi_org/infrastructure/request_dict.py @@ -1,4 +1,5 @@ import flask +from werkzeug.datastructures import MultiDict class RequestDictionary(dict): @@ -13,10 +14,21 @@ def __getattr__(self, key): def create(default_val=None, **route_args) -> RequestDictionary: request = flask.request + # Adding this retro actively. Some folks are experiencing issues where they + # are getting a list rather than plain dict. I think it's from multiple + # entries in the multidict. This should fix it. + args = request.args + if isinstance(request.args, MultiDict): + args = request.args.to_dict() + + form = request.form + if isinstance(request.args, MultiDict): + form = request.form.to_dict() + data = { - **request.args, # The key/value pairs in the URL query string + **args, # The key/value pairs in the URL query string **request.headers, # Header values - **request.form, # The key/value pairs in the body, from a HTML post form + **form, # The key/value pairs in the body, from a HTML post form **route_args # And additional arguments the method access, if they want them merged. } diff --git a/app/ch16_mongodb/starter/pypi_org/infrastructure/request_dict.py b/app/ch16_mongodb/starter/pypi_org/infrastructure/request_dict.py index 495fd979..d7ab10de 100644 --- a/app/ch16_mongodb/starter/pypi_org/infrastructure/request_dict.py +++ b/app/ch16_mongodb/starter/pypi_org/infrastructure/request_dict.py @@ -1,4 +1,5 @@ import flask +from werkzeug.datastructures import MultiDict class RequestDictionary(dict): @@ -13,10 +14,21 @@ def __getattr__(self, key): def create(default_val=None, **route_args) -> RequestDictionary: request = flask.request + # Adding this retro actively. Some folks are experiencing issues where they + # are getting a list rather than plain dict. I think it's from multiple + # entries in the multidict. This should fix it. + args = request.args + if isinstance(request.args, MultiDict): + args = request.args.to_dict() + + form = request.form + if isinstance(request.args, MultiDict): + form = request.form.to_dict() + data = { - **request.args, # The key/value pairs in the URL query string + **args, # The key/value pairs in the URL query string **request.headers, # Header values - **request.form, # The key/value pairs in the body, from a HTML post form + **form, # The key/value pairs in the body, from a HTML post form **route_args # And additional arguments the method access, if they want them merged. } From 10a84d0f5e29609db648e79d990bbaf9438d3234 Mon Sep 17 00:00:00 2001 From: Michael Kennedy Date: Thu, 10 Oct 2019 13:50:54 -0700 Subject: [PATCH 08/44] Let's centralize try_int(). Should be in a lib, not a little script like it was. --- .idea/dictionaries/mkennedy.xml | 13 +++++++++++++ .../final/pypi_org/bin/load_data.py | 8 +------- .../final/pypi_org/infrastructure/num_convert.py | 5 +++++ app/ch11_migrations/final/pypi_org/bin/load_data.py | 8 +------- .../starter/pypi_org/bin/load_data.py | 8 +------- .../starter/pypi_org/infrastructure/num_convert.py | 5 +++++ app/ch12-forms/final/pypi_org/bin/load_data.py | 8 +------- app/ch12-forms/starter/pypi_org/bin/load_data.py | 8 +------- .../starter/pypi_org/infrastructure/num_convert.py | 5 +++++ .../final/pypi_org/infrastructure/cookie_auth.py | 2 +- .../final/pypi_org/infrastructure/num_convert.py | 5 +++++ .../starter/pypi_org/infrastructure/cookie_auth.py | 2 +- .../starter/pypi_org/infrastructure/num_convert.py | 5 +++++ .../final/pypi_org/infrastructure/cookie_auth.py | 2 +- .../final/pypi_org/infrastructure/num_convert.py | 5 +++++ .../starter/pypi_org/infrastructure/cookie_auth.py | 2 +- .../starter/pypi_org/infrastructure/num_convert.py | 5 +++++ .../final/pypi_org/infrastructure/cookie_auth.py | 2 +- .../final/pypi_org/infrastructure/num_convert.py | 5 +++++ .../starter/pypi_org/infrastructure/cookie_auth.py | 2 +- .../starter/pypi_org/infrastructure/num_convert.py | 5 +++++ .../final/pypi_org/infrastructure/cookie_auth.py | 10 +++------- .../final/pypi_org/infrastructure/num_convert.py | 5 +++++ .../starter/pypi_org/infrastructure/cookie_auth.py | 2 +- .../starter/pypi_org/infrastructure/num_convert.py | 5 +++++ 25 files changed, 83 insertions(+), 49 deletions(-) create mode 100644 .idea/dictionaries/mkennedy.xml create mode 100644 app/ch10_using_sqlachemy/final/pypi_org/infrastructure/num_convert.py create mode 100644 app/ch11_migrations/starter/pypi_org/infrastructure/num_convert.py create mode 100644 app/ch12-forms/starter/pypi_org/infrastructure/num_convert.py create mode 100644 app/ch13-validation/final/pypi_org/infrastructure/num_convert.py create mode 100644 app/ch13-validation/starter/pypi_org/infrastructure/num_convert.py create mode 100644 app/ch14_testing/final/pypi_org/infrastructure/num_convert.py create mode 100644 app/ch14_testing/starter/pypi_org/infrastructure/num_convert.py create mode 100644 app/ch15_deploy/final/pypi_org/infrastructure/num_convert.py create mode 100644 app/ch15_deploy/starter/pypi_org/infrastructure/num_convert.py create mode 100644 app/ch16_mongodb/final/pypi_org/infrastructure/num_convert.py create mode 100644 app/ch16_mongodb/starter/pypi_org/infrastructure/num_convert.py diff --git a/.idea/dictionaries/mkennedy.xml b/.idea/dictionaries/mkennedy.xml new file mode 100644 index 00000000..e5612f37 --- /dev/null +++ b/.idea/dictionaries/mkennedy.xml @@ -0,0 +1,13 @@ + + + + dateutil + mimetype + multidict + passlib + pypi + sqlalchemy + werkzeug + + + \ No newline at end of file diff --git a/app/ch10_using_sqlachemy/final/pypi_org/bin/load_data.py b/app/ch10_using_sqlachemy/final/pypi_org/bin/load_data.py index 15237f18..ba62ff7d 100644 --- a/app/ch10_using_sqlachemy/final/pypi_org/bin/load_data.py +++ b/app/ch10_using_sqlachemy/final/pypi_org/bin/load_data.py @@ -10,6 +10,7 @@ sys.path.insert(0, os.path.abspath(os.path.join( os.path.dirname(__file__), "..", ".."))) +from pypi_org.infrastructure.num_convert import try_int import pypi_org.data.db_session as db_session from pypi_org.data.languages import ProgrammingLanguage from pypi_org.data.licenses import License @@ -339,13 +340,6 @@ def make_version_num(version_text): return major, minor, build -def try_int(text) -> int: - try: - return int(text) - except: - return 0 - - def init_db(): top_folder = os.path.dirname(__file__) rel_file = os.path.join('..', 'db', 'pypi.sqlite') diff --git a/app/ch10_using_sqlachemy/final/pypi_org/infrastructure/num_convert.py b/app/ch10_using_sqlachemy/final/pypi_org/infrastructure/num_convert.py new file mode 100644 index 00000000..bf88a6bc --- /dev/null +++ b/app/ch10_using_sqlachemy/final/pypi_org/infrastructure/num_convert.py @@ -0,0 +1,5 @@ +def try_int(text) -> int: + try: + return int(text) + except: + return 0 diff --git a/app/ch11_migrations/final/pypi_org/bin/load_data.py b/app/ch11_migrations/final/pypi_org/bin/load_data.py index 15237f18..277a48f8 100644 --- a/app/ch11_migrations/final/pypi_org/bin/load_data.py +++ b/app/ch11_migrations/final/pypi_org/bin/load_data.py @@ -10,6 +10,7 @@ sys.path.insert(0, os.path.abspath(os.path.join( os.path.dirname(__file__), "..", ".."))) +from pypi_org.bin.load_data import try_int import pypi_org.data.db_session as db_session from pypi_org.data.languages import ProgrammingLanguage from pypi_org.data.licenses import License @@ -339,13 +340,6 @@ def make_version_num(version_text): return major, minor, build -def try_int(text) -> int: - try: - return int(text) - except: - return 0 - - def init_db(): top_folder = os.path.dirname(__file__) rel_file = os.path.join('..', 'db', 'pypi.sqlite') diff --git a/app/ch11_migrations/starter/pypi_org/bin/load_data.py b/app/ch11_migrations/starter/pypi_org/bin/load_data.py index 15237f18..ba62ff7d 100644 --- a/app/ch11_migrations/starter/pypi_org/bin/load_data.py +++ b/app/ch11_migrations/starter/pypi_org/bin/load_data.py @@ -10,6 +10,7 @@ sys.path.insert(0, os.path.abspath(os.path.join( os.path.dirname(__file__), "..", ".."))) +from pypi_org.infrastructure.num_convert import try_int import pypi_org.data.db_session as db_session from pypi_org.data.languages import ProgrammingLanguage from pypi_org.data.licenses import License @@ -339,13 +340,6 @@ def make_version_num(version_text): return major, minor, build -def try_int(text) -> int: - try: - return int(text) - except: - return 0 - - def init_db(): top_folder = os.path.dirname(__file__) rel_file = os.path.join('..', 'db', 'pypi.sqlite') diff --git a/app/ch11_migrations/starter/pypi_org/infrastructure/num_convert.py b/app/ch11_migrations/starter/pypi_org/infrastructure/num_convert.py new file mode 100644 index 00000000..bf88a6bc --- /dev/null +++ b/app/ch11_migrations/starter/pypi_org/infrastructure/num_convert.py @@ -0,0 +1,5 @@ +def try_int(text) -> int: + try: + return int(text) + except: + return 0 diff --git a/app/ch12-forms/final/pypi_org/bin/load_data.py b/app/ch12-forms/final/pypi_org/bin/load_data.py index 15237f18..ba62ff7d 100644 --- a/app/ch12-forms/final/pypi_org/bin/load_data.py +++ b/app/ch12-forms/final/pypi_org/bin/load_data.py @@ -10,6 +10,7 @@ sys.path.insert(0, os.path.abspath(os.path.join( os.path.dirname(__file__), "..", ".."))) +from pypi_org.infrastructure.num_convert import try_int import pypi_org.data.db_session as db_session from pypi_org.data.languages import ProgrammingLanguage from pypi_org.data.licenses import License @@ -339,13 +340,6 @@ def make_version_num(version_text): return major, minor, build -def try_int(text) -> int: - try: - return int(text) - except: - return 0 - - def init_db(): top_folder = os.path.dirname(__file__) rel_file = os.path.join('..', 'db', 'pypi.sqlite') diff --git a/app/ch12-forms/starter/pypi_org/bin/load_data.py b/app/ch12-forms/starter/pypi_org/bin/load_data.py index 15237f18..ba62ff7d 100644 --- a/app/ch12-forms/starter/pypi_org/bin/load_data.py +++ b/app/ch12-forms/starter/pypi_org/bin/load_data.py @@ -10,6 +10,7 @@ sys.path.insert(0, os.path.abspath(os.path.join( os.path.dirname(__file__), "..", ".."))) +from pypi_org.infrastructure.num_convert import try_int import pypi_org.data.db_session as db_session from pypi_org.data.languages import ProgrammingLanguage from pypi_org.data.licenses import License @@ -339,13 +340,6 @@ def make_version_num(version_text): return major, minor, build -def try_int(text) -> int: - try: - return int(text) - except: - return 0 - - def init_db(): top_folder = os.path.dirname(__file__) rel_file = os.path.join('..', 'db', 'pypi.sqlite') diff --git a/app/ch12-forms/starter/pypi_org/infrastructure/num_convert.py b/app/ch12-forms/starter/pypi_org/infrastructure/num_convert.py new file mode 100644 index 00000000..bf88a6bc --- /dev/null +++ b/app/ch12-forms/starter/pypi_org/infrastructure/num_convert.py @@ -0,0 +1,5 @@ +def try_int(text) -> int: + try: + return int(text) + except: + return 0 diff --git a/app/ch13-validation/final/pypi_org/infrastructure/cookie_auth.py b/app/ch13-validation/final/pypi_org/infrastructure/cookie_auth.py index 64dc85a7..a5b3efd9 100644 --- a/app/ch13-validation/final/pypi_org/infrastructure/cookie_auth.py +++ b/app/ch13-validation/final/pypi_org/infrastructure/cookie_auth.py @@ -5,7 +5,7 @@ from flask import Request from flask import Response -from pypi_org.bin.load_data import try_int +from pypi_org.infrastructure.num_convert import try_int auth_cookie_name = 'pypi_demo_user' diff --git a/app/ch13-validation/final/pypi_org/infrastructure/num_convert.py b/app/ch13-validation/final/pypi_org/infrastructure/num_convert.py new file mode 100644 index 00000000..bf88a6bc --- /dev/null +++ b/app/ch13-validation/final/pypi_org/infrastructure/num_convert.py @@ -0,0 +1,5 @@ +def try_int(text) -> int: + try: + return int(text) + except: + return 0 diff --git a/app/ch13-validation/starter/pypi_org/infrastructure/cookie_auth.py b/app/ch13-validation/starter/pypi_org/infrastructure/cookie_auth.py index 64dc85a7..a5b3efd9 100644 --- a/app/ch13-validation/starter/pypi_org/infrastructure/cookie_auth.py +++ b/app/ch13-validation/starter/pypi_org/infrastructure/cookie_auth.py @@ -5,7 +5,7 @@ from flask import Request from flask import Response -from pypi_org.bin.load_data import try_int +from pypi_org.infrastructure.num_convert import try_int auth_cookie_name = 'pypi_demo_user' diff --git a/app/ch13-validation/starter/pypi_org/infrastructure/num_convert.py b/app/ch13-validation/starter/pypi_org/infrastructure/num_convert.py new file mode 100644 index 00000000..bf88a6bc --- /dev/null +++ b/app/ch13-validation/starter/pypi_org/infrastructure/num_convert.py @@ -0,0 +1,5 @@ +def try_int(text) -> int: + try: + return int(text) + except: + return 0 diff --git a/app/ch14_testing/final/pypi_org/infrastructure/cookie_auth.py b/app/ch14_testing/final/pypi_org/infrastructure/cookie_auth.py index 64dc85a7..a5b3efd9 100644 --- a/app/ch14_testing/final/pypi_org/infrastructure/cookie_auth.py +++ b/app/ch14_testing/final/pypi_org/infrastructure/cookie_auth.py @@ -5,7 +5,7 @@ from flask import Request from flask import Response -from pypi_org.bin.load_data import try_int +from pypi_org.infrastructure.num_convert import try_int auth_cookie_name = 'pypi_demo_user' diff --git a/app/ch14_testing/final/pypi_org/infrastructure/num_convert.py b/app/ch14_testing/final/pypi_org/infrastructure/num_convert.py new file mode 100644 index 00000000..bf88a6bc --- /dev/null +++ b/app/ch14_testing/final/pypi_org/infrastructure/num_convert.py @@ -0,0 +1,5 @@ +def try_int(text) -> int: + try: + return int(text) + except: + return 0 diff --git a/app/ch14_testing/starter/pypi_org/infrastructure/cookie_auth.py b/app/ch14_testing/starter/pypi_org/infrastructure/cookie_auth.py index 64dc85a7..a5b3efd9 100644 --- a/app/ch14_testing/starter/pypi_org/infrastructure/cookie_auth.py +++ b/app/ch14_testing/starter/pypi_org/infrastructure/cookie_auth.py @@ -5,7 +5,7 @@ from flask import Request from flask import Response -from pypi_org.bin.load_data import try_int +from pypi_org.infrastructure.num_convert import try_int auth_cookie_name = 'pypi_demo_user' diff --git a/app/ch14_testing/starter/pypi_org/infrastructure/num_convert.py b/app/ch14_testing/starter/pypi_org/infrastructure/num_convert.py new file mode 100644 index 00000000..bf88a6bc --- /dev/null +++ b/app/ch14_testing/starter/pypi_org/infrastructure/num_convert.py @@ -0,0 +1,5 @@ +def try_int(text) -> int: + try: + return int(text) + except: + return 0 diff --git a/app/ch15_deploy/final/pypi_org/infrastructure/cookie_auth.py b/app/ch15_deploy/final/pypi_org/infrastructure/cookie_auth.py index 64dc85a7..a5b3efd9 100644 --- a/app/ch15_deploy/final/pypi_org/infrastructure/cookie_auth.py +++ b/app/ch15_deploy/final/pypi_org/infrastructure/cookie_auth.py @@ -5,7 +5,7 @@ from flask import Request from flask import Response -from pypi_org.bin.load_data import try_int +from pypi_org.infrastructure.num_convert import try_int auth_cookie_name = 'pypi_demo_user' diff --git a/app/ch15_deploy/final/pypi_org/infrastructure/num_convert.py b/app/ch15_deploy/final/pypi_org/infrastructure/num_convert.py new file mode 100644 index 00000000..bf88a6bc --- /dev/null +++ b/app/ch15_deploy/final/pypi_org/infrastructure/num_convert.py @@ -0,0 +1,5 @@ +def try_int(text) -> int: + try: + return int(text) + except: + return 0 diff --git a/app/ch15_deploy/starter/pypi_org/infrastructure/cookie_auth.py b/app/ch15_deploy/starter/pypi_org/infrastructure/cookie_auth.py index 64dc85a7..a5b3efd9 100644 --- a/app/ch15_deploy/starter/pypi_org/infrastructure/cookie_auth.py +++ b/app/ch15_deploy/starter/pypi_org/infrastructure/cookie_auth.py @@ -5,7 +5,7 @@ from flask import Request from flask import Response -from pypi_org.bin.load_data import try_int +from pypi_org.infrastructure.num_convert import try_int auth_cookie_name = 'pypi_demo_user' diff --git a/app/ch15_deploy/starter/pypi_org/infrastructure/num_convert.py b/app/ch15_deploy/starter/pypi_org/infrastructure/num_convert.py new file mode 100644 index 00000000..bf88a6bc --- /dev/null +++ b/app/ch15_deploy/starter/pypi_org/infrastructure/num_convert.py @@ -0,0 +1,5 @@ +def try_int(text) -> int: + try: + return int(text) + except: + return 0 diff --git a/app/ch16_mongodb/final/pypi_org/infrastructure/cookie_auth.py b/app/ch16_mongodb/final/pypi_org/infrastructure/cookie_auth.py index fdbf28b8..a5b3efd9 100644 --- a/app/ch16_mongodb/final/pypi_org/infrastructure/cookie_auth.py +++ b/app/ch16_mongodb/final/pypi_org/infrastructure/cookie_auth.py @@ -2,11 +2,10 @@ from datetime import timedelta from typing import Optional -import bson from flask import Request from flask import Response -from pypi_org.bin.load_data import try_int +from pypi_org.infrastructure.num_convert import try_int auth_cookie_name = 'pypi_demo_user' @@ -26,7 +25,7 @@ def __add_cookie_callback(_, response: Response, name: str, value: str): response.set_cookie(name, value, max_age=timedelta(days=30)) -def get_user_id_via_auth_cookie(request: Request) -> Optional[bson.ObjectId]: +def get_user_id_via_auth_cookie(request: Request) -> Optional[int]: if auth_cookie_name not in request.cookies: return None @@ -42,10 +41,7 @@ def get_user_id_via_auth_cookie(request: Request) -> Optional[bson.ObjectId]: print("Warning: Hash mismatch, invalid cookie value") return None - try: - return bson.ObjectId(user_id) - except: - return None + return try_int(user_id) def logout(response: Response): diff --git a/app/ch16_mongodb/final/pypi_org/infrastructure/num_convert.py b/app/ch16_mongodb/final/pypi_org/infrastructure/num_convert.py new file mode 100644 index 00000000..bf88a6bc --- /dev/null +++ b/app/ch16_mongodb/final/pypi_org/infrastructure/num_convert.py @@ -0,0 +1,5 @@ +def try_int(text) -> int: + try: + return int(text) + except: + return 0 diff --git a/app/ch16_mongodb/starter/pypi_org/infrastructure/cookie_auth.py b/app/ch16_mongodb/starter/pypi_org/infrastructure/cookie_auth.py index 64dc85a7..a5b3efd9 100644 --- a/app/ch16_mongodb/starter/pypi_org/infrastructure/cookie_auth.py +++ b/app/ch16_mongodb/starter/pypi_org/infrastructure/cookie_auth.py @@ -5,7 +5,7 @@ from flask import Request from flask import Response -from pypi_org.bin.load_data import try_int +from pypi_org.infrastructure.num_convert import try_int auth_cookie_name = 'pypi_demo_user' diff --git a/app/ch16_mongodb/starter/pypi_org/infrastructure/num_convert.py b/app/ch16_mongodb/starter/pypi_org/infrastructure/num_convert.py new file mode 100644 index 00000000..bf88a6bc --- /dev/null +++ b/app/ch16_mongodb/starter/pypi_org/infrastructure/num_convert.py @@ -0,0 +1,5 @@ +def try_int(text) -> int: + try: + return int(text) + except: + return 0 From fb1f7875c1821aeccaa1b41075bea2cfd921914d Mon Sep 17 00:00:00 2001 From: Michael Kennedy Date: Thu, 10 Oct 2019 13:53:13 -0700 Subject: [PATCH 09/44] Expected dictionary got response error, fixes #8 --- .../final/pypi_org/infrastructure/view_modifiers.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/ch05_jinja_templates/final/pypi_org/infrastructure/view_modifiers.py b/app/ch05_jinja_templates/final/pypi_org/infrastructure/view_modifiers.py index 2ffe755d..0c0941eb 100644 --- a/app/ch05_jinja_templates/final/pypi_org/infrastructure/view_modifiers.py +++ b/app/ch05_jinja_templates/final/pypi_org/infrastructure/view_modifiers.py @@ -1,5 +1,5 @@ from functools import wraps -import werkzeug + import flask import werkzeug import werkzeug.wrappers @@ -42,6 +42,7 @@ def view_method(*args, **kwargs): return response_inner + # # def template(template_file: str = None): # def template_inner(f): From e2e08ed347ca8d1060261883e188bbefb068f762 Mon Sep 17 00:00:00 2001 From: Michael Kennedy Date: Fri, 11 Oct 2019 15:03:06 -0700 Subject: [PATCH 10/44] ignore these --- .gitignore | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.gitignore b/.gitignore index 44c54156..98d0aa73 100644 --- a/.gitignore +++ b/.gitignore @@ -135,3 +135,10 @@ app/ch10_using_sqlachemy/final/.idea/dataSources.local.xml app/ch10_using_sqlachemy/final/.idea/dataSources/cfaa71de-14c4-40a6-abf7-fc59c06c9b0b.xml app/ch11_migrations/final/.idea/dataSources.local.xml app/ch11_migrations/final/.idea/dataSources/bb882f32-bdb3-45cb-adce-c46711dd125e.xml +.idea/$CACHE_FILE$ +.idea/flask-demos.iml +.idea/misc.xml +.idea/modules.xml +.idea/vagrant.xml +.idea/vcs.xml +.idea/inspectionProfiles/profiles_settings.xml From e435fe55f6903f70740b7ab18027e865160c2884 Mon Sep 17 00:00:00 2001 From: Michael Kennedy Date: Tue, 29 Oct 2019 13:12:56 -0700 Subject: [PATCH 11/44] Minor fix for blueprints + flask run. --- app/ch12-forms/final/pypi_org/app.py | 9 ++++++++- .../final/pypi_org/infrastructure/num_convert.py | 5 +++++ 2 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 app/ch12-forms/final/pypi_org/infrastructure/num_convert.py diff --git a/app/ch12-forms/final/pypi_org/app.py b/app/ch12-forms/final/pypi_org/app.py index dc44d0cf..2227f9db 100644 --- a/app/ch12-forms/final/pypi_org/app.py +++ b/app/ch12-forms/final/pypi_org/app.py @@ -1,6 +1,7 @@ import os import sys import flask + folder = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) sys.path.insert(0, folder) @@ -10,9 +11,13 @@ def main(): + configure() + app.run(debug=True) + + +def configure(): register_blueprints() setup_db() - app.run(debug=True) def setup_db(): @@ -38,3 +43,5 @@ def register_blueprints(): if __name__ == '__main__': main() +else: + configure() diff --git a/app/ch12-forms/final/pypi_org/infrastructure/num_convert.py b/app/ch12-forms/final/pypi_org/infrastructure/num_convert.py new file mode 100644 index 00000000..bf88a6bc --- /dev/null +++ b/app/ch12-forms/final/pypi_org/infrastructure/num_convert.py @@ -0,0 +1,5 @@ +def try_int(text) -> int: + try: + return int(text) + except: + return 0 From 69a783e6fef9d31de52bdcbd5ba3c6bf276fe676 Mon Sep 17 00:00:00 2001 From: Daghan Altas Date: Tue, 31 Dec 2019 10:58:44 +0100 Subject: [PATCH 12/44] improving cookie security --- app/ch12-forms/final/pypi_org/infrastructure/cookie_auth.py | 4 ++-- .../final/pypi_org/infrastructure/cookie_auth.py | 4 ++-- .../starter/pypi_org/infrastructure/cookie_auth.py | 4 ++-- app/ch14_testing/final/pypi_org/infrastructure/cookie_auth.py | 4 ++-- .../starter/pypi_org/infrastructure/cookie_auth.py | 4 ++-- app/ch15_deploy/final/pypi_org/infrastructure/cookie_auth.py | 4 ++-- .../starter/pypi_org/infrastructure/cookie_auth.py | 4 ++-- app/ch16_mongodb/final/pypi_org/infrastructure/cookie_auth.py | 4 ++-- .../starter/pypi_org/infrastructure/cookie_auth.py | 4 ++-- 9 files changed, 18 insertions(+), 18 deletions(-) diff --git a/app/ch12-forms/final/pypi_org/infrastructure/cookie_auth.py b/app/ch12-forms/final/pypi_org/infrastructure/cookie_auth.py index 64dc85a7..e9e4f4d0 100644 --- a/app/ch12-forms/final/pypi_org/infrastructure/cookie_auth.py +++ b/app/ch12-forms/final/pypi_org/infrastructure/cookie_auth.py @@ -13,7 +13,7 @@ def set_auth(response: Response, user_id: int): hash_val = __hash_text(str(user_id)) val = "{}:{}".format(user_id, hash_val) - response.set_cookie(auth_cookie_name, val) + response.set_cookie(auth_cookie_name, val, secure=True, httponly=True, samesite='Lax') def __hash_text(text: str) -> str: @@ -22,7 +22,7 @@ def __hash_text(text: str) -> str: def __add_cookie_callback(_, response: Response, name: str, value: str): - response.set_cookie(name, value, max_age=timedelta(days=30)) + response.set_cookie(name, value, max_age=timedelta(days=30), secure=True, httponly=True, samesite='Lax') def get_user_id_via_auth_cookie(request: Request) -> Optional[int]: diff --git a/app/ch13-validation/final/pypi_org/infrastructure/cookie_auth.py b/app/ch13-validation/final/pypi_org/infrastructure/cookie_auth.py index a5b3efd9..f9724bd3 100644 --- a/app/ch13-validation/final/pypi_org/infrastructure/cookie_auth.py +++ b/app/ch13-validation/final/pypi_org/infrastructure/cookie_auth.py @@ -13,7 +13,7 @@ def set_auth(response: Response, user_id: int): hash_val = __hash_text(str(user_id)) val = "{}:{}".format(user_id, hash_val) - response.set_cookie(auth_cookie_name, val) + response.set_cookie(auth_cookie_name, val, secure=True, httponly=True, samesite='Lax') def __hash_text(text: str) -> str: @@ -22,7 +22,7 @@ def __hash_text(text: str) -> str: def __add_cookie_callback(_, response: Response, name: str, value: str): - response.set_cookie(name, value, max_age=timedelta(days=30)) + response.set_cookie(name, value, max_age=timedelta(days=30), secure=True, httponly=True, samesite='Lax') def get_user_id_via_auth_cookie(request: Request) -> Optional[int]: diff --git a/app/ch13-validation/starter/pypi_org/infrastructure/cookie_auth.py b/app/ch13-validation/starter/pypi_org/infrastructure/cookie_auth.py index a5b3efd9..f9724bd3 100644 --- a/app/ch13-validation/starter/pypi_org/infrastructure/cookie_auth.py +++ b/app/ch13-validation/starter/pypi_org/infrastructure/cookie_auth.py @@ -13,7 +13,7 @@ def set_auth(response: Response, user_id: int): hash_val = __hash_text(str(user_id)) val = "{}:{}".format(user_id, hash_val) - response.set_cookie(auth_cookie_name, val) + response.set_cookie(auth_cookie_name, val, secure=True, httponly=True, samesite='Lax') def __hash_text(text: str) -> str: @@ -22,7 +22,7 @@ def __hash_text(text: str) -> str: def __add_cookie_callback(_, response: Response, name: str, value: str): - response.set_cookie(name, value, max_age=timedelta(days=30)) + response.set_cookie(name, value, max_age=timedelta(days=30), secure=True, httponly=True, samesite='Lax') def get_user_id_via_auth_cookie(request: Request) -> Optional[int]: diff --git a/app/ch14_testing/final/pypi_org/infrastructure/cookie_auth.py b/app/ch14_testing/final/pypi_org/infrastructure/cookie_auth.py index a5b3efd9..f9724bd3 100644 --- a/app/ch14_testing/final/pypi_org/infrastructure/cookie_auth.py +++ b/app/ch14_testing/final/pypi_org/infrastructure/cookie_auth.py @@ -13,7 +13,7 @@ def set_auth(response: Response, user_id: int): hash_val = __hash_text(str(user_id)) val = "{}:{}".format(user_id, hash_val) - response.set_cookie(auth_cookie_name, val) + response.set_cookie(auth_cookie_name, val, secure=True, httponly=True, samesite='Lax') def __hash_text(text: str) -> str: @@ -22,7 +22,7 @@ def __hash_text(text: str) -> str: def __add_cookie_callback(_, response: Response, name: str, value: str): - response.set_cookie(name, value, max_age=timedelta(days=30)) + response.set_cookie(name, value, max_age=timedelta(days=30), secure=True, httponly=True, samesite='Lax') def get_user_id_via_auth_cookie(request: Request) -> Optional[int]: diff --git a/app/ch14_testing/starter/pypi_org/infrastructure/cookie_auth.py b/app/ch14_testing/starter/pypi_org/infrastructure/cookie_auth.py index a5b3efd9..f9724bd3 100644 --- a/app/ch14_testing/starter/pypi_org/infrastructure/cookie_auth.py +++ b/app/ch14_testing/starter/pypi_org/infrastructure/cookie_auth.py @@ -13,7 +13,7 @@ def set_auth(response: Response, user_id: int): hash_val = __hash_text(str(user_id)) val = "{}:{}".format(user_id, hash_val) - response.set_cookie(auth_cookie_name, val) + response.set_cookie(auth_cookie_name, val, secure=True, httponly=True, samesite='Lax') def __hash_text(text: str) -> str: @@ -22,7 +22,7 @@ def __hash_text(text: str) -> str: def __add_cookie_callback(_, response: Response, name: str, value: str): - response.set_cookie(name, value, max_age=timedelta(days=30)) + response.set_cookie(name, value, max_age=timedelta(days=30), secure=True, httponly=True, samesite='Lax') def get_user_id_via_auth_cookie(request: Request) -> Optional[int]: diff --git a/app/ch15_deploy/final/pypi_org/infrastructure/cookie_auth.py b/app/ch15_deploy/final/pypi_org/infrastructure/cookie_auth.py index a5b3efd9..f9724bd3 100644 --- a/app/ch15_deploy/final/pypi_org/infrastructure/cookie_auth.py +++ b/app/ch15_deploy/final/pypi_org/infrastructure/cookie_auth.py @@ -13,7 +13,7 @@ def set_auth(response: Response, user_id: int): hash_val = __hash_text(str(user_id)) val = "{}:{}".format(user_id, hash_val) - response.set_cookie(auth_cookie_name, val) + response.set_cookie(auth_cookie_name, val, secure=True, httponly=True, samesite='Lax') def __hash_text(text: str) -> str: @@ -22,7 +22,7 @@ def __hash_text(text: str) -> str: def __add_cookie_callback(_, response: Response, name: str, value: str): - response.set_cookie(name, value, max_age=timedelta(days=30)) + response.set_cookie(name, value, max_age=timedelta(days=30), secure=True, httponly=True, samesite='Lax') def get_user_id_via_auth_cookie(request: Request) -> Optional[int]: diff --git a/app/ch15_deploy/starter/pypi_org/infrastructure/cookie_auth.py b/app/ch15_deploy/starter/pypi_org/infrastructure/cookie_auth.py index a5b3efd9..f9724bd3 100644 --- a/app/ch15_deploy/starter/pypi_org/infrastructure/cookie_auth.py +++ b/app/ch15_deploy/starter/pypi_org/infrastructure/cookie_auth.py @@ -13,7 +13,7 @@ def set_auth(response: Response, user_id: int): hash_val = __hash_text(str(user_id)) val = "{}:{}".format(user_id, hash_val) - response.set_cookie(auth_cookie_name, val) + response.set_cookie(auth_cookie_name, val, secure=True, httponly=True, samesite='Lax') def __hash_text(text: str) -> str: @@ -22,7 +22,7 @@ def __hash_text(text: str) -> str: def __add_cookie_callback(_, response: Response, name: str, value: str): - response.set_cookie(name, value, max_age=timedelta(days=30)) + response.set_cookie(name, value, max_age=timedelta(days=30), secure=True, httponly=True, samesite='Lax') def get_user_id_via_auth_cookie(request: Request) -> Optional[int]: diff --git a/app/ch16_mongodb/final/pypi_org/infrastructure/cookie_auth.py b/app/ch16_mongodb/final/pypi_org/infrastructure/cookie_auth.py index a5b3efd9..f9724bd3 100644 --- a/app/ch16_mongodb/final/pypi_org/infrastructure/cookie_auth.py +++ b/app/ch16_mongodb/final/pypi_org/infrastructure/cookie_auth.py @@ -13,7 +13,7 @@ def set_auth(response: Response, user_id: int): hash_val = __hash_text(str(user_id)) val = "{}:{}".format(user_id, hash_val) - response.set_cookie(auth_cookie_name, val) + response.set_cookie(auth_cookie_name, val, secure=True, httponly=True, samesite='Lax') def __hash_text(text: str) -> str: @@ -22,7 +22,7 @@ def __hash_text(text: str) -> str: def __add_cookie_callback(_, response: Response, name: str, value: str): - response.set_cookie(name, value, max_age=timedelta(days=30)) + response.set_cookie(name, value, max_age=timedelta(days=30), secure=True, httponly=True, samesite='Lax') def get_user_id_via_auth_cookie(request: Request) -> Optional[int]: diff --git a/app/ch16_mongodb/starter/pypi_org/infrastructure/cookie_auth.py b/app/ch16_mongodb/starter/pypi_org/infrastructure/cookie_auth.py index a5b3efd9..f9724bd3 100644 --- a/app/ch16_mongodb/starter/pypi_org/infrastructure/cookie_auth.py +++ b/app/ch16_mongodb/starter/pypi_org/infrastructure/cookie_auth.py @@ -13,7 +13,7 @@ def set_auth(response: Response, user_id: int): hash_val = __hash_text(str(user_id)) val = "{}:{}".format(user_id, hash_val) - response.set_cookie(auth_cookie_name, val) + response.set_cookie(auth_cookie_name, val, secure=True, httponly=True, samesite='Lax') def __hash_text(text: str) -> str: @@ -22,7 +22,7 @@ def __hash_text(text: str) -> str: def __add_cookie_callback(_, response: Response, name: str, value: str): - response.set_cookie(name, value, max_age=timedelta(days=30)) + response.set_cookie(name, value, max_age=timedelta(days=30), secure=True, httponly=True, samesite='Lax') def get_user_id_via_auth_cookie(request: Request) -> Optional[int]: From 5eb4a8b2f2a5661d4d447b268e01445b5b599e1e Mon Sep 17 00:00:00 2001 From: Daghan Altas Date: Tue, 7 Jan 2020 15:04:26 -0800 Subject: [PATCH 13/44] improving cookie security, keeping httponly and samesite parameters, but relaxing secure param, since the app has to run on http --- app/ch12-forms/final/pypi_org/infrastructure/cookie_auth.py | 4 ++-- .../final/pypi_org/infrastructure/cookie_auth.py | 4 ++-- .../starter/pypi_org/infrastructure/cookie_auth.py | 4 ++-- app/ch14_testing/final/pypi_org/infrastructure/cookie_auth.py | 2 +- .../starter/pypi_org/infrastructure/cookie_auth.py | 4 ++-- app/ch15_deploy/final/pypi_org/infrastructure/cookie_auth.py | 4 ++-- .../starter/pypi_org/infrastructure/cookie_auth.py | 4 ++-- app/ch16_mongodb/final/pypi_org/infrastructure/cookie_auth.py | 4 ++-- .../starter/pypi_org/infrastructure/cookie_auth.py | 4 ++-- 9 files changed, 17 insertions(+), 17 deletions(-) diff --git a/app/ch12-forms/final/pypi_org/infrastructure/cookie_auth.py b/app/ch12-forms/final/pypi_org/infrastructure/cookie_auth.py index e9e4f4d0..46a089b4 100644 --- a/app/ch12-forms/final/pypi_org/infrastructure/cookie_auth.py +++ b/app/ch12-forms/final/pypi_org/infrastructure/cookie_auth.py @@ -13,7 +13,7 @@ def set_auth(response: Response, user_id: int): hash_val = __hash_text(str(user_id)) val = "{}:{}".format(user_id, hash_val) - response.set_cookie(auth_cookie_name, val, secure=True, httponly=True, samesite='Lax') + response.set_cookie(auth_cookie_name, val, secure=False, httponly=True, samesite='Lax') def __hash_text(text: str) -> str: @@ -22,7 +22,7 @@ def __hash_text(text: str) -> str: def __add_cookie_callback(_, response: Response, name: str, value: str): - response.set_cookie(name, value, max_age=timedelta(days=30), secure=True, httponly=True, samesite='Lax') + response.set_cookie(name, value, max_age=timedelta(days=30), secure=False, httponly=True, samesite='Lax') def get_user_id_via_auth_cookie(request: Request) -> Optional[int]: diff --git a/app/ch13-validation/final/pypi_org/infrastructure/cookie_auth.py b/app/ch13-validation/final/pypi_org/infrastructure/cookie_auth.py index f9724bd3..65ee0c10 100644 --- a/app/ch13-validation/final/pypi_org/infrastructure/cookie_auth.py +++ b/app/ch13-validation/final/pypi_org/infrastructure/cookie_auth.py @@ -13,7 +13,7 @@ def set_auth(response: Response, user_id: int): hash_val = __hash_text(str(user_id)) val = "{}:{}".format(user_id, hash_val) - response.set_cookie(auth_cookie_name, val, secure=True, httponly=True, samesite='Lax') + response.set_cookie(auth_cookie_name, val, secure=False, httponly=True, samesite='Lax') def __hash_text(text: str) -> str: @@ -22,7 +22,7 @@ def __hash_text(text: str) -> str: def __add_cookie_callback(_, response: Response, name: str, value: str): - response.set_cookie(name, value, max_age=timedelta(days=30), secure=True, httponly=True, samesite='Lax') + response.set_cookie(name, value, max_age=timedelta(days=30), secure=False, httponly=True, samesite='Lax') def get_user_id_via_auth_cookie(request: Request) -> Optional[int]: diff --git a/app/ch13-validation/starter/pypi_org/infrastructure/cookie_auth.py b/app/ch13-validation/starter/pypi_org/infrastructure/cookie_auth.py index f9724bd3..65ee0c10 100644 --- a/app/ch13-validation/starter/pypi_org/infrastructure/cookie_auth.py +++ b/app/ch13-validation/starter/pypi_org/infrastructure/cookie_auth.py @@ -13,7 +13,7 @@ def set_auth(response: Response, user_id: int): hash_val = __hash_text(str(user_id)) val = "{}:{}".format(user_id, hash_val) - response.set_cookie(auth_cookie_name, val, secure=True, httponly=True, samesite='Lax') + response.set_cookie(auth_cookie_name, val, secure=False, httponly=True, samesite='Lax') def __hash_text(text: str) -> str: @@ -22,7 +22,7 @@ def __hash_text(text: str) -> str: def __add_cookie_callback(_, response: Response, name: str, value: str): - response.set_cookie(name, value, max_age=timedelta(days=30), secure=True, httponly=True, samesite='Lax') + response.set_cookie(name, value, max_age=timedelta(days=30), secure=False, httponly=True, samesite='Lax') def get_user_id_via_auth_cookie(request: Request) -> Optional[int]: diff --git a/app/ch14_testing/final/pypi_org/infrastructure/cookie_auth.py b/app/ch14_testing/final/pypi_org/infrastructure/cookie_auth.py index f9724bd3..c68ca6e5 100644 --- a/app/ch14_testing/final/pypi_org/infrastructure/cookie_auth.py +++ b/app/ch14_testing/final/pypi_org/infrastructure/cookie_auth.py @@ -22,7 +22,7 @@ def __hash_text(text: str) -> str: def __add_cookie_callback(_, response: Response, name: str, value: str): - response.set_cookie(name, value, max_age=timedelta(days=30), secure=True, httponly=True, samesite='Lax') + response.set_cookie(name, value, max_age=timedelta(days=30), secure=False, httponly=True, samesite='Lax') def get_user_id_via_auth_cookie(request: Request) -> Optional[int]: diff --git a/app/ch14_testing/starter/pypi_org/infrastructure/cookie_auth.py b/app/ch14_testing/starter/pypi_org/infrastructure/cookie_auth.py index f9724bd3..65ee0c10 100644 --- a/app/ch14_testing/starter/pypi_org/infrastructure/cookie_auth.py +++ b/app/ch14_testing/starter/pypi_org/infrastructure/cookie_auth.py @@ -13,7 +13,7 @@ def set_auth(response: Response, user_id: int): hash_val = __hash_text(str(user_id)) val = "{}:{}".format(user_id, hash_val) - response.set_cookie(auth_cookie_name, val, secure=True, httponly=True, samesite='Lax') + response.set_cookie(auth_cookie_name, val, secure=False, httponly=True, samesite='Lax') def __hash_text(text: str) -> str: @@ -22,7 +22,7 @@ def __hash_text(text: str) -> str: def __add_cookie_callback(_, response: Response, name: str, value: str): - response.set_cookie(name, value, max_age=timedelta(days=30), secure=True, httponly=True, samesite='Lax') + response.set_cookie(name, value, max_age=timedelta(days=30), secure=False, httponly=True, samesite='Lax') def get_user_id_via_auth_cookie(request: Request) -> Optional[int]: diff --git a/app/ch15_deploy/final/pypi_org/infrastructure/cookie_auth.py b/app/ch15_deploy/final/pypi_org/infrastructure/cookie_auth.py index f9724bd3..65ee0c10 100644 --- a/app/ch15_deploy/final/pypi_org/infrastructure/cookie_auth.py +++ b/app/ch15_deploy/final/pypi_org/infrastructure/cookie_auth.py @@ -13,7 +13,7 @@ def set_auth(response: Response, user_id: int): hash_val = __hash_text(str(user_id)) val = "{}:{}".format(user_id, hash_val) - response.set_cookie(auth_cookie_name, val, secure=True, httponly=True, samesite='Lax') + response.set_cookie(auth_cookie_name, val, secure=False, httponly=True, samesite='Lax') def __hash_text(text: str) -> str: @@ -22,7 +22,7 @@ def __hash_text(text: str) -> str: def __add_cookie_callback(_, response: Response, name: str, value: str): - response.set_cookie(name, value, max_age=timedelta(days=30), secure=True, httponly=True, samesite='Lax') + response.set_cookie(name, value, max_age=timedelta(days=30), secure=False, httponly=True, samesite='Lax') def get_user_id_via_auth_cookie(request: Request) -> Optional[int]: diff --git a/app/ch15_deploy/starter/pypi_org/infrastructure/cookie_auth.py b/app/ch15_deploy/starter/pypi_org/infrastructure/cookie_auth.py index f9724bd3..65ee0c10 100644 --- a/app/ch15_deploy/starter/pypi_org/infrastructure/cookie_auth.py +++ b/app/ch15_deploy/starter/pypi_org/infrastructure/cookie_auth.py @@ -13,7 +13,7 @@ def set_auth(response: Response, user_id: int): hash_val = __hash_text(str(user_id)) val = "{}:{}".format(user_id, hash_val) - response.set_cookie(auth_cookie_name, val, secure=True, httponly=True, samesite='Lax') + response.set_cookie(auth_cookie_name, val, secure=False, httponly=True, samesite='Lax') def __hash_text(text: str) -> str: @@ -22,7 +22,7 @@ def __hash_text(text: str) -> str: def __add_cookie_callback(_, response: Response, name: str, value: str): - response.set_cookie(name, value, max_age=timedelta(days=30), secure=True, httponly=True, samesite='Lax') + response.set_cookie(name, value, max_age=timedelta(days=30), secure=False, httponly=True, samesite='Lax') def get_user_id_via_auth_cookie(request: Request) -> Optional[int]: diff --git a/app/ch16_mongodb/final/pypi_org/infrastructure/cookie_auth.py b/app/ch16_mongodb/final/pypi_org/infrastructure/cookie_auth.py index f9724bd3..65ee0c10 100644 --- a/app/ch16_mongodb/final/pypi_org/infrastructure/cookie_auth.py +++ b/app/ch16_mongodb/final/pypi_org/infrastructure/cookie_auth.py @@ -13,7 +13,7 @@ def set_auth(response: Response, user_id: int): hash_val = __hash_text(str(user_id)) val = "{}:{}".format(user_id, hash_val) - response.set_cookie(auth_cookie_name, val, secure=True, httponly=True, samesite='Lax') + response.set_cookie(auth_cookie_name, val, secure=False, httponly=True, samesite='Lax') def __hash_text(text: str) -> str: @@ -22,7 +22,7 @@ def __hash_text(text: str) -> str: def __add_cookie_callback(_, response: Response, name: str, value: str): - response.set_cookie(name, value, max_age=timedelta(days=30), secure=True, httponly=True, samesite='Lax') + response.set_cookie(name, value, max_age=timedelta(days=30), secure=False, httponly=True, samesite='Lax') def get_user_id_via_auth_cookie(request: Request) -> Optional[int]: diff --git a/app/ch16_mongodb/starter/pypi_org/infrastructure/cookie_auth.py b/app/ch16_mongodb/starter/pypi_org/infrastructure/cookie_auth.py index f9724bd3..65ee0c10 100644 --- a/app/ch16_mongodb/starter/pypi_org/infrastructure/cookie_auth.py +++ b/app/ch16_mongodb/starter/pypi_org/infrastructure/cookie_auth.py @@ -13,7 +13,7 @@ def set_auth(response: Response, user_id: int): hash_val = __hash_text(str(user_id)) val = "{}:{}".format(user_id, hash_val) - response.set_cookie(auth_cookie_name, val, secure=True, httponly=True, samesite='Lax') + response.set_cookie(auth_cookie_name, val, secure=False, httponly=True, samesite='Lax') def __hash_text(text: str) -> str: @@ -22,7 +22,7 @@ def __hash_text(text: str) -> str: def __add_cookie_callback(_, response: Response, name: str, value: str): - response.set_cookie(name, value, max_age=timedelta(days=30), secure=True, httponly=True, samesite='Lax') + response.set_cookie(name, value, max_age=timedelta(days=30), secure=False, httponly=True, samesite='Lax') def get_user_id_via_auth_cookie(request: Request) -> Optional[int]: From 41e87fd676429b9fc4b72fe7502faccb08dce049 Mon Sep 17 00:00:00 2001 From: Michael Kennedy Date: Thu, 16 Jan 2020 09:54:53 -0800 Subject: [PATCH 14/44] Minor fix for blueprints + flask run. --- app/ch06_routing/final/pypi_org/app.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/ch06_routing/final/pypi_org/app.py b/app/ch06_routing/final/pypi_org/app.py index 8b78c217..8b26ae61 100644 --- a/app/ch06_routing/final/pypi_org/app.py +++ b/app/ch06_routing/final/pypi_org/app.py @@ -25,3 +25,5 @@ def register_blueprints(): if __name__ == '__main__': main() +else: + register_blueprints() From b61630c751a7a00e556501879e134a5bd78f206a Mon Sep 17 00:00:00 2001 From: Michael Kennedy Date: Fri, 24 Jan 2020 09:36:07 -0800 Subject: [PATCH 15/44] Spelling (for me at least. :) ) --- .idea/dictionaries/mkennedy.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/.idea/dictionaries/mkennedy.xml b/.idea/dictionaries/mkennedy.xml index e5612f37..630ad4c3 100644 --- a/.idea/dictionaries/mkennedy.xml +++ b/.idea/dictionaries/mkennedy.xml @@ -7,6 +7,7 @@ passlib pypi sqlalchemy + tablename werkzeug From 9047feed3dc73896809ca1b963daa2181446be9f Mon Sep 17 00:00:00 2001 From: Michael Kennedy Date: Mon, 27 Apr 2020 15:28:45 -0700 Subject: [PATCH 16/44] Set connect_args={"check_same_thread": False} to avoid "not the owner thread" warnings from sqlite. --- app/ch09_sqlalchemy/final/.idea/.name | 2 +- .../.idea/flask ch09_sqlalchemy - final.iml | 21 +++++++++++++++++++ .../final/pypi_org/data/db_session.py | 5 ++++- app/ch10_using_sqlachemy/final/.idea/.name | 2 +- ...=> flask ch10_using_sqlachemy - final.iml} | 0 .../inspectionProfiles/Project_Default.xml | 21 +++++++++++++++++++ .../final/.idea/modules.xml | 2 +- .../final/pypi_org/data/db_session.py | 5 ++++- .../flask ch10_using_sqlachemy - starter.iml | 16 ++++++++++++++ .../starter/pypi_org/data/db_session.py | 5 ++++- app/ch11_migrations/final/.idea/.name | 2 +- ....iml => flask ch11_migrations - final.iml} | 0 .../inspectionProfiles/Project_Default.xml | 21 +++++++++++++++++++ app/ch11_migrations/final/.idea/modules.xml | 2 +- .../final/pypi_org/data/db_session.py | 5 ++++- .../.idea/flask ch11_migrations - starter.iml | 16 ++++++++++++++ .../starter/pypi_org/data/db_session.py | 5 ++++- app/ch12-forms/final/.idea/.name | 2 +- .../final/.idea/dataSources.local.xml | 2 +- ...forms.iml => flask ch12-forms - final.iml} | 5 +---- app/ch12-forms/final/.idea/modules.xml | 2 +- .../final/pypi_org/data/db_session.py | 5 ++++- .../.idea/flask ch12-forms - starter.iml | 16 ++++++++++++++ .../starter/pypi_org/data/db_session.py | 5 ++++- .../final/.idea/dataSources.local.xml | 8 +++++-- .../final/pypi_org/data/db_session.py | 5 ++++- .../starter/.idea/dataSources.local.xml | 8 +++++-- .../starter/pypi_org/data/db_session.py | 5 ++++- .../final/pypi_org/data/db_session.py | 5 ++++- .../starter/.idea/dataSources.local.xml | 8 +++++-- .../starter/pypi_org/data/db_session.py | 5 ++++- .../final/pypi_org/data/db_session.py | 5 ++++- .../starter/pypi_org/data/db_session.py | 5 ++++- 33 files changed, 190 insertions(+), 31 deletions(-) create mode 100644 app/ch09_sqlalchemy/final/.idea/flask ch09_sqlalchemy - final.iml rename app/ch10_using_sqlachemy/final/.idea/{using_sqlachemy.iml => flask ch10_using_sqlachemy - final.iml} (100%) create mode 100644 app/ch10_using_sqlachemy/final/.idea/inspectionProfiles/Project_Default.xml create mode 100644 app/ch10_using_sqlachemy/starter/.idea/flask ch10_using_sqlachemy - starter.iml rename app/ch11_migrations/final/.idea/{migrations.iml => flask ch11_migrations - final.iml} (100%) create mode 100644 app/ch11_migrations/final/.idea/inspectionProfiles/Project_Default.xml create mode 100644 app/ch11_migrations/starter/.idea/flask ch11_migrations - starter.iml rename app/ch12-forms/final/.idea/{flask-html-forms.iml => flask ch12-forms - final.iml} (75%) create mode 100644 app/ch12-forms/starter/.idea/flask ch12-forms - starter.iml diff --git a/app/ch09_sqlalchemy/final/.idea/.name b/app/ch09_sqlalchemy/final/.idea/.name index b10607c3..a19c1f1a 100644 --- a/app/ch09_sqlalchemy/final/.idea/.name +++ b/app/ch09_sqlalchemy/final/.idea/.name @@ -1 +1 @@ -sqlalchemy \ No newline at end of file +flask ch09_sqlalchemy - final \ No newline at end of file diff --git a/app/ch09_sqlalchemy/final/.idea/flask ch09_sqlalchemy - final.iml b/app/ch09_sqlalchemy/final/.idea/flask ch09_sqlalchemy - final.iml new file mode 100644 index 00000000..7f037c06 --- /dev/null +++ b/app/ch09_sqlalchemy/final/.idea/flask ch09_sqlalchemy - final.iml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/ch09_sqlalchemy/final/pypi_org/data/db_session.py b/app/ch09_sqlalchemy/final/pypi_org/data/db_session.py index 24973d64..e41bddc7 100644 --- a/app/ch09_sqlalchemy/final/pypi_org/data/db_session.py +++ b/app/ch09_sqlalchemy/final/pypi_org/data/db_session.py @@ -18,7 +18,10 @@ def global_init(db_file: str): conn_str = 'sqlite:///' + db_file.strip() print("Connecting to DB with {}".format(conn_str)) - engine = sa.create_engine(conn_str, echo=False) + # Adding check_same_thread = False after the recording. This can be an issue about + # creating / owner thread when cleaning up sessions, etc. This is a sqlite restriction + # that we probably don't care about in this example. + engine = sa.create_engine(conn_str, echo=False, connect_args={"check_same_thread": False}) factory = orm.sessionmaker(bind=engine) # noinspection PyUnresolvedReferences diff --git a/app/ch10_using_sqlachemy/final/.idea/.name b/app/ch10_using_sqlachemy/final/.idea/.name index 32757fc9..7639e47c 100644 --- a/app/ch10_using_sqlachemy/final/.idea/.name +++ b/app/ch10_using_sqlachemy/final/.idea/.name @@ -1 +1 @@ -using_sqlachemy \ No newline at end of file +flask ch10_using_sqlachemy - final \ No newline at end of file diff --git a/app/ch10_using_sqlachemy/final/.idea/using_sqlachemy.iml b/app/ch10_using_sqlachemy/final/.idea/flask ch10_using_sqlachemy - final.iml similarity index 100% rename from app/ch10_using_sqlachemy/final/.idea/using_sqlachemy.iml rename to app/ch10_using_sqlachemy/final/.idea/flask ch10_using_sqlachemy - final.iml diff --git a/app/ch10_using_sqlachemy/final/.idea/inspectionProfiles/Project_Default.xml b/app/ch10_using_sqlachemy/final/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 00000000..05d4a622 --- /dev/null +++ b/app/ch10_using_sqlachemy/final/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,21 @@ + + + + \ No newline at end of file diff --git a/app/ch10_using_sqlachemy/final/.idea/modules.xml b/app/ch10_using_sqlachemy/final/.idea/modules.xml index bd757f42..dd7bdfdf 100644 --- a/app/ch10_using_sqlachemy/final/.idea/modules.xml +++ b/app/ch10_using_sqlachemy/final/.idea/modules.xml @@ -2,7 +2,7 @@ - + \ No newline at end of file diff --git a/app/ch10_using_sqlachemy/final/pypi_org/data/db_session.py b/app/ch10_using_sqlachemy/final/pypi_org/data/db_session.py index 50861b3b..addbaff9 100644 --- a/app/ch10_using_sqlachemy/final/pypi_org/data/db_session.py +++ b/app/ch10_using_sqlachemy/final/pypi_org/data/db_session.py @@ -19,7 +19,10 @@ def global_init(db_file: str): conn_str = 'sqlite:///' + db_file.strip() print("Connecting to DB with {}".format(conn_str)) - engine = sa.create_engine(conn_str, echo=False) + # Adding check_same_thread = False after the recording. This can be an issue about + # creating / owner thread when cleaning up sessions, etc. This is a sqlite restriction + # that we probably don't care about in this example. + engine = sa.create_engine(conn_str, echo=False, connect_args={"check_same_thread": False}) __factory = orm.sessionmaker(bind=engine) # noinspection PyUnresolvedReferences diff --git a/app/ch10_using_sqlachemy/starter/.idea/flask ch10_using_sqlachemy - starter.iml b/app/ch10_using_sqlachemy/starter/.idea/flask ch10_using_sqlachemy - starter.iml new file mode 100644 index 00000000..2fbaf4e6 --- /dev/null +++ b/app/ch10_using_sqlachemy/starter/.idea/flask ch10_using_sqlachemy - starter.iml @@ -0,0 +1,16 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/app/ch10_using_sqlachemy/starter/pypi_org/data/db_session.py b/app/ch10_using_sqlachemy/starter/pypi_org/data/db_session.py index 24973d64..e41bddc7 100644 --- a/app/ch10_using_sqlachemy/starter/pypi_org/data/db_session.py +++ b/app/ch10_using_sqlachemy/starter/pypi_org/data/db_session.py @@ -18,7 +18,10 @@ def global_init(db_file: str): conn_str = 'sqlite:///' + db_file.strip() print("Connecting to DB with {}".format(conn_str)) - engine = sa.create_engine(conn_str, echo=False) + # Adding check_same_thread = False after the recording. This can be an issue about + # creating / owner thread when cleaning up sessions, etc. This is a sqlite restriction + # that we probably don't care about in this example. + engine = sa.create_engine(conn_str, echo=False, connect_args={"check_same_thread": False}) factory = orm.sessionmaker(bind=engine) # noinspection PyUnresolvedReferences diff --git a/app/ch11_migrations/final/.idea/.name b/app/ch11_migrations/final/.idea/.name index e0d1ea3b..96b7dad3 100644 --- a/app/ch11_migrations/final/.idea/.name +++ b/app/ch11_migrations/final/.idea/.name @@ -1 +1 @@ -migrations \ No newline at end of file +flask ch11_migrations - final \ No newline at end of file diff --git a/app/ch11_migrations/final/.idea/migrations.iml b/app/ch11_migrations/final/.idea/flask ch11_migrations - final.iml similarity index 100% rename from app/ch11_migrations/final/.idea/migrations.iml rename to app/ch11_migrations/final/.idea/flask ch11_migrations - final.iml diff --git a/app/ch11_migrations/final/.idea/inspectionProfiles/Project_Default.xml b/app/ch11_migrations/final/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 00000000..05d4a622 --- /dev/null +++ b/app/ch11_migrations/final/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,21 @@ + + + + \ No newline at end of file diff --git a/app/ch11_migrations/final/.idea/modules.xml b/app/ch11_migrations/final/.idea/modules.xml index c46f156d..9b276c4f 100644 --- a/app/ch11_migrations/final/.idea/modules.xml +++ b/app/ch11_migrations/final/.idea/modules.xml @@ -2,7 +2,7 @@ - + \ No newline at end of file diff --git a/app/ch11_migrations/final/pypi_org/data/db_session.py b/app/ch11_migrations/final/pypi_org/data/db_session.py index 50861b3b..addbaff9 100644 --- a/app/ch11_migrations/final/pypi_org/data/db_session.py +++ b/app/ch11_migrations/final/pypi_org/data/db_session.py @@ -19,7 +19,10 @@ def global_init(db_file: str): conn_str = 'sqlite:///' + db_file.strip() print("Connecting to DB with {}".format(conn_str)) - engine = sa.create_engine(conn_str, echo=False) + # Adding check_same_thread = False after the recording. This can be an issue about + # creating / owner thread when cleaning up sessions, etc. This is a sqlite restriction + # that we probably don't care about in this example. + engine = sa.create_engine(conn_str, echo=False, connect_args={"check_same_thread": False}) __factory = orm.sessionmaker(bind=engine) # noinspection PyUnresolvedReferences diff --git a/app/ch11_migrations/starter/.idea/flask ch11_migrations - starter.iml b/app/ch11_migrations/starter/.idea/flask ch11_migrations - starter.iml new file mode 100644 index 00000000..2fbaf4e6 --- /dev/null +++ b/app/ch11_migrations/starter/.idea/flask ch11_migrations - starter.iml @@ -0,0 +1,16 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/app/ch11_migrations/starter/pypi_org/data/db_session.py b/app/ch11_migrations/starter/pypi_org/data/db_session.py index 50861b3b..addbaff9 100644 --- a/app/ch11_migrations/starter/pypi_org/data/db_session.py +++ b/app/ch11_migrations/starter/pypi_org/data/db_session.py @@ -19,7 +19,10 @@ def global_init(db_file: str): conn_str = 'sqlite:///' + db_file.strip() print("Connecting to DB with {}".format(conn_str)) - engine = sa.create_engine(conn_str, echo=False) + # Adding check_same_thread = False after the recording. This can be an issue about + # creating / owner thread when cleaning up sessions, etc. This is a sqlite restriction + # that we probably don't care about in this example. + engine = sa.create_engine(conn_str, echo=False, connect_args={"check_same_thread": False}) __factory = orm.sessionmaker(bind=engine) # noinspection PyUnresolvedReferences diff --git a/app/ch12-forms/final/.idea/.name b/app/ch12-forms/final/.idea/.name index 868ff2d5..7e120f47 100644 --- a/app/ch12-forms/final/.idea/.name +++ b/app/ch12-forms/final/.idea/.name @@ -1 +1 @@ -flask-html-forms \ No newline at end of file +flask ch12-forms - final \ No newline at end of file diff --git a/app/ch12-forms/final/.idea/dataSources.local.xml b/app/ch12-forms/final/.idea/dataSources.local.xml index 298cdef1..7a996036 100644 --- a/app/ch12-forms/final/.idea/dataSources.local.xml +++ b/app/ch12-forms/final/.idea/dataSources.local.xml @@ -6,7 +6,7 @@ " - false + no-auth diff --git a/app/ch12-forms/final/.idea/flask-html-forms.iml b/app/ch12-forms/final/.idea/flask ch12-forms - final.iml similarity index 75% rename from app/ch12-forms/final/.idea/flask-html-forms.iml rename to app/ch12-forms/final/.idea/flask ch12-forms - final.iml index 776f1339..80a07251 100644 --- a/app/ch12-forms/final/.idea/flask-html-forms.iml +++ b/app/ch12-forms/final/.idea/flask ch12-forms - final.iml @@ -4,7 +4,7 @@ - + @@ -15,7 +15,4 @@ - - \ No newline at end of file diff --git a/app/ch12-forms/final/.idea/modules.xml b/app/ch12-forms/final/.idea/modules.xml index bad5f02c..c3d3a250 100644 --- a/app/ch12-forms/final/.idea/modules.xml +++ b/app/ch12-forms/final/.idea/modules.xml @@ -2,7 +2,7 @@ - + \ No newline at end of file diff --git a/app/ch12-forms/final/pypi_org/data/db_session.py b/app/ch12-forms/final/pypi_org/data/db_session.py index 50861b3b..addbaff9 100644 --- a/app/ch12-forms/final/pypi_org/data/db_session.py +++ b/app/ch12-forms/final/pypi_org/data/db_session.py @@ -19,7 +19,10 @@ def global_init(db_file: str): conn_str = 'sqlite:///' + db_file.strip() print("Connecting to DB with {}".format(conn_str)) - engine = sa.create_engine(conn_str, echo=False) + # Adding check_same_thread = False after the recording. This can be an issue about + # creating / owner thread when cleaning up sessions, etc. This is a sqlite restriction + # that we probably don't care about in this example. + engine = sa.create_engine(conn_str, echo=False, connect_args={"check_same_thread": False}) __factory = orm.sessionmaker(bind=engine) # noinspection PyUnresolvedReferences diff --git a/app/ch12-forms/starter/.idea/flask ch12-forms - starter.iml b/app/ch12-forms/starter/.idea/flask ch12-forms - starter.iml new file mode 100644 index 00000000..2fbaf4e6 --- /dev/null +++ b/app/ch12-forms/starter/.idea/flask ch12-forms - starter.iml @@ -0,0 +1,16 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/app/ch12-forms/starter/pypi_org/data/db_session.py b/app/ch12-forms/starter/pypi_org/data/db_session.py index 50861b3b..addbaff9 100644 --- a/app/ch12-forms/starter/pypi_org/data/db_session.py +++ b/app/ch12-forms/starter/pypi_org/data/db_session.py @@ -19,7 +19,10 @@ def global_init(db_file: str): conn_str = 'sqlite:///' + db_file.strip() print("Connecting to DB with {}".format(conn_str)) - engine = sa.create_engine(conn_str, echo=False) + # Adding check_same_thread = False after the recording. This can be an issue about + # creating / owner thread when cleaning up sessions, etc. This is a sqlite restriction + # that we probably don't care about in this example. + engine = sa.create_engine(conn_str, echo=False, connect_args={"check_same_thread": False}) __factory = orm.sessionmaker(bind=engine) # noinspection PyUnresolvedReferences diff --git a/app/ch13-validation/final/.idea/dataSources.local.xml b/app/ch13-validation/final/.idea/dataSources.local.xml index 94233bb2..7a996036 100644 --- a/app/ch13-validation/final/.idea/dataSources.local.xml +++ b/app/ch13-validation/final/.idea/dataSources.local.xml @@ -6,8 +6,12 @@ " - false - *:@ + no-auth + + + + + \ No newline at end of file diff --git a/app/ch13-validation/final/pypi_org/data/db_session.py b/app/ch13-validation/final/pypi_org/data/db_session.py index acfc485d..39b135cc 100644 --- a/app/ch13-validation/final/pypi_org/data/db_session.py +++ b/app/ch13-validation/final/pypi_org/data/db_session.py @@ -19,7 +19,10 @@ def global_init(db_file: str): conn_str = 'sqlite:///' + db_file.strip() print("Connecting to DB with {}".format(conn_str)) - engine = sa.create_engine(conn_str, echo=False) + # Adding check_same_thread = False after the recording. This can be an issue about + # creating / owner thread when cleaning up sessions, etc. This is a sqlite restriction + # that we probably don't care about in this example. + engine = sa.create_engine(conn_str, echo=False, connect_args={"check_same_thread": False}) __factory = orm.sessionmaker(bind=engine) # noinspection PyUnresolvedReferences diff --git a/app/ch13-validation/starter/.idea/dataSources.local.xml b/app/ch13-validation/starter/.idea/dataSources.local.xml index 94233bb2..7a996036 100644 --- a/app/ch13-validation/starter/.idea/dataSources.local.xml +++ b/app/ch13-validation/starter/.idea/dataSources.local.xml @@ -6,8 +6,12 @@ " - false - *:@ + no-auth + + + + + \ No newline at end of file diff --git a/app/ch13-validation/starter/pypi_org/data/db_session.py b/app/ch13-validation/starter/pypi_org/data/db_session.py index 50861b3b..addbaff9 100644 --- a/app/ch13-validation/starter/pypi_org/data/db_session.py +++ b/app/ch13-validation/starter/pypi_org/data/db_session.py @@ -19,7 +19,10 @@ def global_init(db_file: str): conn_str = 'sqlite:///' + db_file.strip() print("Connecting to DB with {}".format(conn_str)) - engine = sa.create_engine(conn_str, echo=False) + # Adding check_same_thread = False after the recording. This can be an issue about + # creating / owner thread when cleaning up sessions, etc. This is a sqlite restriction + # that we probably don't care about in this example. + engine = sa.create_engine(conn_str, echo=False, connect_args={"check_same_thread": False}) __factory = orm.sessionmaker(bind=engine) # noinspection PyUnresolvedReferences diff --git a/app/ch14_testing/final/pypi_org/data/db_session.py b/app/ch14_testing/final/pypi_org/data/db_session.py index acfc485d..39b135cc 100644 --- a/app/ch14_testing/final/pypi_org/data/db_session.py +++ b/app/ch14_testing/final/pypi_org/data/db_session.py @@ -19,7 +19,10 @@ def global_init(db_file: str): conn_str = 'sqlite:///' + db_file.strip() print("Connecting to DB with {}".format(conn_str)) - engine = sa.create_engine(conn_str, echo=False) + # Adding check_same_thread = False after the recording. This can be an issue about + # creating / owner thread when cleaning up sessions, etc. This is a sqlite restriction + # that we probably don't care about in this example. + engine = sa.create_engine(conn_str, echo=False, connect_args={"check_same_thread": False}) __factory = orm.sessionmaker(bind=engine) # noinspection PyUnresolvedReferences diff --git a/app/ch14_testing/starter/.idea/dataSources.local.xml b/app/ch14_testing/starter/.idea/dataSources.local.xml index 94233bb2..7a996036 100644 --- a/app/ch14_testing/starter/.idea/dataSources.local.xml +++ b/app/ch14_testing/starter/.idea/dataSources.local.xml @@ -6,8 +6,12 @@ " - false - *:@ + no-auth + + + + + \ No newline at end of file diff --git a/app/ch14_testing/starter/pypi_org/data/db_session.py b/app/ch14_testing/starter/pypi_org/data/db_session.py index acfc485d..39b135cc 100644 --- a/app/ch14_testing/starter/pypi_org/data/db_session.py +++ b/app/ch14_testing/starter/pypi_org/data/db_session.py @@ -19,7 +19,10 @@ def global_init(db_file: str): conn_str = 'sqlite:///' + db_file.strip() print("Connecting to DB with {}".format(conn_str)) - engine = sa.create_engine(conn_str, echo=False) + # Adding check_same_thread = False after the recording. This can be an issue about + # creating / owner thread when cleaning up sessions, etc. This is a sqlite restriction + # that we probably don't care about in this example. + engine = sa.create_engine(conn_str, echo=False, connect_args={"check_same_thread": False}) __factory = orm.sessionmaker(bind=engine) # noinspection PyUnresolvedReferences diff --git a/app/ch15_deploy/final/pypi_org/data/db_session.py b/app/ch15_deploy/final/pypi_org/data/db_session.py index acfc485d..39b135cc 100644 --- a/app/ch15_deploy/final/pypi_org/data/db_session.py +++ b/app/ch15_deploy/final/pypi_org/data/db_session.py @@ -19,7 +19,10 @@ def global_init(db_file: str): conn_str = 'sqlite:///' + db_file.strip() print("Connecting to DB with {}".format(conn_str)) - engine = sa.create_engine(conn_str, echo=False) + # Adding check_same_thread = False after the recording. This can be an issue about + # creating / owner thread when cleaning up sessions, etc. This is a sqlite restriction + # that we probably don't care about in this example. + engine = sa.create_engine(conn_str, echo=False, connect_args={"check_same_thread": False}) __factory = orm.sessionmaker(bind=engine) # noinspection PyUnresolvedReferences diff --git a/app/ch15_deploy/starter/pypi_org/data/db_session.py b/app/ch15_deploy/starter/pypi_org/data/db_session.py index acfc485d..39b135cc 100644 --- a/app/ch15_deploy/starter/pypi_org/data/db_session.py +++ b/app/ch15_deploy/starter/pypi_org/data/db_session.py @@ -19,7 +19,10 @@ def global_init(db_file: str): conn_str = 'sqlite:///' + db_file.strip() print("Connecting to DB with {}".format(conn_str)) - engine = sa.create_engine(conn_str, echo=False) + # Adding check_same_thread = False after the recording. This can be an issue about + # creating / owner thread when cleaning up sessions, etc. This is a sqlite restriction + # that we probably don't care about in this example. + engine = sa.create_engine(conn_str, echo=False, connect_args={"check_same_thread": False}) __factory = orm.sessionmaker(bind=engine) # noinspection PyUnresolvedReferences From b98d93fd01f63187b6099ea17700243be332b09e Mon Sep 17 00:00:00 2001 From: Michael Kennedy Date: Mon, 27 Apr 2020 15:29:19 -0700 Subject: [PATCH 17/44] Ignore these. --- .gitignore | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/.gitignore b/.gitignore index 98d0aa73..373e200e 100644 --- a/.gitignore +++ b/.gitignore @@ -142,3 +142,36 @@ app/ch11_migrations/final/.idea/dataSources/bb882f32-bdb3-45cb-adce-c46711dd125e .idea/vagrant.xml .idea/vcs.xml .idea/inspectionProfiles/profiles_settings.xml +app/ch09_sqlalchemy/final/.idea/inspectionProfiles/profiles_settings.xml +app/ch09_sqlalchemy/final/.idea/inspectionProfiles/Project_Default.xml +app/ch10_using_sqlachemy/starter/.idea/$CACHE_FILE$ +app/ch10_using_sqlachemy/starter/.idea/.gitignore +app/ch10_using_sqlachemy/starter/.idea/.name +app/ch10_using_sqlachemy/starter/.idea/misc.xml +app/ch10_using_sqlachemy/starter/.idea/modules.xml +app/ch10_using_sqlachemy/starter/.idea/vagrant.xml +app/ch10_using_sqlachemy/starter/.idea/vcs.xml +app/ch10_using_sqlachemy/starter/.idea/inspectionProfiles/profiles_settings.xml +app/ch10_using_sqlachemy/starter/.idea/inspectionProfiles/Project_Default.xml +app/ch11_migrations/starter/.idea/$CACHE_FILE$ +app/ch11_migrations/starter/.idea/.gitignore +app/ch11_migrations/starter/.idea/.name +app/ch11_migrations/starter/.idea/misc.xml +app/ch11_migrations/starter/.idea/modules.xml +app/ch11_migrations/starter/.idea/vagrant.xml +app/ch11_migrations/starter/.idea/vcs.xml +app/ch11_migrations/starter/.idea/inspectionProfiles/profiles_settings.xml +app/ch11_migrations/starter/.idea/inspectionProfiles/Project_Default.xml +app/ch12-forms/starter/.idea/$CACHE_FILE$ +app/ch12-forms/starter/.idea/.gitignore +app/ch12-forms/starter/.idea/.name +app/ch12-forms/starter/.idea/misc.xml +app/ch12-forms/starter/.idea/modules.xml +app/ch12-forms/starter/.idea/vagrant.xml +app/ch12-forms/starter/.idea/vcs.xml +app/ch12-forms/starter/.idea/inspectionProfiles/profiles_settings.xml +app/ch12-forms/starter/.idea/inspectionProfiles/Project_Default.xml +app/ch13-validation/starter/.idea/inspectionProfiles/Project_Default.xml +app/ch14_testing/final/.idea/inspectionProfiles/Project_Default.xml +app/ch14_testing/starter/.idea/inspectionProfiles/Project_Default.xml +app/ch15_deploy/final/.idea/inspectionProfiles/Project_Default.xml From 35bb6ce8aaf75bb6f4b4a25505c67f93b5fb33f6 Mon Sep 17 00:00:00 2001 From: Michael Kennedy Date: Tue, 28 Jul 2020 12:54:48 -0700 Subject: [PATCH 18/44] More explanation for what's up with the path here. --- .../final/.idea/flask ch10_using_sqlachemy - final.iml | 7 +++---- app/ch10_using_sqlachemy/final/.idea/misc.xml | 2 +- app/ch10_using_sqlachemy/final/pypi_org/bin/load_data.py | 3 +++ .../starter/.idea/flask ch10_using_sqlachemy - starter.iml | 2 +- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/app/ch10_using_sqlachemy/final/.idea/flask ch10_using_sqlachemy - final.iml b/app/ch10_using_sqlachemy/final/.idea/flask ch10_using_sqlachemy - final.iml index cb75d37a..31330bb6 100644 --- a/app/ch10_using_sqlachemy/final/.idea/flask ch10_using_sqlachemy - final.iml +++ b/app/ch10_using_sqlachemy/final/.idea/flask ch10_using_sqlachemy - final.iml @@ -1,7 +1,9 @@ - + + + @@ -13,7 +15,4 @@ - - \ No newline at end of file diff --git a/app/ch10_using_sqlachemy/final/.idea/misc.xml b/app/ch10_using_sqlachemy/final/.idea/misc.xml index aa984a42..a74a0a3b 100644 --- a/app/ch10_using_sqlachemy/final/.idea/misc.xml +++ b/app/ch10_using_sqlachemy/final/.idea/misc.xml @@ -3,5 +3,5 @@ - + \ No newline at end of file diff --git a/app/ch10_using_sqlachemy/final/pypi_org/bin/load_data.py b/app/ch10_using_sqlachemy/final/pypi_org/bin/load_data.py index ba62ff7d..7f3cd4f8 100644 --- a/app/ch10_using_sqlachemy/final/pypi_org/bin/load_data.py +++ b/app/ch10_using_sqlachemy/final/pypi_org/bin/load_data.py @@ -4,9 +4,12 @@ import time from typing import List, Optional, Dict +# This is listed as progressbar2: +# noinspection PyPackageRequirements,PyPackageRequirements import progressbar from dateutil.parser import parse +# Make sure we can import pypi_org.* sys.path.insert(0, os.path.abspath(os.path.join( os.path.dirname(__file__), "..", ".."))) diff --git a/app/ch10_using_sqlachemy/starter/.idea/flask ch10_using_sqlachemy - starter.iml b/app/ch10_using_sqlachemy/starter/.idea/flask ch10_using_sqlachemy - starter.iml index 2fbaf4e6..f50d93bf 100644 --- a/app/ch10_using_sqlachemy/starter/.idea/flask ch10_using_sqlachemy - starter.iml +++ b/app/ch10_using_sqlachemy/starter/.idea/flask ch10_using_sqlachemy - starter.iml @@ -2,7 +2,7 @@ - + From e8040241a4acf9ca4a0706fb40861877a8b8d0e7 Mon Sep 17 00:00:00 2001 From: aambrioso Date: Tue, 4 Aug 2020 20:36:09 -0400 Subject: [PATCH 19/44] change the position of the path-fix code in basic_inserts.py --- .../final/pypi_org/bin/basic_inserts.py | 8 ++++---- app/ch11_migrations/final/pypi_org/bin/basic_inserts.py | 8 ++++---- app/ch11_migrations/starter/pypi_org/bin/basic_inserts.py | 8 ++++---- app/ch12-forms/final/pypi_org/bin/basic_inserts.py | 8 ++++---- app/ch12-forms/starter/pypi_org/bin/basic_inserts.py | 8 ++++---- app/ch13-validation/final/pypi_org/bin/basic_inserts.py | 8 ++++---- app/ch13-validation/starter/pypi_org/bin/basic_inserts.py | 8 ++++---- app/ch14_testing/starter/pypi_org/bin/basic_inserts.py | 8 ++++---- app/ch15_deploy/final/pypi_org/bin/basic_inserts.py | 8 ++++---- app/ch15_deploy/starter/pypi_org/bin/basic_inserts.py | 8 ++++---- app/ch16_mongodb/final/pypi_org/bin/basic_inserts.py | 8 ++++---- app/ch16_mongodb/starter/pypi_org/bin/basic_inserts.py | 8 ++++---- 12 files changed, 48 insertions(+), 48 deletions(-) diff --git a/app/ch10_using_sqlachemy/final/pypi_org/bin/basic_inserts.py b/app/ch10_using_sqlachemy/final/pypi_org/bin/basic_inserts.py index 3a2f360d..d622a6ae 100644 --- a/app/ch10_using_sqlachemy/final/pypi_org/bin/basic_inserts.py +++ b/app/ch10_using_sqlachemy/final/pypi_org/bin/basic_inserts.py @@ -1,14 +1,14 @@ import os import sys -import pypi_org.data.db_session as db_session -from pypi_org.data.package import Package -from pypi_org.data.releases import Release - # Make it run more easily outside of PyCharm sys.path.insert(0, os.path.abspath(os.path.join( os.path.dirname(__file__), "..", ".."))) +import pypi_org.data.db_session as db_session +from pypi_org.data.package import Package +from pypi_org.data.releases import Release + def main(): init_db() diff --git a/app/ch11_migrations/final/pypi_org/bin/basic_inserts.py b/app/ch11_migrations/final/pypi_org/bin/basic_inserts.py index 3a2f360d..d622a6ae 100644 --- a/app/ch11_migrations/final/pypi_org/bin/basic_inserts.py +++ b/app/ch11_migrations/final/pypi_org/bin/basic_inserts.py @@ -1,14 +1,14 @@ import os import sys -import pypi_org.data.db_session as db_session -from pypi_org.data.package import Package -from pypi_org.data.releases import Release - # Make it run more easily outside of PyCharm sys.path.insert(0, os.path.abspath(os.path.join( os.path.dirname(__file__), "..", ".."))) +import pypi_org.data.db_session as db_session +from pypi_org.data.package import Package +from pypi_org.data.releases import Release + def main(): init_db() diff --git a/app/ch11_migrations/starter/pypi_org/bin/basic_inserts.py b/app/ch11_migrations/starter/pypi_org/bin/basic_inserts.py index 3a2f360d..d622a6ae 100644 --- a/app/ch11_migrations/starter/pypi_org/bin/basic_inserts.py +++ b/app/ch11_migrations/starter/pypi_org/bin/basic_inserts.py @@ -1,14 +1,14 @@ import os import sys -import pypi_org.data.db_session as db_session -from pypi_org.data.package import Package -from pypi_org.data.releases import Release - # Make it run more easily outside of PyCharm sys.path.insert(0, os.path.abspath(os.path.join( os.path.dirname(__file__), "..", ".."))) +import pypi_org.data.db_session as db_session +from pypi_org.data.package import Package +from pypi_org.data.releases import Release + def main(): init_db() diff --git a/app/ch12-forms/final/pypi_org/bin/basic_inserts.py b/app/ch12-forms/final/pypi_org/bin/basic_inserts.py index 3a2f360d..d622a6ae 100644 --- a/app/ch12-forms/final/pypi_org/bin/basic_inserts.py +++ b/app/ch12-forms/final/pypi_org/bin/basic_inserts.py @@ -1,14 +1,14 @@ import os import sys -import pypi_org.data.db_session as db_session -from pypi_org.data.package import Package -from pypi_org.data.releases import Release - # Make it run more easily outside of PyCharm sys.path.insert(0, os.path.abspath(os.path.join( os.path.dirname(__file__), "..", ".."))) +import pypi_org.data.db_session as db_session +from pypi_org.data.package import Package +from pypi_org.data.releases import Release + def main(): init_db() diff --git a/app/ch12-forms/starter/pypi_org/bin/basic_inserts.py b/app/ch12-forms/starter/pypi_org/bin/basic_inserts.py index 3a2f360d..d622a6ae 100644 --- a/app/ch12-forms/starter/pypi_org/bin/basic_inserts.py +++ b/app/ch12-forms/starter/pypi_org/bin/basic_inserts.py @@ -1,14 +1,14 @@ import os import sys -import pypi_org.data.db_session as db_session -from pypi_org.data.package import Package -from pypi_org.data.releases import Release - # Make it run more easily outside of PyCharm sys.path.insert(0, os.path.abspath(os.path.join( os.path.dirname(__file__), "..", ".."))) +import pypi_org.data.db_session as db_session +from pypi_org.data.package import Package +from pypi_org.data.releases import Release + def main(): init_db() diff --git a/app/ch13-validation/final/pypi_org/bin/basic_inserts.py b/app/ch13-validation/final/pypi_org/bin/basic_inserts.py index 3a2f360d..d622a6ae 100644 --- a/app/ch13-validation/final/pypi_org/bin/basic_inserts.py +++ b/app/ch13-validation/final/pypi_org/bin/basic_inserts.py @@ -1,14 +1,14 @@ import os import sys -import pypi_org.data.db_session as db_session -from pypi_org.data.package import Package -from pypi_org.data.releases import Release - # Make it run more easily outside of PyCharm sys.path.insert(0, os.path.abspath(os.path.join( os.path.dirname(__file__), "..", ".."))) +import pypi_org.data.db_session as db_session +from pypi_org.data.package import Package +from pypi_org.data.releases import Release + def main(): init_db() diff --git a/app/ch13-validation/starter/pypi_org/bin/basic_inserts.py b/app/ch13-validation/starter/pypi_org/bin/basic_inserts.py index 3a2f360d..d622a6ae 100644 --- a/app/ch13-validation/starter/pypi_org/bin/basic_inserts.py +++ b/app/ch13-validation/starter/pypi_org/bin/basic_inserts.py @@ -1,14 +1,14 @@ import os import sys -import pypi_org.data.db_session as db_session -from pypi_org.data.package import Package -from pypi_org.data.releases import Release - # Make it run more easily outside of PyCharm sys.path.insert(0, os.path.abspath(os.path.join( os.path.dirname(__file__), "..", ".."))) +import pypi_org.data.db_session as db_session +from pypi_org.data.package import Package +from pypi_org.data.releases import Release + def main(): init_db() diff --git a/app/ch14_testing/starter/pypi_org/bin/basic_inserts.py b/app/ch14_testing/starter/pypi_org/bin/basic_inserts.py index 3a2f360d..d622a6ae 100644 --- a/app/ch14_testing/starter/pypi_org/bin/basic_inserts.py +++ b/app/ch14_testing/starter/pypi_org/bin/basic_inserts.py @@ -1,14 +1,14 @@ import os import sys -import pypi_org.data.db_session as db_session -from pypi_org.data.package import Package -from pypi_org.data.releases import Release - # Make it run more easily outside of PyCharm sys.path.insert(0, os.path.abspath(os.path.join( os.path.dirname(__file__), "..", ".."))) +import pypi_org.data.db_session as db_session +from pypi_org.data.package import Package +from pypi_org.data.releases import Release + def main(): init_db() diff --git a/app/ch15_deploy/final/pypi_org/bin/basic_inserts.py b/app/ch15_deploy/final/pypi_org/bin/basic_inserts.py index 3a2f360d..d622a6ae 100644 --- a/app/ch15_deploy/final/pypi_org/bin/basic_inserts.py +++ b/app/ch15_deploy/final/pypi_org/bin/basic_inserts.py @@ -1,14 +1,14 @@ import os import sys -import pypi_org.data.db_session as db_session -from pypi_org.data.package import Package -from pypi_org.data.releases import Release - # Make it run more easily outside of PyCharm sys.path.insert(0, os.path.abspath(os.path.join( os.path.dirname(__file__), "..", ".."))) +import pypi_org.data.db_session as db_session +from pypi_org.data.package import Package +from pypi_org.data.releases import Release + def main(): init_db() diff --git a/app/ch15_deploy/starter/pypi_org/bin/basic_inserts.py b/app/ch15_deploy/starter/pypi_org/bin/basic_inserts.py index 3a2f360d..d622a6ae 100644 --- a/app/ch15_deploy/starter/pypi_org/bin/basic_inserts.py +++ b/app/ch15_deploy/starter/pypi_org/bin/basic_inserts.py @@ -1,14 +1,14 @@ import os import sys -import pypi_org.data.db_session as db_session -from pypi_org.data.package import Package -from pypi_org.data.releases import Release - # Make it run more easily outside of PyCharm sys.path.insert(0, os.path.abspath(os.path.join( os.path.dirname(__file__), "..", ".."))) +import pypi_org.data.db_session as db_session +from pypi_org.data.package import Package +from pypi_org.data.releases import Release + def main(): init_db() diff --git a/app/ch16_mongodb/final/pypi_org/bin/basic_inserts.py b/app/ch16_mongodb/final/pypi_org/bin/basic_inserts.py index 3a2f360d..d622a6ae 100644 --- a/app/ch16_mongodb/final/pypi_org/bin/basic_inserts.py +++ b/app/ch16_mongodb/final/pypi_org/bin/basic_inserts.py @@ -1,14 +1,14 @@ import os import sys -import pypi_org.data.db_session as db_session -from pypi_org.data.package import Package -from pypi_org.data.releases import Release - # Make it run more easily outside of PyCharm sys.path.insert(0, os.path.abspath(os.path.join( os.path.dirname(__file__), "..", ".."))) +import pypi_org.data.db_session as db_session +from pypi_org.data.package import Package +from pypi_org.data.releases import Release + def main(): init_db() diff --git a/app/ch16_mongodb/starter/pypi_org/bin/basic_inserts.py b/app/ch16_mongodb/starter/pypi_org/bin/basic_inserts.py index 3a2f360d..d622a6ae 100644 --- a/app/ch16_mongodb/starter/pypi_org/bin/basic_inserts.py +++ b/app/ch16_mongodb/starter/pypi_org/bin/basic_inserts.py @@ -1,14 +1,14 @@ import os import sys -import pypi_org.data.db_session as db_session -from pypi_org.data.package import Package -from pypi_org.data.releases import Release - # Make it run more easily outside of PyCharm sys.path.insert(0, os.path.abspath(os.path.join( os.path.dirname(__file__), "..", ".."))) +import pypi_org.data.db_session as db_session +from pypi_org.data.package import Package +from pypi_org.data.releases import Release + def main(): init_db() From f0633c8849e4720f3df4b611fb86ad6563ea48d4 Mon Sep 17 00:00:00 2001 From: aambrioso Date: Tue, 4 Aug 2020 20:56:26 -0400 Subject: [PATCH 20/44] missed change to basic_inserts.py in ch14_testing\final --- app/ch14_testing/final/pypi_org/bin/basic_inserts.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/ch14_testing/final/pypi_org/bin/basic_inserts.py b/app/ch14_testing/final/pypi_org/bin/basic_inserts.py index 3a2f360d..d622a6ae 100644 --- a/app/ch14_testing/final/pypi_org/bin/basic_inserts.py +++ b/app/ch14_testing/final/pypi_org/bin/basic_inserts.py @@ -1,14 +1,14 @@ import os import sys -import pypi_org.data.db_session as db_session -from pypi_org.data.package import Package -from pypi_org.data.releases import Release - # Make it run more easily outside of PyCharm sys.path.insert(0, os.path.abspath(os.path.join( os.path.dirname(__file__), "..", ".."))) +import pypi_org.data.db_session as db_session +from pypi_org.data.package import Package +from pypi_org.data.releases import Release + def main(): init_db() From 5346e7cc13852be42d827c2d240fefc9217995ef Mon Sep 17 00:00:00 2001 From: Michael Kennedy Date: Fri, 9 Oct 2020 00:11:12 -0700 Subject: [PATCH 21/44] Add num_convert.py to the starter code, chapter 10. It's absence watch causing confusion. --- .../starter/pypi_org/infrastructure/num_convert.py | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 app/ch10_using_sqlachemy/starter/pypi_org/infrastructure/num_convert.py diff --git a/app/ch10_using_sqlachemy/starter/pypi_org/infrastructure/num_convert.py b/app/ch10_using_sqlachemy/starter/pypi_org/infrastructure/num_convert.py new file mode 100644 index 00000000..bf88a6bc --- /dev/null +++ b/app/ch10_using_sqlachemy/starter/pypi_org/infrastructure/num_convert.py @@ -0,0 +1,5 @@ +def try_int(text) -> int: + try: + return int(text) + except: + return 0 From f359e65419f307020d8976f2b475d5b952b3f83c Mon Sep 17 00:00:00 2001 From: Michael Kennedy Date: Fri, 9 Oct 2020 00:11:22 -0700 Subject: [PATCH 22/44] Add num_convert.py to the starter code, chapter 10. It's absence watch causing confusion. --- .../starter/.idea/codeStyles/codeStyleConfig.xml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 app/ch10_using_sqlachemy/starter/.idea/codeStyles/codeStyleConfig.xml diff --git a/app/ch10_using_sqlachemy/starter/.idea/codeStyles/codeStyleConfig.xml b/app/ch10_using_sqlachemy/starter/.idea/codeStyles/codeStyleConfig.xml new file mode 100644 index 00000000..a55e7a17 --- /dev/null +++ b/app/ch10_using_sqlachemy/starter/.idea/codeStyles/codeStyleConfig.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file From 6aa0a6aab978952d61590f9d72d02eac7acad4dc Mon Sep 17 00:00:00 2001 From: Michael Kennedy Date: Fri, 27 Nov 2020 22:33:15 -0800 Subject: [PATCH 23/44] code style. --- app/ch15_deploy/starter/.idea/codeStyles/codeStyleConfig.xml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 app/ch15_deploy/starter/.idea/codeStyles/codeStyleConfig.xml diff --git a/app/ch15_deploy/starter/.idea/codeStyles/codeStyleConfig.xml b/app/ch15_deploy/starter/.idea/codeStyles/codeStyleConfig.xml new file mode 100644 index 00000000..a55e7a17 --- /dev/null +++ b/app/ch15_deploy/starter/.idea/codeStyles/codeStyleConfig.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file From e7dfe3ed716324ec02a35f7dd3769cb01df97fee Mon Sep 17 00:00:00 2001 From: Michael Kennedy Date: Thu, 31 Dec 2020 07:44:34 -0800 Subject: [PATCH 24/44] Update the venv version. --- app/ch15_deploy/final/.idea/flask-deploy.iml | 5 +---- app/ch15_deploy/final/.idea/misc.xml | 2 +- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/app/ch15_deploy/final/.idea/flask-deploy.iml b/app/ch15_deploy/final/.idea/flask-deploy.iml index d0dc6825..1ac5a163 100644 --- a/app/ch15_deploy/final/.idea/flask-deploy.iml +++ b/app/ch15_deploy/final/.idea/flask-deploy.iml @@ -2,7 +2,7 @@ - + @@ -14,7 +14,4 @@ - - \ No newline at end of file diff --git a/app/ch15_deploy/final/.idea/misc.xml b/app/ch15_deploy/final/.idea/misc.xml index 349d87f1..2c526bdf 100644 --- a/app/ch15_deploy/final/.idea/misc.xml +++ b/app/ch15_deploy/final/.idea/misc.xml @@ -3,5 +3,5 @@ - + \ No newline at end of file From 99575985cbc2fac90eaf99542a11184ccc31f587 Mon Sep 17 00:00:00 2001 From: Michael Kennedy Date: Mon, 19 Apr 2021 08:50:32 -0700 Subject: [PATCH 25/44] Ignore these project files. --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 373e200e..f3397b4f 100644 --- a/.gitignore +++ b/.gitignore @@ -175,3 +175,5 @@ app/ch13-validation/starter/.idea/inspectionProfiles/Project_Default.xml app/ch14_testing/final/.idea/inspectionProfiles/Project_Default.xml app/ch14_testing/starter/.idea/inspectionProfiles/Project_Default.xml app/ch15_deploy/final/.idea/inspectionProfiles/Project_Default.xml +.idea/web-apps-flask-course.iml +.idea/inspectionProfiles/Project_Default.xml From 5280da599755985436b3081b857eecb374770bbb Mon Sep 17 00:00:00 2001 From: Michael Kennedy Date: Wed, 12 May 2021 18:05:16 -0700 Subject: [PATCH 26/44] Related to PR https://github.com/talkpython/data-driven-web-apps-with-flask/pull/20/files --- app/ch14_testing/final/tests/conftest.py | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 app/ch14_testing/final/tests/conftest.py diff --git a/app/ch14_testing/final/tests/conftest.py b/app/ch14_testing/final/tests/conftest.py new file mode 100644 index 00000000..a682b75c --- /dev/null +++ b/app/ch14_testing/final/tests/conftest.py @@ -0,0 +1,6 @@ +from test_client import * + +# Let's be sure to use conftest.py for sharing fixtures across multiple files +# Added after the recording but will help some folks. +# For more info, see: +# https://docs.pytest.org/en/6.2.x/fixture.html#conftest-py-sharing-fixtures-across-multiple-files From 6bbada588374d274c3b7b01cbda936b802a8c366 Mon Sep 17 00:00:00 2001 From: Katrina Alaimo <70788275+katrinaalaimo@users.noreply.github.com> Date: Thu, 13 May 2021 11:45:58 +0900 Subject: [PATCH 27/44] Update home_tests.py Importing `client` no longer needed with the addition of conftest.py --- app/ch14_testing/final/tests/home_tests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/ch14_testing/final/tests/home_tests.py b/app/ch14_testing/final/tests/home_tests.py index b95f48fb..b0e030be 100644 --- a/app/ch14_testing/final/tests/home_tests.py +++ b/app/ch14_testing/final/tests/home_tests.py @@ -1,6 +1,6 @@ from flask import Response -from tests.test_client import client, flask_app +from tests.test_client import flask_app from pypi_org.views import home_views From 545a2a2980c94abcd09c0893918713e211076d6d Mon Sep 17 00:00:00 2001 From: Katrina Alaimo <70788275+katrinaalaimo@users.noreply.github.com> Date: Thu, 13 May 2021 11:46:18 +0900 Subject: [PATCH 28/44] Update account_tests.py Importing `client` no longer needed with the addition of conftest.py --- app/ch14_testing/final/tests/account_tests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/ch14_testing/final/tests/account_tests.py b/app/ch14_testing/final/tests/account_tests.py index 4f5aa156..9c335dba 100644 --- a/app/ch14_testing/final/tests/account_tests.py +++ b/app/ch14_testing/final/tests/account_tests.py @@ -2,7 +2,7 @@ from pypi_org.data.users import User from pypi_org.viewmodels.account.register_viewmodel import RegisterViewModel -from tests.test_client import flask_app, client +from tests.test_client import flask_app import unittest.mock From 26fda6481549dbe3be42e54d684e93add09912e8 Mon Sep 17 00:00:00 2001 From: Michael Kennedy Date: Fri, 16 Sep 2022 14:10:00 -0700 Subject: [PATCH 29/44] Clean up unused method in cookie auth. --- .../final/pypi_org/infrastructure/cookie_auth.py | 5 ----- .../final/pypi_org/infrastructure/cookie_auth.py | 5 ----- .../starter/pypi_org/infrastructure/cookie_auth.py | 5 ----- .../final/pypi_org/infrastructure/cookie_auth.py | 5 ----- .../starter/pypi_org/infrastructure/cookie_auth.py | 5 ----- .../final/pypi_org/infrastructure/cookie_auth.py | 5 ----- .../starter/pypi_org/infrastructure/cookie_auth.py | 5 ----- .../final/pypi_org/infrastructure/cookie_auth.py | 14 +++++--------- .../starter/pypi_org/infrastructure/cookie_auth.py | 5 ----- 9 files changed, 5 insertions(+), 49 deletions(-) diff --git a/app/ch12-forms/final/pypi_org/infrastructure/cookie_auth.py b/app/ch12-forms/final/pypi_org/infrastructure/cookie_auth.py index 46a089b4..e8b1051f 100644 --- a/app/ch12-forms/final/pypi_org/infrastructure/cookie_auth.py +++ b/app/ch12-forms/final/pypi_org/infrastructure/cookie_auth.py @@ -1,5 +1,4 @@ import hashlib -from datetime import timedelta from typing import Optional from flask import Request @@ -21,10 +20,6 @@ def __hash_text(text: str) -> str: return hashlib.sha512(text.encode('utf-8')).hexdigest() -def __add_cookie_callback(_, response: Response, name: str, value: str): - response.set_cookie(name, value, max_age=timedelta(days=30), secure=False, httponly=True, samesite='Lax') - - def get_user_id_via_auth_cookie(request: Request) -> Optional[int]: if auth_cookie_name not in request.cookies: return None diff --git a/app/ch13-validation/final/pypi_org/infrastructure/cookie_auth.py b/app/ch13-validation/final/pypi_org/infrastructure/cookie_auth.py index 65ee0c10..44864438 100644 --- a/app/ch13-validation/final/pypi_org/infrastructure/cookie_auth.py +++ b/app/ch13-validation/final/pypi_org/infrastructure/cookie_auth.py @@ -1,5 +1,4 @@ import hashlib -from datetime import timedelta from typing import Optional from flask import Request @@ -21,10 +20,6 @@ def __hash_text(text: str) -> str: return hashlib.sha512(text.encode('utf-8')).hexdigest() -def __add_cookie_callback(_, response: Response, name: str, value: str): - response.set_cookie(name, value, max_age=timedelta(days=30), secure=False, httponly=True, samesite='Lax') - - def get_user_id_via_auth_cookie(request: Request) -> Optional[int]: if auth_cookie_name not in request.cookies: return None diff --git a/app/ch13-validation/starter/pypi_org/infrastructure/cookie_auth.py b/app/ch13-validation/starter/pypi_org/infrastructure/cookie_auth.py index 65ee0c10..44864438 100644 --- a/app/ch13-validation/starter/pypi_org/infrastructure/cookie_auth.py +++ b/app/ch13-validation/starter/pypi_org/infrastructure/cookie_auth.py @@ -1,5 +1,4 @@ import hashlib -from datetime import timedelta from typing import Optional from flask import Request @@ -21,10 +20,6 @@ def __hash_text(text: str) -> str: return hashlib.sha512(text.encode('utf-8')).hexdigest() -def __add_cookie_callback(_, response: Response, name: str, value: str): - response.set_cookie(name, value, max_age=timedelta(days=30), secure=False, httponly=True, samesite='Lax') - - def get_user_id_via_auth_cookie(request: Request) -> Optional[int]: if auth_cookie_name not in request.cookies: return None diff --git a/app/ch14_testing/final/pypi_org/infrastructure/cookie_auth.py b/app/ch14_testing/final/pypi_org/infrastructure/cookie_auth.py index c68ca6e5..42a19606 100644 --- a/app/ch14_testing/final/pypi_org/infrastructure/cookie_auth.py +++ b/app/ch14_testing/final/pypi_org/infrastructure/cookie_auth.py @@ -1,5 +1,4 @@ import hashlib -from datetime import timedelta from typing import Optional from flask import Request @@ -21,10 +20,6 @@ def __hash_text(text: str) -> str: return hashlib.sha512(text.encode('utf-8')).hexdigest() -def __add_cookie_callback(_, response: Response, name: str, value: str): - response.set_cookie(name, value, max_age=timedelta(days=30), secure=False, httponly=True, samesite='Lax') - - def get_user_id_via_auth_cookie(request: Request) -> Optional[int]: if auth_cookie_name not in request.cookies: return None diff --git a/app/ch14_testing/starter/pypi_org/infrastructure/cookie_auth.py b/app/ch14_testing/starter/pypi_org/infrastructure/cookie_auth.py index 65ee0c10..44864438 100644 --- a/app/ch14_testing/starter/pypi_org/infrastructure/cookie_auth.py +++ b/app/ch14_testing/starter/pypi_org/infrastructure/cookie_auth.py @@ -1,5 +1,4 @@ import hashlib -from datetime import timedelta from typing import Optional from flask import Request @@ -21,10 +20,6 @@ def __hash_text(text: str) -> str: return hashlib.sha512(text.encode('utf-8')).hexdigest() -def __add_cookie_callback(_, response: Response, name: str, value: str): - response.set_cookie(name, value, max_age=timedelta(days=30), secure=False, httponly=True, samesite='Lax') - - def get_user_id_via_auth_cookie(request: Request) -> Optional[int]: if auth_cookie_name not in request.cookies: return None diff --git a/app/ch15_deploy/final/pypi_org/infrastructure/cookie_auth.py b/app/ch15_deploy/final/pypi_org/infrastructure/cookie_auth.py index 65ee0c10..44864438 100644 --- a/app/ch15_deploy/final/pypi_org/infrastructure/cookie_auth.py +++ b/app/ch15_deploy/final/pypi_org/infrastructure/cookie_auth.py @@ -1,5 +1,4 @@ import hashlib -from datetime import timedelta from typing import Optional from flask import Request @@ -21,10 +20,6 @@ def __hash_text(text: str) -> str: return hashlib.sha512(text.encode('utf-8')).hexdigest() -def __add_cookie_callback(_, response: Response, name: str, value: str): - response.set_cookie(name, value, max_age=timedelta(days=30), secure=False, httponly=True, samesite='Lax') - - def get_user_id_via_auth_cookie(request: Request) -> Optional[int]: if auth_cookie_name not in request.cookies: return None diff --git a/app/ch15_deploy/starter/pypi_org/infrastructure/cookie_auth.py b/app/ch15_deploy/starter/pypi_org/infrastructure/cookie_auth.py index 65ee0c10..44864438 100644 --- a/app/ch15_deploy/starter/pypi_org/infrastructure/cookie_auth.py +++ b/app/ch15_deploy/starter/pypi_org/infrastructure/cookie_auth.py @@ -1,5 +1,4 @@ import hashlib -from datetime import timedelta from typing import Optional from flask import Request @@ -21,10 +20,6 @@ def __hash_text(text: str) -> str: return hashlib.sha512(text.encode('utf-8')).hexdigest() -def __add_cookie_callback(_, response: Response, name: str, value: str): - response.set_cookie(name, value, max_age=timedelta(days=30), secure=False, httponly=True, samesite='Lax') - - def get_user_id_via_auth_cookie(request: Request) -> Optional[int]: if auth_cookie_name not in request.cookies: return None diff --git a/app/ch16_mongodb/final/pypi_org/infrastructure/cookie_auth.py b/app/ch16_mongodb/final/pypi_org/infrastructure/cookie_auth.py index 65ee0c10..661168c0 100644 --- a/app/ch16_mongodb/final/pypi_org/infrastructure/cookie_auth.py +++ b/app/ch16_mongodb/final/pypi_org/infrastructure/cookie_auth.py @@ -1,16 +1,16 @@ import hashlib -from datetime import timedelta from typing import Optional +import bson from flask import Request from flask import Response -from pypi_org.infrastructure.num_convert import try_int +from pypi_org.infrastructure.num_convert import try_object_id auth_cookie_name = 'pypi_demo_user' -def set_auth(response: Response, user_id: int): +def set_auth(response: Response, user_id: bson.ObjectId): hash_val = __hash_text(str(user_id)) val = "{}:{}".format(user_id, hash_val) response.set_cookie(auth_cookie_name, val, secure=False, httponly=True, samesite='Lax') @@ -21,11 +21,7 @@ def __hash_text(text: str) -> str: return hashlib.sha512(text.encode('utf-8')).hexdigest() -def __add_cookie_callback(_, response: Response, name: str, value: str): - response.set_cookie(name, value, max_age=timedelta(days=30), secure=False, httponly=True, samesite='Lax') - - -def get_user_id_via_auth_cookie(request: Request) -> Optional[int]: +def get_user_id_via_auth_cookie(request: Request) -> Optional[bson.ObjectId]: if auth_cookie_name not in request.cookies: return None @@ -41,7 +37,7 @@ def get_user_id_via_auth_cookie(request: Request) -> Optional[int]: print("Warning: Hash mismatch, invalid cookie value") return None - return try_int(user_id) + return try_object_id(user_id) def logout(response: Response): diff --git a/app/ch16_mongodb/starter/pypi_org/infrastructure/cookie_auth.py b/app/ch16_mongodb/starter/pypi_org/infrastructure/cookie_auth.py index 65ee0c10..44864438 100644 --- a/app/ch16_mongodb/starter/pypi_org/infrastructure/cookie_auth.py +++ b/app/ch16_mongodb/starter/pypi_org/infrastructure/cookie_auth.py @@ -1,5 +1,4 @@ import hashlib -from datetime import timedelta from typing import Optional from flask import Request @@ -21,10 +20,6 @@ def __hash_text(text: str) -> str: return hashlib.sha512(text.encode('utf-8')).hexdigest() -def __add_cookie_callback(_, response: Response, name: str, value: str): - response.set_cookie(name, value, max_age=timedelta(days=30), secure=False, httponly=True, samesite='Lax') - - def get_user_id_via_auth_cookie(request: Request) -> Optional[int]: if auth_cookie_name not in request.cookies: return None From f94ff174f7a1f4b5c5d7c6e2fd30861defe092f0 Mon Sep 17 00:00:00 2001 From: Michael Kennedy Date: Fri, 16 Sep 2022 14:17:00 -0700 Subject: [PATCH 30/44] Clean up number converter util return type. --- .../pypi_org/infrastructure/num_convert.py | 7 +++++-- .../pypi_org/infrastructure/num_convert.py | 7 +++++-- .../final/pypi_org/infrastructure/num_convert.py | 5 ++++- .../pypi_org/infrastructure/num_convert.py | 7 +++++-- .../final/pypi_org/infrastructure/num_convert.py | 7 +++++-- .../starter/pypi_org/bin/load_data.py | 4 ++-- .../pypi_org/infrastructure/num_convert.py | 7 +++++-- app/ch14_testing/final/pypi_org/bin/load_data.py | 4 ++-- .../final/pypi_org/infrastructure/num_convert.py | 7 +++++-- .../starter/pypi_org/bin/load_data.py | 4 ++-- .../pypi_org/infrastructure/num_convert.py | 7 +++++-- app/ch15_deploy/final/pypi_org/bin/load_data.py | 4 ++-- .../final/pypi_org/infrastructure/num_convert.py | 7 +++++-- .../starter/pypi_org/bin/load_data.py | 4 ++-- .../pypi_org/infrastructure/num_convert.py | 7 +++++-- app/ch16_mongodb/final/pypi_org/bin/load_data.py | 4 ++-- .../final/pypi_org/infrastructure/num_convert.py | 16 ++++++++++++++-- .../starter/pypi_org/bin/load_data.py | 4 ++-- .../pypi_org/infrastructure/num_convert.py | 7 +++++-- 19 files changed, 82 insertions(+), 37 deletions(-) diff --git a/app/ch10_using_sqlachemy/starter/pypi_org/infrastructure/num_convert.py b/app/ch10_using_sqlachemy/starter/pypi_org/infrastructure/num_convert.py index bf88a6bc..4e1d8879 100644 --- a/app/ch10_using_sqlachemy/starter/pypi_org/infrastructure/num_convert.py +++ b/app/ch10_using_sqlachemy/starter/pypi_org/infrastructure/num_convert.py @@ -1,5 +1,8 @@ -def try_int(text) -> int: +from typing import Optional + + +def try_int(text) -> Optional[int]: try: return int(text) except: - return 0 + return None diff --git a/app/ch11_migrations/starter/pypi_org/infrastructure/num_convert.py b/app/ch11_migrations/starter/pypi_org/infrastructure/num_convert.py index bf88a6bc..4e1d8879 100644 --- a/app/ch11_migrations/starter/pypi_org/infrastructure/num_convert.py +++ b/app/ch11_migrations/starter/pypi_org/infrastructure/num_convert.py @@ -1,5 +1,8 @@ -def try_int(text) -> int: +from typing import Optional + + +def try_int(text) -> Optional[int]: try: return int(text) except: - return 0 + return None diff --git a/app/ch12-forms/final/pypi_org/infrastructure/num_convert.py b/app/ch12-forms/final/pypi_org/infrastructure/num_convert.py index bf88a6bc..705fbd60 100644 --- a/app/ch12-forms/final/pypi_org/infrastructure/num_convert.py +++ b/app/ch12-forms/final/pypi_org/infrastructure/num_convert.py @@ -1,4 +1,7 @@ -def try_int(text) -> int: +from typing import Optional + + +def try_int(text) -> Optional[int]: try: return int(text) except: diff --git a/app/ch12-forms/starter/pypi_org/infrastructure/num_convert.py b/app/ch12-forms/starter/pypi_org/infrastructure/num_convert.py index bf88a6bc..4e1d8879 100644 --- a/app/ch12-forms/starter/pypi_org/infrastructure/num_convert.py +++ b/app/ch12-forms/starter/pypi_org/infrastructure/num_convert.py @@ -1,5 +1,8 @@ -def try_int(text) -> int: +from typing import Optional + + +def try_int(text) -> Optional[int]: try: return int(text) except: - return 0 + return None diff --git a/app/ch13-validation/final/pypi_org/infrastructure/num_convert.py b/app/ch13-validation/final/pypi_org/infrastructure/num_convert.py index bf88a6bc..4e1d8879 100644 --- a/app/ch13-validation/final/pypi_org/infrastructure/num_convert.py +++ b/app/ch13-validation/final/pypi_org/infrastructure/num_convert.py @@ -1,5 +1,8 @@ -def try_int(text) -> int: +from typing import Optional + + +def try_int(text) -> Optional[int]: try: return int(text) except: - return 0 + return None diff --git a/app/ch13-validation/starter/pypi_org/bin/load_data.py b/app/ch13-validation/starter/pypi_org/bin/load_data.py index 15237f18..8f43c13c 100644 --- a/app/ch13-validation/starter/pypi_org/bin/load_data.py +++ b/app/ch13-validation/starter/pypi_org/bin/load_data.py @@ -339,11 +339,11 @@ def make_version_num(version_text): return major, minor, build -def try_int(text) -> int: +def try_int(text) -> Optional[int]: try: return int(text) except: - return 0 + return None def init_db(): diff --git a/app/ch13-validation/starter/pypi_org/infrastructure/num_convert.py b/app/ch13-validation/starter/pypi_org/infrastructure/num_convert.py index bf88a6bc..4e1d8879 100644 --- a/app/ch13-validation/starter/pypi_org/infrastructure/num_convert.py +++ b/app/ch13-validation/starter/pypi_org/infrastructure/num_convert.py @@ -1,5 +1,8 @@ -def try_int(text) -> int: +from typing import Optional + + +def try_int(text) -> Optional[int]: try: return int(text) except: - return 0 + return None diff --git a/app/ch14_testing/final/pypi_org/bin/load_data.py b/app/ch14_testing/final/pypi_org/bin/load_data.py index 15237f18..8f43c13c 100644 --- a/app/ch14_testing/final/pypi_org/bin/load_data.py +++ b/app/ch14_testing/final/pypi_org/bin/load_data.py @@ -339,11 +339,11 @@ def make_version_num(version_text): return major, minor, build -def try_int(text) -> int: +def try_int(text) -> Optional[int]: try: return int(text) except: - return 0 + return None def init_db(): diff --git a/app/ch14_testing/final/pypi_org/infrastructure/num_convert.py b/app/ch14_testing/final/pypi_org/infrastructure/num_convert.py index bf88a6bc..4e1d8879 100644 --- a/app/ch14_testing/final/pypi_org/infrastructure/num_convert.py +++ b/app/ch14_testing/final/pypi_org/infrastructure/num_convert.py @@ -1,5 +1,8 @@ -def try_int(text) -> int: +from typing import Optional + + +def try_int(text) -> Optional[int]: try: return int(text) except: - return 0 + return None diff --git a/app/ch14_testing/starter/pypi_org/bin/load_data.py b/app/ch14_testing/starter/pypi_org/bin/load_data.py index 15237f18..8f43c13c 100644 --- a/app/ch14_testing/starter/pypi_org/bin/load_data.py +++ b/app/ch14_testing/starter/pypi_org/bin/load_data.py @@ -339,11 +339,11 @@ def make_version_num(version_text): return major, minor, build -def try_int(text) -> int: +def try_int(text) -> Optional[int]: try: return int(text) except: - return 0 + return None def init_db(): diff --git a/app/ch14_testing/starter/pypi_org/infrastructure/num_convert.py b/app/ch14_testing/starter/pypi_org/infrastructure/num_convert.py index bf88a6bc..4e1d8879 100644 --- a/app/ch14_testing/starter/pypi_org/infrastructure/num_convert.py +++ b/app/ch14_testing/starter/pypi_org/infrastructure/num_convert.py @@ -1,5 +1,8 @@ -def try_int(text) -> int: +from typing import Optional + + +def try_int(text) -> Optional[int]: try: return int(text) except: - return 0 + return None diff --git a/app/ch15_deploy/final/pypi_org/bin/load_data.py b/app/ch15_deploy/final/pypi_org/bin/load_data.py index 15237f18..8f43c13c 100644 --- a/app/ch15_deploy/final/pypi_org/bin/load_data.py +++ b/app/ch15_deploy/final/pypi_org/bin/load_data.py @@ -339,11 +339,11 @@ def make_version_num(version_text): return major, minor, build -def try_int(text) -> int: +def try_int(text) -> Optional[int]: try: return int(text) except: - return 0 + return None def init_db(): diff --git a/app/ch15_deploy/final/pypi_org/infrastructure/num_convert.py b/app/ch15_deploy/final/pypi_org/infrastructure/num_convert.py index bf88a6bc..4e1d8879 100644 --- a/app/ch15_deploy/final/pypi_org/infrastructure/num_convert.py +++ b/app/ch15_deploy/final/pypi_org/infrastructure/num_convert.py @@ -1,5 +1,8 @@ -def try_int(text) -> int: +from typing import Optional + + +def try_int(text) -> Optional[int]: try: return int(text) except: - return 0 + return None diff --git a/app/ch15_deploy/starter/pypi_org/bin/load_data.py b/app/ch15_deploy/starter/pypi_org/bin/load_data.py index 15237f18..8f43c13c 100644 --- a/app/ch15_deploy/starter/pypi_org/bin/load_data.py +++ b/app/ch15_deploy/starter/pypi_org/bin/load_data.py @@ -339,11 +339,11 @@ def make_version_num(version_text): return major, minor, build -def try_int(text) -> int: +def try_int(text) -> Optional[int]: try: return int(text) except: - return 0 + return None def init_db(): diff --git a/app/ch15_deploy/starter/pypi_org/infrastructure/num_convert.py b/app/ch15_deploy/starter/pypi_org/infrastructure/num_convert.py index bf88a6bc..4e1d8879 100644 --- a/app/ch15_deploy/starter/pypi_org/infrastructure/num_convert.py +++ b/app/ch15_deploy/starter/pypi_org/infrastructure/num_convert.py @@ -1,5 +1,8 @@ -def try_int(text) -> int: +from typing import Optional + + +def try_int(text) -> Optional[int]: try: return int(text) except: - return 0 + return None diff --git a/app/ch16_mongodb/final/pypi_org/bin/load_data.py b/app/ch16_mongodb/final/pypi_org/bin/load_data.py index 15237f18..8f43c13c 100644 --- a/app/ch16_mongodb/final/pypi_org/bin/load_data.py +++ b/app/ch16_mongodb/final/pypi_org/bin/load_data.py @@ -339,11 +339,11 @@ def make_version_num(version_text): return major, minor, build -def try_int(text) -> int: +def try_int(text) -> Optional[int]: try: return int(text) except: - return 0 + return None def init_db(): diff --git a/app/ch16_mongodb/final/pypi_org/infrastructure/num_convert.py b/app/ch16_mongodb/final/pypi_org/infrastructure/num_convert.py index bf88a6bc..007e3ff8 100644 --- a/app/ch16_mongodb/final/pypi_org/infrastructure/num_convert.py +++ b/app/ch16_mongodb/final/pypi_org/infrastructure/num_convert.py @@ -1,5 +1,17 @@ -def try_int(text) -> int: +from typing import Optional + +import bson + + +def try_int(text) -> Optional[int]: try: return int(text) except: - return 0 + return None + + +def try_object_id(text) -> Optional[bson.ObjectId]: + try: + return bson.ObjectId(text) + except: + return None diff --git a/app/ch16_mongodb/starter/pypi_org/bin/load_data.py b/app/ch16_mongodb/starter/pypi_org/bin/load_data.py index 15237f18..8f43c13c 100644 --- a/app/ch16_mongodb/starter/pypi_org/bin/load_data.py +++ b/app/ch16_mongodb/starter/pypi_org/bin/load_data.py @@ -339,11 +339,11 @@ def make_version_num(version_text): return major, minor, build -def try_int(text) -> int: +def try_int(text) -> Optional[int]: try: return int(text) except: - return 0 + return None def init_db(): diff --git a/app/ch16_mongodb/starter/pypi_org/infrastructure/num_convert.py b/app/ch16_mongodb/starter/pypi_org/infrastructure/num_convert.py index bf88a6bc..4e1d8879 100644 --- a/app/ch16_mongodb/starter/pypi_org/infrastructure/num_convert.py +++ b/app/ch16_mongodb/starter/pypi_org/infrastructure/num_convert.py @@ -1,5 +1,8 @@ -def try_int(text) -> int: +from typing import Optional + + +def try_int(text) -> Optional[int]: try: return int(text) except: - return 0 + return None From 0e3e4c9d004278c2b09c2c66b0a96a963c4270bc Mon Sep 17 00:00:00 2001 From: Michael Kennedy Date: Fri, 16 Sep 2022 14:17:23 -0700 Subject: [PATCH 31/44] Use bson.ObjectID for user management rather than int (from SQLAlchemy) --- .../final/pypi_org/infrastructure/num_convert.py | 7 +++++-- app/ch16_mongodb/final/pypi_org/services/user_service.py | 3 ++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/app/ch10_using_sqlachemy/final/pypi_org/infrastructure/num_convert.py b/app/ch10_using_sqlachemy/final/pypi_org/infrastructure/num_convert.py index bf88a6bc..4e1d8879 100644 --- a/app/ch10_using_sqlachemy/final/pypi_org/infrastructure/num_convert.py +++ b/app/ch10_using_sqlachemy/final/pypi_org/infrastructure/num_convert.py @@ -1,5 +1,8 @@ -def try_int(text) -> int: +from typing import Optional + + +def try_int(text) -> Optional[int]: try: return int(text) except: - return 0 + return None diff --git a/app/ch16_mongodb/final/pypi_org/services/user_service.py b/app/ch16_mongodb/final/pypi_org/services/user_service.py index bdbef70b..edf62641 100644 --- a/app/ch16_mongodb/final/pypi_org/services/user_service.py +++ b/app/ch16_mongodb/final/pypi_org/services/user_service.py @@ -1,5 +1,6 @@ from typing import Optional +import bson from passlib.handlers.sha2_crypt import sha512_crypt as crypto from pypi_org.nosql.users import User @@ -46,6 +47,6 @@ def login_user(email: str, password: str) -> Optional[User]: return user -def find_user_by_id(user_id: int) -> Optional[User]: +def find_user_by_id(user_id: bson.ObjectId) -> Optional[User]: user = User.objects().filter(id=user_id).first() return user From 0d4e4d72be982f7e5050ee1a7293dbe4ade40ba6 Mon Sep 17 00:00:00 2001 From: Michael Kennedy Date: Fri, 16 Sep 2022 14:24:25 -0700 Subject: [PATCH 32/44] Fixes #24 - Should redirect from login -> account if they are already logged in. --- app/ch14_testing/final/pypi_org/views/account_views.py | 5 +++++ app/ch14_testing/starter/pypi_org/views/account_views.py | 5 +++++ app/ch15_deploy/final/pypi_org/views/account_views.py | 7 ++++++- app/ch15_deploy/starter/pypi_org/views/account_views.py | 5 +++++ app/ch16_mongodb/final/pypi_org/views/account_views.py | 5 +++++ app/ch16_mongodb/starter/pypi_org/views/account_views.py | 5 +++++ 6 files changed, 31 insertions(+), 1 deletion(-) diff --git a/app/ch14_testing/final/pypi_org/views/account_views.py b/app/ch14_testing/final/pypi_org/views/account_views.py index 8697cc24..3854b4cf 100644 --- a/app/ch14_testing/final/pypi_org/views/account_views.py +++ b/app/ch14_testing/final/pypi_org/views/account_views.py @@ -58,6 +58,11 @@ def register_post(): @response(template_file='account/login.html') def login_get(): vm = LoginViewModel() + + # Added after recording, see https://github.com/talkpython/data-driven-web-apps-with-flask/issues/24 + if vm.user_id: + return flask.redirect('/account') + return vm.to_dict() diff --git a/app/ch14_testing/starter/pypi_org/views/account_views.py b/app/ch14_testing/starter/pypi_org/views/account_views.py index 8697cc24..3854b4cf 100644 --- a/app/ch14_testing/starter/pypi_org/views/account_views.py +++ b/app/ch14_testing/starter/pypi_org/views/account_views.py @@ -58,6 +58,11 @@ def register_post(): @response(template_file='account/login.html') def login_get(): vm = LoginViewModel() + + # Added after recording, see https://github.com/talkpython/data-driven-web-apps-with-flask/issues/24 + if vm.user_id: + return flask.redirect('/account') + return vm.to_dict() diff --git a/app/ch15_deploy/final/pypi_org/views/account_views.py b/app/ch15_deploy/final/pypi_org/views/account_views.py index 8697cc24..59cd4c81 100644 --- a/app/ch15_deploy/final/pypi_org/views/account_views.py +++ b/app/ch15_deploy/final/pypi_org/views/account_views.py @@ -1,8 +1,8 @@ import flask +import pypi_org.infrastructure.cookie_auth as cookie_auth from pypi_org.infrastructure.view_modifiers import response from pypi_org.services import user_service -import pypi_org.infrastructure.cookie_auth as cookie_auth from pypi_org.viewmodels.account.index_viewmodel import IndexViewModel from pypi_org.viewmodels.account.login_viewmodel import LoginViewModel from pypi_org.viewmodels.account.register_viewmodel import RegisterViewModel @@ -58,6 +58,11 @@ def register_post(): @response(template_file='account/login.html') def login_get(): vm = LoginViewModel() + + # Added after recording, see https://github.com/talkpython/data-driven-web-apps-with-flask/issues/24 + if vm.user_id: + return flask.redirect('/account') + return vm.to_dict() diff --git a/app/ch15_deploy/starter/pypi_org/views/account_views.py b/app/ch15_deploy/starter/pypi_org/views/account_views.py index 8697cc24..3854b4cf 100644 --- a/app/ch15_deploy/starter/pypi_org/views/account_views.py +++ b/app/ch15_deploy/starter/pypi_org/views/account_views.py @@ -58,6 +58,11 @@ def register_post(): @response(template_file='account/login.html') def login_get(): vm = LoginViewModel() + + # Added after recording, see https://github.com/talkpython/data-driven-web-apps-with-flask/issues/24 + if vm.user_id: + return flask.redirect('/account') + return vm.to_dict() diff --git a/app/ch16_mongodb/final/pypi_org/views/account_views.py b/app/ch16_mongodb/final/pypi_org/views/account_views.py index 8697cc24..3854b4cf 100644 --- a/app/ch16_mongodb/final/pypi_org/views/account_views.py +++ b/app/ch16_mongodb/final/pypi_org/views/account_views.py @@ -58,6 +58,11 @@ def register_post(): @response(template_file='account/login.html') def login_get(): vm = LoginViewModel() + + # Added after recording, see https://github.com/talkpython/data-driven-web-apps-with-flask/issues/24 + if vm.user_id: + return flask.redirect('/account') + return vm.to_dict() diff --git a/app/ch16_mongodb/starter/pypi_org/views/account_views.py b/app/ch16_mongodb/starter/pypi_org/views/account_views.py index 8697cc24..3854b4cf 100644 --- a/app/ch16_mongodb/starter/pypi_org/views/account_views.py +++ b/app/ch16_mongodb/starter/pypi_org/views/account_views.py @@ -58,6 +58,11 @@ def register_post(): @response(template_file='account/login.html') def login_get(): vm = LoginViewModel() + + # Added after recording, see https://github.com/talkpython/data-driven-web-apps-with-flask/issues/24 + if vm.user_id: + return flask.redirect('/account') + return vm.to_dict() From c1c9fde0cb02007d3bcb99f0b57c5c252b51bdd0 Mon Sep 17 00:00:00 2001 From: Michael Kennedy Date: Tue, 12 Dec 2023 16:26:49 -0800 Subject: [PATCH 33/44] Add a pinned requirements via pip-tools for all the code projects. --- .../first_site/requirements.piptools | 1 + .../first_site/requirements.txt | 23 ++++++- .../final/requirements.piptools | 1 + .../final/requirements.txt | 23 ++++++- app/ch06_routing/final/requirements.piptools | 1 + app/ch06_routing/final/requirements.txt | 23 ++++++- .../starter/requirements.piptools | 1 + app/ch06_routing/starter/requirements.txt | 23 ++++++- .../final/requirements.piptools | 1 + .../final/requirements.txt | 23 ++++++- .../starter/requirements.piptools | 1 + .../starter/requirements.txt | 23 ++++++- .../final/requirements.piptools | 2 + app/ch09_sqlalchemy/final/requirements.txt | 28 ++++++++- .../starter/requirements.piptools | 1 + app/ch09_sqlalchemy/starter/requirements.txt | 23 ++++++- .../final/requirements.piptools | 4 ++ .../final/requirements.txt | 42 +++++++++++-- .../starter/requirements.piptools | 2 + .../starter/requirements.txt | 28 ++++++++- .../final/requirements.piptools | 5 ++ app/ch11_migrations/final/requirements.txt | 50 ++++++++++++++-- .../starter/requirements.piptools | 4 ++ app/ch11_migrations/starter/requirements.txt | 42 +++++++++++-- app/ch12-forms/final/requirements.piptools | 6 ++ app/ch12-forms/final/requirements.txt | 54 ++++++++++++++--- app/ch12-forms/starter/requirements.piptools | 5 ++ app/ch12-forms/starter/requirements.txt | 50 ++++++++++++++-- .../final/requirements.piptools | 6 ++ app/ch13-validation/final/requirements.txt | 54 ++++++++++++++--- .../starter/requirements.piptools | 6 ++ app/ch13-validation/starter/requirements.txt | 54 ++++++++++++++--- app/ch14_testing/final/requirements.piptools | 6 ++ app/ch14_testing/final/requirements.txt | 54 ++++++++++++++--- .../starter/requirements.piptools | 6 ++ app/ch14_testing/starter/requirements.txt | 54 ++++++++++++++--- app/ch15_deploy/final/requirements.piptools | 6 ++ app/ch15_deploy/final/requirements.txt | 53 +++++++++++++--- app/ch15_deploy/starter/requirements.piptools | 6 ++ app/ch15_deploy/starter/requirements.txt | 54 ++++++++++++++--- app/ch16_mongodb/final/requirements.piptools | 7 +++ app/ch16_mongodb/final/requirements.txt | 60 ++++++++++++++++--- .../starter/requirements.piptools | 6 ++ app/ch16_mongodb/starter/requirements.txt | 54 ++++++++++++++--- requirements.piptools | 7 +++ requirements.txt | 52 ++++++++++++++++ 46 files changed, 929 insertions(+), 106 deletions(-) create mode 100644 app/ch04_first_site/first_site_final/first_site/requirements.piptools create mode 100644 app/ch05_jinja_templates/final/requirements.piptools create mode 100644 app/ch06_routing/final/requirements.piptools create mode 100644 app/ch06_routing/starter/requirements.piptools create mode 100644 app/ch08_adding_our_design/final/requirements.piptools create mode 100644 app/ch08_adding_our_design/starter/requirements.piptools create mode 100644 app/ch09_sqlalchemy/final/requirements.piptools create mode 100644 app/ch09_sqlalchemy/starter/requirements.piptools create mode 100644 app/ch10_using_sqlachemy/final/requirements.piptools create mode 100644 app/ch10_using_sqlachemy/starter/requirements.piptools create mode 100644 app/ch11_migrations/final/requirements.piptools create mode 100644 app/ch11_migrations/starter/requirements.piptools create mode 100644 app/ch12-forms/final/requirements.piptools create mode 100644 app/ch12-forms/starter/requirements.piptools create mode 100644 app/ch13-validation/final/requirements.piptools create mode 100644 app/ch13-validation/starter/requirements.piptools create mode 100644 app/ch14_testing/final/requirements.piptools create mode 100644 app/ch14_testing/starter/requirements.piptools create mode 100644 app/ch15_deploy/final/requirements.piptools create mode 100644 app/ch15_deploy/starter/requirements.piptools create mode 100644 app/ch16_mongodb/final/requirements.piptools create mode 100644 app/ch16_mongodb/starter/requirements.piptools create mode 100644 requirements.piptools create mode 100644 requirements.txt diff --git a/app/ch04_first_site/first_site_final/first_site/requirements.piptools b/app/ch04_first_site/first_site_final/first_site/requirements.piptools new file mode 100644 index 00000000..7e106024 --- /dev/null +++ b/app/ch04_first_site/first_site_final/first_site/requirements.piptools @@ -0,0 +1 @@ +flask diff --git a/app/ch04_first_site/first_site_final/first_site/requirements.txt b/app/ch04_first_site/first_site_final/first_site/requirements.txt index 7e106024..12e1f645 100644 --- a/app/ch04_first_site/first_site_final/first_site/requirements.txt +++ b/app/ch04_first_site/first_site_final/first_site/requirements.txt @@ -1 +1,22 @@ -flask +# +# This file is autogenerated by pip-compile with Python 3.12 +# by the following command: +# +# pip-compile requirements.piptools +# +blinker==1.7.0 + # via flask +click==8.1.7 + # via flask +flask==3.0.0 + # via -r requirements.piptools +itsdangerous==2.1.2 + # via flask +jinja2==3.1.2 + # via flask +markupsafe==2.1.3 + # via + # jinja2 + # werkzeug +werkzeug==3.0.1 + # via flask diff --git a/app/ch05_jinja_templates/final/requirements.piptools b/app/ch05_jinja_templates/final/requirements.piptools new file mode 100644 index 00000000..7e106024 --- /dev/null +++ b/app/ch05_jinja_templates/final/requirements.piptools @@ -0,0 +1 @@ +flask diff --git a/app/ch05_jinja_templates/final/requirements.txt b/app/ch05_jinja_templates/final/requirements.txt index 7e106024..12e1f645 100644 --- a/app/ch05_jinja_templates/final/requirements.txt +++ b/app/ch05_jinja_templates/final/requirements.txt @@ -1 +1,22 @@ -flask +# +# This file is autogenerated by pip-compile with Python 3.12 +# by the following command: +# +# pip-compile requirements.piptools +# +blinker==1.7.0 + # via flask +click==8.1.7 + # via flask +flask==3.0.0 + # via -r requirements.piptools +itsdangerous==2.1.2 + # via flask +jinja2==3.1.2 + # via flask +markupsafe==2.1.3 + # via + # jinja2 + # werkzeug +werkzeug==3.0.1 + # via flask diff --git a/app/ch06_routing/final/requirements.piptools b/app/ch06_routing/final/requirements.piptools new file mode 100644 index 00000000..7e106024 --- /dev/null +++ b/app/ch06_routing/final/requirements.piptools @@ -0,0 +1 @@ +flask diff --git a/app/ch06_routing/final/requirements.txt b/app/ch06_routing/final/requirements.txt index 7e106024..12e1f645 100644 --- a/app/ch06_routing/final/requirements.txt +++ b/app/ch06_routing/final/requirements.txt @@ -1 +1,22 @@ -flask +# +# This file is autogenerated by pip-compile with Python 3.12 +# by the following command: +# +# pip-compile requirements.piptools +# +blinker==1.7.0 + # via flask +click==8.1.7 + # via flask +flask==3.0.0 + # via -r requirements.piptools +itsdangerous==2.1.2 + # via flask +jinja2==3.1.2 + # via flask +markupsafe==2.1.3 + # via + # jinja2 + # werkzeug +werkzeug==3.0.1 + # via flask diff --git a/app/ch06_routing/starter/requirements.piptools b/app/ch06_routing/starter/requirements.piptools new file mode 100644 index 00000000..7e106024 --- /dev/null +++ b/app/ch06_routing/starter/requirements.piptools @@ -0,0 +1 @@ +flask diff --git a/app/ch06_routing/starter/requirements.txt b/app/ch06_routing/starter/requirements.txt index 7e106024..12e1f645 100644 --- a/app/ch06_routing/starter/requirements.txt +++ b/app/ch06_routing/starter/requirements.txt @@ -1 +1,22 @@ -flask +# +# This file is autogenerated by pip-compile with Python 3.12 +# by the following command: +# +# pip-compile requirements.piptools +# +blinker==1.7.0 + # via flask +click==8.1.7 + # via flask +flask==3.0.0 + # via -r requirements.piptools +itsdangerous==2.1.2 + # via flask +jinja2==3.1.2 + # via flask +markupsafe==2.1.3 + # via + # jinja2 + # werkzeug +werkzeug==3.0.1 + # via flask diff --git a/app/ch08_adding_our_design/final/requirements.piptools b/app/ch08_adding_our_design/final/requirements.piptools new file mode 100644 index 00000000..7e106024 --- /dev/null +++ b/app/ch08_adding_our_design/final/requirements.piptools @@ -0,0 +1 @@ +flask diff --git a/app/ch08_adding_our_design/final/requirements.txt b/app/ch08_adding_our_design/final/requirements.txt index 7e106024..12e1f645 100644 --- a/app/ch08_adding_our_design/final/requirements.txt +++ b/app/ch08_adding_our_design/final/requirements.txt @@ -1 +1,22 @@ -flask +# +# This file is autogenerated by pip-compile with Python 3.12 +# by the following command: +# +# pip-compile requirements.piptools +# +blinker==1.7.0 + # via flask +click==8.1.7 + # via flask +flask==3.0.0 + # via -r requirements.piptools +itsdangerous==2.1.2 + # via flask +jinja2==3.1.2 + # via flask +markupsafe==2.1.3 + # via + # jinja2 + # werkzeug +werkzeug==3.0.1 + # via flask diff --git a/app/ch08_adding_our_design/starter/requirements.piptools b/app/ch08_adding_our_design/starter/requirements.piptools new file mode 100644 index 00000000..7e106024 --- /dev/null +++ b/app/ch08_adding_our_design/starter/requirements.piptools @@ -0,0 +1 @@ +flask diff --git a/app/ch08_adding_our_design/starter/requirements.txt b/app/ch08_adding_our_design/starter/requirements.txt index 7e106024..12e1f645 100644 --- a/app/ch08_adding_our_design/starter/requirements.txt +++ b/app/ch08_adding_our_design/starter/requirements.txt @@ -1 +1,22 @@ -flask +# +# This file is autogenerated by pip-compile with Python 3.12 +# by the following command: +# +# pip-compile requirements.piptools +# +blinker==1.7.0 + # via flask +click==8.1.7 + # via flask +flask==3.0.0 + # via -r requirements.piptools +itsdangerous==2.1.2 + # via flask +jinja2==3.1.2 + # via flask +markupsafe==2.1.3 + # via + # jinja2 + # werkzeug +werkzeug==3.0.1 + # via flask diff --git a/app/ch09_sqlalchemy/final/requirements.piptools b/app/ch09_sqlalchemy/final/requirements.piptools new file mode 100644 index 00000000..e39cea14 --- /dev/null +++ b/app/ch09_sqlalchemy/final/requirements.piptools @@ -0,0 +1,2 @@ +flask +sqlalchemy diff --git a/app/ch09_sqlalchemy/final/requirements.txt b/app/ch09_sqlalchemy/final/requirements.txt index e39cea14..c38d2828 100644 --- a/app/ch09_sqlalchemy/final/requirements.txt +++ b/app/ch09_sqlalchemy/final/requirements.txt @@ -1,2 +1,26 @@ -flask -sqlalchemy +# +# This file is autogenerated by pip-compile with Python 3.11 +# by the following command: +# +# pip-compile requirements.piptools +# +blinker==1.7.0 + # via flask +click==8.1.7 + # via flask +flask==3.0.0 + # via -r requirements.piptools +itsdangerous==2.1.2 + # via flask +jinja2==3.1.2 + # via flask +markupsafe==2.1.3 + # via + # jinja2 + # werkzeug +sqlalchemy==2.0.23 + # via -r requirements.piptools +typing-extensions==4.9.0 + # via sqlalchemy +werkzeug==3.0.1 + # via flask diff --git a/app/ch09_sqlalchemy/starter/requirements.piptools b/app/ch09_sqlalchemy/starter/requirements.piptools new file mode 100644 index 00000000..7e106024 --- /dev/null +++ b/app/ch09_sqlalchemy/starter/requirements.piptools @@ -0,0 +1 @@ +flask diff --git a/app/ch09_sqlalchemy/starter/requirements.txt b/app/ch09_sqlalchemy/starter/requirements.txt index 7e106024..12e1f645 100644 --- a/app/ch09_sqlalchemy/starter/requirements.txt +++ b/app/ch09_sqlalchemy/starter/requirements.txt @@ -1 +1,22 @@ -flask +# +# This file is autogenerated by pip-compile with Python 3.12 +# by the following command: +# +# pip-compile requirements.piptools +# +blinker==1.7.0 + # via flask +click==8.1.7 + # via flask +flask==3.0.0 + # via -r requirements.piptools +itsdangerous==2.1.2 + # via flask +jinja2==3.1.2 + # via flask +markupsafe==2.1.3 + # via + # jinja2 + # werkzeug +werkzeug==3.0.1 + # via flask diff --git a/app/ch10_using_sqlachemy/final/requirements.piptools b/app/ch10_using_sqlachemy/final/requirements.piptools new file mode 100644 index 00000000..2fbbdb71 --- /dev/null +++ b/app/ch10_using_sqlachemy/final/requirements.piptools @@ -0,0 +1,4 @@ +flask +progressbar2 +python-dateutil +sqlalchemy diff --git a/app/ch10_using_sqlachemy/final/requirements.txt b/app/ch10_using_sqlachemy/final/requirements.txt index 9cf703d9..090ec616 100644 --- a/app/ch10_using_sqlachemy/final/requirements.txt +++ b/app/ch10_using_sqlachemy/final/requirements.txt @@ -1,6 +1,36 @@ -flask -sqlalchemy - -progressbar2 -python-dateutil - +# +# This file is autogenerated by pip-compile with Python 3.11 +# by the following command: +# +# pip-compile requirements.piptools +# +blinker==1.7.0 + # via flask +click==8.1.7 + # via flask +flask==3.0.0 + # via -r requirements.piptools +itsdangerous==2.1.2 + # via flask +jinja2==3.1.2 + # via flask +markupsafe==2.1.3 + # via + # jinja2 + # werkzeug +progressbar2==4.2.0 + # via -r requirements.piptools +python-dateutil==2.8.2 + # via -r requirements.piptools +python-utils==3.8.1 + # via progressbar2 +six==1.16.0 + # via python-dateutil +sqlalchemy==2.0.23 + # via -r requirements.piptools +typing-extensions==4.9.0 + # via + # python-utils + # sqlalchemy +werkzeug==3.0.1 + # via flask diff --git a/app/ch10_using_sqlachemy/starter/requirements.piptools b/app/ch10_using_sqlachemy/starter/requirements.piptools new file mode 100644 index 00000000..e39cea14 --- /dev/null +++ b/app/ch10_using_sqlachemy/starter/requirements.piptools @@ -0,0 +1,2 @@ +flask +sqlalchemy diff --git a/app/ch10_using_sqlachemy/starter/requirements.txt b/app/ch10_using_sqlachemy/starter/requirements.txt index e39cea14..c38d2828 100644 --- a/app/ch10_using_sqlachemy/starter/requirements.txt +++ b/app/ch10_using_sqlachemy/starter/requirements.txt @@ -1,2 +1,26 @@ -flask -sqlalchemy +# +# This file is autogenerated by pip-compile with Python 3.11 +# by the following command: +# +# pip-compile requirements.piptools +# +blinker==1.7.0 + # via flask +click==8.1.7 + # via flask +flask==3.0.0 + # via -r requirements.piptools +itsdangerous==2.1.2 + # via flask +jinja2==3.1.2 + # via flask +markupsafe==2.1.3 + # via + # jinja2 + # werkzeug +sqlalchemy==2.0.23 + # via -r requirements.piptools +typing-extensions==4.9.0 + # via sqlalchemy +werkzeug==3.0.1 + # via flask diff --git a/app/ch11_migrations/final/requirements.piptools b/app/ch11_migrations/final/requirements.piptools new file mode 100644 index 00000000..5ba68752 --- /dev/null +++ b/app/ch11_migrations/final/requirements.piptools @@ -0,0 +1,5 @@ +alembic +flask +progressbar2 +python-dateutil +sqlalchemy diff --git a/app/ch11_migrations/final/requirements.txt b/app/ch11_migrations/final/requirements.txt index 9cf703d9..af454bba 100644 --- a/app/ch11_migrations/final/requirements.txt +++ b/app/ch11_migrations/final/requirements.txt @@ -1,6 +1,44 @@ -flask -sqlalchemy - -progressbar2 -python-dateutil - +# +# This file is autogenerated by pip-compile with Python 3.11 +# by the following command: +# +# pip-compile requirements.piptools +# +alembic==1.13.0 + # via -r requirements.piptools +blinker==1.7.0 + # via flask +click==8.1.7 + # via flask +flask==3.0.0 + # via -r requirements.piptools +itsdangerous==2.1.2 + # via flask +jinja2==3.1.2 + # via flask +mako==1.3.0 + # via alembic +markupsafe==2.1.3 + # via + # jinja2 + # mako + # werkzeug +progressbar2==4.2.0 + # via -r requirements.piptools +python-dateutil==2.8.2 + # via -r requirements.piptools +python-utils==3.8.1 + # via progressbar2 +six==1.16.0 + # via python-dateutil +sqlalchemy==2.0.23 + # via + # -r requirements.piptools + # alembic +typing-extensions==4.9.0 + # via + # alembic + # python-utils + # sqlalchemy +werkzeug==3.0.1 + # via flask diff --git a/app/ch11_migrations/starter/requirements.piptools b/app/ch11_migrations/starter/requirements.piptools new file mode 100644 index 00000000..2fbbdb71 --- /dev/null +++ b/app/ch11_migrations/starter/requirements.piptools @@ -0,0 +1,4 @@ +flask +progressbar2 +python-dateutil +sqlalchemy diff --git a/app/ch11_migrations/starter/requirements.txt b/app/ch11_migrations/starter/requirements.txt index 9cf703d9..090ec616 100644 --- a/app/ch11_migrations/starter/requirements.txt +++ b/app/ch11_migrations/starter/requirements.txt @@ -1,6 +1,36 @@ -flask -sqlalchemy - -progressbar2 -python-dateutil - +# +# This file is autogenerated by pip-compile with Python 3.11 +# by the following command: +# +# pip-compile requirements.piptools +# +blinker==1.7.0 + # via flask +click==8.1.7 + # via flask +flask==3.0.0 + # via -r requirements.piptools +itsdangerous==2.1.2 + # via flask +jinja2==3.1.2 + # via flask +markupsafe==2.1.3 + # via + # jinja2 + # werkzeug +progressbar2==4.2.0 + # via -r requirements.piptools +python-dateutil==2.8.2 + # via -r requirements.piptools +python-utils==3.8.1 + # via progressbar2 +six==1.16.0 + # via python-dateutil +sqlalchemy==2.0.23 + # via -r requirements.piptools +typing-extensions==4.9.0 + # via + # python-utils + # sqlalchemy +werkzeug==3.0.1 + # via flask diff --git a/app/ch12-forms/final/requirements.piptools b/app/ch12-forms/final/requirements.piptools new file mode 100644 index 00000000..d13bf0c8 --- /dev/null +++ b/app/ch12-forms/final/requirements.piptools @@ -0,0 +1,6 @@ +alembic +flask +passlib +progressbar2 +python-dateutil +sqlalchemy diff --git a/app/ch12-forms/final/requirements.txt b/app/ch12-forms/final/requirements.txt index e10973d8..662fe297 100644 --- a/app/ch12-forms/final/requirements.txt +++ b/app/ch12-forms/final/requirements.txt @@ -1,8 +1,46 @@ -werkzeug -flask -sqlalchemy - -progressbar2 -python-dateutil -passlib - +# +# This file is autogenerated by pip-compile with Python 3.11 +# by the following command: +# +# pip-compile requirements.piptools +# +alembic==1.13.0 + # via -r requirements.piptools +blinker==1.7.0 + # via flask +click==8.1.7 + # via flask +flask==3.0.0 + # via -r requirements.piptools +itsdangerous==2.1.2 + # via flask +jinja2==3.1.2 + # via flask +mako==1.3.0 + # via alembic +markupsafe==2.1.3 + # via + # jinja2 + # mako + # werkzeug +passlib==1.7.4 + # via -r requirements.piptools +progressbar2==4.2.0 + # via -r requirements.piptools +python-dateutil==2.8.2 + # via -r requirements.piptools +python-utils==3.8.1 + # via progressbar2 +six==1.16.0 + # via python-dateutil +sqlalchemy==2.0.23 + # via + # -r requirements.piptools + # alembic +typing-extensions==4.9.0 + # via + # alembic + # python-utils + # sqlalchemy +werkzeug==3.0.1 + # via flask diff --git a/app/ch12-forms/starter/requirements.piptools b/app/ch12-forms/starter/requirements.piptools new file mode 100644 index 00000000..5ba68752 --- /dev/null +++ b/app/ch12-forms/starter/requirements.piptools @@ -0,0 +1,5 @@ +alembic +flask +progressbar2 +python-dateutil +sqlalchemy diff --git a/app/ch12-forms/starter/requirements.txt b/app/ch12-forms/starter/requirements.txt index 9cf703d9..af454bba 100644 --- a/app/ch12-forms/starter/requirements.txt +++ b/app/ch12-forms/starter/requirements.txt @@ -1,6 +1,44 @@ -flask -sqlalchemy - -progressbar2 -python-dateutil - +# +# This file is autogenerated by pip-compile with Python 3.11 +# by the following command: +# +# pip-compile requirements.piptools +# +alembic==1.13.0 + # via -r requirements.piptools +blinker==1.7.0 + # via flask +click==8.1.7 + # via flask +flask==3.0.0 + # via -r requirements.piptools +itsdangerous==2.1.2 + # via flask +jinja2==3.1.2 + # via flask +mako==1.3.0 + # via alembic +markupsafe==2.1.3 + # via + # jinja2 + # mako + # werkzeug +progressbar2==4.2.0 + # via -r requirements.piptools +python-dateutil==2.8.2 + # via -r requirements.piptools +python-utils==3.8.1 + # via progressbar2 +six==1.16.0 + # via python-dateutil +sqlalchemy==2.0.23 + # via + # -r requirements.piptools + # alembic +typing-extensions==4.9.0 + # via + # alembic + # python-utils + # sqlalchemy +werkzeug==3.0.1 + # via flask diff --git a/app/ch13-validation/final/requirements.piptools b/app/ch13-validation/final/requirements.piptools new file mode 100644 index 00000000..d13bf0c8 --- /dev/null +++ b/app/ch13-validation/final/requirements.piptools @@ -0,0 +1,6 @@ +alembic +flask +passlib +progressbar2 +python-dateutil +sqlalchemy diff --git a/app/ch13-validation/final/requirements.txt b/app/ch13-validation/final/requirements.txt index e10973d8..662fe297 100644 --- a/app/ch13-validation/final/requirements.txt +++ b/app/ch13-validation/final/requirements.txt @@ -1,8 +1,46 @@ -werkzeug -flask -sqlalchemy - -progressbar2 -python-dateutil -passlib - +# +# This file is autogenerated by pip-compile with Python 3.11 +# by the following command: +# +# pip-compile requirements.piptools +# +alembic==1.13.0 + # via -r requirements.piptools +blinker==1.7.0 + # via flask +click==8.1.7 + # via flask +flask==3.0.0 + # via -r requirements.piptools +itsdangerous==2.1.2 + # via flask +jinja2==3.1.2 + # via flask +mako==1.3.0 + # via alembic +markupsafe==2.1.3 + # via + # jinja2 + # mako + # werkzeug +passlib==1.7.4 + # via -r requirements.piptools +progressbar2==4.2.0 + # via -r requirements.piptools +python-dateutil==2.8.2 + # via -r requirements.piptools +python-utils==3.8.1 + # via progressbar2 +six==1.16.0 + # via python-dateutil +sqlalchemy==2.0.23 + # via + # -r requirements.piptools + # alembic +typing-extensions==4.9.0 + # via + # alembic + # python-utils + # sqlalchemy +werkzeug==3.0.1 + # via flask diff --git a/app/ch13-validation/starter/requirements.piptools b/app/ch13-validation/starter/requirements.piptools new file mode 100644 index 00000000..d13bf0c8 --- /dev/null +++ b/app/ch13-validation/starter/requirements.piptools @@ -0,0 +1,6 @@ +alembic +flask +passlib +progressbar2 +python-dateutil +sqlalchemy diff --git a/app/ch13-validation/starter/requirements.txt b/app/ch13-validation/starter/requirements.txt index e10973d8..662fe297 100644 --- a/app/ch13-validation/starter/requirements.txt +++ b/app/ch13-validation/starter/requirements.txt @@ -1,8 +1,46 @@ -werkzeug -flask -sqlalchemy - -progressbar2 -python-dateutil -passlib - +# +# This file is autogenerated by pip-compile with Python 3.11 +# by the following command: +# +# pip-compile requirements.piptools +# +alembic==1.13.0 + # via -r requirements.piptools +blinker==1.7.0 + # via flask +click==8.1.7 + # via flask +flask==3.0.0 + # via -r requirements.piptools +itsdangerous==2.1.2 + # via flask +jinja2==3.1.2 + # via flask +mako==1.3.0 + # via alembic +markupsafe==2.1.3 + # via + # jinja2 + # mako + # werkzeug +passlib==1.7.4 + # via -r requirements.piptools +progressbar2==4.2.0 + # via -r requirements.piptools +python-dateutil==2.8.2 + # via -r requirements.piptools +python-utils==3.8.1 + # via progressbar2 +six==1.16.0 + # via python-dateutil +sqlalchemy==2.0.23 + # via + # -r requirements.piptools + # alembic +typing-extensions==4.9.0 + # via + # alembic + # python-utils + # sqlalchemy +werkzeug==3.0.1 + # via flask diff --git a/app/ch14_testing/final/requirements.piptools b/app/ch14_testing/final/requirements.piptools new file mode 100644 index 00000000..d13bf0c8 --- /dev/null +++ b/app/ch14_testing/final/requirements.piptools @@ -0,0 +1,6 @@ +alembic +flask +passlib +progressbar2 +python-dateutil +sqlalchemy diff --git a/app/ch14_testing/final/requirements.txt b/app/ch14_testing/final/requirements.txt index e10973d8..662fe297 100644 --- a/app/ch14_testing/final/requirements.txt +++ b/app/ch14_testing/final/requirements.txt @@ -1,8 +1,46 @@ -werkzeug -flask -sqlalchemy - -progressbar2 -python-dateutil -passlib - +# +# This file is autogenerated by pip-compile with Python 3.11 +# by the following command: +# +# pip-compile requirements.piptools +# +alembic==1.13.0 + # via -r requirements.piptools +blinker==1.7.0 + # via flask +click==8.1.7 + # via flask +flask==3.0.0 + # via -r requirements.piptools +itsdangerous==2.1.2 + # via flask +jinja2==3.1.2 + # via flask +mako==1.3.0 + # via alembic +markupsafe==2.1.3 + # via + # jinja2 + # mako + # werkzeug +passlib==1.7.4 + # via -r requirements.piptools +progressbar2==4.2.0 + # via -r requirements.piptools +python-dateutil==2.8.2 + # via -r requirements.piptools +python-utils==3.8.1 + # via progressbar2 +six==1.16.0 + # via python-dateutil +sqlalchemy==2.0.23 + # via + # -r requirements.piptools + # alembic +typing-extensions==4.9.0 + # via + # alembic + # python-utils + # sqlalchemy +werkzeug==3.0.1 + # via flask diff --git a/app/ch14_testing/starter/requirements.piptools b/app/ch14_testing/starter/requirements.piptools new file mode 100644 index 00000000..d13bf0c8 --- /dev/null +++ b/app/ch14_testing/starter/requirements.piptools @@ -0,0 +1,6 @@ +alembic +flask +passlib +progressbar2 +python-dateutil +sqlalchemy diff --git a/app/ch14_testing/starter/requirements.txt b/app/ch14_testing/starter/requirements.txt index e10973d8..662fe297 100644 --- a/app/ch14_testing/starter/requirements.txt +++ b/app/ch14_testing/starter/requirements.txt @@ -1,8 +1,46 @@ -werkzeug -flask -sqlalchemy - -progressbar2 -python-dateutil -passlib - +# +# This file is autogenerated by pip-compile with Python 3.11 +# by the following command: +# +# pip-compile requirements.piptools +# +alembic==1.13.0 + # via -r requirements.piptools +blinker==1.7.0 + # via flask +click==8.1.7 + # via flask +flask==3.0.0 + # via -r requirements.piptools +itsdangerous==2.1.2 + # via flask +jinja2==3.1.2 + # via flask +mako==1.3.0 + # via alembic +markupsafe==2.1.3 + # via + # jinja2 + # mako + # werkzeug +passlib==1.7.4 + # via -r requirements.piptools +progressbar2==4.2.0 + # via -r requirements.piptools +python-dateutil==2.8.2 + # via -r requirements.piptools +python-utils==3.8.1 + # via progressbar2 +six==1.16.0 + # via python-dateutil +sqlalchemy==2.0.23 + # via + # -r requirements.piptools + # alembic +typing-extensions==4.9.0 + # via + # alembic + # python-utils + # sqlalchemy +werkzeug==3.0.1 + # via flask diff --git a/app/ch15_deploy/final/requirements.piptools b/app/ch15_deploy/final/requirements.piptools new file mode 100644 index 00000000..d13bf0c8 --- /dev/null +++ b/app/ch15_deploy/final/requirements.piptools @@ -0,0 +1,6 @@ +alembic +flask +passlib +progressbar2 +python-dateutil +sqlalchemy diff --git a/app/ch15_deploy/final/requirements.txt b/app/ch15_deploy/final/requirements.txt index e8ba36b0..662fe297 100644 --- a/app/ch15_deploy/final/requirements.txt +++ b/app/ch15_deploy/final/requirements.txt @@ -1,7 +1,46 @@ -flask -werkzeug -sqlalchemy - -progressbar2 -python-dateutil -passlib +# +# This file is autogenerated by pip-compile with Python 3.11 +# by the following command: +# +# pip-compile requirements.piptools +# +alembic==1.13.0 + # via -r requirements.piptools +blinker==1.7.0 + # via flask +click==8.1.7 + # via flask +flask==3.0.0 + # via -r requirements.piptools +itsdangerous==2.1.2 + # via flask +jinja2==3.1.2 + # via flask +mako==1.3.0 + # via alembic +markupsafe==2.1.3 + # via + # jinja2 + # mako + # werkzeug +passlib==1.7.4 + # via -r requirements.piptools +progressbar2==4.2.0 + # via -r requirements.piptools +python-dateutil==2.8.2 + # via -r requirements.piptools +python-utils==3.8.1 + # via progressbar2 +six==1.16.0 + # via python-dateutil +sqlalchemy==2.0.23 + # via + # -r requirements.piptools + # alembic +typing-extensions==4.9.0 + # via + # alembic + # python-utils + # sqlalchemy +werkzeug==3.0.1 + # via flask diff --git a/app/ch15_deploy/starter/requirements.piptools b/app/ch15_deploy/starter/requirements.piptools new file mode 100644 index 00000000..d13bf0c8 --- /dev/null +++ b/app/ch15_deploy/starter/requirements.piptools @@ -0,0 +1,6 @@ +alembic +flask +passlib +progressbar2 +python-dateutil +sqlalchemy diff --git a/app/ch15_deploy/starter/requirements.txt b/app/ch15_deploy/starter/requirements.txt index e10973d8..662fe297 100644 --- a/app/ch15_deploy/starter/requirements.txt +++ b/app/ch15_deploy/starter/requirements.txt @@ -1,8 +1,46 @@ -werkzeug -flask -sqlalchemy - -progressbar2 -python-dateutil -passlib - +# +# This file is autogenerated by pip-compile with Python 3.11 +# by the following command: +# +# pip-compile requirements.piptools +# +alembic==1.13.0 + # via -r requirements.piptools +blinker==1.7.0 + # via flask +click==8.1.7 + # via flask +flask==3.0.0 + # via -r requirements.piptools +itsdangerous==2.1.2 + # via flask +jinja2==3.1.2 + # via flask +mako==1.3.0 + # via alembic +markupsafe==2.1.3 + # via + # jinja2 + # mako + # werkzeug +passlib==1.7.4 + # via -r requirements.piptools +progressbar2==4.2.0 + # via -r requirements.piptools +python-dateutil==2.8.2 + # via -r requirements.piptools +python-utils==3.8.1 + # via progressbar2 +six==1.16.0 + # via python-dateutil +sqlalchemy==2.0.23 + # via + # -r requirements.piptools + # alembic +typing-extensions==4.9.0 + # via + # alembic + # python-utils + # sqlalchemy +werkzeug==3.0.1 + # via flask diff --git a/app/ch16_mongodb/final/requirements.piptools b/app/ch16_mongodb/final/requirements.piptools new file mode 100644 index 00000000..22a62e3c --- /dev/null +++ b/app/ch16_mongodb/final/requirements.piptools @@ -0,0 +1,7 @@ +alembic +flask +mongoengine +passlib +progressbar2 +python-dateutil +sqlalchemy diff --git a/app/ch16_mongodb/final/requirements.txt b/app/ch16_mongodb/final/requirements.txt index 5c9d660d..85b126c8 100644 --- a/app/ch16_mongodb/final/requirements.txt +++ b/app/ch16_mongodb/final/requirements.txt @@ -1,8 +1,52 @@ -werkzeug -flask -sqlalchemy -mongoengine - -progressbar2 -python-dateutil -passlib +# +# This file is autogenerated by pip-compile with Python 3.11 +# by the following command: +# +# pip-compile requirements.piptools +# +alembic==1.13.0 + # via -r requirements.piptools +blinker==1.7.0 + # via flask +click==8.1.7 + # via flask +dnspython==2.4.2 + # via pymongo +flask==3.0.0 + # via -r requirements.piptools +itsdangerous==2.1.2 + # via flask +jinja2==3.1.2 + # via flask +mako==1.3.0 + # via alembic +markupsafe==2.1.3 + # via + # jinja2 + # mako + # werkzeug +mongoengine==0.27.0 + # via -r requirements.piptools +passlib==1.7.4 + # via -r requirements.piptools +progressbar2==4.2.0 + # via -r requirements.piptools +pymongo==4.6.1 + # via mongoengine +python-dateutil==2.8.2 + # via -r requirements.piptools +python-utils==3.8.1 + # via progressbar2 +six==1.16.0 + # via python-dateutil +sqlalchemy==2.0.23 + # via + # -r requirements.piptools + # alembic +typing-extensions==4.9.0 + # via + # alembic + # python-utils + # sqlalchemy +werkzeug==3.0.1 + # via flask diff --git a/app/ch16_mongodb/starter/requirements.piptools b/app/ch16_mongodb/starter/requirements.piptools new file mode 100644 index 00000000..d13bf0c8 --- /dev/null +++ b/app/ch16_mongodb/starter/requirements.piptools @@ -0,0 +1,6 @@ +alembic +flask +passlib +progressbar2 +python-dateutil +sqlalchemy diff --git a/app/ch16_mongodb/starter/requirements.txt b/app/ch16_mongodb/starter/requirements.txt index e10973d8..662fe297 100644 --- a/app/ch16_mongodb/starter/requirements.txt +++ b/app/ch16_mongodb/starter/requirements.txt @@ -1,8 +1,46 @@ -werkzeug -flask -sqlalchemy - -progressbar2 -python-dateutil -passlib - +# +# This file is autogenerated by pip-compile with Python 3.11 +# by the following command: +# +# pip-compile requirements.piptools +# +alembic==1.13.0 + # via -r requirements.piptools +blinker==1.7.0 + # via flask +click==8.1.7 + # via flask +flask==3.0.0 + # via -r requirements.piptools +itsdangerous==2.1.2 + # via flask +jinja2==3.1.2 + # via flask +mako==1.3.0 + # via alembic +markupsafe==2.1.3 + # via + # jinja2 + # mako + # werkzeug +passlib==1.7.4 + # via -r requirements.piptools +progressbar2==4.2.0 + # via -r requirements.piptools +python-dateutil==2.8.2 + # via -r requirements.piptools +python-utils==3.8.1 + # via progressbar2 +six==1.16.0 + # via python-dateutil +sqlalchemy==2.0.23 + # via + # -r requirements.piptools + # alembic +typing-extensions==4.9.0 + # via + # alembic + # python-utils + # sqlalchemy +werkzeug==3.0.1 + # via flask diff --git a/requirements.piptools b/requirements.piptools new file mode 100644 index 00000000..22a62e3c --- /dev/null +++ b/requirements.piptools @@ -0,0 +1,7 @@ +alembic +flask +mongoengine +passlib +progressbar2 +python-dateutil +sqlalchemy diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 00000000..85b126c8 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,52 @@ +# +# This file is autogenerated by pip-compile with Python 3.11 +# by the following command: +# +# pip-compile requirements.piptools +# +alembic==1.13.0 + # via -r requirements.piptools +blinker==1.7.0 + # via flask +click==8.1.7 + # via flask +dnspython==2.4.2 + # via pymongo +flask==3.0.0 + # via -r requirements.piptools +itsdangerous==2.1.2 + # via flask +jinja2==3.1.2 + # via flask +mako==1.3.0 + # via alembic +markupsafe==2.1.3 + # via + # jinja2 + # mako + # werkzeug +mongoengine==0.27.0 + # via -r requirements.piptools +passlib==1.7.4 + # via -r requirements.piptools +progressbar2==4.2.0 + # via -r requirements.piptools +pymongo==4.6.1 + # via mongoengine +python-dateutil==2.8.2 + # via -r requirements.piptools +python-utils==3.8.1 + # via progressbar2 +six==1.16.0 + # via python-dateutil +sqlalchemy==2.0.23 + # via + # -r requirements.piptools + # alembic +typing-extensions==4.9.0 + # via + # alembic + # python-utils + # sqlalchemy +werkzeug==3.0.1 + # via flask From 1ab7d3be8fcd44a8035b1d08f0b6e0033158027c Mon Sep 17 00:00:00 2001 From: Michael Kennedy Date: Tue, 12 Dec 2023 16:27:35 -0800 Subject: [PATCH 34/44] Add ruff config --- .idea/ruff.xml | 6 ++++++ ruff.toml | 42 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+) create mode 100644 .idea/ruff.xml create mode 100644 ruff.toml diff --git a/.idea/ruff.xml b/.idea/ruff.xml new file mode 100644 index 00000000..5aa89c50 --- /dev/null +++ b/.idea/ruff.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/ruff.toml b/ruff.toml new file mode 100644 index 00000000..5537773d --- /dev/null +++ b/ruff.toml @@ -0,0 +1,42 @@ +# [ruff] +line-length = 120 +format.quote-style = "single" + +# Enable Pyflakes `E` and `F` codes by default. +select = ["E", "F"] +ignore = [] + +# Exclude a variety of commonly ignored directories. +exclude = [ + ".bzr", + ".direnv", + ".eggs", + ".git", + ".hg", + ".mypy_cache", + ".nox", + ".pants.d", + ".ruff_cache", + ".svn", + ".tox", + "__pypackages__", + "_build", + "buck-out", + "build", + "dist", + "node_modules", + ".env", + ".venv", + "venv", +] +per-file-ignores = {} + +# Allow unused variables when underscore-prefixed. +# dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$" + +# Assume Python 3.11. +target-version = "py311" + +#[tool.ruff.mccabe] +## Unlike Flake8, default to a complexity level of 10. +mccabe.max-complexity = 10 From c2e1dbac64e7243cabff96771c29a3fe927b0e5c Mon Sep 17 00:00:00 2001 From: Michael Kennedy Date: Tue, 12 Dec 2023 16:28:23 -0800 Subject: [PATCH 35/44] Update all the code files to be "ruff format" formatted. --- .../first_site_final/first_site/app.py | 4 +- .../final/pypi_org/app.py | 1 + .../pypi_org/infrastructure/view_modifiers.py | 3 +- app/ch06_routing/final/pypi_org/app.py | 1 + .../pypi_org/infrastructure/view_modifiers.py | 4 +- .../final/pypi_org/views/account_views.py | 3 + .../final/pypi_org/views/cms_views.py | 2 +- .../final/pypi_org/views/package_views.py | 4 +- app/ch06_routing/starter/pypi_org/app.py | 1 + .../pypi_org/infrastructure/view_modifiers.py | 4 +- .../final/pypi_org/app.py | 1 + .../pypi_org/infrastructure/view_modifiers.py | 4 +- .../final/pypi_org/views/account_views.py | 3 + .../final/pypi_org/views/cms_views.py | 2 +- .../final/pypi_org/views/package_views.py | 4 +- .../starter/pypi_org/app.py | 1 + .../pypi_org/infrastructure/view_modifiers.py | 4 +- .../starter/pypi_org/views/account_views.py | 3 + .../starter/pypi_org/views/cms_views.py | 2 +- .../starter/pypi_org/views/package_views.py | 4 +- app/ch09_sqlalchemy/final/pypi_org/app.py | 6 +- .../final/pypi_org/data/__all_models.py | 6 ++ .../final/pypi_org/data/db_session.py | 6 +- .../final/pypi_org/data/package.py | 14 +++-- .../final/pypi_org/data/releases.py | 4 +- .../pypi_org/infrastructure/view_modifiers.py | 4 +- .../final/pypi_org/views/account_views.py | 3 + .../final/pypi_org/views/cms_views.py | 2 +- .../final/pypi_org/views/package_views.py | 4 +- app/ch09_sqlalchemy/starter/pypi_org/app.py | 1 + .../pypi_org/infrastructure/view_modifiers.py | 4 +- .../starter/pypi_org/views/account_views.py | 3 + .../starter/pypi_org/views/cms_views.py | 2 +- .../starter/pypi_org/views/package_views.py | 4 +- .../final/pypi_org/app.py | 6 +- .../final/pypi_org/bin/basic_inserts.py | 29 +++++---- .../final/pypi_org/bin/load_data.py | 60 ++++++++----------- .../final/pypi_org/data/__all_models.py | 6 ++ .../final/pypi_org/data/db_session.py | 6 +- .../final/pypi_org/data/downloads.py | 3 +- .../final/pypi_org/data/languages.py | 3 +- .../final/pypi_org/data/package.py | 14 +++-- .../final/pypi_org/data/releases.py | 6 +- .../pypi_org/infrastructure/view_modifiers.py | 4 +- .../pypi_org/services/package_service.py | 20 ++++--- .../final/pypi_org/views/account_views.py | 3 + .../final/pypi_org/views/cms_views.py | 2 +- .../final/pypi_org/views/package_views.py | 4 +- .../starter/pypi_org/app.py | 6 +- .../starter/pypi_org/data/__all_models.py | 6 ++ .../starter/pypi_org/data/db_session.py | 6 +- .../starter/pypi_org/data/package.py | 14 +++-- .../starter/pypi_org/data/releases.py | 4 +- .../pypi_org/infrastructure/view_modifiers.py | 4 +- .../starter/pypi_org/views/account_views.py | 3 + .../starter/pypi_org/views/cms_views.py | 2 +- .../starter/pypi_org/views/package_views.py | 4 +- .../final/alembic/alembic_helpers.py | 3 +- app/ch11_migrations/final/alembic/env.py | 13 ++-- .../722c82f0097c_added_auditing_table.py | 11 ++-- app/ch11_migrations/final/pypi_org/app.py | 6 +- .../final/pypi_org/bin/basic_inserts.py | 29 +++++---- .../final/pypi_org/bin/load_data.py | 60 ++++++++----------- .../final/pypi_org/data/__all_models.py | 7 +++ .../final/pypi_org/data/db_session.py | 6 +- .../final/pypi_org/data/downloads.py | 3 +- .../final/pypi_org/data/languages.py | 3 +- .../final/pypi_org/data/package.py | 14 +++-- .../final/pypi_org/data/releases.py | 6 +- .../pypi_org/infrastructure/view_modifiers.py | 3 +- .../pypi_org/services/package_service.py | 20 ++++--- .../final/pypi_org/views/account_views.py | 3 + .../final/pypi_org/views/cms_views.py | 2 +- .../final/pypi_org/views/package_views.py | 4 +- app/ch11_migrations/starter/pypi_org/app.py | 6 +- .../starter/pypi_org/bin/basic_inserts.py | 29 +++++---- .../starter/pypi_org/bin/load_data.py | 60 ++++++++----------- .../starter/pypi_org/data/__all_models.py | 6 ++ .../starter/pypi_org/data/db_session.py | 6 +- .../starter/pypi_org/data/downloads.py | 3 +- .../starter/pypi_org/data/languages.py | 3 +- .../starter/pypi_org/data/package.py | 14 +++-- .../starter/pypi_org/data/releases.py | 6 +- .../pypi_org/infrastructure/view_modifiers.py | 4 +- .../pypi_org/services/package_service.py | 20 ++++--- .../starter/pypi_org/views/account_views.py | 3 + .../starter/pypi_org/views/cms_views.py | 2 +- .../starter/pypi_org/views/package_views.py | 4 +- .../final/alembic/alembic_helpers.py | 3 +- app/ch12-forms/final/alembic/env.py | 13 ++-- .../722c82f0097c_added_auditing_table.py | 11 ++-- app/ch12-forms/final/pypi_org/app.py | 5 +- .../final/pypi_org/bin/basic_inserts.py | 29 +++++---- .../final/pypi_org/bin/load_data.py | 60 ++++++++----------- .../final/pypi_org/data/__all_models.py | 7 +++ .../final/pypi_org/data/db_session.py | 6 +- .../final/pypi_org/data/downloads.py | 3 +- .../final/pypi_org/data/languages.py | 3 +- app/ch12-forms/final/pypi_org/data/package.py | 14 +++-- .../final/pypi_org/data/releases.py | 6 +- .../pypi_org/infrastructure/cookie_auth.py | 4 +- .../pypi_org/infrastructure/request_dict.py | 2 +- .../pypi_org/infrastructure/view_modifiers.py | 4 +- .../pypi_org/services/package_service.py | 20 ++++--- .../final/pypi_org/views/account_views.py | 11 ++-- .../final/pypi_org/views/cms_views.py | 2 +- .../final/pypi_org/views/package_views.py | 4 +- .../starter/alembic/alembic_helpers.py | 3 +- app/ch12-forms/starter/alembic/env.py | 13 ++-- .../722c82f0097c_added_auditing_table.py | 11 ++-- app/ch12-forms/starter/pypi_org/app.py | 6 +- .../starter/pypi_org/bin/basic_inserts.py | 29 +++++---- .../starter/pypi_org/bin/load_data.py | 60 ++++++++----------- .../starter/pypi_org/data/__all_models.py | 7 +++ .../starter/pypi_org/data/db_session.py | 6 +- .../starter/pypi_org/data/downloads.py | 3 +- .../starter/pypi_org/data/languages.py | 3 +- .../starter/pypi_org/data/package.py | 14 +++-- .../starter/pypi_org/data/releases.py | 6 +- .../pypi_org/infrastructure/view_modifiers.py | 4 +- .../pypi_org/services/package_service.py | 20 ++++--- .../starter/pypi_org/views/account_views.py | 3 + .../starter/pypi_org/views/cms_views.py | 2 +- .../starter/pypi_org/views/package_views.py | 4 +- .../final/alembic/alembic_helpers.py | 3 +- app/ch13-validation/final/alembic/env.py | 13 ++-- .../722c82f0097c_added_auditing_table.py | 11 ++-- app/ch13-validation/final/pypi_org/app.py | 6 +- .../final/pypi_org/bin/basic_inserts.py | 29 +++++---- .../final/pypi_org/bin/load_data.py | 60 ++++++++----------- .../final/pypi_org/data/__all_models.py | 7 +++ .../final/pypi_org/data/db_session.py | 6 +- .../final/pypi_org/data/downloads.py | 3 +- .../final/pypi_org/data/languages.py | 3 +- .../final/pypi_org/data/package.py | 14 +++-- .../final/pypi_org/data/releases.py | 6 +- .../pypi_org/infrastructure/cookie_auth.py | 4 +- .../pypi_org/infrastructure/request_dict.py | 2 +- .../pypi_org/infrastructure/view_modifiers.py | 4 +- .../pypi_org/services/package_service.py | 22 +++---- .../pypi_org/viewmodels/cms/page_viewmodel.py | 1 - .../packages/pagedetails_viewmodel.py | 2 +- .../final/pypi_org/views/account_views.py | 5 +- .../final/pypi_org/views/package_views.py | 2 +- .../starter/alembic/alembic_helpers.py | 3 +- app/ch13-validation/starter/alembic/env.py | 13 ++-- .../722c82f0097c_added_auditing_table.py | 11 ++-- app/ch13-validation/starter/pypi_org/app.py | 6 +- .../starter/pypi_org/bin/basic_inserts.py | 29 +++++---- .../starter/pypi_org/bin/load_data.py | 60 ++++++++----------- .../starter/pypi_org/data/__all_models.py | 7 +++ .../starter/pypi_org/data/db_session.py | 6 +- .../starter/pypi_org/data/downloads.py | 3 +- .../starter/pypi_org/data/languages.py | 3 +- .../starter/pypi_org/data/package.py | 14 +++-- .../starter/pypi_org/data/releases.py | 6 +- .../pypi_org/infrastructure/cookie_auth.py | 4 +- .../pypi_org/infrastructure/request_dict.py | 2 +- .../pypi_org/infrastructure/view_modifiers.py | 4 +- .../pypi_org/services/package_service.py | 20 ++++--- .../starter/pypi_org/views/account_views.py | 11 ++-- .../starter/pypi_org/views/cms_views.py | 2 +- .../starter/pypi_org/views/package_views.py | 4 +- .../final/alembic/alembic_helpers.py | 3 +- app/ch14_testing/final/alembic/env.py | 13 ++-- .../722c82f0097c_added_auditing_table.py | 11 ++-- app/ch14_testing/final/pypi_org/app.py | 6 +- .../final/pypi_org/bin/basic_inserts.py | 29 +++++---- .../final/pypi_org/bin/load_data.py | 60 ++++++++----------- .../final/pypi_org/data/__all_models.py | 7 +++ .../final/pypi_org/data/db_session.py | 6 +- .../final/pypi_org/data/downloads.py | 3 +- .../final/pypi_org/data/languages.py | 3 +- .../final/pypi_org/data/package.py | 14 +++-- .../final/pypi_org/data/releases.py | 6 +- .../pypi_org/infrastructure/cookie_auth.py | 4 +- .../pypi_org/infrastructure/request_dict.py | 2 +- .../pypi_org/infrastructure/view_modifiers.py | 4 +- .../pypi_org/services/package_service.py | 22 +++---- .../pypi_org/viewmodels/cms/page_viewmodel.py | 1 - .../packages/pagedetails_viewmodel.py | 2 +- .../viewmodels/seo/sitemap_viewmodel.py | 4 +- .../final/pypi_org/views/account_views.py | 5 +- .../final/pypi_org/views/package_views.py | 2 +- .../final/pypi_org/views/seo_view.py | 1 + app/ch14_testing/final/tests/_all_tests.py | 7 ++- app/ch14_testing/final/tests/account_tests.py | 21 ++----- app/ch14_testing/final/tests/package_tests.py | 8 +-- app/ch14_testing/final/tests/sitemap_tests.py | 9 +-- app/ch14_testing/final/tests/test_client.py | 4 +- .../starter/alembic/alembic_helpers.py | 3 +- app/ch14_testing/starter/alembic/env.py | 13 ++-- .../722c82f0097c_added_auditing_table.py | 11 ++-- app/ch14_testing/starter/pypi_org/app.py | 6 +- .../starter/pypi_org/bin/basic_inserts.py | 29 +++++---- .../starter/pypi_org/bin/load_data.py | 60 ++++++++----------- .../starter/pypi_org/data/__all_models.py | 7 +++ .../starter/pypi_org/data/db_session.py | 6 +- .../starter/pypi_org/data/downloads.py | 3 +- .../starter/pypi_org/data/languages.py | 3 +- .../starter/pypi_org/data/package.py | 14 +++-- .../starter/pypi_org/data/releases.py | 6 +- .../pypi_org/infrastructure/cookie_auth.py | 4 +- .../pypi_org/infrastructure/request_dict.py | 2 +- .../pypi_org/infrastructure/view_modifiers.py | 4 +- .../pypi_org/services/package_service.py | 22 +++---- .../pypi_org/viewmodels/cms/page_viewmodel.py | 1 - .../packages/pagedetails_viewmodel.py | 2 +- .../starter/pypi_org/views/account_views.py | 5 +- .../starter/pypi_org/views/package_views.py | 2 +- .../final/alembic/alembic_helpers.py | 3 +- app/ch15_deploy/final/alembic/env.py | 13 ++-- .../722c82f0097c_added_auditing_table.py | 11 ++-- app/ch15_deploy/final/pypi_org/app.py | 13 ++-- .../final/pypi_org/bin/basic_inserts.py | 29 +++++---- .../final/pypi_org/bin/load_data.py | 60 ++++++++----------- .../final/pypi_org/data/__all_models.py | 7 +++ .../final/pypi_org/data/db_session.py | 6 +- .../final/pypi_org/data/downloads.py | 3 +- .../final/pypi_org/data/languages.py | 3 +- .../final/pypi_org/data/package.py | 14 +++-- .../final/pypi_org/data/releases.py | 6 +- .../pypi_org/infrastructure/cookie_auth.py | 4 +- .../pypi_org/infrastructure/request_dict.py | 2 +- .../pypi_org/infrastructure/view_modifiers.py | 4 +- .../pypi_org/services/package_service.py | 22 +++---- .../pypi_org/viewmodels/cms/page_viewmodel.py | 1 - .../packages/pagedetails_viewmodel.py | 2 +- .../viewmodels/seo/sitemap_viewmodel.py | 4 +- .../final/pypi_org/views/account_views.py | 5 +- .../final/pypi_org/views/package_views.py | 2 +- .../final/pypi_org/views/seo_view.py | 1 + app/ch15_deploy/final/tests/_all_tests.py | 7 ++- app/ch15_deploy/final/tests/account_tests.py | 21 ++----- app/ch15_deploy/final/tests/package_tests.py | 8 +-- app/ch15_deploy/final/tests/sitemap_tests.py | 9 +-- app/ch15_deploy/final/tests/test_client.py | 4 +- .../starter/alembic/alembic_helpers.py | 3 +- app/ch15_deploy/starter/alembic/env.py | 13 ++-- .../722c82f0097c_added_auditing_table.py | 11 ++-- app/ch15_deploy/starter/pypi_org/app.py | 13 ++-- .../starter/pypi_org/bin/basic_inserts.py | 29 +++++---- .../starter/pypi_org/bin/load_data.py | 60 ++++++++----------- .../starter/pypi_org/data/__all_models.py | 7 +++ .../starter/pypi_org/data/db_session.py | 6 +- .../starter/pypi_org/data/downloads.py | 3 +- .../starter/pypi_org/data/languages.py | 3 +- .../starter/pypi_org/data/package.py | 14 +++-- .../starter/pypi_org/data/releases.py | 6 +- .../pypi_org/infrastructure/cookie_auth.py | 4 +- .../pypi_org/infrastructure/request_dict.py | 2 +- .../pypi_org/infrastructure/view_modifiers.py | 4 +- .../pypi_org/services/package_service.py | 22 +++---- .../pypi_org/viewmodels/cms/page_viewmodel.py | 1 - .../packages/pagedetails_viewmodel.py | 2 +- .../viewmodels/seo/sitemap_viewmodel.py | 4 +- .../starter/pypi_org/views/account_views.py | 5 +- .../starter/pypi_org/views/package_views.py | 2 +- .../starter/pypi_org/views/seo_view.py | 1 + app/ch15_deploy/starter/tests/_all_tests.py | 7 ++- .../starter/tests/account_tests.py | 21 ++----- .../starter/tests/package_tests.py | 8 +-- .../starter/tests/sitemap_tests.py | 9 +-- app/ch15_deploy/starter/tests/test_client.py | 4 +- .../final/alembic/alembic_helpers.py | 3 +- app/ch16_mongodb/final/alembic/env.py | 13 ++-- .../722c82f0097c_added_auditing_table.py | 11 ++-- app/ch16_mongodb/final/pypi_org/app.py | 8 +-- .../final/pypi_org/bin/basic_inserts.py | 29 +++++---- .../final/pypi_org/bin/load_data.py | 60 ++++++++----------- .../final/pypi_org/bin/migrate_to_mongodb.py | 8 +-- .../final/pypi_org/data/__all_models.py | 7 +++ .../final/pypi_org/data/db_session.py | 4 +- .../final/pypi_org/data/downloads.py | 3 +- .../final/pypi_org/data/languages.py | 3 +- .../final/pypi_org/data/package.py | 14 +++-- .../final/pypi_org/data/releases.py | 6 +- .../pypi_org/infrastructure/cookie_auth.py | 4 +- .../pypi_org/infrastructure/request_dict.py | 2 +- .../pypi_org/infrastructure/view_modifiers.py | 4 +- .../final/pypi_org/nosql/downloads.py | 2 +- .../final/pypi_org/nosql/languages.py | 3 +- .../final/pypi_org/nosql/licenses.py | 2 +- .../final/pypi_org/nosql/mongo_setup.py | 10 ++-- .../final/pypi_org/nosql/packages.py | 2 +- .../final/pypi_org/nosql/releases.py | 2 +- .../final/pypi_org/nosql/users.py | 2 +- .../pypi_org/services/package_service.py | 9 +-- .../packages/pagedetails_viewmodel.py | 5 +- .../viewmodels/seo/sitemap_viewmodel.py | 4 +- .../final/pypi_org/views/account_views.py | 5 +- .../final/pypi_org/views/package_views.py | 2 +- .../final/pypi_org/views/seo_view.py | 1 + app/ch16_mongodb/final/tests/_all_tests.py | 7 ++- app/ch16_mongodb/final/tests/account_tests.py | 21 ++----- app/ch16_mongodb/final/tests/package_tests.py | 8 +-- app/ch16_mongodb/final/tests/sitemap_tests.py | 9 +-- app/ch16_mongodb/final/tests/test_client.py | 4 +- .../starter/alembic/alembic_helpers.py | 3 +- app/ch16_mongodb/starter/alembic/env.py | 13 ++-- .../722c82f0097c_added_auditing_table.py | 11 ++-- app/ch16_mongodb/starter/pypi_org/app.py | 13 ++-- .../starter/pypi_org/bin/basic_inserts.py | 29 +++++---- .../starter/pypi_org/bin/load_data.py | 60 ++++++++----------- .../starter/pypi_org/data/__all_models.py | 7 +++ .../starter/pypi_org/data/db_session.py | 4 +- .../starter/pypi_org/data/downloads.py | 3 +- .../starter/pypi_org/data/languages.py | 3 +- .../starter/pypi_org/data/package.py | 14 +++-- .../starter/pypi_org/data/releases.py | 6 +- .../pypi_org/infrastructure/cookie_auth.py | 4 +- .../pypi_org/infrastructure/request_dict.py | 2 +- .../pypi_org/infrastructure/view_modifiers.py | 4 +- .../pypi_org/services/package_service.py | 22 +++---- .../pypi_org/viewmodels/cms/page_viewmodel.py | 1 - .../packages/pagedetails_viewmodel.py | 2 +- .../viewmodels/seo/sitemap_viewmodel.py | 4 +- .../starter/pypi_org/views/account_views.py | 5 +- .../starter/pypi_org/views/package_views.py | 2 +- .../starter/pypi_org/views/seo_view.py | 1 + app/ch16_mongodb/starter/tests/_all_tests.py | 7 ++- .../starter/tests/account_tests.py | 21 ++----- .../starter/tests/package_tests.py | 8 +-- .../starter/tests/sitemap_tests.py | 9 +-- app/ch16_mongodb/starter/tests/test_client.py | 4 +- 325 files changed, 1498 insertions(+), 1533 deletions(-) diff --git a/app/ch04_first_site/first_site_final/first_site/app.py b/app/ch04_first_site/first_site_final/first_site/app.py index 9946e943..63e99004 100644 --- a/app/ch04_first_site/first_site_final/first_site/app.py +++ b/app/ch04_first_site/first_site_final/first_site/app.py @@ -2,8 +2,10 @@ app = flask.Flask(__name__) + @app.route('/') def index(): - return "Hello world" + return 'Hello world' + app.run() diff --git a/app/ch05_jinja_templates/final/pypi_org/app.py b/app/ch05_jinja_templates/final/pypi_org/app.py index fe54fabf..ba6389b2 100644 --- a/app/ch05_jinja_templates/final/pypi_org/app.py +++ b/app/ch05_jinja_templates/final/pypi_org/app.py @@ -1,6 +1,7 @@ import os import sys import flask + folder = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) sys.path.insert(0, folder) diff --git a/app/ch05_jinja_templates/final/pypi_org/infrastructure/view_modifiers.py b/app/ch05_jinja_templates/final/pypi_org/infrastructure/view_modifiers.py index 0c0941eb..d944c142 100644 --- a/app/ch05_jinja_templates/final/pypi_org/infrastructure/view_modifiers.py +++ b/app/ch05_jinja_templates/final/pypi_org/infrastructure/view_modifiers.py @@ -26,7 +26,8 @@ def view_method(*args, **kwargs): if template_file and not isinstance(response_val, dict): raise Exception( - "Invalid return type {}, we expected a dict as the return value.".format(type(response_val))) + 'Invalid return type {}, we expected a dict as the return value.'.format(type(response_val)) + ) if template_file: response_val = flask.render_template(template_file, **response_val) diff --git a/app/ch06_routing/final/pypi_org/app.py b/app/ch06_routing/final/pypi_org/app.py index 8b26ae61..7b493c47 100644 --- a/app/ch06_routing/final/pypi_org/app.py +++ b/app/ch06_routing/final/pypi_org/app.py @@ -1,6 +1,7 @@ import os import sys import flask + folder = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) sys.path.insert(0, folder) diff --git a/app/ch06_routing/final/pypi_org/infrastructure/view_modifiers.py b/app/ch06_routing/final/pypi_org/infrastructure/view_modifiers.py index 0978163e..d944c142 100644 --- a/app/ch06_routing/final/pypi_org/infrastructure/view_modifiers.py +++ b/app/ch06_routing/final/pypi_org/infrastructure/view_modifiers.py @@ -26,7 +26,8 @@ def view_method(*args, **kwargs): if template_file and not isinstance(response_val, dict): raise Exception( - "Invalid return type {}, we expected a dict as the return value.".format(type(response_val))) + 'Invalid return type {}, we expected a dict as the return value.'.format(type(response_val)) + ) if template_file: response_val = flask.render_template(template_file, **response_val) @@ -42,6 +43,7 @@ def view_method(*args, **kwargs): return response_inner + # # def template(template_file: str = None): # def template_inner(f): diff --git a/app/ch06_routing/final/pypi_org/views/account_views.py b/app/ch06_routing/final/pypi_org/views/account_views.py index 0421324a..55e5df41 100644 --- a/app/ch06_routing/final/pypi_org/views/account_views.py +++ b/app/ch06_routing/final/pypi_org/views/account_views.py @@ -16,6 +16,7 @@ def index(): # ################### REGISTER ################################# + @blueprint.route('/account/register', methods=['GET']) @response(template_file='account/register.html') def register_get(): @@ -30,6 +31,7 @@ def register_post(): # ################### LOGIN ################################# + @blueprint.route('/account/login', methods=['GET']) @response(template_file='account/login.html') def login_get(): @@ -44,6 +46,7 @@ def login_post(): # ################### LOGOUT ################################# + @blueprint.route('/account/logout') def logout(): return {} diff --git a/app/ch06_routing/final/pypi_org/views/cms_views.py b/app/ch06_routing/final/pypi_org/views/cms_views.py index f7172d3d..a8b755a8 100644 --- a/app/ch06_routing/final/pypi_org/views/cms_views.py +++ b/app/ch06_routing/final/pypi_org/views/cms_views.py @@ -9,7 +9,7 @@ @blueprint.route('/') @response(template_file='cms/page.html') def cms_page(full_url: str): - print("Getting CMS page for {}".format(full_url)) + print('Getting CMS page for {}'.format(full_url)) page = cms_service.get_page(full_url) if not page: diff --git a/app/ch06_routing/final/pypi_org/views/package_views.py b/app/ch06_routing/final/pypi_org/views/package_views.py index ccf6bf12..7450fa1c 100644 --- a/app/ch06_routing/final/pypi_org/views/package_views.py +++ b/app/ch06_routing/final/pypi_org/views/package_views.py @@ -9,10 +9,10 @@ @blueprint.route('/project/') # @response(template_file='packages/details.html') def package_details(package_name: str): - return "Package details for {}".format(package_name) + return 'Package details for {}'.format(package_name) @blueprint.route('/') def popular(rank: int): print(type(rank), rank) - return "The details for the {}th most popular package".format(rank) + return 'The details for the {}th most popular package'.format(rank) diff --git a/app/ch06_routing/starter/pypi_org/app.py b/app/ch06_routing/starter/pypi_org/app.py index fe54fabf..ba6389b2 100644 --- a/app/ch06_routing/starter/pypi_org/app.py +++ b/app/ch06_routing/starter/pypi_org/app.py @@ -1,6 +1,7 @@ import os import sys import flask + folder = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) sys.path.insert(0, folder) diff --git a/app/ch06_routing/starter/pypi_org/infrastructure/view_modifiers.py b/app/ch06_routing/starter/pypi_org/infrastructure/view_modifiers.py index 0978163e..d944c142 100644 --- a/app/ch06_routing/starter/pypi_org/infrastructure/view_modifiers.py +++ b/app/ch06_routing/starter/pypi_org/infrastructure/view_modifiers.py @@ -26,7 +26,8 @@ def view_method(*args, **kwargs): if template_file and not isinstance(response_val, dict): raise Exception( - "Invalid return type {}, we expected a dict as the return value.".format(type(response_val))) + 'Invalid return type {}, we expected a dict as the return value.'.format(type(response_val)) + ) if template_file: response_val = flask.render_template(template_file, **response_val) @@ -42,6 +43,7 @@ def view_method(*args, **kwargs): return response_inner + # # def template(template_file: str = None): # def template_inner(f): diff --git a/app/ch08_adding_our_design/final/pypi_org/app.py b/app/ch08_adding_our_design/final/pypi_org/app.py index bbd6bc9d..80344a30 100644 --- a/app/ch08_adding_our_design/final/pypi_org/app.py +++ b/app/ch08_adding_our_design/final/pypi_org/app.py @@ -1,6 +1,7 @@ import os import sys import flask + folder = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) sys.path.insert(0, folder) diff --git a/app/ch08_adding_our_design/final/pypi_org/infrastructure/view_modifiers.py b/app/ch08_adding_our_design/final/pypi_org/infrastructure/view_modifiers.py index 0978163e..d944c142 100644 --- a/app/ch08_adding_our_design/final/pypi_org/infrastructure/view_modifiers.py +++ b/app/ch08_adding_our_design/final/pypi_org/infrastructure/view_modifiers.py @@ -26,7 +26,8 @@ def view_method(*args, **kwargs): if template_file and not isinstance(response_val, dict): raise Exception( - "Invalid return type {}, we expected a dict as the return value.".format(type(response_val))) + 'Invalid return type {}, we expected a dict as the return value.'.format(type(response_val)) + ) if template_file: response_val = flask.render_template(template_file, **response_val) @@ -42,6 +43,7 @@ def view_method(*args, **kwargs): return response_inner + # # def template(template_file: str = None): # def template_inner(f): diff --git a/app/ch08_adding_our_design/final/pypi_org/views/account_views.py b/app/ch08_adding_our_design/final/pypi_org/views/account_views.py index 0421324a..55e5df41 100644 --- a/app/ch08_adding_our_design/final/pypi_org/views/account_views.py +++ b/app/ch08_adding_our_design/final/pypi_org/views/account_views.py @@ -16,6 +16,7 @@ def index(): # ################### REGISTER ################################# + @blueprint.route('/account/register', methods=['GET']) @response(template_file='account/register.html') def register_get(): @@ -30,6 +31,7 @@ def register_post(): # ################### LOGIN ################################# + @blueprint.route('/account/login', methods=['GET']) @response(template_file='account/login.html') def login_get(): @@ -44,6 +46,7 @@ def login_post(): # ################### LOGOUT ################################# + @blueprint.route('/account/logout') def logout(): return {} diff --git a/app/ch08_adding_our_design/final/pypi_org/views/cms_views.py b/app/ch08_adding_our_design/final/pypi_org/views/cms_views.py index f7172d3d..a8b755a8 100644 --- a/app/ch08_adding_our_design/final/pypi_org/views/cms_views.py +++ b/app/ch08_adding_our_design/final/pypi_org/views/cms_views.py @@ -9,7 +9,7 @@ @blueprint.route('/') @response(template_file='cms/page.html') def cms_page(full_url: str): - print("Getting CMS page for {}".format(full_url)) + print('Getting CMS page for {}'.format(full_url)) page = cms_service.get_page(full_url) if not page: diff --git a/app/ch08_adding_our_design/final/pypi_org/views/package_views.py b/app/ch08_adding_our_design/final/pypi_org/views/package_views.py index ccf6bf12..7450fa1c 100644 --- a/app/ch08_adding_our_design/final/pypi_org/views/package_views.py +++ b/app/ch08_adding_our_design/final/pypi_org/views/package_views.py @@ -9,10 +9,10 @@ @blueprint.route('/project/') # @response(template_file='packages/details.html') def package_details(package_name: str): - return "Package details for {}".format(package_name) + return 'Package details for {}'.format(package_name) @blueprint.route('/') def popular(rank: int): print(type(rank), rank) - return "The details for the {}th most popular package".format(rank) + return 'The details for the {}th most popular package'.format(rank) diff --git a/app/ch08_adding_our_design/starter/pypi_org/app.py b/app/ch08_adding_our_design/starter/pypi_org/app.py index bbd6bc9d..80344a30 100644 --- a/app/ch08_adding_our_design/starter/pypi_org/app.py +++ b/app/ch08_adding_our_design/starter/pypi_org/app.py @@ -1,6 +1,7 @@ import os import sys import flask + folder = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) sys.path.insert(0, folder) diff --git a/app/ch08_adding_our_design/starter/pypi_org/infrastructure/view_modifiers.py b/app/ch08_adding_our_design/starter/pypi_org/infrastructure/view_modifiers.py index 0978163e..d944c142 100644 --- a/app/ch08_adding_our_design/starter/pypi_org/infrastructure/view_modifiers.py +++ b/app/ch08_adding_our_design/starter/pypi_org/infrastructure/view_modifiers.py @@ -26,7 +26,8 @@ def view_method(*args, **kwargs): if template_file and not isinstance(response_val, dict): raise Exception( - "Invalid return type {}, we expected a dict as the return value.".format(type(response_val))) + 'Invalid return type {}, we expected a dict as the return value.'.format(type(response_val)) + ) if template_file: response_val = flask.render_template(template_file, **response_val) @@ -42,6 +43,7 @@ def view_method(*args, **kwargs): return response_inner + # # def template(template_file: str = None): # def template_inner(f): diff --git a/app/ch08_adding_our_design/starter/pypi_org/views/account_views.py b/app/ch08_adding_our_design/starter/pypi_org/views/account_views.py index 0421324a..55e5df41 100644 --- a/app/ch08_adding_our_design/starter/pypi_org/views/account_views.py +++ b/app/ch08_adding_our_design/starter/pypi_org/views/account_views.py @@ -16,6 +16,7 @@ def index(): # ################### REGISTER ################################# + @blueprint.route('/account/register', methods=['GET']) @response(template_file='account/register.html') def register_get(): @@ -30,6 +31,7 @@ def register_post(): # ################### LOGIN ################################# + @blueprint.route('/account/login', methods=['GET']) @response(template_file='account/login.html') def login_get(): @@ -44,6 +46,7 @@ def login_post(): # ################### LOGOUT ################################# + @blueprint.route('/account/logout') def logout(): return {} diff --git a/app/ch08_adding_our_design/starter/pypi_org/views/cms_views.py b/app/ch08_adding_our_design/starter/pypi_org/views/cms_views.py index f7172d3d..a8b755a8 100644 --- a/app/ch08_adding_our_design/starter/pypi_org/views/cms_views.py +++ b/app/ch08_adding_our_design/starter/pypi_org/views/cms_views.py @@ -9,7 +9,7 @@ @blueprint.route('/') @response(template_file='cms/page.html') def cms_page(full_url: str): - print("Getting CMS page for {}".format(full_url)) + print('Getting CMS page for {}'.format(full_url)) page = cms_service.get_page(full_url) if not page: diff --git a/app/ch08_adding_our_design/starter/pypi_org/views/package_views.py b/app/ch08_adding_our_design/starter/pypi_org/views/package_views.py index ccf6bf12..7450fa1c 100644 --- a/app/ch08_adding_our_design/starter/pypi_org/views/package_views.py +++ b/app/ch08_adding_our_design/starter/pypi_org/views/package_views.py @@ -9,10 +9,10 @@ @blueprint.route('/project/') # @response(template_file='packages/details.html') def package_details(package_name: str): - return "Package details for {}".format(package_name) + return 'Package details for {}'.format(package_name) @blueprint.route('/') def popular(rank: int): print(type(rank), rank) - return "The details for the {}th most popular package".format(rank) + return 'The details for the {}th most popular package'.format(rank) diff --git a/app/ch09_sqlalchemy/final/pypi_org/app.py b/app/ch09_sqlalchemy/final/pypi_org/app.py index 4b39b374..0315d74a 100644 --- a/app/ch09_sqlalchemy/final/pypi_org/app.py +++ b/app/ch09_sqlalchemy/final/pypi_org/app.py @@ -1,6 +1,7 @@ import os import sys import flask + folder = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) sys.path.insert(0, folder) @@ -16,10 +17,7 @@ def main(): def setup_db(): - db_file = os.path.join( - os.path.dirname(__file__), - 'db', - 'pypi.sqlite') + db_file = os.path.join(os.path.dirname(__file__), 'db', 'pypi.sqlite') db_session.global_init(db_file) diff --git a/app/ch09_sqlalchemy/final/pypi_org/data/__all_models.py b/app/ch09_sqlalchemy/final/pypi_org/data/__all_models.py index 6c137449..1b24d092 100644 --- a/app/ch09_sqlalchemy/final/pypi_org/data/__all_models.py +++ b/app/ch09_sqlalchemy/final/pypi_org/data/__all_models.py @@ -5,15 +5,21 @@ # noinspection PyUnresolvedReferences import pypi_org.data.downloads + # noinspection PyUnresolvedReferences import pypi_org.data.languages + # noinspection PyUnresolvedReferences import pypi_org.data.licenses + # noinspection PyUnresolvedReferences import pypi_org.data.maintainers + # noinspection PyUnresolvedReferences import pypi_org.data.package + # noinspection PyUnresolvedReferences import pypi_org.data.releases + # noinspection PyUnresolvedReferences import pypi_org.data.users diff --git a/app/ch09_sqlalchemy/final/pypi_org/data/db_session.py b/app/ch09_sqlalchemy/final/pypi_org/data/db_session.py index e41bddc7..4a39c10f 100644 --- a/app/ch09_sqlalchemy/final/pypi_org/data/db_session.py +++ b/app/ch09_sqlalchemy/final/pypi_org/data/db_session.py @@ -13,15 +13,15 @@ def global_init(db_file: str): return if not db_file or not db_file.strip(): - raise Exception("You must specify a db file.") + raise Exception('You must specify a db file.') conn_str = 'sqlite:///' + db_file.strip() - print("Connecting to DB with {}".format(conn_str)) + print('Connecting to DB with {}'.format(conn_str)) # Adding check_same_thread = False after the recording. This can be an issue about # creating / owner thread when cleaning up sessions, etc. This is a sqlite restriction # that we probably don't care about in this example. - engine = sa.create_engine(conn_str, echo=False, connect_args={"check_same_thread": False}) + engine = sa.create_engine(conn_str, echo=False, connect_args={'check_same_thread': False}) factory = orm.sessionmaker(bind=engine) # noinspection PyUnresolvedReferences diff --git a/app/ch09_sqlalchemy/final/pypi_org/data/package.py b/app/ch09_sqlalchemy/final/pypi_org/data/package.py index d3806ea3..9b8a2ded 100644 --- a/app/ch09_sqlalchemy/final/pypi_org/data/package.py +++ b/app/ch09_sqlalchemy/final/pypi_org/data/package.py @@ -25,11 +25,15 @@ class Package(SqlAlchemyBase): license = sa.Column(sa.String, index=True) # releases relationship - releases: List[Release] = orm.relation("Release", order_by=[ - Release.major_ver.desc(), - Release.minor_ver.desc(), - Release.build_ver.desc(), - ], back_populates='package') + releases: List[Release] = orm.relation( + 'Release', + order_by=[ + Release.major_ver.desc(), + Release.minor_ver.desc(), + Release.build_ver.desc(), + ], + back_populates='package', + ) def __repr__(self): return ''.format(self.id) diff --git a/app/ch09_sqlalchemy/final/pypi_org/data/releases.py b/app/ch09_sqlalchemy/final/pypi_org/data/releases.py index 682fa08a..0faf1a8e 100644 --- a/app/ch09_sqlalchemy/final/pypi_org/data/releases.py +++ b/app/ch09_sqlalchemy/final/pypi_org/data/releases.py @@ -19,11 +19,9 @@ class Release(SqlAlchemyBase): size = sqlalchemy.Column(sqlalchemy.BigInteger) # Package relationship - package_id = sqlalchemy.Column(sqlalchemy.String, sqlalchemy.ForeignKey("packages.id")) + package_id = sqlalchemy.Column(sqlalchemy.String, sqlalchemy.ForeignKey('packages.id')) package = orm.relation('Package') @property def version_text(self): return '{}.{}.{}'.format(self.major_ver, self.minor_ver, self.build_ver) - - diff --git a/app/ch09_sqlalchemy/final/pypi_org/infrastructure/view_modifiers.py b/app/ch09_sqlalchemy/final/pypi_org/infrastructure/view_modifiers.py index 0978163e..d944c142 100644 --- a/app/ch09_sqlalchemy/final/pypi_org/infrastructure/view_modifiers.py +++ b/app/ch09_sqlalchemy/final/pypi_org/infrastructure/view_modifiers.py @@ -26,7 +26,8 @@ def view_method(*args, **kwargs): if template_file and not isinstance(response_val, dict): raise Exception( - "Invalid return type {}, we expected a dict as the return value.".format(type(response_val))) + 'Invalid return type {}, we expected a dict as the return value.'.format(type(response_val)) + ) if template_file: response_val = flask.render_template(template_file, **response_val) @@ -42,6 +43,7 @@ def view_method(*args, **kwargs): return response_inner + # # def template(template_file: str = None): # def template_inner(f): diff --git a/app/ch09_sqlalchemy/final/pypi_org/views/account_views.py b/app/ch09_sqlalchemy/final/pypi_org/views/account_views.py index 0421324a..55e5df41 100644 --- a/app/ch09_sqlalchemy/final/pypi_org/views/account_views.py +++ b/app/ch09_sqlalchemy/final/pypi_org/views/account_views.py @@ -16,6 +16,7 @@ def index(): # ################### REGISTER ################################# + @blueprint.route('/account/register', methods=['GET']) @response(template_file='account/register.html') def register_get(): @@ -30,6 +31,7 @@ def register_post(): # ################### LOGIN ################################# + @blueprint.route('/account/login', methods=['GET']) @response(template_file='account/login.html') def login_get(): @@ -44,6 +46,7 @@ def login_post(): # ################### LOGOUT ################################# + @blueprint.route('/account/logout') def logout(): return {} diff --git a/app/ch09_sqlalchemy/final/pypi_org/views/cms_views.py b/app/ch09_sqlalchemy/final/pypi_org/views/cms_views.py index f7172d3d..a8b755a8 100644 --- a/app/ch09_sqlalchemy/final/pypi_org/views/cms_views.py +++ b/app/ch09_sqlalchemy/final/pypi_org/views/cms_views.py @@ -9,7 +9,7 @@ @blueprint.route('/') @response(template_file='cms/page.html') def cms_page(full_url: str): - print("Getting CMS page for {}".format(full_url)) + print('Getting CMS page for {}'.format(full_url)) page = cms_service.get_page(full_url) if not page: diff --git a/app/ch09_sqlalchemy/final/pypi_org/views/package_views.py b/app/ch09_sqlalchemy/final/pypi_org/views/package_views.py index ccf6bf12..7450fa1c 100644 --- a/app/ch09_sqlalchemy/final/pypi_org/views/package_views.py +++ b/app/ch09_sqlalchemy/final/pypi_org/views/package_views.py @@ -9,10 +9,10 @@ @blueprint.route('/project/') # @response(template_file='packages/details.html') def package_details(package_name: str): - return "Package details for {}".format(package_name) + return 'Package details for {}'.format(package_name) @blueprint.route('/') def popular(rank: int): print(type(rank), rank) - return "The details for the {}th most popular package".format(rank) + return 'The details for the {}th most popular package'.format(rank) diff --git a/app/ch09_sqlalchemy/starter/pypi_org/app.py b/app/ch09_sqlalchemy/starter/pypi_org/app.py index 8b78c217..5ac0607d 100644 --- a/app/ch09_sqlalchemy/starter/pypi_org/app.py +++ b/app/ch09_sqlalchemy/starter/pypi_org/app.py @@ -1,6 +1,7 @@ import os import sys import flask + folder = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) sys.path.insert(0, folder) diff --git a/app/ch09_sqlalchemy/starter/pypi_org/infrastructure/view_modifiers.py b/app/ch09_sqlalchemy/starter/pypi_org/infrastructure/view_modifiers.py index 0978163e..d944c142 100644 --- a/app/ch09_sqlalchemy/starter/pypi_org/infrastructure/view_modifiers.py +++ b/app/ch09_sqlalchemy/starter/pypi_org/infrastructure/view_modifiers.py @@ -26,7 +26,8 @@ def view_method(*args, **kwargs): if template_file and not isinstance(response_val, dict): raise Exception( - "Invalid return type {}, we expected a dict as the return value.".format(type(response_val))) + 'Invalid return type {}, we expected a dict as the return value.'.format(type(response_val)) + ) if template_file: response_val = flask.render_template(template_file, **response_val) @@ -42,6 +43,7 @@ def view_method(*args, **kwargs): return response_inner + # # def template(template_file: str = None): # def template_inner(f): diff --git a/app/ch09_sqlalchemy/starter/pypi_org/views/account_views.py b/app/ch09_sqlalchemy/starter/pypi_org/views/account_views.py index 0421324a..55e5df41 100644 --- a/app/ch09_sqlalchemy/starter/pypi_org/views/account_views.py +++ b/app/ch09_sqlalchemy/starter/pypi_org/views/account_views.py @@ -16,6 +16,7 @@ def index(): # ################### REGISTER ################################# + @blueprint.route('/account/register', methods=['GET']) @response(template_file='account/register.html') def register_get(): @@ -30,6 +31,7 @@ def register_post(): # ################### LOGIN ################################# + @blueprint.route('/account/login', methods=['GET']) @response(template_file='account/login.html') def login_get(): @@ -44,6 +46,7 @@ def login_post(): # ################### LOGOUT ################################# + @blueprint.route('/account/logout') def logout(): return {} diff --git a/app/ch09_sqlalchemy/starter/pypi_org/views/cms_views.py b/app/ch09_sqlalchemy/starter/pypi_org/views/cms_views.py index f7172d3d..a8b755a8 100644 --- a/app/ch09_sqlalchemy/starter/pypi_org/views/cms_views.py +++ b/app/ch09_sqlalchemy/starter/pypi_org/views/cms_views.py @@ -9,7 +9,7 @@ @blueprint.route('/') @response(template_file='cms/page.html') def cms_page(full_url: str): - print("Getting CMS page for {}".format(full_url)) + print('Getting CMS page for {}'.format(full_url)) page = cms_service.get_page(full_url) if not page: diff --git a/app/ch09_sqlalchemy/starter/pypi_org/views/package_views.py b/app/ch09_sqlalchemy/starter/pypi_org/views/package_views.py index ccf6bf12..7450fa1c 100644 --- a/app/ch09_sqlalchemy/starter/pypi_org/views/package_views.py +++ b/app/ch09_sqlalchemy/starter/pypi_org/views/package_views.py @@ -9,10 +9,10 @@ @blueprint.route('/project/') # @response(template_file='packages/details.html') def package_details(package_name: str): - return "Package details for {}".format(package_name) + return 'Package details for {}'.format(package_name) @blueprint.route('/') def popular(rank: int): print(type(rank), rank) - return "The details for the {}th most popular package".format(rank) + return 'The details for the {}th most popular package'.format(rank) diff --git a/app/ch10_using_sqlachemy/final/pypi_org/app.py b/app/ch10_using_sqlachemy/final/pypi_org/app.py index 4b39b374..0315d74a 100644 --- a/app/ch10_using_sqlachemy/final/pypi_org/app.py +++ b/app/ch10_using_sqlachemy/final/pypi_org/app.py @@ -1,6 +1,7 @@ import os import sys import flask + folder = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) sys.path.insert(0, folder) @@ -16,10 +17,7 @@ def main(): def setup_db(): - db_file = os.path.join( - os.path.dirname(__file__), - 'db', - 'pypi.sqlite') + db_file = os.path.join(os.path.dirname(__file__), 'db', 'pypi.sqlite') db_session.global_init(db_file) diff --git a/app/ch10_using_sqlachemy/final/pypi_org/bin/basic_inserts.py b/app/ch10_using_sqlachemy/final/pypi_org/bin/basic_inserts.py index d622a6ae..6d04f551 100644 --- a/app/ch10_using_sqlachemy/final/pypi_org/bin/basic_inserts.py +++ b/app/ch10_using_sqlachemy/final/pypi_org/bin/basic_inserts.py @@ -2,8 +2,7 @@ import sys # Make it run more easily outside of PyCharm -sys.path.insert(0, os.path.abspath(os.path.join( - os.path.dirname(__file__), "..", ".."))) +sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..'))) import pypi_org.data.db_session as db_session from pypi_org.data.package import Package @@ -20,24 +19,24 @@ def insert_a_package(): p = Package() p.id = input('Package id / name: ').strip().lower() - p.summary = input("Package summary: ").strip() - p.author_name = input("Author: ").strip() - p.license = input("License: ").strip() + p.summary = input('Package summary: ').strip() + p.author_name = input('Author: ').strip() + p.license = input('License: ').strip() - print("Release 1:") + print('Release 1:') r = Release() - r.major_ver = int(input("Major version: ")) - r.minor_ver = int(input("Minor version: ")) - r.build_ver = int(input("Build version: ")) - r.size = int(input("Size in bytes: ")) + r.major_ver = int(input('Major version: ')) + r.minor_ver = int(input('Minor version: ')) + r.build_ver = int(input('Build version: ')) + r.size = int(input('Size in bytes: ')) p.releases.append(r) - print("Release 2:") + print('Release 2:') r = Release() - r.major_ver = int(input("Major version: ")) - r.minor_ver = int(input("Minor version: ")) - r.build_ver = int(input("Build version: ")) - r.size = int(input("Size in bytes: ")) + r.major_ver = int(input('Major version: ')) + r.minor_ver = int(input('Minor version: ')) + r.build_ver = int(input('Build version: ')) + r.size = int(input('Size in bytes: ')) p.releases.append(r) session = db_session.create_session() diff --git a/app/ch10_using_sqlachemy/final/pypi_org/bin/load_data.py b/app/ch10_using_sqlachemy/final/pypi_org/bin/load_data.py index 7f3cd4f8..74c45c15 100644 --- a/app/ch10_using_sqlachemy/final/pypi_org/bin/load_data.py +++ b/app/ch10_using_sqlachemy/final/pypi_org/bin/load_data.py @@ -10,8 +10,7 @@ from dateutil.parser import parse # Make sure we can import pypi_org.* -sys.path.insert(0, os.path.abspath(os.path.join( - os.path.dirname(__file__), "..", ".."))) +sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..'))) from pypi_org.infrastructure.num_convert import try_int import pypi_org.data.db_session as db_session @@ -43,7 +42,7 @@ def main(): def do_import_languages(file_data: List[dict]): imported = set() - print("Importing languages ... ", flush=True) + print('Importing languages ... ', flush=True) with progressbar.ProgressBar(max_value=len(file_data)) as bar: for idx, p in enumerate(file_data): info = p.get('info') @@ -78,7 +77,7 @@ def do_import_languages(file_data: List[dict]): def do_import_licenses(file_data: List[dict]): imported = set() - print("Importing licenses ... ", flush=True) + print('Importing licenses ... ', flush=True) with progressbar.ProgressBar(max_value=len(file_data)) as bar: for idx, p in enumerate(file_data): info = p.get('info') @@ -104,17 +103,17 @@ def do_import_licenses(file_data: List[dict]): def do_summary(): session = db_session.create_session() - print("Final numbers:") - print("Users: {:,}".format(session.query(User).count())) - print("Packages: {:,}".format(session.query(Package).count())) - print("Releases: {:,}".format(session.query(Release).count())) - print("Maintainers: {:,}".format(session.query(Maintainer).count())) - print("Languages: {:,}".format(session.query(ProgrammingLanguage).count())) - print("Licenses: {:,}".format(session.query(License).count())) + print('Final numbers:') + print('Users: {:,}'.format(session.query(User).count())) + print('Packages: {:,}'.format(session.query(Package).count())) + print('Releases: {:,}'.format(session.query(Release).count())) + print('Maintainers: {:,}'.format(session.query(Maintainer).count())) + print('Languages: {:,}'.format(session.query(ProgrammingLanguage).count())) + print('Licenses: {:,}'.format(session.query(License).count())) def do_user_import(user_lookup: Dict[str, str]) -> Dict[str, User]: - print("Importing users ... ", flush=True) + print('Importing users ... ', flush=True) with progressbar.ProgressBar(max_value=len(user_lookup)) as bar: for idx, (email, name) in enumerate(user_lookup.items()): session = db_session.create_session() @@ -138,29 +137,29 @@ def do_user_import(user_lookup: Dict[str, str]) -> Dict[str, User]: def do_import_packages(file_data: List[dict], user_lookup: Dict[str, User]): errored_packages = [] - print("Importing packages and releases ... ", flush=True) + print('Importing packages and releases ... ', flush=True) with progressbar.ProgressBar(max_value=len(file_data)) as bar: for idx, p in enumerate(file_data): try: load_package(p, user_lookup) bar.update(idx) except Exception as x: - errored_packages.append((p, " *** Errored out for package {}, {}".format(p.get('package_name'), x))) + errored_packages.append((p, ' *** Errored out for package {}, {}'.format(p.get('package_name'), x))) raise sys.stderr.flush() sys.stdout.flush() print() - print("Completed packages with {} errors.".format(len(errored_packages))) - for (p, txt) in errored_packages: + print('Completed packages with {} errors.'.format(len(errored_packages))) + for p, txt in errored_packages: print(txt) def do_load_files() -> List[dict]: data_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../../../data/pypi-top-100')) - print("Loading files from {}".format(data_path)) + print('Loading files from {}'.format(data_path)) files = get_file_names(data_path) - print("Found {:,} files, loading ...".format(len(files)), flush=True) - time.sleep(.1) + print('Found {:,} files, loading ...'.format(len(files)), flush=True) + time.sleep(0.1) file_data = [] with progressbar.ProgressBar(max_value=len(files)) as bar: @@ -175,7 +174,7 @@ def do_load_files() -> List[dict]: def find_users(data: List[dict]) -> dict: - print("Discovering users...", flush=True) + print('Discovering users...', flush=True) found_users = {} with progressbar.ProgressBar(max_value=len(data)) as bar: @@ -188,7 +187,7 @@ def find_users(data: List[dict]) -> dict: sys.stderr.flush() sys.stdout.flush() print() - print("Discovered {:,} users".format(len(found_users))) + print('Discovered {:,} users'.format(len(found_users))) print() return found_users @@ -219,7 +218,7 @@ def load_file_data(filename: str) -> dict: with open(filename, 'r', encoding='utf-8') as fin: data = json.load(fin) except Exception as x: - print("ERROR in file: {}, details: {}".format(filename, x), flush=True) + print('ERROR in file: {}, details: {}'.format(filename, x), flush=True) raise return data @@ -237,7 +236,7 @@ def load_package(data: dict, user_lookup: Dict[str, User]): p.author = info.get('author') p.author_email = info.get('author_email') - releases = build_releases(p.id, data.get("releases", {})) + releases = build_releases(p.id, data.get('releases', {})) if releases: p.created_date = releases[0].created_date @@ -287,18 +286,13 @@ def detect_license(license_text: str) -> Optional[str]: license_text = license_text.strip() if len(license_text) > 100 or '\n' in license_text: - return "CUSTOM" + return 'CUSTOM' - license_text = license_text \ - .replace('Software License', '') \ - .replace('License', '') + license_text = license_text.replace('Software License', '').replace('License', '') if '::' in license_text: # E.g. 'License :: OSI Approved :: Apache Software License' - return license_text \ - .split(':')[-1] \ - .replace(' ', ' ') \ - .strip() + return license_text.split(':')[-1].replace(' ', ' ').strip() return license_text.strip() @@ -354,9 +348,7 @@ def get_file_names(data_path: str) -> List[str]: files = [] for f in os.listdir(data_path): if f.endswith('.json'): - files.append( - os.path.abspath(os.path.join(data_path, f)) - ) + files.append(os.path.abspath(os.path.join(data_path, f))) files.sort() return files diff --git a/app/ch10_using_sqlachemy/final/pypi_org/data/__all_models.py b/app/ch10_using_sqlachemy/final/pypi_org/data/__all_models.py index 6c137449..1b24d092 100644 --- a/app/ch10_using_sqlachemy/final/pypi_org/data/__all_models.py +++ b/app/ch10_using_sqlachemy/final/pypi_org/data/__all_models.py @@ -5,15 +5,21 @@ # noinspection PyUnresolvedReferences import pypi_org.data.downloads + # noinspection PyUnresolvedReferences import pypi_org.data.languages + # noinspection PyUnresolvedReferences import pypi_org.data.licenses + # noinspection PyUnresolvedReferences import pypi_org.data.maintainers + # noinspection PyUnresolvedReferences import pypi_org.data.package + # noinspection PyUnresolvedReferences import pypi_org.data.releases + # noinspection PyUnresolvedReferences import pypi_org.data.users diff --git a/app/ch10_using_sqlachemy/final/pypi_org/data/db_session.py b/app/ch10_using_sqlachemy/final/pypi_org/data/db_session.py index addbaff9..62391b85 100644 --- a/app/ch10_using_sqlachemy/final/pypi_org/data/db_session.py +++ b/app/ch10_using_sqlachemy/final/pypi_org/data/db_session.py @@ -14,15 +14,15 @@ def global_init(db_file: str): return if not db_file or not db_file.strip(): - raise Exception("You must specify a db file.") + raise Exception('You must specify a db file.') conn_str = 'sqlite:///' + db_file.strip() - print("Connecting to DB with {}".format(conn_str)) + print('Connecting to DB with {}'.format(conn_str)) # Adding check_same_thread = False after the recording. This can be an issue about # creating / owner thread when cleaning up sessions, etc. This is a sqlite restriction # that we probably don't care about in this example. - engine = sa.create_engine(conn_str, echo=False, connect_args={"check_same_thread": False}) + engine = sa.create_engine(conn_str, echo=False, connect_args={'check_same_thread': False}) __factory = orm.sessionmaker(bind=engine) # noinspection PyUnresolvedReferences diff --git a/app/ch10_using_sqlachemy/final/pypi_org/data/downloads.py b/app/ch10_using_sqlachemy/final/pypi_org/data/downloads.py index 66068f02..dd8afd65 100644 --- a/app/ch10_using_sqlachemy/final/pypi_org/data/downloads.py +++ b/app/ch10_using_sqlachemy/final/pypi_org/data/downloads.py @@ -7,8 +7,7 @@ class Download(SqlAlchemyBase): __tablename__ = 'downloads' id: int = sqlalchemy.Column(sqlalchemy.BigInteger, primary_key=True, autoincrement=True) - created_date: datetime.datetime = sqlalchemy.Column( - sqlalchemy.DateTime, default=datetime.datetime.now, index=True) + created_date: datetime.datetime = sqlalchemy.Column(sqlalchemy.DateTime, default=datetime.datetime.now, index=True) package_id: str = sqlalchemy.Column(sqlalchemy.String, index=True) release_id: int = sqlalchemy.Column(sqlalchemy.BigInteger, index=True) diff --git a/app/ch10_using_sqlachemy/final/pypi_org/data/languages.py b/app/ch10_using_sqlachemy/final/pypi_org/data/languages.py index 964b8444..3a73dde0 100644 --- a/app/ch10_using_sqlachemy/final/pypi_org/data/languages.py +++ b/app/ch10_using_sqlachemy/final/pypi_org/data/languages.py @@ -7,6 +7,5 @@ class ProgrammingLanguage(SqlAlchemyBase): __tablename__ = 'languages' id: str = sqlalchemy.Column(sqlalchemy.String, primary_key=True) - created_date: datetime.datetime = sqlalchemy.Column( - sqlalchemy.DateTime, default=datetime.datetime.now, index=True) + created_date: datetime.datetime = sqlalchemy.Column(sqlalchemy.DateTime, default=datetime.datetime.now, index=True) description: str = sqlalchemy.Column(sqlalchemy.String) diff --git a/app/ch10_using_sqlachemy/final/pypi_org/data/package.py b/app/ch10_using_sqlachemy/final/pypi_org/data/package.py index 9e0dcecf..17fbf2f4 100644 --- a/app/ch10_using_sqlachemy/final/pypi_org/data/package.py +++ b/app/ch10_using_sqlachemy/final/pypi_org/data/package.py @@ -25,11 +25,15 @@ class Package(SqlAlchemyBase): license: str = sa.Column(sa.String, index=True) # releases relationship - releases: List[Release] = orm.relation("Release", order_by=[ - Release.major_ver.desc(), - Release.minor_ver.desc(), - Release.build_ver.desc(), - ], back_populates='package') + releases: List[Release] = orm.relation( + 'Release', + order_by=[ + Release.major_ver.desc(), + Release.minor_ver.desc(), + Release.build_ver.desc(), + ], + back_populates='package', + ) def __repr__(self): return ''.format(self.id) diff --git a/app/ch10_using_sqlachemy/final/pypi_org/data/releases.py b/app/ch10_using_sqlachemy/final/pypi_org/data/releases.py index 7650e438..8596f65c 100644 --- a/app/ch10_using_sqlachemy/final/pypi_org/data/releases.py +++ b/app/ch10_using_sqlachemy/final/pypi_org/data/releases.py @@ -13,15 +13,13 @@ class Release(SqlAlchemyBase): minor_ver: int = sqlalchemy.Column(sqlalchemy.BigInteger, index=True) build_ver: int = sqlalchemy.Column(sqlalchemy.BigInteger, index=True) - created_date: datetime.datetime = sqlalchemy.Column(sqlalchemy.DateTime, - default=datetime.datetime.now, - index=True) + created_date: datetime.datetime = sqlalchemy.Column(sqlalchemy.DateTime, default=datetime.datetime.now, index=True) comment: str = sqlalchemy.Column(sqlalchemy.String) url: str = sqlalchemy.Column(sqlalchemy.String) size: int = sqlalchemy.Column(sqlalchemy.BigInteger) # Package relationship - package_id: str = sqlalchemy.Column(sqlalchemy.String, sqlalchemy.ForeignKey("packages.id")) + package_id: str = sqlalchemy.Column(sqlalchemy.String, sqlalchemy.ForeignKey('packages.id')) package = orm.relation('Package') @property diff --git a/app/ch10_using_sqlachemy/final/pypi_org/infrastructure/view_modifiers.py b/app/ch10_using_sqlachemy/final/pypi_org/infrastructure/view_modifiers.py index 0978163e..d944c142 100644 --- a/app/ch10_using_sqlachemy/final/pypi_org/infrastructure/view_modifiers.py +++ b/app/ch10_using_sqlachemy/final/pypi_org/infrastructure/view_modifiers.py @@ -26,7 +26,8 @@ def view_method(*args, **kwargs): if template_file and not isinstance(response_val, dict): raise Exception( - "Invalid return type {}, we expected a dict as the return value.".format(type(response_val))) + 'Invalid return type {}, we expected a dict as the return value.'.format(type(response_val)) + ) if template_file: response_val = flask.render_template(template_file, **response_val) @@ -42,6 +43,7 @@ def view_method(*args, **kwargs): return response_inner + # # def template(template_file: str = None): # def template_inner(f): diff --git a/app/ch10_using_sqlachemy/final/pypi_org/services/package_service.py b/app/ch10_using_sqlachemy/final/pypi_org/services/package_service.py index e51241ae..6ac445e6 100644 --- a/app/ch10_using_sqlachemy/final/pypi_org/services/package_service.py +++ b/app/ch10_using_sqlachemy/final/pypi_org/services/package_service.py @@ -9,11 +9,13 @@ def get_latest_releases(limit=10) -> List[Release]: session = db_session.create_session() - releases = session.query(Release). \ - options(sqlalchemy.orm.joinedload(Release.package)). \ - order_by(Release.created_date.desc()). \ - limit(limit). \ - all() + releases = ( + session.query(Release) + .options(sqlalchemy.orm.joinedload(Release.package)) + .order_by(Release.created_date.desc()) + .limit(limit) + .all() + ) session.close() @@ -38,10 +40,12 @@ def get_package_by_id(package_id: str) -> Optional[Package]: session = db_session.create_session() - package = session.query(Package) \ - .options(sqlalchemy.orm.joinedload(Package.releases)) \ - .filter(Package.id == package_id) \ + package = ( + session.query(Package) + .options(sqlalchemy.orm.joinedload(Package.releases)) + .filter(Package.id == package_id) .first() + ) session.close() diff --git a/app/ch10_using_sqlachemy/final/pypi_org/views/account_views.py b/app/ch10_using_sqlachemy/final/pypi_org/views/account_views.py index 0421324a..55e5df41 100644 --- a/app/ch10_using_sqlachemy/final/pypi_org/views/account_views.py +++ b/app/ch10_using_sqlachemy/final/pypi_org/views/account_views.py @@ -16,6 +16,7 @@ def index(): # ################### REGISTER ################################# + @blueprint.route('/account/register', methods=['GET']) @response(template_file='account/register.html') def register_get(): @@ -30,6 +31,7 @@ def register_post(): # ################### LOGIN ################################# + @blueprint.route('/account/login', methods=['GET']) @response(template_file='account/login.html') def login_get(): @@ -44,6 +46,7 @@ def login_post(): # ################### LOGOUT ################################# + @blueprint.route('/account/logout') def logout(): return {} diff --git a/app/ch10_using_sqlachemy/final/pypi_org/views/cms_views.py b/app/ch10_using_sqlachemy/final/pypi_org/views/cms_views.py index f7172d3d..a8b755a8 100644 --- a/app/ch10_using_sqlachemy/final/pypi_org/views/cms_views.py +++ b/app/ch10_using_sqlachemy/final/pypi_org/views/cms_views.py @@ -9,7 +9,7 @@ @blueprint.route('/') @response(template_file='cms/page.html') def cms_page(full_url: str): - print("Getting CMS page for {}".format(full_url)) + print('Getting CMS page for {}'.format(full_url)) page = cms_service.get_page(full_url) if not page: diff --git a/app/ch10_using_sqlachemy/final/pypi_org/views/package_views.py b/app/ch10_using_sqlachemy/final/pypi_org/views/package_views.py index 70526f59..92d9109a 100644 --- a/app/ch10_using_sqlachemy/final/pypi_org/views/package_views.py +++ b/app/ch10_using_sqlachemy/final/pypi_org/views/package_views.py @@ -16,7 +16,7 @@ def package_details(package_name: str): if not package: return flask.abort(status=404) - latest_version = "0.0.0" + latest_version = '0.0.0' latest_release = None is_latest = True @@ -36,4 +36,4 @@ def package_details(package_name: str): @blueprint.route('/') def popular(rank: int): print(type(rank), rank) - return "The details for the {}th most popular package".format(rank) + return 'The details for the {}th most popular package'.format(rank) diff --git a/app/ch10_using_sqlachemy/starter/pypi_org/app.py b/app/ch10_using_sqlachemy/starter/pypi_org/app.py index 4b39b374..0315d74a 100644 --- a/app/ch10_using_sqlachemy/starter/pypi_org/app.py +++ b/app/ch10_using_sqlachemy/starter/pypi_org/app.py @@ -1,6 +1,7 @@ import os import sys import flask + folder = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) sys.path.insert(0, folder) @@ -16,10 +17,7 @@ def main(): def setup_db(): - db_file = os.path.join( - os.path.dirname(__file__), - 'db', - 'pypi.sqlite') + db_file = os.path.join(os.path.dirname(__file__), 'db', 'pypi.sqlite') db_session.global_init(db_file) diff --git a/app/ch10_using_sqlachemy/starter/pypi_org/data/__all_models.py b/app/ch10_using_sqlachemy/starter/pypi_org/data/__all_models.py index 6c137449..1b24d092 100644 --- a/app/ch10_using_sqlachemy/starter/pypi_org/data/__all_models.py +++ b/app/ch10_using_sqlachemy/starter/pypi_org/data/__all_models.py @@ -5,15 +5,21 @@ # noinspection PyUnresolvedReferences import pypi_org.data.downloads + # noinspection PyUnresolvedReferences import pypi_org.data.languages + # noinspection PyUnresolvedReferences import pypi_org.data.licenses + # noinspection PyUnresolvedReferences import pypi_org.data.maintainers + # noinspection PyUnresolvedReferences import pypi_org.data.package + # noinspection PyUnresolvedReferences import pypi_org.data.releases + # noinspection PyUnresolvedReferences import pypi_org.data.users diff --git a/app/ch10_using_sqlachemy/starter/pypi_org/data/db_session.py b/app/ch10_using_sqlachemy/starter/pypi_org/data/db_session.py index e41bddc7..4a39c10f 100644 --- a/app/ch10_using_sqlachemy/starter/pypi_org/data/db_session.py +++ b/app/ch10_using_sqlachemy/starter/pypi_org/data/db_session.py @@ -13,15 +13,15 @@ def global_init(db_file: str): return if not db_file or not db_file.strip(): - raise Exception("You must specify a db file.") + raise Exception('You must specify a db file.') conn_str = 'sqlite:///' + db_file.strip() - print("Connecting to DB with {}".format(conn_str)) + print('Connecting to DB with {}'.format(conn_str)) # Adding check_same_thread = False after the recording. This can be an issue about # creating / owner thread when cleaning up sessions, etc. This is a sqlite restriction # that we probably don't care about in this example. - engine = sa.create_engine(conn_str, echo=False, connect_args={"check_same_thread": False}) + engine = sa.create_engine(conn_str, echo=False, connect_args={'check_same_thread': False}) factory = orm.sessionmaker(bind=engine) # noinspection PyUnresolvedReferences diff --git a/app/ch10_using_sqlachemy/starter/pypi_org/data/package.py b/app/ch10_using_sqlachemy/starter/pypi_org/data/package.py index d3806ea3..9b8a2ded 100644 --- a/app/ch10_using_sqlachemy/starter/pypi_org/data/package.py +++ b/app/ch10_using_sqlachemy/starter/pypi_org/data/package.py @@ -25,11 +25,15 @@ class Package(SqlAlchemyBase): license = sa.Column(sa.String, index=True) # releases relationship - releases: List[Release] = orm.relation("Release", order_by=[ - Release.major_ver.desc(), - Release.minor_ver.desc(), - Release.build_ver.desc(), - ], back_populates='package') + releases: List[Release] = orm.relation( + 'Release', + order_by=[ + Release.major_ver.desc(), + Release.minor_ver.desc(), + Release.build_ver.desc(), + ], + back_populates='package', + ) def __repr__(self): return ''.format(self.id) diff --git a/app/ch10_using_sqlachemy/starter/pypi_org/data/releases.py b/app/ch10_using_sqlachemy/starter/pypi_org/data/releases.py index 682fa08a..0faf1a8e 100644 --- a/app/ch10_using_sqlachemy/starter/pypi_org/data/releases.py +++ b/app/ch10_using_sqlachemy/starter/pypi_org/data/releases.py @@ -19,11 +19,9 @@ class Release(SqlAlchemyBase): size = sqlalchemy.Column(sqlalchemy.BigInteger) # Package relationship - package_id = sqlalchemy.Column(sqlalchemy.String, sqlalchemy.ForeignKey("packages.id")) + package_id = sqlalchemy.Column(sqlalchemy.String, sqlalchemy.ForeignKey('packages.id')) package = orm.relation('Package') @property def version_text(self): return '{}.{}.{}'.format(self.major_ver, self.minor_ver, self.build_ver) - - diff --git a/app/ch10_using_sqlachemy/starter/pypi_org/infrastructure/view_modifiers.py b/app/ch10_using_sqlachemy/starter/pypi_org/infrastructure/view_modifiers.py index 0978163e..d944c142 100644 --- a/app/ch10_using_sqlachemy/starter/pypi_org/infrastructure/view_modifiers.py +++ b/app/ch10_using_sqlachemy/starter/pypi_org/infrastructure/view_modifiers.py @@ -26,7 +26,8 @@ def view_method(*args, **kwargs): if template_file and not isinstance(response_val, dict): raise Exception( - "Invalid return type {}, we expected a dict as the return value.".format(type(response_val))) + 'Invalid return type {}, we expected a dict as the return value.'.format(type(response_val)) + ) if template_file: response_val = flask.render_template(template_file, **response_val) @@ -42,6 +43,7 @@ def view_method(*args, **kwargs): return response_inner + # # def template(template_file: str = None): # def template_inner(f): diff --git a/app/ch10_using_sqlachemy/starter/pypi_org/views/account_views.py b/app/ch10_using_sqlachemy/starter/pypi_org/views/account_views.py index 0421324a..55e5df41 100644 --- a/app/ch10_using_sqlachemy/starter/pypi_org/views/account_views.py +++ b/app/ch10_using_sqlachemy/starter/pypi_org/views/account_views.py @@ -16,6 +16,7 @@ def index(): # ################### REGISTER ################################# + @blueprint.route('/account/register', methods=['GET']) @response(template_file='account/register.html') def register_get(): @@ -30,6 +31,7 @@ def register_post(): # ################### LOGIN ################################# + @blueprint.route('/account/login', methods=['GET']) @response(template_file='account/login.html') def login_get(): @@ -44,6 +46,7 @@ def login_post(): # ################### LOGOUT ################################# + @blueprint.route('/account/logout') def logout(): return {} diff --git a/app/ch10_using_sqlachemy/starter/pypi_org/views/cms_views.py b/app/ch10_using_sqlachemy/starter/pypi_org/views/cms_views.py index f7172d3d..a8b755a8 100644 --- a/app/ch10_using_sqlachemy/starter/pypi_org/views/cms_views.py +++ b/app/ch10_using_sqlachemy/starter/pypi_org/views/cms_views.py @@ -9,7 +9,7 @@ @blueprint.route('/') @response(template_file='cms/page.html') def cms_page(full_url: str): - print("Getting CMS page for {}".format(full_url)) + print('Getting CMS page for {}'.format(full_url)) page = cms_service.get_page(full_url) if not page: diff --git a/app/ch10_using_sqlachemy/starter/pypi_org/views/package_views.py b/app/ch10_using_sqlachemy/starter/pypi_org/views/package_views.py index ccf6bf12..7450fa1c 100644 --- a/app/ch10_using_sqlachemy/starter/pypi_org/views/package_views.py +++ b/app/ch10_using_sqlachemy/starter/pypi_org/views/package_views.py @@ -9,10 +9,10 @@ @blueprint.route('/project/') # @response(template_file='packages/details.html') def package_details(package_name: str): - return "Package details for {}".format(package_name) + return 'Package details for {}'.format(package_name) @blueprint.route('/') def popular(rank: int): print(type(rank), rank) - return "The details for the {}th most popular package".format(rank) + return 'The details for the {}th most popular package'.format(rank) diff --git a/app/ch11_migrations/final/alembic/alembic_helpers.py b/app/ch11_migrations/final/alembic/alembic_helpers.py index 561f7a70..6aea52d4 100644 --- a/app/ch11_migrations/final/alembic/alembic_helpers.py +++ b/app/ch11_migrations/final/alembic/alembic_helpers.py @@ -5,8 +5,7 @@ def table_has_column(table, column): config = op.get_context().config - engine = engine_from_config( - config.get_section(config.config_ini_section), prefix='sqlalchemy.') + engine = engine_from_config(config.get_section(config.config_ini_section), prefix='sqlalchemy.') insp = reflection.Inspector.from_engine(engine) has_column = False for col in insp.get_columns(table): diff --git a/app/ch11_migrations/final/alembic/env.py b/app/ch11_migrations/final/alembic/env.py index 27ec49fb..1fdc9cab 100644 --- a/app/ch11_migrations/final/alembic/env.py +++ b/app/ch11_migrations/final/alembic/env.py @@ -26,6 +26,7 @@ sys.path.insert(0, folder) from pypi_org.data.modelbase import SqlAlchemyBase + # noinspection PyUnresolvedReferences import pypi_org.data.__all_models @@ -49,10 +50,8 @@ def run_migrations_offline(): script output. """ - url = config.get_main_option("sqlalchemy.url") - context.configure( - url=url, target_metadata=target_metadata, literal_binds=True - ) + url = config.get_main_option('sqlalchemy.url') + context.configure(url=url, target_metadata=target_metadata, literal_binds=True) with context.begin_transaction(): context.run_migrations() @@ -67,14 +66,12 @@ def run_migrations_online(): """ connectable = engine_from_config( config.get_section(config.config_ini_section), - prefix="sqlalchemy.", + prefix='sqlalchemy.', poolclass=pool.NullPool, ) with connectable.connect() as connection: - context.configure( - connection=connection, target_metadata=target_metadata - ) + context.configure(connection=connection, target_metadata=target_metadata) with context.begin_transaction(): context.run_migrations() diff --git a/app/ch11_migrations/final/alembic/versions/722c82f0097c_added_auditing_table.py b/app/ch11_migrations/final/alembic/versions/722c82f0097c_added_auditing_table.py index 2c3e2a39..7c6e892f 100644 --- a/app/ch11_migrations/final/alembic/versions/722c82f0097c_added_auditing_table.py +++ b/app/ch11_migrations/final/alembic/versions/722c82f0097c_added_auditing_table.py @@ -18,11 +18,12 @@ def upgrade(): # ### commands auto generated by Alembic - please adjust! ### - op.create_table('auditing', - sa.Column('id', sa.String(), nullable=False), - sa.Column('created_date', sa.DateTime(), nullable=True), - sa.Column('description', sa.String(), nullable=True), - sa.PrimaryKeyConstraint('id') + op.create_table( + 'auditing', + sa.Column('id', sa.String(), nullable=False), + sa.Column('created_date', sa.DateTime(), nullable=True), + sa.Column('description', sa.String(), nullable=True), + sa.PrimaryKeyConstraint('id'), ) op.create_index(op.f('ix_auditing_created_date'), 'auditing', ['created_date'], unique=False) # ### end Alembic commands ### diff --git a/app/ch11_migrations/final/pypi_org/app.py b/app/ch11_migrations/final/pypi_org/app.py index 4b39b374..0315d74a 100644 --- a/app/ch11_migrations/final/pypi_org/app.py +++ b/app/ch11_migrations/final/pypi_org/app.py @@ -1,6 +1,7 @@ import os import sys import flask + folder = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) sys.path.insert(0, folder) @@ -16,10 +17,7 @@ def main(): def setup_db(): - db_file = os.path.join( - os.path.dirname(__file__), - 'db', - 'pypi.sqlite') + db_file = os.path.join(os.path.dirname(__file__), 'db', 'pypi.sqlite') db_session.global_init(db_file) diff --git a/app/ch11_migrations/final/pypi_org/bin/basic_inserts.py b/app/ch11_migrations/final/pypi_org/bin/basic_inserts.py index d622a6ae..6d04f551 100644 --- a/app/ch11_migrations/final/pypi_org/bin/basic_inserts.py +++ b/app/ch11_migrations/final/pypi_org/bin/basic_inserts.py @@ -2,8 +2,7 @@ import sys # Make it run more easily outside of PyCharm -sys.path.insert(0, os.path.abspath(os.path.join( - os.path.dirname(__file__), "..", ".."))) +sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..'))) import pypi_org.data.db_session as db_session from pypi_org.data.package import Package @@ -20,24 +19,24 @@ def insert_a_package(): p = Package() p.id = input('Package id / name: ').strip().lower() - p.summary = input("Package summary: ").strip() - p.author_name = input("Author: ").strip() - p.license = input("License: ").strip() + p.summary = input('Package summary: ').strip() + p.author_name = input('Author: ').strip() + p.license = input('License: ').strip() - print("Release 1:") + print('Release 1:') r = Release() - r.major_ver = int(input("Major version: ")) - r.minor_ver = int(input("Minor version: ")) - r.build_ver = int(input("Build version: ")) - r.size = int(input("Size in bytes: ")) + r.major_ver = int(input('Major version: ')) + r.minor_ver = int(input('Minor version: ')) + r.build_ver = int(input('Build version: ')) + r.size = int(input('Size in bytes: ')) p.releases.append(r) - print("Release 2:") + print('Release 2:') r = Release() - r.major_ver = int(input("Major version: ")) - r.minor_ver = int(input("Minor version: ")) - r.build_ver = int(input("Build version: ")) - r.size = int(input("Size in bytes: ")) + r.major_ver = int(input('Major version: ')) + r.minor_ver = int(input('Minor version: ')) + r.build_ver = int(input('Build version: ')) + r.size = int(input('Size in bytes: ')) p.releases.append(r) session = db_session.create_session() diff --git a/app/ch11_migrations/final/pypi_org/bin/load_data.py b/app/ch11_migrations/final/pypi_org/bin/load_data.py index 277a48f8..d64cb582 100644 --- a/app/ch11_migrations/final/pypi_org/bin/load_data.py +++ b/app/ch11_migrations/final/pypi_org/bin/load_data.py @@ -7,8 +7,7 @@ import progressbar from dateutil.parser import parse -sys.path.insert(0, os.path.abspath(os.path.join( - os.path.dirname(__file__), "..", ".."))) +sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..'))) from pypi_org.bin.load_data import try_int import pypi_org.data.db_session as db_session @@ -40,7 +39,7 @@ def main(): def do_import_languages(file_data: List[dict]): imported = set() - print("Importing languages ... ", flush=True) + print('Importing languages ... ', flush=True) with progressbar.ProgressBar(max_value=len(file_data)) as bar: for idx, p in enumerate(file_data): info = p.get('info') @@ -75,7 +74,7 @@ def do_import_languages(file_data: List[dict]): def do_import_licenses(file_data: List[dict]): imported = set() - print("Importing licenses ... ", flush=True) + print('Importing licenses ... ', flush=True) with progressbar.ProgressBar(max_value=len(file_data)) as bar: for idx, p in enumerate(file_data): info = p.get('info') @@ -101,17 +100,17 @@ def do_import_licenses(file_data: List[dict]): def do_summary(): session = db_session.create_session() - print("Final numbers:") - print("Users: {:,}".format(session.query(User).count())) - print("Packages: {:,}".format(session.query(Package).count())) - print("Releases: {:,}".format(session.query(Release).count())) - print("Maintainers: {:,}".format(session.query(Maintainer).count())) - print("Languages: {:,}".format(session.query(ProgrammingLanguage).count())) - print("Licenses: {:,}".format(session.query(License).count())) + print('Final numbers:') + print('Users: {:,}'.format(session.query(User).count())) + print('Packages: {:,}'.format(session.query(Package).count())) + print('Releases: {:,}'.format(session.query(Release).count())) + print('Maintainers: {:,}'.format(session.query(Maintainer).count())) + print('Languages: {:,}'.format(session.query(ProgrammingLanguage).count())) + print('Licenses: {:,}'.format(session.query(License).count())) def do_user_import(user_lookup: Dict[str, str]) -> Dict[str, User]: - print("Importing users ... ", flush=True) + print('Importing users ... ', flush=True) with progressbar.ProgressBar(max_value=len(user_lookup)) as bar: for idx, (email, name) in enumerate(user_lookup.items()): session = db_session.create_session() @@ -135,29 +134,29 @@ def do_user_import(user_lookup: Dict[str, str]) -> Dict[str, User]: def do_import_packages(file_data: List[dict], user_lookup: Dict[str, User]): errored_packages = [] - print("Importing packages and releases ... ", flush=True) + print('Importing packages and releases ... ', flush=True) with progressbar.ProgressBar(max_value=len(file_data)) as bar: for idx, p in enumerate(file_data): try: load_package(p, user_lookup) bar.update(idx) except Exception as x: - errored_packages.append((p, " *** Errored out for package {}, {}".format(p.get('package_name'), x))) + errored_packages.append((p, ' *** Errored out for package {}, {}'.format(p.get('package_name'), x))) raise sys.stderr.flush() sys.stdout.flush() print() - print("Completed packages with {} errors.".format(len(errored_packages))) - for (p, txt) in errored_packages: + print('Completed packages with {} errors.'.format(len(errored_packages))) + for p, txt in errored_packages: print(txt) def do_load_files() -> List[dict]: data_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../../../data/pypi-top-100')) - print("Loading files from {}".format(data_path)) + print('Loading files from {}'.format(data_path)) files = get_file_names(data_path) - print("Found {:,} files, loading ...".format(len(files)), flush=True) - time.sleep(.1) + print('Found {:,} files, loading ...'.format(len(files)), flush=True) + time.sleep(0.1) file_data = [] with progressbar.ProgressBar(max_value=len(files)) as bar: @@ -172,7 +171,7 @@ def do_load_files() -> List[dict]: def find_users(data: List[dict]) -> dict: - print("Discovering users...", flush=True) + print('Discovering users...', flush=True) found_users = {} with progressbar.ProgressBar(max_value=len(data)) as bar: @@ -185,7 +184,7 @@ def find_users(data: List[dict]) -> dict: sys.stderr.flush() sys.stdout.flush() print() - print("Discovered {:,} users".format(len(found_users))) + print('Discovered {:,} users'.format(len(found_users))) print() return found_users @@ -216,7 +215,7 @@ def load_file_data(filename: str) -> dict: with open(filename, 'r', encoding='utf-8') as fin: data = json.load(fin) except Exception as x: - print("ERROR in file: {}, details: {}".format(filename, x), flush=True) + print('ERROR in file: {}, details: {}'.format(filename, x), flush=True) raise return data @@ -234,7 +233,7 @@ def load_package(data: dict, user_lookup: Dict[str, User]): p.author = info.get('author') p.author_email = info.get('author_email') - releases = build_releases(p.id, data.get("releases", {})) + releases = build_releases(p.id, data.get('releases', {})) if releases: p.created_date = releases[0].created_date @@ -284,18 +283,13 @@ def detect_license(license_text: str) -> Optional[str]: license_text = license_text.strip() if len(license_text) > 100 or '\n' in license_text: - return "CUSTOM" + return 'CUSTOM' - license_text = license_text \ - .replace('Software License', '') \ - .replace('License', '') + license_text = license_text.replace('Software License', '').replace('License', '') if '::' in license_text: # E.g. 'License :: OSI Approved :: Apache Software License' - return license_text \ - .split(':')[-1] \ - .replace(' ', ' ') \ - .strip() + return license_text.split(':')[-1].replace(' ', ' ').strip() return license_text.strip() @@ -351,9 +345,7 @@ def get_file_names(data_path: str) -> List[str]: files = [] for f in os.listdir(data_path): if f.endswith('.json'): - files.append( - os.path.abspath(os.path.join(data_path, f)) - ) + files.append(os.path.abspath(os.path.join(data_path, f))) files.sort() return files diff --git a/app/ch11_migrations/final/pypi_org/data/__all_models.py b/app/ch11_migrations/final/pypi_org/data/__all_models.py index f399ef54..ca4804ac 100644 --- a/app/ch11_migrations/final/pypi_org/data/__all_models.py +++ b/app/ch11_migrations/final/pypi_org/data/__all_models.py @@ -5,17 +5,24 @@ # noinspection PyUnresolvedReferences import pypi_org.data.audit + # noinspection PyUnresolvedReferences import pypi_org.data.downloads + # noinspection PyUnresolvedReferences import pypi_org.data.languages + # noinspection PyUnresolvedReferences import pypi_org.data.licenses + # noinspection PyUnresolvedReferences import pypi_org.data.maintainers + # noinspection PyUnresolvedReferences import pypi_org.data.package + # noinspection PyUnresolvedReferences import pypi_org.data.releases + # noinspection PyUnresolvedReferences import pypi_org.data.users diff --git a/app/ch11_migrations/final/pypi_org/data/db_session.py b/app/ch11_migrations/final/pypi_org/data/db_session.py index addbaff9..62391b85 100644 --- a/app/ch11_migrations/final/pypi_org/data/db_session.py +++ b/app/ch11_migrations/final/pypi_org/data/db_session.py @@ -14,15 +14,15 @@ def global_init(db_file: str): return if not db_file or not db_file.strip(): - raise Exception("You must specify a db file.") + raise Exception('You must specify a db file.') conn_str = 'sqlite:///' + db_file.strip() - print("Connecting to DB with {}".format(conn_str)) + print('Connecting to DB with {}'.format(conn_str)) # Adding check_same_thread = False after the recording. This can be an issue about # creating / owner thread when cleaning up sessions, etc. This is a sqlite restriction # that we probably don't care about in this example. - engine = sa.create_engine(conn_str, echo=False, connect_args={"check_same_thread": False}) + engine = sa.create_engine(conn_str, echo=False, connect_args={'check_same_thread': False}) __factory = orm.sessionmaker(bind=engine) # noinspection PyUnresolvedReferences diff --git a/app/ch11_migrations/final/pypi_org/data/downloads.py b/app/ch11_migrations/final/pypi_org/data/downloads.py index 66068f02..dd8afd65 100644 --- a/app/ch11_migrations/final/pypi_org/data/downloads.py +++ b/app/ch11_migrations/final/pypi_org/data/downloads.py @@ -7,8 +7,7 @@ class Download(SqlAlchemyBase): __tablename__ = 'downloads' id: int = sqlalchemy.Column(sqlalchemy.BigInteger, primary_key=True, autoincrement=True) - created_date: datetime.datetime = sqlalchemy.Column( - sqlalchemy.DateTime, default=datetime.datetime.now, index=True) + created_date: datetime.datetime = sqlalchemy.Column(sqlalchemy.DateTime, default=datetime.datetime.now, index=True) package_id: str = sqlalchemy.Column(sqlalchemy.String, index=True) release_id: int = sqlalchemy.Column(sqlalchemy.BigInteger, index=True) diff --git a/app/ch11_migrations/final/pypi_org/data/languages.py b/app/ch11_migrations/final/pypi_org/data/languages.py index 964b8444..3a73dde0 100644 --- a/app/ch11_migrations/final/pypi_org/data/languages.py +++ b/app/ch11_migrations/final/pypi_org/data/languages.py @@ -7,6 +7,5 @@ class ProgrammingLanguage(SqlAlchemyBase): __tablename__ = 'languages' id: str = sqlalchemy.Column(sqlalchemy.String, primary_key=True) - created_date: datetime.datetime = sqlalchemy.Column( - sqlalchemy.DateTime, default=datetime.datetime.now, index=True) + created_date: datetime.datetime = sqlalchemy.Column(sqlalchemy.DateTime, default=datetime.datetime.now, index=True) description: str = sqlalchemy.Column(sqlalchemy.String) diff --git a/app/ch11_migrations/final/pypi_org/data/package.py b/app/ch11_migrations/final/pypi_org/data/package.py index c3420d1b..16e6d156 100644 --- a/app/ch11_migrations/final/pypi_org/data/package.py +++ b/app/ch11_migrations/final/pypi_org/data/package.py @@ -26,11 +26,15 @@ class Package(SqlAlchemyBase): license: str = sa.Column(sa.String, index=True) # releases relationship - releases: List[Release] = orm.relation("Release", order_by=[ - Release.major_ver.desc(), - Release.minor_ver.desc(), - Release.build_ver.desc(), - ], back_populates='package') + releases: List[Release] = orm.relation( + 'Release', + order_by=[ + Release.major_ver.desc(), + Release.minor_ver.desc(), + Release.build_ver.desc(), + ], + back_populates='package', + ) def __repr__(self): return ''.format(self.id) diff --git a/app/ch11_migrations/final/pypi_org/data/releases.py b/app/ch11_migrations/final/pypi_org/data/releases.py index 7650e438..8596f65c 100644 --- a/app/ch11_migrations/final/pypi_org/data/releases.py +++ b/app/ch11_migrations/final/pypi_org/data/releases.py @@ -13,15 +13,13 @@ class Release(SqlAlchemyBase): minor_ver: int = sqlalchemy.Column(sqlalchemy.BigInteger, index=True) build_ver: int = sqlalchemy.Column(sqlalchemy.BigInteger, index=True) - created_date: datetime.datetime = sqlalchemy.Column(sqlalchemy.DateTime, - default=datetime.datetime.now, - index=True) + created_date: datetime.datetime = sqlalchemy.Column(sqlalchemy.DateTime, default=datetime.datetime.now, index=True) comment: str = sqlalchemy.Column(sqlalchemy.String) url: str = sqlalchemy.Column(sqlalchemy.String) size: int = sqlalchemy.Column(sqlalchemy.BigInteger) # Package relationship - package_id: str = sqlalchemy.Column(sqlalchemy.String, sqlalchemy.ForeignKey("packages.id")) + package_id: str = sqlalchemy.Column(sqlalchemy.String, sqlalchemy.ForeignKey('packages.id')) package = orm.relation('Package') @property diff --git a/app/ch11_migrations/final/pypi_org/infrastructure/view_modifiers.py b/app/ch11_migrations/final/pypi_org/infrastructure/view_modifiers.py index 0c0941eb..d944c142 100644 --- a/app/ch11_migrations/final/pypi_org/infrastructure/view_modifiers.py +++ b/app/ch11_migrations/final/pypi_org/infrastructure/view_modifiers.py @@ -26,7 +26,8 @@ def view_method(*args, **kwargs): if template_file and not isinstance(response_val, dict): raise Exception( - "Invalid return type {}, we expected a dict as the return value.".format(type(response_val))) + 'Invalid return type {}, we expected a dict as the return value.'.format(type(response_val)) + ) if template_file: response_val = flask.render_template(template_file, **response_val) diff --git a/app/ch11_migrations/final/pypi_org/services/package_service.py b/app/ch11_migrations/final/pypi_org/services/package_service.py index e51241ae..6ac445e6 100644 --- a/app/ch11_migrations/final/pypi_org/services/package_service.py +++ b/app/ch11_migrations/final/pypi_org/services/package_service.py @@ -9,11 +9,13 @@ def get_latest_releases(limit=10) -> List[Release]: session = db_session.create_session() - releases = session.query(Release). \ - options(sqlalchemy.orm.joinedload(Release.package)). \ - order_by(Release.created_date.desc()). \ - limit(limit). \ - all() + releases = ( + session.query(Release) + .options(sqlalchemy.orm.joinedload(Release.package)) + .order_by(Release.created_date.desc()) + .limit(limit) + .all() + ) session.close() @@ -38,10 +40,12 @@ def get_package_by_id(package_id: str) -> Optional[Package]: session = db_session.create_session() - package = session.query(Package) \ - .options(sqlalchemy.orm.joinedload(Package.releases)) \ - .filter(Package.id == package_id) \ + package = ( + session.query(Package) + .options(sqlalchemy.orm.joinedload(Package.releases)) + .filter(Package.id == package_id) .first() + ) session.close() diff --git a/app/ch11_migrations/final/pypi_org/views/account_views.py b/app/ch11_migrations/final/pypi_org/views/account_views.py index 0421324a..55e5df41 100644 --- a/app/ch11_migrations/final/pypi_org/views/account_views.py +++ b/app/ch11_migrations/final/pypi_org/views/account_views.py @@ -16,6 +16,7 @@ def index(): # ################### REGISTER ################################# + @blueprint.route('/account/register', methods=['GET']) @response(template_file='account/register.html') def register_get(): @@ -30,6 +31,7 @@ def register_post(): # ################### LOGIN ################################# + @blueprint.route('/account/login', methods=['GET']) @response(template_file='account/login.html') def login_get(): @@ -44,6 +46,7 @@ def login_post(): # ################### LOGOUT ################################# + @blueprint.route('/account/logout') def logout(): return {} diff --git a/app/ch11_migrations/final/pypi_org/views/cms_views.py b/app/ch11_migrations/final/pypi_org/views/cms_views.py index f7172d3d..a8b755a8 100644 --- a/app/ch11_migrations/final/pypi_org/views/cms_views.py +++ b/app/ch11_migrations/final/pypi_org/views/cms_views.py @@ -9,7 +9,7 @@ @blueprint.route('/') @response(template_file='cms/page.html') def cms_page(full_url: str): - print("Getting CMS page for {}".format(full_url)) + print('Getting CMS page for {}'.format(full_url)) page = cms_service.get_page(full_url) if not page: diff --git a/app/ch11_migrations/final/pypi_org/views/package_views.py b/app/ch11_migrations/final/pypi_org/views/package_views.py index 70526f59..92d9109a 100644 --- a/app/ch11_migrations/final/pypi_org/views/package_views.py +++ b/app/ch11_migrations/final/pypi_org/views/package_views.py @@ -16,7 +16,7 @@ def package_details(package_name: str): if not package: return flask.abort(status=404) - latest_version = "0.0.0" + latest_version = '0.0.0' latest_release = None is_latest = True @@ -36,4 +36,4 @@ def package_details(package_name: str): @blueprint.route('/') def popular(rank: int): print(type(rank), rank) - return "The details for the {}th most popular package".format(rank) + return 'The details for the {}th most popular package'.format(rank) diff --git a/app/ch11_migrations/starter/pypi_org/app.py b/app/ch11_migrations/starter/pypi_org/app.py index 4b39b374..0315d74a 100644 --- a/app/ch11_migrations/starter/pypi_org/app.py +++ b/app/ch11_migrations/starter/pypi_org/app.py @@ -1,6 +1,7 @@ import os import sys import flask + folder = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) sys.path.insert(0, folder) @@ -16,10 +17,7 @@ def main(): def setup_db(): - db_file = os.path.join( - os.path.dirname(__file__), - 'db', - 'pypi.sqlite') + db_file = os.path.join(os.path.dirname(__file__), 'db', 'pypi.sqlite') db_session.global_init(db_file) diff --git a/app/ch11_migrations/starter/pypi_org/bin/basic_inserts.py b/app/ch11_migrations/starter/pypi_org/bin/basic_inserts.py index d622a6ae..6d04f551 100644 --- a/app/ch11_migrations/starter/pypi_org/bin/basic_inserts.py +++ b/app/ch11_migrations/starter/pypi_org/bin/basic_inserts.py @@ -2,8 +2,7 @@ import sys # Make it run more easily outside of PyCharm -sys.path.insert(0, os.path.abspath(os.path.join( - os.path.dirname(__file__), "..", ".."))) +sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..'))) import pypi_org.data.db_session as db_session from pypi_org.data.package import Package @@ -20,24 +19,24 @@ def insert_a_package(): p = Package() p.id = input('Package id / name: ').strip().lower() - p.summary = input("Package summary: ").strip() - p.author_name = input("Author: ").strip() - p.license = input("License: ").strip() + p.summary = input('Package summary: ').strip() + p.author_name = input('Author: ').strip() + p.license = input('License: ').strip() - print("Release 1:") + print('Release 1:') r = Release() - r.major_ver = int(input("Major version: ")) - r.minor_ver = int(input("Minor version: ")) - r.build_ver = int(input("Build version: ")) - r.size = int(input("Size in bytes: ")) + r.major_ver = int(input('Major version: ')) + r.minor_ver = int(input('Minor version: ')) + r.build_ver = int(input('Build version: ')) + r.size = int(input('Size in bytes: ')) p.releases.append(r) - print("Release 2:") + print('Release 2:') r = Release() - r.major_ver = int(input("Major version: ")) - r.minor_ver = int(input("Minor version: ")) - r.build_ver = int(input("Build version: ")) - r.size = int(input("Size in bytes: ")) + r.major_ver = int(input('Major version: ')) + r.minor_ver = int(input('Minor version: ')) + r.build_ver = int(input('Build version: ')) + r.size = int(input('Size in bytes: ')) p.releases.append(r) session = db_session.create_session() diff --git a/app/ch11_migrations/starter/pypi_org/bin/load_data.py b/app/ch11_migrations/starter/pypi_org/bin/load_data.py index ba62ff7d..3af7a03d 100644 --- a/app/ch11_migrations/starter/pypi_org/bin/load_data.py +++ b/app/ch11_migrations/starter/pypi_org/bin/load_data.py @@ -7,8 +7,7 @@ import progressbar from dateutil.parser import parse -sys.path.insert(0, os.path.abspath(os.path.join( - os.path.dirname(__file__), "..", ".."))) +sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..'))) from pypi_org.infrastructure.num_convert import try_int import pypi_org.data.db_session as db_session @@ -40,7 +39,7 @@ def main(): def do_import_languages(file_data: List[dict]): imported = set() - print("Importing languages ... ", flush=True) + print('Importing languages ... ', flush=True) with progressbar.ProgressBar(max_value=len(file_data)) as bar: for idx, p in enumerate(file_data): info = p.get('info') @@ -75,7 +74,7 @@ def do_import_languages(file_data: List[dict]): def do_import_licenses(file_data: List[dict]): imported = set() - print("Importing licenses ... ", flush=True) + print('Importing licenses ... ', flush=True) with progressbar.ProgressBar(max_value=len(file_data)) as bar: for idx, p in enumerate(file_data): info = p.get('info') @@ -101,17 +100,17 @@ def do_import_licenses(file_data: List[dict]): def do_summary(): session = db_session.create_session() - print("Final numbers:") - print("Users: {:,}".format(session.query(User).count())) - print("Packages: {:,}".format(session.query(Package).count())) - print("Releases: {:,}".format(session.query(Release).count())) - print("Maintainers: {:,}".format(session.query(Maintainer).count())) - print("Languages: {:,}".format(session.query(ProgrammingLanguage).count())) - print("Licenses: {:,}".format(session.query(License).count())) + print('Final numbers:') + print('Users: {:,}'.format(session.query(User).count())) + print('Packages: {:,}'.format(session.query(Package).count())) + print('Releases: {:,}'.format(session.query(Release).count())) + print('Maintainers: {:,}'.format(session.query(Maintainer).count())) + print('Languages: {:,}'.format(session.query(ProgrammingLanguage).count())) + print('Licenses: {:,}'.format(session.query(License).count())) def do_user_import(user_lookup: Dict[str, str]) -> Dict[str, User]: - print("Importing users ... ", flush=True) + print('Importing users ... ', flush=True) with progressbar.ProgressBar(max_value=len(user_lookup)) as bar: for idx, (email, name) in enumerate(user_lookup.items()): session = db_session.create_session() @@ -135,29 +134,29 @@ def do_user_import(user_lookup: Dict[str, str]) -> Dict[str, User]: def do_import_packages(file_data: List[dict], user_lookup: Dict[str, User]): errored_packages = [] - print("Importing packages and releases ... ", flush=True) + print('Importing packages and releases ... ', flush=True) with progressbar.ProgressBar(max_value=len(file_data)) as bar: for idx, p in enumerate(file_data): try: load_package(p, user_lookup) bar.update(idx) except Exception as x: - errored_packages.append((p, " *** Errored out for package {}, {}".format(p.get('package_name'), x))) + errored_packages.append((p, ' *** Errored out for package {}, {}'.format(p.get('package_name'), x))) raise sys.stderr.flush() sys.stdout.flush() print() - print("Completed packages with {} errors.".format(len(errored_packages))) - for (p, txt) in errored_packages: + print('Completed packages with {} errors.'.format(len(errored_packages))) + for p, txt in errored_packages: print(txt) def do_load_files() -> List[dict]: data_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../../../data/pypi-top-100')) - print("Loading files from {}".format(data_path)) + print('Loading files from {}'.format(data_path)) files = get_file_names(data_path) - print("Found {:,} files, loading ...".format(len(files)), flush=True) - time.sleep(.1) + print('Found {:,} files, loading ...'.format(len(files)), flush=True) + time.sleep(0.1) file_data = [] with progressbar.ProgressBar(max_value=len(files)) as bar: @@ -172,7 +171,7 @@ def do_load_files() -> List[dict]: def find_users(data: List[dict]) -> dict: - print("Discovering users...", flush=True) + print('Discovering users...', flush=True) found_users = {} with progressbar.ProgressBar(max_value=len(data)) as bar: @@ -185,7 +184,7 @@ def find_users(data: List[dict]) -> dict: sys.stderr.flush() sys.stdout.flush() print() - print("Discovered {:,} users".format(len(found_users))) + print('Discovered {:,} users'.format(len(found_users))) print() return found_users @@ -216,7 +215,7 @@ def load_file_data(filename: str) -> dict: with open(filename, 'r', encoding='utf-8') as fin: data = json.load(fin) except Exception as x: - print("ERROR in file: {}, details: {}".format(filename, x), flush=True) + print('ERROR in file: {}, details: {}'.format(filename, x), flush=True) raise return data @@ -234,7 +233,7 @@ def load_package(data: dict, user_lookup: Dict[str, User]): p.author = info.get('author') p.author_email = info.get('author_email') - releases = build_releases(p.id, data.get("releases", {})) + releases = build_releases(p.id, data.get('releases', {})) if releases: p.created_date = releases[0].created_date @@ -284,18 +283,13 @@ def detect_license(license_text: str) -> Optional[str]: license_text = license_text.strip() if len(license_text) > 100 or '\n' in license_text: - return "CUSTOM" + return 'CUSTOM' - license_text = license_text \ - .replace('Software License', '') \ - .replace('License', '') + license_text = license_text.replace('Software License', '').replace('License', '') if '::' in license_text: # E.g. 'License :: OSI Approved :: Apache Software License' - return license_text \ - .split(':')[-1] \ - .replace(' ', ' ') \ - .strip() + return license_text.split(':')[-1].replace(' ', ' ').strip() return license_text.strip() @@ -351,9 +345,7 @@ def get_file_names(data_path: str) -> List[str]: files = [] for f in os.listdir(data_path): if f.endswith('.json'): - files.append( - os.path.abspath(os.path.join(data_path, f)) - ) + files.append(os.path.abspath(os.path.join(data_path, f))) files.sort() return files diff --git a/app/ch11_migrations/starter/pypi_org/data/__all_models.py b/app/ch11_migrations/starter/pypi_org/data/__all_models.py index 6c137449..1b24d092 100644 --- a/app/ch11_migrations/starter/pypi_org/data/__all_models.py +++ b/app/ch11_migrations/starter/pypi_org/data/__all_models.py @@ -5,15 +5,21 @@ # noinspection PyUnresolvedReferences import pypi_org.data.downloads + # noinspection PyUnresolvedReferences import pypi_org.data.languages + # noinspection PyUnresolvedReferences import pypi_org.data.licenses + # noinspection PyUnresolvedReferences import pypi_org.data.maintainers + # noinspection PyUnresolvedReferences import pypi_org.data.package + # noinspection PyUnresolvedReferences import pypi_org.data.releases + # noinspection PyUnresolvedReferences import pypi_org.data.users diff --git a/app/ch11_migrations/starter/pypi_org/data/db_session.py b/app/ch11_migrations/starter/pypi_org/data/db_session.py index addbaff9..62391b85 100644 --- a/app/ch11_migrations/starter/pypi_org/data/db_session.py +++ b/app/ch11_migrations/starter/pypi_org/data/db_session.py @@ -14,15 +14,15 @@ def global_init(db_file: str): return if not db_file or not db_file.strip(): - raise Exception("You must specify a db file.") + raise Exception('You must specify a db file.') conn_str = 'sqlite:///' + db_file.strip() - print("Connecting to DB with {}".format(conn_str)) + print('Connecting to DB with {}'.format(conn_str)) # Adding check_same_thread = False after the recording. This can be an issue about # creating / owner thread when cleaning up sessions, etc. This is a sqlite restriction # that we probably don't care about in this example. - engine = sa.create_engine(conn_str, echo=False, connect_args={"check_same_thread": False}) + engine = sa.create_engine(conn_str, echo=False, connect_args={'check_same_thread': False}) __factory = orm.sessionmaker(bind=engine) # noinspection PyUnresolvedReferences diff --git a/app/ch11_migrations/starter/pypi_org/data/downloads.py b/app/ch11_migrations/starter/pypi_org/data/downloads.py index 66068f02..dd8afd65 100644 --- a/app/ch11_migrations/starter/pypi_org/data/downloads.py +++ b/app/ch11_migrations/starter/pypi_org/data/downloads.py @@ -7,8 +7,7 @@ class Download(SqlAlchemyBase): __tablename__ = 'downloads' id: int = sqlalchemy.Column(sqlalchemy.BigInteger, primary_key=True, autoincrement=True) - created_date: datetime.datetime = sqlalchemy.Column( - sqlalchemy.DateTime, default=datetime.datetime.now, index=True) + created_date: datetime.datetime = sqlalchemy.Column(sqlalchemy.DateTime, default=datetime.datetime.now, index=True) package_id: str = sqlalchemy.Column(sqlalchemy.String, index=True) release_id: int = sqlalchemy.Column(sqlalchemy.BigInteger, index=True) diff --git a/app/ch11_migrations/starter/pypi_org/data/languages.py b/app/ch11_migrations/starter/pypi_org/data/languages.py index 964b8444..3a73dde0 100644 --- a/app/ch11_migrations/starter/pypi_org/data/languages.py +++ b/app/ch11_migrations/starter/pypi_org/data/languages.py @@ -7,6 +7,5 @@ class ProgrammingLanguage(SqlAlchemyBase): __tablename__ = 'languages' id: str = sqlalchemy.Column(sqlalchemy.String, primary_key=True) - created_date: datetime.datetime = sqlalchemy.Column( - sqlalchemy.DateTime, default=datetime.datetime.now, index=True) + created_date: datetime.datetime = sqlalchemy.Column(sqlalchemy.DateTime, default=datetime.datetime.now, index=True) description: str = sqlalchemy.Column(sqlalchemy.String) diff --git a/app/ch11_migrations/starter/pypi_org/data/package.py b/app/ch11_migrations/starter/pypi_org/data/package.py index 9e0dcecf..17fbf2f4 100644 --- a/app/ch11_migrations/starter/pypi_org/data/package.py +++ b/app/ch11_migrations/starter/pypi_org/data/package.py @@ -25,11 +25,15 @@ class Package(SqlAlchemyBase): license: str = sa.Column(sa.String, index=True) # releases relationship - releases: List[Release] = orm.relation("Release", order_by=[ - Release.major_ver.desc(), - Release.minor_ver.desc(), - Release.build_ver.desc(), - ], back_populates='package') + releases: List[Release] = orm.relation( + 'Release', + order_by=[ + Release.major_ver.desc(), + Release.minor_ver.desc(), + Release.build_ver.desc(), + ], + back_populates='package', + ) def __repr__(self): return ''.format(self.id) diff --git a/app/ch11_migrations/starter/pypi_org/data/releases.py b/app/ch11_migrations/starter/pypi_org/data/releases.py index 7650e438..8596f65c 100644 --- a/app/ch11_migrations/starter/pypi_org/data/releases.py +++ b/app/ch11_migrations/starter/pypi_org/data/releases.py @@ -13,15 +13,13 @@ class Release(SqlAlchemyBase): minor_ver: int = sqlalchemy.Column(sqlalchemy.BigInteger, index=True) build_ver: int = sqlalchemy.Column(sqlalchemy.BigInteger, index=True) - created_date: datetime.datetime = sqlalchemy.Column(sqlalchemy.DateTime, - default=datetime.datetime.now, - index=True) + created_date: datetime.datetime = sqlalchemy.Column(sqlalchemy.DateTime, default=datetime.datetime.now, index=True) comment: str = sqlalchemy.Column(sqlalchemy.String) url: str = sqlalchemy.Column(sqlalchemy.String) size: int = sqlalchemy.Column(sqlalchemy.BigInteger) # Package relationship - package_id: str = sqlalchemy.Column(sqlalchemy.String, sqlalchemy.ForeignKey("packages.id")) + package_id: str = sqlalchemy.Column(sqlalchemy.String, sqlalchemy.ForeignKey('packages.id')) package = orm.relation('Package') @property diff --git a/app/ch11_migrations/starter/pypi_org/infrastructure/view_modifiers.py b/app/ch11_migrations/starter/pypi_org/infrastructure/view_modifiers.py index 0978163e..d944c142 100644 --- a/app/ch11_migrations/starter/pypi_org/infrastructure/view_modifiers.py +++ b/app/ch11_migrations/starter/pypi_org/infrastructure/view_modifiers.py @@ -26,7 +26,8 @@ def view_method(*args, **kwargs): if template_file and not isinstance(response_val, dict): raise Exception( - "Invalid return type {}, we expected a dict as the return value.".format(type(response_val))) + 'Invalid return type {}, we expected a dict as the return value.'.format(type(response_val)) + ) if template_file: response_val = flask.render_template(template_file, **response_val) @@ -42,6 +43,7 @@ def view_method(*args, **kwargs): return response_inner + # # def template(template_file: str = None): # def template_inner(f): diff --git a/app/ch11_migrations/starter/pypi_org/services/package_service.py b/app/ch11_migrations/starter/pypi_org/services/package_service.py index e51241ae..6ac445e6 100644 --- a/app/ch11_migrations/starter/pypi_org/services/package_service.py +++ b/app/ch11_migrations/starter/pypi_org/services/package_service.py @@ -9,11 +9,13 @@ def get_latest_releases(limit=10) -> List[Release]: session = db_session.create_session() - releases = session.query(Release). \ - options(sqlalchemy.orm.joinedload(Release.package)). \ - order_by(Release.created_date.desc()). \ - limit(limit). \ - all() + releases = ( + session.query(Release) + .options(sqlalchemy.orm.joinedload(Release.package)) + .order_by(Release.created_date.desc()) + .limit(limit) + .all() + ) session.close() @@ -38,10 +40,12 @@ def get_package_by_id(package_id: str) -> Optional[Package]: session = db_session.create_session() - package = session.query(Package) \ - .options(sqlalchemy.orm.joinedload(Package.releases)) \ - .filter(Package.id == package_id) \ + package = ( + session.query(Package) + .options(sqlalchemy.orm.joinedload(Package.releases)) + .filter(Package.id == package_id) .first() + ) session.close() diff --git a/app/ch11_migrations/starter/pypi_org/views/account_views.py b/app/ch11_migrations/starter/pypi_org/views/account_views.py index 0421324a..55e5df41 100644 --- a/app/ch11_migrations/starter/pypi_org/views/account_views.py +++ b/app/ch11_migrations/starter/pypi_org/views/account_views.py @@ -16,6 +16,7 @@ def index(): # ################### REGISTER ################################# + @blueprint.route('/account/register', methods=['GET']) @response(template_file='account/register.html') def register_get(): @@ -30,6 +31,7 @@ def register_post(): # ################### LOGIN ################################# + @blueprint.route('/account/login', methods=['GET']) @response(template_file='account/login.html') def login_get(): @@ -44,6 +46,7 @@ def login_post(): # ################### LOGOUT ################################# + @blueprint.route('/account/logout') def logout(): return {} diff --git a/app/ch11_migrations/starter/pypi_org/views/cms_views.py b/app/ch11_migrations/starter/pypi_org/views/cms_views.py index f7172d3d..a8b755a8 100644 --- a/app/ch11_migrations/starter/pypi_org/views/cms_views.py +++ b/app/ch11_migrations/starter/pypi_org/views/cms_views.py @@ -9,7 +9,7 @@ @blueprint.route('/') @response(template_file='cms/page.html') def cms_page(full_url: str): - print("Getting CMS page for {}".format(full_url)) + print('Getting CMS page for {}'.format(full_url)) page = cms_service.get_page(full_url) if not page: diff --git a/app/ch11_migrations/starter/pypi_org/views/package_views.py b/app/ch11_migrations/starter/pypi_org/views/package_views.py index 70526f59..92d9109a 100644 --- a/app/ch11_migrations/starter/pypi_org/views/package_views.py +++ b/app/ch11_migrations/starter/pypi_org/views/package_views.py @@ -16,7 +16,7 @@ def package_details(package_name: str): if not package: return flask.abort(status=404) - latest_version = "0.0.0" + latest_version = '0.0.0' latest_release = None is_latest = True @@ -36,4 +36,4 @@ def package_details(package_name: str): @blueprint.route('/') def popular(rank: int): print(type(rank), rank) - return "The details for the {}th most popular package".format(rank) + return 'The details for the {}th most popular package'.format(rank) diff --git a/app/ch12-forms/final/alembic/alembic_helpers.py b/app/ch12-forms/final/alembic/alembic_helpers.py index 561f7a70..6aea52d4 100644 --- a/app/ch12-forms/final/alembic/alembic_helpers.py +++ b/app/ch12-forms/final/alembic/alembic_helpers.py @@ -5,8 +5,7 @@ def table_has_column(table, column): config = op.get_context().config - engine = engine_from_config( - config.get_section(config.config_ini_section), prefix='sqlalchemy.') + engine = engine_from_config(config.get_section(config.config_ini_section), prefix='sqlalchemy.') insp = reflection.Inspector.from_engine(engine) has_column = False for col in insp.get_columns(table): diff --git a/app/ch12-forms/final/alembic/env.py b/app/ch12-forms/final/alembic/env.py index 27ec49fb..1fdc9cab 100644 --- a/app/ch12-forms/final/alembic/env.py +++ b/app/ch12-forms/final/alembic/env.py @@ -26,6 +26,7 @@ sys.path.insert(0, folder) from pypi_org.data.modelbase import SqlAlchemyBase + # noinspection PyUnresolvedReferences import pypi_org.data.__all_models @@ -49,10 +50,8 @@ def run_migrations_offline(): script output. """ - url = config.get_main_option("sqlalchemy.url") - context.configure( - url=url, target_metadata=target_metadata, literal_binds=True - ) + url = config.get_main_option('sqlalchemy.url') + context.configure(url=url, target_metadata=target_metadata, literal_binds=True) with context.begin_transaction(): context.run_migrations() @@ -67,14 +66,12 @@ def run_migrations_online(): """ connectable = engine_from_config( config.get_section(config.config_ini_section), - prefix="sqlalchemy.", + prefix='sqlalchemy.', poolclass=pool.NullPool, ) with connectable.connect() as connection: - context.configure( - connection=connection, target_metadata=target_metadata - ) + context.configure(connection=connection, target_metadata=target_metadata) with context.begin_transaction(): context.run_migrations() diff --git a/app/ch12-forms/final/alembic/versions/722c82f0097c_added_auditing_table.py b/app/ch12-forms/final/alembic/versions/722c82f0097c_added_auditing_table.py index 2c3e2a39..7c6e892f 100644 --- a/app/ch12-forms/final/alembic/versions/722c82f0097c_added_auditing_table.py +++ b/app/ch12-forms/final/alembic/versions/722c82f0097c_added_auditing_table.py @@ -18,11 +18,12 @@ def upgrade(): # ### commands auto generated by Alembic - please adjust! ### - op.create_table('auditing', - sa.Column('id', sa.String(), nullable=False), - sa.Column('created_date', sa.DateTime(), nullable=True), - sa.Column('description', sa.String(), nullable=True), - sa.PrimaryKeyConstraint('id') + op.create_table( + 'auditing', + sa.Column('id', sa.String(), nullable=False), + sa.Column('created_date', sa.DateTime(), nullable=True), + sa.Column('description', sa.String(), nullable=True), + sa.PrimaryKeyConstraint('id'), ) op.create_index(op.f('ix_auditing_created_date'), 'auditing', ['created_date'], unique=False) # ### end Alembic commands ### diff --git a/app/ch12-forms/final/pypi_org/app.py b/app/ch12-forms/final/pypi_org/app.py index 2227f9db..0fbd8016 100644 --- a/app/ch12-forms/final/pypi_org/app.py +++ b/app/ch12-forms/final/pypi_org/app.py @@ -21,10 +21,7 @@ def configure(): def setup_db(): - db_file = os.path.join( - os.path.dirname(__file__), - 'db', - 'pypi.sqlite') + db_file = os.path.join(os.path.dirname(__file__), 'db', 'pypi.sqlite') db_session.global_init(db_file) diff --git a/app/ch12-forms/final/pypi_org/bin/basic_inserts.py b/app/ch12-forms/final/pypi_org/bin/basic_inserts.py index d622a6ae..6d04f551 100644 --- a/app/ch12-forms/final/pypi_org/bin/basic_inserts.py +++ b/app/ch12-forms/final/pypi_org/bin/basic_inserts.py @@ -2,8 +2,7 @@ import sys # Make it run more easily outside of PyCharm -sys.path.insert(0, os.path.abspath(os.path.join( - os.path.dirname(__file__), "..", ".."))) +sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..'))) import pypi_org.data.db_session as db_session from pypi_org.data.package import Package @@ -20,24 +19,24 @@ def insert_a_package(): p = Package() p.id = input('Package id / name: ').strip().lower() - p.summary = input("Package summary: ").strip() - p.author_name = input("Author: ").strip() - p.license = input("License: ").strip() + p.summary = input('Package summary: ').strip() + p.author_name = input('Author: ').strip() + p.license = input('License: ').strip() - print("Release 1:") + print('Release 1:') r = Release() - r.major_ver = int(input("Major version: ")) - r.minor_ver = int(input("Minor version: ")) - r.build_ver = int(input("Build version: ")) - r.size = int(input("Size in bytes: ")) + r.major_ver = int(input('Major version: ')) + r.minor_ver = int(input('Minor version: ')) + r.build_ver = int(input('Build version: ')) + r.size = int(input('Size in bytes: ')) p.releases.append(r) - print("Release 2:") + print('Release 2:') r = Release() - r.major_ver = int(input("Major version: ")) - r.minor_ver = int(input("Minor version: ")) - r.build_ver = int(input("Build version: ")) - r.size = int(input("Size in bytes: ")) + r.major_ver = int(input('Major version: ')) + r.minor_ver = int(input('Minor version: ')) + r.build_ver = int(input('Build version: ')) + r.size = int(input('Size in bytes: ')) p.releases.append(r) session = db_session.create_session() diff --git a/app/ch12-forms/final/pypi_org/bin/load_data.py b/app/ch12-forms/final/pypi_org/bin/load_data.py index ba62ff7d..3af7a03d 100644 --- a/app/ch12-forms/final/pypi_org/bin/load_data.py +++ b/app/ch12-forms/final/pypi_org/bin/load_data.py @@ -7,8 +7,7 @@ import progressbar from dateutil.parser import parse -sys.path.insert(0, os.path.abspath(os.path.join( - os.path.dirname(__file__), "..", ".."))) +sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..'))) from pypi_org.infrastructure.num_convert import try_int import pypi_org.data.db_session as db_session @@ -40,7 +39,7 @@ def main(): def do_import_languages(file_data: List[dict]): imported = set() - print("Importing languages ... ", flush=True) + print('Importing languages ... ', flush=True) with progressbar.ProgressBar(max_value=len(file_data)) as bar: for idx, p in enumerate(file_data): info = p.get('info') @@ -75,7 +74,7 @@ def do_import_languages(file_data: List[dict]): def do_import_licenses(file_data: List[dict]): imported = set() - print("Importing licenses ... ", flush=True) + print('Importing licenses ... ', flush=True) with progressbar.ProgressBar(max_value=len(file_data)) as bar: for idx, p in enumerate(file_data): info = p.get('info') @@ -101,17 +100,17 @@ def do_import_licenses(file_data: List[dict]): def do_summary(): session = db_session.create_session() - print("Final numbers:") - print("Users: {:,}".format(session.query(User).count())) - print("Packages: {:,}".format(session.query(Package).count())) - print("Releases: {:,}".format(session.query(Release).count())) - print("Maintainers: {:,}".format(session.query(Maintainer).count())) - print("Languages: {:,}".format(session.query(ProgrammingLanguage).count())) - print("Licenses: {:,}".format(session.query(License).count())) + print('Final numbers:') + print('Users: {:,}'.format(session.query(User).count())) + print('Packages: {:,}'.format(session.query(Package).count())) + print('Releases: {:,}'.format(session.query(Release).count())) + print('Maintainers: {:,}'.format(session.query(Maintainer).count())) + print('Languages: {:,}'.format(session.query(ProgrammingLanguage).count())) + print('Licenses: {:,}'.format(session.query(License).count())) def do_user_import(user_lookup: Dict[str, str]) -> Dict[str, User]: - print("Importing users ... ", flush=True) + print('Importing users ... ', flush=True) with progressbar.ProgressBar(max_value=len(user_lookup)) as bar: for idx, (email, name) in enumerate(user_lookup.items()): session = db_session.create_session() @@ -135,29 +134,29 @@ def do_user_import(user_lookup: Dict[str, str]) -> Dict[str, User]: def do_import_packages(file_data: List[dict], user_lookup: Dict[str, User]): errored_packages = [] - print("Importing packages and releases ... ", flush=True) + print('Importing packages and releases ... ', flush=True) with progressbar.ProgressBar(max_value=len(file_data)) as bar: for idx, p in enumerate(file_data): try: load_package(p, user_lookup) bar.update(idx) except Exception as x: - errored_packages.append((p, " *** Errored out for package {}, {}".format(p.get('package_name'), x))) + errored_packages.append((p, ' *** Errored out for package {}, {}'.format(p.get('package_name'), x))) raise sys.stderr.flush() sys.stdout.flush() print() - print("Completed packages with {} errors.".format(len(errored_packages))) - for (p, txt) in errored_packages: + print('Completed packages with {} errors.'.format(len(errored_packages))) + for p, txt in errored_packages: print(txt) def do_load_files() -> List[dict]: data_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../../../data/pypi-top-100')) - print("Loading files from {}".format(data_path)) + print('Loading files from {}'.format(data_path)) files = get_file_names(data_path) - print("Found {:,} files, loading ...".format(len(files)), flush=True) - time.sleep(.1) + print('Found {:,} files, loading ...'.format(len(files)), flush=True) + time.sleep(0.1) file_data = [] with progressbar.ProgressBar(max_value=len(files)) as bar: @@ -172,7 +171,7 @@ def do_load_files() -> List[dict]: def find_users(data: List[dict]) -> dict: - print("Discovering users...", flush=True) + print('Discovering users...', flush=True) found_users = {} with progressbar.ProgressBar(max_value=len(data)) as bar: @@ -185,7 +184,7 @@ def find_users(data: List[dict]) -> dict: sys.stderr.flush() sys.stdout.flush() print() - print("Discovered {:,} users".format(len(found_users))) + print('Discovered {:,} users'.format(len(found_users))) print() return found_users @@ -216,7 +215,7 @@ def load_file_data(filename: str) -> dict: with open(filename, 'r', encoding='utf-8') as fin: data = json.load(fin) except Exception as x: - print("ERROR in file: {}, details: {}".format(filename, x), flush=True) + print('ERROR in file: {}, details: {}'.format(filename, x), flush=True) raise return data @@ -234,7 +233,7 @@ def load_package(data: dict, user_lookup: Dict[str, User]): p.author = info.get('author') p.author_email = info.get('author_email') - releases = build_releases(p.id, data.get("releases", {})) + releases = build_releases(p.id, data.get('releases', {})) if releases: p.created_date = releases[0].created_date @@ -284,18 +283,13 @@ def detect_license(license_text: str) -> Optional[str]: license_text = license_text.strip() if len(license_text) > 100 or '\n' in license_text: - return "CUSTOM" + return 'CUSTOM' - license_text = license_text \ - .replace('Software License', '') \ - .replace('License', '') + license_text = license_text.replace('Software License', '').replace('License', '') if '::' in license_text: # E.g. 'License :: OSI Approved :: Apache Software License' - return license_text \ - .split(':')[-1] \ - .replace(' ', ' ') \ - .strip() + return license_text.split(':')[-1].replace(' ', ' ').strip() return license_text.strip() @@ -351,9 +345,7 @@ def get_file_names(data_path: str) -> List[str]: files = [] for f in os.listdir(data_path): if f.endswith('.json'): - files.append( - os.path.abspath(os.path.join(data_path, f)) - ) + files.append(os.path.abspath(os.path.join(data_path, f))) files.sort() return files diff --git a/app/ch12-forms/final/pypi_org/data/__all_models.py b/app/ch12-forms/final/pypi_org/data/__all_models.py index f399ef54..ca4804ac 100644 --- a/app/ch12-forms/final/pypi_org/data/__all_models.py +++ b/app/ch12-forms/final/pypi_org/data/__all_models.py @@ -5,17 +5,24 @@ # noinspection PyUnresolvedReferences import pypi_org.data.audit + # noinspection PyUnresolvedReferences import pypi_org.data.downloads + # noinspection PyUnresolvedReferences import pypi_org.data.languages + # noinspection PyUnresolvedReferences import pypi_org.data.licenses + # noinspection PyUnresolvedReferences import pypi_org.data.maintainers + # noinspection PyUnresolvedReferences import pypi_org.data.package + # noinspection PyUnresolvedReferences import pypi_org.data.releases + # noinspection PyUnresolvedReferences import pypi_org.data.users diff --git a/app/ch12-forms/final/pypi_org/data/db_session.py b/app/ch12-forms/final/pypi_org/data/db_session.py index addbaff9..62391b85 100644 --- a/app/ch12-forms/final/pypi_org/data/db_session.py +++ b/app/ch12-forms/final/pypi_org/data/db_session.py @@ -14,15 +14,15 @@ def global_init(db_file: str): return if not db_file or not db_file.strip(): - raise Exception("You must specify a db file.") + raise Exception('You must specify a db file.') conn_str = 'sqlite:///' + db_file.strip() - print("Connecting to DB with {}".format(conn_str)) + print('Connecting to DB with {}'.format(conn_str)) # Adding check_same_thread = False after the recording. This can be an issue about # creating / owner thread when cleaning up sessions, etc. This is a sqlite restriction # that we probably don't care about in this example. - engine = sa.create_engine(conn_str, echo=False, connect_args={"check_same_thread": False}) + engine = sa.create_engine(conn_str, echo=False, connect_args={'check_same_thread': False}) __factory = orm.sessionmaker(bind=engine) # noinspection PyUnresolvedReferences diff --git a/app/ch12-forms/final/pypi_org/data/downloads.py b/app/ch12-forms/final/pypi_org/data/downloads.py index 66068f02..dd8afd65 100644 --- a/app/ch12-forms/final/pypi_org/data/downloads.py +++ b/app/ch12-forms/final/pypi_org/data/downloads.py @@ -7,8 +7,7 @@ class Download(SqlAlchemyBase): __tablename__ = 'downloads' id: int = sqlalchemy.Column(sqlalchemy.BigInteger, primary_key=True, autoincrement=True) - created_date: datetime.datetime = sqlalchemy.Column( - sqlalchemy.DateTime, default=datetime.datetime.now, index=True) + created_date: datetime.datetime = sqlalchemy.Column(sqlalchemy.DateTime, default=datetime.datetime.now, index=True) package_id: str = sqlalchemy.Column(sqlalchemy.String, index=True) release_id: int = sqlalchemy.Column(sqlalchemy.BigInteger, index=True) diff --git a/app/ch12-forms/final/pypi_org/data/languages.py b/app/ch12-forms/final/pypi_org/data/languages.py index 964b8444..3a73dde0 100644 --- a/app/ch12-forms/final/pypi_org/data/languages.py +++ b/app/ch12-forms/final/pypi_org/data/languages.py @@ -7,6 +7,5 @@ class ProgrammingLanguage(SqlAlchemyBase): __tablename__ = 'languages' id: str = sqlalchemy.Column(sqlalchemy.String, primary_key=True) - created_date: datetime.datetime = sqlalchemy.Column( - sqlalchemy.DateTime, default=datetime.datetime.now, index=True) + created_date: datetime.datetime = sqlalchemy.Column(sqlalchemy.DateTime, default=datetime.datetime.now, index=True) description: str = sqlalchemy.Column(sqlalchemy.String) diff --git a/app/ch12-forms/final/pypi_org/data/package.py b/app/ch12-forms/final/pypi_org/data/package.py index c3420d1b..16e6d156 100644 --- a/app/ch12-forms/final/pypi_org/data/package.py +++ b/app/ch12-forms/final/pypi_org/data/package.py @@ -26,11 +26,15 @@ class Package(SqlAlchemyBase): license: str = sa.Column(sa.String, index=True) # releases relationship - releases: List[Release] = orm.relation("Release", order_by=[ - Release.major_ver.desc(), - Release.minor_ver.desc(), - Release.build_ver.desc(), - ], back_populates='package') + releases: List[Release] = orm.relation( + 'Release', + order_by=[ + Release.major_ver.desc(), + Release.minor_ver.desc(), + Release.build_ver.desc(), + ], + back_populates='package', + ) def __repr__(self): return ''.format(self.id) diff --git a/app/ch12-forms/final/pypi_org/data/releases.py b/app/ch12-forms/final/pypi_org/data/releases.py index 7650e438..8596f65c 100644 --- a/app/ch12-forms/final/pypi_org/data/releases.py +++ b/app/ch12-forms/final/pypi_org/data/releases.py @@ -13,15 +13,13 @@ class Release(SqlAlchemyBase): minor_ver: int = sqlalchemy.Column(sqlalchemy.BigInteger, index=True) build_ver: int = sqlalchemy.Column(sqlalchemy.BigInteger, index=True) - created_date: datetime.datetime = sqlalchemy.Column(sqlalchemy.DateTime, - default=datetime.datetime.now, - index=True) + created_date: datetime.datetime = sqlalchemy.Column(sqlalchemy.DateTime, default=datetime.datetime.now, index=True) comment: str = sqlalchemy.Column(sqlalchemy.String) url: str = sqlalchemy.Column(sqlalchemy.String) size: int = sqlalchemy.Column(sqlalchemy.BigInteger) # Package relationship - package_id: str = sqlalchemy.Column(sqlalchemy.String, sqlalchemy.ForeignKey("packages.id")) + package_id: str = sqlalchemy.Column(sqlalchemy.String, sqlalchemy.ForeignKey('packages.id')) package = orm.relation('Package') @property diff --git a/app/ch12-forms/final/pypi_org/infrastructure/cookie_auth.py b/app/ch12-forms/final/pypi_org/infrastructure/cookie_auth.py index e8b1051f..d76a4d30 100644 --- a/app/ch12-forms/final/pypi_org/infrastructure/cookie_auth.py +++ b/app/ch12-forms/final/pypi_org/infrastructure/cookie_auth.py @@ -11,7 +11,7 @@ def set_auth(response: Response, user_id: int): hash_val = __hash_text(str(user_id)) - val = "{}:{}".format(user_id, hash_val) + val = '{}:{}'.format(user_id, hash_val) response.set_cookie(auth_cookie_name, val, secure=False, httponly=True, samesite='Lax') @@ -33,7 +33,7 @@ def get_user_id_via_auth_cookie(request: Request) -> Optional[int]: hash_val = parts[1] hash_val_check = __hash_text(user_id) if hash_val != hash_val_check: - print("Warning: Hash mismatch, invalid cookie value") + print('Warning: Hash mismatch, invalid cookie value') return None return try_int(user_id) diff --git a/app/ch12-forms/final/pypi_org/infrastructure/request_dict.py b/app/ch12-forms/final/pypi_org/infrastructure/request_dict.py index d7ab10de..d44ae574 100644 --- a/app/ch12-forms/final/pypi_org/infrastructure/request_dict.py +++ b/app/ch12-forms/final/pypi_org/infrastructure/request_dict.py @@ -29,7 +29,7 @@ def create(default_val=None, **route_args) -> RequestDictionary: **args, # The key/value pairs in the URL query string **request.headers, # Header values **form, # The key/value pairs in the body, from a HTML post form - **route_args # And additional arguments the method access, if they want them merged. + **route_args, # And additional arguments the method access, if they want them merged. } return RequestDictionary(data, default_val=default_val) diff --git a/app/ch12-forms/final/pypi_org/infrastructure/view_modifiers.py b/app/ch12-forms/final/pypi_org/infrastructure/view_modifiers.py index 0978163e..d944c142 100644 --- a/app/ch12-forms/final/pypi_org/infrastructure/view_modifiers.py +++ b/app/ch12-forms/final/pypi_org/infrastructure/view_modifiers.py @@ -26,7 +26,8 @@ def view_method(*args, **kwargs): if template_file and not isinstance(response_val, dict): raise Exception( - "Invalid return type {}, we expected a dict as the return value.".format(type(response_val))) + 'Invalid return type {}, we expected a dict as the return value.'.format(type(response_val)) + ) if template_file: response_val = flask.render_template(template_file, **response_val) @@ -42,6 +43,7 @@ def view_method(*args, **kwargs): return response_inner + # # def template(template_file: str = None): # def template_inner(f): diff --git a/app/ch12-forms/final/pypi_org/services/package_service.py b/app/ch12-forms/final/pypi_org/services/package_service.py index e51241ae..6ac445e6 100644 --- a/app/ch12-forms/final/pypi_org/services/package_service.py +++ b/app/ch12-forms/final/pypi_org/services/package_service.py @@ -9,11 +9,13 @@ def get_latest_releases(limit=10) -> List[Release]: session = db_session.create_session() - releases = session.query(Release). \ - options(sqlalchemy.orm.joinedload(Release.package)). \ - order_by(Release.created_date.desc()). \ - limit(limit). \ - all() + releases = ( + session.query(Release) + .options(sqlalchemy.orm.joinedload(Release.package)) + .order_by(Release.created_date.desc()) + .limit(limit) + .all() + ) session.close() @@ -38,10 +40,12 @@ def get_package_by_id(package_id: str) -> Optional[Package]: session = db_session.create_session() - package = session.query(Package) \ - .options(sqlalchemy.orm.joinedload(Package.releases)) \ - .filter(Package.id == package_id) \ + package = ( + session.query(Package) + .options(sqlalchemy.orm.joinedload(Package.releases)) + .filter(Package.id == package_id) .first() + ) session.close() diff --git a/app/ch12-forms/final/pypi_org/views/account_views.py b/app/ch12-forms/final/pypi_org/views/account_views.py index f127310b..877231ba 100644 --- a/app/ch12-forms/final/pypi_org/views/account_views.py +++ b/app/ch12-forms/final/pypi_org/views/account_views.py @@ -30,6 +30,7 @@ def index(): # ################### REGISTER ################################# + @blueprint.route('/account/register', methods=['GET']) @response(template_file='account/register.html') def register_get(): @@ -52,7 +53,7 @@ def register_post(): 'name': name, 'email': email, 'password': password, - 'error': "Some required fields are missing.", + 'error': 'Some required fields are missing.', 'user_id': cookie_auth.get_user_id_via_auth_cookie(flask.request), } @@ -62,7 +63,7 @@ def register_post(): 'name': name, 'email': email, 'password': password, - 'error': "A user with that email already exists.", + 'error': 'A user with that email already exists.', 'user_id': cookie_auth.get_user_id_via_auth_cookie(flask.request), } @@ -74,6 +75,7 @@ def register_post(): # ################### LOGIN ################################# + @blueprint.route('/account/login', methods=['GET']) @response(template_file='account/login.html') def login_get(): @@ -92,7 +94,7 @@ def login_post(): return { 'email': email, 'password': password, - 'error': "Some required fields are missing.", + 'error': 'Some required fields are missing.', 'user_id': cookie_auth.get_user_id_via_auth_cookie(flask.request), } @@ -101,7 +103,7 @@ def login_post(): return { 'email': email, 'password': password, - 'error': "The account does not exist or the password is wrong.", + 'error': 'The account does not exist or the password is wrong.', 'user_id': cookie_auth.get_user_id_via_auth_cookie(flask.request), } @@ -113,6 +115,7 @@ def login_post(): # ################### LOGOUT ################################# + @blueprint.route('/account/logout') def logout(): resp = flask.redirect('/') diff --git a/app/ch12-forms/final/pypi_org/views/cms_views.py b/app/ch12-forms/final/pypi_org/views/cms_views.py index f7172d3d..a8b755a8 100644 --- a/app/ch12-forms/final/pypi_org/views/cms_views.py +++ b/app/ch12-forms/final/pypi_org/views/cms_views.py @@ -9,7 +9,7 @@ @blueprint.route('/') @response(template_file='cms/page.html') def cms_page(full_url: str): - print("Getting CMS page for {}".format(full_url)) + print('Getting CMS page for {}'.format(full_url)) page = cms_service.get_page(full_url) if not page: diff --git a/app/ch12-forms/final/pypi_org/views/package_views.py b/app/ch12-forms/final/pypi_org/views/package_views.py index f1ad7811..2587b704 100644 --- a/app/ch12-forms/final/pypi_org/views/package_views.py +++ b/app/ch12-forms/final/pypi_org/views/package_views.py @@ -17,7 +17,7 @@ def package_details(package_name: str): if not package: return flask.abort(status=404) - latest_version = "0.0.0" + latest_version = '0.0.0' latest_release = None is_latest = True @@ -38,4 +38,4 @@ def package_details(package_name: str): @blueprint.route('/') def popular(rank: int): print(type(rank), rank) - return "The details for the {}th most popular package".format(rank) + return 'The details for the {}th most popular package'.format(rank) diff --git a/app/ch12-forms/starter/alembic/alembic_helpers.py b/app/ch12-forms/starter/alembic/alembic_helpers.py index 561f7a70..6aea52d4 100644 --- a/app/ch12-forms/starter/alembic/alembic_helpers.py +++ b/app/ch12-forms/starter/alembic/alembic_helpers.py @@ -5,8 +5,7 @@ def table_has_column(table, column): config = op.get_context().config - engine = engine_from_config( - config.get_section(config.config_ini_section), prefix='sqlalchemy.') + engine = engine_from_config(config.get_section(config.config_ini_section), prefix='sqlalchemy.') insp = reflection.Inspector.from_engine(engine) has_column = False for col in insp.get_columns(table): diff --git a/app/ch12-forms/starter/alembic/env.py b/app/ch12-forms/starter/alembic/env.py index 27ec49fb..1fdc9cab 100644 --- a/app/ch12-forms/starter/alembic/env.py +++ b/app/ch12-forms/starter/alembic/env.py @@ -26,6 +26,7 @@ sys.path.insert(0, folder) from pypi_org.data.modelbase import SqlAlchemyBase + # noinspection PyUnresolvedReferences import pypi_org.data.__all_models @@ -49,10 +50,8 @@ def run_migrations_offline(): script output. """ - url = config.get_main_option("sqlalchemy.url") - context.configure( - url=url, target_metadata=target_metadata, literal_binds=True - ) + url = config.get_main_option('sqlalchemy.url') + context.configure(url=url, target_metadata=target_metadata, literal_binds=True) with context.begin_transaction(): context.run_migrations() @@ -67,14 +66,12 @@ def run_migrations_online(): """ connectable = engine_from_config( config.get_section(config.config_ini_section), - prefix="sqlalchemy.", + prefix='sqlalchemy.', poolclass=pool.NullPool, ) with connectable.connect() as connection: - context.configure( - connection=connection, target_metadata=target_metadata - ) + context.configure(connection=connection, target_metadata=target_metadata) with context.begin_transaction(): context.run_migrations() diff --git a/app/ch12-forms/starter/alembic/versions/722c82f0097c_added_auditing_table.py b/app/ch12-forms/starter/alembic/versions/722c82f0097c_added_auditing_table.py index 2c3e2a39..7c6e892f 100644 --- a/app/ch12-forms/starter/alembic/versions/722c82f0097c_added_auditing_table.py +++ b/app/ch12-forms/starter/alembic/versions/722c82f0097c_added_auditing_table.py @@ -18,11 +18,12 @@ def upgrade(): # ### commands auto generated by Alembic - please adjust! ### - op.create_table('auditing', - sa.Column('id', sa.String(), nullable=False), - sa.Column('created_date', sa.DateTime(), nullable=True), - sa.Column('description', sa.String(), nullable=True), - sa.PrimaryKeyConstraint('id') + op.create_table( + 'auditing', + sa.Column('id', sa.String(), nullable=False), + sa.Column('created_date', sa.DateTime(), nullable=True), + sa.Column('description', sa.String(), nullable=True), + sa.PrimaryKeyConstraint('id'), ) op.create_index(op.f('ix_auditing_created_date'), 'auditing', ['created_date'], unique=False) # ### end Alembic commands ### diff --git a/app/ch12-forms/starter/pypi_org/app.py b/app/ch12-forms/starter/pypi_org/app.py index 4b39b374..0315d74a 100644 --- a/app/ch12-forms/starter/pypi_org/app.py +++ b/app/ch12-forms/starter/pypi_org/app.py @@ -1,6 +1,7 @@ import os import sys import flask + folder = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) sys.path.insert(0, folder) @@ -16,10 +17,7 @@ def main(): def setup_db(): - db_file = os.path.join( - os.path.dirname(__file__), - 'db', - 'pypi.sqlite') + db_file = os.path.join(os.path.dirname(__file__), 'db', 'pypi.sqlite') db_session.global_init(db_file) diff --git a/app/ch12-forms/starter/pypi_org/bin/basic_inserts.py b/app/ch12-forms/starter/pypi_org/bin/basic_inserts.py index d622a6ae..6d04f551 100644 --- a/app/ch12-forms/starter/pypi_org/bin/basic_inserts.py +++ b/app/ch12-forms/starter/pypi_org/bin/basic_inserts.py @@ -2,8 +2,7 @@ import sys # Make it run more easily outside of PyCharm -sys.path.insert(0, os.path.abspath(os.path.join( - os.path.dirname(__file__), "..", ".."))) +sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..'))) import pypi_org.data.db_session as db_session from pypi_org.data.package import Package @@ -20,24 +19,24 @@ def insert_a_package(): p = Package() p.id = input('Package id / name: ').strip().lower() - p.summary = input("Package summary: ").strip() - p.author_name = input("Author: ").strip() - p.license = input("License: ").strip() + p.summary = input('Package summary: ').strip() + p.author_name = input('Author: ').strip() + p.license = input('License: ').strip() - print("Release 1:") + print('Release 1:') r = Release() - r.major_ver = int(input("Major version: ")) - r.minor_ver = int(input("Minor version: ")) - r.build_ver = int(input("Build version: ")) - r.size = int(input("Size in bytes: ")) + r.major_ver = int(input('Major version: ')) + r.minor_ver = int(input('Minor version: ')) + r.build_ver = int(input('Build version: ')) + r.size = int(input('Size in bytes: ')) p.releases.append(r) - print("Release 2:") + print('Release 2:') r = Release() - r.major_ver = int(input("Major version: ")) - r.minor_ver = int(input("Minor version: ")) - r.build_ver = int(input("Build version: ")) - r.size = int(input("Size in bytes: ")) + r.major_ver = int(input('Major version: ')) + r.minor_ver = int(input('Minor version: ')) + r.build_ver = int(input('Build version: ')) + r.size = int(input('Size in bytes: ')) p.releases.append(r) session = db_session.create_session() diff --git a/app/ch12-forms/starter/pypi_org/bin/load_data.py b/app/ch12-forms/starter/pypi_org/bin/load_data.py index ba62ff7d..3af7a03d 100644 --- a/app/ch12-forms/starter/pypi_org/bin/load_data.py +++ b/app/ch12-forms/starter/pypi_org/bin/load_data.py @@ -7,8 +7,7 @@ import progressbar from dateutil.parser import parse -sys.path.insert(0, os.path.abspath(os.path.join( - os.path.dirname(__file__), "..", ".."))) +sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..'))) from pypi_org.infrastructure.num_convert import try_int import pypi_org.data.db_session as db_session @@ -40,7 +39,7 @@ def main(): def do_import_languages(file_data: List[dict]): imported = set() - print("Importing languages ... ", flush=True) + print('Importing languages ... ', flush=True) with progressbar.ProgressBar(max_value=len(file_data)) as bar: for idx, p in enumerate(file_data): info = p.get('info') @@ -75,7 +74,7 @@ def do_import_languages(file_data: List[dict]): def do_import_licenses(file_data: List[dict]): imported = set() - print("Importing licenses ... ", flush=True) + print('Importing licenses ... ', flush=True) with progressbar.ProgressBar(max_value=len(file_data)) as bar: for idx, p in enumerate(file_data): info = p.get('info') @@ -101,17 +100,17 @@ def do_import_licenses(file_data: List[dict]): def do_summary(): session = db_session.create_session() - print("Final numbers:") - print("Users: {:,}".format(session.query(User).count())) - print("Packages: {:,}".format(session.query(Package).count())) - print("Releases: {:,}".format(session.query(Release).count())) - print("Maintainers: {:,}".format(session.query(Maintainer).count())) - print("Languages: {:,}".format(session.query(ProgrammingLanguage).count())) - print("Licenses: {:,}".format(session.query(License).count())) + print('Final numbers:') + print('Users: {:,}'.format(session.query(User).count())) + print('Packages: {:,}'.format(session.query(Package).count())) + print('Releases: {:,}'.format(session.query(Release).count())) + print('Maintainers: {:,}'.format(session.query(Maintainer).count())) + print('Languages: {:,}'.format(session.query(ProgrammingLanguage).count())) + print('Licenses: {:,}'.format(session.query(License).count())) def do_user_import(user_lookup: Dict[str, str]) -> Dict[str, User]: - print("Importing users ... ", flush=True) + print('Importing users ... ', flush=True) with progressbar.ProgressBar(max_value=len(user_lookup)) as bar: for idx, (email, name) in enumerate(user_lookup.items()): session = db_session.create_session() @@ -135,29 +134,29 @@ def do_user_import(user_lookup: Dict[str, str]) -> Dict[str, User]: def do_import_packages(file_data: List[dict], user_lookup: Dict[str, User]): errored_packages = [] - print("Importing packages and releases ... ", flush=True) + print('Importing packages and releases ... ', flush=True) with progressbar.ProgressBar(max_value=len(file_data)) as bar: for idx, p in enumerate(file_data): try: load_package(p, user_lookup) bar.update(idx) except Exception as x: - errored_packages.append((p, " *** Errored out for package {}, {}".format(p.get('package_name'), x))) + errored_packages.append((p, ' *** Errored out for package {}, {}'.format(p.get('package_name'), x))) raise sys.stderr.flush() sys.stdout.flush() print() - print("Completed packages with {} errors.".format(len(errored_packages))) - for (p, txt) in errored_packages: + print('Completed packages with {} errors.'.format(len(errored_packages))) + for p, txt in errored_packages: print(txt) def do_load_files() -> List[dict]: data_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../../../data/pypi-top-100')) - print("Loading files from {}".format(data_path)) + print('Loading files from {}'.format(data_path)) files = get_file_names(data_path) - print("Found {:,} files, loading ...".format(len(files)), flush=True) - time.sleep(.1) + print('Found {:,} files, loading ...'.format(len(files)), flush=True) + time.sleep(0.1) file_data = [] with progressbar.ProgressBar(max_value=len(files)) as bar: @@ -172,7 +171,7 @@ def do_load_files() -> List[dict]: def find_users(data: List[dict]) -> dict: - print("Discovering users...", flush=True) + print('Discovering users...', flush=True) found_users = {} with progressbar.ProgressBar(max_value=len(data)) as bar: @@ -185,7 +184,7 @@ def find_users(data: List[dict]) -> dict: sys.stderr.flush() sys.stdout.flush() print() - print("Discovered {:,} users".format(len(found_users))) + print('Discovered {:,} users'.format(len(found_users))) print() return found_users @@ -216,7 +215,7 @@ def load_file_data(filename: str) -> dict: with open(filename, 'r', encoding='utf-8') as fin: data = json.load(fin) except Exception as x: - print("ERROR in file: {}, details: {}".format(filename, x), flush=True) + print('ERROR in file: {}, details: {}'.format(filename, x), flush=True) raise return data @@ -234,7 +233,7 @@ def load_package(data: dict, user_lookup: Dict[str, User]): p.author = info.get('author') p.author_email = info.get('author_email') - releases = build_releases(p.id, data.get("releases", {})) + releases = build_releases(p.id, data.get('releases', {})) if releases: p.created_date = releases[0].created_date @@ -284,18 +283,13 @@ def detect_license(license_text: str) -> Optional[str]: license_text = license_text.strip() if len(license_text) > 100 or '\n' in license_text: - return "CUSTOM" + return 'CUSTOM' - license_text = license_text \ - .replace('Software License', '') \ - .replace('License', '') + license_text = license_text.replace('Software License', '').replace('License', '') if '::' in license_text: # E.g. 'License :: OSI Approved :: Apache Software License' - return license_text \ - .split(':')[-1] \ - .replace(' ', ' ') \ - .strip() + return license_text.split(':')[-1].replace(' ', ' ').strip() return license_text.strip() @@ -351,9 +345,7 @@ def get_file_names(data_path: str) -> List[str]: files = [] for f in os.listdir(data_path): if f.endswith('.json'): - files.append( - os.path.abspath(os.path.join(data_path, f)) - ) + files.append(os.path.abspath(os.path.join(data_path, f))) files.sort() return files diff --git a/app/ch12-forms/starter/pypi_org/data/__all_models.py b/app/ch12-forms/starter/pypi_org/data/__all_models.py index f399ef54..ca4804ac 100644 --- a/app/ch12-forms/starter/pypi_org/data/__all_models.py +++ b/app/ch12-forms/starter/pypi_org/data/__all_models.py @@ -5,17 +5,24 @@ # noinspection PyUnresolvedReferences import pypi_org.data.audit + # noinspection PyUnresolvedReferences import pypi_org.data.downloads + # noinspection PyUnresolvedReferences import pypi_org.data.languages + # noinspection PyUnresolvedReferences import pypi_org.data.licenses + # noinspection PyUnresolvedReferences import pypi_org.data.maintainers + # noinspection PyUnresolvedReferences import pypi_org.data.package + # noinspection PyUnresolvedReferences import pypi_org.data.releases + # noinspection PyUnresolvedReferences import pypi_org.data.users diff --git a/app/ch12-forms/starter/pypi_org/data/db_session.py b/app/ch12-forms/starter/pypi_org/data/db_session.py index addbaff9..62391b85 100644 --- a/app/ch12-forms/starter/pypi_org/data/db_session.py +++ b/app/ch12-forms/starter/pypi_org/data/db_session.py @@ -14,15 +14,15 @@ def global_init(db_file: str): return if not db_file or not db_file.strip(): - raise Exception("You must specify a db file.") + raise Exception('You must specify a db file.') conn_str = 'sqlite:///' + db_file.strip() - print("Connecting to DB with {}".format(conn_str)) + print('Connecting to DB with {}'.format(conn_str)) # Adding check_same_thread = False after the recording. This can be an issue about # creating / owner thread when cleaning up sessions, etc. This is a sqlite restriction # that we probably don't care about in this example. - engine = sa.create_engine(conn_str, echo=False, connect_args={"check_same_thread": False}) + engine = sa.create_engine(conn_str, echo=False, connect_args={'check_same_thread': False}) __factory = orm.sessionmaker(bind=engine) # noinspection PyUnresolvedReferences diff --git a/app/ch12-forms/starter/pypi_org/data/downloads.py b/app/ch12-forms/starter/pypi_org/data/downloads.py index 66068f02..dd8afd65 100644 --- a/app/ch12-forms/starter/pypi_org/data/downloads.py +++ b/app/ch12-forms/starter/pypi_org/data/downloads.py @@ -7,8 +7,7 @@ class Download(SqlAlchemyBase): __tablename__ = 'downloads' id: int = sqlalchemy.Column(sqlalchemy.BigInteger, primary_key=True, autoincrement=True) - created_date: datetime.datetime = sqlalchemy.Column( - sqlalchemy.DateTime, default=datetime.datetime.now, index=True) + created_date: datetime.datetime = sqlalchemy.Column(sqlalchemy.DateTime, default=datetime.datetime.now, index=True) package_id: str = sqlalchemy.Column(sqlalchemy.String, index=True) release_id: int = sqlalchemy.Column(sqlalchemy.BigInteger, index=True) diff --git a/app/ch12-forms/starter/pypi_org/data/languages.py b/app/ch12-forms/starter/pypi_org/data/languages.py index 964b8444..3a73dde0 100644 --- a/app/ch12-forms/starter/pypi_org/data/languages.py +++ b/app/ch12-forms/starter/pypi_org/data/languages.py @@ -7,6 +7,5 @@ class ProgrammingLanguage(SqlAlchemyBase): __tablename__ = 'languages' id: str = sqlalchemy.Column(sqlalchemy.String, primary_key=True) - created_date: datetime.datetime = sqlalchemy.Column( - sqlalchemy.DateTime, default=datetime.datetime.now, index=True) + created_date: datetime.datetime = sqlalchemy.Column(sqlalchemy.DateTime, default=datetime.datetime.now, index=True) description: str = sqlalchemy.Column(sqlalchemy.String) diff --git a/app/ch12-forms/starter/pypi_org/data/package.py b/app/ch12-forms/starter/pypi_org/data/package.py index c3420d1b..16e6d156 100644 --- a/app/ch12-forms/starter/pypi_org/data/package.py +++ b/app/ch12-forms/starter/pypi_org/data/package.py @@ -26,11 +26,15 @@ class Package(SqlAlchemyBase): license: str = sa.Column(sa.String, index=True) # releases relationship - releases: List[Release] = orm.relation("Release", order_by=[ - Release.major_ver.desc(), - Release.minor_ver.desc(), - Release.build_ver.desc(), - ], back_populates='package') + releases: List[Release] = orm.relation( + 'Release', + order_by=[ + Release.major_ver.desc(), + Release.minor_ver.desc(), + Release.build_ver.desc(), + ], + back_populates='package', + ) def __repr__(self): return ''.format(self.id) diff --git a/app/ch12-forms/starter/pypi_org/data/releases.py b/app/ch12-forms/starter/pypi_org/data/releases.py index 7650e438..8596f65c 100644 --- a/app/ch12-forms/starter/pypi_org/data/releases.py +++ b/app/ch12-forms/starter/pypi_org/data/releases.py @@ -13,15 +13,13 @@ class Release(SqlAlchemyBase): minor_ver: int = sqlalchemy.Column(sqlalchemy.BigInteger, index=True) build_ver: int = sqlalchemy.Column(sqlalchemy.BigInteger, index=True) - created_date: datetime.datetime = sqlalchemy.Column(sqlalchemy.DateTime, - default=datetime.datetime.now, - index=True) + created_date: datetime.datetime = sqlalchemy.Column(sqlalchemy.DateTime, default=datetime.datetime.now, index=True) comment: str = sqlalchemy.Column(sqlalchemy.String) url: str = sqlalchemy.Column(sqlalchemy.String) size: int = sqlalchemy.Column(sqlalchemy.BigInteger) # Package relationship - package_id: str = sqlalchemy.Column(sqlalchemy.String, sqlalchemy.ForeignKey("packages.id")) + package_id: str = sqlalchemy.Column(sqlalchemy.String, sqlalchemy.ForeignKey('packages.id')) package = orm.relation('Package') @property diff --git a/app/ch12-forms/starter/pypi_org/infrastructure/view_modifiers.py b/app/ch12-forms/starter/pypi_org/infrastructure/view_modifiers.py index 0978163e..d944c142 100644 --- a/app/ch12-forms/starter/pypi_org/infrastructure/view_modifiers.py +++ b/app/ch12-forms/starter/pypi_org/infrastructure/view_modifiers.py @@ -26,7 +26,8 @@ def view_method(*args, **kwargs): if template_file and not isinstance(response_val, dict): raise Exception( - "Invalid return type {}, we expected a dict as the return value.".format(type(response_val))) + 'Invalid return type {}, we expected a dict as the return value.'.format(type(response_val)) + ) if template_file: response_val = flask.render_template(template_file, **response_val) @@ -42,6 +43,7 @@ def view_method(*args, **kwargs): return response_inner + # # def template(template_file: str = None): # def template_inner(f): diff --git a/app/ch12-forms/starter/pypi_org/services/package_service.py b/app/ch12-forms/starter/pypi_org/services/package_service.py index e51241ae..6ac445e6 100644 --- a/app/ch12-forms/starter/pypi_org/services/package_service.py +++ b/app/ch12-forms/starter/pypi_org/services/package_service.py @@ -9,11 +9,13 @@ def get_latest_releases(limit=10) -> List[Release]: session = db_session.create_session() - releases = session.query(Release). \ - options(sqlalchemy.orm.joinedload(Release.package)). \ - order_by(Release.created_date.desc()). \ - limit(limit). \ - all() + releases = ( + session.query(Release) + .options(sqlalchemy.orm.joinedload(Release.package)) + .order_by(Release.created_date.desc()) + .limit(limit) + .all() + ) session.close() @@ -38,10 +40,12 @@ def get_package_by_id(package_id: str) -> Optional[Package]: session = db_session.create_session() - package = session.query(Package) \ - .options(sqlalchemy.orm.joinedload(Package.releases)) \ - .filter(Package.id == package_id) \ + package = ( + session.query(Package) + .options(sqlalchemy.orm.joinedload(Package.releases)) + .filter(Package.id == package_id) .first() + ) session.close() diff --git a/app/ch12-forms/starter/pypi_org/views/account_views.py b/app/ch12-forms/starter/pypi_org/views/account_views.py index 0421324a..55e5df41 100644 --- a/app/ch12-forms/starter/pypi_org/views/account_views.py +++ b/app/ch12-forms/starter/pypi_org/views/account_views.py @@ -16,6 +16,7 @@ def index(): # ################### REGISTER ################################# + @blueprint.route('/account/register', methods=['GET']) @response(template_file='account/register.html') def register_get(): @@ -30,6 +31,7 @@ def register_post(): # ################### LOGIN ################################# + @blueprint.route('/account/login', methods=['GET']) @response(template_file='account/login.html') def login_get(): @@ -44,6 +46,7 @@ def login_post(): # ################### LOGOUT ################################# + @blueprint.route('/account/logout') def logout(): return {} diff --git a/app/ch12-forms/starter/pypi_org/views/cms_views.py b/app/ch12-forms/starter/pypi_org/views/cms_views.py index f7172d3d..a8b755a8 100644 --- a/app/ch12-forms/starter/pypi_org/views/cms_views.py +++ b/app/ch12-forms/starter/pypi_org/views/cms_views.py @@ -9,7 +9,7 @@ @blueprint.route('/') @response(template_file='cms/page.html') def cms_page(full_url: str): - print("Getting CMS page for {}".format(full_url)) + print('Getting CMS page for {}'.format(full_url)) page = cms_service.get_page(full_url) if not page: diff --git a/app/ch12-forms/starter/pypi_org/views/package_views.py b/app/ch12-forms/starter/pypi_org/views/package_views.py index 70526f59..92d9109a 100644 --- a/app/ch12-forms/starter/pypi_org/views/package_views.py +++ b/app/ch12-forms/starter/pypi_org/views/package_views.py @@ -16,7 +16,7 @@ def package_details(package_name: str): if not package: return flask.abort(status=404) - latest_version = "0.0.0" + latest_version = '0.0.0' latest_release = None is_latest = True @@ -36,4 +36,4 @@ def package_details(package_name: str): @blueprint.route('/') def popular(rank: int): print(type(rank), rank) - return "The details for the {}th most popular package".format(rank) + return 'The details for the {}th most popular package'.format(rank) diff --git a/app/ch13-validation/final/alembic/alembic_helpers.py b/app/ch13-validation/final/alembic/alembic_helpers.py index 561f7a70..6aea52d4 100644 --- a/app/ch13-validation/final/alembic/alembic_helpers.py +++ b/app/ch13-validation/final/alembic/alembic_helpers.py @@ -5,8 +5,7 @@ def table_has_column(table, column): config = op.get_context().config - engine = engine_from_config( - config.get_section(config.config_ini_section), prefix='sqlalchemy.') + engine = engine_from_config(config.get_section(config.config_ini_section), prefix='sqlalchemy.') insp = reflection.Inspector.from_engine(engine) has_column = False for col in insp.get_columns(table): diff --git a/app/ch13-validation/final/alembic/env.py b/app/ch13-validation/final/alembic/env.py index 27ec49fb..1fdc9cab 100644 --- a/app/ch13-validation/final/alembic/env.py +++ b/app/ch13-validation/final/alembic/env.py @@ -26,6 +26,7 @@ sys.path.insert(0, folder) from pypi_org.data.modelbase import SqlAlchemyBase + # noinspection PyUnresolvedReferences import pypi_org.data.__all_models @@ -49,10 +50,8 @@ def run_migrations_offline(): script output. """ - url = config.get_main_option("sqlalchemy.url") - context.configure( - url=url, target_metadata=target_metadata, literal_binds=True - ) + url = config.get_main_option('sqlalchemy.url') + context.configure(url=url, target_metadata=target_metadata, literal_binds=True) with context.begin_transaction(): context.run_migrations() @@ -67,14 +66,12 @@ def run_migrations_online(): """ connectable = engine_from_config( config.get_section(config.config_ini_section), - prefix="sqlalchemy.", + prefix='sqlalchemy.', poolclass=pool.NullPool, ) with connectable.connect() as connection: - context.configure( - connection=connection, target_metadata=target_metadata - ) + context.configure(connection=connection, target_metadata=target_metadata) with context.begin_transaction(): context.run_migrations() diff --git a/app/ch13-validation/final/alembic/versions/722c82f0097c_added_auditing_table.py b/app/ch13-validation/final/alembic/versions/722c82f0097c_added_auditing_table.py index 2c3e2a39..7c6e892f 100644 --- a/app/ch13-validation/final/alembic/versions/722c82f0097c_added_auditing_table.py +++ b/app/ch13-validation/final/alembic/versions/722c82f0097c_added_auditing_table.py @@ -18,11 +18,12 @@ def upgrade(): # ### commands auto generated by Alembic - please adjust! ### - op.create_table('auditing', - sa.Column('id', sa.String(), nullable=False), - sa.Column('created_date', sa.DateTime(), nullable=True), - sa.Column('description', sa.String(), nullable=True), - sa.PrimaryKeyConstraint('id') + op.create_table( + 'auditing', + sa.Column('id', sa.String(), nullable=False), + sa.Column('created_date', sa.DateTime(), nullable=True), + sa.Column('description', sa.String(), nullable=True), + sa.PrimaryKeyConstraint('id'), ) op.create_index(op.f('ix_auditing_created_date'), 'auditing', ['created_date'], unique=False) # ### end Alembic commands ### diff --git a/app/ch13-validation/final/pypi_org/app.py b/app/ch13-validation/final/pypi_org/app.py index 89004d09..9b491bad 100644 --- a/app/ch13-validation/final/pypi_org/app.py +++ b/app/ch13-validation/final/pypi_org/app.py @@ -1,6 +1,7 @@ import os import sys import flask + folder = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) sys.path.insert(0, folder) @@ -16,10 +17,7 @@ def main(): def setup_db(): - db_file = os.path.join( - os.path.dirname(__file__), - 'db', - 'pypi.sqlite') + db_file = os.path.join(os.path.dirname(__file__), 'db', 'pypi.sqlite') db_session.global_init(db_file) diff --git a/app/ch13-validation/final/pypi_org/bin/basic_inserts.py b/app/ch13-validation/final/pypi_org/bin/basic_inserts.py index d622a6ae..6d04f551 100644 --- a/app/ch13-validation/final/pypi_org/bin/basic_inserts.py +++ b/app/ch13-validation/final/pypi_org/bin/basic_inserts.py @@ -2,8 +2,7 @@ import sys # Make it run more easily outside of PyCharm -sys.path.insert(0, os.path.abspath(os.path.join( - os.path.dirname(__file__), "..", ".."))) +sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..'))) import pypi_org.data.db_session as db_session from pypi_org.data.package import Package @@ -20,24 +19,24 @@ def insert_a_package(): p = Package() p.id = input('Package id / name: ').strip().lower() - p.summary = input("Package summary: ").strip() - p.author_name = input("Author: ").strip() - p.license = input("License: ").strip() + p.summary = input('Package summary: ').strip() + p.author_name = input('Author: ').strip() + p.license = input('License: ').strip() - print("Release 1:") + print('Release 1:') r = Release() - r.major_ver = int(input("Major version: ")) - r.minor_ver = int(input("Minor version: ")) - r.build_ver = int(input("Build version: ")) - r.size = int(input("Size in bytes: ")) + r.major_ver = int(input('Major version: ')) + r.minor_ver = int(input('Minor version: ')) + r.build_ver = int(input('Build version: ')) + r.size = int(input('Size in bytes: ')) p.releases.append(r) - print("Release 2:") + print('Release 2:') r = Release() - r.major_ver = int(input("Major version: ")) - r.minor_ver = int(input("Minor version: ")) - r.build_ver = int(input("Build version: ")) - r.size = int(input("Size in bytes: ")) + r.major_ver = int(input('Major version: ')) + r.minor_ver = int(input('Minor version: ')) + r.build_ver = int(input('Build version: ')) + r.size = int(input('Size in bytes: ')) p.releases.append(r) session = db_session.create_session() diff --git a/app/ch13-validation/final/pypi_org/bin/load_data.py b/app/ch13-validation/final/pypi_org/bin/load_data.py index 277a48f8..d64cb582 100644 --- a/app/ch13-validation/final/pypi_org/bin/load_data.py +++ b/app/ch13-validation/final/pypi_org/bin/load_data.py @@ -7,8 +7,7 @@ import progressbar from dateutil.parser import parse -sys.path.insert(0, os.path.abspath(os.path.join( - os.path.dirname(__file__), "..", ".."))) +sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..'))) from pypi_org.bin.load_data import try_int import pypi_org.data.db_session as db_session @@ -40,7 +39,7 @@ def main(): def do_import_languages(file_data: List[dict]): imported = set() - print("Importing languages ... ", flush=True) + print('Importing languages ... ', flush=True) with progressbar.ProgressBar(max_value=len(file_data)) as bar: for idx, p in enumerate(file_data): info = p.get('info') @@ -75,7 +74,7 @@ def do_import_languages(file_data: List[dict]): def do_import_licenses(file_data: List[dict]): imported = set() - print("Importing licenses ... ", flush=True) + print('Importing licenses ... ', flush=True) with progressbar.ProgressBar(max_value=len(file_data)) as bar: for idx, p in enumerate(file_data): info = p.get('info') @@ -101,17 +100,17 @@ def do_import_licenses(file_data: List[dict]): def do_summary(): session = db_session.create_session() - print("Final numbers:") - print("Users: {:,}".format(session.query(User).count())) - print("Packages: {:,}".format(session.query(Package).count())) - print("Releases: {:,}".format(session.query(Release).count())) - print("Maintainers: {:,}".format(session.query(Maintainer).count())) - print("Languages: {:,}".format(session.query(ProgrammingLanguage).count())) - print("Licenses: {:,}".format(session.query(License).count())) + print('Final numbers:') + print('Users: {:,}'.format(session.query(User).count())) + print('Packages: {:,}'.format(session.query(Package).count())) + print('Releases: {:,}'.format(session.query(Release).count())) + print('Maintainers: {:,}'.format(session.query(Maintainer).count())) + print('Languages: {:,}'.format(session.query(ProgrammingLanguage).count())) + print('Licenses: {:,}'.format(session.query(License).count())) def do_user_import(user_lookup: Dict[str, str]) -> Dict[str, User]: - print("Importing users ... ", flush=True) + print('Importing users ... ', flush=True) with progressbar.ProgressBar(max_value=len(user_lookup)) as bar: for idx, (email, name) in enumerate(user_lookup.items()): session = db_session.create_session() @@ -135,29 +134,29 @@ def do_user_import(user_lookup: Dict[str, str]) -> Dict[str, User]: def do_import_packages(file_data: List[dict], user_lookup: Dict[str, User]): errored_packages = [] - print("Importing packages and releases ... ", flush=True) + print('Importing packages and releases ... ', flush=True) with progressbar.ProgressBar(max_value=len(file_data)) as bar: for idx, p in enumerate(file_data): try: load_package(p, user_lookup) bar.update(idx) except Exception as x: - errored_packages.append((p, " *** Errored out for package {}, {}".format(p.get('package_name'), x))) + errored_packages.append((p, ' *** Errored out for package {}, {}'.format(p.get('package_name'), x))) raise sys.stderr.flush() sys.stdout.flush() print() - print("Completed packages with {} errors.".format(len(errored_packages))) - for (p, txt) in errored_packages: + print('Completed packages with {} errors.'.format(len(errored_packages))) + for p, txt in errored_packages: print(txt) def do_load_files() -> List[dict]: data_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../../../data/pypi-top-100')) - print("Loading files from {}".format(data_path)) + print('Loading files from {}'.format(data_path)) files = get_file_names(data_path) - print("Found {:,} files, loading ...".format(len(files)), flush=True) - time.sleep(.1) + print('Found {:,} files, loading ...'.format(len(files)), flush=True) + time.sleep(0.1) file_data = [] with progressbar.ProgressBar(max_value=len(files)) as bar: @@ -172,7 +171,7 @@ def do_load_files() -> List[dict]: def find_users(data: List[dict]) -> dict: - print("Discovering users...", flush=True) + print('Discovering users...', flush=True) found_users = {} with progressbar.ProgressBar(max_value=len(data)) as bar: @@ -185,7 +184,7 @@ def find_users(data: List[dict]) -> dict: sys.stderr.flush() sys.stdout.flush() print() - print("Discovered {:,} users".format(len(found_users))) + print('Discovered {:,} users'.format(len(found_users))) print() return found_users @@ -216,7 +215,7 @@ def load_file_data(filename: str) -> dict: with open(filename, 'r', encoding='utf-8') as fin: data = json.load(fin) except Exception as x: - print("ERROR in file: {}, details: {}".format(filename, x), flush=True) + print('ERROR in file: {}, details: {}'.format(filename, x), flush=True) raise return data @@ -234,7 +233,7 @@ def load_package(data: dict, user_lookup: Dict[str, User]): p.author = info.get('author') p.author_email = info.get('author_email') - releases = build_releases(p.id, data.get("releases", {})) + releases = build_releases(p.id, data.get('releases', {})) if releases: p.created_date = releases[0].created_date @@ -284,18 +283,13 @@ def detect_license(license_text: str) -> Optional[str]: license_text = license_text.strip() if len(license_text) > 100 or '\n' in license_text: - return "CUSTOM" + return 'CUSTOM' - license_text = license_text \ - .replace('Software License', '') \ - .replace('License', '') + license_text = license_text.replace('Software License', '').replace('License', '') if '::' in license_text: # E.g. 'License :: OSI Approved :: Apache Software License' - return license_text \ - .split(':')[-1] \ - .replace(' ', ' ') \ - .strip() + return license_text.split(':')[-1].replace(' ', ' ').strip() return license_text.strip() @@ -351,9 +345,7 @@ def get_file_names(data_path: str) -> List[str]: files = [] for f in os.listdir(data_path): if f.endswith('.json'): - files.append( - os.path.abspath(os.path.join(data_path, f)) - ) + files.append(os.path.abspath(os.path.join(data_path, f))) files.sort() return files diff --git a/app/ch13-validation/final/pypi_org/data/__all_models.py b/app/ch13-validation/final/pypi_org/data/__all_models.py index f399ef54..ca4804ac 100644 --- a/app/ch13-validation/final/pypi_org/data/__all_models.py +++ b/app/ch13-validation/final/pypi_org/data/__all_models.py @@ -5,17 +5,24 @@ # noinspection PyUnresolvedReferences import pypi_org.data.audit + # noinspection PyUnresolvedReferences import pypi_org.data.downloads + # noinspection PyUnresolvedReferences import pypi_org.data.languages + # noinspection PyUnresolvedReferences import pypi_org.data.licenses + # noinspection PyUnresolvedReferences import pypi_org.data.maintainers + # noinspection PyUnresolvedReferences import pypi_org.data.package + # noinspection PyUnresolvedReferences import pypi_org.data.releases + # noinspection PyUnresolvedReferences import pypi_org.data.users diff --git a/app/ch13-validation/final/pypi_org/data/db_session.py b/app/ch13-validation/final/pypi_org/data/db_session.py index 39b135cc..86eb3fb2 100644 --- a/app/ch13-validation/final/pypi_org/data/db_session.py +++ b/app/ch13-validation/final/pypi_org/data/db_session.py @@ -14,15 +14,15 @@ def global_init(db_file: str): return if not db_file or not db_file.strip(): - raise Exception("You must specify a db file.") + raise Exception('You must specify a db file.') conn_str = 'sqlite:///' + db_file.strip() - print("Connecting to DB with {}".format(conn_str)) + print('Connecting to DB with {}'.format(conn_str)) # Adding check_same_thread = False after the recording. This can be an issue about # creating / owner thread when cleaning up sessions, etc. This is a sqlite restriction # that we probably don't care about in this example. - engine = sa.create_engine(conn_str, echo=False, connect_args={"check_same_thread": False}) + engine = sa.create_engine(conn_str, echo=False, connect_args={'check_same_thread': False}) __factory = orm.sessionmaker(bind=engine) # noinspection PyUnresolvedReferences diff --git a/app/ch13-validation/final/pypi_org/data/downloads.py b/app/ch13-validation/final/pypi_org/data/downloads.py index 66068f02..dd8afd65 100644 --- a/app/ch13-validation/final/pypi_org/data/downloads.py +++ b/app/ch13-validation/final/pypi_org/data/downloads.py @@ -7,8 +7,7 @@ class Download(SqlAlchemyBase): __tablename__ = 'downloads' id: int = sqlalchemy.Column(sqlalchemy.BigInteger, primary_key=True, autoincrement=True) - created_date: datetime.datetime = sqlalchemy.Column( - sqlalchemy.DateTime, default=datetime.datetime.now, index=True) + created_date: datetime.datetime = sqlalchemy.Column(sqlalchemy.DateTime, default=datetime.datetime.now, index=True) package_id: str = sqlalchemy.Column(sqlalchemy.String, index=True) release_id: int = sqlalchemy.Column(sqlalchemy.BigInteger, index=True) diff --git a/app/ch13-validation/final/pypi_org/data/languages.py b/app/ch13-validation/final/pypi_org/data/languages.py index 964b8444..3a73dde0 100644 --- a/app/ch13-validation/final/pypi_org/data/languages.py +++ b/app/ch13-validation/final/pypi_org/data/languages.py @@ -7,6 +7,5 @@ class ProgrammingLanguage(SqlAlchemyBase): __tablename__ = 'languages' id: str = sqlalchemy.Column(sqlalchemy.String, primary_key=True) - created_date: datetime.datetime = sqlalchemy.Column( - sqlalchemy.DateTime, default=datetime.datetime.now, index=True) + created_date: datetime.datetime = sqlalchemy.Column(sqlalchemy.DateTime, default=datetime.datetime.now, index=True) description: str = sqlalchemy.Column(sqlalchemy.String) diff --git a/app/ch13-validation/final/pypi_org/data/package.py b/app/ch13-validation/final/pypi_org/data/package.py index c3420d1b..16e6d156 100644 --- a/app/ch13-validation/final/pypi_org/data/package.py +++ b/app/ch13-validation/final/pypi_org/data/package.py @@ -26,11 +26,15 @@ class Package(SqlAlchemyBase): license: str = sa.Column(sa.String, index=True) # releases relationship - releases: List[Release] = orm.relation("Release", order_by=[ - Release.major_ver.desc(), - Release.minor_ver.desc(), - Release.build_ver.desc(), - ], back_populates='package') + releases: List[Release] = orm.relation( + 'Release', + order_by=[ + Release.major_ver.desc(), + Release.minor_ver.desc(), + Release.build_ver.desc(), + ], + back_populates='package', + ) def __repr__(self): return ''.format(self.id) diff --git a/app/ch13-validation/final/pypi_org/data/releases.py b/app/ch13-validation/final/pypi_org/data/releases.py index 7650e438..8596f65c 100644 --- a/app/ch13-validation/final/pypi_org/data/releases.py +++ b/app/ch13-validation/final/pypi_org/data/releases.py @@ -13,15 +13,13 @@ class Release(SqlAlchemyBase): minor_ver: int = sqlalchemy.Column(sqlalchemy.BigInteger, index=True) build_ver: int = sqlalchemy.Column(sqlalchemy.BigInteger, index=True) - created_date: datetime.datetime = sqlalchemy.Column(sqlalchemy.DateTime, - default=datetime.datetime.now, - index=True) + created_date: datetime.datetime = sqlalchemy.Column(sqlalchemy.DateTime, default=datetime.datetime.now, index=True) comment: str = sqlalchemy.Column(sqlalchemy.String) url: str = sqlalchemy.Column(sqlalchemy.String) size: int = sqlalchemy.Column(sqlalchemy.BigInteger) # Package relationship - package_id: str = sqlalchemy.Column(sqlalchemy.String, sqlalchemy.ForeignKey("packages.id")) + package_id: str = sqlalchemy.Column(sqlalchemy.String, sqlalchemy.ForeignKey('packages.id')) package = orm.relation('Package') @property diff --git a/app/ch13-validation/final/pypi_org/infrastructure/cookie_auth.py b/app/ch13-validation/final/pypi_org/infrastructure/cookie_auth.py index 44864438..c215c0af 100644 --- a/app/ch13-validation/final/pypi_org/infrastructure/cookie_auth.py +++ b/app/ch13-validation/final/pypi_org/infrastructure/cookie_auth.py @@ -11,7 +11,7 @@ def set_auth(response: Response, user_id: int): hash_val = __hash_text(str(user_id)) - val = "{}:{}".format(user_id, hash_val) + val = '{}:{}'.format(user_id, hash_val) response.set_cookie(auth_cookie_name, val, secure=False, httponly=True, samesite='Lax') @@ -33,7 +33,7 @@ def get_user_id_via_auth_cookie(request: Request) -> Optional[int]: hash_val = parts[1] hash_val_check = __hash_text(user_id) if hash_val != hash_val_check: - print("Warning: Hash mismatch, invalid cookie value") + print('Warning: Hash mismatch, invalid cookie value') return None return try_int(user_id) diff --git a/app/ch13-validation/final/pypi_org/infrastructure/request_dict.py b/app/ch13-validation/final/pypi_org/infrastructure/request_dict.py index d7ab10de..d44ae574 100644 --- a/app/ch13-validation/final/pypi_org/infrastructure/request_dict.py +++ b/app/ch13-validation/final/pypi_org/infrastructure/request_dict.py @@ -29,7 +29,7 @@ def create(default_val=None, **route_args) -> RequestDictionary: **args, # The key/value pairs in the URL query string **request.headers, # Header values **form, # The key/value pairs in the body, from a HTML post form - **route_args # And additional arguments the method access, if they want them merged. + **route_args, # And additional arguments the method access, if they want them merged. } return RequestDictionary(data, default_val=default_val) diff --git a/app/ch13-validation/final/pypi_org/infrastructure/view_modifiers.py b/app/ch13-validation/final/pypi_org/infrastructure/view_modifiers.py index 0978163e..d944c142 100644 --- a/app/ch13-validation/final/pypi_org/infrastructure/view_modifiers.py +++ b/app/ch13-validation/final/pypi_org/infrastructure/view_modifiers.py @@ -26,7 +26,8 @@ def view_method(*args, **kwargs): if template_file and not isinstance(response_val, dict): raise Exception( - "Invalid return type {}, we expected a dict as the return value.".format(type(response_val))) + 'Invalid return type {}, we expected a dict as the return value.'.format(type(response_val)) + ) if template_file: response_val = flask.render_template(template_file, **response_val) @@ -42,6 +43,7 @@ def view_method(*args, **kwargs): return response_inner + # # def template(template_file: str = None): # def template_inner(f): diff --git a/app/ch13-validation/final/pypi_org/services/package_service.py b/app/ch13-validation/final/pypi_org/services/package_service.py index 71d4d02f..c2675f8d 100644 --- a/app/ch13-validation/final/pypi_org/services/package_service.py +++ b/app/ch13-validation/final/pypi_org/services/package_service.py @@ -9,12 +9,13 @@ def get_latest_releases(limit=10) -> List[Release]: session = db_session.create_session() try: - - releases = session.query(Release). \ - options(sqlalchemy.orm.joinedload(Release.package)). \ - order_by(Release.created_date.desc()). \ - limit(limit). \ - all() + releases = ( + session.query(Release) + .options(sqlalchemy.orm.joinedload(Release.package)) + .order_by(Release.created_date.desc()) + .limit(limit) + .all() + ) finally: session.close() @@ -46,11 +47,12 @@ def get_package_by_id(package_id: str) -> Optional[Package]: session = db_session.create_session() try: - - package = session.query(Package) \ - .options(sqlalchemy.orm.joinedload(Package.releases)) \ - .filter(Package.id == package_id) \ + package = ( + session.query(Package) + .options(sqlalchemy.orm.joinedload(Package.releases)) + .filter(Package.id == package_id) .first() + ) finally: session.close() diff --git a/app/ch13-validation/final/pypi_org/viewmodels/cms/page_viewmodel.py b/app/ch13-validation/final/pypi_org/viewmodels/cms/page_viewmodel.py index b7bb3249..ec033c3f 100644 --- a/app/ch13-validation/final/pypi_org/viewmodels/cms/page_viewmodel.py +++ b/app/ch13-validation/final/pypi_org/viewmodels/cms/page_viewmodel.py @@ -7,4 +7,3 @@ def __init__(self, full_url: str): super().__init__() self.page = cms_service.get_page(full_url) - diff --git a/app/ch13-validation/final/pypi_org/viewmodels/packages/pagedetails_viewmodel.py b/app/ch13-validation/final/pypi_org/viewmodels/packages/pagedetails_viewmodel.py index 63c4cf68..09f47c6f 100644 --- a/app/ch13-validation/final/pypi_org/viewmodels/packages/pagedetails_viewmodel.py +++ b/app/ch13-validation/final/pypi_org/viewmodels/packages/pagedetails_viewmodel.py @@ -11,7 +11,7 @@ def __init__(self, package_name: str): self.package_name = package_name.strip().lower() self.package = package_service.get_package_by_id(self.package_name) - self.latest_version = "0.0.0" + self.latest_version = '0.0.0' self.latest_release = None self.is_latest = True diff --git a/app/ch13-validation/final/pypi_org/views/account_views.py b/app/ch13-validation/final/pypi_org/views/account_views.py index 8697cc24..83df8950 100644 --- a/app/ch13-validation/final/pypi_org/views/account_views.py +++ b/app/ch13-validation/final/pypi_org/views/account_views.py @@ -25,6 +25,7 @@ def index(): # ################### REGISTER ################################# + @blueprint.route('/account/register', methods=['GET']) @response(template_file='account/register.html') def register_get(): @@ -54,6 +55,7 @@ def register_post(): # ################### LOGIN ################################# + @blueprint.route('/account/login', methods=['GET']) @response(template_file='account/login.html') def login_get(): @@ -72,7 +74,7 @@ def login_post(): user = user_service.login_user(vm.email, vm.password) if not user: - vm.error = "The account does not exist or the password is wrong." + vm.error = 'The account does not exist or the password is wrong.' return vm.to_dict() resp = flask.redirect('/account') @@ -83,6 +85,7 @@ def login_post(): # ################### LOGOUT ################################# + @blueprint.route('/account/logout') def logout(): resp = flask.redirect('/') diff --git a/app/ch13-validation/final/pypi_org/views/package_views.py b/app/ch13-validation/final/pypi_org/views/package_views.py index 1a74549f..2f862740 100644 --- a/app/ch13-validation/final/pypi_org/views/package_views.py +++ b/app/ch13-validation/final/pypi_org/views/package_views.py @@ -19,4 +19,4 @@ def package_details(package_name: str): @blueprint.route('/') def popular(rank: int): print(type(rank), rank) - return "The details for the {}th most popular package".format(rank) + return 'The details for the {}th most popular package'.format(rank) diff --git a/app/ch13-validation/starter/alembic/alembic_helpers.py b/app/ch13-validation/starter/alembic/alembic_helpers.py index 561f7a70..6aea52d4 100644 --- a/app/ch13-validation/starter/alembic/alembic_helpers.py +++ b/app/ch13-validation/starter/alembic/alembic_helpers.py @@ -5,8 +5,7 @@ def table_has_column(table, column): config = op.get_context().config - engine = engine_from_config( - config.get_section(config.config_ini_section), prefix='sqlalchemy.') + engine = engine_from_config(config.get_section(config.config_ini_section), prefix='sqlalchemy.') insp = reflection.Inspector.from_engine(engine) has_column = False for col in insp.get_columns(table): diff --git a/app/ch13-validation/starter/alembic/env.py b/app/ch13-validation/starter/alembic/env.py index 27ec49fb..1fdc9cab 100644 --- a/app/ch13-validation/starter/alembic/env.py +++ b/app/ch13-validation/starter/alembic/env.py @@ -26,6 +26,7 @@ sys.path.insert(0, folder) from pypi_org.data.modelbase import SqlAlchemyBase + # noinspection PyUnresolvedReferences import pypi_org.data.__all_models @@ -49,10 +50,8 @@ def run_migrations_offline(): script output. """ - url = config.get_main_option("sqlalchemy.url") - context.configure( - url=url, target_metadata=target_metadata, literal_binds=True - ) + url = config.get_main_option('sqlalchemy.url') + context.configure(url=url, target_metadata=target_metadata, literal_binds=True) with context.begin_transaction(): context.run_migrations() @@ -67,14 +66,12 @@ def run_migrations_online(): """ connectable = engine_from_config( config.get_section(config.config_ini_section), - prefix="sqlalchemy.", + prefix='sqlalchemy.', poolclass=pool.NullPool, ) with connectable.connect() as connection: - context.configure( - connection=connection, target_metadata=target_metadata - ) + context.configure(connection=connection, target_metadata=target_metadata) with context.begin_transaction(): context.run_migrations() diff --git a/app/ch13-validation/starter/alembic/versions/722c82f0097c_added_auditing_table.py b/app/ch13-validation/starter/alembic/versions/722c82f0097c_added_auditing_table.py index 2c3e2a39..7c6e892f 100644 --- a/app/ch13-validation/starter/alembic/versions/722c82f0097c_added_auditing_table.py +++ b/app/ch13-validation/starter/alembic/versions/722c82f0097c_added_auditing_table.py @@ -18,11 +18,12 @@ def upgrade(): # ### commands auto generated by Alembic - please adjust! ### - op.create_table('auditing', - sa.Column('id', sa.String(), nullable=False), - sa.Column('created_date', sa.DateTime(), nullable=True), - sa.Column('description', sa.String(), nullable=True), - sa.PrimaryKeyConstraint('id') + op.create_table( + 'auditing', + sa.Column('id', sa.String(), nullable=False), + sa.Column('created_date', sa.DateTime(), nullable=True), + sa.Column('description', sa.String(), nullable=True), + sa.PrimaryKeyConstraint('id'), ) op.create_index(op.f('ix_auditing_created_date'), 'auditing', ['created_date'], unique=False) # ### end Alembic commands ### diff --git a/app/ch13-validation/starter/pypi_org/app.py b/app/ch13-validation/starter/pypi_org/app.py index 89004d09..9b491bad 100644 --- a/app/ch13-validation/starter/pypi_org/app.py +++ b/app/ch13-validation/starter/pypi_org/app.py @@ -1,6 +1,7 @@ import os import sys import flask + folder = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) sys.path.insert(0, folder) @@ -16,10 +17,7 @@ def main(): def setup_db(): - db_file = os.path.join( - os.path.dirname(__file__), - 'db', - 'pypi.sqlite') + db_file = os.path.join(os.path.dirname(__file__), 'db', 'pypi.sqlite') db_session.global_init(db_file) diff --git a/app/ch13-validation/starter/pypi_org/bin/basic_inserts.py b/app/ch13-validation/starter/pypi_org/bin/basic_inserts.py index d622a6ae..6d04f551 100644 --- a/app/ch13-validation/starter/pypi_org/bin/basic_inserts.py +++ b/app/ch13-validation/starter/pypi_org/bin/basic_inserts.py @@ -2,8 +2,7 @@ import sys # Make it run more easily outside of PyCharm -sys.path.insert(0, os.path.abspath(os.path.join( - os.path.dirname(__file__), "..", ".."))) +sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..'))) import pypi_org.data.db_session as db_session from pypi_org.data.package import Package @@ -20,24 +19,24 @@ def insert_a_package(): p = Package() p.id = input('Package id / name: ').strip().lower() - p.summary = input("Package summary: ").strip() - p.author_name = input("Author: ").strip() - p.license = input("License: ").strip() + p.summary = input('Package summary: ').strip() + p.author_name = input('Author: ').strip() + p.license = input('License: ').strip() - print("Release 1:") + print('Release 1:') r = Release() - r.major_ver = int(input("Major version: ")) - r.minor_ver = int(input("Minor version: ")) - r.build_ver = int(input("Build version: ")) - r.size = int(input("Size in bytes: ")) + r.major_ver = int(input('Major version: ')) + r.minor_ver = int(input('Minor version: ')) + r.build_ver = int(input('Build version: ')) + r.size = int(input('Size in bytes: ')) p.releases.append(r) - print("Release 2:") + print('Release 2:') r = Release() - r.major_ver = int(input("Major version: ")) - r.minor_ver = int(input("Minor version: ")) - r.build_ver = int(input("Build version: ")) - r.size = int(input("Size in bytes: ")) + r.major_ver = int(input('Major version: ')) + r.minor_ver = int(input('Minor version: ')) + r.build_ver = int(input('Build version: ')) + r.size = int(input('Size in bytes: ')) p.releases.append(r) session = db_session.create_session() diff --git a/app/ch13-validation/starter/pypi_org/bin/load_data.py b/app/ch13-validation/starter/pypi_org/bin/load_data.py index 8f43c13c..228c1b6b 100644 --- a/app/ch13-validation/starter/pypi_org/bin/load_data.py +++ b/app/ch13-validation/starter/pypi_org/bin/load_data.py @@ -7,8 +7,7 @@ import progressbar from dateutil.parser import parse -sys.path.insert(0, os.path.abspath(os.path.join( - os.path.dirname(__file__), "..", ".."))) +sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..'))) import pypi_org.data.db_session as db_session from pypi_org.data.languages import ProgrammingLanguage @@ -39,7 +38,7 @@ def main(): def do_import_languages(file_data: List[dict]): imported = set() - print("Importing languages ... ", flush=True) + print('Importing languages ... ', flush=True) with progressbar.ProgressBar(max_value=len(file_data)) as bar: for idx, p in enumerate(file_data): info = p.get('info') @@ -74,7 +73,7 @@ def do_import_languages(file_data: List[dict]): def do_import_licenses(file_data: List[dict]): imported = set() - print("Importing licenses ... ", flush=True) + print('Importing licenses ... ', flush=True) with progressbar.ProgressBar(max_value=len(file_data)) as bar: for idx, p in enumerate(file_data): info = p.get('info') @@ -100,17 +99,17 @@ def do_import_licenses(file_data: List[dict]): def do_summary(): session = db_session.create_session() - print("Final numbers:") - print("Users: {:,}".format(session.query(User).count())) - print("Packages: {:,}".format(session.query(Package).count())) - print("Releases: {:,}".format(session.query(Release).count())) - print("Maintainers: {:,}".format(session.query(Maintainer).count())) - print("Languages: {:,}".format(session.query(ProgrammingLanguage).count())) - print("Licenses: {:,}".format(session.query(License).count())) + print('Final numbers:') + print('Users: {:,}'.format(session.query(User).count())) + print('Packages: {:,}'.format(session.query(Package).count())) + print('Releases: {:,}'.format(session.query(Release).count())) + print('Maintainers: {:,}'.format(session.query(Maintainer).count())) + print('Languages: {:,}'.format(session.query(ProgrammingLanguage).count())) + print('Licenses: {:,}'.format(session.query(License).count())) def do_user_import(user_lookup: Dict[str, str]) -> Dict[str, User]: - print("Importing users ... ", flush=True) + print('Importing users ... ', flush=True) with progressbar.ProgressBar(max_value=len(user_lookup)) as bar: for idx, (email, name) in enumerate(user_lookup.items()): session = db_session.create_session() @@ -134,29 +133,29 @@ def do_user_import(user_lookup: Dict[str, str]) -> Dict[str, User]: def do_import_packages(file_data: List[dict], user_lookup: Dict[str, User]): errored_packages = [] - print("Importing packages and releases ... ", flush=True) + print('Importing packages and releases ... ', flush=True) with progressbar.ProgressBar(max_value=len(file_data)) as bar: for idx, p in enumerate(file_data): try: load_package(p, user_lookup) bar.update(idx) except Exception as x: - errored_packages.append((p, " *** Errored out for package {}, {}".format(p.get('package_name'), x))) + errored_packages.append((p, ' *** Errored out for package {}, {}'.format(p.get('package_name'), x))) raise sys.stderr.flush() sys.stdout.flush() print() - print("Completed packages with {} errors.".format(len(errored_packages))) - for (p, txt) in errored_packages: + print('Completed packages with {} errors.'.format(len(errored_packages))) + for p, txt in errored_packages: print(txt) def do_load_files() -> List[dict]: data_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../../../data/pypi-top-100')) - print("Loading files from {}".format(data_path)) + print('Loading files from {}'.format(data_path)) files = get_file_names(data_path) - print("Found {:,} files, loading ...".format(len(files)), flush=True) - time.sleep(.1) + print('Found {:,} files, loading ...'.format(len(files)), flush=True) + time.sleep(0.1) file_data = [] with progressbar.ProgressBar(max_value=len(files)) as bar: @@ -171,7 +170,7 @@ def do_load_files() -> List[dict]: def find_users(data: List[dict]) -> dict: - print("Discovering users...", flush=True) + print('Discovering users...', flush=True) found_users = {} with progressbar.ProgressBar(max_value=len(data)) as bar: @@ -184,7 +183,7 @@ def find_users(data: List[dict]) -> dict: sys.stderr.flush() sys.stdout.flush() print() - print("Discovered {:,} users".format(len(found_users))) + print('Discovered {:,} users'.format(len(found_users))) print() return found_users @@ -215,7 +214,7 @@ def load_file_data(filename: str) -> dict: with open(filename, 'r', encoding='utf-8') as fin: data = json.load(fin) except Exception as x: - print("ERROR in file: {}, details: {}".format(filename, x), flush=True) + print('ERROR in file: {}, details: {}'.format(filename, x), flush=True) raise return data @@ -233,7 +232,7 @@ def load_package(data: dict, user_lookup: Dict[str, User]): p.author = info.get('author') p.author_email = info.get('author_email') - releases = build_releases(p.id, data.get("releases", {})) + releases = build_releases(p.id, data.get('releases', {})) if releases: p.created_date = releases[0].created_date @@ -283,18 +282,13 @@ def detect_license(license_text: str) -> Optional[str]: license_text = license_text.strip() if len(license_text) > 100 or '\n' in license_text: - return "CUSTOM" + return 'CUSTOM' - license_text = license_text \ - .replace('Software License', '') \ - .replace('License', '') + license_text = license_text.replace('Software License', '').replace('License', '') if '::' in license_text: # E.g. 'License :: OSI Approved :: Apache Software License' - return license_text \ - .split(':')[-1] \ - .replace(' ', ' ') \ - .strip() + return license_text.split(':')[-1].replace(' ', ' ').strip() return license_text.strip() @@ -357,9 +351,7 @@ def get_file_names(data_path: str) -> List[str]: files = [] for f in os.listdir(data_path): if f.endswith('.json'): - files.append( - os.path.abspath(os.path.join(data_path, f)) - ) + files.append(os.path.abspath(os.path.join(data_path, f))) files.sort() return files diff --git a/app/ch13-validation/starter/pypi_org/data/__all_models.py b/app/ch13-validation/starter/pypi_org/data/__all_models.py index f399ef54..ca4804ac 100644 --- a/app/ch13-validation/starter/pypi_org/data/__all_models.py +++ b/app/ch13-validation/starter/pypi_org/data/__all_models.py @@ -5,17 +5,24 @@ # noinspection PyUnresolvedReferences import pypi_org.data.audit + # noinspection PyUnresolvedReferences import pypi_org.data.downloads + # noinspection PyUnresolvedReferences import pypi_org.data.languages + # noinspection PyUnresolvedReferences import pypi_org.data.licenses + # noinspection PyUnresolvedReferences import pypi_org.data.maintainers + # noinspection PyUnresolvedReferences import pypi_org.data.package + # noinspection PyUnresolvedReferences import pypi_org.data.releases + # noinspection PyUnresolvedReferences import pypi_org.data.users diff --git a/app/ch13-validation/starter/pypi_org/data/db_session.py b/app/ch13-validation/starter/pypi_org/data/db_session.py index addbaff9..62391b85 100644 --- a/app/ch13-validation/starter/pypi_org/data/db_session.py +++ b/app/ch13-validation/starter/pypi_org/data/db_session.py @@ -14,15 +14,15 @@ def global_init(db_file: str): return if not db_file or not db_file.strip(): - raise Exception("You must specify a db file.") + raise Exception('You must specify a db file.') conn_str = 'sqlite:///' + db_file.strip() - print("Connecting to DB with {}".format(conn_str)) + print('Connecting to DB with {}'.format(conn_str)) # Adding check_same_thread = False after the recording. This can be an issue about # creating / owner thread when cleaning up sessions, etc. This is a sqlite restriction # that we probably don't care about in this example. - engine = sa.create_engine(conn_str, echo=False, connect_args={"check_same_thread": False}) + engine = sa.create_engine(conn_str, echo=False, connect_args={'check_same_thread': False}) __factory = orm.sessionmaker(bind=engine) # noinspection PyUnresolvedReferences diff --git a/app/ch13-validation/starter/pypi_org/data/downloads.py b/app/ch13-validation/starter/pypi_org/data/downloads.py index 66068f02..dd8afd65 100644 --- a/app/ch13-validation/starter/pypi_org/data/downloads.py +++ b/app/ch13-validation/starter/pypi_org/data/downloads.py @@ -7,8 +7,7 @@ class Download(SqlAlchemyBase): __tablename__ = 'downloads' id: int = sqlalchemy.Column(sqlalchemy.BigInteger, primary_key=True, autoincrement=True) - created_date: datetime.datetime = sqlalchemy.Column( - sqlalchemy.DateTime, default=datetime.datetime.now, index=True) + created_date: datetime.datetime = sqlalchemy.Column(sqlalchemy.DateTime, default=datetime.datetime.now, index=True) package_id: str = sqlalchemy.Column(sqlalchemy.String, index=True) release_id: int = sqlalchemy.Column(sqlalchemy.BigInteger, index=True) diff --git a/app/ch13-validation/starter/pypi_org/data/languages.py b/app/ch13-validation/starter/pypi_org/data/languages.py index 964b8444..3a73dde0 100644 --- a/app/ch13-validation/starter/pypi_org/data/languages.py +++ b/app/ch13-validation/starter/pypi_org/data/languages.py @@ -7,6 +7,5 @@ class ProgrammingLanguage(SqlAlchemyBase): __tablename__ = 'languages' id: str = sqlalchemy.Column(sqlalchemy.String, primary_key=True) - created_date: datetime.datetime = sqlalchemy.Column( - sqlalchemy.DateTime, default=datetime.datetime.now, index=True) + created_date: datetime.datetime = sqlalchemy.Column(sqlalchemy.DateTime, default=datetime.datetime.now, index=True) description: str = sqlalchemy.Column(sqlalchemy.String) diff --git a/app/ch13-validation/starter/pypi_org/data/package.py b/app/ch13-validation/starter/pypi_org/data/package.py index c3420d1b..16e6d156 100644 --- a/app/ch13-validation/starter/pypi_org/data/package.py +++ b/app/ch13-validation/starter/pypi_org/data/package.py @@ -26,11 +26,15 @@ class Package(SqlAlchemyBase): license: str = sa.Column(sa.String, index=True) # releases relationship - releases: List[Release] = orm.relation("Release", order_by=[ - Release.major_ver.desc(), - Release.minor_ver.desc(), - Release.build_ver.desc(), - ], back_populates='package') + releases: List[Release] = orm.relation( + 'Release', + order_by=[ + Release.major_ver.desc(), + Release.minor_ver.desc(), + Release.build_ver.desc(), + ], + back_populates='package', + ) def __repr__(self): return ''.format(self.id) diff --git a/app/ch13-validation/starter/pypi_org/data/releases.py b/app/ch13-validation/starter/pypi_org/data/releases.py index 7650e438..8596f65c 100644 --- a/app/ch13-validation/starter/pypi_org/data/releases.py +++ b/app/ch13-validation/starter/pypi_org/data/releases.py @@ -13,15 +13,13 @@ class Release(SqlAlchemyBase): minor_ver: int = sqlalchemy.Column(sqlalchemy.BigInteger, index=True) build_ver: int = sqlalchemy.Column(sqlalchemy.BigInteger, index=True) - created_date: datetime.datetime = sqlalchemy.Column(sqlalchemy.DateTime, - default=datetime.datetime.now, - index=True) + created_date: datetime.datetime = sqlalchemy.Column(sqlalchemy.DateTime, default=datetime.datetime.now, index=True) comment: str = sqlalchemy.Column(sqlalchemy.String) url: str = sqlalchemy.Column(sqlalchemy.String) size: int = sqlalchemy.Column(sqlalchemy.BigInteger) # Package relationship - package_id: str = sqlalchemy.Column(sqlalchemy.String, sqlalchemy.ForeignKey("packages.id")) + package_id: str = sqlalchemy.Column(sqlalchemy.String, sqlalchemy.ForeignKey('packages.id')) package = orm.relation('Package') @property diff --git a/app/ch13-validation/starter/pypi_org/infrastructure/cookie_auth.py b/app/ch13-validation/starter/pypi_org/infrastructure/cookie_auth.py index 44864438..c215c0af 100644 --- a/app/ch13-validation/starter/pypi_org/infrastructure/cookie_auth.py +++ b/app/ch13-validation/starter/pypi_org/infrastructure/cookie_auth.py @@ -11,7 +11,7 @@ def set_auth(response: Response, user_id: int): hash_val = __hash_text(str(user_id)) - val = "{}:{}".format(user_id, hash_val) + val = '{}:{}'.format(user_id, hash_val) response.set_cookie(auth_cookie_name, val, secure=False, httponly=True, samesite='Lax') @@ -33,7 +33,7 @@ def get_user_id_via_auth_cookie(request: Request) -> Optional[int]: hash_val = parts[1] hash_val_check = __hash_text(user_id) if hash_val != hash_val_check: - print("Warning: Hash mismatch, invalid cookie value") + print('Warning: Hash mismatch, invalid cookie value') return None return try_int(user_id) diff --git a/app/ch13-validation/starter/pypi_org/infrastructure/request_dict.py b/app/ch13-validation/starter/pypi_org/infrastructure/request_dict.py index d7ab10de..d44ae574 100644 --- a/app/ch13-validation/starter/pypi_org/infrastructure/request_dict.py +++ b/app/ch13-validation/starter/pypi_org/infrastructure/request_dict.py @@ -29,7 +29,7 @@ def create(default_val=None, **route_args) -> RequestDictionary: **args, # The key/value pairs in the URL query string **request.headers, # Header values **form, # The key/value pairs in the body, from a HTML post form - **route_args # And additional arguments the method access, if they want them merged. + **route_args, # And additional arguments the method access, if they want them merged. } return RequestDictionary(data, default_val=default_val) diff --git a/app/ch13-validation/starter/pypi_org/infrastructure/view_modifiers.py b/app/ch13-validation/starter/pypi_org/infrastructure/view_modifiers.py index 0978163e..d944c142 100644 --- a/app/ch13-validation/starter/pypi_org/infrastructure/view_modifiers.py +++ b/app/ch13-validation/starter/pypi_org/infrastructure/view_modifiers.py @@ -26,7 +26,8 @@ def view_method(*args, **kwargs): if template_file and not isinstance(response_val, dict): raise Exception( - "Invalid return type {}, we expected a dict as the return value.".format(type(response_val))) + 'Invalid return type {}, we expected a dict as the return value.'.format(type(response_val)) + ) if template_file: response_val = flask.render_template(template_file, **response_val) @@ -42,6 +43,7 @@ def view_method(*args, **kwargs): return response_inner + # # def template(template_file: str = None): # def template_inner(f): diff --git a/app/ch13-validation/starter/pypi_org/services/package_service.py b/app/ch13-validation/starter/pypi_org/services/package_service.py index e51241ae..6ac445e6 100644 --- a/app/ch13-validation/starter/pypi_org/services/package_service.py +++ b/app/ch13-validation/starter/pypi_org/services/package_service.py @@ -9,11 +9,13 @@ def get_latest_releases(limit=10) -> List[Release]: session = db_session.create_session() - releases = session.query(Release). \ - options(sqlalchemy.orm.joinedload(Release.package)). \ - order_by(Release.created_date.desc()). \ - limit(limit). \ - all() + releases = ( + session.query(Release) + .options(sqlalchemy.orm.joinedload(Release.package)) + .order_by(Release.created_date.desc()) + .limit(limit) + .all() + ) session.close() @@ -38,10 +40,12 @@ def get_package_by_id(package_id: str) -> Optional[Package]: session = db_session.create_session() - package = session.query(Package) \ - .options(sqlalchemy.orm.joinedload(Package.releases)) \ - .filter(Package.id == package_id) \ + package = ( + session.query(Package) + .options(sqlalchemy.orm.joinedload(Package.releases)) + .filter(Package.id == package_id) .first() + ) session.close() diff --git a/app/ch13-validation/starter/pypi_org/views/account_views.py b/app/ch13-validation/starter/pypi_org/views/account_views.py index f127310b..877231ba 100644 --- a/app/ch13-validation/starter/pypi_org/views/account_views.py +++ b/app/ch13-validation/starter/pypi_org/views/account_views.py @@ -30,6 +30,7 @@ def index(): # ################### REGISTER ################################# + @blueprint.route('/account/register', methods=['GET']) @response(template_file='account/register.html') def register_get(): @@ -52,7 +53,7 @@ def register_post(): 'name': name, 'email': email, 'password': password, - 'error': "Some required fields are missing.", + 'error': 'Some required fields are missing.', 'user_id': cookie_auth.get_user_id_via_auth_cookie(flask.request), } @@ -62,7 +63,7 @@ def register_post(): 'name': name, 'email': email, 'password': password, - 'error': "A user with that email already exists.", + 'error': 'A user with that email already exists.', 'user_id': cookie_auth.get_user_id_via_auth_cookie(flask.request), } @@ -74,6 +75,7 @@ def register_post(): # ################### LOGIN ################################# + @blueprint.route('/account/login', methods=['GET']) @response(template_file='account/login.html') def login_get(): @@ -92,7 +94,7 @@ def login_post(): return { 'email': email, 'password': password, - 'error': "Some required fields are missing.", + 'error': 'Some required fields are missing.', 'user_id': cookie_auth.get_user_id_via_auth_cookie(flask.request), } @@ -101,7 +103,7 @@ def login_post(): return { 'email': email, 'password': password, - 'error': "The account does not exist or the password is wrong.", + 'error': 'The account does not exist or the password is wrong.', 'user_id': cookie_auth.get_user_id_via_auth_cookie(flask.request), } @@ -113,6 +115,7 @@ def login_post(): # ################### LOGOUT ################################# + @blueprint.route('/account/logout') def logout(): resp = flask.redirect('/') diff --git a/app/ch13-validation/starter/pypi_org/views/cms_views.py b/app/ch13-validation/starter/pypi_org/views/cms_views.py index f7172d3d..a8b755a8 100644 --- a/app/ch13-validation/starter/pypi_org/views/cms_views.py +++ b/app/ch13-validation/starter/pypi_org/views/cms_views.py @@ -9,7 +9,7 @@ @blueprint.route('/') @response(template_file='cms/page.html') def cms_page(full_url: str): - print("Getting CMS page for {}".format(full_url)) + print('Getting CMS page for {}'.format(full_url)) page = cms_service.get_page(full_url) if not page: diff --git a/app/ch13-validation/starter/pypi_org/views/package_views.py b/app/ch13-validation/starter/pypi_org/views/package_views.py index f1ad7811..2587b704 100644 --- a/app/ch13-validation/starter/pypi_org/views/package_views.py +++ b/app/ch13-validation/starter/pypi_org/views/package_views.py @@ -17,7 +17,7 @@ def package_details(package_name: str): if not package: return flask.abort(status=404) - latest_version = "0.0.0" + latest_version = '0.0.0' latest_release = None is_latest = True @@ -38,4 +38,4 @@ def package_details(package_name: str): @blueprint.route('/') def popular(rank: int): print(type(rank), rank) - return "The details for the {}th most popular package".format(rank) + return 'The details for the {}th most popular package'.format(rank) diff --git a/app/ch14_testing/final/alembic/alembic_helpers.py b/app/ch14_testing/final/alembic/alembic_helpers.py index 561f7a70..6aea52d4 100644 --- a/app/ch14_testing/final/alembic/alembic_helpers.py +++ b/app/ch14_testing/final/alembic/alembic_helpers.py @@ -5,8 +5,7 @@ def table_has_column(table, column): config = op.get_context().config - engine = engine_from_config( - config.get_section(config.config_ini_section), prefix='sqlalchemy.') + engine = engine_from_config(config.get_section(config.config_ini_section), prefix='sqlalchemy.') insp = reflection.Inspector.from_engine(engine) has_column = False for col in insp.get_columns(table): diff --git a/app/ch14_testing/final/alembic/env.py b/app/ch14_testing/final/alembic/env.py index 27ec49fb..1fdc9cab 100644 --- a/app/ch14_testing/final/alembic/env.py +++ b/app/ch14_testing/final/alembic/env.py @@ -26,6 +26,7 @@ sys.path.insert(0, folder) from pypi_org.data.modelbase import SqlAlchemyBase + # noinspection PyUnresolvedReferences import pypi_org.data.__all_models @@ -49,10 +50,8 @@ def run_migrations_offline(): script output. """ - url = config.get_main_option("sqlalchemy.url") - context.configure( - url=url, target_metadata=target_metadata, literal_binds=True - ) + url = config.get_main_option('sqlalchemy.url') + context.configure(url=url, target_metadata=target_metadata, literal_binds=True) with context.begin_transaction(): context.run_migrations() @@ -67,14 +66,12 @@ def run_migrations_online(): """ connectable = engine_from_config( config.get_section(config.config_ini_section), - prefix="sqlalchemy.", + prefix='sqlalchemy.', poolclass=pool.NullPool, ) with connectable.connect() as connection: - context.configure( - connection=connection, target_metadata=target_metadata - ) + context.configure(connection=connection, target_metadata=target_metadata) with context.begin_transaction(): context.run_migrations() diff --git a/app/ch14_testing/final/alembic/versions/722c82f0097c_added_auditing_table.py b/app/ch14_testing/final/alembic/versions/722c82f0097c_added_auditing_table.py index 2c3e2a39..7c6e892f 100644 --- a/app/ch14_testing/final/alembic/versions/722c82f0097c_added_auditing_table.py +++ b/app/ch14_testing/final/alembic/versions/722c82f0097c_added_auditing_table.py @@ -18,11 +18,12 @@ def upgrade(): # ### commands auto generated by Alembic - please adjust! ### - op.create_table('auditing', - sa.Column('id', sa.String(), nullable=False), - sa.Column('created_date', sa.DateTime(), nullable=True), - sa.Column('description', sa.String(), nullable=True), - sa.PrimaryKeyConstraint('id') + op.create_table( + 'auditing', + sa.Column('id', sa.String(), nullable=False), + sa.Column('created_date', sa.DateTime(), nullable=True), + sa.Column('description', sa.String(), nullable=True), + sa.PrimaryKeyConstraint('id'), ) op.create_index(op.f('ix_auditing_created_date'), 'auditing', ['created_date'], unique=False) # ### end Alembic commands ### diff --git a/app/ch14_testing/final/pypi_org/app.py b/app/ch14_testing/final/pypi_org/app.py index 6ecc1c13..23eafbe9 100644 --- a/app/ch14_testing/final/pypi_org/app.py +++ b/app/ch14_testing/final/pypi_org/app.py @@ -2,6 +2,7 @@ import sys import flask + folder = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) sys.path.insert(0, folder) import pypi_org.data.db_session as db_session @@ -16,10 +17,7 @@ def main(): def setup_db(): - db_file = os.path.join( - os.path.dirname(__file__), - 'db', - 'pypi.sqlite') + db_file = os.path.join(os.path.dirname(__file__), 'db', 'pypi.sqlite') db_session.global_init(db_file) diff --git a/app/ch14_testing/final/pypi_org/bin/basic_inserts.py b/app/ch14_testing/final/pypi_org/bin/basic_inserts.py index d622a6ae..6d04f551 100644 --- a/app/ch14_testing/final/pypi_org/bin/basic_inserts.py +++ b/app/ch14_testing/final/pypi_org/bin/basic_inserts.py @@ -2,8 +2,7 @@ import sys # Make it run more easily outside of PyCharm -sys.path.insert(0, os.path.abspath(os.path.join( - os.path.dirname(__file__), "..", ".."))) +sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..'))) import pypi_org.data.db_session as db_session from pypi_org.data.package import Package @@ -20,24 +19,24 @@ def insert_a_package(): p = Package() p.id = input('Package id / name: ').strip().lower() - p.summary = input("Package summary: ").strip() - p.author_name = input("Author: ").strip() - p.license = input("License: ").strip() + p.summary = input('Package summary: ').strip() + p.author_name = input('Author: ').strip() + p.license = input('License: ').strip() - print("Release 1:") + print('Release 1:') r = Release() - r.major_ver = int(input("Major version: ")) - r.minor_ver = int(input("Minor version: ")) - r.build_ver = int(input("Build version: ")) - r.size = int(input("Size in bytes: ")) + r.major_ver = int(input('Major version: ')) + r.minor_ver = int(input('Minor version: ')) + r.build_ver = int(input('Build version: ')) + r.size = int(input('Size in bytes: ')) p.releases.append(r) - print("Release 2:") + print('Release 2:') r = Release() - r.major_ver = int(input("Major version: ")) - r.minor_ver = int(input("Minor version: ")) - r.build_ver = int(input("Build version: ")) - r.size = int(input("Size in bytes: ")) + r.major_ver = int(input('Major version: ')) + r.minor_ver = int(input('Minor version: ')) + r.build_ver = int(input('Build version: ')) + r.size = int(input('Size in bytes: ')) p.releases.append(r) session = db_session.create_session() diff --git a/app/ch14_testing/final/pypi_org/bin/load_data.py b/app/ch14_testing/final/pypi_org/bin/load_data.py index 8f43c13c..228c1b6b 100644 --- a/app/ch14_testing/final/pypi_org/bin/load_data.py +++ b/app/ch14_testing/final/pypi_org/bin/load_data.py @@ -7,8 +7,7 @@ import progressbar from dateutil.parser import parse -sys.path.insert(0, os.path.abspath(os.path.join( - os.path.dirname(__file__), "..", ".."))) +sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..'))) import pypi_org.data.db_session as db_session from pypi_org.data.languages import ProgrammingLanguage @@ -39,7 +38,7 @@ def main(): def do_import_languages(file_data: List[dict]): imported = set() - print("Importing languages ... ", flush=True) + print('Importing languages ... ', flush=True) with progressbar.ProgressBar(max_value=len(file_data)) as bar: for idx, p in enumerate(file_data): info = p.get('info') @@ -74,7 +73,7 @@ def do_import_languages(file_data: List[dict]): def do_import_licenses(file_data: List[dict]): imported = set() - print("Importing licenses ... ", flush=True) + print('Importing licenses ... ', flush=True) with progressbar.ProgressBar(max_value=len(file_data)) as bar: for idx, p in enumerate(file_data): info = p.get('info') @@ -100,17 +99,17 @@ def do_import_licenses(file_data: List[dict]): def do_summary(): session = db_session.create_session() - print("Final numbers:") - print("Users: {:,}".format(session.query(User).count())) - print("Packages: {:,}".format(session.query(Package).count())) - print("Releases: {:,}".format(session.query(Release).count())) - print("Maintainers: {:,}".format(session.query(Maintainer).count())) - print("Languages: {:,}".format(session.query(ProgrammingLanguage).count())) - print("Licenses: {:,}".format(session.query(License).count())) + print('Final numbers:') + print('Users: {:,}'.format(session.query(User).count())) + print('Packages: {:,}'.format(session.query(Package).count())) + print('Releases: {:,}'.format(session.query(Release).count())) + print('Maintainers: {:,}'.format(session.query(Maintainer).count())) + print('Languages: {:,}'.format(session.query(ProgrammingLanguage).count())) + print('Licenses: {:,}'.format(session.query(License).count())) def do_user_import(user_lookup: Dict[str, str]) -> Dict[str, User]: - print("Importing users ... ", flush=True) + print('Importing users ... ', flush=True) with progressbar.ProgressBar(max_value=len(user_lookup)) as bar: for idx, (email, name) in enumerate(user_lookup.items()): session = db_session.create_session() @@ -134,29 +133,29 @@ def do_user_import(user_lookup: Dict[str, str]) -> Dict[str, User]: def do_import_packages(file_data: List[dict], user_lookup: Dict[str, User]): errored_packages = [] - print("Importing packages and releases ... ", flush=True) + print('Importing packages and releases ... ', flush=True) with progressbar.ProgressBar(max_value=len(file_data)) as bar: for idx, p in enumerate(file_data): try: load_package(p, user_lookup) bar.update(idx) except Exception as x: - errored_packages.append((p, " *** Errored out for package {}, {}".format(p.get('package_name'), x))) + errored_packages.append((p, ' *** Errored out for package {}, {}'.format(p.get('package_name'), x))) raise sys.stderr.flush() sys.stdout.flush() print() - print("Completed packages with {} errors.".format(len(errored_packages))) - for (p, txt) in errored_packages: + print('Completed packages with {} errors.'.format(len(errored_packages))) + for p, txt in errored_packages: print(txt) def do_load_files() -> List[dict]: data_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../../../data/pypi-top-100')) - print("Loading files from {}".format(data_path)) + print('Loading files from {}'.format(data_path)) files = get_file_names(data_path) - print("Found {:,} files, loading ...".format(len(files)), flush=True) - time.sleep(.1) + print('Found {:,} files, loading ...'.format(len(files)), flush=True) + time.sleep(0.1) file_data = [] with progressbar.ProgressBar(max_value=len(files)) as bar: @@ -171,7 +170,7 @@ def do_load_files() -> List[dict]: def find_users(data: List[dict]) -> dict: - print("Discovering users...", flush=True) + print('Discovering users...', flush=True) found_users = {} with progressbar.ProgressBar(max_value=len(data)) as bar: @@ -184,7 +183,7 @@ def find_users(data: List[dict]) -> dict: sys.stderr.flush() sys.stdout.flush() print() - print("Discovered {:,} users".format(len(found_users))) + print('Discovered {:,} users'.format(len(found_users))) print() return found_users @@ -215,7 +214,7 @@ def load_file_data(filename: str) -> dict: with open(filename, 'r', encoding='utf-8') as fin: data = json.load(fin) except Exception as x: - print("ERROR in file: {}, details: {}".format(filename, x), flush=True) + print('ERROR in file: {}, details: {}'.format(filename, x), flush=True) raise return data @@ -233,7 +232,7 @@ def load_package(data: dict, user_lookup: Dict[str, User]): p.author = info.get('author') p.author_email = info.get('author_email') - releases = build_releases(p.id, data.get("releases", {})) + releases = build_releases(p.id, data.get('releases', {})) if releases: p.created_date = releases[0].created_date @@ -283,18 +282,13 @@ def detect_license(license_text: str) -> Optional[str]: license_text = license_text.strip() if len(license_text) > 100 or '\n' in license_text: - return "CUSTOM" + return 'CUSTOM' - license_text = license_text \ - .replace('Software License', '') \ - .replace('License', '') + license_text = license_text.replace('Software License', '').replace('License', '') if '::' in license_text: # E.g. 'License :: OSI Approved :: Apache Software License' - return license_text \ - .split(':')[-1] \ - .replace(' ', ' ') \ - .strip() + return license_text.split(':')[-1].replace(' ', ' ').strip() return license_text.strip() @@ -357,9 +351,7 @@ def get_file_names(data_path: str) -> List[str]: files = [] for f in os.listdir(data_path): if f.endswith('.json'): - files.append( - os.path.abspath(os.path.join(data_path, f)) - ) + files.append(os.path.abspath(os.path.join(data_path, f))) files.sort() return files diff --git a/app/ch14_testing/final/pypi_org/data/__all_models.py b/app/ch14_testing/final/pypi_org/data/__all_models.py index f399ef54..ca4804ac 100644 --- a/app/ch14_testing/final/pypi_org/data/__all_models.py +++ b/app/ch14_testing/final/pypi_org/data/__all_models.py @@ -5,17 +5,24 @@ # noinspection PyUnresolvedReferences import pypi_org.data.audit + # noinspection PyUnresolvedReferences import pypi_org.data.downloads + # noinspection PyUnresolvedReferences import pypi_org.data.languages + # noinspection PyUnresolvedReferences import pypi_org.data.licenses + # noinspection PyUnresolvedReferences import pypi_org.data.maintainers + # noinspection PyUnresolvedReferences import pypi_org.data.package + # noinspection PyUnresolvedReferences import pypi_org.data.releases + # noinspection PyUnresolvedReferences import pypi_org.data.users diff --git a/app/ch14_testing/final/pypi_org/data/db_session.py b/app/ch14_testing/final/pypi_org/data/db_session.py index 39b135cc..86eb3fb2 100644 --- a/app/ch14_testing/final/pypi_org/data/db_session.py +++ b/app/ch14_testing/final/pypi_org/data/db_session.py @@ -14,15 +14,15 @@ def global_init(db_file: str): return if not db_file or not db_file.strip(): - raise Exception("You must specify a db file.") + raise Exception('You must specify a db file.') conn_str = 'sqlite:///' + db_file.strip() - print("Connecting to DB with {}".format(conn_str)) + print('Connecting to DB with {}'.format(conn_str)) # Adding check_same_thread = False after the recording. This can be an issue about # creating / owner thread when cleaning up sessions, etc. This is a sqlite restriction # that we probably don't care about in this example. - engine = sa.create_engine(conn_str, echo=False, connect_args={"check_same_thread": False}) + engine = sa.create_engine(conn_str, echo=False, connect_args={'check_same_thread': False}) __factory = orm.sessionmaker(bind=engine) # noinspection PyUnresolvedReferences diff --git a/app/ch14_testing/final/pypi_org/data/downloads.py b/app/ch14_testing/final/pypi_org/data/downloads.py index 66068f02..dd8afd65 100644 --- a/app/ch14_testing/final/pypi_org/data/downloads.py +++ b/app/ch14_testing/final/pypi_org/data/downloads.py @@ -7,8 +7,7 @@ class Download(SqlAlchemyBase): __tablename__ = 'downloads' id: int = sqlalchemy.Column(sqlalchemy.BigInteger, primary_key=True, autoincrement=True) - created_date: datetime.datetime = sqlalchemy.Column( - sqlalchemy.DateTime, default=datetime.datetime.now, index=True) + created_date: datetime.datetime = sqlalchemy.Column(sqlalchemy.DateTime, default=datetime.datetime.now, index=True) package_id: str = sqlalchemy.Column(sqlalchemy.String, index=True) release_id: int = sqlalchemy.Column(sqlalchemy.BigInteger, index=True) diff --git a/app/ch14_testing/final/pypi_org/data/languages.py b/app/ch14_testing/final/pypi_org/data/languages.py index 964b8444..3a73dde0 100644 --- a/app/ch14_testing/final/pypi_org/data/languages.py +++ b/app/ch14_testing/final/pypi_org/data/languages.py @@ -7,6 +7,5 @@ class ProgrammingLanguage(SqlAlchemyBase): __tablename__ = 'languages' id: str = sqlalchemy.Column(sqlalchemy.String, primary_key=True) - created_date: datetime.datetime = sqlalchemy.Column( - sqlalchemy.DateTime, default=datetime.datetime.now, index=True) + created_date: datetime.datetime = sqlalchemy.Column(sqlalchemy.DateTime, default=datetime.datetime.now, index=True) description: str = sqlalchemy.Column(sqlalchemy.String) diff --git a/app/ch14_testing/final/pypi_org/data/package.py b/app/ch14_testing/final/pypi_org/data/package.py index c3420d1b..16e6d156 100644 --- a/app/ch14_testing/final/pypi_org/data/package.py +++ b/app/ch14_testing/final/pypi_org/data/package.py @@ -26,11 +26,15 @@ class Package(SqlAlchemyBase): license: str = sa.Column(sa.String, index=True) # releases relationship - releases: List[Release] = orm.relation("Release", order_by=[ - Release.major_ver.desc(), - Release.minor_ver.desc(), - Release.build_ver.desc(), - ], back_populates='package') + releases: List[Release] = orm.relation( + 'Release', + order_by=[ + Release.major_ver.desc(), + Release.minor_ver.desc(), + Release.build_ver.desc(), + ], + back_populates='package', + ) def __repr__(self): return ''.format(self.id) diff --git a/app/ch14_testing/final/pypi_org/data/releases.py b/app/ch14_testing/final/pypi_org/data/releases.py index 7650e438..8596f65c 100644 --- a/app/ch14_testing/final/pypi_org/data/releases.py +++ b/app/ch14_testing/final/pypi_org/data/releases.py @@ -13,15 +13,13 @@ class Release(SqlAlchemyBase): minor_ver: int = sqlalchemy.Column(sqlalchemy.BigInteger, index=True) build_ver: int = sqlalchemy.Column(sqlalchemy.BigInteger, index=True) - created_date: datetime.datetime = sqlalchemy.Column(sqlalchemy.DateTime, - default=datetime.datetime.now, - index=True) + created_date: datetime.datetime = sqlalchemy.Column(sqlalchemy.DateTime, default=datetime.datetime.now, index=True) comment: str = sqlalchemy.Column(sqlalchemy.String) url: str = sqlalchemy.Column(sqlalchemy.String) size: int = sqlalchemy.Column(sqlalchemy.BigInteger) # Package relationship - package_id: str = sqlalchemy.Column(sqlalchemy.String, sqlalchemy.ForeignKey("packages.id")) + package_id: str = sqlalchemy.Column(sqlalchemy.String, sqlalchemy.ForeignKey('packages.id')) package = orm.relation('Package') @property diff --git a/app/ch14_testing/final/pypi_org/infrastructure/cookie_auth.py b/app/ch14_testing/final/pypi_org/infrastructure/cookie_auth.py index 42a19606..d8f2b4ec 100644 --- a/app/ch14_testing/final/pypi_org/infrastructure/cookie_auth.py +++ b/app/ch14_testing/final/pypi_org/infrastructure/cookie_auth.py @@ -11,7 +11,7 @@ def set_auth(response: Response, user_id: int): hash_val = __hash_text(str(user_id)) - val = "{}:{}".format(user_id, hash_val) + val = '{}:{}'.format(user_id, hash_val) response.set_cookie(auth_cookie_name, val, secure=True, httponly=True, samesite='Lax') @@ -33,7 +33,7 @@ def get_user_id_via_auth_cookie(request: Request) -> Optional[int]: hash_val = parts[1] hash_val_check = __hash_text(user_id) if hash_val != hash_val_check: - print("Warning: Hash mismatch, invalid cookie value") + print('Warning: Hash mismatch, invalid cookie value') return None return try_int(user_id) diff --git a/app/ch14_testing/final/pypi_org/infrastructure/request_dict.py b/app/ch14_testing/final/pypi_org/infrastructure/request_dict.py index d7ab10de..d44ae574 100644 --- a/app/ch14_testing/final/pypi_org/infrastructure/request_dict.py +++ b/app/ch14_testing/final/pypi_org/infrastructure/request_dict.py @@ -29,7 +29,7 @@ def create(default_val=None, **route_args) -> RequestDictionary: **args, # The key/value pairs in the URL query string **request.headers, # Header values **form, # The key/value pairs in the body, from a HTML post form - **route_args # And additional arguments the method access, if they want them merged. + **route_args, # And additional arguments the method access, if they want them merged. } return RequestDictionary(data, default_val=default_val) diff --git a/app/ch14_testing/final/pypi_org/infrastructure/view_modifiers.py b/app/ch14_testing/final/pypi_org/infrastructure/view_modifiers.py index 0978163e..d944c142 100644 --- a/app/ch14_testing/final/pypi_org/infrastructure/view_modifiers.py +++ b/app/ch14_testing/final/pypi_org/infrastructure/view_modifiers.py @@ -26,7 +26,8 @@ def view_method(*args, **kwargs): if template_file and not isinstance(response_val, dict): raise Exception( - "Invalid return type {}, we expected a dict as the return value.".format(type(response_val))) + 'Invalid return type {}, we expected a dict as the return value.'.format(type(response_val)) + ) if template_file: response_val = flask.render_template(template_file, **response_val) @@ -42,6 +43,7 @@ def view_method(*args, **kwargs): return response_inner + # # def template(template_file: str = None): # def template_inner(f): diff --git a/app/ch14_testing/final/pypi_org/services/package_service.py b/app/ch14_testing/final/pypi_org/services/package_service.py index b03408d2..9a153773 100644 --- a/app/ch14_testing/final/pypi_org/services/package_service.py +++ b/app/ch14_testing/final/pypi_org/services/package_service.py @@ -10,12 +10,13 @@ def get_latest_releases(limit=10) -> List[Release]: session = db_session.create_session() try: - - releases = session.query(Release). \ - options(sqlalchemy.orm.joinedload(Release.package)). \ - order_by(Release.created_date.desc()). \ - limit(limit). \ - all() + releases = ( + session.query(Release) + .options(sqlalchemy.orm.joinedload(Release.package)) + .order_by(Release.created_date.desc()) + .limit(limit) + .all() + ) finally: session.close() @@ -47,11 +48,12 @@ def get_package_by_id(package_id: str) -> Optional[Package]: session = db_session.create_session() try: - - package = session.query(Package) \ - .options(sqlalchemy.orm.joinedload(Package.releases)) \ - .filter(Package.id == package_id) \ + package = ( + session.query(Package) + .options(sqlalchemy.orm.joinedload(Package.releases)) + .filter(Package.id == package_id) .first() + ) finally: session.close() diff --git a/app/ch14_testing/final/pypi_org/viewmodels/cms/page_viewmodel.py b/app/ch14_testing/final/pypi_org/viewmodels/cms/page_viewmodel.py index b7bb3249..ec033c3f 100644 --- a/app/ch14_testing/final/pypi_org/viewmodels/cms/page_viewmodel.py +++ b/app/ch14_testing/final/pypi_org/viewmodels/cms/page_viewmodel.py @@ -7,4 +7,3 @@ def __init__(self, full_url: str): super().__init__() self.page = cms_service.get_page(full_url) - diff --git a/app/ch14_testing/final/pypi_org/viewmodels/packages/pagedetails_viewmodel.py b/app/ch14_testing/final/pypi_org/viewmodels/packages/pagedetails_viewmodel.py index 63c4cf68..09f47c6f 100644 --- a/app/ch14_testing/final/pypi_org/viewmodels/packages/pagedetails_viewmodel.py +++ b/app/ch14_testing/final/pypi_org/viewmodels/packages/pagedetails_viewmodel.py @@ -11,7 +11,7 @@ def __init__(self, package_name: str): self.package_name = package_name.strip().lower() self.package = package_service.get_package_by_id(self.package_name) - self.latest_version = "0.0.0" + self.latest_version = '0.0.0' self.latest_release = None self.is_latest = True diff --git a/app/ch14_testing/final/pypi_org/viewmodels/seo/sitemap_viewmodel.py b/app/ch14_testing/final/pypi_org/viewmodels/seo/sitemap_viewmodel.py index 912c4df0..71df2f99 100644 --- a/app/ch14_testing/final/pypi_org/viewmodels/seo/sitemap_viewmodel.py +++ b/app/ch14_testing/final/pypi_org/viewmodels/seo/sitemap_viewmodel.py @@ -8,5 +8,5 @@ class SiteMapViewModel(ViewModelBase): def __init__(self, limit: int): super().__init__() self.packages = package_service.all_packages(limit) - self.last_updated_text = "2019-07-15" - self.site = "{}://{}".format(flask.request.scheme, flask.request.host) + self.last_updated_text = '2019-07-15' + self.site = '{}://{}'.format(flask.request.scheme, flask.request.host) diff --git a/app/ch14_testing/final/pypi_org/views/account_views.py b/app/ch14_testing/final/pypi_org/views/account_views.py index 3854b4cf..652f43b3 100644 --- a/app/ch14_testing/final/pypi_org/views/account_views.py +++ b/app/ch14_testing/final/pypi_org/views/account_views.py @@ -25,6 +25,7 @@ def index(): # ################### REGISTER ################################# + @blueprint.route('/account/register', methods=['GET']) @response(template_file='account/register.html') def register_get(): @@ -54,6 +55,7 @@ def register_post(): # ################### LOGIN ################################# + @blueprint.route('/account/login', methods=['GET']) @response(template_file='account/login.html') def login_get(): @@ -77,7 +79,7 @@ def login_post(): user = user_service.login_user(vm.email, vm.password) if not user: - vm.error = "The account does not exist or the password is wrong." + vm.error = 'The account does not exist or the password is wrong.' return vm.to_dict() resp = flask.redirect('/account') @@ -88,6 +90,7 @@ def login_post(): # ################### LOGOUT ################################# + @blueprint.route('/account/logout') def logout(): resp = flask.redirect('/') diff --git a/app/ch14_testing/final/pypi_org/views/package_views.py b/app/ch14_testing/final/pypi_org/views/package_views.py index 1a74549f..2f862740 100644 --- a/app/ch14_testing/final/pypi_org/views/package_views.py +++ b/app/ch14_testing/final/pypi_org/views/package_views.py @@ -19,4 +19,4 @@ def package_details(package_name: str): @blueprint.route('/') def popular(rank: int): print(type(rank), rank) - return "The details for the {}th most popular package".format(rank) + return 'The details for the {}th most popular package'.format(rank) diff --git a/app/ch14_testing/final/pypi_org/views/seo_view.py b/app/ch14_testing/final/pypi_org/views/seo_view.py index 93c88de5..f86b6bff 100644 --- a/app/ch14_testing/final/pypi_org/views/seo_view.py +++ b/app/ch14_testing/final/pypi_org/views/seo_view.py @@ -18,6 +18,7 @@ def sitemap(): # ################### Robots ################################# + @blueprint.route('/robots.txt') @response(mimetype='text/plain', template_file='seo/robots.txt') def robots(): diff --git a/app/ch14_testing/final/tests/_all_tests.py b/app/ch14_testing/final/tests/_all_tests.py index daa69ea4..e5c9b9ea 100644 --- a/app/ch14_testing/final/tests/_all_tests.py +++ b/app/ch14_testing/final/tests/_all_tests.py @@ -1,17 +1,18 @@ import sys import os -container_folder = os.path.abspath(os.path.join( - os.path.dirname(__file__), '..' -)) +container_folder = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) sys.path.insert(0, container_folder) # noinspection PyUnresolvedReferences from account_tests import * + # noinspection PyUnresolvedReferences from package_tests import * + # noinspection PyUnresolvedReferences from sitemap_tests import * + # noinspection PyUnresolvedReferences from home_tests import * diff --git a/app/ch14_testing/final/tests/account_tests.py b/app/ch14_testing/final/tests/account_tests.py index 9c335dba..6f8a65a7 100644 --- a/app/ch14_testing/final/tests/account_tests.py +++ b/app/ch14_testing/final/tests/account_tests.py @@ -7,7 +7,7 @@ def test_example(): - print("Test example...") + print('Test example...') assert 1 + 2 == 3 @@ -15,11 +15,7 @@ def test_vm_register_validation_when_valid(): # 3 A's of test: Arrange, Act, then Assert # Arrange - form_data = { - 'name': 'Michael', - 'email': 'michael@talkpython.fm', - 'password': 'a' * 6 - } + form_data = {'name': 'Michael', 'email': 'michael@talkpython.fm', 'password': 'a' * 6} with flask_app.test_request_context(path='/account/register', data=form_data): vm = RegisterViewModel() @@ -37,11 +33,7 @@ def test_vm_register_validation_for_existing_user(): # 3 A's of test: Arrange, Act, then Assert # Arrange - form_data = { - 'name': 'Michael', - 'email': 'michael@talkpython.fm', - 'password': 'a' * 6 - } + form_data = {'name': 'Michael', 'email': 'michael@talkpython.fm', 'password': 'a' * 6} with flask_app.test_request_context(path='/account/register', data=form_data): vm = RegisterViewModel() @@ -62,11 +54,8 @@ def test_v_register_view_new_user(): # Arrange from pypi_org.views.account_views import register_post - form_data = { - 'name': 'Michael', - 'email': 'michael@talkpython.fm', - 'password': 'a' * 6 - } + + form_data = {'name': 'Michael', 'email': 'michael@talkpython.fm', 'password': 'a' * 6} target = 'pypi_org.services.user_service.find_user_by_email' find_user = unittest.mock.patch(target, return_value=None) diff --git a/app/ch14_testing/final/tests/package_tests.py b/app/ch14_testing/final/tests/package_tests.py index efd04ef5..a7c221a5 100644 --- a/app/ch14_testing/final/tests/package_tests.py +++ b/app/ch14_testing/final/tests/package_tests.py @@ -12,15 +12,14 @@ def test_package_details_success(): test_package = Package() test_package.id = 'sqlalchemy' - test_package.description = "TDB" + test_package.description = 'TDB' test_package.releases = [ Release(created_date=datetime.datetime.now(), major_ver=1, minor_ver=2, build_ver=200), Release(created_date=datetime.datetime.now() - datetime.timedelta(days=10)), ] # Act - with unittest.mock.patch('pypi_org.services.package_service.get_package_by_id', - return_value=test_package): + with unittest.mock.patch('pypi_org.services.package_service.get_package_by_id', return_value=test_package): with flask_app.test_request_context(path='/project/' + test_package.id): resp: Response = package_details(test_package.id) @@ -33,8 +32,7 @@ def test_package_details_404(client): bad_package_url = 'sqlalchemy_missing' # Act - with unittest.mock.patch('pypi_org.services.package_service.get_package_by_id', - return_value=None): + with unittest.mock.patch('pypi_org.services.package_service.get_package_by_id', return_value=None): resp: Response = client.get(bad_package_url) assert resp.status_code == 404 diff --git a/app/ch14_testing/final/tests/sitemap_tests.py b/app/ch14_testing/final/tests/sitemap_tests.py index b1afe0fe..4494c30a 100644 --- a/app/ch14_testing/final/tests/sitemap_tests.py +++ b/app/ch14_testing/final/tests/sitemap_tests.py @@ -10,10 +10,7 @@ def test_int_site_mapped_urls(client): href.text.strip().replace('http://127.0.0.1:5000', '').replace('http://localhost', '') for href in list(x.findall('url/loc')) ] - urls = [ - u if u else '/' - for u in urls - ] + urls = [u if u else '/' for u in urls] print('Testing {} urls from sitemap...'.format(len(urls)), flush=True) has_tested_projects = False @@ -40,7 +37,7 @@ def get_sitemap_text(client): # # ... # - res: Response = client.get("/sitemap.xml") - text = res.data.decode("utf-8") + res: Response = client.get('/sitemap.xml') + text = res.data.decode('utf-8') text = text.replace('xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"', '') return text diff --git a/app/ch14_testing/final/tests/test_client.py b/app/ch14_testing/final/tests/test_client.py index ffbea486..4390409a 100644 --- a/app/ch14_testing/final/tests/test_client.py +++ b/app/ch14_testing/final/tests/test_client.py @@ -4,9 +4,7 @@ import sys import os -container_folder = os.path.abspath(os.path.join( - os.path.dirname(__file__), '..' -)) +container_folder = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) sys.path.insert(0, container_folder) import pypi_org.app diff --git a/app/ch14_testing/starter/alembic/alembic_helpers.py b/app/ch14_testing/starter/alembic/alembic_helpers.py index 561f7a70..6aea52d4 100644 --- a/app/ch14_testing/starter/alembic/alembic_helpers.py +++ b/app/ch14_testing/starter/alembic/alembic_helpers.py @@ -5,8 +5,7 @@ def table_has_column(table, column): config = op.get_context().config - engine = engine_from_config( - config.get_section(config.config_ini_section), prefix='sqlalchemy.') + engine = engine_from_config(config.get_section(config.config_ini_section), prefix='sqlalchemy.') insp = reflection.Inspector.from_engine(engine) has_column = False for col in insp.get_columns(table): diff --git a/app/ch14_testing/starter/alembic/env.py b/app/ch14_testing/starter/alembic/env.py index 27ec49fb..1fdc9cab 100644 --- a/app/ch14_testing/starter/alembic/env.py +++ b/app/ch14_testing/starter/alembic/env.py @@ -26,6 +26,7 @@ sys.path.insert(0, folder) from pypi_org.data.modelbase import SqlAlchemyBase + # noinspection PyUnresolvedReferences import pypi_org.data.__all_models @@ -49,10 +50,8 @@ def run_migrations_offline(): script output. """ - url = config.get_main_option("sqlalchemy.url") - context.configure( - url=url, target_metadata=target_metadata, literal_binds=True - ) + url = config.get_main_option('sqlalchemy.url') + context.configure(url=url, target_metadata=target_metadata, literal_binds=True) with context.begin_transaction(): context.run_migrations() @@ -67,14 +66,12 @@ def run_migrations_online(): """ connectable = engine_from_config( config.get_section(config.config_ini_section), - prefix="sqlalchemy.", + prefix='sqlalchemy.', poolclass=pool.NullPool, ) with connectable.connect() as connection: - context.configure( - connection=connection, target_metadata=target_metadata - ) + context.configure(connection=connection, target_metadata=target_metadata) with context.begin_transaction(): context.run_migrations() diff --git a/app/ch14_testing/starter/alembic/versions/722c82f0097c_added_auditing_table.py b/app/ch14_testing/starter/alembic/versions/722c82f0097c_added_auditing_table.py index 2c3e2a39..7c6e892f 100644 --- a/app/ch14_testing/starter/alembic/versions/722c82f0097c_added_auditing_table.py +++ b/app/ch14_testing/starter/alembic/versions/722c82f0097c_added_auditing_table.py @@ -18,11 +18,12 @@ def upgrade(): # ### commands auto generated by Alembic - please adjust! ### - op.create_table('auditing', - sa.Column('id', sa.String(), nullable=False), - sa.Column('created_date', sa.DateTime(), nullable=True), - sa.Column('description', sa.String(), nullable=True), - sa.PrimaryKeyConstraint('id') + op.create_table( + 'auditing', + sa.Column('id', sa.String(), nullable=False), + sa.Column('created_date', sa.DateTime(), nullable=True), + sa.Column('description', sa.String(), nullable=True), + sa.PrimaryKeyConstraint('id'), ) op.create_index(op.f('ix_auditing_created_date'), 'auditing', ['created_date'], unique=False) # ### end Alembic commands ### diff --git a/app/ch14_testing/starter/pypi_org/app.py b/app/ch14_testing/starter/pypi_org/app.py index 46c84acc..0aa9e391 100644 --- a/app/ch14_testing/starter/pypi_org/app.py +++ b/app/ch14_testing/starter/pypi_org/app.py @@ -2,6 +2,7 @@ import sys import flask + folder = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) sys.path.insert(0, folder) import pypi_org.data.db_session as db_session @@ -16,10 +17,7 @@ def main(): def setup_db(): - db_file = os.path.join( - os.path.dirname(__file__), - 'db', - 'pypi.sqlite') + db_file = os.path.join(os.path.dirname(__file__), 'db', 'pypi.sqlite') db_session.global_init(db_file) diff --git a/app/ch14_testing/starter/pypi_org/bin/basic_inserts.py b/app/ch14_testing/starter/pypi_org/bin/basic_inserts.py index d622a6ae..6d04f551 100644 --- a/app/ch14_testing/starter/pypi_org/bin/basic_inserts.py +++ b/app/ch14_testing/starter/pypi_org/bin/basic_inserts.py @@ -2,8 +2,7 @@ import sys # Make it run more easily outside of PyCharm -sys.path.insert(0, os.path.abspath(os.path.join( - os.path.dirname(__file__), "..", ".."))) +sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..'))) import pypi_org.data.db_session as db_session from pypi_org.data.package import Package @@ -20,24 +19,24 @@ def insert_a_package(): p = Package() p.id = input('Package id / name: ').strip().lower() - p.summary = input("Package summary: ").strip() - p.author_name = input("Author: ").strip() - p.license = input("License: ").strip() + p.summary = input('Package summary: ').strip() + p.author_name = input('Author: ').strip() + p.license = input('License: ').strip() - print("Release 1:") + print('Release 1:') r = Release() - r.major_ver = int(input("Major version: ")) - r.minor_ver = int(input("Minor version: ")) - r.build_ver = int(input("Build version: ")) - r.size = int(input("Size in bytes: ")) + r.major_ver = int(input('Major version: ')) + r.minor_ver = int(input('Minor version: ')) + r.build_ver = int(input('Build version: ')) + r.size = int(input('Size in bytes: ')) p.releases.append(r) - print("Release 2:") + print('Release 2:') r = Release() - r.major_ver = int(input("Major version: ")) - r.minor_ver = int(input("Minor version: ")) - r.build_ver = int(input("Build version: ")) - r.size = int(input("Size in bytes: ")) + r.major_ver = int(input('Major version: ')) + r.minor_ver = int(input('Minor version: ')) + r.build_ver = int(input('Build version: ')) + r.size = int(input('Size in bytes: ')) p.releases.append(r) session = db_session.create_session() diff --git a/app/ch14_testing/starter/pypi_org/bin/load_data.py b/app/ch14_testing/starter/pypi_org/bin/load_data.py index 8f43c13c..228c1b6b 100644 --- a/app/ch14_testing/starter/pypi_org/bin/load_data.py +++ b/app/ch14_testing/starter/pypi_org/bin/load_data.py @@ -7,8 +7,7 @@ import progressbar from dateutil.parser import parse -sys.path.insert(0, os.path.abspath(os.path.join( - os.path.dirname(__file__), "..", ".."))) +sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..'))) import pypi_org.data.db_session as db_session from pypi_org.data.languages import ProgrammingLanguage @@ -39,7 +38,7 @@ def main(): def do_import_languages(file_data: List[dict]): imported = set() - print("Importing languages ... ", flush=True) + print('Importing languages ... ', flush=True) with progressbar.ProgressBar(max_value=len(file_data)) as bar: for idx, p in enumerate(file_data): info = p.get('info') @@ -74,7 +73,7 @@ def do_import_languages(file_data: List[dict]): def do_import_licenses(file_data: List[dict]): imported = set() - print("Importing licenses ... ", flush=True) + print('Importing licenses ... ', flush=True) with progressbar.ProgressBar(max_value=len(file_data)) as bar: for idx, p in enumerate(file_data): info = p.get('info') @@ -100,17 +99,17 @@ def do_import_licenses(file_data: List[dict]): def do_summary(): session = db_session.create_session() - print("Final numbers:") - print("Users: {:,}".format(session.query(User).count())) - print("Packages: {:,}".format(session.query(Package).count())) - print("Releases: {:,}".format(session.query(Release).count())) - print("Maintainers: {:,}".format(session.query(Maintainer).count())) - print("Languages: {:,}".format(session.query(ProgrammingLanguage).count())) - print("Licenses: {:,}".format(session.query(License).count())) + print('Final numbers:') + print('Users: {:,}'.format(session.query(User).count())) + print('Packages: {:,}'.format(session.query(Package).count())) + print('Releases: {:,}'.format(session.query(Release).count())) + print('Maintainers: {:,}'.format(session.query(Maintainer).count())) + print('Languages: {:,}'.format(session.query(ProgrammingLanguage).count())) + print('Licenses: {:,}'.format(session.query(License).count())) def do_user_import(user_lookup: Dict[str, str]) -> Dict[str, User]: - print("Importing users ... ", flush=True) + print('Importing users ... ', flush=True) with progressbar.ProgressBar(max_value=len(user_lookup)) as bar: for idx, (email, name) in enumerate(user_lookup.items()): session = db_session.create_session() @@ -134,29 +133,29 @@ def do_user_import(user_lookup: Dict[str, str]) -> Dict[str, User]: def do_import_packages(file_data: List[dict], user_lookup: Dict[str, User]): errored_packages = [] - print("Importing packages and releases ... ", flush=True) + print('Importing packages and releases ... ', flush=True) with progressbar.ProgressBar(max_value=len(file_data)) as bar: for idx, p in enumerate(file_data): try: load_package(p, user_lookup) bar.update(idx) except Exception as x: - errored_packages.append((p, " *** Errored out for package {}, {}".format(p.get('package_name'), x))) + errored_packages.append((p, ' *** Errored out for package {}, {}'.format(p.get('package_name'), x))) raise sys.stderr.flush() sys.stdout.flush() print() - print("Completed packages with {} errors.".format(len(errored_packages))) - for (p, txt) in errored_packages: + print('Completed packages with {} errors.'.format(len(errored_packages))) + for p, txt in errored_packages: print(txt) def do_load_files() -> List[dict]: data_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../../../data/pypi-top-100')) - print("Loading files from {}".format(data_path)) + print('Loading files from {}'.format(data_path)) files = get_file_names(data_path) - print("Found {:,} files, loading ...".format(len(files)), flush=True) - time.sleep(.1) + print('Found {:,} files, loading ...'.format(len(files)), flush=True) + time.sleep(0.1) file_data = [] with progressbar.ProgressBar(max_value=len(files)) as bar: @@ -171,7 +170,7 @@ def do_load_files() -> List[dict]: def find_users(data: List[dict]) -> dict: - print("Discovering users...", flush=True) + print('Discovering users...', flush=True) found_users = {} with progressbar.ProgressBar(max_value=len(data)) as bar: @@ -184,7 +183,7 @@ def find_users(data: List[dict]) -> dict: sys.stderr.flush() sys.stdout.flush() print() - print("Discovered {:,} users".format(len(found_users))) + print('Discovered {:,} users'.format(len(found_users))) print() return found_users @@ -215,7 +214,7 @@ def load_file_data(filename: str) -> dict: with open(filename, 'r', encoding='utf-8') as fin: data = json.load(fin) except Exception as x: - print("ERROR in file: {}, details: {}".format(filename, x), flush=True) + print('ERROR in file: {}, details: {}'.format(filename, x), flush=True) raise return data @@ -233,7 +232,7 @@ def load_package(data: dict, user_lookup: Dict[str, User]): p.author = info.get('author') p.author_email = info.get('author_email') - releases = build_releases(p.id, data.get("releases", {})) + releases = build_releases(p.id, data.get('releases', {})) if releases: p.created_date = releases[0].created_date @@ -283,18 +282,13 @@ def detect_license(license_text: str) -> Optional[str]: license_text = license_text.strip() if len(license_text) > 100 or '\n' in license_text: - return "CUSTOM" + return 'CUSTOM' - license_text = license_text \ - .replace('Software License', '') \ - .replace('License', '') + license_text = license_text.replace('Software License', '').replace('License', '') if '::' in license_text: # E.g. 'License :: OSI Approved :: Apache Software License' - return license_text \ - .split(':')[-1] \ - .replace(' ', ' ') \ - .strip() + return license_text.split(':')[-1].replace(' ', ' ').strip() return license_text.strip() @@ -357,9 +351,7 @@ def get_file_names(data_path: str) -> List[str]: files = [] for f in os.listdir(data_path): if f.endswith('.json'): - files.append( - os.path.abspath(os.path.join(data_path, f)) - ) + files.append(os.path.abspath(os.path.join(data_path, f))) files.sort() return files diff --git a/app/ch14_testing/starter/pypi_org/data/__all_models.py b/app/ch14_testing/starter/pypi_org/data/__all_models.py index f399ef54..ca4804ac 100644 --- a/app/ch14_testing/starter/pypi_org/data/__all_models.py +++ b/app/ch14_testing/starter/pypi_org/data/__all_models.py @@ -5,17 +5,24 @@ # noinspection PyUnresolvedReferences import pypi_org.data.audit + # noinspection PyUnresolvedReferences import pypi_org.data.downloads + # noinspection PyUnresolvedReferences import pypi_org.data.languages + # noinspection PyUnresolvedReferences import pypi_org.data.licenses + # noinspection PyUnresolvedReferences import pypi_org.data.maintainers + # noinspection PyUnresolvedReferences import pypi_org.data.package + # noinspection PyUnresolvedReferences import pypi_org.data.releases + # noinspection PyUnresolvedReferences import pypi_org.data.users diff --git a/app/ch14_testing/starter/pypi_org/data/db_session.py b/app/ch14_testing/starter/pypi_org/data/db_session.py index 39b135cc..86eb3fb2 100644 --- a/app/ch14_testing/starter/pypi_org/data/db_session.py +++ b/app/ch14_testing/starter/pypi_org/data/db_session.py @@ -14,15 +14,15 @@ def global_init(db_file: str): return if not db_file or not db_file.strip(): - raise Exception("You must specify a db file.") + raise Exception('You must specify a db file.') conn_str = 'sqlite:///' + db_file.strip() - print("Connecting to DB with {}".format(conn_str)) + print('Connecting to DB with {}'.format(conn_str)) # Adding check_same_thread = False after the recording. This can be an issue about # creating / owner thread when cleaning up sessions, etc. This is a sqlite restriction # that we probably don't care about in this example. - engine = sa.create_engine(conn_str, echo=False, connect_args={"check_same_thread": False}) + engine = sa.create_engine(conn_str, echo=False, connect_args={'check_same_thread': False}) __factory = orm.sessionmaker(bind=engine) # noinspection PyUnresolvedReferences diff --git a/app/ch14_testing/starter/pypi_org/data/downloads.py b/app/ch14_testing/starter/pypi_org/data/downloads.py index 66068f02..dd8afd65 100644 --- a/app/ch14_testing/starter/pypi_org/data/downloads.py +++ b/app/ch14_testing/starter/pypi_org/data/downloads.py @@ -7,8 +7,7 @@ class Download(SqlAlchemyBase): __tablename__ = 'downloads' id: int = sqlalchemy.Column(sqlalchemy.BigInteger, primary_key=True, autoincrement=True) - created_date: datetime.datetime = sqlalchemy.Column( - sqlalchemy.DateTime, default=datetime.datetime.now, index=True) + created_date: datetime.datetime = sqlalchemy.Column(sqlalchemy.DateTime, default=datetime.datetime.now, index=True) package_id: str = sqlalchemy.Column(sqlalchemy.String, index=True) release_id: int = sqlalchemy.Column(sqlalchemy.BigInteger, index=True) diff --git a/app/ch14_testing/starter/pypi_org/data/languages.py b/app/ch14_testing/starter/pypi_org/data/languages.py index 964b8444..3a73dde0 100644 --- a/app/ch14_testing/starter/pypi_org/data/languages.py +++ b/app/ch14_testing/starter/pypi_org/data/languages.py @@ -7,6 +7,5 @@ class ProgrammingLanguage(SqlAlchemyBase): __tablename__ = 'languages' id: str = sqlalchemy.Column(sqlalchemy.String, primary_key=True) - created_date: datetime.datetime = sqlalchemy.Column( - sqlalchemy.DateTime, default=datetime.datetime.now, index=True) + created_date: datetime.datetime = sqlalchemy.Column(sqlalchemy.DateTime, default=datetime.datetime.now, index=True) description: str = sqlalchemy.Column(sqlalchemy.String) diff --git a/app/ch14_testing/starter/pypi_org/data/package.py b/app/ch14_testing/starter/pypi_org/data/package.py index c3420d1b..16e6d156 100644 --- a/app/ch14_testing/starter/pypi_org/data/package.py +++ b/app/ch14_testing/starter/pypi_org/data/package.py @@ -26,11 +26,15 @@ class Package(SqlAlchemyBase): license: str = sa.Column(sa.String, index=True) # releases relationship - releases: List[Release] = orm.relation("Release", order_by=[ - Release.major_ver.desc(), - Release.minor_ver.desc(), - Release.build_ver.desc(), - ], back_populates='package') + releases: List[Release] = orm.relation( + 'Release', + order_by=[ + Release.major_ver.desc(), + Release.minor_ver.desc(), + Release.build_ver.desc(), + ], + back_populates='package', + ) def __repr__(self): return ''.format(self.id) diff --git a/app/ch14_testing/starter/pypi_org/data/releases.py b/app/ch14_testing/starter/pypi_org/data/releases.py index 7650e438..8596f65c 100644 --- a/app/ch14_testing/starter/pypi_org/data/releases.py +++ b/app/ch14_testing/starter/pypi_org/data/releases.py @@ -13,15 +13,13 @@ class Release(SqlAlchemyBase): minor_ver: int = sqlalchemy.Column(sqlalchemy.BigInteger, index=True) build_ver: int = sqlalchemy.Column(sqlalchemy.BigInteger, index=True) - created_date: datetime.datetime = sqlalchemy.Column(sqlalchemy.DateTime, - default=datetime.datetime.now, - index=True) + created_date: datetime.datetime = sqlalchemy.Column(sqlalchemy.DateTime, default=datetime.datetime.now, index=True) comment: str = sqlalchemy.Column(sqlalchemy.String) url: str = sqlalchemy.Column(sqlalchemy.String) size: int = sqlalchemy.Column(sqlalchemy.BigInteger) # Package relationship - package_id: str = sqlalchemy.Column(sqlalchemy.String, sqlalchemy.ForeignKey("packages.id")) + package_id: str = sqlalchemy.Column(sqlalchemy.String, sqlalchemy.ForeignKey('packages.id')) package = orm.relation('Package') @property diff --git a/app/ch14_testing/starter/pypi_org/infrastructure/cookie_auth.py b/app/ch14_testing/starter/pypi_org/infrastructure/cookie_auth.py index 44864438..c215c0af 100644 --- a/app/ch14_testing/starter/pypi_org/infrastructure/cookie_auth.py +++ b/app/ch14_testing/starter/pypi_org/infrastructure/cookie_auth.py @@ -11,7 +11,7 @@ def set_auth(response: Response, user_id: int): hash_val = __hash_text(str(user_id)) - val = "{}:{}".format(user_id, hash_val) + val = '{}:{}'.format(user_id, hash_val) response.set_cookie(auth_cookie_name, val, secure=False, httponly=True, samesite='Lax') @@ -33,7 +33,7 @@ def get_user_id_via_auth_cookie(request: Request) -> Optional[int]: hash_val = parts[1] hash_val_check = __hash_text(user_id) if hash_val != hash_val_check: - print("Warning: Hash mismatch, invalid cookie value") + print('Warning: Hash mismatch, invalid cookie value') return None return try_int(user_id) diff --git a/app/ch14_testing/starter/pypi_org/infrastructure/request_dict.py b/app/ch14_testing/starter/pypi_org/infrastructure/request_dict.py index d7ab10de..d44ae574 100644 --- a/app/ch14_testing/starter/pypi_org/infrastructure/request_dict.py +++ b/app/ch14_testing/starter/pypi_org/infrastructure/request_dict.py @@ -29,7 +29,7 @@ def create(default_val=None, **route_args) -> RequestDictionary: **args, # The key/value pairs in the URL query string **request.headers, # Header values **form, # The key/value pairs in the body, from a HTML post form - **route_args # And additional arguments the method access, if they want them merged. + **route_args, # And additional arguments the method access, if they want them merged. } return RequestDictionary(data, default_val=default_val) diff --git a/app/ch14_testing/starter/pypi_org/infrastructure/view_modifiers.py b/app/ch14_testing/starter/pypi_org/infrastructure/view_modifiers.py index 0978163e..d944c142 100644 --- a/app/ch14_testing/starter/pypi_org/infrastructure/view_modifiers.py +++ b/app/ch14_testing/starter/pypi_org/infrastructure/view_modifiers.py @@ -26,7 +26,8 @@ def view_method(*args, **kwargs): if template_file and not isinstance(response_val, dict): raise Exception( - "Invalid return type {}, we expected a dict as the return value.".format(type(response_val))) + 'Invalid return type {}, we expected a dict as the return value.'.format(type(response_val)) + ) if template_file: response_val = flask.render_template(template_file, **response_val) @@ -42,6 +43,7 @@ def view_method(*args, **kwargs): return response_inner + # # def template(template_file: str = None): # def template_inner(f): diff --git a/app/ch14_testing/starter/pypi_org/services/package_service.py b/app/ch14_testing/starter/pypi_org/services/package_service.py index 71d4d02f..c2675f8d 100644 --- a/app/ch14_testing/starter/pypi_org/services/package_service.py +++ b/app/ch14_testing/starter/pypi_org/services/package_service.py @@ -9,12 +9,13 @@ def get_latest_releases(limit=10) -> List[Release]: session = db_session.create_session() try: - - releases = session.query(Release). \ - options(sqlalchemy.orm.joinedload(Release.package)). \ - order_by(Release.created_date.desc()). \ - limit(limit). \ - all() + releases = ( + session.query(Release) + .options(sqlalchemy.orm.joinedload(Release.package)) + .order_by(Release.created_date.desc()) + .limit(limit) + .all() + ) finally: session.close() @@ -46,11 +47,12 @@ def get_package_by_id(package_id: str) -> Optional[Package]: session = db_session.create_session() try: - - package = session.query(Package) \ - .options(sqlalchemy.orm.joinedload(Package.releases)) \ - .filter(Package.id == package_id) \ + package = ( + session.query(Package) + .options(sqlalchemy.orm.joinedload(Package.releases)) + .filter(Package.id == package_id) .first() + ) finally: session.close() diff --git a/app/ch14_testing/starter/pypi_org/viewmodels/cms/page_viewmodel.py b/app/ch14_testing/starter/pypi_org/viewmodels/cms/page_viewmodel.py index b7bb3249..ec033c3f 100644 --- a/app/ch14_testing/starter/pypi_org/viewmodels/cms/page_viewmodel.py +++ b/app/ch14_testing/starter/pypi_org/viewmodels/cms/page_viewmodel.py @@ -7,4 +7,3 @@ def __init__(self, full_url: str): super().__init__() self.page = cms_service.get_page(full_url) - diff --git a/app/ch14_testing/starter/pypi_org/viewmodels/packages/pagedetails_viewmodel.py b/app/ch14_testing/starter/pypi_org/viewmodels/packages/pagedetails_viewmodel.py index 63c4cf68..09f47c6f 100644 --- a/app/ch14_testing/starter/pypi_org/viewmodels/packages/pagedetails_viewmodel.py +++ b/app/ch14_testing/starter/pypi_org/viewmodels/packages/pagedetails_viewmodel.py @@ -11,7 +11,7 @@ def __init__(self, package_name: str): self.package_name = package_name.strip().lower() self.package = package_service.get_package_by_id(self.package_name) - self.latest_version = "0.0.0" + self.latest_version = '0.0.0' self.latest_release = None self.is_latest = True diff --git a/app/ch14_testing/starter/pypi_org/views/account_views.py b/app/ch14_testing/starter/pypi_org/views/account_views.py index 3854b4cf..652f43b3 100644 --- a/app/ch14_testing/starter/pypi_org/views/account_views.py +++ b/app/ch14_testing/starter/pypi_org/views/account_views.py @@ -25,6 +25,7 @@ def index(): # ################### REGISTER ################################# + @blueprint.route('/account/register', methods=['GET']) @response(template_file='account/register.html') def register_get(): @@ -54,6 +55,7 @@ def register_post(): # ################### LOGIN ################################# + @blueprint.route('/account/login', methods=['GET']) @response(template_file='account/login.html') def login_get(): @@ -77,7 +79,7 @@ def login_post(): user = user_service.login_user(vm.email, vm.password) if not user: - vm.error = "The account does not exist or the password is wrong." + vm.error = 'The account does not exist or the password is wrong.' return vm.to_dict() resp = flask.redirect('/account') @@ -88,6 +90,7 @@ def login_post(): # ################### LOGOUT ################################# + @blueprint.route('/account/logout') def logout(): resp = flask.redirect('/') diff --git a/app/ch14_testing/starter/pypi_org/views/package_views.py b/app/ch14_testing/starter/pypi_org/views/package_views.py index 1a74549f..2f862740 100644 --- a/app/ch14_testing/starter/pypi_org/views/package_views.py +++ b/app/ch14_testing/starter/pypi_org/views/package_views.py @@ -19,4 +19,4 @@ def package_details(package_name: str): @blueprint.route('/') def popular(rank: int): print(type(rank), rank) - return "The details for the {}th most popular package".format(rank) + return 'The details for the {}th most popular package'.format(rank) diff --git a/app/ch15_deploy/final/alembic/alembic_helpers.py b/app/ch15_deploy/final/alembic/alembic_helpers.py index 561f7a70..6aea52d4 100644 --- a/app/ch15_deploy/final/alembic/alembic_helpers.py +++ b/app/ch15_deploy/final/alembic/alembic_helpers.py @@ -5,8 +5,7 @@ def table_has_column(table, column): config = op.get_context().config - engine = engine_from_config( - config.get_section(config.config_ini_section), prefix='sqlalchemy.') + engine = engine_from_config(config.get_section(config.config_ini_section), prefix='sqlalchemy.') insp = reflection.Inspector.from_engine(engine) has_column = False for col in insp.get_columns(table): diff --git a/app/ch15_deploy/final/alembic/env.py b/app/ch15_deploy/final/alembic/env.py index 27ec49fb..1fdc9cab 100644 --- a/app/ch15_deploy/final/alembic/env.py +++ b/app/ch15_deploy/final/alembic/env.py @@ -26,6 +26,7 @@ sys.path.insert(0, folder) from pypi_org.data.modelbase import SqlAlchemyBase + # noinspection PyUnresolvedReferences import pypi_org.data.__all_models @@ -49,10 +50,8 @@ def run_migrations_offline(): script output. """ - url = config.get_main_option("sqlalchemy.url") - context.configure( - url=url, target_metadata=target_metadata, literal_binds=True - ) + url = config.get_main_option('sqlalchemy.url') + context.configure(url=url, target_metadata=target_metadata, literal_binds=True) with context.begin_transaction(): context.run_migrations() @@ -67,14 +66,12 @@ def run_migrations_online(): """ connectable = engine_from_config( config.get_section(config.config_ini_section), - prefix="sqlalchemy.", + prefix='sqlalchemy.', poolclass=pool.NullPool, ) with connectable.connect() as connection: - context.configure( - connection=connection, target_metadata=target_metadata - ) + context.configure(connection=connection, target_metadata=target_metadata) with context.begin_transaction(): context.run_migrations() diff --git a/app/ch15_deploy/final/alembic/versions/722c82f0097c_added_auditing_table.py b/app/ch15_deploy/final/alembic/versions/722c82f0097c_added_auditing_table.py index 2c3e2a39..7c6e892f 100644 --- a/app/ch15_deploy/final/alembic/versions/722c82f0097c_added_auditing_table.py +++ b/app/ch15_deploy/final/alembic/versions/722c82f0097c_added_auditing_table.py @@ -18,11 +18,12 @@ def upgrade(): # ### commands auto generated by Alembic - please adjust! ### - op.create_table('auditing', - sa.Column('id', sa.String(), nullable=False), - sa.Column('created_date', sa.DateTime(), nullable=True), - sa.Column('description', sa.String(), nullable=True), - sa.PrimaryKeyConstraint('id') + op.create_table( + 'auditing', + sa.Column('id', sa.String(), nullable=False), + sa.Column('created_date', sa.DateTime(), nullable=True), + sa.Column('description', sa.String(), nullable=True), + sa.PrimaryKeyConstraint('id'), ) op.create_index(op.f('ix_auditing_created_date'), 'auditing', ['created_date'], unique=False) # ### end Alembic commands ### diff --git a/app/ch15_deploy/final/pypi_org/app.py b/app/ch15_deploy/final/pypi_org/app.py index d1de87c6..ee364816 100644 --- a/app/ch15_deploy/final/pypi_org/app.py +++ b/app/ch15_deploy/final/pypi_org/app.py @@ -16,21 +16,18 @@ def main(): def configure(): - print("Configuring Flask app:") + print('Configuring Flask app:') register_blueprints() - print("Registered blueprints") + print('Registered blueprints') setup_db() - print("DB setup completed.") - print("", flush=True) + print('DB setup completed.') + print('', flush=True) def setup_db(): - db_file = os.path.join( - os.path.dirname(__file__), - 'db', - 'pypi.sqlite') + db_file = os.path.join(os.path.dirname(__file__), 'db', 'pypi.sqlite') db_session.global_init(db_file) diff --git a/app/ch15_deploy/final/pypi_org/bin/basic_inserts.py b/app/ch15_deploy/final/pypi_org/bin/basic_inserts.py index d622a6ae..6d04f551 100644 --- a/app/ch15_deploy/final/pypi_org/bin/basic_inserts.py +++ b/app/ch15_deploy/final/pypi_org/bin/basic_inserts.py @@ -2,8 +2,7 @@ import sys # Make it run more easily outside of PyCharm -sys.path.insert(0, os.path.abspath(os.path.join( - os.path.dirname(__file__), "..", ".."))) +sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..'))) import pypi_org.data.db_session as db_session from pypi_org.data.package import Package @@ -20,24 +19,24 @@ def insert_a_package(): p = Package() p.id = input('Package id / name: ').strip().lower() - p.summary = input("Package summary: ").strip() - p.author_name = input("Author: ").strip() - p.license = input("License: ").strip() + p.summary = input('Package summary: ').strip() + p.author_name = input('Author: ').strip() + p.license = input('License: ').strip() - print("Release 1:") + print('Release 1:') r = Release() - r.major_ver = int(input("Major version: ")) - r.minor_ver = int(input("Minor version: ")) - r.build_ver = int(input("Build version: ")) - r.size = int(input("Size in bytes: ")) + r.major_ver = int(input('Major version: ')) + r.minor_ver = int(input('Minor version: ')) + r.build_ver = int(input('Build version: ')) + r.size = int(input('Size in bytes: ')) p.releases.append(r) - print("Release 2:") + print('Release 2:') r = Release() - r.major_ver = int(input("Major version: ")) - r.minor_ver = int(input("Minor version: ")) - r.build_ver = int(input("Build version: ")) - r.size = int(input("Size in bytes: ")) + r.major_ver = int(input('Major version: ')) + r.minor_ver = int(input('Minor version: ')) + r.build_ver = int(input('Build version: ')) + r.size = int(input('Size in bytes: ')) p.releases.append(r) session = db_session.create_session() diff --git a/app/ch15_deploy/final/pypi_org/bin/load_data.py b/app/ch15_deploy/final/pypi_org/bin/load_data.py index 8f43c13c..228c1b6b 100644 --- a/app/ch15_deploy/final/pypi_org/bin/load_data.py +++ b/app/ch15_deploy/final/pypi_org/bin/load_data.py @@ -7,8 +7,7 @@ import progressbar from dateutil.parser import parse -sys.path.insert(0, os.path.abspath(os.path.join( - os.path.dirname(__file__), "..", ".."))) +sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..'))) import pypi_org.data.db_session as db_session from pypi_org.data.languages import ProgrammingLanguage @@ -39,7 +38,7 @@ def main(): def do_import_languages(file_data: List[dict]): imported = set() - print("Importing languages ... ", flush=True) + print('Importing languages ... ', flush=True) with progressbar.ProgressBar(max_value=len(file_data)) as bar: for idx, p in enumerate(file_data): info = p.get('info') @@ -74,7 +73,7 @@ def do_import_languages(file_data: List[dict]): def do_import_licenses(file_data: List[dict]): imported = set() - print("Importing licenses ... ", flush=True) + print('Importing licenses ... ', flush=True) with progressbar.ProgressBar(max_value=len(file_data)) as bar: for idx, p in enumerate(file_data): info = p.get('info') @@ -100,17 +99,17 @@ def do_import_licenses(file_data: List[dict]): def do_summary(): session = db_session.create_session() - print("Final numbers:") - print("Users: {:,}".format(session.query(User).count())) - print("Packages: {:,}".format(session.query(Package).count())) - print("Releases: {:,}".format(session.query(Release).count())) - print("Maintainers: {:,}".format(session.query(Maintainer).count())) - print("Languages: {:,}".format(session.query(ProgrammingLanguage).count())) - print("Licenses: {:,}".format(session.query(License).count())) + print('Final numbers:') + print('Users: {:,}'.format(session.query(User).count())) + print('Packages: {:,}'.format(session.query(Package).count())) + print('Releases: {:,}'.format(session.query(Release).count())) + print('Maintainers: {:,}'.format(session.query(Maintainer).count())) + print('Languages: {:,}'.format(session.query(ProgrammingLanguage).count())) + print('Licenses: {:,}'.format(session.query(License).count())) def do_user_import(user_lookup: Dict[str, str]) -> Dict[str, User]: - print("Importing users ... ", flush=True) + print('Importing users ... ', flush=True) with progressbar.ProgressBar(max_value=len(user_lookup)) as bar: for idx, (email, name) in enumerate(user_lookup.items()): session = db_session.create_session() @@ -134,29 +133,29 @@ def do_user_import(user_lookup: Dict[str, str]) -> Dict[str, User]: def do_import_packages(file_data: List[dict], user_lookup: Dict[str, User]): errored_packages = [] - print("Importing packages and releases ... ", flush=True) + print('Importing packages and releases ... ', flush=True) with progressbar.ProgressBar(max_value=len(file_data)) as bar: for idx, p in enumerate(file_data): try: load_package(p, user_lookup) bar.update(idx) except Exception as x: - errored_packages.append((p, " *** Errored out for package {}, {}".format(p.get('package_name'), x))) + errored_packages.append((p, ' *** Errored out for package {}, {}'.format(p.get('package_name'), x))) raise sys.stderr.flush() sys.stdout.flush() print() - print("Completed packages with {} errors.".format(len(errored_packages))) - for (p, txt) in errored_packages: + print('Completed packages with {} errors.'.format(len(errored_packages))) + for p, txt in errored_packages: print(txt) def do_load_files() -> List[dict]: data_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../../../data/pypi-top-100')) - print("Loading files from {}".format(data_path)) + print('Loading files from {}'.format(data_path)) files = get_file_names(data_path) - print("Found {:,} files, loading ...".format(len(files)), flush=True) - time.sleep(.1) + print('Found {:,} files, loading ...'.format(len(files)), flush=True) + time.sleep(0.1) file_data = [] with progressbar.ProgressBar(max_value=len(files)) as bar: @@ -171,7 +170,7 @@ def do_load_files() -> List[dict]: def find_users(data: List[dict]) -> dict: - print("Discovering users...", flush=True) + print('Discovering users...', flush=True) found_users = {} with progressbar.ProgressBar(max_value=len(data)) as bar: @@ -184,7 +183,7 @@ def find_users(data: List[dict]) -> dict: sys.stderr.flush() sys.stdout.flush() print() - print("Discovered {:,} users".format(len(found_users))) + print('Discovered {:,} users'.format(len(found_users))) print() return found_users @@ -215,7 +214,7 @@ def load_file_data(filename: str) -> dict: with open(filename, 'r', encoding='utf-8') as fin: data = json.load(fin) except Exception as x: - print("ERROR in file: {}, details: {}".format(filename, x), flush=True) + print('ERROR in file: {}, details: {}'.format(filename, x), flush=True) raise return data @@ -233,7 +232,7 @@ def load_package(data: dict, user_lookup: Dict[str, User]): p.author = info.get('author') p.author_email = info.get('author_email') - releases = build_releases(p.id, data.get("releases", {})) + releases = build_releases(p.id, data.get('releases', {})) if releases: p.created_date = releases[0].created_date @@ -283,18 +282,13 @@ def detect_license(license_text: str) -> Optional[str]: license_text = license_text.strip() if len(license_text) > 100 or '\n' in license_text: - return "CUSTOM" + return 'CUSTOM' - license_text = license_text \ - .replace('Software License', '') \ - .replace('License', '') + license_text = license_text.replace('Software License', '').replace('License', '') if '::' in license_text: # E.g. 'License :: OSI Approved :: Apache Software License' - return license_text \ - .split(':')[-1] \ - .replace(' ', ' ') \ - .strip() + return license_text.split(':')[-1].replace(' ', ' ').strip() return license_text.strip() @@ -357,9 +351,7 @@ def get_file_names(data_path: str) -> List[str]: files = [] for f in os.listdir(data_path): if f.endswith('.json'): - files.append( - os.path.abspath(os.path.join(data_path, f)) - ) + files.append(os.path.abspath(os.path.join(data_path, f))) files.sort() return files diff --git a/app/ch15_deploy/final/pypi_org/data/__all_models.py b/app/ch15_deploy/final/pypi_org/data/__all_models.py index f399ef54..ca4804ac 100644 --- a/app/ch15_deploy/final/pypi_org/data/__all_models.py +++ b/app/ch15_deploy/final/pypi_org/data/__all_models.py @@ -5,17 +5,24 @@ # noinspection PyUnresolvedReferences import pypi_org.data.audit + # noinspection PyUnresolvedReferences import pypi_org.data.downloads + # noinspection PyUnresolvedReferences import pypi_org.data.languages + # noinspection PyUnresolvedReferences import pypi_org.data.licenses + # noinspection PyUnresolvedReferences import pypi_org.data.maintainers + # noinspection PyUnresolvedReferences import pypi_org.data.package + # noinspection PyUnresolvedReferences import pypi_org.data.releases + # noinspection PyUnresolvedReferences import pypi_org.data.users diff --git a/app/ch15_deploy/final/pypi_org/data/db_session.py b/app/ch15_deploy/final/pypi_org/data/db_session.py index 39b135cc..86eb3fb2 100644 --- a/app/ch15_deploy/final/pypi_org/data/db_session.py +++ b/app/ch15_deploy/final/pypi_org/data/db_session.py @@ -14,15 +14,15 @@ def global_init(db_file: str): return if not db_file or not db_file.strip(): - raise Exception("You must specify a db file.") + raise Exception('You must specify a db file.') conn_str = 'sqlite:///' + db_file.strip() - print("Connecting to DB with {}".format(conn_str)) + print('Connecting to DB with {}'.format(conn_str)) # Adding check_same_thread = False after the recording. This can be an issue about # creating / owner thread when cleaning up sessions, etc. This is a sqlite restriction # that we probably don't care about in this example. - engine = sa.create_engine(conn_str, echo=False, connect_args={"check_same_thread": False}) + engine = sa.create_engine(conn_str, echo=False, connect_args={'check_same_thread': False}) __factory = orm.sessionmaker(bind=engine) # noinspection PyUnresolvedReferences diff --git a/app/ch15_deploy/final/pypi_org/data/downloads.py b/app/ch15_deploy/final/pypi_org/data/downloads.py index 66068f02..dd8afd65 100644 --- a/app/ch15_deploy/final/pypi_org/data/downloads.py +++ b/app/ch15_deploy/final/pypi_org/data/downloads.py @@ -7,8 +7,7 @@ class Download(SqlAlchemyBase): __tablename__ = 'downloads' id: int = sqlalchemy.Column(sqlalchemy.BigInteger, primary_key=True, autoincrement=True) - created_date: datetime.datetime = sqlalchemy.Column( - sqlalchemy.DateTime, default=datetime.datetime.now, index=True) + created_date: datetime.datetime = sqlalchemy.Column(sqlalchemy.DateTime, default=datetime.datetime.now, index=True) package_id: str = sqlalchemy.Column(sqlalchemy.String, index=True) release_id: int = sqlalchemy.Column(sqlalchemy.BigInteger, index=True) diff --git a/app/ch15_deploy/final/pypi_org/data/languages.py b/app/ch15_deploy/final/pypi_org/data/languages.py index 964b8444..3a73dde0 100644 --- a/app/ch15_deploy/final/pypi_org/data/languages.py +++ b/app/ch15_deploy/final/pypi_org/data/languages.py @@ -7,6 +7,5 @@ class ProgrammingLanguage(SqlAlchemyBase): __tablename__ = 'languages' id: str = sqlalchemy.Column(sqlalchemy.String, primary_key=True) - created_date: datetime.datetime = sqlalchemy.Column( - sqlalchemy.DateTime, default=datetime.datetime.now, index=True) + created_date: datetime.datetime = sqlalchemy.Column(sqlalchemy.DateTime, default=datetime.datetime.now, index=True) description: str = sqlalchemy.Column(sqlalchemy.String) diff --git a/app/ch15_deploy/final/pypi_org/data/package.py b/app/ch15_deploy/final/pypi_org/data/package.py index c3420d1b..16e6d156 100644 --- a/app/ch15_deploy/final/pypi_org/data/package.py +++ b/app/ch15_deploy/final/pypi_org/data/package.py @@ -26,11 +26,15 @@ class Package(SqlAlchemyBase): license: str = sa.Column(sa.String, index=True) # releases relationship - releases: List[Release] = orm.relation("Release", order_by=[ - Release.major_ver.desc(), - Release.minor_ver.desc(), - Release.build_ver.desc(), - ], back_populates='package') + releases: List[Release] = orm.relation( + 'Release', + order_by=[ + Release.major_ver.desc(), + Release.minor_ver.desc(), + Release.build_ver.desc(), + ], + back_populates='package', + ) def __repr__(self): return ''.format(self.id) diff --git a/app/ch15_deploy/final/pypi_org/data/releases.py b/app/ch15_deploy/final/pypi_org/data/releases.py index 7650e438..8596f65c 100644 --- a/app/ch15_deploy/final/pypi_org/data/releases.py +++ b/app/ch15_deploy/final/pypi_org/data/releases.py @@ -13,15 +13,13 @@ class Release(SqlAlchemyBase): minor_ver: int = sqlalchemy.Column(sqlalchemy.BigInteger, index=True) build_ver: int = sqlalchemy.Column(sqlalchemy.BigInteger, index=True) - created_date: datetime.datetime = sqlalchemy.Column(sqlalchemy.DateTime, - default=datetime.datetime.now, - index=True) + created_date: datetime.datetime = sqlalchemy.Column(sqlalchemy.DateTime, default=datetime.datetime.now, index=True) comment: str = sqlalchemy.Column(sqlalchemy.String) url: str = sqlalchemy.Column(sqlalchemy.String) size: int = sqlalchemy.Column(sqlalchemy.BigInteger) # Package relationship - package_id: str = sqlalchemy.Column(sqlalchemy.String, sqlalchemy.ForeignKey("packages.id")) + package_id: str = sqlalchemy.Column(sqlalchemy.String, sqlalchemy.ForeignKey('packages.id')) package = orm.relation('Package') @property diff --git a/app/ch15_deploy/final/pypi_org/infrastructure/cookie_auth.py b/app/ch15_deploy/final/pypi_org/infrastructure/cookie_auth.py index 44864438..c215c0af 100644 --- a/app/ch15_deploy/final/pypi_org/infrastructure/cookie_auth.py +++ b/app/ch15_deploy/final/pypi_org/infrastructure/cookie_auth.py @@ -11,7 +11,7 @@ def set_auth(response: Response, user_id: int): hash_val = __hash_text(str(user_id)) - val = "{}:{}".format(user_id, hash_val) + val = '{}:{}'.format(user_id, hash_val) response.set_cookie(auth_cookie_name, val, secure=False, httponly=True, samesite='Lax') @@ -33,7 +33,7 @@ def get_user_id_via_auth_cookie(request: Request) -> Optional[int]: hash_val = parts[1] hash_val_check = __hash_text(user_id) if hash_val != hash_val_check: - print("Warning: Hash mismatch, invalid cookie value") + print('Warning: Hash mismatch, invalid cookie value') return None return try_int(user_id) diff --git a/app/ch15_deploy/final/pypi_org/infrastructure/request_dict.py b/app/ch15_deploy/final/pypi_org/infrastructure/request_dict.py index d7ab10de..d44ae574 100644 --- a/app/ch15_deploy/final/pypi_org/infrastructure/request_dict.py +++ b/app/ch15_deploy/final/pypi_org/infrastructure/request_dict.py @@ -29,7 +29,7 @@ def create(default_val=None, **route_args) -> RequestDictionary: **args, # The key/value pairs in the URL query string **request.headers, # Header values **form, # The key/value pairs in the body, from a HTML post form - **route_args # And additional arguments the method access, if they want them merged. + **route_args, # And additional arguments the method access, if they want them merged. } return RequestDictionary(data, default_val=default_val) diff --git a/app/ch15_deploy/final/pypi_org/infrastructure/view_modifiers.py b/app/ch15_deploy/final/pypi_org/infrastructure/view_modifiers.py index 0978163e..d944c142 100644 --- a/app/ch15_deploy/final/pypi_org/infrastructure/view_modifiers.py +++ b/app/ch15_deploy/final/pypi_org/infrastructure/view_modifiers.py @@ -26,7 +26,8 @@ def view_method(*args, **kwargs): if template_file and not isinstance(response_val, dict): raise Exception( - "Invalid return type {}, we expected a dict as the return value.".format(type(response_val))) + 'Invalid return type {}, we expected a dict as the return value.'.format(type(response_val)) + ) if template_file: response_val = flask.render_template(template_file, **response_val) @@ -42,6 +43,7 @@ def view_method(*args, **kwargs): return response_inner + # # def template(template_file: str = None): # def template_inner(f): diff --git a/app/ch15_deploy/final/pypi_org/services/package_service.py b/app/ch15_deploy/final/pypi_org/services/package_service.py index b03408d2..9a153773 100644 --- a/app/ch15_deploy/final/pypi_org/services/package_service.py +++ b/app/ch15_deploy/final/pypi_org/services/package_service.py @@ -10,12 +10,13 @@ def get_latest_releases(limit=10) -> List[Release]: session = db_session.create_session() try: - - releases = session.query(Release). \ - options(sqlalchemy.orm.joinedload(Release.package)). \ - order_by(Release.created_date.desc()). \ - limit(limit). \ - all() + releases = ( + session.query(Release) + .options(sqlalchemy.orm.joinedload(Release.package)) + .order_by(Release.created_date.desc()) + .limit(limit) + .all() + ) finally: session.close() @@ -47,11 +48,12 @@ def get_package_by_id(package_id: str) -> Optional[Package]: session = db_session.create_session() try: - - package = session.query(Package) \ - .options(sqlalchemy.orm.joinedload(Package.releases)) \ - .filter(Package.id == package_id) \ + package = ( + session.query(Package) + .options(sqlalchemy.orm.joinedload(Package.releases)) + .filter(Package.id == package_id) .first() + ) finally: session.close() diff --git a/app/ch15_deploy/final/pypi_org/viewmodels/cms/page_viewmodel.py b/app/ch15_deploy/final/pypi_org/viewmodels/cms/page_viewmodel.py index b7bb3249..ec033c3f 100644 --- a/app/ch15_deploy/final/pypi_org/viewmodels/cms/page_viewmodel.py +++ b/app/ch15_deploy/final/pypi_org/viewmodels/cms/page_viewmodel.py @@ -7,4 +7,3 @@ def __init__(self, full_url: str): super().__init__() self.page = cms_service.get_page(full_url) - diff --git a/app/ch15_deploy/final/pypi_org/viewmodels/packages/pagedetails_viewmodel.py b/app/ch15_deploy/final/pypi_org/viewmodels/packages/pagedetails_viewmodel.py index 63c4cf68..09f47c6f 100644 --- a/app/ch15_deploy/final/pypi_org/viewmodels/packages/pagedetails_viewmodel.py +++ b/app/ch15_deploy/final/pypi_org/viewmodels/packages/pagedetails_viewmodel.py @@ -11,7 +11,7 @@ def __init__(self, package_name: str): self.package_name = package_name.strip().lower() self.package = package_service.get_package_by_id(self.package_name) - self.latest_version = "0.0.0" + self.latest_version = '0.0.0' self.latest_release = None self.is_latest = True diff --git a/app/ch15_deploy/final/pypi_org/viewmodels/seo/sitemap_viewmodel.py b/app/ch15_deploy/final/pypi_org/viewmodels/seo/sitemap_viewmodel.py index 912c4df0..71df2f99 100644 --- a/app/ch15_deploy/final/pypi_org/viewmodels/seo/sitemap_viewmodel.py +++ b/app/ch15_deploy/final/pypi_org/viewmodels/seo/sitemap_viewmodel.py @@ -8,5 +8,5 @@ class SiteMapViewModel(ViewModelBase): def __init__(self, limit: int): super().__init__() self.packages = package_service.all_packages(limit) - self.last_updated_text = "2019-07-15" - self.site = "{}://{}".format(flask.request.scheme, flask.request.host) + self.last_updated_text = '2019-07-15' + self.site = '{}://{}'.format(flask.request.scheme, flask.request.host) diff --git a/app/ch15_deploy/final/pypi_org/views/account_views.py b/app/ch15_deploy/final/pypi_org/views/account_views.py index 59cd4c81..261f9c34 100644 --- a/app/ch15_deploy/final/pypi_org/views/account_views.py +++ b/app/ch15_deploy/final/pypi_org/views/account_views.py @@ -25,6 +25,7 @@ def index(): # ################### REGISTER ################################# + @blueprint.route('/account/register', methods=['GET']) @response(template_file='account/register.html') def register_get(): @@ -54,6 +55,7 @@ def register_post(): # ################### LOGIN ################################# + @blueprint.route('/account/login', methods=['GET']) @response(template_file='account/login.html') def login_get(): @@ -77,7 +79,7 @@ def login_post(): user = user_service.login_user(vm.email, vm.password) if not user: - vm.error = "The account does not exist or the password is wrong." + vm.error = 'The account does not exist or the password is wrong.' return vm.to_dict() resp = flask.redirect('/account') @@ -88,6 +90,7 @@ def login_post(): # ################### LOGOUT ################################# + @blueprint.route('/account/logout') def logout(): resp = flask.redirect('/') diff --git a/app/ch15_deploy/final/pypi_org/views/package_views.py b/app/ch15_deploy/final/pypi_org/views/package_views.py index 1a74549f..2f862740 100644 --- a/app/ch15_deploy/final/pypi_org/views/package_views.py +++ b/app/ch15_deploy/final/pypi_org/views/package_views.py @@ -19,4 +19,4 @@ def package_details(package_name: str): @blueprint.route('/') def popular(rank: int): print(type(rank), rank) - return "The details for the {}th most popular package".format(rank) + return 'The details for the {}th most popular package'.format(rank) diff --git a/app/ch15_deploy/final/pypi_org/views/seo_view.py b/app/ch15_deploy/final/pypi_org/views/seo_view.py index 93c88de5..f86b6bff 100644 --- a/app/ch15_deploy/final/pypi_org/views/seo_view.py +++ b/app/ch15_deploy/final/pypi_org/views/seo_view.py @@ -18,6 +18,7 @@ def sitemap(): # ################### Robots ################################# + @blueprint.route('/robots.txt') @response(mimetype='text/plain', template_file='seo/robots.txt') def robots(): diff --git a/app/ch15_deploy/final/tests/_all_tests.py b/app/ch15_deploy/final/tests/_all_tests.py index daa69ea4..e5c9b9ea 100644 --- a/app/ch15_deploy/final/tests/_all_tests.py +++ b/app/ch15_deploy/final/tests/_all_tests.py @@ -1,17 +1,18 @@ import sys import os -container_folder = os.path.abspath(os.path.join( - os.path.dirname(__file__), '..' -)) +container_folder = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) sys.path.insert(0, container_folder) # noinspection PyUnresolvedReferences from account_tests import * + # noinspection PyUnresolvedReferences from package_tests import * + # noinspection PyUnresolvedReferences from sitemap_tests import * + # noinspection PyUnresolvedReferences from home_tests import * diff --git a/app/ch15_deploy/final/tests/account_tests.py b/app/ch15_deploy/final/tests/account_tests.py index 4f5aa156..e31e8c28 100644 --- a/app/ch15_deploy/final/tests/account_tests.py +++ b/app/ch15_deploy/final/tests/account_tests.py @@ -7,7 +7,7 @@ def test_example(): - print("Test example...") + print('Test example...') assert 1 + 2 == 3 @@ -15,11 +15,7 @@ def test_vm_register_validation_when_valid(): # 3 A's of test: Arrange, Act, then Assert # Arrange - form_data = { - 'name': 'Michael', - 'email': 'michael@talkpython.fm', - 'password': 'a' * 6 - } + form_data = {'name': 'Michael', 'email': 'michael@talkpython.fm', 'password': 'a' * 6} with flask_app.test_request_context(path='/account/register', data=form_data): vm = RegisterViewModel() @@ -37,11 +33,7 @@ def test_vm_register_validation_for_existing_user(): # 3 A's of test: Arrange, Act, then Assert # Arrange - form_data = { - 'name': 'Michael', - 'email': 'michael@talkpython.fm', - 'password': 'a' * 6 - } + form_data = {'name': 'Michael', 'email': 'michael@talkpython.fm', 'password': 'a' * 6} with flask_app.test_request_context(path='/account/register', data=form_data): vm = RegisterViewModel() @@ -62,11 +54,8 @@ def test_v_register_view_new_user(): # Arrange from pypi_org.views.account_views import register_post - form_data = { - 'name': 'Michael', - 'email': 'michael@talkpython.fm', - 'password': 'a' * 6 - } + + form_data = {'name': 'Michael', 'email': 'michael@talkpython.fm', 'password': 'a' * 6} target = 'pypi_org.services.user_service.find_user_by_email' find_user = unittest.mock.patch(target, return_value=None) diff --git a/app/ch15_deploy/final/tests/package_tests.py b/app/ch15_deploy/final/tests/package_tests.py index efd04ef5..a7c221a5 100644 --- a/app/ch15_deploy/final/tests/package_tests.py +++ b/app/ch15_deploy/final/tests/package_tests.py @@ -12,15 +12,14 @@ def test_package_details_success(): test_package = Package() test_package.id = 'sqlalchemy' - test_package.description = "TDB" + test_package.description = 'TDB' test_package.releases = [ Release(created_date=datetime.datetime.now(), major_ver=1, minor_ver=2, build_ver=200), Release(created_date=datetime.datetime.now() - datetime.timedelta(days=10)), ] # Act - with unittest.mock.patch('pypi_org.services.package_service.get_package_by_id', - return_value=test_package): + with unittest.mock.patch('pypi_org.services.package_service.get_package_by_id', return_value=test_package): with flask_app.test_request_context(path='/project/' + test_package.id): resp: Response = package_details(test_package.id) @@ -33,8 +32,7 @@ def test_package_details_404(client): bad_package_url = 'sqlalchemy_missing' # Act - with unittest.mock.patch('pypi_org.services.package_service.get_package_by_id', - return_value=None): + with unittest.mock.patch('pypi_org.services.package_service.get_package_by_id', return_value=None): resp: Response = client.get(bad_package_url) assert resp.status_code == 404 diff --git a/app/ch15_deploy/final/tests/sitemap_tests.py b/app/ch15_deploy/final/tests/sitemap_tests.py index b1afe0fe..4494c30a 100644 --- a/app/ch15_deploy/final/tests/sitemap_tests.py +++ b/app/ch15_deploy/final/tests/sitemap_tests.py @@ -10,10 +10,7 @@ def test_int_site_mapped_urls(client): href.text.strip().replace('http://127.0.0.1:5000', '').replace('http://localhost', '') for href in list(x.findall('url/loc')) ] - urls = [ - u if u else '/' - for u in urls - ] + urls = [u if u else '/' for u in urls] print('Testing {} urls from sitemap...'.format(len(urls)), flush=True) has_tested_projects = False @@ -40,7 +37,7 @@ def get_sitemap_text(client): # # ... # - res: Response = client.get("/sitemap.xml") - text = res.data.decode("utf-8") + res: Response = client.get('/sitemap.xml') + text = res.data.decode('utf-8') text = text.replace('xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"', '') return text diff --git a/app/ch15_deploy/final/tests/test_client.py b/app/ch15_deploy/final/tests/test_client.py index ffbea486..4390409a 100644 --- a/app/ch15_deploy/final/tests/test_client.py +++ b/app/ch15_deploy/final/tests/test_client.py @@ -4,9 +4,7 @@ import sys import os -container_folder = os.path.abspath(os.path.join( - os.path.dirname(__file__), '..' -)) +container_folder = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) sys.path.insert(0, container_folder) import pypi_org.app diff --git a/app/ch15_deploy/starter/alembic/alembic_helpers.py b/app/ch15_deploy/starter/alembic/alembic_helpers.py index 561f7a70..6aea52d4 100644 --- a/app/ch15_deploy/starter/alembic/alembic_helpers.py +++ b/app/ch15_deploy/starter/alembic/alembic_helpers.py @@ -5,8 +5,7 @@ def table_has_column(table, column): config = op.get_context().config - engine = engine_from_config( - config.get_section(config.config_ini_section), prefix='sqlalchemy.') + engine = engine_from_config(config.get_section(config.config_ini_section), prefix='sqlalchemy.') insp = reflection.Inspector.from_engine(engine) has_column = False for col in insp.get_columns(table): diff --git a/app/ch15_deploy/starter/alembic/env.py b/app/ch15_deploy/starter/alembic/env.py index 27ec49fb..1fdc9cab 100644 --- a/app/ch15_deploy/starter/alembic/env.py +++ b/app/ch15_deploy/starter/alembic/env.py @@ -26,6 +26,7 @@ sys.path.insert(0, folder) from pypi_org.data.modelbase import SqlAlchemyBase + # noinspection PyUnresolvedReferences import pypi_org.data.__all_models @@ -49,10 +50,8 @@ def run_migrations_offline(): script output. """ - url = config.get_main_option("sqlalchemy.url") - context.configure( - url=url, target_metadata=target_metadata, literal_binds=True - ) + url = config.get_main_option('sqlalchemy.url') + context.configure(url=url, target_metadata=target_metadata, literal_binds=True) with context.begin_transaction(): context.run_migrations() @@ -67,14 +66,12 @@ def run_migrations_online(): """ connectable = engine_from_config( config.get_section(config.config_ini_section), - prefix="sqlalchemy.", + prefix='sqlalchemy.', poolclass=pool.NullPool, ) with connectable.connect() as connection: - context.configure( - connection=connection, target_metadata=target_metadata - ) + context.configure(connection=connection, target_metadata=target_metadata) with context.begin_transaction(): context.run_migrations() diff --git a/app/ch15_deploy/starter/alembic/versions/722c82f0097c_added_auditing_table.py b/app/ch15_deploy/starter/alembic/versions/722c82f0097c_added_auditing_table.py index 2c3e2a39..7c6e892f 100644 --- a/app/ch15_deploy/starter/alembic/versions/722c82f0097c_added_auditing_table.py +++ b/app/ch15_deploy/starter/alembic/versions/722c82f0097c_added_auditing_table.py @@ -18,11 +18,12 @@ def upgrade(): # ### commands auto generated by Alembic - please adjust! ### - op.create_table('auditing', - sa.Column('id', sa.String(), nullable=False), - sa.Column('created_date', sa.DateTime(), nullable=True), - sa.Column('description', sa.String(), nullable=True), - sa.PrimaryKeyConstraint('id') + op.create_table( + 'auditing', + sa.Column('id', sa.String(), nullable=False), + sa.Column('created_date', sa.DateTime(), nullable=True), + sa.Column('description', sa.String(), nullable=True), + sa.PrimaryKeyConstraint('id'), ) op.create_index(op.f('ix_auditing_created_date'), 'auditing', ['created_date'], unique=False) # ### end Alembic commands ### diff --git a/app/ch15_deploy/starter/pypi_org/app.py b/app/ch15_deploy/starter/pypi_org/app.py index d1de87c6..ee364816 100644 --- a/app/ch15_deploy/starter/pypi_org/app.py +++ b/app/ch15_deploy/starter/pypi_org/app.py @@ -16,21 +16,18 @@ def main(): def configure(): - print("Configuring Flask app:") + print('Configuring Flask app:') register_blueprints() - print("Registered blueprints") + print('Registered blueprints') setup_db() - print("DB setup completed.") - print("", flush=True) + print('DB setup completed.') + print('', flush=True) def setup_db(): - db_file = os.path.join( - os.path.dirname(__file__), - 'db', - 'pypi.sqlite') + db_file = os.path.join(os.path.dirname(__file__), 'db', 'pypi.sqlite') db_session.global_init(db_file) diff --git a/app/ch15_deploy/starter/pypi_org/bin/basic_inserts.py b/app/ch15_deploy/starter/pypi_org/bin/basic_inserts.py index d622a6ae..6d04f551 100644 --- a/app/ch15_deploy/starter/pypi_org/bin/basic_inserts.py +++ b/app/ch15_deploy/starter/pypi_org/bin/basic_inserts.py @@ -2,8 +2,7 @@ import sys # Make it run more easily outside of PyCharm -sys.path.insert(0, os.path.abspath(os.path.join( - os.path.dirname(__file__), "..", ".."))) +sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..'))) import pypi_org.data.db_session as db_session from pypi_org.data.package import Package @@ -20,24 +19,24 @@ def insert_a_package(): p = Package() p.id = input('Package id / name: ').strip().lower() - p.summary = input("Package summary: ").strip() - p.author_name = input("Author: ").strip() - p.license = input("License: ").strip() + p.summary = input('Package summary: ').strip() + p.author_name = input('Author: ').strip() + p.license = input('License: ').strip() - print("Release 1:") + print('Release 1:') r = Release() - r.major_ver = int(input("Major version: ")) - r.minor_ver = int(input("Minor version: ")) - r.build_ver = int(input("Build version: ")) - r.size = int(input("Size in bytes: ")) + r.major_ver = int(input('Major version: ')) + r.minor_ver = int(input('Minor version: ')) + r.build_ver = int(input('Build version: ')) + r.size = int(input('Size in bytes: ')) p.releases.append(r) - print("Release 2:") + print('Release 2:') r = Release() - r.major_ver = int(input("Major version: ")) - r.minor_ver = int(input("Minor version: ")) - r.build_ver = int(input("Build version: ")) - r.size = int(input("Size in bytes: ")) + r.major_ver = int(input('Major version: ')) + r.minor_ver = int(input('Minor version: ')) + r.build_ver = int(input('Build version: ')) + r.size = int(input('Size in bytes: ')) p.releases.append(r) session = db_session.create_session() diff --git a/app/ch15_deploy/starter/pypi_org/bin/load_data.py b/app/ch15_deploy/starter/pypi_org/bin/load_data.py index 8f43c13c..228c1b6b 100644 --- a/app/ch15_deploy/starter/pypi_org/bin/load_data.py +++ b/app/ch15_deploy/starter/pypi_org/bin/load_data.py @@ -7,8 +7,7 @@ import progressbar from dateutil.parser import parse -sys.path.insert(0, os.path.abspath(os.path.join( - os.path.dirname(__file__), "..", ".."))) +sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..'))) import pypi_org.data.db_session as db_session from pypi_org.data.languages import ProgrammingLanguage @@ -39,7 +38,7 @@ def main(): def do_import_languages(file_data: List[dict]): imported = set() - print("Importing languages ... ", flush=True) + print('Importing languages ... ', flush=True) with progressbar.ProgressBar(max_value=len(file_data)) as bar: for idx, p in enumerate(file_data): info = p.get('info') @@ -74,7 +73,7 @@ def do_import_languages(file_data: List[dict]): def do_import_licenses(file_data: List[dict]): imported = set() - print("Importing licenses ... ", flush=True) + print('Importing licenses ... ', flush=True) with progressbar.ProgressBar(max_value=len(file_data)) as bar: for idx, p in enumerate(file_data): info = p.get('info') @@ -100,17 +99,17 @@ def do_import_licenses(file_data: List[dict]): def do_summary(): session = db_session.create_session() - print("Final numbers:") - print("Users: {:,}".format(session.query(User).count())) - print("Packages: {:,}".format(session.query(Package).count())) - print("Releases: {:,}".format(session.query(Release).count())) - print("Maintainers: {:,}".format(session.query(Maintainer).count())) - print("Languages: {:,}".format(session.query(ProgrammingLanguage).count())) - print("Licenses: {:,}".format(session.query(License).count())) + print('Final numbers:') + print('Users: {:,}'.format(session.query(User).count())) + print('Packages: {:,}'.format(session.query(Package).count())) + print('Releases: {:,}'.format(session.query(Release).count())) + print('Maintainers: {:,}'.format(session.query(Maintainer).count())) + print('Languages: {:,}'.format(session.query(ProgrammingLanguage).count())) + print('Licenses: {:,}'.format(session.query(License).count())) def do_user_import(user_lookup: Dict[str, str]) -> Dict[str, User]: - print("Importing users ... ", flush=True) + print('Importing users ... ', flush=True) with progressbar.ProgressBar(max_value=len(user_lookup)) as bar: for idx, (email, name) in enumerate(user_lookup.items()): session = db_session.create_session() @@ -134,29 +133,29 @@ def do_user_import(user_lookup: Dict[str, str]) -> Dict[str, User]: def do_import_packages(file_data: List[dict], user_lookup: Dict[str, User]): errored_packages = [] - print("Importing packages and releases ... ", flush=True) + print('Importing packages and releases ... ', flush=True) with progressbar.ProgressBar(max_value=len(file_data)) as bar: for idx, p in enumerate(file_data): try: load_package(p, user_lookup) bar.update(idx) except Exception as x: - errored_packages.append((p, " *** Errored out for package {}, {}".format(p.get('package_name'), x))) + errored_packages.append((p, ' *** Errored out for package {}, {}'.format(p.get('package_name'), x))) raise sys.stderr.flush() sys.stdout.flush() print() - print("Completed packages with {} errors.".format(len(errored_packages))) - for (p, txt) in errored_packages: + print('Completed packages with {} errors.'.format(len(errored_packages))) + for p, txt in errored_packages: print(txt) def do_load_files() -> List[dict]: data_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../../../data/pypi-top-100')) - print("Loading files from {}".format(data_path)) + print('Loading files from {}'.format(data_path)) files = get_file_names(data_path) - print("Found {:,} files, loading ...".format(len(files)), flush=True) - time.sleep(.1) + print('Found {:,} files, loading ...'.format(len(files)), flush=True) + time.sleep(0.1) file_data = [] with progressbar.ProgressBar(max_value=len(files)) as bar: @@ -171,7 +170,7 @@ def do_load_files() -> List[dict]: def find_users(data: List[dict]) -> dict: - print("Discovering users...", flush=True) + print('Discovering users...', flush=True) found_users = {} with progressbar.ProgressBar(max_value=len(data)) as bar: @@ -184,7 +183,7 @@ def find_users(data: List[dict]) -> dict: sys.stderr.flush() sys.stdout.flush() print() - print("Discovered {:,} users".format(len(found_users))) + print('Discovered {:,} users'.format(len(found_users))) print() return found_users @@ -215,7 +214,7 @@ def load_file_data(filename: str) -> dict: with open(filename, 'r', encoding='utf-8') as fin: data = json.load(fin) except Exception as x: - print("ERROR in file: {}, details: {}".format(filename, x), flush=True) + print('ERROR in file: {}, details: {}'.format(filename, x), flush=True) raise return data @@ -233,7 +232,7 @@ def load_package(data: dict, user_lookup: Dict[str, User]): p.author = info.get('author') p.author_email = info.get('author_email') - releases = build_releases(p.id, data.get("releases", {})) + releases = build_releases(p.id, data.get('releases', {})) if releases: p.created_date = releases[0].created_date @@ -283,18 +282,13 @@ def detect_license(license_text: str) -> Optional[str]: license_text = license_text.strip() if len(license_text) > 100 or '\n' in license_text: - return "CUSTOM" + return 'CUSTOM' - license_text = license_text \ - .replace('Software License', '') \ - .replace('License', '') + license_text = license_text.replace('Software License', '').replace('License', '') if '::' in license_text: # E.g. 'License :: OSI Approved :: Apache Software License' - return license_text \ - .split(':')[-1] \ - .replace(' ', ' ') \ - .strip() + return license_text.split(':')[-1].replace(' ', ' ').strip() return license_text.strip() @@ -357,9 +351,7 @@ def get_file_names(data_path: str) -> List[str]: files = [] for f in os.listdir(data_path): if f.endswith('.json'): - files.append( - os.path.abspath(os.path.join(data_path, f)) - ) + files.append(os.path.abspath(os.path.join(data_path, f))) files.sort() return files diff --git a/app/ch15_deploy/starter/pypi_org/data/__all_models.py b/app/ch15_deploy/starter/pypi_org/data/__all_models.py index f399ef54..ca4804ac 100644 --- a/app/ch15_deploy/starter/pypi_org/data/__all_models.py +++ b/app/ch15_deploy/starter/pypi_org/data/__all_models.py @@ -5,17 +5,24 @@ # noinspection PyUnresolvedReferences import pypi_org.data.audit + # noinspection PyUnresolvedReferences import pypi_org.data.downloads + # noinspection PyUnresolvedReferences import pypi_org.data.languages + # noinspection PyUnresolvedReferences import pypi_org.data.licenses + # noinspection PyUnresolvedReferences import pypi_org.data.maintainers + # noinspection PyUnresolvedReferences import pypi_org.data.package + # noinspection PyUnresolvedReferences import pypi_org.data.releases + # noinspection PyUnresolvedReferences import pypi_org.data.users diff --git a/app/ch15_deploy/starter/pypi_org/data/db_session.py b/app/ch15_deploy/starter/pypi_org/data/db_session.py index 39b135cc..86eb3fb2 100644 --- a/app/ch15_deploy/starter/pypi_org/data/db_session.py +++ b/app/ch15_deploy/starter/pypi_org/data/db_session.py @@ -14,15 +14,15 @@ def global_init(db_file: str): return if not db_file or not db_file.strip(): - raise Exception("You must specify a db file.") + raise Exception('You must specify a db file.') conn_str = 'sqlite:///' + db_file.strip() - print("Connecting to DB with {}".format(conn_str)) + print('Connecting to DB with {}'.format(conn_str)) # Adding check_same_thread = False after the recording. This can be an issue about # creating / owner thread when cleaning up sessions, etc. This is a sqlite restriction # that we probably don't care about in this example. - engine = sa.create_engine(conn_str, echo=False, connect_args={"check_same_thread": False}) + engine = sa.create_engine(conn_str, echo=False, connect_args={'check_same_thread': False}) __factory = orm.sessionmaker(bind=engine) # noinspection PyUnresolvedReferences diff --git a/app/ch15_deploy/starter/pypi_org/data/downloads.py b/app/ch15_deploy/starter/pypi_org/data/downloads.py index 66068f02..dd8afd65 100644 --- a/app/ch15_deploy/starter/pypi_org/data/downloads.py +++ b/app/ch15_deploy/starter/pypi_org/data/downloads.py @@ -7,8 +7,7 @@ class Download(SqlAlchemyBase): __tablename__ = 'downloads' id: int = sqlalchemy.Column(sqlalchemy.BigInteger, primary_key=True, autoincrement=True) - created_date: datetime.datetime = sqlalchemy.Column( - sqlalchemy.DateTime, default=datetime.datetime.now, index=True) + created_date: datetime.datetime = sqlalchemy.Column(sqlalchemy.DateTime, default=datetime.datetime.now, index=True) package_id: str = sqlalchemy.Column(sqlalchemy.String, index=True) release_id: int = sqlalchemy.Column(sqlalchemy.BigInteger, index=True) diff --git a/app/ch15_deploy/starter/pypi_org/data/languages.py b/app/ch15_deploy/starter/pypi_org/data/languages.py index 964b8444..3a73dde0 100644 --- a/app/ch15_deploy/starter/pypi_org/data/languages.py +++ b/app/ch15_deploy/starter/pypi_org/data/languages.py @@ -7,6 +7,5 @@ class ProgrammingLanguage(SqlAlchemyBase): __tablename__ = 'languages' id: str = sqlalchemy.Column(sqlalchemy.String, primary_key=True) - created_date: datetime.datetime = sqlalchemy.Column( - sqlalchemy.DateTime, default=datetime.datetime.now, index=True) + created_date: datetime.datetime = sqlalchemy.Column(sqlalchemy.DateTime, default=datetime.datetime.now, index=True) description: str = sqlalchemy.Column(sqlalchemy.String) diff --git a/app/ch15_deploy/starter/pypi_org/data/package.py b/app/ch15_deploy/starter/pypi_org/data/package.py index c3420d1b..16e6d156 100644 --- a/app/ch15_deploy/starter/pypi_org/data/package.py +++ b/app/ch15_deploy/starter/pypi_org/data/package.py @@ -26,11 +26,15 @@ class Package(SqlAlchemyBase): license: str = sa.Column(sa.String, index=True) # releases relationship - releases: List[Release] = orm.relation("Release", order_by=[ - Release.major_ver.desc(), - Release.minor_ver.desc(), - Release.build_ver.desc(), - ], back_populates='package') + releases: List[Release] = orm.relation( + 'Release', + order_by=[ + Release.major_ver.desc(), + Release.minor_ver.desc(), + Release.build_ver.desc(), + ], + back_populates='package', + ) def __repr__(self): return ''.format(self.id) diff --git a/app/ch15_deploy/starter/pypi_org/data/releases.py b/app/ch15_deploy/starter/pypi_org/data/releases.py index 7650e438..8596f65c 100644 --- a/app/ch15_deploy/starter/pypi_org/data/releases.py +++ b/app/ch15_deploy/starter/pypi_org/data/releases.py @@ -13,15 +13,13 @@ class Release(SqlAlchemyBase): minor_ver: int = sqlalchemy.Column(sqlalchemy.BigInteger, index=True) build_ver: int = sqlalchemy.Column(sqlalchemy.BigInteger, index=True) - created_date: datetime.datetime = sqlalchemy.Column(sqlalchemy.DateTime, - default=datetime.datetime.now, - index=True) + created_date: datetime.datetime = sqlalchemy.Column(sqlalchemy.DateTime, default=datetime.datetime.now, index=True) comment: str = sqlalchemy.Column(sqlalchemy.String) url: str = sqlalchemy.Column(sqlalchemy.String) size: int = sqlalchemy.Column(sqlalchemy.BigInteger) # Package relationship - package_id: str = sqlalchemy.Column(sqlalchemy.String, sqlalchemy.ForeignKey("packages.id")) + package_id: str = sqlalchemy.Column(sqlalchemy.String, sqlalchemy.ForeignKey('packages.id')) package = orm.relation('Package') @property diff --git a/app/ch15_deploy/starter/pypi_org/infrastructure/cookie_auth.py b/app/ch15_deploy/starter/pypi_org/infrastructure/cookie_auth.py index 44864438..c215c0af 100644 --- a/app/ch15_deploy/starter/pypi_org/infrastructure/cookie_auth.py +++ b/app/ch15_deploy/starter/pypi_org/infrastructure/cookie_auth.py @@ -11,7 +11,7 @@ def set_auth(response: Response, user_id: int): hash_val = __hash_text(str(user_id)) - val = "{}:{}".format(user_id, hash_val) + val = '{}:{}'.format(user_id, hash_val) response.set_cookie(auth_cookie_name, val, secure=False, httponly=True, samesite='Lax') @@ -33,7 +33,7 @@ def get_user_id_via_auth_cookie(request: Request) -> Optional[int]: hash_val = parts[1] hash_val_check = __hash_text(user_id) if hash_val != hash_val_check: - print("Warning: Hash mismatch, invalid cookie value") + print('Warning: Hash mismatch, invalid cookie value') return None return try_int(user_id) diff --git a/app/ch15_deploy/starter/pypi_org/infrastructure/request_dict.py b/app/ch15_deploy/starter/pypi_org/infrastructure/request_dict.py index d7ab10de..d44ae574 100644 --- a/app/ch15_deploy/starter/pypi_org/infrastructure/request_dict.py +++ b/app/ch15_deploy/starter/pypi_org/infrastructure/request_dict.py @@ -29,7 +29,7 @@ def create(default_val=None, **route_args) -> RequestDictionary: **args, # The key/value pairs in the URL query string **request.headers, # Header values **form, # The key/value pairs in the body, from a HTML post form - **route_args # And additional arguments the method access, if they want them merged. + **route_args, # And additional arguments the method access, if they want them merged. } return RequestDictionary(data, default_val=default_val) diff --git a/app/ch15_deploy/starter/pypi_org/infrastructure/view_modifiers.py b/app/ch15_deploy/starter/pypi_org/infrastructure/view_modifiers.py index 0978163e..d944c142 100644 --- a/app/ch15_deploy/starter/pypi_org/infrastructure/view_modifiers.py +++ b/app/ch15_deploy/starter/pypi_org/infrastructure/view_modifiers.py @@ -26,7 +26,8 @@ def view_method(*args, **kwargs): if template_file and not isinstance(response_val, dict): raise Exception( - "Invalid return type {}, we expected a dict as the return value.".format(type(response_val))) + 'Invalid return type {}, we expected a dict as the return value.'.format(type(response_val)) + ) if template_file: response_val = flask.render_template(template_file, **response_val) @@ -42,6 +43,7 @@ def view_method(*args, **kwargs): return response_inner + # # def template(template_file: str = None): # def template_inner(f): diff --git a/app/ch15_deploy/starter/pypi_org/services/package_service.py b/app/ch15_deploy/starter/pypi_org/services/package_service.py index b03408d2..9a153773 100644 --- a/app/ch15_deploy/starter/pypi_org/services/package_service.py +++ b/app/ch15_deploy/starter/pypi_org/services/package_service.py @@ -10,12 +10,13 @@ def get_latest_releases(limit=10) -> List[Release]: session = db_session.create_session() try: - - releases = session.query(Release). \ - options(sqlalchemy.orm.joinedload(Release.package)). \ - order_by(Release.created_date.desc()). \ - limit(limit). \ - all() + releases = ( + session.query(Release) + .options(sqlalchemy.orm.joinedload(Release.package)) + .order_by(Release.created_date.desc()) + .limit(limit) + .all() + ) finally: session.close() @@ -47,11 +48,12 @@ def get_package_by_id(package_id: str) -> Optional[Package]: session = db_session.create_session() try: - - package = session.query(Package) \ - .options(sqlalchemy.orm.joinedload(Package.releases)) \ - .filter(Package.id == package_id) \ + package = ( + session.query(Package) + .options(sqlalchemy.orm.joinedload(Package.releases)) + .filter(Package.id == package_id) .first() + ) finally: session.close() diff --git a/app/ch15_deploy/starter/pypi_org/viewmodels/cms/page_viewmodel.py b/app/ch15_deploy/starter/pypi_org/viewmodels/cms/page_viewmodel.py index b7bb3249..ec033c3f 100644 --- a/app/ch15_deploy/starter/pypi_org/viewmodels/cms/page_viewmodel.py +++ b/app/ch15_deploy/starter/pypi_org/viewmodels/cms/page_viewmodel.py @@ -7,4 +7,3 @@ def __init__(self, full_url: str): super().__init__() self.page = cms_service.get_page(full_url) - diff --git a/app/ch15_deploy/starter/pypi_org/viewmodels/packages/pagedetails_viewmodel.py b/app/ch15_deploy/starter/pypi_org/viewmodels/packages/pagedetails_viewmodel.py index 63c4cf68..09f47c6f 100644 --- a/app/ch15_deploy/starter/pypi_org/viewmodels/packages/pagedetails_viewmodel.py +++ b/app/ch15_deploy/starter/pypi_org/viewmodels/packages/pagedetails_viewmodel.py @@ -11,7 +11,7 @@ def __init__(self, package_name: str): self.package_name = package_name.strip().lower() self.package = package_service.get_package_by_id(self.package_name) - self.latest_version = "0.0.0" + self.latest_version = '0.0.0' self.latest_release = None self.is_latest = True diff --git a/app/ch15_deploy/starter/pypi_org/viewmodels/seo/sitemap_viewmodel.py b/app/ch15_deploy/starter/pypi_org/viewmodels/seo/sitemap_viewmodel.py index 912c4df0..71df2f99 100644 --- a/app/ch15_deploy/starter/pypi_org/viewmodels/seo/sitemap_viewmodel.py +++ b/app/ch15_deploy/starter/pypi_org/viewmodels/seo/sitemap_viewmodel.py @@ -8,5 +8,5 @@ class SiteMapViewModel(ViewModelBase): def __init__(self, limit: int): super().__init__() self.packages = package_service.all_packages(limit) - self.last_updated_text = "2019-07-15" - self.site = "{}://{}".format(flask.request.scheme, flask.request.host) + self.last_updated_text = '2019-07-15' + self.site = '{}://{}'.format(flask.request.scheme, flask.request.host) diff --git a/app/ch15_deploy/starter/pypi_org/views/account_views.py b/app/ch15_deploy/starter/pypi_org/views/account_views.py index 3854b4cf..652f43b3 100644 --- a/app/ch15_deploy/starter/pypi_org/views/account_views.py +++ b/app/ch15_deploy/starter/pypi_org/views/account_views.py @@ -25,6 +25,7 @@ def index(): # ################### REGISTER ################################# + @blueprint.route('/account/register', methods=['GET']) @response(template_file='account/register.html') def register_get(): @@ -54,6 +55,7 @@ def register_post(): # ################### LOGIN ################################# + @blueprint.route('/account/login', methods=['GET']) @response(template_file='account/login.html') def login_get(): @@ -77,7 +79,7 @@ def login_post(): user = user_service.login_user(vm.email, vm.password) if not user: - vm.error = "The account does not exist or the password is wrong." + vm.error = 'The account does not exist or the password is wrong.' return vm.to_dict() resp = flask.redirect('/account') @@ -88,6 +90,7 @@ def login_post(): # ################### LOGOUT ################################# + @blueprint.route('/account/logout') def logout(): resp = flask.redirect('/') diff --git a/app/ch15_deploy/starter/pypi_org/views/package_views.py b/app/ch15_deploy/starter/pypi_org/views/package_views.py index 1a74549f..2f862740 100644 --- a/app/ch15_deploy/starter/pypi_org/views/package_views.py +++ b/app/ch15_deploy/starter/pypi_org/views/package_views.py @@ -19,4 +19,4 @@ def package_details(package_name: str): @blueprint.route('/') def popular(rank: int): print(type(rank), rank) - return "The details for the {}th most popular package".format(rank) + return 'The details for the {}th most popular package'.format(rank) diff --git a/app/ch15_deploy/starter/pypi_org/views/seo_view.py b/app/ch15_deploy/starter/pypi_org/views/seo_view.py index 93c88de5..f86b6bff 100644 --- a/app/ch15_deploy/starter/pypi_org/views/seo_view.py +++ b/app/ch15_deploy/starter/pypi_org/views/seo_view.py @@ -18,6 +18,7 @@ def sitemap(): # ################### Robots ################################# + @blueprint.route('/robots.txt') @response(mimetype='text/plain', template_file='seo/robots.txt') def robots(): diff --git a/app/ch15_deploy/starter/tests/_all_tests.py b/app/ch15_deploy/starter/tests/_all_tests.py index daa69ea4..e5c9b9ea 100644 --- a/app/ch15_deploy/starter/tests/_all_tests.py +++ b/app/ch15_deploy/starter/tests/_all_tests.py @@ -1,17 +1,18 @@ import sys import os -container_folder = os.path.abspath(os.path.join( - os.path.dirname(__file__), '..' -)) +container_folder = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) sys.path.insert(0, container_folder) # noinspection PyUnresolvedReferences from account_tests import * + # noinspection PyUnresolvedReferences from package_tests import * + # noinspection PyUnresolvedReferences from sitemap_tests import * + # noinspection PyUnresolvedReferences from home_tests import * diff --git a/app/ch15_deploy/starter/tests/account_tests.py b/app/ch15_deploy/starter/tests/account_tests.py index 4f5aa156..e31e8c28 100644 --- a/app/ch15_deploy/starter/tests/account_tests.py +++ b/app/ch15_deploy/starter/tests/account_tests.py @@ -7,7 +7,7 @@ def test_example(): - print("Test example...") + print('Test example...') assert 1 + 2 == 3 @@ -15,11 +15,7 @@ def test_vm_register_validation_when_valid(): # 3 A's of test: Arrange, Act, then Assert # Arrange - form_data = { - 'name': 'Michael', - 'email': 'michael@talkpython.fm', - 'password': 'a' * 6 - } + form_data = {'name': 'Michael', 'email': 'michael@talkpython.fm', 'password': 'a' * 6} with flask_app.test_request_context(path='/account/register', data=form_data): vm = RegisterViewModel() @@ -37,11 +33,7 @@ def test_vm_register_validation_for_existing_user(): # 3 A's of test: Arrange, Act, then Assert # Arrange - form_data = { - 'name': 'Michael', - 'email': 'michael@talkpython.fm', - 'password': 'a' * 6 - } + form_data = {'name': 'Michael', 'email': 'michael@talkpython.fm', 'password': 'a' * 6} with flask_app.test_request_context(path='/account/register', data=form_data): vm = RegisterViewModel() @@ -62,11 +54,8 @@ def test_v_register_view_new_user(): # Arrange from pypi_org.views.account_views import register_post - form_data = { - 'name': 'Michael', - 'email': 'michael@talkpython.fm', - 'password': 'a' * 6 - } + + form_data = {'name': 'Michael', 'email': 'michael@talkpython.fm', 'password': 'a' * 6} target = 'pypi_org.services.user_service.find_user_by_email' find_user = unittest.mock.patch(target, return_value=None) diff --git a/app/ch15_deploy/starter/tests/package_tests.py b/app/ch15_deploy/starter/tests/package_tests.py index efd04ef5..a7c221a5 100644 --- a/app/ch15_deploy/starter/tests/package_tests.py +++ b/app/ch15_deploy/starter/tests/package_tests.py @@ -12,15 +12,14 @@ def test_package_details_success(): test_package = Package() test_package.id = 'sqlalchemy' - test_package.description = "TDB" + test_package.description = 'TDB' test_package.releases = [ Release(created_date=datetime.datetime.now(), major_ver=1, minor_ver=2, build_ver=200), Release(created_date=datetime.datetime.now() - datetime.timedelta(days=10)), ] # Act - with unittest.mock.patch('pypi_org.services.package_service.get_package_by_id', - return_value=test_package): + with unittest.mock.patch('pypi_org.services.package_service.get_package_by_id', return_value=test_package): with flask_app.test_request_context(path='/project/' + test_package.id): resp: Response = package_details(test_package.id) @@ -33,8 +32,7 @@ def test_package_details_404(client): bad_package_url = 'sqlalchemy_missing' # Act - with unittest.mock.patch('pypi_org.services.package_service.get_package_by_id', - return_value=None): + with unittest.mock.patch('pypi_org.services.package_service.get_package_by_id', return_value=None): resp: Response = client.get(bad_package_url) assert resp.status_code == 404 diff --git a/app/ch15_deploy/starter/tests/sitemap_tests.py b/app/ch15_deploy/starter/tests/sitemap_tests.py index b1afe0fe..4494c30a 100644 --- a/app/ch15_deploy/starter/tests/sitemap_tests.py +++ b/app/ch15_deploy/starter/tests/sitemap_tests.py @@ -10,10 +10,7 @@ def test_int_site_mapped_urls(client): href.text.strip().replace('http://127.0.0.1:5000', '').replace('http://localhost', '') for href in list(x.findall('url/loc')) ] - urls = [ - u if u else '/' - for u in urls - ] + urls = [u if u else '/' for u in urls] print('Testing {} urls from sitemap...'.format(len(urls)), flush=True) has_tested_projects = False @@ -40,7 +37,7 @@ def get_sitemap_text(client): # # ... # - res: Response = client.get("/sitemap.xml") - text = res.data.decode("utf-8") + res: Response = client.get('/sitemap.xml') + text = res.data.decode('utf-8') text = text.replace('xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"', '') return text diff --git a/app/ch15_deploy/starter/tests/test_client.py b/app/ch15_deploy/starter/tests/test_client.py index ffbea486..4390409a 100644 --- a/app/ch15_deploy/starter/tests/test_client.py +++ b/app/ch15_deploy/starter/tests/test_client.py @@ -4,9 +4,7 @@ import sys import os -container_folder = os.path.abspath(os.path.join( - os.path.dirname(__file__), '..' -)) +container_folder = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) sys.path.insert(0, container_folder) import pypi_org.app diff --git a/app/ch16_mongodb/final/alembic/alembic_helpers.py b/app/ch16_mongodb/final/alembic/alembic_helpers.py index 561f7a70..6aea52d4 100644 --- a/app/ch16_mongodb/final/alembic/alembic_helpers.py +++ b/app/ch16_mongodb/final/alembic/alembic_helpers.py @@ -5,8 +5,7 @@ def table_has_column(table, column): config = op.get_context().config - engine = engine_from_config( - config.get_section(config.config_ini_section), prefix='sqlalchemy.') + engine = engine_from_config(config.get_section(config.config_ini_section), prefix='sqlalchemy.') insp = reflection.Inspector.from_engine(engine) has_column = False for col in insp.get_columns(table): diff --git a/app/ch16_mongodb/final/alembic/env.py b/app/ch16_mongodb/final/alembic/env.py index 27ec49fb..1fdc9cab 100644 --- a/app/ch16_mongodb/final/alembic/env.py +++ b/app/ch16_mongodb/final/alembic/env.py @@ -26,6 +26,7 @@ sys.path.insert(0, folder) from pypi_org.data.modelbase import SqlAlchemyBase + # noinspection PyUnresolvedReferences import pypi_org.data.__all_models @@ -49,10 +50,8 @@ def run_migrations_offline(): script output. """ - url = config.get_main_option("sqlalchemy.url") - context.configure( - url=url, target_metadata=target_metadata, literal_binds=True - ) + url = config.get_main_option('sqlalchemy.url') + context.configure(url=url, target_metadata=target_metadata, literal_binds=True) with context.begin_transaction(): context.run_migrations() @@ -67,14 +66,12 @@ def run_migrations_online(): """ connectable = engine_from_config( config.get_section(config.config_ini_section), - prefix="sqlalchemy.", + prefix='sqlalchemy.', poolclass=pool.NullPool, ) with connectable.connect() as connection: - context.configure( - connection=connection, target_metadata=target_metadata - ) + context.configure(connection=connection, target_metadata=target_metadata) with context.begin_transaction(): context.run_migrations() diff --git a/app/ch16_mongodb/final/alembic/versions/722c82f0097c_added_auditing_table.py b/app/ch16_mongodb/final/alembic/versions/722c82f0097c_added_auditing_table.py index 2c3e2a39..7c6e892f 100644 --- a/app/ch16_mongodb/final/alembic/versions/722c82f0097c_added_auditing_table.py +++ b/app/ch16_mongodb/final/alembic/versions/722c82f0097c_added_auditing_table.py @@ -18,11 +18,12 @@ def upgrade(): # ### commands auto generated by Alembic - please adjust! ### - op.create_table('auditing', - sa.Column('id', sa.String(), nullable=False), - sa.Column('created_date', sa.DateTime(), nullable=True), - sa.Column('description', sa.String(), nullable=True), - sa.PrimaryKeyConstraint('id') + op.create_table( + 'auditing', + sa.Column('id', sa.String(), nullable=False), + sa.Column('created_date', sa.DateTime(), nullable=True), + sa.Column('description', sa.String(), nullable=True), + sa.PrimaryKeyConstraint('id'), ) op.create_index(op.f('ix_auditing_created_date'), 'auditing', ['created_date'], unique=False) # ### end Alembic commands ### diff --git a/app/ch16_mongodb/final/pypi_org/app.py b/app/ch16_mongodb/final/pypi_org/app.py index 38ba85d7..2b98b408 100644 --- a/app/ch16_mongodb/final/pypi_org/app.py +++ b/app/ch16_mongodb/final/pypi_org/app.py @@ -19,14 +19,14 @@ def main(): def configure(): - print("Configuring Flask app:") + print('Configuring Flask app:') register_blueprints() - print("Registered blueprints") + print('Registered blueprints') setup_db() - print("DB setup completed.") - print("", flush=True) + print('DB setup completed.') + print('', flush=True) def setup_db(): diff --git a/app/ch16_mongodb/final/pypi_org/bin/basic_inserts.py b/app/ch16_mongodb/final/pypi_org/bin/basic_inserts.py index d622a6ae..6d04f551 100644 --- a/app/ch16_mongodb/final/pypi_org/bin/basic_inserts.py +++ b/app/ch16_mongodb/final/pypi_org/bin/basic_inserts.py @@ -2,8 +2,7 @@ import sys # Make it run more easily outside of PyCharm -sys.path.insert(0, os.path.abspath(os.path.join( - os.path.dirname(__file__), "..", ".."))) +sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..'))) import pypi_org.data.db_session as db_session from pypi_org.data.package import Package @@ -20,24 +19,24 @@ def insert_a_package(): p = Package() p.id = input('Package id / name: ').strip().lower() - p.summary = input("Package summary: ").strip() - p.author_name = input("Author: ").strip() - p.license = input("License: ").strip() + p.summary = input('Package summary: ').strip() + p.author_name = input('Author: ').strip() + p.license = input('License: ').strip() - print("Release 1:") + print('Release 1:') r = Release() - r.major_ver = int(input("Major version: ")) - r.minor_ver = int(input("Minor version: ")) - r.build_ver = int(input("Build version: ")) - r.size = int(input("Size in bytes: ")) + r.major_ver = int(input('Major version: ')) + r.minor_ver = int(input('Minor version: ')) + r.build_ver = int(input('Build version: ')) + r.size = int(input('Size in bytes: ')) p.releases.append(r) - print("Release 2:") + print('Release 2:') r = Release() - r.major_ver = int(input("Major version: ")) - r.minor_ver = int(input("Minor version: ")) - r.build_ver = int(input("Build version: ")) - r.size = int(input("Size in bytes: ")) + r.major_ver = int(input('Major version: ')) + r.minor_ver = int(input('Minor version: ')) + r.build_ver = int(input('Build version: ')) + r.size = int(input('Size in bytes: ')) p.releases.append(r) session = db_session.create_session() diff --git a/app/ch16_mongodb/final/pypi_org/bin/load_data.py b/app/ch16_mongodb/final/pypi_org/bin/load_data.py index 8f43c13c..228c1b6b 100644 --- a/app/ch16_mongodb/final/pypi_org/bin/load_data.py +++ b/app/ch16_mongodb/final/pypi_org/bin/load_data.py @@ -7,8 +7,7 @@ import progressbar from dateutil.parser import parse -sys.path.insert(0, os.path.abspath(os.path.join( - os.path.dirname(__file__), "..", ".."))) +sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..'))) import pypi_org.data.db_session as db_session from pypi_org.data.languages import ProgrammingLanguage @@ -39,7 +38,7 @@ def main(): def do_import_languages(file_data: List[dict]): imported = set() - print("Importing languages ... ", flush=True) + print('Importing languages ... ', flush=True) with progressbar.ProgressBar(max_value=len(file_data)) as bar: for idx, p in enumerate(file_data): info = p.get('info') @@ -74,7 +73,7 @@ def do_import_languages(file_data: List[dict]): def do_import_licenses(file_data: List[dict]): imported = set() - print("Importing licenses ... ", flush=True) + print('Importing licenses ... ', flush=True) with progressbar.ProgressBar(max_value=len(file_data)) as bar: for idx, p in enumerate(file_data): info = p.get('info') @@ -100,17 +99,17 @@ def do_import_licenses(file_data: List[dict]): def do_summary(): session = db_session.create_session() - print("Final numbers:") - print("Users: {:,}".format(session.query(User).count())) - print("Packages: {:,}".format(session.query(Package).count())) - print("Releases: {:,}".format(session.query(Release).count())) - print("Maintainers: {:,}".format(session.query(Maintainer).count())) - print("Languages: {:,}".format(session.query(ProgrammingLanguage).count())) - print("Licenses: {:,}".format(session.query(License).count())) + print('Final numbers:') + print('Users: {:,}'.format(session.query(User).count())) + print('Packages: {:,}'.format(session.query(Package).count())) + print('Releases: {:,}'.format(session.query(Release).count())) + print('Maintainers: {:,}'.format(session.query(Maintainer).count())) + print('Languages: {:,}'.format(session.query(ProgrammingLanguage).count())) + print('Licenses: {:,}'.format(session.query(License).count())) def do_user_import(user_lookup: Dict[str, str]) -> Dict[str, User]: - print("Importing users ... ", flush=True) + print('Importing users ... ', flush=True) with progressbar.ProgressBar(max_value=len(user_lookup)) as bar: for idx, (email, name) in enumerate(user_lookup.items()): session = db_session.create_session() @@ -134,29 +133,29 @@ def do_user_import(user_lookup: Dict[str, str]) -> Dict[str, User]: def do_import_packages(file_data: List[dict], user_lookup: Dict[str, User]): errored_packages = [] - print("Importing packages and releases ... ", flush=True) + print('Importing packages and releases ... ', flush=True) with progressbar.ProgressBar(max_value=len(file_data)) as bar: for idx, p in enumerate(file_data): try: load_package(p, user_lookup) bar.update(idx) except Exception as x: - errored_packages.append((p, " *** Errored out for package {}, {}".format(p.get('package_name'), x))) + errored_packages.append((p, ' *** Errored out for package {}, {}'.format(p.get('package_name'), x))) raise sys.stderr.flush() sys.stdout.flush() print() - print("Completed packages with {} errors.".format(len(errored_packages))) - for (p, txt) in errored_packages: + print('Completed packages with {} errors.'.format(len(errored_packages))) + for p, txt in errored_packages: print(txt) def do_load_files() -> List[dict]: data_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../../../data/pypi-top-100')) - print("Loading files from {}".format(data_path)) + print('Loading files from {}'.format(data_path)) files = get_file_names(data_path) - print("Found {:,} files, loading ...".format(len(files)), flush=True) - time.sleep(.1) + print('Found {:,} files, loading ...'.format(len(files)), flush=True) + time.sleep(0.1) file_data = [] with progressbar.ProgressBar(max_value=len(files)) as bar: @@ -171,7 +170,7 @@ def do_load_files() -> List[dict]: def find_users(data: List[dict]) -> dict: - print("Discovering users...", flush=True) + print('Discovering users...', flush=True) found_users = {} with progressbar.ProgressBar(max_value=len(data)) as bar: @@ -184,7 +183,7 @@ def find_users(data: List[dict]) -> dict: sys.stderr.flush() sys.stdout.flush() print() - print("Discovered {:,} users".format(len(found_users))) + print('Discovered {:,} users'.format(len(found_users))) print() return found_users @@ -215,7 +214,7 @@ def load_file_data(filename: str) -> dict: with open(filename, 'r', encoding='utf-8') as fin: data = json.load(fin) except Exception as x: - print("ERROR in file: {}, details: {}".format(filename, x), flush=True) + print('ERROR in file: {}, details: {}'.format(filename, x), flush=True) raise return data @@ -233,7 +232,7 @@ def load_package(data: dict, user_lookup: Dict[str, User]): p.author = info.get('author') p.author_email = info.get('author_email') - releases = build_releases(p.id, data.get("releases", {})) + releases = build_releases(p.id, data.get('releases', {})) if releases: p.created_date = releases[0].created_date @@ -283,18 +282,13 @@ def detect_license(license_text: str) -> Optional[str]: license_text = license_text.strip() if len(license_text) > 100 or '\n' in license_text: - return "CUSTOM" + return 'CUSTOM' - license_text = license_text \ - .replace('Software License', '') \ - .replace('License', '') + license_text = license_text.replace('Software License', '').replace('License', '') if '::' in license_text: # E.g. 'License :: OSI Approved :: Apache Software License' - return license_text \ - .split(':')[-1] \ - .replace(' ', ' ') \ - .strip() + return license_text.split(':')[-1].replace(' ', ' ').strip() return license_text.strip() @@ -357,9 +351,7 @@ def get_file_names(data_path: str) -> List[str]: files = [] for f in os.listdir(data_path): if f.endswith('.json'): - files.append( - os.path.abspath(os.path.join(data_path, f)) - ) + files.append(os.path.abspath(os.path.join(data_path, f))) files.sort() return files diff --git a/app/ch16_mongodb/final/pypi_org/bin/migrate_to_mongodb.py b/app/ch16_mongodb/final/pypi_org/bin/migrate_to_mongodb.py index f56a1e32..51a6c105 100644 --- a/app/ch16_mongodb/final/pypi_org/bin/migrate_to_mongodb.py +++ b/app/ch16_mongodb/final/pypi_org/bin/migrate_to_mongodb.py @@ -84,13 +84,7 @@ def migrate_releases(): def init_dbs(): - db_file = os.path.abspath( - os.path.join( - os.path.dirname(__file__), - '..', - 'db', - 'pypi.sqlite' - )) + db_file = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'db', 'pypi.sqlite')) db_session.global_init(db_file) mongo_setup.global_init() diff --git a/app/ch16_mongodb/final/pypi_org/data/__all_models.py b/app/ch16_mongodb/final/pypi_org/data/__all_models.py index f399ef54..ca4804ac 100644 --- a/app/ch16_mongodb/final/pypi_org/data/__all_models.py +++ b/app/ch16_mongodb/final/pypi_org/data/__all_models.py @@ -5,17 +5,24 @@ # noinspection PyUnresolvedReferences import pypi_org.data.audit + # noinspection PyUnresolvedReferences import pypi_org.data.downloads + # noinspection PyUnresolvedReferences import pypi_org.data.languages + # noinspection PyUnresolvedReferences import pypi_org.data.licenses + # noinspection PyUnresolvedReferences import pypi_org.data.maintainers + # noinspection PyUnresolvedReferences import pypi_org.data.package + # noinspection PyUnresolvedReferences import pypi_org.data.releases + # noinspection PyUnresolvedReferences import pypi_org.data.users diff --git a/app/ch16_mongodb/final/pypi_org/data/db_session.py b/app/ch16_mongodb/final/pypi_org/data/db_session.py index acfc485d..a1c4df68 100644 --- a/app/ch16_mongodb/final/pypi_org/data/db_session.py +++ b/app/ch16_mongodb/final/pypi_org/data/db_session.py @@ -14,10 +14,10 @@ def global_init(db_file: str): return if not db_file or not db_file.strip(): - raise Exception("You must specify a db file.") + raise Exception('You must specify a db file.') conn_str = 'sqlite:///' + db_file.strip() - print("Connecting to DB with {}".format(conn_str)) + print('Connecting to DB with {}'.format(conn_str)) engine = sa.create_engine(conn_str, echo=False) __factory = orm.sessionmaker(bind=engine) diff --git a/app/ch16_mongodb/final/pypi_org/data/downloads.py b/app/ch16_mongodb/final/pypi_org/data/downloads.py index 66068f02..dd8afd65 100644 --- a/app/ch16_mongodb/final/pypi_org/data/downloads.py +++ b/app/ch16_mongodb/final/pypi_org/data/downloads.py @@ -7,8 +7,7 @@ class Download(SqlAlchemyBase): __tablename__ = 'downloads' id: int = sqlalchemy.Column(sqlalchemy.BigInteger, primary_key=True, autoincrement=True) - created_date: datetime.datetime = sqlalchemy.Column( - sqlalchemy.DateTime, default=datetime.datetime.now, index=True) + created_date: datetime.datetime = sqlalchemy.Column(sqlalchemy.DateTime, default=datetime.datetime.now, index=True) package_id: str = sqlalchemy.Column(sqlalchemy.String, index=True) release_id: int = sqlalchemy.Column(sqlalchemy.BigInteger, index=True) diff --git a/app/ch16_mongodb/final/pypi_org/data/languages.py b/app/ch16_mongodb/final/pypi_org/data/languages.py index 964b8444..3a73dde0 100644 --- a/app/ch16_mongodb/final/pypi_org/data/languages.py +++ b/app/ch16_mongodb/final/pypi_org/data/languages.py @@ -7,6 +7,5 @@ class ProgrammingLanguage(SqlAlchemyBase): __tablename__ = 'languages' id: str = sqlalchemy.Column(sqlalchemy.String, primary_key=True) - created_date: datetime.datetime = sqlalchemy.Column( - sqlalchemy.DateTime, default=datetime.datetime.now, index=True) + created_date: datetime.datetime = sqlalchemy.Column(sqlalchemy.DateTime, default=datetime.datetime.now, index=True) description: str = sqlalchemy.Column(sqlalchemy.String) diff --git a/app/ch16_mongodb/final/pypi_org/data/package.py b/app/ch16_mongodb/final/pypi_org/data/package.py index c3420d1b..16e6d156 100644 --- a/app/ch16_mongodb/final/pypi_org/data/package.py +++ b/app/ch16_mongodb/final/pypi_org/data/package.py @@ -26,11 +26,15 @@ class Package(SqlAlchemyBase): license: str = sa.Column(sa.String, index=True) # releases relationship - releases: List[Release] = orm.relation("Release", order_by=[ - Release.major_ver.desc(), - Release.minor_ver.desc(), - Release.build_ver.desc(), - ], back_populates='package') + releases: List[Release] = orm.relation( + 'Release', + order_by=[ + Release.major_ver.desc(), + Release.minor_ver.desc(), + Release.build_ver.desc(), + ], + back_populates='package', + ) def __repr__(self): return ''.format(self.id) diff --git a/app/ch16_mongodb/final/pypi_org/data/releases.py b/app/ch16_mongodb/final/pypi_org/data/releases.py index 7650e438..8596f65c 100644 --- a/app/ch16_mongodb/final/pypi_org/data/releases.py +++ b/app/ch16_mongodb/final/pypi_org/data/releases.py @@ -13,15 +13,13 @@ class Release(SqlAlchemyBase): minor_ver: int = sqlalchemy.Column(sqlalchemy.BigInteger, index=True) build_ver: int = sqlalchemy.Column(sqlalchemy.BigInteger, index=True) - created_date: datetime.datetime = sqlalchemy.Column(sqlalchemy.DateTime, - default=datetime.datetime.now, - index=True) + created_date: datetime.datetime = sqlalchemy.Column(sqlalchemy.DateTime, default=datetime.datetime.now, index=True) comment: str = sqlalchemy.Column(sqlalchemy.String) url: str = sqlalchemy.Column(sqlalchemy.String) size: int = sqlalchemy.Column(sqlalchemy.BigInteger) # Package relationship - package_id: str = sqlalchemy.Column(sqlalchemy.String, sqlalchemy.ForeignKey("packages.id")) + package_id: str = sqlalchemy.Column(sqlalchemy.String, sqlalchemy.ForeignKey('packages.id')) package = orm.relation('Package') @property diff --git a/app/ch16_mongodb/final/pypi_org/infrastructure/cookie_auth.py b/app/ch16_mongodb/final/pypi_org/infrastructure/cookie_auth.py index 661168c0..aa2f4c2b 100644 --- a/app/ch16_mongodb/final/pypi_org/infrastructure/cookie_auth.py +++ b/app/ch16_mongodb/final/pypi_org/infrastructure/cookie_auth.py @@ -12,7 +12,7 @@ def set_auth(response: Response, user_id: bson.ObjectId): hash_val = __hash_text(str(user_id)) - val = "{}:{}".format(user_id, hash_val) + val = '{}:{}'.format(user_id, hash_val) response.set_cookie(auth_cookie_name, val, secure=False, httponly=True, samesite='Lax') @@ -34,7 +34,7 @@ def get_user_id_via_auth_cookie(request: Request) -> Optional[bson.ObjectId]: hash_val = parts[1] hash_val_check = __hash_text(user_id) if hash_val != hash_val_check: - print("Warning: Hash mismatch, invalid cookie value") + print('Warning: Hash mismatch, invalid cookie value') return None return try_object_id(user_id) diff --git a/app/ch16_mongodb/final/pypi_org/infrastructure/request_dict.py b/app/ch16_mongodb/final/pypi_org/infrastructure/request_dict.py index d7ab10de..d44ae574 100644 --- a/app/ch16_mongodb/final/pypi_org/infrastructure/request_dict.py +++ b/app/ch16_mongodb/final/pypi_org/infrastructure/request_dict.py @@ -29,7 +29,7 @@ def create(default_val=None, **route_args) -> RequestDictionary: **args, # The key/value pairs in the URL query string **request.headers, # Header values **form, # The key/value pairs in the body, from a HTML post form - **route_args # And additional arguments the method access, if they want them merged. + **route_args, # And additional arguments the method access, if they want them merged. } return RequestDictionary(data, default_val=default_val) diff --git a/app/ch16_mongodb/final/pypi_org/infrastructure/view_modifiers.py b/app/ch16_mongodb/final/pypi_org/infrastructure/view_modifiers.py index 0978163e..d944c142 100644 --- a/app/ch16_mongodb/final/pypi_org/infrastructure/view_modifiers.py +++ b/app/ch16_mongodb/final/pypi_org/infrastructure/view_modifiers.py @@ -26,7 +26,8 @@ def view_method(*args, **kwargs): if template_file and not isinstance(response_val, dict): raise Exception( - "Invalid return type {}, we expected a dict as the return value.".format(type(response_val))) + 'Invalid return type {}, we expected a dict as the return value.'.format(type(response_val)) + ) if template_file: response_val = flask.render_template(template_file, **response_val) @@ -42,6 +43,7 @@ def view_method(*args, **kwargs): return response_inner + # # def template(template_file: str = None): # def template_inner(f): diff --git a/app/ch16_mongodb/final/pypi_org/nosql/downloads.py b/app/ch16_mongodb/final/pypi_org/nosql/downloads.py index 6be34547..3cdaa009 100644 --- a/app/ch16_mongodb/final/pypi_org/nosql/downloads.py +++ b/app/ch16_mongodb/final/pypi_org/nosql/downloads.py @@ -18,5 +18,5 @@ class Download(mongoengine.Document): 'created_date', 'package_id', 'release_id', - ] + ], } diff --git a/app/ch16_mongodb/final/pypi_org/nosql/languages.py b/app/ch16_mongodb/final/pypi_org/nosql/languages.py index 5251cb9f..b2042d52 100644 --- a/app/ch16_mongodb/final/pypi_org/nosql/languages.py +++ b/app/ch16_mongodb/final/pypi_org/nosql/languages.py @@ -3,7 +3,6 @@ class ProgrammingLanguage(mongoengine.Document): - id = mongoengine.StringField(primary_key=True) created_date = mongoengine.DateTimeField(default=datetime.datetime.now) description = mongoengine.StringField() @@ -13,5 +12,5 @@ class ProgrammingLanguage(mongoengine.Document): 'collection': 'languages', 'indexes': [ 'created_date', - ] + ], } diff --git a/app/ch16_mongodb/final/pypi_org/nosql/licenses.py b/app/ch16_mongodb/final/pypi_org/nosql/licenses.py index c7190069..daf5a004 100644 --- a/app/ch16_mongodb/final/pypi_org/nosql/licenses.py +++ b/app/ch16_mongodb/final/pypi_org/nosql/licenses.py @@ -12,5 +12,5 @@ class License(mongoengine.Document): 'collection': 'licenses', 'indexes': [ 'created_date', - ] + ], } diff --git a/app/ch16_mongodb/final/pypi_org/nosql/mongo_setup.py b/app/ch16_mongodb/final/pypi_org/nosql/mongo_setup.py index 56694d6a..4fb8a8ae 100644 --- a/app/ch16_mongodb/final/pypi_org/nosql/mongo_setup.py +++ b/app/ch16_mongodb/final/pypi_org/nosql/mongo_setup.py @@ -3,8 +3,7 @@ import mongoengine -def global_init(user=None, password=None, port=27017, - server='localhost', use_ssl=True, db_name='pypi'): +def global_init(user=None, password=None, port=27017, server='localhost', use_ssl=True, db_name='pypi'): if user or password: # noinspection PyUnresolvedReferences data = dict( @@ -15,10 +14,11 @@ def global_init(user=None, password=None, port=27017, authentication_source='admin', authentication_mechanism='SCRAM-SHA-1', ssl=use_ssl, - ssl_cert_reqs=ssl.CERT_NONE) + ssl_cert_reqs=ssl.CERT_NONE, + ) mongoengine.register_connection(alias='core', name=db_name, **data) data['password'] = '*************' - print(" --> Registering prod connection: {}".format(data)) + print(' --> Registering prod connection: {}'.format(data)) else: - print(" --> Registering dev connection") + print(' --> Registering dev connection') mongoengine.register_connection(alias='core', name=db_name) diff --git a/app/ch16_mongodb/final/pypi_org/nosql/packages.py b/app/ch16_mongodb/final/pypi_org/nosql/packages.py index 3f426a03..47f3354b 100644 --- a/app/ch16_mongodb/final/pypi_org/nosql/packages.py +++ b/app/ch16_mongodb/final/pypi_org/nosql/packages.py @@ -26,7 +26,7 @@ class Package(mongoengine.Document): 'created_date', 'author_email', 'license', - ] + ], } def __repr__(self): diff --git a/app/ch16_mongodb/final/pypi_org/nosql/releases.py b/app/ch16_mongodb/final/pypi_org/nosql/releases.py index 4a0623e3..9ad11a67 100644 --- a/app/ch16_mongodb/final/pypi_org/nosql/releases.py +++ b/app/ch16_mongodb/final/pypi_org/nosql/releases.py @@ -26,7 +26,7 @@ class Release(mongoengine.Document): 'build_ver', {'fields': ['major_ver', 'minor_ver', 'build_ver']}, {'fields': ['-major_ver', '-minor_ver', '-build_ver']}, - ] + ], } @property diff --git a/app/ch16_mongodb/final/pypi_org/nosql/users.py b/app/ch16_mongodb/final/pypi_org/nosql/users.py index 96ce7d65..6757e067 100644 --- a/app/ch16_mongodb/final/pypi_org/nosql/users.py +++ b/app/ch16_mongodb/final/pypi_org/nosql/users.py @@ -15,5 +15,5 @@ class User(mongoengine.Document): 'email', 'hashed_password', 'created_date', - ] + ], } diff --git a/app/ch16_mongodb/final/pypi_org/services/package_service.py b/app/ch16_mongodb/final/pypi_org/services/package_service.py index 1d6ea91e..8de9ed80 100644 --- a/app/ch16_mongodb/final/pypi_org/services/package_service.py +++ b/app/ch16_mongodb/final/pypi_org/services/package_service.py @@ -5,10 +5,7 @@ def get_latest_releases(limit=10) -> List[Release]: - releases = Release.objects(). \ - order_by("-created_date"). \ - limit(limit). \ - all() + releases = Release.objects().order_by('-created_date').limit(limit).all() return releases @@ -26,9 +23,7 @@ def get_package_by_id(package_id: str) -> Optional[Package]: package_id = package_id.strip().lower() - package = Package.objects() \ - .filter(id=package_id) \ - .first() + package = Package.objects().filter(id=package_id).first() return package diff --git a/app/ch16_mongodb/final/pypi_org/viewmodels/packages/pagedetails_viewmodel.py b/app/ch16_mongodb/final/pypi_org/viewmodels/packages/pagedetails_viewmodel.py index d25f3c70..3a2f6935 100644 --- a/app/ch16_mongodb/final/pypi_org/viewmodels/packages/pagedetails_viewmodel.py +++ b/app/ch16_mongodb/final/pypi_org/viewmodels/packages/pagedetails_viewmodel.py @@ -11,13 +11,12 @@ def __init__(self, package_name: str): self.package_name = package_name.strip().lower() self.package = package_service.get_package_by_id(self.package_name) - self.latest_version = "0.0.0" + self.latest_version = '0.0.0' self.latest_release = None self.is_latest = True if self.package: - self.latest_release = package_service.get_latest_release_for_package( - self.package.id) + self.latest_release = package_service.get_latest_release_for_package(self.package.id) if self.latest_release: self.latest_version = self.latest_release.version_text diff --git a/app/ch16_mongodb/final/pypi_org/viewmodels/seo/sitemap_viewmodel.py b/app/ch16_mongodb/final/pypi_org/viewmodels/seo/sitemap_viewmodel.py index 912c4df0..71df2f99 100644 --- a/app/ch16_mongodb/final/pypi_org/viewmodels/seo/sitemap_viewmodel.py +++ b/app/ch16_mongodb/final/pypi_org/viewmodels/seo/sitemap_viewmodel.py @@ -8,5 +8,5 @@ class SiteMapViewModel(ViewModelBase): def __init__(self, limit: int): super().__init__() self.packages = package_service.all_packages(limit) - self.last_updated_text = "2019-07-15" - self.site = "{}://{}".format(flask.request.scheme, flask.request.host) + self.last_updated_text = '2019-07-15' + self.site = '{}://{}'.format(flask.request.scheme, flask.request.host) diff --git a/app/ch16_mongodb/final/pypi_org/views/account_views.py b/app/ch16_mongodb/final/pypi_org/views/account_views.py index 3854b4cf..652f43b3 100644 --- a/app/ch16_mongodb/final/pypi_org/views/account_views.py +++ b/app/ch16_mongodb/final/pypi_org/views/account_views.py @@ -25,6 +25,7 @@ def index(): # ################### REGISTER ################################# + @blueprint.route('/account/register', methods=['GET']) @response(template_file='account/register.html') def register_get(): @@ -54,6 +55,7 @@ def register_post(): # ################### LOGIN ################################# + @blueprint.route('/account/login', methods=['GET']) @response(template_file='account/login.html') def login_get(): @@ -77,7 +79,7 @@ def login_post(): user = user_service.login_user(vm.email, vm.password) if not user: - vm.error = "The account does not exist or the password is wrong." + vm.error = 'The account does not exist or the password is wrong.' return vm.to_dict() resp = flask.redirect('/account') @@ -88,6 +90,7 @@ def login_post(): # ################### LOGOUT ################################# + @blueprint.route('/account/logout') def logout(): resp = flask.redirect('/') diff --git a/app/ch16_mongodb/final/pypi_org/views/package_views.py b/app/ch16_mongodb/final/pypi_org/views/package_views.py index 1a74549f..2f862740 100644 --- a/app/ch16_mongodb/final/pypi_org/views/package_views.py +++ b/app/ch16_mongodb/final/pypi_org/views/package_views.py @@ -19,4 +19,4 @@ def package_details(package_name: str): @blueprint.route('/') def popular(rank: int): print(type(rank), rank) - return "The details for the {}th most popular package".format(rank) + return 'The details for the {}th most popular package'.format(rank) diff --git a/app/ch16_mongodb/final/pypi_org/views/seo_view.py b/app/ch16_mongodb/final/pypi_org/views/seo_view.py index 93c88de5..f86b6bff 100644 --- a/app/ch16_mongodb/final/pypi_org/views/seo_view.py +++ b/app/ch16_mongodb/final/pypi_org/views/seo_view.py @@ -18,6 +18,7 @@ def sitemap(): # ################### Robots ################################# + @blueprint.route('/robots.txt') @response(mimetype='text/plain', template_file='seo/robots.txt') def robots(): diff --git a/app/ch16_mongodb/final/tests/_all_tests.py b/app/ch16_mongodb/final/tests/_all_tests.py index daa69ea4..e5c9b9ea 100644 --- a/app/ch16_mongodb/final/tests/_all_tests.py +++ b/app/ch16_mongodb/final/tests/_all_tests.py @@ -1,17 +1,18 @@ import sys import os -container_folder = os.path.abspath(os.path.join( - os.path.dirname(__file__), '..' -)) +container_folder = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) sys.path.insert(0, container_folder) # noinspection PyUnresolvedReferences from account_tests import * + # noinspection PyUnresolvedReferences from package_tests import * + # noinspection PyUnresolvedReferences from sitemap_tests import * + # noinspection PyUnresolvedReferences from home_tests import * diff --git a/app/ch16_mongodb/final/tests/account_tests.py b/app/ch16_mongodb/final/tests/account_tests.py index 4f5aa156..e31e8c28 100644 --- a/app/ch16_mongodb/final/tests/account_tests.py +++ b/app/ch16_mongodb/final/tests/account_tests.py @@ -7,7 +7,7 @@ def test_example(): - print("Test example...") + print('Test example...') assert 1 + 2 == 3 @@ -15,11 +15,7 @@ def test_vm_register_validation_when_valid(): # 3 A's of test: Arrange, Act, then Assert # Arrange - form_data = { - 'name': 'Michael', - 'email': 'michael@talkpython.fm', - 'password': 'a' * 6 - } + form_data = {'name': 'Michael', 'email': 'michael@talkpython.fm', 'password': 'a' * 6} with flask_app.test_request_context(path='/account/register', data=form_data): vm = RegisterViewModel() @@ -37,11 +33,7 @@ def test_vm_register_validation_for_existing_user(): # 3 A's of test: Arrange, Act, then Assert # Arrange - form_data = { - 'name': 'Michael', - 'email': 'michael@talkpython.fm', - 'password': 'a' * 6 - } + form_data = {'name': 'Michael', 'email': 'michael@talkpython.fm', 'password': 'a' * 6} with flask_app.test_request_context(path='/account/register', data=form_data): vm = RegisterViewModel() @@ -62,11 +54,8 @@ def test_v_register_view_new_user(): # Arrange from pypi_org.views.account_views import register_post - form_data = { - 'name': 'Michael', - 'email': 'michael@talkpython.fm', - 'password': 'a' * 6 - } + + form_data = {'name': 'Michael', 'email': 'michael@talkpython.fm', 'password': 'a' * 6} target = 'pypi_org.services.user_service.find_user_by_email' find_user = unittest.mock.patch(target, return_value=None) diff --git a/app/ch16_mongodb/final/tests/package_tests.py b/app/ch16_mongodb/final/tests/package_tests.py index efd04ef5..a7c221a5 100644 --- a/app/ch16_mongodb/final/tests/package_tests.py +++ b/app/ch16_mongodb/final/tests/package_tests.py @@ -12,15 +12,14 @@ def test_package_details_success(): test_package = Package() test_package.id = 'sqlalchemy' - test_package.description = "TDB" + test_package.description = 'TDB' test_package.releases = [ Release(created_date=datetime.datetime.now(), major_ver=1, minor_ver=2, build_ver=200), Release(created_date=datetime.datetime.now() - datetime.timedelta(days=10)), ] # Act - with unittest.mock.patch('pypi_org.services.package_service.get_package_by_id', - return_value=test_package): + with unittest.mock.patch('pypi_org.services.package_service.get_package_by_id', return_value=test_package): with flask_app.test_request_context(path='/project/' + test_package.id): resp: Response = package_details(test_package.id) @@ -33,8 +32,7 @@ def test_package_details_404(client): bad_package_url = 'sqlalchemy_missing' # Act - with unittest.mock.patch('pypi_org.services.package_service.get_package_by_id', - return_value=None): + with unittest.mock.patch('pypi_org.services.package_service.get_package_by_id', return_value=None): resp: Response = client.get(bad_package_url) assert resp.status_code == 404 diff --git a/app/ch16_mongodb/final/tests/sitemap_tests.py b/app/ch16_mongodb/final/tests/sitemap_tests.py index b1afe0fe..4494c30a 100644 --- a/app/ch16_mongodb/final/tests/sitemap_tests.py +++ b/app/ch16_mongodb/final/tests/sitemap_tests.py @@ -10,10 +10,7 @@ def test_int_site_mapped_urls(client): href.text.strip().replace('http://127.0.0.1:5000', '').replace('http://localhost', '') for href in list(x.findall('url/loc')) ] - urls = [ - u if u else '/' - for u in urls - ] + urls = [u if u else '/' for u in urls] print('Testing {} urls from sitemap...'.format(len(urls)), flush=True) has_tested_projects = False @@ -40,7 +37,7 @@ def get_sitemap_text(client): # # ... # - res: Response = client.get("/sitemap.xml") - text = res.data.decode("utf-8") + res: Response = client.get('/sitemap.xml') + text = res.data.decode('utf-8') text = text.replace('xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"', '') return text diff --git a/app/ch16_mongodb/final/tests/test_client.py b/app/ch16_mongodb/final/tests/test_client.py index ffbea486..4390409a 100644 --- a/app/ch16_mongodb/final/tests/test_client.py +++ b/app/ch16_mongodb/final/tests/test_client.py @@ -4,9 +4,7 @@ import sys import os -container_folder = os.path.abspath(os.path.join( - os.path.dirname(__file__), '..' -)) +container_folder = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) sys.path.insert(0, container_folder) import pypi_org.app diff --git a/app/ch16_mongodb/starter/alembic/alembic_helpers.py b/app/ch16_mongodb/starter/alembic/alembic_helpers.py index 561f7a70..6aea52d4 100644 --- a/app/ch16_mongodb/starter/alembic/alembic_helpers.py +++ b/app/ch16_mongodb/starter/alembic/alembic_helpers.py @@ -5,8 +5,7 @@ def table_has_column(table, column): config = op.get_context().config - engine = engine_from_config( - config.get_section(config.config_ini_section), prefix='sqlalchemy.') + engine = engine_from_config(config.get_section(config.config_ini_section), prefix='sqlalchemy.') insp = reflection.Inspector.from_engine(engine) has_column = False for col in insp.get_columns(table): diff --git a/app/ch16_mongodb/starter/alembic/env.py b/app/ch16_mongodb/starter/alembic/env.py index 27ec49fb..1fdc9cab 100644 --- a/app/ch16_mongodb/starter/alembic/env.py +++ b/app/ch16_mongodb/starter/alembic/env.py @@ -26,6 +26,7 @@ sys.path.insert(0, folder) from pypi_org.data.modelbase import SqlAlchemyBase + # noinspection PyUnresolvedReferences import pypi_org.data.__all_models @@ -49,10 +50,8 @@ def run_migrations_offline(): script output. """ - url = config.get_main_option("sqlalchemy.url") - context.configure( - url=url, target_metadata=target_metadata, literal_binds=True - ) + url = config.get_main_option('sqlalchemy.url') + context.configure(url=url, target_metadata=target_metadata, literal_binds=True) with context.begin_transaction(): context.run_migrations() @@ -67,14 +66,12 @@ def run_migrations_online(): """ connectable = engine_from_config( config.get_section(config.config_ini_section), - prefix="sqlalchemy.", + prefix='sqlalchemy.', poolclass=pool.NullPool, ) with connectable.connect() as connection: - context.configure( - connection=connection, target_metadata=target_metadata - ) + context.configure(connection=connection, target_metadata=target_metadata) with context.begin_transaction(): context.run_migrations() diff --git a/app/ch16_mongodb/starter/alembic/versions/722c82f0097c_added_auditing_table.py b/app/ch16_mongodb/starter/alembic/versions/722c82f0097c_added_auditing_table.py index 2c3e2a39..7c6e892f 100644 --- a/app/ch16_mongodb/starter/alembic/versions/722c82f0097c_added_auditing_table.py +++ b/app/ch16_mongodb/starter/alembic/versions/722c82f0097c_added_auditing_table.py @@ -18,11 +18,12 @@ def upgrade(): # ### commands auto generated by Alembic - please adjust! ### - op.create_table('auditing', - sa.Column('id', sa.String(), nullable=False), - sa.Column('created_date', sa.DateTime(), nullable=True), - sa.Column('description', sa.String(), nullable=True), - sa.PrimaryKeyConstraint('id') + op.create_table( + 'auditing', + sa.Column('id', sa.String(), nullable=False), + sa.Column('created_date', sa.DateTime(), nullable=True), + sa.Column('description', sa.String(), nullable=True), + sa.PrimaryKeyConstraint('id'), ) op.create_index(op.f('ix_auditing_created_date'), 'auditing', ['created_date'], unique=False) # ### end Alembic commands ### diff --git a/app/ch16_mongodb/starter/pypi_org/app.py b/app/ch16_mongodb/starter/pypi_org/app.py index d1de87c6..ee364816 100644 --- a/app/ch16_mongodb/starter/pypi_org/app.py +++ b/app/ch16_mongodb/starter/pypi_org/app.py @@ -16,21 +16,18 @@ def main(): def configure(): - print("Configuring Flask app:") + print('Configuring Flask app:') register_blueprints() - print("Registered blueprints") + print('Registered blueprints') setup_db() - print("DB setup completed.") - print("", flush=True) + print('DB setup completed.') + print('', flush=True) def setup_db(): - db_file = os.path.join( - os.path.dirname(__file__), - 'db', - 'pypi.sqlite') + db_file = os.path.join(os.path.dirname(__file__), 'db', 'pypi.sqlite') db_session.global_init(db_file) diff --git a/app/ch16_mongodb/starter/pypi_org/bin/basic_inserts.py b/app/ch16_mongodb/starter/pypi_org/bin/basic_inserts.py index d622a6ae..6d04f551 100644 --- a/app/ch16_mongodb/starter/pypi_org/bin/basic_inserts.py +++ b/app/ch16_mongodb/starter/pypi_org/bin/basic_inserts.py @@ -2,8 +2,7 @@ import sys # Make it run more easily outside of PyCharm -sys.path.insert(0, os.path.abspath(os.path.join( - os.path.dirname(__file__), "..", ".."))) +sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..'))) import pypi_org.data.db_session as db_session from pypi_org.data.package import Package @@ -20,24 +19,24 @@ def insert_a_package(): p = Package() p.id = input('Package id / name: ').strip().lower() - p.summary = input("Package summary: ").strip() - p.author_name = input("Author: ").strip() - p.license = input("License: ").strip() + p.summary = input('Package summary: ').strip() + p.author_name = input('Author: ').strip() + p.license = input('License: ').strip() - print("Release 1:") + print('Release 1:') r = Release() - r.major_ver = int(input("Major version: ")) - r.minor_ver = int(input("Minor version: ")) - r.build_ver = int(input("Build version: ")) - r.size = int(input("Size in bytes: ")) + r.major_ver = int(input('Major version: ')) + r.minor_ver = int(input('Minor version: ')) + r.build_ver = int(input('Build version: ')) + r.size = int(input('Size in bytes: ')) p.releases.append(r) - print("Release 2:") + print('Release 2:') r = Release() - r.major_ver = int(input("Major version: ")) - r.minor_ver = int(input("Minor version: ")) - r.build_ver = int(input("Build version: ")) - r.size = int(input("Size in bytes: ")) + r.major_ver = int(input('Major version: ')) + r.minor_ver = int(input('Minor version: ')) + r.build_ver = int(input('Build version: ')) + r.size = int(input('Size in bytes: ')) p.releases.append(r) session = db_session.create_session() diff --git a/app/ch16_mongodb/starter/pypi_org/bin/load_data.py b/app/ch16_mongodb/starter/pypi_org/bin/load_data.py index 8f43c13c..228c1b6b 100644 --- a/app/ch16_mongodb/starter/pypi_org/bin/load_data.py +++ b/app/ch16_mongodb/starter/pypi_org/bin/load_data.py @@ -7,8 +7,7 @@ import progressbar from dateutil.parser import parse -sys.path.insert(0, os.path.abspath(os.path.join( - os.path.dirname(__file__), "..", ".."))) +sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..'))) import pypi_org.data.db_session as db_session from pypi_org.data.languages import ProgrammingLanguage @@ -39,7 +38,7 @@ def main(): def do_import_languages(file_data: List[dict]): imported = set() - print("Importing languages ... ", flush=True) + print('Importing languages ... ', flush=True) with progressbar.ProgressBar(max_value=len(file_data)) as bar: for idx, p in enumerate(file_data): info = p.get('info') @@ -74,7 +73,7 @@ def do_import_languages(file_data: List[dict]): def do_import_licenses(file_data: List[dict]): imported = set() - print("Importing licenses ... ", flush=True) + print('Importing licenses ... ', flush=True) with progressbar.ProgressBar(max_value=len(file_data)) as bar: for idx, p in enumerate(file_data): info = p.get('info') @@ -100,17 +99,17 @@ def do_import_licenses(file_data: List[dict]): def do_summary(): session = db_session.create_session() - print("Final numbers:") - print("Users: {:,}".format(session.query(User).count())) - print("Packages: {:,}".format(session.query(Package).count())) - print("Releases: {:,}".format(session.query(Release).count())) - print("Maintainers: {:,}".format(session.query(Maintainer).count())) - print("Languages: {:,}".format(session.query(ProgrammingLanguage).count())) - print("Licenses: {:,}".format(session.query(License).count())) + print('Final numbers:') + print('Users: {:,}'.format(session.query(User).count())) + print('Packages: {:,}'.format(session.query(Package).count())) + print('Releases: {:,}'.format(session.query(Release).count())) + print('Maintainers: {:,}'.format(session.query(Maintainer).count())) + print('Languages: {:,}'.format(session.query(ProgrammingLanguage).count())) + print('Licenses: {:,}'.format(session.query(License).count())) def do_user_import(user_lookup: Dict[str, str]) -> Dict[str, User]: - print("Importing users ... ", flush=True) + print('Importing users ... ', flush=True) with progressbar.ProgressBar(max_value=len(user_lookup)) as bar: for idx, (email, name) in enumerate(user_lookup.items()): session = db_session.create_session() @@ -134,29 +133,29 @@ def do_user_import(user_lookup: Dict[str, str]) -> Dict[str, User]: def do_import_packages(file_data: List[dict], user_lookup: Dict[str, User]): errored_packages = [] - print("Importing packages and releases ... ", flush=True) + print('Importing packages and releases ... ', flush=True) with progressbar.ProgressBar(max_value=len(file_data)) as bar: for idx, p in enumerate(file_data): try: load_package(p, user_lookup) bar.update(idx) except Exception as x: - errored_packages.append((p, " *** Errored out for package {}, {}".format(p.get('package_name'), x))) + errored_packages.append((p, ' *** Errored out for package {}, {}'.format(p.get('package_name'), x))) raise sys.stderr.flush() sys.stdout.flush() print() - print("Completed packages with {} errors.".format(len(errored_packages))) - for (p, txt) in errored_packages: + print('Completed packages with {} errors.'.format(len(errored_packages))) + for p, txt in errored_packages: print(txt) def do_load_files() -> List[dict]: data_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../../../data/pypi-top-100')) - print("Loading files from {}".format(data_path)) + print('Loading files from {}'.format(data_path)) files = get_file_names(data_path) - print("Found {:,} files, loading ...".format(len(files)), flush=True) - time.sleep(.1) + print('Found {:,} files, loading ...'.format(len(files)), flush=True) + time.sleep(0.1) file_data = [] with progressbar.ProgressBar(max_value=len(files)) as bar: @@ -171,7 +170,7 @@ def do_load_files() -> List[dict]: def find_users(data: List[dict]) -> dict: - print("Discovering users...", flush=True) + print('Discovering users...', flush=True) found_users = {} with progressbar.ProgressBar(max_value=len(data)) as bar: @@ -184,7 +183,7 @@ def find_users(data: List[dict]) -> dict: sys.stderr.flush() sys.stdout.flush() print() - print("Discovered {:,} users".format(len(found_users))) + print('Discovered {:,} users'.format(len(found_users))) print() return found_users @@ -215,7 +214,7 @@ def load_file_data(filename: str) -> dict: with open(filename, 'r', encoding='utf-8') as fin: data = json.load(fin) except Exception as x: - print("ERROR in file: {}, details: {}".format(filename, x), flush=True) + print('ERROR in file: {}, details: {}'.format(filename, x), flush=True) raise return data @@ -233,7 +232,7 @@ def load_package(data: dict, user_lookup: Dict[str, User]): p.author = info.get('author') p.author_email = info.get('author_email') - releases = build_releases(p.id, data.get("releases", {})) + releases = build_releases(p.id, data.get('releases', {})) if releases: p.created_date = releases[0].created_date @@ -283,18 +282,13 @@ def detect_license(license_text: str) -> Optional[str]: license_text = license_text.strip() if len(license_text) > 100 or '\n' in license_text: - return "CUSTOM" + return 'CUSTOM' - license_text = license_text \ - .replace('Software License', '') \ - .replace('License', '') + license_text = license_text.replace('Software License', '').replace('License', '') if '::' in license_text: # E.g. 'License :: OSI Approved :: Apache Software License' - return license_text \ - .split(':')[-1] \ - .replace(' ', ' ') \ - .strip() + return license_text.split(':')[-1].replace(' ', ' ').strip() return license_text.strip() @@ -357,9 +351,7 @@ def get_file_names(data_path: str) -> List[str]: files = [] for f in os.listdir(data_path): if f.endswith('.json'): - files.append( - os.path.abspath(os.path.join(data_path, f)) - ) + files.append(os.path.abspath(os.path.join(data_path, f))) files.sort() return files diff --git a/app/ch16_mongodb/starter/pypi_org/data/__all_models.py b/app/ch16_mongodb/starter/pypi_org/data/__all_models.py index f399ef54..ca4804ac 100644 --- a/app/ch16_mongodb/starter/pypi_org/data/__all_models.py +++ b/app/ch16_mongodb/starter/pypi_org/data/__all_models.py @@ -5,17 +5,24 @@ # noinspection PyUnresolvedReferences import pypi_org.data.audit + # noinspection PyUnresolvedReferences import pypi_org.data.downloads + # noinspection PyUnresolvedReferences import pypi_org.data.languages + # noinspection PyUnresolvedReferences import pypi_org.data.licenses + # noinspection PyUnresolvedReferences import pypi_org.data.maintainers + # noinspection PyUnresolvedReferences import pypi_org.data.package + # noinspection PyUnresolvedReferences import pypi_org.data.releases + # noinspection PyUnresolvedReferences import pypi_org.data.users diff --git a/app/ch16_mongodb/starter/pypi_org/data/db_session.py b/app/ch16_mongodb/starter/pypi_org/data/db_session.py index acfc485d..a1c4df68 100644 --- a/app/ch16_mongodb/starter/pypi_org/data/db_session.py +++ b/app/ch16_mongodb/starter/pypi_org/data/db_session.py @@ -14,10 +14,10 @@ def global_init(db_file: str): return if not db_file or not db_file.strip(): - raise Exception("You must specify a db file.") + raise Exception('You must specify a db file.') conn_str = 'sqlite:///' + db_file.strip() - print("Connecting to DB with {}".format(conn_str)) + print('Connecting to DB with {}'.format(conn_str)) engine = sa.create_engine(conn_str, echo=False) __factory = orm.sessionmaker(bind=engine) diff --git a/app/ch16_mongodb/starter/pypi_org/data/downloads.py b/app/ch16_mongodb/starter/pypi_org/data/downloads.py index 66068f02..dd8afd65 100644 --- a/app/ch16_mongodb/starter/pypi_org/data/downloads.py +++ b/app/ch16_mongodb/starter/pypi_org/data/downloads.py @@ -7,8 +7,7 @@ class Download(SqlAlchemyBase): __tablename__ = 'downloads' id: int = sqlalchemy.Column(sqlalchemy.BigInteger, primary_key=True, autoincrement=True) - created_date: datetime.datetime = sqlalchemy.Column( - sqlalchemy.DateTime, default=datetime.datetime.now, index=True) + created_date: datetime.datetime = sqlalchemy.Column(sqlalchemy.DateTime, default=datetime.datetime.now, index=True) package_id: str = sqlalchemy.Column(sqlalchemy.String, index=True) release_id: int = sqlalchemy.Column(sqlalchemy.BigInteger, index=True) diff --git a/app/ch16_mongodb/starter/pypi_org/data/languages.py b/app/ch16_mongodb/starter/pypi_org/data/languages.py index 964b8444..3a73dde0 100644 --- a/app/ch16_mongodb/starter/pypi_org/data/languages.py +++ b/app/ch16_mongodb/starter/pypi_org/data/languages.py @@ -7,6 +7,5 @@ class ProgrammingLanguage(SqlAlchemyBase): __tablename__ = 'languages' id: str = sqlalchemy.Column(sqlalchemy.String, primary_key=True) - created_date: datetime.datetime = sqlalchemy.Column( - sqlalchemy.DateTime, default=datetime.datetime.now, index=True) + created_date: datetime.datetime = sqlalchemy.Column(sqlalchemy.DateTime, default=datetime.datetime.now, index=True) description: str = sqlalchemy.Column(sqlalchemy.String) diff --git a/app/ch16_mongodb/starter/pypi_org/data/package.py b/app/ch16_mongodb/starter/pypi_org/data/package.py index c3420d1b..16e6d156 100644 --- a/app/ch16_mongodb/starter/pypi_org/data/package.py +++ b/app/ch16_mongodb/starter/pypi_org/data/package.py @@ -26,11 +26,15 @@ class Package(SqlAlchemyBase): license: str = sa.Column(sa.String, index=True) # releases relationship - releases: List[Release] = orm.relation("Release", order_by=[ - Release.major_ver.desc(), - Release.minor_ver.desc(), - Release.build_ver.desc(), - ], back_populates='package') + releases: List[Release] = orm.relation( + 'Release', + order_by=[ + Release.major_ver.desc(), + Release.minor_ver.desc(), + Release.build_ver.desc(), + ], + back_populates='package', + ) def __repr__(self): return ''.format(self.id) diff --git a/app/ch16_mongodb/starter/pypi_org/data/releases.py b/app/ch16_mongodb/starter/pypi_org/data/releases.py index 7650e438..8596f65c 100644 --- a/app/ch16_mongodb/starter/pypi_org/data/releases.py +++ b/app/ch16_mongodb/starter/pypi_org/data/releases.py @@ -13,15 +13,13 @@ class Release(SqlAlchemyBase): minor_ver: int = sqlalchemy.Column(sqlalchemy.BigInteger, index=True) build_ver: int = sqlalchemy.Column(sqlalchemy.BigInteger, index=True) - created_date: datetime.datetime = sqlalchemy.Column(sqlalchemy.DateTime, - default=datetime.datetime.now, - index=True) + created_date: datetime.datetime = sqlalchemy.Column(sqlalchemy.DateTime, default=datetime.datetime.now, index=True) comment: str = sqlalchemy.Column(sqlalchemy.String) url: str = sqlalchemy.Column(sqlalchemy.String) size: int = sqlalchemy.Column(sqlalchemy.BigInteger) # Package relationship - package_id: str = sqlalchemy.Column(sqlalchemy.String, sqlalchemy.ForeignKey("packages.id")) + package_id: str = sqlalchemy.Column(sqlalchemy.String, sqlalchemy.ForeignKey('packages.id')) package = orm.relation('Package') @property diff --git a/app/ch16_mongodb/starter/pypi_org/infrastructure/cookie_auth.py b/app/ch16_mongodb/starter/pypi_org/infrastructure/cookie_auth.py index 44864438..c215c0af 100644 --- a/app/ch16_mongodb/starter/pypi_org/infrastructure/cookie_auth.py +++ b/app/ch16_mongodb/starter/pypi_org/infrastructure/cookie_auth.py @@ -11,7 +11,7 @@ def set_auth(response: Response, user_id: int): hash_val = __hash_text(str(user_id)) - val = "{}:{}".format(user_id, hash_val) + val = '{}:{}'.format(user_id, hash_val) response.set_cookie(auth_cookie_name, val, secure=False, httponly=True, samesite='Lax') @@ -33,7 +33,7 @@ def get_user_id_via_auth_cookie(request: Request) -> Optional[int]: hash_val = parts[1] hash_val_check = __hash_text(user_id) if hash_val != hash_val_check: - print("Warning: Hash mismatch, invalid cookie value") + print('Warning: Hash mismatch, invalid cookie value') return None return try_int(user_id) diff --git a/app/ch16_mongodb/starter/pypi_org/infrastructure/request_dict.py b/app/ch16_mongodb/starter/pypi_org/infrastructure/request_dict.py index d7ab10de..d44ae574 100644 --- a/app/ch16_mongodb/starter/pypi_org/infrastructure/request_dict.py +++ b/app/ch16_mongodb/starter/pypi_org/infrastructure/request_dict.py @@ -29,7 +29,7 @@ def create(default_val=None, **route_args) -> RequestDictionary: **args, # The key/value pairs in the URL query string **request.headers, # Header values **form, # The key/value pairs in the body, from a HTML post form - **route_args # And additional arguments the method access, if they want them merged. + **route_args, # And additional arguments the method access, if they want them merged. } return RequestDictionary(data, default_val=default_val) diff --git a/app/ch16_mongodb/starter/pypi_org/infrastructure/view_modifiers.py b/app/ch16_mongodb/starter/pypi_org/infrastructure/view_modifiers.py index 0978163e..d944c142 100644 --- a/app/ch16_mongodb/starter/pypi_org/infrastructure/view_modifiers.py +++ b/app/ch16_mongodb/starter/pypi_org/infrastructure/view_modifiers.py @@ -26,7 +26,8 @@ def view_method(*args, **kwargs): if template_file and not isinstance(response_val, dict): raise Exception( - "Invalid return type {}, we expected a dict as the return value.".format(type(response_val))) + 'Invalid return type {}, we expected a dict as the return value.'.format(type(response_val)) + ) if template_file: response_val = flask.render_template(template_file, **response_val) @@ -42,6 +43,7 @@ def view_method(*args, **kwargs): return response_inner + # # def template(template_file: str = None): # def template_inner(f): diff --git a/app/ch16_mongodb/starter/pypi_org/services/package_service.py b/app/ch16_mongodb/starter/pypi_org/services/package_service.py index b03408d2..9a153773 100644 --- a/app/ch16_mongodb/starter/pypi_org/services/package_service.py +++ b/app/ch16_mongodb/starter/pypi_org/services/package_service.py @@ -10,12 +10,13 @@ def get_latest_releases(limit=10) -> List[Release]: session = db_session.create_session() try: - - releases = session.query(Release). \ - options(sqlalchemy.orm.joinedload(Release.package)). \ - order_by(Release.created_date.desc()). \ - limit(limit). \ - all() + releases = ( + session.query(Release) + .options(sqlalchemy.orm.joinedload(Release.package)) + .order_by(Release.created_date.desc()) + .limit(limit) + .all() + ) finally: session.close() @@ -47,11 +48,12 @@ def get_package_by_id(package_id: str) -> Optional[Package]: session = db_session.create_session() try: - - package = session.query(Package) \ - .options(sqlalchemy.orm.joinedload(Package.releases)) \ - .filter(Package.id == package_id) \ + package = ( + session.query(Package) + .options(sqlalchemy.orm.joinedload(Package.releases)) + .filter(Package.id == package_id) .first() + ) finally: session.close() diff --git a/app/ch16_mongodb/starter/pypi_org/viewmodels/cms/page_viewmodel.py b/app/ch16_mongodb/starter/pypi_org/viewmodels/cms/page_viewmodel.py index b7bb3249..ec033c3f 100644 --- a/app/ch16_mongodb/starter/pypi_org/viewmodels/cms/page_viewmodel.py +++ b/app/ch16_mongodb/starter/pypi_org/viewmodels/cms/page_viewmodel.py @@ -7,4 +7,3 @@ def __init__(self, full_url: str): super().__init__() self.page = cms_service.get_page(full_url) - diff --git a/app/ch16_mongodb/starter/pypi_org/viewmodels/packages/pagedetails_viewmodel.py b/app/ch16_mongodb/starter/pypi_org/viewmodels/packages/pagedetails_viewmodel.py index 63c4cf68..09f47c6f 100644 --- a/app/ch16_mongodb/starter/pypi_org/viewmodels/packages/pagedetails_viewmodel.py +++ b/app/ch16_mongodb/starter/pypi_org/viewmodels/packages/pagedetails_viewmodel.py @@ -11,7 +11,7 @@ def __init__(self, package_name: str): self.package_name = package_name.strip().lower() self.package = package_service.get_package_by_id(self.package_name) - self.latest_version = "0.0.0" + self.latest_version = '0.0.0' self.latest_release = None self.is_latest = True diff --git a/app/ch16_mongodb/starter/pypi_org/viewmodels/seo/sitemap_viewmodel.py b/app/ch16_mongodb/starter/pypi_org/viewmodels/seo/sitemap_viewmodel.py index 912c4df0..71df2f99 100644 --- a/app/ch16_mongodb/starter/pypi_org/viewmodels/seo/sitemap_viewmodel.py +++ b/app/ch16_mongodb/starter/pypi_org/viewmodels/seo/sitemap_viewmodel.py @@ -8,5 +8,5 @@ class SiteMapViewModel(ViewModelBase): def __init__(self, limit: int): super().__init__() self.packages = package_service.all_packages(limit) - self.last_updated_text = "2019-07-15" - self.site = "{}://{}".format(flask.request.scheme, flask.request.host) + self.last_updated_text = '2019-07-15' + self.site = '{}://{}'.format(flask.request.scheme, flask.request.host) diff --git a/app/ch16_mongodb/starter/pypi_org/views/account_views.py b/app/ch16_mongodb/starter/pypi_org/views/account_views.py index 3854b4cf..652f43b3 100644 --- a/app/ch16_mongodb/starter/pypi_org/views/account_views.py +++ b/app/ch16_mongodb/starter/pypi_org/views/account_views.py @@ -25,6 +25,7 @@ def index(): # ################### REGISTER ################################# + @blueprint.route('/account/register', methods=['GET']) @response(template_file='account/register.html') def register_get(): @@ -54,6 +55,7 @@ def register_post(): # ################### LOGIN ################################# + @blueprint.route('/account/login', methods=['GET']) @response(template_file='account/login.html') def login_get(): @@ -77,7 +79,7 @@ def login_post(): user = user_service.login_user(vm.email, vm.password) if not user: - vm.error = "The account does not exist or the password is wrong." + vm.error = 'The account does not exist or the password is wrong.' return vm.to_dict() resp = flask.redirect('/account') @@ -88,6 +90,7 @@ def login_post(): # ################### LOGOUT ################################# + @blueprint.route('/account/logout') def logout(): resp = flask.redirect('/') diff --git a/app/ch16_mongodb/starter/pypi_org/views/package_views.py b/app/ch16_mongodb/starter/pypi_org/views/package_views.py index 1a74549f..2f862740 100644 --- a/app/ch16_mongodb/starter/pypi_org/views/package_views.py +++ b/app/ch16_mongodb/starter/pypi_org/views/package_views.py @@ -19,4 +19,4 @@ def package_details(package_name: str): @blueprint.route('/') def popular(rank: int): print(type(rank), rank) - return "The details for the {}th most popular package".format(rank) + return 'The details for the {}th most popular package'.format(rank) diff --git a/app/ch16_mongodb/starter/pypi_org/views/seo_view.py b/app/ch16_mongodb/starter/pypi_org/views/seo_view.py index 93c88de5..f86b6bff 100644 --- a/app/ch16_mongodb/starter/pypi_org/views/seo_view.py +++ b/app/ch16_mongodb/starter/pypi_org/views/seo_view.py @@ -18,6 +18,7 @@ def sitemap(): # ################### Robots ################################# + @blueprint.route('/robots.txt') @response(mimetype='text/plain', template_file='seo/robots.txt') def robots(): diff --git a/app/ch16_mongodb/starter/tests/_all_tests.py b/app/ch16_mongodb/starter/tests/_all_tests.py index daa69ea4..e5c9b9ea 100644 --- a/app/ch16_mongodb/starter/tests/_all_tests.py +++ b/app/ch16_mongodb/starter/tests/_all_tests.py @@ -1,17 +1,18 @@ import sys import os -container_folder = os.path.abspath(os.path.join( - os.path.dirname(__file__), '..' -)) +container_folder = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) sys.path.insert(0, container_folder) # noinspection PyUnresolvedReferences from account_tests import * + # noinspection PyUnresolvedReferences from package_tests import * + # noinspection PyUnresolvedReferences from sitemap_tests import * + # noinspection PyUnresolvedReferences from home_tests import * diff --git a/app/ch16_mongodb/starter/tests/account_tests.py b/app/ch16_mongodb/starter/tests/account_tests.py index 4f5aa156..e31e8c28 100644 --- a/app/ch16_mongodb/starter/tests/account_tests.py +++ b/app/ch16_mongodb/starter/tests/account_tests.py @@ -7,7 +7,7 @@ def test_example(): - print("Test example...") + print('Test example...') assert 1 + 2 == 3 @@ -15,11 +15,7 @@ def test_vm_register_validation_when_valid(): # 3 A's of test: Arrange, Act, then Assert # Arrange - form_data = { - 'name': 'Michael', - 'email': 'michael@talkpython.fm', - 'password': 'a' * 6 - } + form_data = {'name': 'Michael', 'email': 'michael@talkpython.fm', 'password': 'a' * 6} with flask_app.test_request_context(path='/account/register', data=form_data): vm = RegisterViewModel() @@ -37,11 +33,7 @@ def test_vm_register_validation_for_existing_user(): # 3 A's of test: Arrange, Act, then Assert # Arrange - form_data = { - 'name': 'Michael', - 'email': 'michael@talkpython.fm', - 'password': 'a' * 6 - } + form_data = {'name': 'Michael', 'email': 'michael@talkpython.fm', 'password': 'a' * 6} with flask_app.test_request_context(path='/account/register', data=form_data): vm = RegisterViewModel() @@ -62,11 +54,8 @@ def test_v_register_view_new_user(): # Arrange from pypi_org.views.account_views import register_post - form_data = { - 'name': 'Michael', - 'email': 'michael@talkpython.fm', - 'password': 'a' * 6 - } + + form_data = {'name': 'Michael', 'email': 'michael@talkpython.fm', 'password': 'a' * 6} target = 'pypi_org.services.user_service.find_user_by_email' find_user = unittest.mock.patch(target, return_value=None) diff --git a/app/ch16_mongodb/starter/tests/package_tests.py b/app/ch16_mongodb/starter/tests/package_tests.py index efd04ef5..a7c221a5 100644 --- a/app/ch16_mongodb/starter/tests/package_tests.py +++ b/app/ch16_mongodb/starter/tests/package_tests.py @@ -12,15 +12,14 @@ def test_package_details_success(): test_package = Package() test_package.id = 'sqlalchemy' - test_package.description = "TDB" + test_package.description = 'TDB' test_package.releases = [ Release(created_date=datetime.datetime.now(), major_ver=1, minor_ver=2, build_ver=200), Release(created_date=datetime.datetime.now() - datetime.timedelta(days=10)), ] # Act - with unittest.mock.patch('pypi_org.services.package_service.get_package_by_id', - return_value=test_package): + with unittest.mock.patch('pypi_org.services.package_service.get_package_by_id', return_value=test_package): with flask_app.test_request_context(path='/project/' + test_package.id): resp: Response = package_details(test_package.id) @@ -33,8 +32,7 @@ def test_package_details_404(client): bad_package_url = 'sqlalchemy_missing' # Act - with unittest.mock.patch('pypi_org.services.package_service.get_package_by_id', - return_value=None): + with unittest.mock.patch('pypi_org.services.package_service.get_package_by_id', return_value=None): resp: Response = client.get(bad_package_url) assert resp.status_code == 404 diff --git a/app/ch16_mongodb/starter/tests/sitemap_tests.py b/app/ch16_mongodb/starter/tests/sitemap_tests.py index b1afe0fe..4494c30a 100644 --- a/app/ch16_mongodb/starter/tests/sitemap_tests.py +++ b/app/ch16_mongodb/starter/tests/sitemap_tests.py @@ -10,10 +10,7 @@ def test_int_site_mapped_urls(client): href.text.strip().replace('http://127.0.0.1:5000', '').replace('http://localhost', '') for href in list(x.findall('url/loc')) ] - urls = [ - u if u else '/' - for u in urls - ] + urls = [u if u else '/' for u in urls] print('Testing {} urls from sitemap...'.format(len(urls)), flush=True) has_tested_projects = False @@ -40,7 +37,7 @@ def get_sitemap_text(client): # # ... # - res: Response = client.get("/sitemap.xml") - text = res.data.decode("utf-8") + res: Response = client.get('/sitemap.xml') + text = res.data.decode('utf-8') text = text.replace('xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"', '') return text diff --git a/app/ch16_mongodb/starter/tests/test_client.py b/app/ch16_mongodb/starter/tests/test_client.py index ffbea486..4390409a 100644 --- a/app/ch16_mongodb/starter/tests/test_client.py +++ b/app/ch16_mongodb/starter/tests/test_client.py @@ -4,9 +4,7 @@ import sys import os -container_folder = os.path.abspath(os.path.join( - os.path.dirname(__file__), '..' -)) +container_folder = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) sys.path.insert(0, container_folder) import pypi_org.app From d0b735e8e07b301b7963a4d38e10c0e8067b514a Mon Sep 17 00:00:00 2001 From: Michael Kennedy Date: Tue, 12 Dec 2023 16:41:14 -0800 Subject: [PATCH 36/44] Update package and releases due to change with sqlalchemy 2.0. --- .../final/pypi_org/data/package.py | 4 +++- .../final/pypi_org/data/releases.py | 2 +- .../final/pypi_org/data/package.py | 4 +++- .../final/pypi_org/data/releases.py | 2 +- .../starter/pypi_org/data/package.py | 24 ++++++++++--------- .../starter/pypi_org/data/releases.py | 20 ++++++++-------- .../final/pypi_org/bin/load_data.py | 3 ++- .../final/pypi_org/data/package.py | 5 ++-- .../final/pypi_org/data/releases.py | 2 +- .../pypi_org/infrastructure/num_convert.py | 8 +++++++ app/ch12-forms/final/pypi_org/data/package.py | 5 ++-- .../final/pypi_org/data/releases.py | 2 +- 12 files changed, 49 insertions(+), 32 deletions(-) create mode 100644 app/ch11_migrations/final/pypi_org/infrastructure/num_convert.py diff --git a/app/ch09_sqlalchemy/final/pypi_org/data/package.py b/app/ch09_sqlalchemy/final/pypi_org/data/package.py index 9b8a2ded..a272243d 100644 --- a/app/ch09_sqlalchemy/final/pypi_org/data/package.py +++ b/app/ch09_sqlalchemy/final/pypi_org/data/package.py @@ -3,6 +3,8 @@ import sqlalchemy as sa import sqlalchemy.orm as orm +from sqlalchemy.orm import Mapped + from pypi_org.data.modelbase import SqlAlchemyBase from pypi_org.data.releases import Release @@ -25,7 +27,7 @@ class Package(SqlAlchemyBase): license = sa.Column(sa.String, index=True) # releases relationship - releases: List[Release] = orm.relation( + releases: Mapped[Release] = orm.relationship( 'Release', order_by=[ Release.major_ver.desc(), diff --git a/app/ch09_sqlalchemy/final/pypi_org/data/releases.py b/app/ch09_sqlalchemy/final/pypi_org/data/releases.py index 0faf1a8e..a0be5918 100644 --- a/app/ch09_sqlalchemy/final/pypi_org/data/releases.py +++ b/app/ch09_sqlalchemy/final/pypi_org/data/releases.py @@ -20,7 +20,7 @@ class Release(SqlAlchemyBase): # Package relationship package_id = sqlalchemy.Column(sqlalchemy.String, sqlalchemy.ForeignKey('packages.id')) - package = orm.relation('Package') + package = orm.relationship('Package') @property def version_text(self): diff --git a/app/ch10_using_sqlachemy/final/pypi_org/data/package.py b/app/ch10_using_sqlachemy/final/pypi_org/data/package.py index 17fbf2f4..e0e48878 100644 --- a/app/ch10_using_sqlachemy/final/pypi_org/data/package.py +++ b/app/ch10_using_sqlachemy/final/pypi_org/data/package.py @@ -3,6 +3,8 @@ import sqlalchemy as sa import sqlalchemy.orm as orm +from sqlalchemy.orm import Mapped + from pypi_org.data.modelbase import SqlAlchemyBase from pypi_org.data.releases import Release @@ -25,7 +27,7 @@ class Package(SqlAlchemyBase): license: str = sa.Column(sa.String, index=True) # releases relationship - releases: List[Release] = orm.relation( + releases: Mapped[Release] = orm.relationship( 'Release', order_by=[ Release.major_ver.desc(), diff --git a/app/ch10_using_sqlachemy/final/pypi_org/data/releases.py b/app/ch10_using_sqlachemy/final/pypi_org/data/releases.py index 8596f65c..4b2db2bf 100644 --- a/app/ch10_using_sqlachemy/final/pypi_org/data/releases.py +++ b/app/ch10_using_sqlachemy/final/pypi_org/data/releases.py @@ -20,7 +20,7 @@ class Release(SqlAlchemyBase): # Package relationship package_id: str = sqlalchemy.Column(sqlalchemy.String, sqlalchemy.ForeignKey('packages.id')) - package = orm.relation('Package') + package = orm.relationship('Package') @property def version_text(self): diff --git a/app/ch10_using_sqlachemy/starter/pypi_org/data/package.py b/app/ch10_using_sqlachemy/starter/pypi_org/data/package.py index 9b8a2ded..e0e48878 100644 --- a/app/ch10_using_sqlachemy/starter/pypi_org/data/package.py +++ b/app/ch10_using_sqlachemy/starter/pypi_org/data/package.py @@ -3,6 +3,8 @@ import sqlalchemy as sa import sqlalchemy.orm as orm +from sqlalchemy.orm import Mapped + from pypi_org.data.modelbase import SqlAlchemyBase from pypi_org.data.releases import Release @@ -10,22 +12,22 @@ class Package(SqlAlchemyBase): __tablename__ = 'packages' - id = sa.Column(sa.String, primary_key=True) - created_date = sa.Column(sa.DateTime, default=datetime.datetime.now, index=True) - summary = sa.Column(sa.String, nullable=False) - description = sa.Column(sa.String, nullable=True) + id: str = sa.Column(sa.String, primary_key=True) + created_date: datetime.datetime = sa.Column(sa.DateTime, default=datetime.datetime.now, index=True) + summary: str = sa.Column(sa.String, nullable=False) + description: str = sa.Column(sa.String, nullable=True) - home_page = sa.Column(sa.String) - docs_url = sa.Column(sa.String) - package_url = sa.Column(sa.String) + home_page: str = sa.Column(sa.String) + docs_url: str = sa.Column(sa.String) + package_url: str = sa.Column(sa.String) - author_name = sa.Column(sa.String) - author_email = sa.Column(sa.String, index=True) + author_name: str = sa.Column(sa.String) + author_email: str = sa.Column(sa.String, index=True) - license = sa.Column(sa.String, index=True) + license: str = sa.Column(sa.String, index=True) # releases relationship - releases: List[Release] = orm.relation( + releases: Mapped[Release] = orm.relationship( 'Release', order_by=[ Release.major_ver.desc(), diff --git a/app/ch10_using_sqlachemy/starter/pypi_org/data/releases.py b/app/ch10_using_sqlachemy/starter/pypi_org/data/releases.py index 0faf1a8e..4b2db2bf 100644 --- a/app/ch10_using_sqlachemy/starter/pypi_org/data/releases.py +++ b/app/ch10_using_sqlachemy/starter/pypi_org/data/releases.py @@ -7,20 +7,20 @@ class Release(SqlAlchemyBase): __tablename__ = 'releases' - id = sqlalchemy.Column(sqlalchemy.Integer, primary_key=True, autoincrement=True) + id: int = sqlalchemy.Column(sqlalchemy.Integer, primary_key=True, autoincrement=True) - major_ver = sqlalchemy.Column(sqlalchemy.BigInteger, index=True) - minor_ver = sqlalchemy.Column(sqlalchemy.BigInteger, index=True) - build_ver = sqlalchemy.Column(sqlalchemy.BigInteger, index=True) + major_ver: int = sqlalchemy.Column(sqlalchemy.BigInteger, index=True) + minor_ver: int = sqlalchemy.Column(sqlalchemy.BigInteger, index=True) + build_ver: int = sqlalchemy.Column(sqlalchemy.BigInteger, index=True) - created_date = sqlalchemy.Column(sqlalchemy.DateTime, default=datetime.datetime.now, index=True) - comment = sqlalchemy.Column(sqlalchemy.String) - url = sqlalchemy.Column(sqlalchemy.String) - size = sqlalchemy.Column(sqlalchemy.BigInteger) + created_date: datetime.datetime = sqlalchemy.Column(sqlalchemy.DateTime, default=datetime.datetime.now, index=True) + comment: str = sqlalchemy.Column(sqlalchemy.String) + url: str = sqlalchemy.Column(sqlalchemy.String) + size: int = sqlalchemy.Column(sqlalchemy.BigInteger) # Package relationship - package_id = sqlalchemy.Column(sqlalchemy.String, sqlalchemy.ForeignKey('packages.id')) - package = orm.relation('Package') + package_id: str = sqlalchemy.Column(sqlalchemy.String, sqlalchemy.ForeignKey('packages.id')) + package = orm.relationship('Package') @property def version_text(self): diff --git a/app/ch11_migrations/final/pypi_org/bin/load_data.py b/app/ch11_migrations/final/pypi_org/bin/load_data.py index d64cb582..6e0bd617 100644 --- a/app/ch11_migrations/final/pypi_org/bin/load_data.py +++ b/app/ch11_migrations/final/pypi_org/bin/load_data.py @@ -7,9 +7,10 @@ import progressbar from dateutil.parser import parse +from pypi_org.infrastructure.num_convert import try_int + sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..'))) -from pypi_org.bin.load_data import try_int import pypi_org.data.db_session as db_session from pypi_org.data.languages import ProgrammingLanguage from pypi_org.data.licenses import License diff --git a/app/ch11_migrations/final/pypi_org/data/package.py b/app/ch11_migrations/final/pypi_org/data/package.py index 16e6d156..e0e48878 100644 --- a/app/ch11_migrations/final/pypi_org/data/package.py +++ b/app/ch11_migrations/final/pypi_org/data/package.py @@ -3,6 +3,8 @@ import sqlalchemy as sa import sqlalchemy.orm as orm +from sqlalchemy.orm import Mapped + from pypi_org.data.modelbase import SqlAlchemyBase from pypi_org.data.releases import Release @@ -12,7 +14,6 @@ class Package(SqlAlchemyBase): id: str = sa.Column(sa.String, primary_key=True) created_date: datetime.datetime = sa.Column(sa.DateTime, default=datetime.datetime.now, index=True) - last_updated: datetime.datetime = sa.Column(sa.DateTime, default=datetime.datetime.now, index=True) summary: str = sa.Column(sa.String, nullable=False) description: str = sa.Column(sa.String, nullable=True) @@ -26,7 +27,7 @@ class Package(SqlAlchemyBase): license: str = sa.Column(sa.String, index=True) # releases relationship - releases: List[Release] = orm.relation( + releases: Mapped[Release] = orm.relationship( 'Release', order_by=[ Release.major_ver.desc(), diff --git a/app/ch11_migrations/final/pypi_org/data/releases.py b/app/ch11_migrations/final/pypi_org/data/releases.py index 8596f65c..4b2db2bf 100644 --- a/app/ch11_migrations/final/pypi_org/data/releases.py +++ b/app/ch11_migrations/final/pypi_org/data/releases.py @@ -20,7 +20,7 @@ class Release(SqlAlchemyBase): # Package relationship package_id: str = sqlalchemy.Column(sqlalchemy.String, sqlalchemy.ForeignKey('packages.id')) - package = orm.relation('Package') + package = orm.relationship('Package') @property def version_text(self): diff --git a/app/ch11_migrations/final/pypi_org/infrastructure/num_convert.py b/app/ch11_migrations/final/pypi_org/infrastructure/num_convert.py new file mode 100644 index 00000000..4e1d8879 --- /dev/null +++ b/app/ch11_migrations/final/pypi_org/infrastructure/num_convert.py @@ -0,0 +1,8 @@ +from typing import Optional + + +def try_int(text) -> Optional[int]: + try: + return int(text) + except: + return None diff --git a/app/ch12-forms/final/pypi_org/data/package.py b/app/ch12-forms/final/pypi_org/data/package.py index 16e6d156..e0e48878 100644 --- a/app/ch12-forms/final/pypi_org/data/package.py +++ b/app/ch12-forms/final/pypi_org/data/package.py @@ -3,6 +3,8 @@ import sqlalchemy as sa import sqlalchemy.orm as orm +from sqlalchemy.orm import Mapped + from pypi_org.data.modelbase import SqlAlchemyBase from pypi_org.data.releases import Release @@ -12,7 +14,6 @@ class Package(SqlAlchemyBase): id: str = sa.Column(sa.String, primary_key=True) created_date: datetime.datetime = sa.Column(sa.DateTime, default=datetime.datetime.now, index=True) - last_updated: datetime.datetime = sa.Column(sa.DateTime, default=datetime.datetime.now, index=True) summary: str = sa.Column(sa.String, nullable=False) description: str = sa.Column(sa.String, nullable=True) @@ -26,7 +27,7 @@ class Package(SqlAlchemyBase): license: str = sa.Column(sa.String, index=True) # releases relationship - releases: List[Release] = orm.relation( + releases: Mapped[Release] = orm.relationship( 'Release', order_by=[ Release.major_ver.desc(), diff --git a/app/ch12-forms/final/pypi_org/data/releases.py b/app/ch12-forms/final/pypi_org/data/releases.py index 8596f65c..4b2db2bf 100644 --- a/app/ch12-forms/final/pypi_org/data/releases.py +++ b/app/ch12-forms/final/pypi_org/data/releases.py @@ -20,7 +20,7 @@ class Release(SqlAlchemyBase): # Package relationship package_id: str = sqlalchemy.Column(sqlalchemy.String, sqlalchemy.ForeignKey('packages.id')) - package = orm.relation('Package') + package = orm.relationship('Package') @property def version_text(self): From 5d27c638ccdd0f1b1b7ec2f4ab7d66952b2e497e Mon Sep 17 00:00:00 2001 From: Michael Kennedy Date: Tue, 12 Dec 2023 16:41:42 -0800 Subject: [PATCH 37/44] Update package and releases due to change with sqlalchemy 2.0. --- app/ch11_migrations/starter/pypi_org/data/package.py | 4 +++- app/ch11_migrations/starter/pypi_org/data/releases.py | 2 +- app/ch12-forms/starter/pypi_org/data/package.py | 5 +++-- app/ch12-forms/starter/pypi_org/data/releases.py | 2 +- 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/app/ch11_migrations/starter/pypi_org/data/package.py b/app/ch11_migrations/starter/pypi_org/data/package.py index 17fbf2f4..e0e48878 100644 --- a/app/ch11_migrations/starter/pypi_org/data/package.py +++ b/app/ch11_migrations/starter/pypi_org/data/package.py @@ -3,6 +3,8 @@ import sqlalchemy as sa import sqlalchemy.orm as orm +from sqlalchemy.orm import Mapped + from pypi_org.data.modelbase import SqlAlchemyBase from pypi_org.data.releases import Release @@ -25,7 +27,7 @@ class Package(SqlAlchemyBase): license: str = sa.Column(sa.String, index=True) # releases relationship - releases: List[Release] = orm.relation( + releases: Mapped[Release] = orm.relationship( 'Release', order_by=[ Release.major_ver.desc(), diff --git a/app/ch11_migrations/starter/pypi_org/data/releases.py b/app/ch11_migrations/starter/pypi_org/data/releases.py index 8596f65c..4b2db2bf 100644 --- a/app/ch11_migrations/starter/pypi_org/data/releases.py +++ b/app/ch11_migrations/starter/pypi_org/data/releases.py @@ -20,7 +20,7 @@ class Release(SqlAlchemyBase): # Package relationship package_id: str = sqlalchemy.Column(sqlalchemy.String, sqlalchemy.ForeignKey('packages.id')) - package = orm.relation('Package') + package = orm.relationship('Package') @property def version_text(self): diff --git a/app/ch12-forms/starter/pypi_org/data/package.py b/app/ch12-forms/starter/pypi_org/data/package.py index 16e6d156..e0e48878 100644 --- a/app/ch12-forms/starter/pypi_org/data/package.py +++ b/app/ch12-forms/starter/pypi_org/data/package.py @@ -3,6 +3,8 @@ import sqlalchemy as sa import sqlalchemy.orm as orm +from sqlalchemy.orm import Mapped + from pypi_org.data.modelbase import SqlAlchemyBase from pypi_org.data.releases import Release @@ -12,7 +14,6 @@ class Package(SqlAlchemyBase): id: str = sa.Column(sa.String, primary_key=True) created_date: datetime.datetime = sa.Column(sa.DateTime, default=datetime.datetime.now, index=True) - last_updated: datetime.datetime = sa.Column(sa.DateTime, default=datetime.datetime.now, index=True) summary: str = sa.Column(sa.String, nullable=False) description: str = sa.Column(sa.String, nullable=True) @@ -26,7 +27,7 @@ class Package(SqlAlchemyBase): license: str = sa.Column(sa.String, index=True) # releases relationship - releases: List[Release] = orm.relation( + releases: Mapped[Release] = orm.relationship( 'Release', order_by=[ Release.major_ver.desc(), diff --git a/app/ch12-forms/starter/pypi_org/data/releases.py b/app/ch12-forms/starter/pypi_org/data/releases.py index 8596f65c..4b2db2bf 100644 --- a/app/ch12-forms/starter/pypi_org/data/releases.py +++ b/app/ch12-forms/starter/pypi_org/data/releases.py @@ -20,7 +20,7 @@ class Release(SqlAlchemyBase): # Package relationship package_id: str = sqlalchemy.Column(sqlalchemy.String, sqlalchemy.ForeignKey('packages.id')) - package = orm.relation('Package') + package = orm.relationship('Package') @property def version_text(self): From e47b3ecf3830f2d28db1e718ecf260aa57aaa467 Mon Sep 17 00:00:00 2001 From: Michael Kennedy Date: Tue, 12 Dec 2023 16:49:44 -0800 Subject: [PATCH 38/44] Update package and releases due to change with sqlalchemy 2.0. --- .../final/pypi_org/bin/load_data.py | 2 +- .../final/pypi_org/data/package.py | 5 +- .../final/pypi_org/data/releases.py | 2 +- .../starter/pypi_org/bin/load_data.py | 8 +- .../starter/pypi_org/data/package.py | 5 +- .../starter/pypi_org/data/releases.py | 2 +- .../final/pypi_org/bin/load_data.py | 8 +- .../final/pypi_org/data/package.py | 5 +- .../final/pypi_org/data/releases.py | 2 +- .../starter/pypi_org/bin/load_data.py | 8 +- .../starter/pypi_org/data/package.py | 5 +- .../starter/pypi_org/data/releases.py | 2 +- .../final/pypi_org/bin/load_data.py | 8 +- .../final/pypi_org/data/package.py | 5 +- .../final/pypi_org/data/releases.py | 2 +- .../starter/pypi_org/bin/load_data.py | 8 +- .../starter/pypi_org/data/package.py | 5 +- .../starter/pypi_org/data/releases.py | 2 +- app/ch16_mongodb/final/alembic/README | 1 - .../final/alembic/alembic_helpers.py | 15 ---- app/ch16_mongodb/final/alembic/env.py | 83 ------------------- app/ch16_mongodb/final/alembic/script.py.mako | 24 ------ .../722c82f0097c_added_auditing_table.py | 36 -------- .../a55036d4e943_added_last_updated.py | 30 ------- .../final/pypi_org/data/package.py | 5 +- .../final/pypi_org/data/releases.py | 2 +- .../final/pypi_org/nosql/mongo_setup.py | 2 +- .../starter/pypi_org/data/package.py | 5 +- .../starter/pypi_org/data/releases.py | 2 +- 29 files changed, 39 insertions(+), 250 deletions(-) delete mode 100644 app/ch16_mongodb/final/alembic/README delete mode 100644 app/ch16_mongodb/final/alembic/alembic_helpers.py delete mode 100644 app/ch16_mongodb/final/alembic/env.py delete mode 100644 app/ch16_mongodb/final/alembic/script.py.mako delete mode 100644 app/ch16_mongodb/final/alembic/versions/722c82f0097c_added_auditing_table.py delete mode 100644 app/ch16_mongodb/final/alembic/versions/a55036d4e943_added_last_updated.py diff --git a/app/ch13-validation/final/pypi_org/bin/load_data.py b/app/ch13-validation/final/pypi_org/bin/load_data.py index d64cb582..3af7a03d 100644 --- a/app/ch13-validation/final/pypi_org/bin/load_data.py +++ b/app/ch13-validation/final/pypi_org/bin/load_data.py @@ -9,7 +9,7 @@ sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..'))) -from pypi_org.bin.load_data import try_int +from pypi_org.infrastructure.num_convert import try_int import pypi_org.data.db_session as db_session from pypi_org.data.languages import ProgrammingLanguage from pypi_org.data.licenses import License diff --git a/app/ch13-validation/final/pypi_org/data/package.py b/app/ch13-validation/final/pypi_org/data/package.py index 16e6d156..e0e48878 100644 --- a/app/ch13-validation/final/pypi_org/data/package.py +++ b/app/ch13-validation/final/pypi_org/data/package.py @@ -3,6 +3,8 @@ import sqlalchemy as sa import sqlalchemy.orm as orm +from sqlalchemy.orm import Mapped + from pypi_org.data.modelbase import SqlAlchemyBase from pypi_org.data.releases import Release @@ -12,7 +14,6 @@ class Package(SqlAlchemyBase): id: str = sa.Column(sa.String, primary_key=True) created_date: datetime.datetime = sa.Column(sa.DateTime, default=datetime.datetime.now, index=True) - last_updated: datetime.datetime = sa.Column(sa.DateTime, default=datetime.datetime.now, index=True) summary: str = sa.Column(sa.String, nullable=False) description: str = sa.Column(sa.String, nullable=True) @@ -26,7 +27,7 @@ class Package(SqlAlchemyBase): license: str = sa.Column(sa.String, index=True) # releases relationship - releases: List[Release] = orm.relation( + releases: Mapped[Release] = orm.relationship( 'Release', order_by=[ Release.major_ver.desc(), diff --git a/app/ch13-validation/final/pypi_org/data/releases.py b/app/ch13-validation/final/pypi_org/data/releases.py index 8596f65c..4b2db2bf 100644 --- a/app/ch13-validation/final/pypi_org/data/releases.py +++ b/app/ch13-validation/final/pypi_org/data/releases.py @@ -20,7 +20,7 @@ class Release(SqlAlchemyBase): # Package relationship package_id: str = sqlalchemy.Column(sqlalchemy.String, sqlalchemy.ForeignKey('packages.id')) - package = orm.relation('Package') + package = orm.relationship('Package') @property def version_text(self): diff --git a/app/ch13-validation/starter/pypi_org/bin/load_data.py b/app/ch13-validation/starter/pypi_org/bin/load_data.py index 228c1b6b..3af7a03d 100644 --- a/app/ch13-validation/starter/pypi_org/bin/load_data.py +++ b/app/ch13-validation/starter/pypi_org/bin/load_data.py @@ -9,6 +9,7 @@ sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..'))) +from pypi_org.infrastructure.num_convert import try_int import pypi_org.data.db_session as db_session from pypi_org.data.languages import ProgrammingLanguage from pypi_org.data.licenses import License @@ -333,13 +334,6 @@ def make_version_num(version_text): return major, minor, build -def try_int(text) -> Optional[int]: - try: - return int(text) - except: - return None - - def init_db(): top_folder = os.path.dirname(__file__) rel_file = os.path.join('..', 'db', 'pypi.sqlite') diff --git a/app/ch13-validation/starter/pypi_org/data/package.py b/app/ch13-validation/starter/pypi_org/data/package.py index 16e6d156..e0e48878 100644 --- a/app/ch13-validation/starter/pypi_org/data/package.py +++ b/app/ch13-validation/starter/pypi_org/data/package.py @@ -3,6 +3,8 @@ import sqlalchemy as sa import sqlalchemy.orm as orm +from sqlalchemy.orm import Mapped + from pypi_org.data.modelbase import SqlAlchemyBase from pypi_org.data.releases import Release @@ -12,7 +14,6 @@ class Package(SqlAlchemyBase): id: str = sa.Column(sa.String, primary_key=True) created_date: datetime.datetime = sa.Column(sa.DateTime, default=datetime.datetime.now, index=True) - last_updated: datetime.datetime = sa.Column(sa.DateTime, default=datetime.datetime.now, index=True) summary: str = sa.Column(sa.String, nullable=False) description: str = sa.Column(sa.String, nullable=True) @@ -26,7 +27,7 @@ class Package(SqlAlchemyBase): license: str = sa.Column(sa.String, index=True) # releases relationship - releases: List[Release] = orm.relation( + releases: Mapped[Release] = orm.relationship( 'Release', order_by=[ Release.major_ver.desc(), diff --git a/app/ch13-validation/starter/pypi_org/data/releases.py b/app/ch13-validation/starter/pypi_org/data/releases.py index 8596f65c..4b2db2bf 100644 --- a/app/ch13-validation/starter/pypi_org/data/releases.py +++ b/app/ch13-validation/starter/pypi_org/data/releases.py @@ -20,7 +20,7 @@ class Release(SqlAlchemyBase): # Package relationship package_id: str = sqlalchemy.Column(sqlalchemy.String, sqlalchemy.ForeignKey('packages.id')) - package = orm.relation('Package') + package = orm.relationship('Package') @property def version_text(self): diff --git a/app/ch14_testing/final/pypi_org/bin/load_data.py b/app/ch14_testing/final/pypi_org/bin/load_data.py index 228c1b6b..3af7a03d 100644 --- a/app/ch14_testing/final/pypi_org/bin/load_data.py +++ b/app/ch14_testing/final/pypi_org/bin/load_data.py @@ -9,6 +9,7 @@ sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..'))) +from pypi_org.infrastructure.num_convert import try_int import pypi_org.data.db_session as db_session from pypi_org.data.languages import ProgrammingLanguage from pypi_org.data.licenses import License @@ -333,13 +334,6 @@ def make_version_num(version_text): return major, minor, build -def try_int(text) -> Optional[int]: - try: - return int(text) - except: - return None - - def init_db(): top_folder = os.path.dirname(__file__) rel_file = os.path.join('..', 'db', 'pypi.sqlite') diff --git a/app/ch14_testing/final/pypi_org/data/package.py b/app/ch14_testing/final/pypi_org/data/package.py index 16e6d156..e0e48878 100644 --- a/app/ch14_testing/final/pypi_org/data/package.py +++ b/app/ch14_testing/final/pypi_org/data/package.py @@ -3,6 +3,8 @@ import sqlalchemy as sa import sqlalchemy.orm as orm +from sqlalchemy.orm import Mapped + from pypi_org.data.modelbase import SqlAlchemyBase from pypi_org.data.releases import Release @@ -12,7 +14,6 @@ class Package(SqlAlchemyBase): id: str = sa.Column(sa.String, primary_key=True) created_date: datetime.datetime = sa.Column(sa.DateTime, default=datetime.datetime.now, index=True) - last_updated: datetime.datetime = sa.Column(sa.DateTime, default=datetime.datetime.now, index=True) summary: str = sa.Column(sa.String, nullable=False) description: str = sa.Column(sa.String, nullable=True) @@ -26,7 +27,7 @@ class Package(SqlAlchemyBase): license: str = sa.Column(sa.String, index=True) # releases relationship - releases: List[Release] = orm.relation( + releases: Mapped[Release] = orm.relationship( 'Release', order_by=[ Release.major_ver.desc(), diff --git a/app/ch14_testing/final/pypi_org/data/releases.py b/app/ch14_testing/final/pypi_org/data/releases.py index 8596f65c..4b2db2bf 100644 --- a/app/ch14_testing/final/pypi_org/data/releases.py +++ b/app/ch14_testing/final/pypi_org/data/releases.py @@ -20,7 +20,7 @@ class Release(SqlAlchemyBase): # Package relationship package_id: str = sqlalchemy.Column(sqlalchemy.String, sqlalchemy.ForeignKey('packages.id')) - package = orm.relation('Package') + package = orm.relationship('Package') @property def version_text(self): diff --git a/app/ch14_testing/starter/pypi_org/bin/load_data.py b/app/ch14_testing/starter/pypi_org/bin/load_data.py index 228c1b6b..3af7a03d 100644 --- a/app/ch14_testing/starter/pypi_org/bin/load_data.py +++ b/app/ch14_testing/starter/pypi_org/bin/load_data.py @@ -9,6 +9,7 @@ sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..'))) +from pypi_org.infrastructure.num_convert import try_int import pypi_org.data.db_session as db_session from pypi_org.data.languages import ProgrammingLanguage from pypi_org.data.licenses import License @@ -333,13 +334,6 @@ def make_version_num(version_text): return major, minor, build -def try_int(text) -> Optional[int]: - try: - return int(text) - except: - return None - - def init_db(): top_folder = os.path.dirname(__file__) rel_file = os.path.join('..', 'db', 'pypi.sqlite') diff --git a/app/ch14_testing/starter/pypi_org/data/package.py b/app/ch14_testing/starter/pypi_org/data/package.py index 16e6d156..e0e48878 100644 --- a/app/ch14_testing/starter/pypi_org/data/package.py +++ b/app/ch14_testing/starter/pypi_org/data/package.py @@ -3,6 +3,8 @@ import sqlalchemy as sa import sqlalchemy.orm as orm +from sqlalchemy.orm import Mapped + from pypi_org.data.modelbase import SqlAlchemyBase from pypi_org.data.releases import Release @@ -12,7 +14,6 @@ class Package(SqlAlchemyBase): id: str = sa.Column(sa.String, primary_key=True) created_date: datetime.datetime = sa.Column(sa.DateTime, default=datetime.datetime.now, index=True) - last_updated: datetime.datetime = sa.Column(sa.DateTime, default=datetime.datetime.now, index=True) summary: str = sa.Column(sa.String, nullable=False) description: str = sa.Column(sa.String, nullable=True) @@ -26,7 +27,7 @@ class Package(SqlAlchemyBase): license: str = sa.Column(sa.String, index=True) # releases relationship - releases: List[Release] = orm.relation( + releases: Mapped[Release] = orm.relationship( 'Release', order_by=[ Release.major_ver.desc(), diff --git a/app/ch14_testing/starter/pypi_org/data/releases.py b/app/ch14_testing/starter/pypi_org/data/releases.py index 8596f65c..4b2db2bf 100644 --- a/app/ch14_testing/starter/pypi_org/data/releases.py +++ b/app/ch14_testing/starter/pypi_org/data/releases.py @@ -20,7 +20,7 @@ class Release(SqlAlchemyBase): # Package relationship package_id: str = sqlalchemy.Column(sqlalchemy.String, sqlalchemy.ForeignKey('packages.id')) - package = orm.relation('Package') + package = orm.relationship('Package') @property def version_text(self): diff --git a/app/ch15_deploy/final/pypi_org/bin/load_data.py b/app/ch15_deploy/final/pypi_org/bin/load_data.py index 228c1b6b..3af7a03d 100644 --- a/app/ch15_deploy/final/pypi_org/bin/load_data.py +++ b/app/ch15_deploy/final/pypi_org/bin/load_data.py @@ -9,6 +9,7 @@ sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..'))) +from pypi_org.infrastructure.num_convert import try_int import pypi_org.data.db_session as db_session from pypi_org.data.languages import ProgrammingLanguage from pypi_org.data.licenses import License @@ -333,13 +334,6 @@ def make_version_num(version_text): return major, minor, build -def try_int(text) -> Optional[int]: - try: - return int(text) - except: - return None - - def init_db(): top_folder = os.path.dirname(__file__) rel_file = os.path.join('..', 'db', 'pypi.sqlite') diff --git a/app/ch15_deploy/final/pypi_org/data/package.py b/app/ch15_deploy/final/pypi_org/data/package.py index 16e6d156..e0e48878 100644 --- a/app/ch15_deploy/final/pypi_org/data/package.py +++ b/app/ch15_deploy/final/pypi_org/data/package.py @@ -3,6 +3,8 @@ import sqlalchemy as sa import sqlalchemy.orm as orm +from sqlalchemy.orm import Mapped + from pypi_org.data.modelbase import SqlAlchemyBase from pypi_org.data.releases import Release @@ -12,7 +14,6 @@ class Package(SqlAlchemyBase): id: str = sa.Column(sa.String, primary_key=True) created_date: datetime.datetime = sa.Column(sa.DateTime, default=datetime.datetime.now, index=True) - last_updated: datetime.datetime = sa.Column(sa.DateTime, default=datetime.datetime.now, index=True) summary: str = sa.Column(sa.String, nullable=False) description: str = sa.Column(sa.String, nullable=True) @@ -26,7 +27,7 @@ class Package(SqlAlchemyBase): license: str = sa.Column(sa.String, index=True) # releases relationship - releases: List[Release] = orm.relation( + releases: Mapped[Release] = orm.relationship( 'Release', order_by=[ Release.major_ver.desc(), diff --git a/app/ch15_deploy/final/pypi_org/data/releases.py b/app/ch15_deploy/final/pypi_org/data/releases.py index 8596f65c..4b2db2bf 100644 --- a/app/ch15_deploy/final/pypi_org/data/releases.py +++ b/app/ch15_deploy/final/pypi_org/data/releases.py @@ -20,7 +20,7 @@ class Release(SqlAlchemyBase): # Package relationship package_id: str = sqlalchemy.Column(sqlalchemy.String, sqlalchemy.ForeignKey('packages.id')) - package = orm.relation('Package') + package = orm.relationship('Package') @property def version_text(self): diff --git a/app/ch15_deploy/starter/pypi_org/bin/load_data.py b/app/ch15_deploy/starter/pypi_org/bin/load_data.py index 228c1b6b..3af7a03d 100644 --- a/app/ch15_deploy/starter/pypi_org/bin/load_data.py +++ b/app/ch15_deploy/starter/pypi_org/bin/load_data.py @@ -9,6 +9,7 @@ sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..'))) +from pypi_org.infrastructure.num_convert import try_int import pypi_org.data.db_session as db_session from pypi_org.data.languages import ProgrammingLanguage from pypi_org.data.licenses import License @@ -333,13 +334,6 @@ def make_version_num(version_text): return major, minor, build -def try_int(text) -> Optional[int]: - try: - return int(text) - except: - return None - - def init_db(): top_folder = os.path.dirname(__file__) rel_file = os.path.join('..', 'db', 'pypi.sqlite') diff --git a/app/ch15_deploy/starter/pypi_org/data/package.py b/app/ch15_deploy/starter/pypi_org/data/package.py index 16e6d156..e0e48878 100644 --- a/app/ch15_deploy/starter/pypi_org/data/package.py +++ b/app/ch15_deploy/starter/pypi_org/data/package.py @@ -3,6 +3,8 @@ import sqlalchemy as sa import sqlalchemy.orm as orm +from sqlalchemy.orm import Mapped + from pypi_org.data.modelbase import SqlAlchemyBase from pypi_org.data.releases import Release @@ -12,7 +14,6 @@ class Package(SqlAlchemyBase): id: str = sa.Column(sa.String, primary_key=True) created_date: datetime.datetime = sa.Column(sa.DateTime, default=datetime.datetime.now, index=True) - last_updated: datetime.datetime = sa.Column(sa.DateTime, default=datetime.datetime.now, index=True) summary: str = sa.Column(sa.String, nullable=False) description: str = sa.Column(sa.String, nullable=True) @@ -26,7 +27,7 @@ class Package(SqlAlchemyBase): license: str = sa.Column(sa.String, index=True) # releases relationship - releases: List[Release] = orm.relation( + releases: Mapped[Release] = orm.relationship( 'Release', order_by=[ Release.major_ver.desc(), diff --git a/app/ch15_deploy/starter/pypi_org/data/releases.py b/app/ch15_deploy/starter/pypi_org/data/releases.py index 8596f65c..4b2db2bf 100644 --- a/app/ch15_deploy/starter/pypi_org/data/releases.py +++ b/app/ch15_deploy/starter/pypi_org/data/releases.py @@ -20,7 +20,7 @@ class Release(SqlAlchemyBase): # Package relationship package_id: str = sqlalchemy.Column(sqlalchemy.String, sqlalchemy.ForeignKey('packages.id')) - package = orm.relation('Package') + package = orm.relationship('Package') @property def version_text(self): diff --git a/app/ch16_mongodb/final/alembic/README b/app/ch16_mongodb/final/alembic/README deleted file mode 100644 index 98e4f9c4..00000000 --- a/app/ch16_mongodb/final/alembic/README +++ /dev/null @@ -1 +0,0 @@ -Generic single-database configuration. \ No newline at end of file diff --git a/app/ch16_mongodb/final/alembic/alembic_helpers.py b/app/ch16_mongodb/final/alembic/alembic_helpers.py deleted file mode 100644 index 6aea52d4..00000000 --- a/app/ch16_mongodb/final/alembic/alembic_helpers.py +++ /dev/null @@ -1,15 +0,0 @@ -from alembic import op -from sqlalchemy import engine_from_config -from sqlalchemy.engine import reflection - - -def table_has_column(table, column): - config = op.get_context().config - engine = engine_from_config(config.get_section(config.config_ini_section), prefix='sqlalchemy.') - insp = reflection.Inspector.from_engine(engine) - has_column = False - for col in insp.get_columns(table): - if column not in col['name']: - continue - has_column = True - return has_column diff --git a/app/ch16_mongodb/final/alembic/env.py b/app/ch16_mongodb/final/alembic/env.py deleted file mode 100644 index 1fdc9cab..00000000 --- a/app/ch16_mongodb/final/alembic/env.py +++ /dev/null @@ -1,83 +0,0 @@ -import os -from logging.config import fileConfig - -from sqlalchemy import engine_from_config -from sqlalchemy import pool - -from alembic import context - -# this is the Alembic Config object, which provides -# access to the values within the .ini file in use. - -config = context.config - -# Interpret the config file for Python logging. -# This line sets up loggers basically. -fileConfig(config.config_file_name) - -# add your model's MetaData object here -# for 'autogenerate' support -# from myapp import mymodel -# target_metadata = mymodel.Base.metadata - -import sys - -folder = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) -sys.path.insert(0, folder) - -from pypi_org.data.modelbase import SqlAlchemyBase - -# noinspection PyUnresolvedReferences -import pypi_org.data.__all_models - -target_metadata = SqlAlchemyBase.metadata - -# other values from the config, defined by the needs of env.py, -# can be acquired: -# my_important_option = config.get_main_option("my_important_option") -# ... etc. - - -def run_migrations_offline(): - """Run migrations in 'offline' mode. - - This configures the context with just a URL - and not an Engine, though an Engine is acceptable - here as well. By skipping the Engine creation - we don't even need a DBAPI to be available. - - Calls to context.execute() here emit the given string to the - script output. - - """ - url = config.get_main_option('sqlalchemy.url') - context.configure(url=url, target_metadata=target_metadata, literal_binds=True) - - with context.begin_transaction(): - context.run_migrations() - - -def run_migrations_online(): - """Run migrations in 'online' mode. - - In this scenario we need to create an Engine - and associate a connection with the context. - - """ - connectable = engine_from_config( - config.get_section(config.config_ini_section), - prefix='sqlalchemy.', - poolclass=pool.NullPool, - ) - - with connectable.connect() as connection: - context.configure(connection=connection, target_metadata=target_metadata) - - with context.begin_transaction(): - context.run_migrations() - - -if context.is_offline_mode(): - run_migrations_offline() -else: - run_migrations_online() diff --git a/app/ch16_mongodb/final/alembic/script.py.mako b/app/ch16_mongodb/final/alembic/script.py.mako deleted file mode 100644 index 2c015630..00000000 --- a/app/ch16_mongodb/final/alembic/script.py.mako +++ /dev/null @@ -1,24 +0,0 @@ -"""${message} - -Revision ID: ${up_revision} -Revises: ${down_revision | comma,n} -Create Date: ${create_date} - -""" -from alembic import op -import sqlalchemy as sa -${imports if imports else ""} - -# revision identifiers, used by Alembic. -revision = ${repr(up_revision)} -down_revision = ${repr(down_revision)} -branch_labels = ${repr(branch_labels)} -depends_on = ${repr(depends_on)} - - -def upgrade(): - ${upgrades if upgrades else "pass"} - - -def downgrade(): - ${downgrades if downgrades else "pass"} diff --git a/app/ch16_mongodb/final/alembic/versions/722c82f0097c_added_auditing_table.py b/app/ch16_mongodb/final/alembic/versions/722c82f0097c_added_auditing_table.py deleted file mode 100644 index 7c6e892f..00000000 --- a/app/ch16_mongodb/final/alembic/versions/722c82f0097c_added_auditing_table.py +++ /dev/null @@ -1,36 +0,0 @@ -"""Added Auditing table - -Revision ID: 722c82f0097c -Revises: a55036d4e943 -Create Date: 2019-05-16 11:16:42.514539 - -""" -from alembic import op -import sqlalchemy as sa - - -# revision identifiers, used by Alembic. -revision = '722c82f0097c' -down_revision = 'a55036d4e943' -branch_labels = None -depends_on = None - - -def upgrade(): - # ### commands auto generated by Alembic - please adjust! ### - op.create_table( - 'auditing', - sa.Column('id', sa.String(), nullable=False), - sa.Column('created_date', sa.DateTime(), nullable=True), - sa.Column('description', sa.String(), nullable=True), - sa.PrimaryKeyConstraint('id'), - ) - op.create_index(op.f('ix_auditing_created_date'), 'auditing', ['created_date'], unique=False) - # ### end Alembic commands ### - - -def downgrade(): - # ### commands auto generated by Alembic - please adjust! ### - op.drop_index(op.f('ix_auditing_created_date'), table_name='auditing') - op.drop_table('auditing') - # ### end Alembic commands ### diff --git a/app/ch16_mongodb/final/alembic/versions/a55036d4e943_added_last_updated.py b/app/ch16_mongodb/final/alembic/versions/a55036d4e943_added_last_updated.py deleted file mode 100644 index 074ce04a..00000000 --- a/app/ch16_mongodb/final/alembic/versions/a55036d4e943_added_last_updated.py +++ /dev/null @@ -1,30 +0,0 @@ -"""Added last updated - -Revision ID: a55036d4e943 -Revises: -Create Date: 2019-05-16 10:55:28.413573 - -""" -from alembic import op -import sqlalchemy as sa - - -# revision identifiers, used by Alembic. -revision = 'a55036d4e943' -down_revision = None -branch_labels = None -depends_on = None - - -def upgrade(): - # ### commands auto generated by Alembic - please adjust! ### - op.add_column('packages', sa.Column('last_updated', sa.DateTime(), nullable=True)) - op.create_index(op.f('ix_packages_last_updated'), 'packages', ['last_updated'], unique=False) - # ### end Alembic commands ### - - -def downgrade(): - # ### commands auto generated by Alembic - please adjust! ### - op.drop_index(op.f('ix_packages_last_updated'), table_name='packages') - op.drop_column('packages', 'last_updated') - # ### end Alembic commands ### diff --git a/app/ch16_mongodb/final/pypi_org/data/package.py b/app/ch16_mongodb/final/pypi_org/data/package.py index 16e6d156..e0e48878 100644 --- a/app/ch16_mongodb/final/pypi_org/data/package.py +++ b/app/ch16_mongodb/final/pypi_org/data/package.py @@ -3,6 +3,8 @@ import sqlalchemy as sa import sqlalchemy.orm as orm +from sqlalchemy.orm import Mapped + from pypi_org.data.modelbase import SqlAlchemyBase from pypi_org.data.releases import Release @@ -12,7 +14,6 @@ class Package(SqlAlchemyBase): id: str = sa.Column(sa.String, primary_key=True) created_date: datetime.datetime = sa.Column(sa.DateTime, default=datetime.datetime.now, index=True) - last_updated: datetime.datetime = sa.Column(sa.DateTime, default=datetime.datetime.now, index=True) summary: str = sa.Column(sa.String, nullable=False) description: str = sa.Column(sa.String, nullable=True) @@ -26,7 +27,7 @@ class Package(SqlAlchemyBase): license: str = sa.Column(sa.String, index=True) # releases relationship - releases: List[Release] = orm.relation( + releases: Mapped[Release] = orm.relationship( 'Release', order_by=[ Release.major_ver.desc(), diff --git a/app/ch16_mongodb/final/pypi_org/data/releases.py b/app/ch16_mongodb/final/pypi_org/data/releases.py index 8596f65c..4b2db2bf 100644 --- a/app/ch16_mongodb/final/pypi_org/data/releases.py +++ b/app/ch16_mongodb/final/pypi_org/data/releases.py @@ -20,7 +20,7 @@ class Release(SqlAlchemyBase): # Package relationship package_id: str = sqlalchemy.Column(sqlalchemy.String, sqlalchemy.ForeignKey('packages.id')) - package = orm.relation('Package') + package = orm.relationship('Package') @property def version_text(self): diff --git a/app/ch16_mongodb/final/pypi_org/nosql/mongo_setup.py b/app/ch16_mongodb/final/pypi_org/nosql/mongo_setup.py index 4fb8a8ae..b0e9ecbc 100644 --- a/app/ch16_mongodb/final/pypi_org/nosql/mongo_setup.py +++ b/app/ch16_mongodb/final/pypi_org/nosql/mongo_setup.py @@ -3,7 +3,7 @@ import mongoengine -def global_init(user=None, password=None, port=27017, server='localhost', use_ssl=True, db_name='pypi'): +def global_init(user=None, password=None, port=27017, server='localhost', use_ssl=True, db_name='pypi-flask-data-driven'): if user or password: # noinspection PyUnresolvedReferences data = dict( diff --git a/app/ch16_mongodb/starter/pypi_org/data/package.py b/app/ch16_mongodb/starter/pypi_org/data/package.py index 16e6d156..e0e48878 100644 --- a/app/ch16_mongodb/starter/pypi_org/data/package.py +++ b/app/ch16_mongodb/starter/pypi_org/data/package.py @@ -3,6 +3,8 @@ import sqlalchemy as sa import sqlalchemy.orm as orm +from sqlalchemy.orm import Mapped + from pypi_org.data.modelbase import SqlAlchemyBase from pypi_org.data.releases import Release @@ -12,7 +14,6 @@ class Package(SqlAlchemyBase): id: str = sa.Column(sa.String, primary_key=True) created_date: datetime.datetime = sa.Column(sa.DateTime, default=datetime.datetime.now, index=True) - last_updated: datetime.datetime = sa.Column(sa.DateTime, default=datetime.datetime.now, index=True) summary: str = sa.Column(sa.String, nullable=False) description: str = sa.Column(sa.String, nullable=True) @@ -26,7 +27,7 @@ class Package(SqlAlchemyBase): license: str = sa.Column(sa.String, index=True) # releases relationship - releases: List[Release] = orm.relation( + releases: Mapped[Release] = orm.relationship( 'Release', order_by=[ Release.major_ver.desc(), diff --git a/app/ch16_mongodb/starter/pypi_org/data/releases.py b/app/ch16_mongodb/starter/pypi_org/data/releases.py index 8596f65c..4b2db2bf 100644 --- a/app/ch16_mongodb/starter/pypi_org/data/releases.py +++ b/app/ch16_mongodb/starter/pypi_org/data/releases.py @@ -20,7 +20,7 @@ class Release(SqlAlchemyBase): # Package relationship package_id: str = sqlalchemy.Column(sqlalchemy.String, sqlalchemy.ForeignKey('packages.id')) - package = orm.relation('Package') + package = orm.relationship('Package') @property def version_text(self): From 48cf78fc8e00944fe1a32902660faa5da409f01f Mon Sep 17 00:00:00 2001 From: Michael Kennedy Date: Tue, 12 Dec 2023 16:52:43 -0800 Subject: [PATCH 39/44] Update package and releases due to change with sqlalchemy 2.0. --- app/ch16_mongodb/final/pypi_org/nosql/mongo_setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/ch16_mongodb/final/pypi_org/nosql/mongo_setup.py b/app/ch16_mongodb/final/pypi_org/nosql/mongo_setup.py index b0e9ecbc..4fb8a8ae 100644 --- a/app/ch16_mongodb/final/pypi_org/nosql/mongo_setup.py +++ b/app/ch16_mongodb/final/pypi_org/nosql/mongo_setup.py @@ -3,7 +3,7 @@ import mongoengine -def global_init(user=None, password=None, port=27017, server='localhost', use_ssl=True, db_name='pypi-flask-data-driven'): +def global_init(user=None, password=None, port=27017, server='localhost', use_ssl=True, db_name='pypi'): if user or password: # noinspection PyUnresolvedReferences data = dict( From 552fdbfd4463e335991a07979c69f1304497bab6 Mon Sep 17 00:00:00 2001 From: Michael Kennedy Date: Tue, 12 Dec 2023 16:52:57 -0800 Subject: [PATCH 40/44] Update to latest let's encrypt / certbot steps. --- app/ch15_deploy/final/server/server_setup.sh | 26 +++++++++++++++++--- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/app/ch15_deploy/final/server/server_setup.sh b/app/ch15_deploy/final/server/server_setup.sh index 16842e59..013ea4b4 100644 --- a/app/ch15_deploy/final/server/server_setup.sh +++ b/app/ch15_deploy/final/server/server_setup.sh @@ -74,9 +74,27 @@ update-rc.d nginx enable service nginx restart -# Optionally add SSL support via Let's Encrypt: -# https://www.digitalocean.com/community/tutorials/how-to-secure-nginx-with-let-s-encrypt-on-ubuntu-18-04 +# Optionally add SSL support via Let's Encrypt +# NOTE: These steps have changed since the recording. -add-apt-repository ppa:certbot/certbot -apt install python-certbot-nginx +####### NEW STEPS ############################################### +# See https://certbot.eff.org/instructions?ws=nginx&os=ubuntufocal&tab=standard + +# Because always a good idea :) +apt update +apt upgrade + +# Not need even though it's in the instructions, is installed on Ubuntu +# Skip -> install snapd https://snapcraft.io/docs/installing-snapd + +snap install --classic certbot +ln -s /snap/bin/certbot /usr/bin/certbot certbot --nginx -d fakepypi.talkpython.com + +####### THESE ARE THE OLD STEPS ################################# +# +## https://www.digitalocean.com/community/tutorials/how-to-secure-nginx-with-let-s-encrypt-on-ubuntu-18-04 +# +#add-apt-repository ppa:certbot/certbot +#apt install python-certbot-nginx +#certbot --nginx -d fakepypi.talkpython.com From 1fb22f30a2a7562c53699e2b62cb6c1cf9428b05 Mon Sep 17 00:00:00 2001 From: Michael Kennedy Date: Tue, 27 Aug 2024 14:28:45 -0700 Subject: [PATCH 41/44] Update to latest versions of libraries. --- .idea/ruff.xml | 1 + requirements.txt | 40 ++++++++++++++++++---------------------- 2 files changed, 19 insertions(+), 22 deletions(-) diff --git a/.idea/ruff.xml b/.idea/ruff.xml index 5aa89c50..100ae2fc 100644 --- a/.idea/ruff.xml +++ b/.idea/ruff.xml @@ -1,6 +1,7 @@ + \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index 85b126c8..42fb216b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,52 +1,48 @@ -# -# This file is autogenerated by pip-compile with Python 3.11 -# by the following command: -# -# pip-compile requirements.piptools -# -alembic==1.13.0 +# This file was autogenerated by uv via the following command: +# uv pip compile requirements.piptools --output-file requirements.txt +alembic==1.13.2 # via -r requirements.piptools -blinker==1.7.0 +blinker==1.8.2 # via flask click==8.1.7 # via flask -dnspython==2.4.2 +dnspython==2.6.1 # via pymongo -flask==3.0.0 +flask==3.0.3 # via -r requirements.piptools -itsdangerous==2.1.2 +itsdangerous==2.2.0 # via flask -jinja2==3.1.2 +jinja2==3.1.4 # via flask -mako==1.3.0 +mako==1.3.5 # via alembic -markupsafe==2.1.3 +markupsafe==2.1.5 # via # jinja2 # mako # werkzeug -mongoengine==0.27.0 +mongoengine==0.29.0 # via -r requirements.piptools passlib==1.7.4 # via -r requirements.piptools -progressbar2==4.2.0 +progressbar2==4.4.2 # via -r requirements.piptools -pymongo==4.6.1 +pymongo==4.8.0 # via mongoengine -python-dateutil==2.8.2 +python-dateutil==2.9.0.post0 # via -r requirements.piptools -python-utils==3.8.1 +python-utils==3.8.2 # via progressbar2 six==1.16.0 # via python-dateutil -sqlalchemy==2.0.23 +sqlalchemy==2.0.32 # via # -r requirements.piptools # alembic -typing-extensions==4.9.0 +typing-extensions==4.12.2 # via # alembic # python-utils # sqlalchemy -werkzeug==3.0.1 +werkzeug==3.0.4 # via flask From d64317a7e91f6b5311fc12049bdb6e66da7ed0a4 Mon Sep 17 00:00:00 2001 From: Michael Kennedy Date: Wed, 28 Aug 2024 09:20:52 -0700 Subject: [PATCH 42/44] Update to latest versions of libraries and patch up some changes needed for the code. --- .../first_site/requirements.txt | 20 +++++------ .../final/requirements.txt | 20 +++++------ app/ch06_routing/final/requirements.txt | 20 +++++------ app/ch06_routing/starter/requirements.txt | 20 +++++------ .../final/requirements.txt | 20 +++++------ .../starter/requirements.txt | 20 +++++------ app/ch09_sqlalchemy/final/requirements.txt | 24 ++++++------- app/ch09_sqlalchemy/starter/requirements.txt | 20 +++++------ .../final/pypi_org/views/package_views.py | 2 +- .../final/requirements.txt | 30 +++++++--------- .../starter/requirements.txt | 24 ++++++------- .../final/pypi_org/views/package_views.py | 2 +- app/ch11_migrations/final/requirements.txt | 34 ++++++++----------- .../starter/pypi_org/views/package_views.py | 2 +- app/ch11_migrations/starter/requirements.txt | 30 +++++++--------- .../final/pypi_org/views/package_views.py | 2 +- app/ch12-forms/final/requirements.txt | 34 ++++++++----------- .../starter/pypi_org/views/package_views.py | 2 +- app/ch12-forms/starter/requirements.txt | 34 ++++++++----------- .../packages/pagedetails_viewmodel.py | 2 +- app/ch13-validation/final/requirements.txt | 34 ++++++++----------- .../starter/pypi_org/views/package_views.py | 2 +- app/ch13-validation/starter/requirements.txt | 34 ++++++++----------- .../packages/pagedetails_viewmodel.py | 2 +- app/ch14_testing/final/requirements.txt | 34 ++++++++----------- .../packages/pagedetails_viewmodel.py | 2 +- app/ch14_testing/starter/requirements.txt | 34 ++++++++----------- .../packages/pagedetails_viewmodel.py | 2 +- app/ch15_deploy/final/requirements.txt | 34 ++++++++----------- .../packages/pagedetails_viewmodel.py | 2 +- app/ch15_deploy/starter/requirements.txt | 34 ++++++++----------- 31 files changed, 248 insertions(+), 328 deletions(-) diff --git a/app/ch04_first_site/first_site_final/first_site/requirements.txt b/app/ch04_first_site/first_site_final/first_site/requirements.txt index 12e1f645..1603e3f2 100644 --- a/app/ch04_first_site/first_site_final/first_site/requirements.txt +++ b/app/ch04_first_site/first_site_final/first_site/requirements.txt @@ -1,22 +1,18 @@ -# -# This file is autogenerated by pip-compile with Python 3.12 -# by the following command: -# -# pip-compile requirements.piptools -# -blinker==1.7.0 +# This file was autogenerated by uv via the following command: +# uv pip compile requirements.piptools --output-file requirements.txt +blinker==1.8.2 # via flask click==8.1.7 # via flask -flask==3.0.0 +flask==3.0.3 # via -r requirements.piptools -itsdangerous==2.1.2 +itsdangerous==2.2.0 # via flask -jinja2==3.1.2 +jinja2==3.1.4 # via flask -markupsafe==2.1.3 +markupsafe==2.1.5 # via # jinja2 # werkzeug -werkzeug==3.0.1 +werkzeug==3.0.4 # via flask diff --git a/app/ch05_jinja_templates/final/requirements.txt b/app/ch05_jinja_templates/final/requirements.txt index 12e1f645..1603e3f2 100644 --- a/app/ch05_jinja_templates/final/requirements.txt +++ b/app/ch05_jinja_templates/final/requirements.txt @@ -1,22 +1,18 @@ -# -# This file is autogenerated by pip-compile with Python 3.12 -# by the following command: -# -# pip-compile requirements.piptools -# -blinker==1.7.0 +# This file was autogenerated by uv via the following command: +# uv pip compile requirements.piptools --output-file requirements.txt +blinker==1.8.2 # via flask click==8.1.7 # via flask -flask==3.0.0 +flask==3.0.3 # via -r requirements.piptools -itsdangerous==2.1.2 +itsdangerous==2.2.0 # via flask -jinja2==3.1.2 +jinja2==3.1.4 # via flask -markupsafe==2.1.3 +markupsafe==2.1.5 # via # jinja2 # werkzeug -werkzeug==3.0.1 +werkzeug==3.0.4 # via flask diff --git a/app/ch06_routing/final/requirements.txt b/app/ch06_routing/final/requirements.txt index 12e1f645..1603e3f2 100644 --- a/app/ch06_routing/final/requirements.txt +++ b/app/ch06_routing/final/requirements.txt @@ -1,22 +1,18 @@ -# -# This file is autogenerated by pip-compile with Python 3.12 -# by the following command: -# -# pip-compile requirements.piptools -# -blinker==1.7.0 +# This file was autogenerated by uv via the following command: +# uv pip compile requirements.piptools --output-file requirements.txt +blinker==1.8.2 # via flask click==8.1.7 # via flask -flask==3.0.0 +flask==3.0.3 # via -r requirements.piptools -itsdangerous==2.1.2 +itsdangerous==2.2.0 # via flask -jinja2==3.1.2 +jinja2==3.1.4 # via flask -markupsafe==2.1.3 +markupsafe==2.1.5 # via # jinja2 # werkzeug -werkzeug==3.0.1 +werkzeug==3.0.4 # via flask diff --git a/app/ch06_routing/starter/requirements.txt b/app/ch06_routing/starter/requirements.txt index 12e1f645..1603e3f2 100644 --- a/app/ch06_routing/starter/requirements.txt +++ b/app/ch06_routing/starter/requirements.txt @@ -1,22 +1,18 @@ -# -# This file is autogenerated by pip-compile with Python 3.12 -# by the following command: -# -# pip-compile requirements.piptools -# -blinker==1.7.0 +# This file was autogenerated by uv via the following command: +# uv pip compile requirements.piptools --output-file requirements.txt +blinker==1.8.2 # via flask click==8.1.7 # via flask -flask==3.0.0 +flask==3.0.3 # via -r requirements.piptools -itsdangerous==2.1.2 +itsdangerous==2.2.0 # via flask -jinja2==3.1.2 +jinja2==3.1.4 # via flask -markupsafe==2.1.3 +markupsafe==2.1.5 # via # jinja2 # werkzeug -werkzeug==3.0.1 +werkzeug==3.0.4 # via flask diff --git a/app/ch08_adding_our_design/final/requirements.txt b/app/ch08_adding_our_design/final/requirements.txt index 12e1f645..1603e3f2 100644 --- a/app/ch08_adding_our_design/final/requirements.txt +++ b/app/ch08_adding_our_design/final/requirements.txt @@ -1,22 +1,18 @@ -# -# This file is autogenerated by pip-compile with Python 3.12 -# by the following command: -# -# pip-compile requirements.piptools -# -blinker==1.7.0 +# This file was autogenerated by uv via the following command: +# uv pip compile requirements.piptools --output-file requirements.txt +blinker==1.8.2 # via flask click==8.1.7 # via flask -flask==3.0.0 +flask==3.0.3 # via -r requirements.piptools -itsdangerous==2.1.2 +itsdangerous==2.2.0 # via flask -jinja2==3.1.2 +jinja2==3.1.4 # via flask -markupsafe==2.1.3 +markupsafe==2.1.5 # via # jinja2 # werkzeug -werkzeug==3.0.1 +werkzeug==3.0.4 # via flask diff --git a/app/ch08_adding_our_design/starter/requirements.txt b/app/ch08_adding_our_design/starter/requirements.txt index 12e1f645..1603e3f2 100644 --- a/app/ch08_adding_our_design/starter/requirements.txt +++ b/app/ch08_adding_our_design/starter/requirements.txt @@ -1,22 +1,18 @@ -# -# This file is autogenerated by pip-compile with Python 3.12 -# by the following command: -# -# pip-compile requirements.piptools -# -blinker==1.7.0 +# This file was autogenerated by uv via the following command: +# uv pip compile requirements.piptools --output-file requirements.txt +blinker==1.8.2 # via flask click==8.1.7 # via flask -flask==3.0.0 +flask==3.0.3 # via -r requirements.piptools -itsdangerous==2.1.2 +itsdangerous==2.2.0 # via flask -jinja2==3.1.2 +jinja2==3.1.4 # via flask -markupsafe==2.1.3 +markupsafe==2.1.5 # via # jinja2 # werkzeug -werkzeug==3.0.1 +werkzeug==3.0.4 # via flask diff --git a/app/ch09_sqlalchemy/final/requirements.txt b/app/ch09_sqlalchemy/final/requirements.txt index c38d2828..f4803bb6 100644 --- a/app/ch09_sqlalchemy/final/requirements.txt +++ b/app/ch09_sqlalchemy/final/requirements.txt @@ -1,26 +1,22 @@ -# -# This file is autogenerated by pip-compile with Python 3.11 -# by the following command: -# -# pip-compile requirements.piptools -# -blinker==1.7.0 +# This file was autogenerated by uv via the following command: +# uv pip compile requirements.piptools --output-file requirements.txt +blinker==1.8.2 # via flask click==8.1.7 # via flask -flask==3.0.0 +flask==3.0.3 # via -r requirements.piptools -itsdangerous==2.1.2 +itsdangerous==2.2.0 # via flask -jinja2==3.1.2 +jinja2==3.1.4 # via flask -markupsafe==2.1.3 +markupsafe==2.1.5 # via # jinja2 # werkzeug -sqlalchemy==2.0.23 +sqlalchemy==2.0.32 # via -r requirements.piptools -typing-extensions==4.9.0 +typing-extensions==4.12.2 # via sqlalchemy -werkzeug==3.0.1 +werkzeug==3.0.4 # via flask diff --git a/app/ch09_sqlalchemy/starter/requirements.txt b/app/ch09_sqlalchemy/starter/requirements.txt index 12e1f645..1603e3f2 100644 --- a/app/ch09_sqlalchemy/starter/requirements.txt +++ b/app/ch09_sqlalchemy/starter/requirements.txt @@ -1,22 +1,18 @@ -# -# This file is autogenerated by pip-compile with Python 3.12 -# by the following command: -# -# pip-compile requirements.piptools -# -blinker==1.7.0 +# This file was autogenerated by uv via the following command: +# uv pip compile requirements.piptools --output-file requirements.txt +blinker==1.8.2 # via flask click==8.1.7 # via flask -flask==3.0.0 +flask==3.0.3 # via -r requirements.piptools -itsdangerous==2.1.2 +itsdangerous==2.2.0 # via flask -jinja2==3.1.2 +jinja2==3.1.4 # via flask -markupsafe==2.1.3 +markupsafe==2.1.5 # via # jinja2 # werkzeug -werkzeug==3.0.1 +werkzeug==3.0.4 # via flask diff --git a/app/ch10_using_sqlachemy/final/pypi_org/views/package_views.py b/app/ch10_using_sqlachemy/final/pypi_org/views/package_views.py index 92d9109a..4589fe56 100644 --- a/app/ch10_using_sqlachemy/final/pypi_org/views/package_views.py +++ b/app/ch10_using_sqlachemy/final/pypi_org/views/package_views.py @@ -21,7 +21,7 @@ def package_details(package_name: str): is_latest = True if package.releases: - latest_release = package.releases[0] + latest_release = package.releases latest_version = latest_release.version_text return { diff --git a/app/ch10_using_sqlachemy/final/requirements.txt b/app/ch10_using_sqlachemy/final/requirements.txt index 090ec616..d532261b 100644 --- a/app/ch10_using_sqlachemy/final/requirements.txt +++ b/app/ch10_using_sqlachemy/final/requirements.txt @@ -1,36 +1,32 @@ -# -# This file is autogenerated by pip-compile with Python 3.11 -# by the following command: -# -# pip-compile requirements.piptools -# -blinker==1.7.0 +# This file was autogenerated by uv via the following command: +# uv pip compile requirements.piptools --output-file requirements.txt +blinker==1.8.2 # via flask click==8.1.7 # via flask -flask==3.0.0 +flask==3.0.3 # via -r requirements.piptools -itsdangerous==2.1.2 +itsdangerous==2.2.0 # via flask -jinja2==3.1.2 +jinja2==3.1.4 # via flask -markupsafe==2.1.3 +markupsafe==2.1.5 # via # jinja2 # werkzeug -progressbar2==4.2.0 +progressbar2==4.4.2 # via -r requirements.piptools -python-dateutil==2.8.2 +python-dateutil==2.9.0.post0 # via -r requirements.piptools -python-utils==3.8.1 +python-utils==3.8.2 # via progressbar2 six==1.16.0 # via python-dateutil -sqlalchemy==2.0.23 +sqlalchemy==2.0.32 # via -r requirements.piptools -typing-extensions==4.9.0 +typing-extensions==4.12.2 # via # python-utils # sqlalchemy -werkzeug==3.0.1 +werkzeug==3.0.4 # via flask diff --git a/app/ch10_using_sqlachemy/starter/requirements.txt b/app/ch10_using_sqlachemy/starter/requirements.txt index c38d2828..f4803bb6 100644 --- a/app/ch10_using_sqlachemy/starter/requirements.txt +++ b/app/ch10_using_sqlachemy/starter/requirements.txt @@ -1,26 +1,22 @@ -# -# This file is autogenerated by pip-compile with Python 3.11 -# by the following command: -# -# pip-compile requirements.piptools -# -blinker==1.7.0 +# This file was autogenerated by uv via the following command: +# uv pip compile requirements.piptools --output-file requirements.txt +blinker==1.8.2 # via flask click==8.1.7 # via flask -flask==3.0.0 +flask==3.0.3 # via -r requirements.piptools -itsdangerous==2.1.2 +itsdangerous==2.2.0 # via flask -jinja2==3.1.2 +jinja2==3.1.4 # via flask -markupsafe==2.1.3 +markupsafe==2.1.5 # via # jinja2 # werkzeug -sqlalchemy==2.0.23 +sqlalchemy==2.0.32 # via -r requirements.piptools -typing-extensions==4.9.0 +typing-extensions==4.12.2 # via sqlalchemy -werkzeug==3.0.1 +werkzeug==3.0.4 # via flask diff --git a/app/ch11_migrations/final/pypi_org/views/package_views.py b/app/ch11_migrations/final/pypi_org/views/package_views.py index 92d9109a..4589fe56 100644 --- a/app/ch11_migrations/final/pypi_org/views/package_views.py +++ b/app/ch11_migrations/final/pypi_org/views/package_views.py @@ -21,7 +21,7 @@ def package_details(package_name: str): is_latest = True if package.releases: - latest_release = package.releases[0] + latest_release = package.releases latest_version = latest_release.version_text return { diff --git a/app/ch11_migrations/final/requirements.txt b/app/ch11_migrations/final/requirements.txt index af454bba..8a6a1923 100644 --- a/app/ch11_migrations/final/requirements.txt +++ b/app/ch11_migrations/final/requirements.txt @@ -1,44 +1,40 @@ -# -# This file is autogenerated by pip-compile with Python 3.11 -# by the following command: -# -# pip-compile requirements.piptools -# -alembic==1.13.0 +# This file was autogenerated by uv via the following command: +# uv pip compile requirements.piptools --output-file requirements.txt +alembic==1.13.2 # via -r requirements.piptools -blinker==1.7.0 +blinker==1.8.2 # via flask click==8.1.7 # via flask -flask==3.0.0 +flask==3.0.3 # via -r requirements.piptools -itsdangerous==2.1.2 +itsdangerous==2.2.0 # via flask -jinja2==3.1.2 +jinja2==3.1.4 # via flask -mako==1.3.0 +mako==1.3.5 # via alembic -markupsafe==2.1.3 +markupsafe==2.1.5 # via # jinja2 # mako # werkzeug -progressbar2==4.2.0 +progressbar2==4.4.2 # via -r requirements.piptools -python-dateutil==2.8.2 +python-dateutil==2.9.0.post0 # via -r requirements.piptools -python-utils==3.8.1 +python-utils==3.8.2 # via progressbar2 six==1.16.0 # via python-dateutil -sqlalchemy==2.0.23 +sqlalchemy==2.0.32 # via # -r requirements.piptools # alembic -typing-extensions==4.9.0 +typing-extensions==4.12.2 # via # alembic # python-utils # sqlalchemy -werkzeug==3.0.1 +werkzeug==3.0.4 # via flask diff --git a/app/ch11_migrations/starter/pypi_org/views/package_views.py b/app/ch11_migrations/starter/pypi_org/views/package_views.py index 92d9109a..4589fe56 100644 --- a/app/ch11_migrations/starter/pypi_org/views/package_views.py +++ b/app/ch11_migrations/starter/pypi_org/views/package_views.py @@ -21,7 +21,7 @@ def package_details(package_name: str): is_latest = True if package.releases: - latest_release = package.releases[0] + latest_release = package.releases latest_version = latest_release.version_text return { diff --git a/app/ch11_migrations/starter/requirements.txt b/app/ch11_migrations/starter/requirements.txt index 090ec616..d532261b 100644 --- a/app/ch11_migrations/starter/requirements.txt +++ b/app/ch11_migrations/starter/requirements.txt @@ -1,36 +1,32 @@ -# -# This file is autogenerated by pip-compile with Python 3.11 -# by the following command: -# -# pip-compile requirements.piptools -# -blinker==1.7.0 +# This file was autogenerated by uv via the following command: +# uv pip compile requirements.piptools --output-file requirements.txt +blinker==1.8.2 # via flask click==8.1.7 # via flask -flask==3.0.0 +flask==3.0.3 # via -r requirements.piptools -itsdangerous==2.1.2 +itsdangerous==2.2.0 # via flask -jinja2==3.1.2 +jinja2==3.1.4 # via flask -markupsafe==2.1.3 +markupsafe==2.1.5 # via # jinja2 # werkzeug -progressbar2==4.2.0 +progressbar2==4.4.2 # via -r requirements.piptools -python-dateutil==2.8.2 +python-dateutil==2.9.0.post0 # via -r requirements.piptools -python-utils==3.8.1 +python-utils==3.8.2 # via progressbar2 six==1.16.0 # via python-dateutil -sqlalchemy==2.0.23 +sqlalchemy==2.0.32 # via -r requirements.piptools -typing-extensions==4.9.0 +typing-extensions==4.12.2 # via # python-utils # sqlalchemy -werkzeug==3.0.1 +werkzeug==3.0.4 # via flask diff --git a/app/ch12-forms/final/pypi_org/views/package_views.py b/app/ch12-forms/final/pypi_org/views/package_views.py index 2587b704..e634d845 100644 --- a/app/ch12-forms/final/pypi_org/views/package_views.py +++ b/app/ch12-forms/final/pypi_org/views/package_views.py @@ -22,7 +22,7 @@ def package_details(package_name: str): is_latest = True if package.releases: - latest_release = package.releases[0] + latest_release = package.releases latest_version = latest_release.version_text return { diff --git a/app/ch12-forms/final/requirements.txt b/app/ch12-forms/final/requirements.txt index 662fe297..c7dbe9a5 100644 --- a/app/ch12-forms/final/requirements.txt +++ b/app/ch12-forms/final/requirements.txt @@ -1,46 +1,42 @@ -# -# This file is autogenerated by pip-compile with Python 3.11 -# by the following command: -# -# pip-compile requirements.piptools -# -alembic==1.13.0 +# This file was autogenerated by uv via the following command: +# uv pip compile requirements.piptools --output-file requirements.txt +alembic==1.13.2 # via -r requirements.piptools -blinker==1.7.0 +blinker==1.8.2 # via flask click==8.1.7 # via flask -flask==3.0.0 +flask==3.0.3 # via -r requirements.piptools -itsdangerous==2.1.2 +itsdangerous==2.2.0 # via flask -jinja2==3.1.2 +jinja2==3.1.4 # via flask -mako==1.3.0 +mako==1.3.5 # via alembic -markupsafe==2.1.3 +markupsafe==2.1.5 # via # jinja2 # mako # werkzeug passlib==1.7.4 # via -r requirements.piptools -progressbar2==4.2.0 +progressbar2==4.4.2 # via -r requirements.piptools -python-dateutil==2.8.2 +python-dateutil==2.9.0.post0 # via -r requirements.piptools -python-utils==3.8.1 +python-utils==3.8.2 # via progressbar2 six==1.16.0 # via python-dateutil -sqlalchemy==2.0.23 +sqlalchemy==2.0.32 # via # -r requirements.piptools # alembic -typing-extensions==4.9.0 +typing-extensions==4.12.2 # via # alembic # python-utils # sqlalchemy -werkzeug==3.0.1 +werkzeug==3.0.4 # via flask diff --git a/app/ch12-forms/starter/pypi_org/views/package_views.py b/app/ch12-forms/starter/pypi_org/views/package_views.py index 92d9109a..4589fe56 100644 --- a/app/ch12-forms/starter/pypi_org/views/package_views.py +++ b/app/ch12-forms/starter/pypi_org/views/package_views.py @@ -21,7 +21,7 @@ def package_details(package_name: str): is_latest = True if package.releases: - latest_release = package.releases[0] + latest_release = package.releases latest_version = latest_release.version_text return { diff --git a/app/ch12-forms/starter/requirements.txt b/app/ch12-forms/starter/requirements.txt index af454bba..8a6a1923 100644 --- a/app/ch12-forms/starter/requirements.txt +++ b/app/ch12-forms/starter/requirements.txt @@ -1,44 +1,40 @@ -# -# This file is autogenerated by pip-compile with Python 3.11 -# by the following command: -# -# pip-compile requirements.piptools -# -alembic==1.13.0 +# This file was autogenerated by uv via the following command: +# uv pip compile requirements.piptools --output-file requirements.txt +alembic==1.13.2 # via -r requirements.piptools -blinker==1.7.0 +blinker==1.8.2 # via flask click==8.1.7 # via flask -flask==3.0.0 +flask==3.0.3 # via -r requirements.piptools -itsdangerous==2.1.2 +itsdangerous==2.2.0 # via flask -jinja2==3.1.2 +jinja2==3.1.4 # via flask -mako==1.3.0 +mako==1.3.5 # via alembic -markupsafe==2.1.3 +markupsafe==2.1.5 # via # jinja2 # mako # werkzeug -progressbar2==4.2.0 +progressbar2==4.4.2 # via -r requirements.piptools -python-dateutil==2.8.2 +python-dateutil==2.9.0.post0 # via -r requirements.piptools -python-utils==3.8.1 +python-utils==3.8.2 # via progressbar2 six==1.16.0 # via python-dateutil -sqlalchemy==2.0.23 +sqlalchemy==2.0.32 # via # -r requirements.piptools # alembic -typing-extensions==4.9.0 +typing-extensions==4.12.2 # via # alembic # python-utils # sqlalchemy -werkzeug==3.0.1 +werkzeug==3.0.4 # via flask diff --git a/app/ch13-validation/final/pypi_org/viewmodels/packages/pagedetails_viewmodel.py b/app/ch13-validation/final/pypi_org/viewmodels/packages/pagedetails_viewmodel.py index 09f47c6f..62bdca3d 100644 --- a/app/ch13-validation/final/pypi_org/viewmodels/packages/pagedetails_viewmodel.py +++ b/app/ch13-validation/final/pypi_org/viewmodels/packages/pagedetails_viewmodel.py @@ -16,7 +16,7 @@ def __init__(self, package_name: str): self.is_latest = True if self.package and self.package.releases: - self.latest_release = self.package.releases[0] + self.latest_release = self.package.releases self.latest_version = self.latest_release.version_text self.release_version = self.latest_release diff --git a/app/ch13-validation/final/requirements.txt b/app/ch13-validation/final/requirements.txt index 662fe297..c7dbe9a5 100644 --- a/app/ch13-validation/final/requirements.txt +++ b/app/ch13-validation/final/requirements.txt @@ -1,46 +1,42 @@ -# -# This file is autogenerated by pip-compile with Python 3.11 -# by the following command: -# -# pip-compile requirements.piptools -# -alembic==1.13.0 +# This file was autogenerated by uv via the following command: +# uv pip compile requirements.piptools --output-file requirements.txt +alembic==1.13.2 # via -r requirements.piptools -blinker==1.7.0 +blinker==1.8.2 # via flask click==8.1.7 # via flask -flask==3.0.0 +flask==3.0.3 # via -r requirements.piptools -itsdangerous==2.1.2 +itsdangerous==2.2.0 # via flask -jinja2==3.1.2 +jinja2==3.1.4 # via flask -mako==1.3.0 +mako==1.3.5 # via alembic -markupsafe==2.1.3 +markupsafe==2.1.5 # via # jinja2 # mako # werkzeug passlib==1.7.4 # via -r requirements.piptools -progressbar2==4.2.0 +progressbar2==4.4.2 # via -r requirements.piptools -python-dateutil==2.8.2 +python-dateutil==2.9.0.post0 # via -r requirements.piptools -python-utils==3.8.1 +python-utils==3.8.2 # via progressbar2 six==1.16.0 # via python-dateutil -sqlalchemy==2.0.23 +sqlalchemy==2.0.32 # via # -r requirements.piptools # alembic -typing-extensions==4.9.0 +typing-extensions==4.12.2 # via # alembic # python-utils # sqlalchemy -werkzeug==3.0.1 +werkzeug==3.0.4 # via flask diff --git a/app/ch13-validation/starter/pypi_org/views/package_views.py b/app/ch13-validation/starter/pypi_org/views/package_views.py index 2587b704..e634d845 100644 --- a/app/ch13-validation/starter/pypi_org/views/package_views.py +++ b/app/ch13-validation/starter/pypi_org/views/package_views.py @@ -22,7 +22,7 @@ def package_details(package_name: str): is_latest = True if package.releases: - latest_release = package.releases[0] + latest_release = package.releases latest_version = latest_release.version_text return { diff --git a/app/ch13-validation/starter/requirements.txt b/app/ch13-validation/starter/requirements.txt index 662fe297..c7dbe9a5 100644 --- a/app/ch13-validation/starter/requirements.txt +++ b/app/ch13-validation/starter/requirements.txt @@ -1,46 +1,42 @@ -# -# This file is autogenerated by pip-compile with Python 3.11 -# by the following command: -# -# pip-compile requirements.piptools -# -alembic==1.13.0 +# This file was autogenerated by uv via the following command: +# uv pip compile requirements.piptools --output-file requirements.txt +alembic==1.13.2 # via -r requirements.piptools -blinker==1.7.0 +blinker==1.8.2 # via flask click==8.1.7 # via flask -flask==3.0.0 +flask==3.0.3 # via -r requirements.piptools -itsdangerous==2.1.2 +itsdangerous==2.2.0 # via flask -jinja2==3.1.2 +jinja2==3.1.4 # via flask -mako==1.3.0 +mako==1.3.5 # via alembic -markupsafe==2.1.3 +markupsafe==2.1.5 # via # jinja2 # mako # werkzeug passlib==1.7.4 # via -r requirements.piptools -progressbar2==4.2.0 +progressbar2==4.4.2 # via -r requirements.piptools -python-dateutil==2.8.2 +python-dateutil==2.9.0.post0 # via -r requirements.piptools -python-utils==3.8.1 +python-utils==3.8.2 # via progressbar2 six==1.16.0 # via python-dateutil -sqlalchemy==2.0.23 +sqlalchemy==2.0.32 # via # -r requirements.piptools # alembic -typing-extensions==4.9.0 +typing-extensions==4.12.2 # via # alembic # python-utils # sqlalchemy -werkzeug==3.0.1 +werkzeug==3.0.4 # via flask diff --git a/app/ch14_testing/final/pypi_org/viewmodels/packages/pagedetails_viewmodel.py b/app/ch14_testing/final/pypi_org/viewmodels/packages/pagedetails_viewmodel.py index 09f47c6f..62bdca3d 100644 --- a/app/ch14_testing/final/pypi_org/viewmodels/packages/pagedetails_viewmodel.py +++ b/app/ch14_testing/final/pypi_org/viewmodels/packages/pagedetails_viewmodel.py @@ -16,7 +16,7 @@ def __init__(self, package_name: str): self.is_latest = True if self.package and self.package.releases: - self.latest_release = self.package.releases[0] + self.latest_release = self.package.releases self.latest_version = self.latest_release.version_text self.release_version = self.latest_release diff --git a/app/ch14_testing/final/requirements.txt b/app/ch14_testing/final/requirements.txt index 662fe297..c7dbe9a5 100644 --- a/app/ch14_testing/final/requirements.txt +++ b/app/ch14_testing/final/requirements.txt @@ -1,46 +1,42 @@ -# -# This file is autogenerated by pip-compile with Python 3.11 -# by the following command: -# -# pip-compile requirements.piptools -# -alembic==1.13.0 +# This file was autogenerated by uv via the following command: +# uv pip compile requirements.piptools --output-file requirements.txt +alembic==1.13.2 # via -r requirements.piptools -blinker==1.7.0 +blinker==1.8.2 # via flask click==8.1.7 # via flask -flask==3.0.0 +flask==3.0.3 # via -r requirements.piptools -itsdangerous==2.1.2 +itsdangerous==2.2.0 # via flask -jinja2==3.1.2 +jinja2==3.1.4 # via flask -mako==1.3.0 +mako==1.3.5 # via alembic -markupsafe==2.1.3 +markupsafe==2.1.5 # via # jinja2 # mako # werkzeug passlib==1.7.4 # via -r requirements.piptools -progressbar2==4.2.0 +progressbar2==4.4.2 # via -r requirements.piptools -python-dateutil==2.8.2 +python-dateutil==2.9.0.post0 # via -r requirements.piptools -python-utils==3.8.1 +python-utils==3.8.2 # via progressbar2 six==1.16.0 # via python-dateutil -sqlalchemy==2.0.23 +sqlalchemy==2.0.32 # via # -r requirements.piptools # alembic -typing-extensions==4.9.0 +typing-extensions==4.12.2 # via # alembic # python-utils # sqlalchemy -werkzeug==3.0.1 +werkzeug==3.0.4 # via flask diff --git a/app/ch14_testing/starter/pypi_org/viewmodels/packages/pagedetails_viewmodel.py b/app/ch14_testing/starter/pypi_org/viewmodels/packages/pagedetails_viewmodel.py index 09f47c6f..62bdca3d 100644 --- a/app/ch14_testing/starter/pypi_org/viewmodels/packages/pagedetails_viewmodel.py +++ b/app/ch14_testing/starter/pypi_org/viewmodels/packages/pagedetails_viewmodel.py @@ -16,7 +16,7 @@ def __init__(self, package_name: str): self.is_latest = True if self.package and self.package.releases: - self.latest_release = self.package.releases[0] + self.latest_release = self.package.releases self.latest_version = self.latest_release.version_text self.release_version = self.latest_release diff --git a/app/ch14_testing/starter/requirements.txt b/app/ch14_testing/starter/requirements.txt index 662fe297..c7dbe9a5 100644 --- a/app/ch14_testing/starter/requirements.txt +++ b/app/ch14_testing/starter/requirements.txt @@ -1,46 +1,42 @@ -# -# This file is autogenerated by pip-compile with Python 3.11 -# by the following command: -# -# pip-compile requirements.piptools -# -alembic==1.13.0 +# This file was autogenerated by uv via the following command: +# uv pip compile requirements.piptools --output-file requirements.txt +alembic==1.13.2 # via -r requirements.piptools -blinker==1.7.0 +blinker==1.8.2 # via flask click==8.1.7 # via flask -flask==3.0.0 +flask==3.0.3 # via -r requirements.piptools -itsdangerous==2.1.2 +itsdangerous==2.2.0 # via flask -jinja2==3.1.2 +jinja2==3.1.4 # via flask -mako==1.3.0 +mako==1.3.5 # via alembic -markupsafe==2.1.3 +markupsafe==2.1.5 # via # jinja2 # mako # werkzeug passlib==1.7.4 # via -r requirements.piptools -progressbar2==4.2.0 +progressbar2==4.4.2 # via -r requirements.piptools -python-dateutil==2.8.2 +python-dateutil==2.9.0.post0 # via -r requirements.piptools -python-utils==3.8.1 +python-utils==3.8.2 # via progressbar2 six==1.16.0 # via python-dateutil -sqlalchemy==2.0.23 +sqlalchemy==2.0.32 # via # -r requirements.piptools # alembic -typing-extensions==4.9.0 +typing-extensions==4.12.2 # via # alembic # python-utils # sqlalchemy -werkzeug==3.0.1 +werkzeug==3.0.4 # via flask diff --git a/app/ch15_deploy/final/pypi_org/viewmodels/packages/pagedetails_viewmodel.py b/app/ch15_deploy/final/pypi_org/viewmodels/packages/pagedetails_viewmodel.py index 09f47c6f..62bdca3d 100644 --- a/app/ch15_deploy/final/pypi_org/viewmodels/packages/pagedetails_viewmodel.py +++ b/app/ch15_deploy/final/pypi_org/viewmodels/packages/pagedetails_viewmodel.py @@ -16,7 +16,7 @@ def __init__(self, package_name: str): self.is_latest = True if self.package and self.package.releases: - self.latest_release = self.package.releases[0] + self.latest_release = self.package.releases self.latest_version = self.latest_release.version_text self.release_version = self.latest_release diff --git a/app/ch15_deploy/final/requirements.txt b/app/ch15_deploy/final/requirements.txt index 662fe297..c7dbe9a5 100644 --- a/app/ch15_deploy/final/requirements.txt +++ b/app/ch15_deploy/final/requirements.txt @@ -1,46 +1,42 @@ -# -# This file is autogenerated by pip-compile with Python 3.11 -# by the following command: -# -# pip-compile requirements.piptools -# -alembic==1.13.0 +# This file was autogenerated by uv via the following command: +# uv pip compile requirements.piptools --output-file requirements.txt +alembic==1.13.2 # via -r requirements.piptools -blinker==1.7.0 +blinker==1.8.2 # via flask click==8.1.7 # via flask -flask==3.0.0 +flask==3.0.3 # via -r requirements.piptools -itsdangerous==2.1.2 +itsdangerous==2.2.0 # via flask -jinja2==3.1.2 +jinja2==3.1.4 # via flask -mako==1.3.0 +mako==1.3.5 # via alembic -markupsafe==2.1.3 +markupsafe==2.1.5 # via # jinja2 # mako # werkzeug passlib==1.7.4 # via -r requirements.piptools -progressbar2==4.2.0 +progressbar2==4.4.2 # via -r requirements.piptools -python-dateutil==2.8.2 +python-dateutil==2.9.0.post0 # via -r requirements.piptools -python-utils==3.8.1 +python-utils==3.8.2 # via progressbar2 six==1.16.0 # via python-dateutil -sqlalchemy==2.0.23 +sqlalchemy==2.0.32 # via # -r requirements.piptools # alembic -typing-extensions==4.9.0 +typing-extensions==4.12.2 # via # alembic # python-utils # sqlalchemy -werkzeug==3.0.1 +werkzeug==3.0.4 # via flask diff --git a/app/ch15_deploy/starter/pypi_org/viewmodels/packages/pagedetails_viewmodel.py b/app/ch15_deploy/starter/pypi_org/viewmodels/packages/pagedetails_viewmodel.py index 09f47c6f..62bdca3d 100644 --- a/app/ch15_deploy/starter/pypi_org/viewmodels/packages/pagedetails_viewmodel.py +++ b/app/ch15_deploy/starter/pypi_org/viewmodels/packages/pagedetails_viewmodel.py @@ -16,7 +16,7 @@ def __init__(self, package_name: str): self.is_latest = True if self.package and self.package.releases: - self.latest_release = self.package.releases[0] + self.latest_release = self.package.releases self.latest_version = self.latest_release.version_text self.release_version = self.latest_release diff --git a/app/ch15_deploy/starter/requirements.txt b/app/ch15_deploy/starter/requirements.txt index 662fe297..c7dbe9a5 100644 --- a/app/ch15_deploy/starter/requirements.txt +++ b/app/ch15_deploy/starter/requirements.txt @@ -1,46 +1,42 @@ -# -# This file is autogenerated by pip-compile with Python 3.11 -# by the following command: -# -# pip-compile requirements.piptools -# -alembic==1.13.0 +# This file was autogenerated by uv via the following command: +# uv pip compile requirements.piptools --output-file requirements.txt +alembic==1.13.2 # via -r requirements.piptools -blinker==1.7.0 +blinker==1.8.2 # via flask click==8.1.7 # via flask -flask==3.0.0 +flask==3.0.3 # via -r requirements.piptools -itsdangerous==2.1.2 +itsdangerous==2.2.0 # via flask -jinja2==3.1.2 +jinja2==3.1.4 # via flask -mako==1.3.0 +mako==1.3.5 # via alembic -markupsafe==2.1.3 +markupsafe==2.1.5 # via # jinja2 # mako # werkzeug passlib==1.7.4 # via -r requirements.piptools -progressbar2==4.2.0 +progressbar2==4.4.2 # via -r requirements.piptools -python-dateutil==2.8.2 +python-dateutil==2.9.0.post0 # via -r requirements.piptools -python-utils==3.8.1 +python-utils==3.8.2 # via progressbar2 six==1.16.0 # via python-dateutil -sqlalchemy==2.0.23 +sqlalchemy==2.0.32 # via # -r requirements.piptools # alembic -typing-extensions==4.9.0 +typing-extensions==4.12.2 # via # alembic # python-utils # sqlalchemy -werkzeug==3.0.1 +werkzeug==3.0.4 # via flask From e3e09d8c5d9950d015fc58cc98e9c3bde0bec88a Mon Sep 17 00:00:00 2001 From: Michael Kennedy Date: Sun, 2 Mar 2025 09:31:57 -0800 Subject: [PATCH 43/44] Update to latest versions of libraries. --- .gitignore | 2 + .../first_site/requirements.txt | 12 ++--- .../final/requirements.txt | 12 ++--- app/ch06_routing/final/requirements.txt | 12 ++--- app/ch06_routing/starter/requirements.txt | 12 ++--- .../final/requirements.txt | 12 ++--- .../starter/requirements.txt | 12 ++--- app/ch09_sqlalchemy/final/requirements.txt | 14 +++--- app/ch09_sqlalchemy/starter/requirements.txt | 12 ++--- .../final/requirements.txt | 20 ++++----- .../starter/requirements.txt | 14 +++--- app/ch11_migrations/final/requirements.txt | 24 +++++----- app/ch11_migrations/starter/requirements.txt | 20 ++++----- app/ch12-forms/final/requirements.txt | 24 +++++----- app/ch12-forms/starter/requirements.txt | 24 +++++----- app/ch13-validation/final/requirements.txt | 24 +++++----- app/ch13-validation/starter/requirements.txt | 24 +++++----- app/ch14_testing/final/requirements.txt | 24 +++++----- app/ch14_testing/starter/requirements.txt | 24 +++++----- app/ch15_deploy/final/requirements.txt | 24 +++++----- app/ch15_deploy/starter/requirements.txt | 24 +++++----- app/ch16_mongodb/final/requirements.txt | 44 +++++++++---------- app/ch16_mongodb/starter/requirements.txt | 38 +++++++--------- 23 files changed, 223 insertions(+), 229 deletions(-) diff --git a/.gitignore b/.gitignore index f3397b4f..e0bf6584 100644 --- a/.gitignore +++ b/.gitignore @@ -177,3 +177,5 @@ app/ch14_testing/starter/.idea/inspectionProfiles/Project_Default.xml app/ch15_deploy/final/.idea/inspectionProfiles/Project_Default.xml .idea/web-apps-flask-course.iml .idea/inspectionProfiles/Project_Default.xml +/.idea/jsLibraryMappings.xml +/.idea/webResources.xml diff --git a/app/ch04_first_site/first_site_final/first_site/requirements.txt b/app/ch04_first_site/first_site_final/first_site/requirements.txt index 1603e3f2..eea1cfd5 100644 --- a/app/ch04_first_site/first_site_final/first_site/requirements.txt +++ b/app/ch04_first_site/first_site_final/first_site/requirements.txt @@ -1,18 +1,18 @@ # This file was autogenerated by uv via the following command: # uv pip compile requirements.piptools --output-file requirements.txt -blinker==1.8.2 +blinker==1.9.0 # via flask -click==8.1.7 +click==8.1.8 # via flask -flask==3.0.3 +flask==3.1.0 # via -r requirements.piptools itsdangerous==2.2.0 # via flask -jinja2==3.1.4 +jinja2==3.1.5 # via flask -markupsafe==2.1.5 +markupsafe==3.0.2 # via # jinja2 # werkzeug -werkzeug==3.0.4 +werkzeug==3.1.3 # via flask diff --git a/app/ch05_jinja_templates/final/requirements.txt b/app/ch05_jinja_templates/final/requirements.txt index 1603e3f2..eea1cfd5 100644 --- a/app/ch05_jinja_templates/final/requirements.txt +++ b/app/ch05_jinja_templates/final/requirements.txt @@ -1,18 +1,18 @@ # This file was autogenerated by uv via the following command: # uv pip compile requirements.piptools --output-file requirements.txt -blinker==1.8.2 +blinker==1.9.0 # via flask -click==8.1.7 +click==8.1.8 # via flask -flask==3.0.3 +flask==3.1.0 # via -r requirements.piptools itsdangerous==2.2.0 # via flask -jinja2==3.1.4 +jinja2==3.1.5 # via flask -markupsafe==2.1.5 +markupsafe==3.0.2 # via # jinja2 # werkzeug -werkzeug==3.0.4 +werkzeug==3.1.3 # via flask diff --git a/app/ch06_routing/final/requirements.txt b/app/ch06_routing/final/requirements.txt index 1603e3f2..eea1cfd5 100644 --- a/app/ch06_routing/final/requirements.txt +++ b/app/ch06_routing/final/requirements.txt @@ -1,18 +1,18 @@ # This file was autogenerated by uv via the following command: # uv pip compile requirements.piptools --output-file requirements.txt -blinker==1.8.2 +blinker==1.9.0 # via flask -click==8.1.7 +click==8.1.8 # via flask -flask==3.0.3 +flask==3.1.0 # via -r requirements.piptools itsdangerous==2.2.0 # via flask -jinja2==3.1.4 +jinja2==3.1.5 # via flask -markupsafe==2.1.5 +markupsafe==3.0.2 # via # jinja2 # werkzeug -werkzeug==3.0.4 +werkzeug==3.1.3 # via flask diff --git a/app/ch06_routing/starter/requirements.txt b/app/ch06_routing/starter/requirements.txt index 1603e3f2..eea1cfd5 100644 --- a/app/ch06_routing/starter/requirements.txt +++ b/app/ch06_routing/starter/requirements.txt @@ -1,18 +1,18 @@ # This file was autogenerated by uv via the following command: # uv pip compile requirements.piptools --output-file requirements.txt -blinker==1.8.2 +blinker==1.9.0 # via flask -click==8.1.7 +click==8.1.8 # via flask -flask==3.0.3 +flask==3.1.0 # via -r requirements.piptools itsdangerous==2.2.0 # via flask -jinja2==3.1.4 +jinja2==3.1.5 # via flask -markupsafe==2.1.5 +markupsafe==3.0.2 # via # jinja2 # werkzeug -werkzeug==3.0.4 +werkzeug==3.1.3 # via flask diff --git a/app/ch08_adding_our_design/final/requirements.txt b/app/ch08_adding_our_design/final/requirements.txt index 1603e3f2..eea1cfd5 100644 --- a/app/ch08_adding_our_design/final/requirements.txt +++ b/app/ch08_adding_our_design/final/requirements.txt @@ -1,18 +1,18 @@ # This file was autogenerated by uv via the following command: # uv pip compile requirements.piptools --output-file requirements.txt -blinker==1.8.2 +blinker==1.9.0 # via flask -click==8.1.7 +click==8.1.8 # via flask -flask==3.0.3 +flask==3.1.0 # via -r requirements.piptools itsdangerous==2.2.0 # via flask -jinja2==3.1.4 +jinja2==3.1.5 # via flask -markupsafe==2.1.5 +markupsafe==3.0.2 # via # jinja2 # werkzeug -werkzeug==3.0.4 +werkzeug==3.1.3 # via flask diff --git a/app/ch08_adding_our_design/starter/requirements.txt b/app/ch08_adding_our_design/starter/requirements.txt index 1603e3f2..eea1cfd5 100644 --- a/app/ch08_adding_our_design/starter/requirements.txt +++ b/app/ch08_adding_our_design/starter/requirements.txt @@ -1,18 +1,18 @@ # This file was autogenerated by uv via the following command: # uv pip compile requirements.piptools --output-file requirements.txt -blinker==1.8.2 +blinker==1.9.0 # via flask -click==8.1.7 +click==8.1.8 # via flask -flask==3.0.3 +flask==3.1.0 # via -r requirements.piptools itsdangerous==2.2.0 # via flask -jinja2==3.1.4 +jinja2==3.1.5 # via flask -markupsafe==2.1.5 +markupsafe==3.0.2 # via # jinja2 # werkzeug -werkzeug==3.0.4 +werkzeug==3.1.3 # via flask diff --git a/app/ch09_sqlalchemy/final/requirements.txt b/app/ch09_sqlalchemy/final/requirements.txt index f4803bb6..25908d2b 100644 --- a/app/ch09_sqlalchemy/final/requirements.txt +++ b/app/ch09_sqlalchemy/final/requirements.txt @@ -1,22 +1,22 @@ # This file was autogenerated by uv via the following command: # uv pip compile requirements.piptools --output-file requirements.txt -blinker==1.8.2 +blinker==1.9.0 # via flask -click==8.1.7 +click==8.1.8 # via flask -flask==3.0.3 +flask==3.1.0 # via -r requirements.piptools itsdangerous==2.2.0 # via flask -jinja2==3.1.4 +jinja2==3.1.5 # via flask -markupsafe==2.1.5 +markupsafe==3.0.2 # via # jinja2 # werkzeug -sqlalchemy==2.0.32 +sqlalchemy==2.0.38 # via -r requirements.piptools typing-extensions==4.12.2 # via sqlalchemy -werkzeug==3.0.4 +werkzeug==3.1.3 # via flask diff --git a/app/ch09_sqlalchemy/starter/requirements.txt b/app/ch09_sqlalchemy/starter/requirements.txt index 1603e3f2..eea1cfd5 100644 --- a/app/ch09_sqlalchemy/starter/requirements.txt +++ b/app/ch09_sqlalchemy/starter/requirements.txt @@ -1,18 +1,18 @@ # This file was autogenerated by uv via the following command: # uv pip compile requirements.piptools --output-file requirements.txt -blinker==1.8.2 +blinker==1.9.0 # via flask -click==8.1.7 +click==8.1.8 # via flask -flask==3.0.3 +flask==3.1.0 # via -r requirements.piptools itsdangerous==2.2.0 # via flask -jinja2==3.1.4 +jinja2==3.1.5 # via flask -markupsafe==2.1.5 +markupsafe==3.0.2 # via # jinja2 # werkzeug -werkzeug==3.0.4 +werkzeug==3.1.3 # via flask diff --git a/app/ch10_using_sqlachemy/final/requirements.txt b/app/ch10_using_sqlachemy/final/requirements.txt index d532261b..943a0812 100644 --- a/app/ch10_using_sqlachemy/final/requirements.txt +++ b/app/ch10_using_sqlachemy/final/requirements.txt @@ -1,32 +1,32 @@ # This file was autogenerated by uv via the following command: # uv pip compile requirements.piptools --output-file requirements.txt -blinker==1.8.2 +blinker==1.9.0 # via flask -click==8.1.7 +click==8.1.8 # via flask -flask==3.0.3 +flask==3.1.0 # via -r requirements.piptools itsdangerous==2.2.0 # via flask -jinja2==3.1.4 +jinja2==3.1.5 # via flask -markupsafe==2.1.5 +markupsafe==3.0.2 # via # jinja2 # werkzeug -progressbar2==4.4.2 +progressbar2==4.5.0 # via -r requirements.piptools python-dateutil==2.9.0.post0 # via -r requirements.piptools -python-utils==3.8.2 +python-utils==3.9.1 # via progressbar2 -six==1.16.0 +six==1.17.0 # via python-dateutil -sqlalchemy==2.0.32 +sqlalchemy==2.0.38 # via -r requirements.piptools typing-extensions==4.12.2 # via # python-utils # sqlalchemy -werkzeug==3.0.4 +werkzeug==3.1.3 # via flask diff --git a/app/ch10_using_sqlachemy/starter/requirements.txt b/app/ch10_using_sqlachemy/starter/requirements.txt index f4803bb6..25908d2b 100644 --- a/app/ch10_using_sqlachemy/starter/requirements.txt +++ b/app/ch10_using_sqlachemy/starter/requirements.txt @@ -1,22 +1,22 @@ # This file was autogenerated by uv via the following command: # uv pip compile requirements.piptools --output-file requirements.txt -blinker==1.8.2 +blinker==1.9.0 # via flask -click==8.1.7 +click==8.1.8 # via flask -flask==3.0.3 +flask==3.1.0 # via -r requirements.piptools itsdangerous==2.2.0 # via flask -jinja2==3.1.4 +jinja2==3.1.5 # via flask -markupsafe==2.1.5 +markupsafe==3.0.2 # via # jinja2 # werkzeug -sqlalchemy==2.0.32 +sqlalchemy==2.0.38 # via -r requirements.piptools typing-extensions==4.12.2 # via sqlalchemy -werkzeug==3.0.4 +werkzeug==3.1.3 # via flask diff --git a/app/ch11_migrations/final/requirements.txt b/app/ch11_migrations/final/requirements.txt index 8a6a1923..d802976d 100644 --- a/app/ch11_migrations/final/requirements.txt +++ b/app/ch11_migrations/final/requirements.txt @@ -1,33 +1,33 @@ # This file was autogenerated by uv via the following command: # uv pip compile requirements.piptools --output-file requirements.txt -alembic==1.13.2 +alembic==1.14.1 # via -r requirements.piptools -blinker==1.8.2 +blinker==1.9.0 # via flask -click==8.1.7 +click==8.1.8 # via flask -flask==3.0.3 +flask==3.1.0 # via -r requirements.piptools itsdangerous==2.2.0 # via flask -jinja2==3.1.4 +jinja2==3.1.5 # via flask -mako==1.3.5 +mako==1.3.9 # via alembic -markupsafe==2.1.5 +markupsafe==3.0.2 # via # jinja2 # mako # werkzeug -progressbar2==4.4.2 +progressbar2==4.5.0 # via -r requirements.piptools python-dateutil==2.9.0.post0 # via -r requirements.piptools -python-utils==3.8.2 +python-utils==3.9.1 # via progressbar2 -six==1.16.0 +six==1.17.0 # via python-dateutil -sqlalchemy==2.0.32 +sqlalchemy==2.0.38 # via # -r requirements.piptools # alembic @@ -36,5 +36,5 @@ typing-extensions==4.12.2 # alembic # python-utils # sqlalchemy -werkzeug==3.0.4 +werkzeug==3.1.3 # via flask diff --git a/app/ch11_migrations/starter/requirements.txt b/app/ch11_migrations/starter/requirements.txt index d532261b..943a0812 100644 --- a/app/ch11_migrations/starter/requirements.txt +++ b/app/ch11_migrations/starter/requirements.txt @@ -1,32 +1,32 @@ # This file was autogenerated by uv via the following command: # uv pip compile requirements.piptools --output-file requirements.txt -blinker==1.8.2 +blinker==1.9.0 # via flask -click==8.1.7 +click==8.1.8 # via flask -flask==3.0.3 +flask==3.1.0 # via -r requirements.piptools itsdangerous==2.2.0 # via flask -jinja2==3.1.4 +jinja2==3.1.5 # via flask -markupsafe==2.1.5 +markupsafe==3.0.2 # via # jinja2 # werkzeug -progressbar2==4.4.2 +progressbar2==4.5.0 # via -r requirements.piptools python-dateutil==2.9.0.post0 # via -r requirements.piptools -python-utils==3.8.2 +python-utils==3.9.1 # via progressbar2 -six==1.16.0 +six==1.17.0 # via python-dateutil -sqlalchemy==2.0.32 +sqlalchemy==2.0.38 # via -r requirements.piptools typing-extensions==4.12.2 # via # python-utils # sqlalchemy -werkzeug==3.0.4 +werkzeug==3.1.3 # via flask diff --git a/app/ch12-forms/final/requirements.txt b/app/ch12-forms/final/requirements.txt index c7dbe9a5..19fc8c45 100644 --- a/app/ch12-forms/final/requirements.txt +++ b/app/ch12-forms/final/requirements.txt @@ -1,35 +1,35 @@ # This file was autogenerated by uv via the following command: # uv pip compile requirements.piptools --output-file requirements.txt -alembic==1.13.2 +alembic==1.14.1 # via -r requirements.piptools -blinker==1.8.2 +blinker==1.9.0 # via flask -click==8.1.7 +click==8.1.8 # via flask -flask==3.0.3 +flask==3.1.0 # via -r requirements.piptools itsdangerous==2.2.0 # via flask -jinja2==3.1.4 +jinja2==3.1.5 # via flask -mako==1.3.5 +mako==1.3.9 # via alembic -markupsafe==2.1.5 +markupsafe==3.0.2 # via # jinja2 # mako # werkzeug passlib==1.7.4 # via -r requirements.piptools -progressbar2==4.4.2 +progressbar2==4.5.0 # via -r requirements.piptools python-dateutil==2.9.0.post0 # via -r requirements.piptools -python-utils==3.8.2 +python-utils==3.9.1 # via progressbar2 -six==1.16.0 +six==1.17.0 # via python-dateutil -sqlalchemy==2.0.32 +sqlalchemy==2.0.38 # via # -r requirements.piptools # alembic @@ -38,5 +38,5 @@ typing-extensions==4.12.2 # alembic # python-utils # sqlalchemy -werkzeug==3.0.4 +werkzeug==3.1.3 # via flask diff --git a/app/ch12-forms/starter/requirements.txt b/app/ch12-forms/starter/requirements.txt index 8a6a1923..d802976d 100644 --- a/app/ch12-forms/starter/requirements.txt +++ b/app/ch12-forms/starter/requirements.txt @@ -1,33 +1,33 @@ # This file was autogenerated by uv via the following command: # uv pip compile requirements.piptools --output-file requirements.txt -alembic==1.13.2 +alembic==1.14.1 # via -r requirements.piptools -blinker==1.8.2 +blinker==1.9.0 # via flask -click==8.1.7 +click==8.1.8 # via flask -flask==3.0.3 +flask==3.1.0 # via -r requirements.piptools itsdangerous==2.2.0 # via flask -jinja2==3.1.4 +jinja2==3.1.5 # via flask -mako==1.3.5 +mako==1.3.9 # via alembic -markupsafe==2.1.5 +markupsafe==3.0.2 # via # jinja2 # mako # werkzeug -progressbar2==4.4.2 +progressbar2==4.5.0 # via -r requirements.piptools python-dateutil==2.9.0.post0 # via -r requirements.piptools -python-utils==3.8.2 +python-utils==3.9.1 # via progressbar2 -six==1.16.0 +six==1.17.0 # via python-dateutil -sqlalchemy==2.0.32 +sqlalchemy==2.0.38 # via # -r requirements.piptools # alembic @@ -36,5 +36,5 @@ typing-extensions==4.12.2 # alembic # python-utils # sqlalchemy -werkzeug==3.0.4 +werkzeug==3.1.3 # via flask diff --git a/app/ch13-validation/final/requirements.txt b/app/ch13-validation/final/requirements.txt index c7dbe9a5..19fc8c45 100644 --- a/app/ch13-validation/final/requirements.txt +++ b/app/ch13-validation/final/requirements.txt @@ -1,35 +1,35 @@ # This file was autogenerated by uv via the following command: # uv pip compile requirements.piptools --output-file requirements.txt -alembic==1.13.2 +alembic==1.14.1 # via -r requirements.piptools -blinker==1.8.2 +blinker==1.9.0 # via flask -click==8.1.7 +click==8.1.8 # via flask -flask==3.0.3 +flask==3.1.0 # via -r requirements.piptools itsdangerous==2.2.0 # via flask -jinja2==3.1.4 +jinja2==3.1.5 # via flask -mako==1.3.5 +mako==1.3.9 # via alembic -markupsafe==2.1.5 +markupsafe==3.0.2 # via # jinja2 # mako # werkzeug passlib==1.7.4 # via -r requirements.piptools -progressbar2==4.4.2 +progressbar2==4.5.0 # via -r requirements.piptools python-dateutil==2.9.0.post0 # via -r requirements.piptools -python-utils==3.8.2 +python-utils==3.9.1 # via progressbar2 -six==1.16.0 +six==1.17.0 # via python-dateutil -sqlalchemy==2.0.32 +sqlalchemy==2.0.38 # via # -r requirements.piptools # alembic @@ -38,5 +38,5 @@ typing-extensions==4.12.2 # alembic # python-utils # sqlalchemy -werkzeug==3.0.4 +werkzeug==3.1.3 # via flask diff --git a/app/ch13-validation/starter/requirements.txt b/app/ch13-validation/starter/requirements.txt index c7dbe9a5..19fc8c45 100644 --- a/app/ch13-validation/starter/requirements.txt +++ b/app/ch13-validation/starter/requirements.txt @@ -1,35 +1,35 @@ # This file was autogenerated by uv via the following command: # uv pip compile requirements.piptools --output-file requirements.txt -alembic==1.13.2 +alembic==1.14.1 # via -r requirements.piptools -blinker==1.8.2 +blinker==1.9.0 # via flask -click==8.1.7 +click==8.1.8 # via flask -flask==3.0.3 +flask==3.1.0 # via -r requirements.piptools itsdangerous==2.2.0 # via flask -jinja2==3.1.4 +jinja2==3.1.5 # via flask -mako==1.3.5 +mako==1.3.9 # via alembic -markupsafe==2.1.5 +markupsafe==3.0.2 # via # jinja2 # mako # werkzeug passlib==1.7.4 # via -r requirements.piptools -progressbar2==4.4.2 +progressbar2==4.5.0 # via -r requirements.piptools python-dateutil==2.9.0.post0 # via -r requirements.piptools -python-utils==3.8.2 +python-utils==3.9.1 # via progressbar2 -six==1.16.0 +six==1.17.0 # via python-dateutil -sqlalchemy==2.0.32 +sqlalchemy==2.0.38 # via # -r requirements.piptools # alembic @@ -38,5 +38,5 @@ typing-extensions==4.12.2 # alembic # python-utils # sqlalchemy -werkzeug==3.0.4 +werkzeug==3.1.3 # via flask diff --git a/app/ch14_testing/final/requirements.txt b/app/ch14_testing/final/requirements.txt index c7dbe9a5..19fc8c45 100644 --- a/app/ch14_testing/final/requirements.txt +++ b/app/ch14_testing/final/requirements.txt @@ -1,35 +1,35 @@ # This file was autogenerated by uv via the following command: # uv pip compile requirements.piptools --output-file requirements.txt -alembic==1.13.2 +alembic==1.14.1 # via -r requirements.piptools -blinker==1.8.2 +blinker==1.9.0 # via flask -click==8.1.7 +click==8.1.8 # via flask -flask==3.0.3 +flask==3.1.0 # via -r requirements.piptools itsdangerous==2.2.0 # via flask -jinja2==3.1.4 +jinja2==3.1.5 # via flask -mako==1.3.5 +mako==1.3.9 # via alembic -markupsafe==2.1.5 +markupsafe==3.0.2 # via # jinja2 # mako # werkzeug passlib==1.7.4 # via -r requirements.piptools -progressbar2==4.4.2 +progressbar2==4.5.0 # via -r requirements.piptools python-dateutil==2.9.0.post0 # via -r requirements.piptools -python-utils==3.8.2 +python-utils==3.9.1 # via progressbar2 -six==1.16.0 +six==1.17.0 # via python-dateutil -sqlalchemy==2.0.32 +sqlalchemy==2.0.38 # via # -r requirements.piptools # alembic @@ -38,5 +38,5 @@ typing-extensions==4.12.2 # alembic # python-utils # sqlalchemy -werkzeug==3.0.4 +werkzeug==3.1.3 # via flask diff --git a/app/ch14_testing/starter/requirements.txt b/app/ch14_testing/starter/requirements.txt index c7dbe9a5..19fc8c45 100644 --- a/app/ch14_testing/starter/requirements.txt +++ b/app/ch14_testing/starter/requirements.txt @@ -1,35 +1,35 @@ # This file was autogenerated by uv via the following command: # uv pip compile requirements.piptools --output-file requirements.txt -alembic==1.13.2 +alembic==1.14.1 # via -r requirements.piptools -blinker==1.8.2 +blinker==1.9.0 # via flask -click==8.1.7 +click==8.1.8 # via flask -flask==3.0.3 +flask==3.1.0 # via -r requirements.piptools itsdangerous==2.2.0 # via flask -jinja2==3.1.4 +jinja2==3.1.5 # via flask -mako==1.3.5 +mako==1.3.9 # via alembic -markupsafe==2.1.5 +markupsafe==3.0.2 # via # jinja2 # mako # werkzeug passlib==1.7.4 # via -r requirements.piptools -progressbar2==4.4.2 +progressbar2==4.5.0 # via -r requirements.piptools python-dateutil==2.9.0.post0 # via -r requirements.piptools -python-utils==3.8.2 +python-utils==3.9.1 # via progressbar2 -six==1.16.0 +six==1.17.0 # via python-dateutil -sqlalchemy==2.0.32 +sqlalchemy==2.0.38 # via # -r requirements.piptools # alembic @@ -38,5 +38,5 @@ typing-extensions==4.12.2 # alembic # python-utils # sqlalchemy -werkzeug==3.0.4 +werkzeug==3.1.3 # via flask diff --git a/app/ch15_deploy/final/requirements.txt b/app/ch15_deploy/final/requirements.txt index c7dbe9a5..19fc8c45 100644 --- a/app/ch15_deploy/final/requirements.txt +++ b/app/ch15_deploy/final/requirements.txt @@ -1,35 +1,35 @@ # This file was autogenerated by uv via the following command: # uv pip compile requirements.piptools --output-file requirements.txt -alembic==1.13.2 +alembic==1.14.1 # via -r requirements.piptools -blinker==1.8.2 +blinker==1.9.0 # via flask -click==8.1.7 +click==8.1.8 # via flask -flask==3.0.3 +flask==3.1.0 # via -r requirements.piptools itsdangerous==2.2.0 # via flask -jinja2==3.1.4 +jinja2==3.1.5 # via flask -mako==1.3.5 +mako==1.3.9 # via alembic -markupsafe==2.1.5 +markupsafe==3.0.2 # via # jinja2 # mako # werkzeug passlib==1.7.4 # via -r requirements.piptools -progressbar2==4.4.2 +progressbar2==4.5.0 # via -r requirements.piptools python-dateutil==2.9.0.post0 # via -r requirements.piptools -python-utils==3.8.2 +python-utils==3.9.1 # via progressbar2 -six==1.16.0 +six==1.17.0 # via python-dateutil -sqlalchemy==2.0.32 +sqlalchemy==2.0.38 # via # -r requirements.piptools # alembic @@ -38,5 +38,5 @@ typing-extensions==4.12.2 # alembic # python-utils # sqlalchemy -werkzeug==3.0.4 +werkzeug==3.1.3 # via flask diff --git a/app/ch15_deploy/starter/requirements.txt b/app/ch15_deploy/starter/requirements.txt index c7dbe9a5..19fc8c45 100644 --- a/app/ch15_deploy/starter/requirements.txt +++ b/app/ch15_deploy/starter/requirements.txt @@ -1,35 +1,35 @@ # This file was autogenerated by uv via the following command: # uv pip compile requirements.piptools --output-file requirements.txt -alembic==1.13.2 +alembic==1.14.1 # via -r requirements.piptools -blinker==1.8.2 +blinker==1.9.0 # via flask -click==8.1.7 +click==8.1.8 # via flask -flask==3.0.3 +flask==3.1.0 # via -r requirements.piptools itsdangerous==2.2.0 # via flask -jinja2==3.1.4 +jinja2==3.1.5 # via flask -mako==1.3.5 +mako==1.3.9 # via alembic -markupsafe==2.1.5 +markupsafe==3.0.2 # via # jinja2 # mako # werkzeug passlib==1.7.4 # via -r requirements.piptools -progressbar2==4.4.2 +progressbar2==4.5.0 # via -r requirements.piptools python-dateutil==2.9.0.post0 # via -r requirements.piptools -python-utils==3.8.2 +python-utils==3.9.1 # via progressbar2 -six==1.16.0 +six==1.17.0 # via python-dateutil -sqlalchemy==2.0.32 +sqlalchemy==2.0.38 # via # -r requirements.piptools # alembic @@ -38,5 +38,5 @@ typing-extensions==4.12.2 # alembic # python-utils # sqlalchemy -werkzeug==3.0.4 +werkzeug==3.1.3 # via flask diff --git a/app/ch16_mongodb/final/requirements.txt b/app/ch16_mongodb/final/requirements.txt index 85b126c8..4dbe5e95 100644 --- a/app/ch16_mongodb/final/requirements.txt +++ b/app/ch16_mongodb/final/requirements.txt @@ -1,52 +1,48 @@ -# -# This file is autogenerated by pip-compile with Python 3.11 -# by the following command: -# -# pip-compile requirements.piptools -# -alembic==1.13.0 +# This file was autogenerated by uv via the following command: +# uv pip compile requirements.piptools --output-file requirements.txt +alembic==1.14.1 # via -r requirements.piptools -blinker==1.7.0 +blinker==1.9.0 # via flask -click==8.1.7 +click==8.1.8 # via flask -dnspython==2.4.2 +dnspython==2.7.0 # via pymongo -flask==3.0.0 +flask==3.1.0 # via -r requirements.piptools -itsdangerous==2.1.2 +itsdangerous==2.2.0 # via flask -jinja2==3.1.2 +jinja2==3.1.5 # via flask -mako==1.3.0 +mako==1.3.9 # via alembic -markupsafe==2.1.3 +markupsafe==3.0.2 # via # jinja2 # mako # werkzeug -mongoengine==0.27.0 +mongoengine==0.29.1 # via -r requirements.piptools passlib==1.7.4 # via -r requirements.piptools -progressbar2==4.2.0 +progressbar2==4.5.0 # via -r requirements.piptools -pymongo==4.6.1 +pymongo==4.11.1 # via mongoengine -python-dateutil==2.8.2 +python-dateutil==2.9.0.post0 # via -r requirements.piptools -python-utils==3.8.1 +python-utils==3.9.1 # via progressbar2 -six==1.16.0 +six==1.17.0 # via python-dateutil -sqlalchemy==2.0.23 +sqlalchemy==2.0.38 # via # -r requirements.piptools # alembic -typing-extensions==4.9.0 +typing-extensions==4.12.2 # via # alembic # python-utils # sqlalchemy -werkzeug==3.0.1 +werkzeug==3.1.3 # via flask diff --git a/app/ch16_mongodb/starter/requirements.txt b/app/ch16_mongodb/starter/requirements.txt index 662fe297..19fc8c45 100644 --- a/app/ch16_mongodb/starter/requirements.txt +++ b/app/ch16_mongodb/starter/requirements.txt @@ -1,46 +1,42 @@ -# -# This file is autogenerated by pip-compile with Python 3.11 -# by the following command: -# -# pip-compile requirements.piptools -# -alembic==1.13.0 +# This file was autogenerated by uv via the following command: +# uv pip compile requirements.piptools --output-file requirements.txt +alembic==1.14.1 # via -r requirements.piptools -blinker==1.7.0 +blinker==1.9.0 # via flask -click==8.1.7 +click==8.1.8 # via flask -flask==3.0.0 +flask==3.1.0 # via -r requirements.piptools -itsdangerous==2.1.2 +itsdangerous==2.2.0 # via flask -jinja2==3.1.2 +jinja2==3.1.5 # via flask -mako==1.3.0 +mako==1.3.9 # via alembic -markupsafe==2.1.3 +markupsafe==3.0.2 # via # jinja2 # mako # werkzeug passlib==1.7.4 # via -r requirements.piptools -progressbar2==4.2.0 +progressbar2==4.5.0 # via -r requirements.piptools -python-dateutil==2.8.2 +python-dateutil==2.9.0.post0 # via -r requirements.piptools -python-utils==3.8.1 +python-utils==3.9.1 # via progressbar2 -six==1.16.0 +six==1.17.0 # via python-dateutil -sqlalchemy==2.0.23 +sqlalchemy==2.0.38 # via # -r requirements.piptools # alembic -typing-extensions==4.9.0 +typing-extensions==4.12.2 # via # alembic # python-utils # sqlalchemy -werkzeug==3.0.1 +werkzeug==3.1.3 # via flask From 1aa9e14c2280468c657fab6d1f95f74f79e8ff01 Mon Sep 17 00:00:00 2001 From: Michael Kennedy Date: Sun, 2 Mar 2025 09:35:13 -0800 Subject: [PATCH 44/44] Update to latest versions of libraries. --- requirements.txt | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/requirements.txt b/requirements.txt index 42fb216b..4dbe5e95 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,41 +1,41 @@ # This file was autogenerated by uv via the following command: # uv pip compile requirements.piptools --output-file requirements.txt -alembic==1.13.2 +alembic==1.14.1 # via -r requirements.piptools -blinker==1.8.2 +blinker==1.9.0 # via flask -click==8.1.7 +click==8.1.8 # via flask -dnspython==2.6.1 +dnspython==2.7.0 # via pymongo -flask==3.0.3 +flask==3.1.0 # via -r requirements.piptools itsdangerous==2.2.0 # via flask -jinja2==3.1.4 +jinja2==3.1.5 # via flask -mako==1.3.5 +mako==1.3.9 # via alembic -markupsafe==2.1.5 +markupsafe==3.0.2 # via # jinja2 # mako # werkzeug -mongoengine==0.29.0 +mongoengine==0.29.1 # via -r requirements.piptools passlib==1.7.4 # via -r requirements.piptools -progressbar2==4.4.2 +progressbar2==4.5.0 # via -r requirements.piptools -pymongo==4.8.0 +pymongo==4.11.1 # via mongoengine python-dateutil==2.9.0.post0 # via -r requirements.piptools -python-utils==3.8.2 +python-utils==3.9.1 # via progressbar2 -six==1.16.0 +six==1.17.0 # via python-dateutil -sqlalchemy==2.0.32 +sqlalchemy==2.0.38 # via # -r requirements.piptools # alembic @@ -44,5 +44,5 @@ typing-extensions==4.12.2 # alembic # python-utils # sqlalchemy -werkzeug==3.0.4 +werkzeug==3.1.3 # via flask