miguelgrinberg / microblog

The microblogging application developed in my Flask Mega-Tutorial series. This version maps to the 2024 Edition of the tutorial.
http://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-i-hello-world
MIT License
4.52k stars 1.62k forks source link

Project dependencies may have API risk issues #326

Closed PyDeps closed 1 year ago

PyDeps commented 1 year ago

Hi, In microblog, inappropriate dependency versioning constraints can cause risks.

Below are the dependencies and version constraints that the project is using

alembic==1.6.5
Babel==2.9.1
blinker==1.4
certifi==2021.5.30
chardet==4.0.0
click==8.0.1
dnspython==2.1.0
dominate==2.6.0
elasticsearch==7.13.3
email-validator==1.1.3
Flask==2.0.1
Flask-Babel==2.0.0
Flask-Bootstrap==3.3.7.1
Flask-HTTPAuth==4.4.0
Flask-Login==0.5.0
Flask-Mail==0.9.1
Flask-Migrate==3.0.1
Flask-Moment==1.0.1
Flask-SQLAlchemy==2.5.1
Flask-WTF==0.15.1
greenlet==1.1.0
httpie==2.4.0
idna==2.10
itsdangerous==2.0.1
Jinja2==3.0.1
langdetect==1.0.9
Mako==1.1.4
MarkupSafe==2.0.1
Pygments==2.9.0
PyJWT==2.1.0
PySocks==1.7.1
python-dateutil==2.8.1
python-dotenv==0.18.0
python-editor==1.0.4
pytz==2021.1
redis==3.5.3
requests==2.25.1
requests-toolbelt==0.9.1
rq==1.9.0
six==1.16.0
SQLAlchemy==1.4.20
urllib3==1.26.6
visitor==0.1.3
Werkzeug==2.0.1
WTForms==2.3.3

The version constraint == will introduce the risk of dependency conflicts because the scope of dependencies is too strict. The version constraint No Upper Bound and * will introduce the risk of the missing API Error because the latest version of the dependencies may remove some APIs.

After further analysis, in this project, The version constraint of dependency alembic can be changed to >=0.1.0,<=0.1.1. The version constraint of dependency Flask-Babel can be changed to >=0.9,<=2.0.0. The version constraint of dependency Flask-HTTPAuth can be changed to >=3.0.0,<=4.7.0. The version constraint of dependency Flask-Login can be changed to >=0.1.3,<=0.6.2. The version constraint of dependency Flask-Mail can be changed to >=0.7.0,<=0.7.6. The version constraint of dependency Flask-Mail can be changed to >=0.9.0,<=0.9.1. The version constraint of dependency Flask-Moment can be changed to >=0.1.0,<=0.11.0. The version constraint of dependency Flask-Moment can be changed to >=1.0.1,<=1.0.2. The version constraint of dependency Flask-SQLAlchemy can be changed to >=0.16,<=3.0.0a1. The version constraint of dependency PyJWT can be changed to >=0.1.1,<=1.1.0. The version constraint of dependency redis can be changed to >=3.0.0,<=4.3.3. The version constraint of dependency requests can be changed to >=0.2.1,<=0.2.3. The version constraint of dependency requests can be changed to >=0.7.0,<=2.24.0. The version constraint of dependency requests can be changed to ==2.26.0. The version constraint of dependency rq can be changed to >=0.3.3,<=1.10.1. The version constraint of dependency SQLAlchemy can be changed to >=0.5.0beta3,<=1.4.41. The version constraint of dependency Werkzeug can be changed to >=0.9,<=2.1.2. The version constraint of dependency WTForms can be changed to >=1.0.2,<=3.0.1.

The above modification suggestions can reduce the dependency conflicts as much as possible, and introduce the latest version as much as possible without calling Error in the projects.

The invocation of the current project includes all the following methods.

The calling methods from the alembic
alembic.op.create_index
alembic.op.drop_table
alembic.op.add_column
alembic.op.drop_index
alembic.op.drop_column
alembic.op.create_table
alembic.context.run_migrations
alembic.context.is_offline_mode
alembic.context.begin_transaction
alembic.context.configure
The calling methods from the Flask-Babel
flask_babel.Babel.init_app
flask_babel.get_locale
flask_babel.lazy_gettext
flask_babel.Babel
The calling methods from the Flask-HTTPAuth
flask_httpauth.HTTPTokenAuth
The calling methods from the Flask-Login
flask_login.login_user
flask_login.LoginManager
flask_login.logout_user
flask_login.LoginManager.init_app
The calling methods from the Flask-Mail
flask_mail.Message.attach
flask_mail.Mail
flask_mail.Message
flask_mail.Mail.init_app
The calling methods from the Flask-Moment
flask_moment.Moment
flask_moment.Moment.init_app
The calling methods from the Flask-SQLAlchemy
flask_sqlalchemy.SQLAlchemy
flask_sqlalchemy.SQLAlchemy.init_app
The calling methods from the PyJWT
jwt.encode
jwt.decode
The calling methods from the redis
redis.Redis.from_url
The calling methods from the requests
requests.post
The calling methods from the rq
rq.get_current_job
The calling methods from the SQLAlchemy
sqlalchemy.PrimaryKeyConstraint
sqlalchemy.String
sqlalchemy.Column
sqlalchemy.ForeignKeyConstraint
sqlalchemy.Boolean
sqlalchemy.Text
sqlalchemy.Float
sqlalchemy.Integer
sqlalchemy.DateTime
The calling methods from the Werkzeug
werkzeug.urls.url_parse
werkzeug.security.check_password_hash
werkzeug.security.generate_password_hash
The calling methods from the WTForms
wtforms.validators.Length
wtforms.validators.ValidationError
wtforms.validators.EqualTo
wtforms.validators.Email
wtforms.validators.DataRequired
The calling methods from the all methods
sqlalchemy.engine_from_config.connect
self.SearchForm.super.__init__
app.api.auth.basic_auth.current_user
sqlalchemy.PrimaryKeyConstraint
click.argument
flask.render_template
flask_migrate.Migrate
app.logger.addHandler
flask_babel.Babel
flask_login.current_user.followed_posts.paginate
app.create_app.app_context
flask.request.args.get
flask_migrate.Migrate.init_app
os.mkdir
flask.Flask.register_blueprint
rq.Queue
flask_login.logout_user
alembic.op.drop_index
sys.exc_info
alembic.op.drop_column
list
os.path.join
username.data.User.query.filter_by.first
flask.Blueprint
wtforms.BooleanField
app.auth.forms.ResetPasswordRequestForm
user.id.followers.c.followed_id.self.followed.filter.count
alembic.context.begin_transaction
flask_mail.Mail
Post.query.join
app.models.User.query.get_or_404.from_dict
flask_bootstrap.Bootstrap
app.models.Post
sqlalchemy.engine_from_config
logging.StreamHandler.setLevel
self.followers.count
elasticsearch.Elasticsearch
User.query.get
username.User.query.filter_by.first.check_password
app.auth.forms.LoginForm
sqlalchemy.String
run_migrations_online
dotenv.load_dotenv
flask.current_app.elasticsearch.index
app.models.Message.timestamp.desc
rq.get_current_job.get_id
app.models.Post.timestamp.asc
str
Message.query.filter_by
datetime.datetime.utcnow
username.User.query.filter_by.first
self.followed.filter
hashlib.md5
app.logger.info
werkzeug.http.HTTP_STATUS_CODES.get
threading.Thread
username.User.query.filter_by.first_or_404
_set_task_progress
app.api.auth.token_auth.current_user
requests.post.json
flask_mail.Message
app.db.session.rollback
email.data.User.query.filter_by.first
self.name.Task.query.filter_by.first
msg.current_app._get_current_object.send_async_email.Thread.start
app.main.forms.MessageForm
flask.current_app.config.get
self.followed.count
requests.post
user.posts.count
Task.query.filter_by
app.models.User.query.filter_by
app.models.User.verify_reset_password_token.set_password
app.logger.setLevel
app.api.errors.error_response
app.db.relationship
cls.id.in_
flask.current_app._get_current_object
werkzeug.urls.url_parse
app.auth.forms.RegistrationForm
app.models.Notification.timestamp.asc
flask_login.current_user.notifications.filter
app.mail.send
wtforms.validators.Length
app.models.User.query.get_or_404
flask.request.accept_languages.best_match
os.remove
app.models.Message.timestamp.desc.current_user.messages_received.order_by.paginate
flask.redirect
self.set_password
user.get_reset_password_token
app.models.User.verify_reset_password_token.check_password
form.username.data.User.query.filter_by.first
app.db.session.commit
self.last_seen.isoformat
getattr
flask_sqlalchemy.SQLAlchemy.init_app
jwt.decode
flask_babel.get_locale
flask_login.current_user.follow
wtforms.validators.DataRequired
logging.getLogger
query.paginate
os.urandom.base64.b64encode.decode
int
alembic.op.f
self.avatar
token.User.query.filter_by.first
wtforms.PasswordField
flask.Flask
flask_login.current_user.add_notification
alembic.context.configure
since.Notification.timestamp.current_user.notifications.filter.order_by
super
flask_babel.Babel.init_app
app.search.add_to_index
redis.Redis.from_url
Post.query.filter_by
wtforms.SubmitField
n.get_data
app.main.forms.EditProfileForm
flask_login.current_user.get_task_in_progress
os.path.dirname
config.get_main_option
app.create_app
alembic.op.create_table
logging.handlers.RotatingFileHandler
alembic.context.is_offline_mode
flask.flash
self.followed.append
app.main.forms.MessageForm.validate_on_submit
wtforms.validators.ValidationError
rq.job.Job.fetch
os.system
self.email.lower
app.api.errors.bad_request
os.environ.get
app.db.ForeignKey
app.main.forms.EmptyForm
flask_login.current_user.followed_posts
engine.connect.close
self.is_following
app.models.User.query.get_or_404.to_dict
flask_babel.lazy_gettext
logging.config.fileConfig
app.api.auth.basic_auth.current_user.get_token
flask_login.current_user.unfollow
User.query.filter_by
app.cli.register
min
id.User.query.get_or_404.to_dict
os.environ.get.replace
datetime.datetime
self.username.data.User.query.filter_by.first
flask_login.current_user.launch_task
range
flask_login.login_user
wants_json_response
app.models.User.check_token
name.self.notifications.filter_by.delete
own.followed.union.order_by
flask.request.get_json
app.db.backref
json.loads
json.dumps
app.models.Post.timestamp.desc.Post.query.order_by.paginate
Notification
cls.query.filter
recipient.User.query.filter_by.first_or_404.add_notification
logging.StreamHandler
translate.command
app.db.event.listen
app.app_context.push
sqlalchemy.Column
Post.user_id.followers.c.followed_id.followers.Post.query.join.filter.union
sqlalchemy.ForeignKeyConstraint
app.search.query_index
logging.Formatter
app.cli.group
app.api.auth.token_auth.current_user.revoke_token
logging.getLogger.info
self.get_rq_job
flask.current_app.elasticsearch.search
flask_login.LoginManager.init_app
self.posts.count
flask_babel._
user.posts.order_by
os.path.abspath
flask_mail.Message.attach
recipient.User.query.filter_by.first_or_404.new_messages
flask_httpauth.HTTPBasicAuth
Task
app.auth.forms.ResetPasswordForm
app.errors.bp.app_errorhandler
run_migrations_offline
alembic.op.add_column
app.db.String
app.models.User.to_collection_dict
app.app_context
alembic.context.run_migrations
alembic.op.create_index
app.db.Column
len
flask.jsonify
sqlalchemy.Text
wtforms.validators.EqualTo
when.append
app.logger.error
app.api.bp.route
werkzeug.security.generate_password_hash
app.models.Post.timestamp.desc.user.posts.order_by.paginate
wtforms.validators.Email
flask_login.current_user.messages_received.order_by
job.meta.get
app.translate.translate
data.append
app.main.bp.route
app.db.Table
self.followed.remove
flask.current_app.elasticsearch.delete
self.notifications.filter_by
form.email.data.User.query.filter_by.first
logging.handlers.RotatingFileHandler.setFormatter
flask_bootstrap.Bootstrap.init_app
app.models.User.verify_reset_password_token
post.timestamp.isoformat
app.auth.bp.route
datetime.timedelta
flask.abort
setattr
app.models.Task.query.get
app.models.User
flask_mail.Mail.init_app
app.db.case
app.models.Post.timestamp.desc
rq.get_current_job
flask.current_app.task_queue.enqueue
app.models.Message
flask.g.search_form.validate
sqlalchemy.Boolean
flask_httpauth.HTTPTokenAuth
app.main.forms.SearchForm
cls.query.filter_by
Post.timestamp.desc
error_response
isinstance
self.Task.query.filter_by.all
sqlalchemy.DateTime
self.email.lower.encode.md5.hexdigest
app.db.session.add
self.Message.query.filter_by.filter
rq.job.Job.fetch.get_id
flask_moment.Moment.init_app
recipient.User.query.filter_by.first_or_404
wtforms.TextAreaField
task.user.add_notification
app.models.Post.search
app.search.remove_from_index
langdetect.detect
Post.user_id.followers.c.followed_id.followers.Post.query.join.filter
RuntimeError
flask.url_for
app.models.Post.query.order_by
flask_moment.Moment
data.User.query.filter_by.first
app.auth.forms.ResetPasswordForm.validate_on_submit
script.upgrade_ops.is_empty
time.sleep
rq.get_current_job.save_meta
logging.handlers.SMTPHandler
flask_sqlalchemy.SQLAlchemy
app.config.from_object
flask_login.LoginManager
app.main.forms.PostForm
sqlalchemy.Integer
sqlalchemy.Float
alembic.op.drop_table
config.set_main_option
jwt.encode
self.EditProfileForm.super.__init__
base64.b64encode
logging.handlers.SMTPHandler.setLevel
time.time
app.email.send_email
app.models.User.query.get
wtforms.StringField
config.get_section
werkzeug.security.check_password_hash
os.path.exists
last_read_time.Message.timestamp.self.Message.query.filter_by.filter.count
ids.cls.id.in_.cls.query.filter.order_by
os.urandom
app.auth.email.send_password_reset_email
item.to_dict
logging.handlers.RotatingFileHandler.setLevel
format
self.email.lower.encode

@developer Could please help me check this issue? May I pull a request to fix it? Thank you very much.

miguelgrinberg commented 1 year ago

Not interested.