Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Binding DB sessions based on SQLAlchemy 1, changing how to declare Base Model classes, and other code modernization #50

Open
wants to merge 19 commits into
base: master
Choose a base branch
from

Conversation

search5
Copy link

@search5 search5 commented Feb 24, 2024

  • DB session binding based on SQLAlchemy 2, Base Model class declaration method change
  • Reflected select, delete code based on SQLAlchemy 2
  • Changed how to declare Model class based on SQLAlchemy 2
  • Fixed social login not connecting issue found while testing example program code (for example-pyramid)
  • Fixed issue with social connection termination (for example-cherrypy, example-tornado, example-webpy)
  • Added local_settings.py.template file to some example folders to make it easier to create local_settings.py files
  • Fixed import errors found in several examples

Proposed changes

With the introduction of PEP 517/518, the Python package build process has changed to allow the use of multiple build backends. We've improved the build process accordingly.
In addition, we improved the program to ensure that several previously developed libraries work properly with the newly updated SQLAlchemy 2 in January 2023.

Please consider this PR and look forward to the new version release. I took the time to fix the program and submit the patch because I'm planning to include it in a Korean Flask-based programming book I'm writing.

Types of changes

Please check the type of change your PR introduces:

  • Release (new release request)
  • Bugfix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Code style update (PEP8, lint, formatting, renaming, etc)
  • Refactoring (no functional changes, no api changes)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Build related changes (build process, tests runner, etc)
  • Other (please describe):

Checklist

Put an x in the boxes that apply. You can also fill these out after creating
the PR. If you're unsure about any of them, don't hesitate to ask. We're here to
help! This is simply a reminder of what we are going to look for before merging
your code.

  • Lint and unit tests pass locally with my changes
  • I have added tests that prove my fix is effective or that my feature works
  • I have added documentation to https://github.com/python-social-auth/social-docs
  • I created a running environment for the program and carefully verified that my modifications worked.

Summary by CodeRabbit

  • Bug Fixes

    • Addressed import issues across several examples (CherryPy, WebPy, Flask).
    • Fixed DB session handling and model creation for SQLAlchemy 2 compatibility.
  • New Features

    • Introduced templates for easier configuration in Tornado and WebPy examples.
  • Refactor

    • Removed flask-script dependency, transitioning to Flask's built-in CLI.
    • Updated session management from db_session.remove() to db_session.close().
    • Refactored command line management in Flask, Flask-MongoEngine, and Flask-Peewee examples to use click and FlaskGroup.
    • Enhanced readability and structure in filters.py, pipeline.py, and utils.py across examples.
    • Modified SQLAlchemy column declarations using Mapped and mapped_column for improved type hinting.
  • Chores

    • Added # noqa: F401 comments to suppress unused import warnings in Django and Django-MongoEngine examples.
  • Documentation

    • Improved error message clarity in CherryPy example.

이지호 and others added 2 commits February 24, 2024 13:39
…se Model classes, and other code modernization

- DB session binding based on SQLAlchemy 2, Base Model class declaration method change
- Reflected select, delete code based on SQLAlchemy 2
- Changed how to declare Model class based on SQLAlchemy 2
- Fixed social login not connecting issue found while testing example program code (for example-pyramid)
- Fixed issue with social connection termination (for example-cherrypy, example-tornado, example-webpy)
- Added local_settings.py.template file to some example folders to make it easier to create local_settings.py files
- Fixed import errors found in several examples
Copy link

coderabbitai bot commented Feb 24, 2024

Warning

Rate Limit Exceeded

@pre-commit-ci[bot] has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 21 minutes and 8 seconds before requesting another review.

How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.
Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.
Please see our FAQ for further information.

Commits Files that changed from the base of the PR and between dbc3d62 and e6b31e0.

Walkthrough

This update focuses on enhancing compatibility with SQLAlchemy 2 across various Python web frameworks, removing deprecated dependencies, and refining the codebase for better configuration and readability. It addresses import bugs, session handling, and model creation adjustments, alongside removing the flask-script dependency and introducing template configurations for easier setup.

Changes

Files Summary
example-cherrypy/example/app.py, example-tornado/example/app.py, example-webpy/app.py Updated import statements, session handling, and SQLAlchemy column declarations. Introduced template configuration.
example-flask/example/__init__.py, example-flask-mongoengine/manage.py, example-flask-peewee/manage.py, example-flask/manage.py Removed flask-script dependency, refactored for click and FlaskGroup, updated session and SQLAlchemy handling.
example-pyramid/example/__init__.py, example-django-mongoengine/app/views.py, example-django/app/views.py Adjusted DB session binding, removed Google Plus ID retrieval, and updated social login key handling.
example-common/..., example-django-mongoengine/..., example-django/..., example-flask-mongoengine/..., example-flask-peewee/..., example-flask/... Various readability and code quality improvements.

Related issues

Poem

In the land of code, where the rabbits hop,
Changes abound, making old bugs stop.
SQLAlchemy two, now friends with all,
Flask-script gone, no longer to stall.
🐇 With every commit, we leap and cheer,
For cleaner code, the goal is near.
Let's celebrate, with carrots near, this code so dear! 🥕

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

Share

Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>.
    • Generate unit-tests for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit tests for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai generate interesting stats about this repository and render them as a table.
    • @coderabbitai show all the console.log statements in this repository.
    • @coderabbitai read src/utils.ts and generate unit tests.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (invoked as PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger a review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai help to get help.

Additionally, you can add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.

CodeRabbit Configration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • The JSON schema for the configuration file is available here.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/coderabbit-overrides.v2.json

CodeRabbit Discord Community

Join our Discord Community to get help, request features, and share feedback.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review Status

Actionable comments generated: 0

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between fe5a005 and 93b4de1.
Files selected for processing (27)
  • CHANGELOG.md (1 hunks)
  • example-cherrypy/example/app.py (3 hunks)
  • example-cherrypy/example/db/init.py (1 hunks)
  • example-cherrypy/example/db/saplugin.py (3 hunks)
  • example-cherrypy/example/db/user.py (1 hunks)
  • example-flask-mongoengine/manage.py (1 hunks)
  • example-flask-mongoengine/requirements.txt (1 hunks)
  • example-flask-peewee/manage.py (2 hunks)
  • example-flask-peewee/requirements.txt (1 hunks)
  • example-flask/example/init.py (4 hunks)
  • example-flask/example/models/user.py (1 hunks)
  • example-flask/manage.py (2 hunks)
  • example-flask/requirements.txt (1 hunks)
  • example-pyramid/example/init.py (1 hunks)
  • example-pyramid/example/auth.py (2 hunks)
  • example-pyramid/example/local_settings.py.template (1 hunks)
  • example-pyramid/example/models.py (1 hunks)
  • example-pyramid/example/scripts/initializedb.py (1 hunks)
  • example-pyramid/example/views.py (1 hunks)
  • example-tornado/example/app.py (3 hunks)
  • example-tornado/example/local_settings.py.template (1 hunks)
  • example-tornado/example/models.py (1 hunks)
  • example-tornado/example/settings.py (1 hunks)
  • example-webpy/app.py (3 hunks)
  • example-webpy/local_settings.py.template (1 hunks)
  • example-webpy/models.py (1 hunks)
  • example-webpy/settings.py (1 hunks)
Files skipped from review due to trivial changes (1)
  • example-flask-mongoengine/requirements.txt
Additional comments: 37
example-flask-peewee/requirements.txt (1)
  • 1-2: The changes in the requirements.txt file, removing flask-script and adding social-auth-app-flask-peewee, align with the PR's objectives for modernization and enhancing social authentication support. Ensure to thoroughly test the application to verify that these changes do not introduce any issues.
example-cherrypy/example/db/__init__.py (1)
  • 1-4: The update to import DeclarativeBase from sqlalchemy.orm and the definition of the Base class to inherit from DeclarativeBase correctly align with SQLAlchemy 2 compatibility requirements. This is a well-implemented change.
example-flask/requirements.txt (1)
  • 1-6: The removal of Flask-Script from the requirements.txt file is in line with modernizing the codebase and transitioning to Flask's built-in CLI. Ensure comprehensive testing to confirm that this change integrates smoothly with the rest of the application.
example-flask-mongoengine/manage.py (1)
  • 1-17: The refactoring of the manage.py script to use click and FlaskGroup is correctly implemented, aligning with modern Flask CLI practices. This change enhances the maintainability and readability of the script.
example-flask/manage.py (1)
  • 1-17: > 📝 NOTE

This review was outside the diff hunks and was mapped to the diff hunk with the greatest overlap. Original lines [1-24]

The refactoring of the manage.py script to utilize click and FlaskGroup for command line management is well-executed, aligning with Flask's recommendations for CLI usage. This modern approach enhances the script's maintainability and usability.

example-cherrypy/example/db/user.py (1)
  • 1-15: The refactoring of the User class to use Mapped and mapped_column for SQLAlchemy column declarations aligns with SQLAlchemy 2 compatibility and best practices. This change enhances clarity and maintainability of the model definitions.
example-flask-peewee/manage.py (1)
  • 1-15: > 📝 NOTE

This review was outside the diff hunks and was mapped to the diff hunk with the greatest overlap. Original lines [1-30]

The update of the manage.py script to use click and FlaskGroup for command handling is correctly implemented, aligning with modern Flask CLI practices. This enhances the script's maintainability and readability.

example-tornado/example/models.py (1)
  • 1-14: The update to use Mapped and mapped_column for SQLAlchemy column declarations in the models.py file aligns with SQLAlchemy 2 compatibility and best practices. This enhances the clarity and maintainability of the model definitions.
example-pyramid/example/auth.py (1)
  • 1-5: > 📝 NOTE

This review was outside the diff hunks and was mapped to the diff hunk with the greatest overlap. Original lines [1-18]

The modification to use DBSession.scalar(select(User).where(User.id == user_id)) in the get_user function aligns with SQLAlchemy 2 querying best practices. This change ensures compatibility and enhances the clarity of the query execution.

example-webpy/models.py (1)
  • 1-19: The update to use Mapped and mapped_column for SQLAlchemy column declarations in the models.py file aligns with SQLAlchemy 2 compatibility and best practices. This enhances the clarity and maintainability of the model definitions.
example-flask/example/models/user.py (1)
  • 1-19: The modifications in the User class to use mapped_column for column definitions and specifying types explicitly using Mapped align with SQLAlchemy 2 compatibility and best practices. This enhances the clarity and maintainability of the model definitions.
example-pyramid/example/models.py (1)
  • 1-23: The update to use Mapped and mapped_column for SQLAlchemy column declarations in the models.py file aligns with SQLAlchemy 2 compatibility and best practices. This enhances the clarity and maintainability of the model definitions.
example-pyramid/example/scripts/initializedb.py (1)
  • 28-34: > 📝 NOTE

This review was outside the diff hunks and was mapped to the diff hunk with the greatest overlap. Original lines [1-31]

The modification in the initializedb.py script to set the DBSession.bind attribute directly to the engine aligns with SQLAlchemy 2 session management practices. This change ensures proper session binding in a clear and effective manner.

example-cherrypy/example/db/saplugin.py (1)
  • 1-13: > 📝 NOTE

This review was outside the diff hunks and was mapped to the diff hunk with the greatest overlap. Original lines [1-36]

The update in the saplugin.py file to replace scoped_session with Session and adjust the session's bind attribute directly to the SQLAlchemy engine instance aligns with SQLAlchemy 2 compatibility and session management best practices. This change enhances clarity and maintainability of the session management.

example-pyramid/example/views.py (1)
  • 21-26: > 📝 NOTE

This review was outside the diff hunks and was mapped to the diff hunk with the greatest overlap. Original lines [1-29]

The removal of the plus_id parameter in the done function is appropriate, reflecting the discontinuation of Google Plus. This cleanup enhances the code's relevance and maintainability by removing references to a deprecated service.

example-pyramid/example/__init__.py (1)
  • 22-28: > 📝 NOTE

This review was outside the diff hunks and was mapped to the diff hunk with the greatest overlap. Original lines [1-25]

The modification in the example/__init__.py file to set the DBSession.bind attribute directly to the engine aligns with SQLAlchemy 2 session management practices. This change ensures proper session binding in a clear and effective manner.

example-pyramid/example/local_settings.py.template (1)
  • 1-89: The conversion of social authentication keys into individual variables in the local_settings.py.template file simplifies the configuration process and enhances the clarity and maintainability of the settings. This is a well-implemented improvement.
example-tornado/example/local_settings.py.template (1)
  • 1-89: The update to convert social authentication keys into individual variables in the local_settings.py.template file simplifies the configuration process and enhances the clarity and maintainability of the settings. This is a positive improvement.
example-webpy/local_settings.py.template (1)
  • 1-89: The conversion of social authentication keys into individual variables in the local_settings.py.template file simplifies the configuration process and enhances the clarity and maintainability of the settings. This is a commendable improvement.
CHANGELOG.md (1)
  • 15-29: The changelog provides a comprehensive summary of the changes made for SQLAlchemy 2 compatibility, social login fixes, and other improvements. It's clear and well-structured, making it easy for readers to understand the scope of the updates.
example-flask/example/__init__.py (4)
  • 13-13: The import of Session from sqlalchemy.orm is correctly done to support SQLAlchemy 2's session management.
  • 28-28: The initialization of db_session using Session(engine, autocommit=False, autoflush=False) aligns with SQLAlchemy 2's recommended practices for session management. This ensures that the session is correctly configured for transaction management.
  • 44-44: The use of db_session.get(models.user.User, int(userid)) for user loading is a good practice, leveraging SQLAlchemy 2's simplified API for fetching records by primary key.
  • 62-62: Replacing db_session.remove() with db_session.close() for SQLAlchemy 2 compatibility is correctly implemented. This ensures proper session closure at the end of the request lifecycle.
example-tornado/example/app.py (4)
  • 3-3: The explicit import of settings from the example module is a good practice, ensuring clarity in where the settings are being loaded from.
  • 12-12: The import of Session and DeclarativeBase from sqlalchemy.orm is correctly done to support SQLAlchemy 2's session management and model declaration.
  • 19-20: Initializing the session with Session(engine) is correctly implemented for SQLAlchemy 2 compatibility, ensuring that the session is correctly configured for the application.
  • 33-33: The use of session.get(User, int(user_id)) for querying the User model is a good practice, leveraging SQLAlchemy 2's simplified API for fetching records by primary key within a Tornado application.
example-webpy/app.py (4)
  • 3-4: The explicit import of settings and local_settings from the example module is a good practice, ensuring clarity in where the settings are being loaded from.
  • 11-11: The import of Session from sqlalchemy.orm is correctly done to support SQLAlchemy 2's session management in a web.py application.
  • 18-19: Simplifying the configuration of AUTHENTICATION_BACKENDS and PIPELINE settings by directly using values from settings is a good practice, enhancing readability and maintainability of the code.
  • 95-95: Replacing scoped_session with Session(engine) for SQLAlchemy 2 compatibility in the load_sqla processor is correctly implemented, ensuring proper session management in web.py applications.
example-cherrypy/example/app.py (3)
  • 5-5: The explicit import of settings from the example module is a good practice, ensuring clarity in where the settings are being loaded from in a CherryPy application.
  • 69-69: Importing local_settings explicitly from the example module enhances clarity and maintainability by specifying the exact location of the settings.
  • 85-85: Modifying the session storage setting to use cherrypy.lib.sessions.RamSession aligns with CherryPy's recommended practices for session management, ensuring efficient and appropriate session storage.
example-tornado/example/settings.py (1)
  • 111-111: Updating the import statement to reference example.local_settings is a good practice, ensuring clarity and maintainability by specifying the exact location of the local settings module.
example-webpy/settings.py (1)
  • 1-103: The configuration of SOCIAL_AUTH_AUTHENTICATION_BACKENDS and SOCIAL_AUTH_PIPELINE in example-webpy/settings.py is comprehensive and correctly lists the supported authentication backends and the steps in the authentication pipeline. This ensures a flexible and customizable authentication process for the application.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review Status

Actionable comments generated: 0

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between 93b4de1 and e063508.
Files selected for processing (12)
  • example-cherrypy/example/app.py (3 hunks)
  • example-cherrypy/example/db/init.py (1 hunks)
  • example-cherrypy/example/db/user.py (1 hunks)
  • example-flask-mongoengine/manage.py (1 hunks)
  • example-flask-peewee/manage.py (2 hunks)
  • example-flask/example/models/user.py (1 hunks)
  • example-flask/manage.py (2 hunks)
  • example-pyramid/example/auth.py (2 hunks)
  • example-pyramid/example/models.py (1 hunks)
  • example-tornado/example/app.py (2 hunks)
  • example-tornado/example/models.py (1 hunks)
  • example-webpy/app.py (3 hunks)
Files skipped from review as they are similar to previous changes (12)
  • example-cherrypy/example/app.py
  • example-cherrypy/example/db/init.py
  • example-cherrypy/example/db/user.py
  • example-flask-mongoengine/manage.py
  • example-flask-peewee/manage.py
  • example-flask/example/models/user.py
  • example-flask/manage.py
  • example-pyramid/example/auth.py
  • example-pyramid/example/models.py
  • example-tornado/example/app.py
  • example-tornado/example/models.py
  • example-webpy/app.py

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review Status

Actionable comments generated: 3

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between e063508 and 55c7d74.
Files selected for processing (34)
  • example-cherrypy/example/app.py (5 hunks)
  • example-cherrypy/example/db/saplugin.py (2 hunks)
  • example-cherrypy/example/db/user.py (1 hunks)
  • example-cherrypy/manage.py (1 hunks)
  • example-common/filters.py (1 hunks)
  • example-django-mongoengine/app/admin.py (1 hunks)
  • example-django-mongoengine/app/templatetags/backend_utils.py (1 hunks)
  • example-django-mongoengine/app/tests.py (1 hunks)
  • example-django-mongoengine/app/views.py (1 hunks)
  • example-django-mongoengine/example/settings.py (1 hunks)
  • example-django-mongoengine/manage.py (1 hunks)
  • example-django/app/admin.py (1 hunks)
  • example-django/app/templatetags/backend_utils.py (1 hunks)
  • example-django/app/tests.py (1 hunks)
  • example-django/app/views.py (1 hunks)
  • example-django/example/settings.py (1 hunks)
  • example-django/manage.py (1 hunks)
  • example-flask-mongoengine/example/init.py (2 hunks)
  • example-flask-mongoengine/example/models/init.py (1 hunks)
  • example-flask-mongoengine/example/models/user.py (1 hunks)
  • example-flask-mongoengine/example/routes/init.py (1 hunks)
  • example-flask-mongoengine/example/settings.py (1 hunks)
  • example-flask-peewee/example/init.py (2 hunks)
  • example-flask-peewee/example/models/init.py (1 hunks)
  • example-flask-peewee/example/routes/init.py (1 hunks)
  • example-flask-peewee/manage.py (2 hunks)
  • example-flask/example/init.py (4 hunks)
  • example-flask/example/models/init.py (1 hunks)
  • example-flask/example/models/user.py (1 hunks)
  • example-flask/example/routes/init.py (1 hunks)
  • example-pyramid/example/init.py (2 hunks)
  • example-tornado/example/settings.py (1 hunks)
  • example-tornado/manage.py (1 hunks)
  • example-webpy/app.py (2 hunks)
Files skipped from review due to trivial changes (17)
  • example-django-mongoengine/app/admin.py
  • example-django-mongoengine/app/templatetags/backend_utils.py
  • example-django-mongoengine/app/tests.py
  • example-django-mongoengine/example/settings.py
  • example-django-mongoengine/manage.py
  • example-django/app/admin.py
  • example-django/app/templatetags/backend_utils.py
  • example-django/app/tests.py
  • example-django/example/settings.py
  • example-django/manage.py
  • example-flask-mongoengine/example/models/init.py
  • example-flask-mongoengine/example/routes/init.py
  • example-flask-mongoengine/example/settings.py
  • example-flask-peewee/example/routes/init.py
  • example-flask/example/models/init.py
  • example-flask/example/routes/init.py
  • example-tornado/manage.py
Additional comments: 24
example-flask-peewee/example/models/__init__.py (1)
  • 1-2: The addition of # noqa: F401 comments to suppress linting errors for unused imports is a common and acceptable practice in Python, especially in __init__.py files where imports are made to simplify access to modules throughout the application. This change aligns with the PR's objectives of modernizing the codebase and fixing import errors.
example-flask-mongoengine/example/models/user.py (1)
  • 3-3: The removal of ListField and ReferenceField imports from mongoengine is justified, as there is no usage of these fields in the User model. This change aligns with the PR's objectives of modernizing the codebase and possibly simplifying the data models.
example-cherrypy/manage.py (1)
  • 6-8: The reordering and removal of redundant imports in this file improve code readability and maintainability. These changes align with the PR's objectives of modernizing the codebase and enhancing clarity.
example-cherrypy/example/db/user.py (1)
  • 11-16: The replacement of traditional SQLAlchemy column declarations with Mapped and mapped_column using type hints is a significant improvement. This change aligns with SQLAlchemy 2's features, enhancing code readability and static type checking. It directly supports the PR's objectives of updating the codebase for SQLAlchemy 2 compatibility.
example-flask-peewee/manage.py (1)
  • 1-15: > 📝 NOTE

This review was outside the diff hunks and was mapped to the diff hunk with the greatest overlap. Original lines [7-30]

The refactor to use click and FlaskGroup for command line management is a significant improvement, aligning with modern Flask development practices. This change simplifies the CLI setup and makes it more extensible, directly supporting the PR's objectives of modernizing the codebase.

example-flask/example/models/user.py (1)
  • 14-19: The use of type hints and mapped_column for column definitions in the User class represents a significant improvement in code readability and static type checking. This change aligns with SQLAlchemy 2's features and supports the PR's objectives of updating the codebase for SQLAlchemy 2 compatibility.
example-cherrypy/example/db/saplugin.py (1)
  • 23-36: > 📝 NOTE

This review was outside the diff hunks and was mapped to the diff hunk with the greatest overlap. Original lines [3-36]

The replacement of scoped_session and sessionmaker with Session directly from sqlalchemy.orm, and the update from remove() to close() for session closure, align with SQLAlchemy 2's recommendations for session management. These changes simplify session handling and enhance code clarity, supporting the PR's objectives of modernizing the codebase for SQLAlchemy 2 compatibility.

example-common/filters.py (1)
  • 41-41: The modification to the slice_by function, adjusting the slicing operation in the list comprehension, is a minor but positive change that improves code readability. This aligns with the PR's objectives of code modernization and refactoring for clarity.
example-django-mongoengine/app/views.py (1)
  • 9-9: The removal of certain imports related to authentication and strategy loading mechanisms, while retaining the import for psa, suggests a simplification or refactoring that aligns with the PR's objectives. This change maintains the necessary functionality while potentially improving code clarity.
example-pyramid/example/__init__.py (1)
  • 23-23: The refactoring of the database session configuration, specifically changing how the database session is bound to the engine, represents a simplification that aligns with modern practices for Pyramid applications. This change enhances code readability and maintainability, supporting the PR's objectives of modernizing the codebase.
example-flask-mongoengine/example/__init__.py (3)
  • 6-6: The import of models from the example module directly is a good change for clarity and direct access to models. However, ensure that the models module is properly structured and contains all necessary model definitions used within this Flask application.
  • 6-6: The removal of routes import suggests that route definitions might have been moved or restructured. It's important to verify that all routes are still correctly defined and accessible within the application, ensuring no functionality is lost due to this change.
Verification successful

The script output confirms that route definitions are present in example-flask-mongoengine/example/routes/main.py, indicating that the routes have likely been restructured and moved to this location. While the direct integration of these routes into the Flask application cannot be fully verified without additional context (e.g., how app is defined and imported in main.py), the presence of these route definitions strongly suggests that the necessary restructuring has been done to maintain functionality after the removal of the routes import from __init__.py.

Scripts Executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Verify that route definitions are present and correctly set up in other parts of the application.
rg --type py "app.route"

Length of output: 787

* 6-6: Removing the `url_for` import from `flask` and relying on `common_url_for` from `common.utils` is a strategic decision to standardize URL generation across the application. This can enhance maintainability by centralizing URL-related logic. Ensure that `common_url_for` is fully compatible with Flask's `url_for` functionality and that all instances of `url_for` have been replaced accordingly.
example-flask-peewee/example/__init__.py (1)
  • 6-6: The removal of url_for from the imports and not using routes and models directly in this file suggests a refactoring or reorganization of the code. It's crucial to ensure that the application's routing and model usage are not adversely affected by these changes. Verify that all necessary functionalities are still correctly implemented and accessible.
Verification successful

The verification process has shown that route definitions and model usages are present and correctly set up in other parts of the application, specifically within the example-flask-peewee project. This suggests that the removal of certain imports from the file under review has not adversely affected the application's routing and model usage, indicating that the initial review comment's concern has been addressed by the current structure of the application.

Scripts Executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Verify that model and route definitions are present and correctly set up in other parts of the application.
rg --type py "app.route"
rg --type py "models."

Length of output: 5652

example-flask/example/__init__.py (4)
  • 13-13: Switching to Session directly from sqlalchemy.orm for database session handling aligns with SQLAlchemy 2's recommendations for more explicit session management. This change enhances control over the session lifecycle, which is beneficial for performance and debugging. Ensure that the session is properly managed throughout the application lifecycle to avoid leaks or unintended transactions.
  • 29-29: The instantiation of Session with autocommit=False and autoflush=False is a good practice for explicit transaction control. This setup requires manual commit or rollback, which can prevent unintended data persistence and gives more control over when data is actually committed to the database. Ensure that all database operations are correctly managed within transaction boundaries.
  • 43-43: Modifying the user loading logic to use db_session.get(models.user.User, int(userid)) is a direct and efficient way to retrieve user instances. This change simplifies the logic and potentially improves performance by directly fetching the user based on the ID. Ensure that error handling is adequate for cases where userid cannot be converted to an integer or when the user does not exist.
  • 61-61: Explicitly closing the database session in the teardown_appcontext hook is a crucial step in managing the session lifecycle. This ensures that resources are properly released at the end of a request or application context, preventing potential memory leaks or connection pool exhaustion. Verify that this hook is correctly configured to be called at the appropriate times.
example-django/app/views.py (1)
  • 8-8: Removing the import of GooglePlusAuth and load_backends reflects the discontinuation of Google+ services and the need to streamline backend loading. This change is a positive step towards modernizing the authentication flow and removing deprecated functionalities. Ensure that alternative authentication methods are properly implemented and tested.
example-webpy/app.py (2)
  • 94-94: The introduction of a new session management pattern using Session from SQLAlchemy directly in the load_sqla processor is a significant improvement for explicit session control. This change aligns with modern practices for managing database sessions. Ensure that the session is correctly managed across requests to prevent any potential issues with transactions or database connections.
  • 19-21: Consolidating the social authentication backend settings and pipeline configuration in the web.config object simplifies the application's configuration management. This centralization makes it easier to maintain and update authentication settings. Verify that all necessary authentication backends and pipeline steps are correctly configured and functional.
example-cherrypy/example/app.py (2)
  • 17-18: Updating the database connection string to use format for dynamic path construction is a clear and maintainable approach. This change ensures that the database path is correctly resolved relative to the BASE_DIR. Verify that the database file (db.sqlite3) is correctly located and accessible at the constructed path.
  • 59-63: Modifying the get_settings function to explicitly exclude __builtins__ and __file__ from the settings dictionary is a good practice for security and cleanliness. This prevents unnecessary or sensitive information from being exposed through settings. Ensure that no other sensitive items need to be excluded from the settings.
example-tornado/example/settings.py (1)
  • 111-111: Updating the import statement to use example.local_settings improves the clarity and specificity of where the settings are being imported from. This change helps maintain a clear structure in the project's configuration management. Ensure that the local_settings.py file is correctly placed within the example module and contains all necessary overrides for the application settings.

Comment on lines 1 to 12
import json

from django.conf import settings
from django.contrib.auth import login
from django.contrib.auth import logout as auth_logout
from django.contrib.auth.decorators import login_required
from django.http import HttpResponse, HttpResponseBadRequest
from django.shortcuts import redirect
from social_core.backends.google import GooglePlusAuth
from social_core.backends.oauth import BaseOAuth1, BaseOAuth2
from social_core.backends.utils import load_backends
from social_django.utils import load_strategy, psa
from social_django.utils import psa

from .decorators import render_to

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 NOTE
This review was outside the diff hunks, and no overlapping diff hunk was found. Original lines [71-71]

Detected a potential XSS vulnerability in the ajax_auth function where data is rendered directly to the end user via HttpResponse. To mitigate this risk, consider using Django's template engine to safely render HTML, ensuring that any dynamic content is properly escaped.

Comment on lines 1 to 11
import json

from django.conf import settings
from django.contrib.auth import login
from django.contrib.auth import logout as auth_logout
from django.contrib.auth.decorators import login_required
from django.http import HttpResponse, HttpResponseBadRequest
from django.shortcuts import redirect
from social_core.backends.google import GooglePlusAuth
from social_core.backends.oauth import BaseOAuth1, BaseOAuth2
from social_core.backends.utils import load_backends
from social_django.utils import load_strategy, psa
from social_django.utils import psa

from .decorators import render_to

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 NOTE
This review was outside the diff hunks, and no overlapping diff hunk was found. Original lines [97-97]

Directly rendering data to the end user via HttpResponse in the ajax_auth function could potentially introduce cross-site scripting (XSS) vulnerabilities if the data is not properly sanitized. Consider using Django's built-in template rendering or JSON response utilities that automatically handle escaping to mitigate XSS risks.

- return HttpResponse(json.dumps(data), mimetype="application/json")
+ from django.http import JsonResponse
+ return JsonResponse(data)

Comment on lines 42 to 43
return cherrypy.tools.jinja2env.get_template( # fix: skip
"home.html").render(**context)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Direct use of Jinja2 for template rendering in the render_home method, while functional, may bypass HTML escaping, potentially leading to XSS vulnerabilities. Consider using CherryPy's built-in tools or ensuring that Jinja2's autoescape feature is enabled to mitigate this risk.

- return cherrypy.tools.jinja2env.get_template("home.html").render(**context)
+ # Ensure Jinja2 autoescape is enabled or use CherryPy's safer rendering methods

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
return cherrypy.tools.jinja2env.get_template( # fix: skip
"home.html").render(**context)
# Ensure Jinja2 autoescape is enabled or use CherryPy's safer rendering methods

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review Status

Actionable comments generated: 2

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between 55c7d74 and 96aa71b.
Files selected for processing (6)
  • example-cherrypy/example/app.py (5 hunks)
  • example-cherrypy/manage.py (2 hunks)
  • example-django/app/views.py (1 hunks)
  • example-flask-mongoengine/example/init.py (2 hunks)
  • example-flask/example/init.py (4 hunks)
  • example-webpy/app.py (2 hunks)
Files skipped from review as they are similar to previous changes (4)
  • example-cherrypy/manage.py
  • example-flask-mongoengine/example/init.py
  • example-flask/example/init.py
  • example-webpy/app.py
Additional comments: 4
example-django/app/views.py (1)
  • 9-9: The import of psa from social_django.utils is correctly updated to reflect the removal of unused imports. This change aligns with the PR objectives of modernizing the codebase and removing deprecated functionalities.
example-cherrypy/example/app.py (3)
  • 6-6: The import of settings from example is correctly updated to reflect the removal of the local import. This change is part of the PR's objective to modernize the codebase and improve project configuration.
  • 43-45: Direct use of Jinja2 for template rendering in CherryPy is noted. Ensure that HTML escaping is properly handled to prevent Cross-Site Scripting (XSS) vulnerabilities. While the PR does not introduce this pattern, it's crucial to verify that the application correctly escapes all user-generated content.
  • 89-89: Changing the session storage type to RamSession is appropriate for development or testing environments but might not be suitable for production due to scalability and persistence issues. Ensure that this change aligns with the deployment environment's requirements.

Comment on lines 1 to 12
import json

from django.conf import settings
from django.contrib.auth import login
from django.contrib.auth import logout as auth_logout
from django.contrib.auth.decorators import login_required
from django.http import HttpResponse, HttpResponseBadRequest
from django.shortcuts import redirect
from social_core.backends.google import GooglePlusAuth
from social_core.backends.oauth import BaseOAuth1, BaseOAuth2
from social_core.backends.utils import load_backends
from social_django.utils import load_strategy, psa
from social_django.utils import psa

from .decorators import render_to

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 NOTE
This review was outside the diff hunks, and no overlapping diff hunk was found. Original lines [97-97]

Detected direct rendering of data to the end user via 'HttpResponse'. This could potentially lead to Cross-Site Scripting (XSS) vulnerabilities if the data is not properly sanitized. Consider using Django's template engine to safely render HTML, which automatically escapes variables unless explicitly marked otherwise.

- return HttpResponse(json.dumps(data), mimetype="application/json")
+ return JsonResponse(data)

Note: JsonResponse automatically sets the Content-Type header to application/json and safely handles data serialization.

Comment on lines +17 to +19
DATABASE_NAME = "sqlite:///{dbname}".format( # fix: skip
dbname=os.path.join(BASE_DIR, "db.sqlite3")
)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The update to the database connection string formatting using format is correct and improves readability. However, consider using f-strings for string formatting as they are more readable and efficient in Python 3.6+.

- DATABASE_NAME = "sqlite:///{dbname}".format(
-     dbname=os.path.join(BASE_DIR, "db.sqlite3")
- )
+ DATABASE_NAME = f"sqlite:///{os.path.join(BASE_DIR, 'db.sqlite3')}"

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
DATABASE_NAME = "sqlite:///{dbname}".format( # fix: skip
dbname=os.path.join(BASE_DIR, "db.sqlite3")
)
DATABASE_NAME = f"sqlite:///{os.path.join(BASE_DIR, 'db.sqlite3')}"

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review Status

Actionable comments generated: 2

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between 96aa71b and 010a756.
Files selected for processing (4)
  • example-cherrypy/example/app.py (5 hunks)
  • example-common/filters.py (1 hunks)
  • example-common/pipeline.py (3 hunks)
  • example-common/utils.py (1 hunks)
Files skipped from review due to trivial changes (1)
  • example-common/pipeline.py
Files skipped from review as they are similar to previous changes (1)
  • example-common/filters.py
Additional comments: 5
example-common/utils.py (1)
  • 19-20: The reformatting of the common_context function signature improves readability and maintainability. Good job on this change.
example-cherrypy/example/app.py (4)
  • 6-6: The update to import settings from example is appropriate and aligns with project restructuring. Ensure that the settings module contains all necessary configurations.
  • 60-64: The update to the get_settings function to exclude specific items is a good practice, enhancing clarity and security by preventing unintended exposure of sensitive or irrelevant information.
  • 71-77: The reorganization of the local_settings import and the improvement of the error message clarity are beneficial changes. They enhance maintainability and provide clearer guidance to users setting up their local environment.
  • 88-88: The change to use RamSession for session storage may improve performance but consider the implications for scalability and persistence, especially in production environments.

Comment on lines 19 to 20
def common_context( # fix: skip
authentication_backends, strategy, user=None, plus_id=None, **extra):
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The use of GooglePlusAuth is concerning given that Google+ has been shut down. Please verify if this part of the code is still relevant or if it should be removed or replaced with a different authentication method.

Comment on lines +43 to +44
jinja2env = cherrypy.tools.jinja2env
return jinja2env.get_template("home.html").render(**context)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The adjustments to template rendering calls improve clarity. However, ensure that HTML escaping is properly handled to prevent potential XSS vulnerabilities when using Jinja2 directly.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review Status

Actionable comments generated: 0

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between 010a756 and f4d595c.
Files selected for processing (3)
  • example-common/filters.py (1 hunks)
  • example-common/pipeline.py (3 hunks)
  • example-common/utils.py (1 hunks)
Files skipped from review as they are similar to previous changes (3)
  • example-common/filters.py
  • example-common/pipeline.py
  • example-common/utils.py

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review Status

Actionable comments generated: 3

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between f4d595c and a60326a.
Files selected for processing (21)
  • example-common/filters.py (1 hunks)
  • example-django-mongoengine/app/decorators.py (1 hunks)
  • example-django-mongoengine/app/mail.py (1 hunks)
  • example-django-mongoengine/app/templatetags/backend_utils.py (2 hunks)
  • example-django-mongoengine/app/views.py (1 hunks)
  • example-django-mongoengine/example/settings.py (2 hunks)
  • example-django-mongoengine/example/urls.py (1 hunks)
  • example-django/app/decorators.py (1 hunks)
  • example-django/app/mail.py (1 hunks)
  • example-django/app/models.py (1 hunks)
  • example-django/app/templatetags/backend_utils.py (1 hunks)
  • example-django/app/views.py (1 hunks)
  • example-django/example/settings.py (2 hunks)
  • example-flask-mongoengine/example/init.py (3 hunks)
  • example-flask-peewee/example/init.py (3 hunks)
  • example-flask-peewee/example/models/user.py (1 hunks)
  • example-flask/example/init.py (4 hunks)
  • example-pyramid/example/init.py (2 hunks)
  • example-pyramid/example/views.py (1 hunks)
  • example-tornado/example/app.py (2 hunks)
  • example-webpy/app.py (3 hunks)
Files skipped from review due to trivial changes (2)
  • example-django-mongoengine/example/urls.py
  • example-django/app/models.py
Files skipped from review as they are similar to previous changes (10)
  • example-common/filters.py
  • example-django-mongoengine/app/templatetags/backend_utils.py
  • example-django-mongoengine/example/settings.py
  • example-django/app/templatetags/backend_utils.py
  • example-django/example/settings.py
  • example-flask-mongoengine/example/init.py
  • example-flask-peewee/example/init.py
  • example-flask/example/init.py
  • example-pyramid/example/init.py
  • example-webpy/app.py
Additional comments: 6
example-django-mongoengine/app/mail.py (1)
  • 7-10: The updated URL formatting in the send_validation function improves readability and ensures the correct URL is generated for sending validation emails. This change aligns with best practices for string formatting in Python. Good job on making this update.
example-django/app/mail.py (1)
  • 7-10: The changes made to the URL formatting in the send_validation function are well done, enhancing readability and ensuring the correct URL structure for validation emails. This is a good practice for string formatting and improves the maintainability of the code.
example-flask-peewee/example/models/user.py (1)
  • 10-11: The updated comments in the BaseModel class provide clearer guidance on how to specify the database for model definitions. This is a good practice for code documentation, making it easier for new developers to understand the purpose and usage of the base model class.
example-django-mongoengine/app/decorators.py (1)
  • 24-29: > 📝 NOTE

This review was outside the diff hunks and was mapped to the diff hunk with the greatest overlap. Original lines [1-25]

The removal of the plus_id parameter in the wrapper function aligns with the PR's objective of removing deprecated features, such as Google Plus ID retrieval. This change simplifies the code and removes unnecessary dependencies, which is a positive step towards modernizing the codebase.

example-django/app/decorators.py (1)
  • 24-29: > 📝 NOTE

This review was outside the diff hunks and was mapped to the diff hunk with the greatest overlap. Original lines [1-25]

The removal of the plus_id parameter from the wrapper function is consistent with the PR's goal of code modernization by eliminating deprecated features. This change helps in simplifying the code and removing outdated dependencies, which is beneficial for maintaining a clean and up-to-date codebase.

example-pyramid/example/views.py (1)
  • 27-30: The reformatting of the @view_config decorator for the email_required function improves readability without altering its functionality. This kind of code formatting aligns with best practices for Python development, making the code more accessible and maintainable.

Comment on lines 1 to 11
import json

from django.conf import settings
from django.contrib.auth import login
from django.contrib.auth import logout as auth_logout
from django.contrib.auth.decorators import login_required
from django.http import HttpResponse, HttpResponseBadRequest
from django.shortcuts import redirect
from social_core.backends.google import GooglePlusAuth
from social_core.backends.oauth import BaseOAuth1, BaseOAuth2
from social_core.backends.utils import load_backends
from social_django.utils import load_strategy, psa

from .decorators import render_to
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 NOTE
This review was outside the diff hunks, and no overlapping diff hunk was found. Original lines [71-71]

The direct rendering of data to the end user via HttpResponse in the ajax_auth function could potentially expose the application to cross-site scripting (XSS) vulnerabilities. Consider using Django's template engine to safely render HTML, which automatically escapes variables, providing a safer way to render dynamic content.

- return HttpResponse(json.dumps(data), mimetype="application/json")
+ return HttpResponse(json.dumps(data), content_type="application/json")

Comment on lines 1 to 11
import json

from django.conf import settings
from django.contrib.auth import login
from django.contrib.auth import logout as auth_logout
from django.contrib.auth.decorators import login_required
from django.http import HttpResponse, HttpResponseBadRequest
from django.shortcuts import redirect
from social_core.backends.google import GooglePlusAuth
from social_core.backends.oauth import BaseOAuth1, BaseOAuth2
from social_core.backends.utils import load_backends
from social_django.utils import load_strategy, psa

from .decorators import render_to
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 NOTE
This review was outside the diff hunks, and no overlapping diff hunk was found. Original lines [97-97]

Similar to the previous file, rendering data directly to the end user via HttpResponse in the ajax_auth function could lead to cross-site scripting (XSS) vulnerabilities. It's recommended to use Django's template engine for rendering HTML content safely. This ensures that variables are automatically escaped, reducing the risk of XSS attacks.

- return HttpResponse(json.dumps(data), mimetype="application/json")
+ return HttpResponse(json.dumps(data), content_type="application/json")

Comment on lines 1 to 38
import os

import settings
import tornado.options
import tornado.web
from common import filters
from common.utils import common_context, url_for
from example import settings
from jinja2 import Environment, FileSystemLoader
from social_tornado.routes import SOCIAL_AUTH_ROUTES
from social_tornado.utils import load_strategy
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import scoped_session, sessionmaker
from sqlalchemy.orm import DeclarativeBase, Session
from tornado_jinja2 import Jinja2Loader

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
DATABASE_NAME = "sqlite:///{dbname}".format(dbname=os.path.join(BASE_DIR, "db.sqlite3"))
DATABASE_NAME = "sqlite:///{dbname}".format( # fix: skip
dbname=os.path.join(BASE_DIR, "db.sqlite3")
)

engine = create_engine(DATABASE_NAME, echo=False)
session = scoped_session(sessionmaker(bind=engine))
Base = declarative_base()
session = Session(engine)


class Base(DeclarativeBase):
pass


class BaseHandler(tornado.web.RequestHandler):
def render_home(self, **extra):
from models import User
from example.models import User

user_id = self.get_secure_cookie("user_id")

if user_id:
user = session.query(User).get(int(user_id))
user = session.get(User, int(user_id))
else:
user = None

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 NOTE
This review was outside the diff hunks, and no overlapping diff hunk was found. Original lines [77-79]

The direct use of Jinja2 for rendering templates in Tornado applications should be handled with care to prevent cross-site scripting (XSS) vulnerabilities. Ensure that HTML escaping is properly configured in Jinja2 to automatically escape variables. This is crucial for safely rendering dynamic content and protecting against XSS attacks.

+ jinja2env.autoescape = True

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review Status

Actionable comments generated: 0

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between a60326a and dbc3d62.
Files selected for processing (3)
  • example-common/filters.py (1 hunks)
  • example-django-mongoengine/app/templatetags/backend_utils.py (1 hunks)
  • example-pyramid/example/views.py (1 hunks)
Files skipped from review as they are similar to previous changes (3)
  • example-common/filters.py
  • example-django-mongoengine/app/templatetags/backend_utils.py
  • example-pyramid/example/views.py

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

1 participant