From 7c2401622b01010862aec69c5d44f3bbc1a33a1e Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 12 Apr 2020 20:58:47 -0700 Subject: [PATCH 001/206] remove all references to "self" from old class structure --- versions/v0.py | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/versions/v0.py b/versions/v0.py index bd7b7d3..decc642 100644 --- a/versions/v0.py +++ b/versions/v0.py @@ -140,7 +140,7 @@ def create_school(self): @check_headers @requires_auth @requires_admin -def update_school(self, school_id): +def update_school(school_id): """ input: { "data": { @@ -194,7 +194,7 @@ def update_school(self, school_id): @check_headers @requires_auth @requires_admin -def delete_school(self, school_id): +def delete_school(school_id): check_permissions( [APIScopes.DELETE_SCHOOL, APIScopes.DELETE_BELL_SCHEDULE]) @@ -215,8 +215,7 @@ def delete_school(self, school_id): @blueprint.route("/school//bellschedules/", methods=['GET']) @check_headers -def list_bellschedules(self, school_id): - +def list_bellschedules(school_id): check_permissions([APIScopes.LIST_BELL_SCHEDULES]) schedule_list = [] @@ -229,7 +228,7 @@ def list_bellschedules(self, school_id): @blueprint.route("/school//bellschedule/", methods=['GET']) @check_headers -def get_bellschedule(self, school_id, bell_schedule_id): +def get_bellschedule(school_id, bell_schedule_id): check_permissions([APIScopes.READ_BELL_SCHEDULE]) @@ -248,7 +247,7 @@ def get_bellschedule(self, school_id, bell_schedule_id): @check_headers @requires_auth @requires_admin -def create_bellschedule(self, school_id): +def create_bellschedule(school_id): check_permissions([APIScopes.CREATE_BELL_SCHEDULE]) @@ -269,7 +268,7 @@ def create_bellschedule(self, school_id): @check_headers @requires_auth @requires_admin -def update_bellschedule(self, school_id, bell_schedule_id): +def update_bellschedule(school_id, bell_schedule_id): check_permissions([APIScopes.EDIT_BELL_SCHEDULE]) @@ -299,7 +298,7 @@ def update_bellschedule(self, school_id, bell_schedule_id): @check_headers @requires_auth @requires_admin -def delete_bellschedule(self, school_id, bell_schedule_id): +def delete_bellschedule(school_id, bell_schedule_id): check_permissions([APIScopes.DELETE_BELL_SCHEDULE]) From 9416acfd618745524759b5bbe62ecdeca29677f0 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 12 Apr 2020 21:17:53 -0700 Subject: [PATCH 002/206] fix single bell schedule endpoint URL --- versions/v0.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/versions/v0.py b/versions/v0.py index decc642..b345047 100644 --- a/versions/v0.py +++ b/versions/v0.py @@ -226,7 +226,7 @@ def list_bellschedules(school_id): return BellScheduleSchema(exclude=('school_id',)).dump(schedule_list, many=True) -@blueprint.route("/school//bellschedule/", methods=['GET']) +@blueprint.route("/school//bellschedule//", methods=['GET']) @check_headers def get_bellschedule(school_id, bell_schedule_id): From 3fd587b3607d40c3db51d06e4c9c3a17cdc68ad0 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 12 Apr 2020 21:18:58 -0700 Subject: [PATCH 003/206] temporarily remove credentials for CORS --- versions/v0.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/versions/v0.py b/versions/v0.py index b345047..5b53188 100644 --- a/versions/v0.py +++ b/versions/v0.py @@ -34,8 +34,8 @@ blueprint = Blueprint('v0', __name__) CORS(blueprint, origins="https://web.classclock.app", allow_headers=[ - "Accept", "Authorization"], - supports_credentials=True) + "Accept", "Authorization"]) + # supports_credentials=True) # @blueprint.route("/schools", methods=['GET']) From fec9e943e2973fbf85df8e09c627e19a214131b9 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sat, 18 Apr 2020 17:08:04 -0700 Subject: [PATCH 004/206] add 'application/vnd.api+json' Content-Type header to all requests --- versions/v0.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/versions/v0.py b/versions/v0.py index 5b53188..170d4e3 100644 --- a/versions/v0.py +++ b/versions/v0.py @@ -329,6 +329,12 @@ def before(): current_app.logger.info( "Handling " + request.method + " Request for endpoint " + request.path + " from API user '" + get_api_user_id() + "' from address " + util.get_remote_address() ) pass + +@blueprint.after_request +def after_request(response): + response.headers['Content-Type'] = 'application/vnd.api+json' + return response + # # # Error Handler Section From 51b9bb3a7b5b6bb2667242897a0d498c4b6ac641 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sat, 18 Apr 2020 17:11:42 -0700 Subject: [PATCH 005/206] remove /relationships/ links from JSONAPI links objects --- common/fields.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/common/fields.py b/common/fields.py index c19d800..016654c 100644 --- a/common/fields.py +++ b/common/fields.py @@ -46,10 +46,10 @@ def __init__(self, parent_self_url='', relationship_name='', parent_model=None, :param models.bases.BaseModel parent_model: Model Class of Schema containing this field. """ # Calculate our relationship URLs beased on the parent schema's self_url - if parent_self_url and relationship_name and kwargs['self_url_kwargs']: - kwargs['self_url'] = '{0}/relationships/{1}'.format(parent_self_url, relationship_name) - kwargs['related_url'] = '{0}/{1}'.format(parent_self_url, relationship_name) - kwargs['related_url_kwargs'] = kwargs['self_url_kwargs'] + #if parent_self_url and relationship_name and kwargs['self_url_kwargs']: + # kwargs['self_url'] = '{0}/relationships/{1}'.format(parent_self_url, relationship_name) + # kwargs['related_url'] = '{0}/{1}'.format(parent_self_url, relationship_name) + # kwargs['related_url_kwargs'] = kwargs['self_url_kwargs'] # Set the class of the model for the schema containing this field. self.parent_model = parent_model From d5fa4daba40195bde1de5196730ff056f856b403 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Thu, 7 May 2020 19:27:36 -0700 Subject: [PATCH 006/206] add flask-sqlalchemy and marshmallow-sqlalchemy dependencies --- Pipfile | 2 ++ Pipfile.lock | 89 +++++++++++++++++++++++++++++++--------------------- api.py | 3 +- 3 files changed, 57 insertions(+), 37 deletions(-) diff --git a/Pipfile b/Pipfile index 3fc0401..a91a643 100644 --- a/Pipfile +++ b/Pipfile @@ -20,6 +20,8 @@ gunicorn = "*" sqlalchemy = "*" json-api-doc = "*" marshmallow-jsonapi = "*" +flask-sqlalchemy = "*" +marshmallow-sqlalchemy = "*" [requires] python_version = "3.6" diff --git a/Pipfile.lock b/Pipfile.lock index b72520a..21efd7c 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "39eaf869ef189205d378a0bc9bb9a78dc8de0ca25a12a84b0aabf3826af0e3d6" + "sha256": "f0f9f5660e21adaf4651977ab1b8d83ee04f160b4116181c2258618ed6d6d404" }, "pipfile-spec": 6, "requires": { @@ -25,10 +25,10 @@ }, "click": { "hashes": [ - "sha256:8a18b4ea89d8820c5d0c7da8a64b2c324b4dabb695804dbfea19b9be9d88c0cc", - "sha256:e345d143d80bf5ee7534056164e5e112ea5e22716bbb1ce727941f4c8b471b9a" + "sha256:d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a", + "sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc" ], - "version": "==7.1.1" + "version": "==7.1.2" }, "dnspython": { "hashes": [ @@ -79,11 +79,19 @@ }, "flask-marshmallow": { "hashes": [ - "sha256:01520ef1851ccb64d4ffb33196cddff895cc1302ae1585bff1abf58684a8111a", - "sha256:28b969193958d9602ab5d6add6d280e0e360c8e373d3492c2f73b024ecd36374" + "sha256:6e6aec171b8e092e0eafaf035ff5b8637bf3a58ab46f568c4c1bab02f2a3c196", + "sha256:a1685536e7ab5abdc712bbc1ac1a6b0b50951a368502f7985e7d1c27b3c21e59" ], "index": "pypi", - "version": "==0.11.0" + "version": "==0.12.0" + }, + "flask-sqlalchemy": { + "hashes": [ + "sha256:0078d8663330dc05a74bc72b3b6ddc441b9a744e2f56fe60af1a5bfc81334327", + "sha256:6974785d913666587949f7c2946f7001e4fa2cb2d19f4e69ead02e4b8f50b33d" + ], + "index": "pypi", + "version": "==2.4.1" }, "gunicorn": { "hashes": [ @@ -93,14 +101,6 @@ "index": "pypi", "version": "==20.0.4" }, - "importlib-metadata": { - "hashes": [ - "sha256:2a688cbaa90e0cc587f1df48bdc97a6eadccdcd9c35fb3f976a09e3b5016d90f", - "sha256:34513a8a0c4962bc66d35b359558fd8a5e10cd472d37aec5f66858addef32c1e" - ], - "markers": "python_version < '3.8'", - "version": "==1.6.0" - }, "itsdangerous": { "hashes": [ "sha256:321b033d07f2a4136d3ec762eac9f16a10ccd60f53c0c91af90217ace7ba1f19", @@ -110,18 +110,18 @@ }, "jinja2": { "hashes": [ - "sha256:93187ffbc7808079673ef52771baa950426fd664d3aad1d0fa3e95644360e250", - "sha256:b0eaf100007721b5c16c1fc1eecb87409464edc10469ddc9a22a27a99123be49" + "sha256:89aab215427ef59c34ad58735269eb58b1a5808103067f7bb9d5836c651b3bb0", + "sha256:f0a4641d3cf955324a89c04f3d94663aa4d638abe8f733ecd3582848e1c37035" ], - "version": "==2.11.1" + "version": "==2.11.2" }, "json-api-doc": { "hashes": [ - "sha256:3a4724d9b86c5a52686a76f2c7538101f1a933fc1a08b85b20541f9885ec2433", - "sha256:a073be2309ec90fc33a02701a5f73a715cb6475a2dffa71d0e9df63e0fbe9182" + "sha256:1d2718da739845d65f994a7de727ff7d38bc69f5defa1f7cf6f8df114b0d5879", + "sha256:ead8275f5d77f2d67493d37b78a61c23a4157abf97ee91b70890e13534c2707e" ], "index": "pypi", - "version": "==0.11.0" + "version": "==0.13.0" }, "jsonschema": { "hashes": [ @@ -177,10 +177,10 @@ }, "marshmallow": { "hashes": [ - "sha256:90854221bbb1498d003a0c3cc9d8390259137551917961c8b5258c64026b2f85", - "sha256:ac2e13b30165501b7d41fc0371b8df35944f5849769d136f20e2c5f6cdc6e665" + "sha256:56663fa1d5385c14c6a1236badd166d6dee987a5f64d2b6cc099dadf96eb4f09", + "sha256:f12203bf8d94c410ab4b8d66edfde4f8a364892bde1f6747179765559f93d62a" ], - "version": "==3.5.1" + "version": "==3.5.2" }, "marshmallow-jsonapi": { "hashes": [ @@ -190,6 +190,14 @@ "index": "pypi", "version": "==0.23.1" }, + "marshmallow-sqlalchemy": { + "hashes": [ + "sha256:3247e41e424146340b03a369f2b7c6f0364477ccedc4e2481e84d5f3a8d3c67f", + "sha256:dbbe51d28bb28e7ee2782e51310477f7a2c5a111a301f6dd8e264e11ab820427" + ], + "index": "pypi", + "version": "==0.23.0" + }, "mistune": { "hashes": [ "sha256:59a3429db53c50b5c6bcc8a07f8848cb00d7dc8bdb431a4ab41920d201d4756e", @@ -219,11 +227,11 @@ }, "python-dotenv": { "hashes": [ - "sha256:81822227f771e0cab235a2939f0f265954ac4763cafd806d845801c863bf372f", - "sha256:92b3123fb2d58a284f76cc92bfe4ee6c502c32ded73e8b051c4f6afc8b6751ed" + "sha256:25c0ff1a3e12f4bde8d592cc254ab075cfe734fc5dd989036716fd17ee7e5ec7", + "sha256:3b9909bc96b0edc6b01586e1eed05e71174ef4e04c71da5786370cebea53ad74" ], "index": "pypi", - "version": "==0.12.0" + "version": "==0.13.0" }, "python-jose": { "hashes": [ @@ -266,7 +274,25 @@ }, "sqlalchemy": { "hashes": [ - "sha256:7224e126c00b8178dfd227bc337ba5e754b197a3867d33b9f30dc0208f773d70" + "sha256:083e383a1dca8384d0ea6378bd182d83c600ed4ff4ec8247d3b2442cf70db1ad", + "sha256:0a690a6486658d03cc6a73536d46e796b6570ac1f8a7ec133f9e28c448b69828", + "sha256:114b6ace30001f056e944cebd46daef38fdb41ebb98f5e5940241a03ed6cad43", + "sha256:128f6179325f7597a46403dde0bf148478f868df44841348dfc8d158e00db1f9", + "sha256:13d48cd8b925b6893a4e59b2dfb3e59a5204fd8c98289aad353af78bd214db49", + "sha256:211a1ce7e825f7142121144bac76f53ac28b12172716a710f4bf3eab477e730b", + "sha256:2dc57ee80b76813759cccd1a7affedf9c4dbe5b065a91fb6092c9d8151d66078", + "sha256:3e625e283eecc15aee5b1ef77203bfb542563fa4a9aa622c7643c7b55438ff49", + "sha256:43078c7ec0457387c79b8d52fff90a7ad352ca4c7aa841c366238c3e2cf52fdf", + "sha256:5b1bf3c2c2dca738235ce08079783ef04f1a7fc5b21cf24adaae77f2da4e73c3", + "sha256:6056b671aeda3fc451382e52ab8a753c0d5f66ef2a5ccc8fa5ba7abd20988b4d", + "sha256:68d78cf4a9dfade2e6cf57c4be19f7b82ed66e67dacf93b32bb390c9bed12749", + "sha256:7025c639ce7e170db845e94006cf5f404e243e6fc00d6c86fa19e8ad8d411880", + "sha256:7224e126c00b8178dfd227bc337ba5e754b197a3867d33b9f30dc0208f773d70", + "sha256:7d98e0785c4cd7ae30b4a451416db71f5724a1839025544b4edbd92e00b91f0f", + "sha256:8d8c21e9d4efef01351bf28513648ceb988031be4159745a7ad1b3e28c8ff68a", + "sha256:bbb545da054e6297242a1bb1ba88e7a8ffb679f518258d66798ec712b82e4e07", + "sha256:d00b393f05dbd4ecd65c989b7f5a81110eae4baea7a6a4cdd94c20a908d1456e", + "sha256:e18752cecaef61031252ca72031d4d6247b3212ebb84748fc5d1a0d2029c23ea" ], "index": "pypi", "version": "==1.3.16" @@ -277,13 +303,6 @@ "sha256:6c80b1e5ad3665290ea39320b91e1be1e0d5f60652b964a3070216de83d2e47c" ], "version": "==1.0.1" - }, - "zipp": { - "hashes": [ - "sha256:aa36550ff0c0b7ef7fa639055d797116ee891440eac1a56f378e2d3179e0320b", - "sha256:c599e4d75c98f6798c509911d08a22e6c021d074469042177c8c86fb92eefd96" - ], - "version": "==3.1.0" } }, "develop": {} diff --git a/api.py b/api.py index 54b3aab..b6dcb32 100644 --- a/api.py +++ b/api.py @@ -61,8 +61,7 @@ ] }) -app.config.update( - SQLALCHEMY_DATABASE_URI='mysql+mysqlconnector://{user}:{pw}@{url}/{db}'.format(user=env.get("DB_USERNAME"), pw=env.get("DB_PASSWORD"), url=env.get("DB_HOST"), db="classclock"), DEBUG=True, SQLALCHEMY_TRACK_MODIFICATIONS=False) +app.config.update(DEBUG=True, SQLALCHEMY_TRACK_MODIFICATIONS=False) db.init_app(app) if __name__ == "__main__": From fce6450207242f4290768995a77d3a962003e9df Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Thu, 7 May 2020 19:28:28 -0700 Subject: [PATCH 007/206] add a "setup" command and interactive prompt for missing db credentials --- api.py | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/api.py b/api.py index b6dcb32..fc850d8 100644 --- a/api.py +++ b/api.py @@ -5,8 +5,30 @@ from flasgger import Swagger from common.helpers import get_request_origin_identifier from common.db_schema import db +import os, sys, getpass from os import environ as env +#default values are only needed for some of these +db_username = env.get("DB_USERNAME") +db_password = env.get("DB_PASSWORD") +db_host = os.getenv("DB_HOST", "localhost") +db_name = os.getenv("DB_NAME", "classclock") + +if not db_username: + db_username = input('database username: ') +if not db_password: + db_password = getpass.getpass('database password (input not shown): ') + + +db_connection_string=os.getenv("DB_CONNECTION_URL", + 'mysql+mysqlconnector://{user}:{pw}@{url}/{db}'.format( + user=db_username, + pw=db_password, + url=db_host, + db=db_name + ) +) + app = Flask(__name__) limiter = Limiter(app, default_limits=[ "25/hour", "5/minute"], key_func=get_request_origin_identifier, headers_enabled=True) @@ -61,9 +83,19 @@ ] }) -app.config.update(DEBUG=True, SQLALCHEMY_TRACK_MODIFICATIONS=False) +app.config.update(SQLALCHEMY_DATABASE_URI=db_connection_string,DEBUG=True, SQLALCHEMY_TRACK_MODIFICATIONS=False) db.init_app(app) +if sys.argv[1] == "setup": + +# https://stackoverflow.com/a/46541219 + with app.app_context(): + db.create_all() + db.session.commit() + print("Done.") + exit(0) + + if __name__ == "__main__": app.run() else: From 193ce6f1a4ce0e89cfd3442a7f36faed2863e3a6 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Thu, 7 May 2020 20:31:37 -0700 Subject: [PATCH 008/206] add readme documenting environment variables and db initialization --- README.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..0e98321 --- /dev/null +++ b/README.md @@ -0,0 +1,23 @@ +# ClassClockAPI + +This is the backend that provides access to the ClassClock database. + +## Environment Variables + +| Environment Variable | Default | Purpose | +| ------------- | ------------- | ------------- | +| DB_USERNAME | no default. this value is required | The username of the user to connect to the database with | +| DB_PASSWORD | no default. this value is required | The password of the user to connect to the database with | +| DB_HOST | `localhost` | the hostname where the database is located | +| DB_NAME | `classclock` | the name of the database to use if it is different | +| DB_CONNECTION_URL | constructed based on the above values | Allows the SQLAlchemy connection string to be manually set | +| AUTH0_DOMAIN | no default | The Auth0 api domain i.e. `yourapp.auth0.com` | +| API_IDENTIFIER | no default | Your Auth0 api identifier. This may be your API domain name. i.e. `https://api.yourdomain.com` | +| AUTH0_CLIENT_ID | no default | Your Auth0 Client ID | +| AUTH0_CLIENT_SECRET | no default | Your Auth0 Client Secret | + + + +## Setup command + +To run the setup script, first create an empty database and a new user that can access the database. Then, with the environment variables set appropriately as listed above, execute `python3 api.py setup`. If you have not specified the `DB_USERNAME` or `DB_PASSWORD` environment variables, you will be prompted for them interactively when the script runs. \ No newline at end of file From cac55f8c4068d5a3acc8f568f8f824b18152cdb3 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Fri, 8 May 2020 20:53:48 -0700 Subject: [PATCH 009/206] add a demo command to populate the database with sample data --- api.py | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 68 insertions(+), 5 deletions(-) diff --git a/api.py b/api.py index fc850d8..ba94d63 100644 --- a/api.py +++ b/api.py @@ -14,10 +14,12 @@ db_host = os.getenv("DB_HOST", "localhost") db_name = os.getenv("DB_NAME", "classclock") -if not db_username: - db_username = input('database username: ') -if not db_password: - db_password = getpass.getpass('database password (input not shown): ') +if sys.argv[1] in ("setup", "demo"): + if not env.get("DB_CONNECTION_URL"): + if not db_username: + db_username = input('database username: ') + if not db_password: + db_password = getpass.getpass('database password (input not shown): ') db_connection_string=os.getenv("DB_CONNECTION_URL", @@ -87,13 +89,74 @@ db.init_app(app) if sys.argv[1] == "setup": - # https://stackoverflow.com/a/46541219 with app.app_context(): db.create_all() db.session.commit() print("Done.") exit(0) +elif sys.argv[1] == "demo": +# https://stackoverflow.com/a/46541219 + with app.app_context(): + from common.db_schema import * + import datetime + import time + + + def today_plus(sch, num_days): + return BellScheduleDate(school_id = sch, date=datetime.date.today() + datetime.timedelta(days=num_days)) + + s = School(owner_id="1234567890", full_name="Demonstration High School", acronym="DHS") + + + sc1 = BellSchedule( + school_id = s.id, + name="Even Day", + display_name= "Even", + dates=[ + today_plus(s.id, 0), + today_plus(s.id, 2), + today_plus(s.id, 4) + ] + ) + + sc2 = BellSchedule( + school_id = s.id, + name="Odd Day", + display_name="Odd", + dates=[ + today_plus(s.id, 1), + today_plus(s.id, 3) + ] + ) + + + s.schedules = [sc1,sc2] + + + sc1.meetingtimes = [ + BellScheduleMeetingTime( + schedule_id =sc1.id, + name="First Period", + start_time=datetime.time(hour=8, minute=25, second=0, microsecond=0), + end_time=datetime.time(9,25) + ) + ] + + sc2.meetingtimes = [ + BellScheduleMeetingTime( + schedule_id =sc2.id, + name="First Period", + start_time=datetime.time(8,45), + end_time=datetime.time(9,45) + ) + + ] + + db.session.add(s) + db.session.commit() + print("Done.") + exit(0) if __name__ == "__main__": From c0a08068f9bf88f0340a95c2861e5475f42075ad Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Fri, 8 May 2020 20:55:52 -0700 Subject: [PATCH 010/206] update HashColumn so that it works with a BINARY column, not a VARCHAR column --- common/guid.py | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/common/guid.py b/common/guid.py index fa25853..3c21e24 100644 --- a/common/guid.py +++ b/common/guid.py @@ -1,13 +1,18 @@ from __future__ import absolute_import -# import uuid +import uuid from sqlalchemy import types, func -class HashColumn(types.VARCHAR): +#https://docs.sqlalchemy.org/en/13/core/custom_types.html#backend-agnostic-guid-type +class HashColumn(types.TypeDecorator): + impl=types.BINARY - def bind_expression(self, bindvalue): - # convert the bind's type from Hex string to binary - return func.UNHEX(bindvalue) + def process_bind_param(self, value, dialect): + if value is not None: + return uuid.UUID(hex=value).bytes - def column_expression(self, col): - # convert select value from binary to hex String - return func.HEX(col) + def process_result_value(self, value, dialect): + return uuid.UUID(bytes=value).hex + + + def copy(self, **kw): + return HashColumn(self.impl.length) \ No newline at end of file From 24de5bb474e84fcabe613b4e884d14efc86fc962 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Thu, 28 May 2020 16:33:45 -0700 Subject: [PATCH 011/206] remove marshmallow_jsonapi and update schemas --- common/convert.py | 51 ------------- common/fields.py | 57 -------------- common/schemas.py | 191 ++-------------------------------------------- 3 files changed, 6 insertions(+), 293 deletions(-) delete mode 100644 common/convert.py delete mode 100644 common/fields.py diff --git a/common/convert.py b/common/convert.py deleted file mode 100644 index 764a31f..0000000 --- a/common/convert.py +++ /dev/null @@ -1,51 +0,0 @@ -""" -Customized Marshmallow-SQLAlchemy ModelConverter to combine Related and Relationship fields. -""" - - -import marshmallow_sqlalchemy - -from common.helpers import camel_to_delimiter_separated -from common.fields import Relationship - - -class ModelConverter(marshmallow_sqlalchemy.ModelConverter): - """ Customize SQLAlchemy Model Converter to use JSON API Relationships. """ - - # property2field will convert the Relationship to a List field if the prop.direction.name in - # this mapping returns True. Hack to work around that since this mapping is only used there. - # https://github.com/marshmallow-code/marshmallow-sqlalchemy/blob/af8304a33bfc11468d9ddb6c96e183964806d637/marshmallow_sqlalchemy/convert.py#L131 - DIRECTION_MAPPING = { - 'MANYTOONE': False, - 'MANYTOMANY': False, - 'ONETOMANY': False, - } - - def _get_field_class_for_property(self, prop): - """ Use our Relationship field type for SQLAlchemy relations instead. """ - if hasattr(prop, 'direction'): - return Relationship - return super()._get_field_class_for_property(prop) - - def _add_relationship_kwargs(self, kwargs, prop): - """ Customize the kwargs for Relationship field based on prop. """ - # super()._add_relationship_kwargs(kwargs, prop) - - # All Schema names should be based on Model name. - kwargs['schema'] = prop.mapper.class_.__name__ + 'Schema' - # If the relation uses a list then the Relationship is many - kwargs['many'] = prop.uselist - # JSONAPI type is calculated from Model name to kebab-case. - kwargs['type_'] = camel_to_delimiter_separated(prop.mapper.class_.__name__, glue='-') - # Attribute of the model for this relationship. - kwargs['attribute'] = prop.key - # self.schema_cls is not an instance of the class so we need to use the options directly. - # Name of the relationship on parent model to use for constructing relationship URLs. - kwargs['relationship_name'] = self.schema_cls.opts.inflect(prop.key) - # The relationship's URLs will be calculated from the parent schema's self URL. - kwargs['parent_self_url'] = self.schema_cls.opts.self_url - # Relationship URLs will use the same kwargs as the parent schema. - kwargs['self_url_kwargs'] = self.schema_cls.opts.self_url_kwargs - # Store the model of the schema_cls so the relationship knows everything necessary for the - # endpoint. - kwargs['parent_model'] = self.schema_cls.opts.model diff --git a/common/fields.py b/common/fields.py deleted file mode 100644 index 016654c..0000000 --- a/common/fields.py +++ /dev/null @@ -1,57 +0,0 @@ -""" -Customized Fields for Our Marshmallow. -""" - -from marshmallow.base import FieldABC -# Make marshmallow core and jsonapi fields importable from ourmarshmallow -from marshmallow.fields import * # pylint: disable=wildcard-import,unused-wildcard-import -import marshmallow_jsonapi.fields -import marshmallow_sqlalchemy.fields - - -class MetaData(marshmallow_jsonapi.fields.ResourceMeta): #update - """ Per-field metadata wrapper. Turns another field into MetaData. - Based on marshmallow.fields.List """ - def __init__(self, cls_or_instance, **kwargs): - # Force dump_only=True. - kwargs['dump_only'] = True - # Since we don't always know what the attribute is for this field, and Meta sets the - # load_from to '_meta' it is difficult to load this value so don't. - - super().__init__(**kwargs) - - if isinstance(cls_or_instance, type): - if not issubclass(cls_or_instance, FieldABC): - raise ValueError('The type of the metadata elements must be a subclass of ' - 'marshmallow.base.FieldABC') - self.container = cls_or_instance() - else: - if not isinstance(cls_or_instance, FieldABC): - raise ValueError('The instances of the metadata elements must be of type ' - 'marshmallow.base.FieldABC') - self.container = cls_or_instance - - def _serialize(self, value, attr, obj): # pylint: disable=arguments-differ - return {self.dump_to or attr: self.container._serialize(value, attr, obj)} # pylint: disable=protected-access - - -class Relationship(marshmallow_jsonapi.fields.Relationship, marshmallow_sqlalchemy.fields.Related): - """ - Combine the marshmallow-jsonapi.fields.Relationship with marshmallow-sqlalchemy.fields.Related. - """ - def __init__(self, parent_self_url='', relationship_name='', parent_model=None, **kwargs): - """ - :param str parent_self_url: Used to calculate self_url and related_url from a parent schema. - :param str relationship_name: Name of this relationship for self_url and related_url. - :param models.bases.BaseModel parent_model: Model Class of Schema containing this field. - """ - # Calculate our relationship URLs beased on the parent schema's self_url - #if parent_self_url and relationship_name and kwargs['self_url_kwargs']: - # kwargs['self_url'] = '{0}/relationships/{1}'.format(parent_self_url, relationship_name) - # kwargs['related_url'] = '{0}/{1}'.format(parent_self_url, relationship_name) - # kwargs['related_url_kwargs'] = kwargs['self_url_kwargs'] - - # Set the class of the model for the schema containing this field. - self.parent_model = parent_model - - super().__init__(**kwargs) diff --git a/common/schemas.py b/common/schemas.py index bfb324f..1a0f4cb 100644 --- a/common/schemas.py +++ b/common/schemas.py @@ -2,186 +2,23 @@ Customized Marshmallow-SQLAlchemy and Marshmallow-JSONAPI Schemas to combine Schema Meta data. """ import marshmallow as ma -import marshmallow_jsonapi -import marshmallow_sqlalchemy +from marshmallow_sqlalchemy import SQLAlchemyAutoSchema from common.helpers import camel_to_delimiter_separated from common.db_schema import db -from .convert import ModelConverter from .exceptions import ForbiddenIdError, MismatchIdError, NullPrimaryData -from .fields import MetaData from common.db_schema import BellSchedule, BellScheduleMeetingTime, School, BellScheduleDate -class SchemaOpts(marshmallow_jsonapi.SchemaOpts, marshmallow_sqlalchemy.ModelSchemaOpts): # pylint: disable=too-few-public-methods - """ Combine JSON API Schema Opts with SQLAlchemy Schema Opts. - This fixes the error: AttributeError: 'SchemaOpts' object has no attribute 'model_converter """ - def __init__(self, meta, *args, **kwargs): - """ - Forces strict=True. - Forces type_ to kebab-case of self.opts.model.__name__ for JSONAPI recommendation. - Sets up default self_url and kwargs if model option is set. - Sets up default self_url_many if model and listable are truthy. - """ - # Does Resource support a read list endpoint? Default False. Needed for Swagger. - self.listable = getattr(meta, 'listable', False) - - # TODO: ROB 20170726 Check status of github.com/marshmallow-code/marshmallow/issues/377 - # Force strict by default until ticket is resolved. - meta.strict = True - - # When the base Schema below is first initialized there won't be a model element. - model = getattr(meta, 'model', None) - if model: - # Automatically set the JSONAPI type (marshmallow-jsonapi) based on model name. - # JSONAPI recommends kebab-case for naming: http://jsonapi.org/recommendations/#naming - type_ = camel_to_delimiter_separated( - model.__name__, glue='-') - meta.type_ = type_ - - # Self URLs are always based on the JSONAPI type and the model id - meta.self_url = f'/{type_}/{{id}}' - meta.self_url_kwargs = {'id': ''} - # Always include the many url for resource creation at least - meta.self_url_many = f'/{type_}s' - - # Use our custom ModelConverter to turn SQLAlchemy relations into JSONAPI Relationships. - meta.model_converter = ModelConverter - - def dasherize(text): - """ - Convert snake_case field names to jsonapi kebab-case. - :param str text: field name - :return str: kebab-case name - """ - return text.replace('_', '-') - meta.inflect = dasherize - - super().__init__(meta, *args, **kwargs) - - -class Schema(marshmallow_jsonapi.Schema, marshmallow_sqlalchemy.ModelSchema): - """ Set custom options class to combine JSONAPI and SQLAlchemy. Set strict option by default. - Configure DB connection on init. """ - OPTIONS_CLASS = SchemaOpts - - # id must be a string: http://jsonapi.org/format/#document-resource-object-identification - id = marshmallow_jsonapi.fields.String(length=16) # pylint: disable=invalid-name - # This field is read only, place in meta data: http://jsonapi.org/format/#document-meta - modified_at = MetaData(marshmallow_jsonapi.fields.DateTime()) - - def __init__(self, *args, **kwargs): - """ - Combine the inits for marshmallow_jsonapi.Schema, marshmallow_sqlalchemy.ModelSchema. - Forces session=db.connect(). - """ - # control if unwrap_item checks for the id field in the object. - self.load_existing = True - - # Each instance of the schema should have the current session with the DB - # (marshmallow-sqlschema). This must be done on instance init, not on class creation! - - # kwargs['session'] = db.connect() - - super().__init__(*args, **kwargs) - - @classmethod - def field_for(cls, field_name): - """ - Get a marshmallow field object for an attribute of this schema. - :param str field_name: Name of attribute to return the marshmallow.fields for. - :return ourmarshmallow.fields.Field: Subclass of Field for attribute of schema class. - """ - # _declared_fields is set by the metaclass marshmallow.schema.SchemaMeta - ret = cls._declared_fields[field_name] # pylint: disable=no-member - # ret._add_to_schema(field_name, cls) - return ret - - @ma.post_load(pass_many=True) - def make_instance(self, data, many): # pylint: disable=arguments-differ - """ - Deserialize data to instances of the model. Update an existing if specified in - `self.instance` or loaded by primary key(s) in the data; else create a new model. - :param data: Data to deserialize. - :param many: Does data represent many models. - :return models.BaseModel or list(models.BaseModel): Instance(s) of model(s) updated with - data. - """ - if many: - return [super().make_instance(each) for each in data] - return super().make_instance(data) - - def unwrap_item(self, item): - """ - If the schema has an existing instance the id field must be set. - :raises ValidationError: id field isn't present when required. - """ - id_in_item = 'id' in item - if self.load_existing and not id_in_item: - # Updating Resources must include type and id keys - # http://jsonapi.org/format/1.1/#crud-updating - raise ma.ValidationError([{'detail': '`data` object must include `id` key.', - 'source': {'pointer': '/data'}}]) - - if not self.load_existing and id_in_item: - # Don't support client side identifier generation at this time. - raise ForbiddenIdError() - - return super().unwrap_item(item) - - @ma.pre_load(pass_many=True) - def unwrap_request(self, data, many): - if 'data' not in data: - raise ma.ValidationError('Object must include `data` key.') - - data = data['data'] - data_is_collection = ma.utils.is_collection(data) - if many: - if not data_is_collection: - raise ma.ValidationError([{'detail': '`data` object must be a collection.', - 'source': {'pointer': '/data'}}]) - - return [self.unwrap_item(each) for each in data] - - if data_is_collection: - raise ma.ValidationError([ - {'detail': '`data` object must be an object, not a collection.', - 'source': {'pointer': '/data'}}]) - - if data is None: - # When updating relationships we need to specially handle the primary data being null. - # http://jsonapi.org/format/1.1/#crud-updating-to-one-relationships - raise NullPrimaryData() - - return self.unwrap_item(data) - - @ma.validates('id') - def validate_id(self, value): - """ - If the schema has an existing instance the id value must match id. Use custom errors so we - can generate to the correct source.pointer and response code. - :param int value: identifier from payload. - :raises MismatchIdError: id field doesn't match self.instance. - """ - if self.instance and self.instance.id != value: - raise MismatchIdError(actual=value, expected=self.instance.id) - - -class SchoolSchema(Schema): +class SchoolSchema(SQLAlchemyAutoSchema): class Meta: model = School include_relationships = True load_instance = True include_fk = True - # Marshmallow-JSONAPI - type_ = model.__name__.lower() - self_view = type_ + '_detail' - self_view_kwargs = {'id': ''} - self_view_many = type_ + '_list' - -class BellScheduleDateSchema(Schema): +class BellScheduleDateSchema(SQLAlchemyAutoSchema): class Meta: model = BellScheduleDate @@ -189,26 +26,14 @@ class Meta: load_instance = True include_fk = True - # Marshmallow-JSONAPI - type_ = model.__name__.lower() - self_view = type_ + '_detail' - self_view_kwargs = {'id': ''} - self_view_many = type_ + '_list' - -class BellScheduleMeetingTimeSchema(Schema): +class BellScheduleMeetingTimeSchema(SQLAlchemyAutoSchema): class Meta: model = BellScheduleMeetingTime include_relationships = True load_instance = True include_fk = True - # Marshmallow-JSONAPI - type_ = model.__name__.lower() - self_view = type_ + '_detail' - self_view_kwargs = {'id': ''} - self_view_many = type_ + '_list' - -class BellScheduleSchema(Schema): +class BellScheduleSchema(SQLAlchemyAutoSchema): class Meta: model = BellSchedule @@ -216,8 +41,4 @@ class Meta: load_instance = True include_fk = True - # Marshmallow-JSONAPI - type_ = model.__name__.lower() - self_view = type_ + '_detail' - self_view_kwargs = {'id': ''} - self_view_many = type_ + '_list' + # Pluck dates and meeting times? From 7f352ce3ad6d5d8f9bc48ffc5df5af3b0930ce41 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Thu, 28 May 2020 23:27:44 -0700 Subject: [PATCH 012/206] uninstall marshmallow_jsonapi dependency --- Pipfile | 1 - Pipfile.lock | 89 ++++++++++++++++++++++++++-------------------------- 2 files changed, 45 insertions(+), 45 deletions(-) diff --git a/Pipfile b/Pipfile index a91a643..62495f5 100644 --- a/Pipfile +++ b/Pipfile @@ -19,7 +19,6 @@ Flask-Limiter = "*" gunicorn = "*" sqlalchemy = "*" json-api-doc = "*" -marshmallow-jsonapi = "*" flask-sqlalchemy = "*" marshmallow-sqlalchemy = "*" diff --git a/Pipfile.lock b/Pipfile.lock index 21efd7c..3188800 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "f0f9f5660e21adaf4651977ab1b8d83ee04f160b4116181c2258618ed6d6d404" + "sha256": "db83acf67cdf36f0d6afde39fe2aad3c4fad55e5b53149534e455fd45652f739" }, "pipfile-spec": 6, "requires": { @@ -71,11 +71,11 @@ }, "flask-limiter": { "hashes": [ - "sha256:d984a57ef37acb6eee29edc864ff22cd4cf090845f06968c015093ffd91e96f1", - "sha256:db2a069402977927282b0fcf650753bfcb50488028def9f5b2398e1d525f2f9f" + "sha256:08d6d7534a847c532fd36d0df978f93908d8616813085941c862bbcfcf6811aa", + "sha256:82c154bd96c0a9c8307d9500876e72b247a35a5c7374a2c606fc32b647a6d8cb" ], "index": "pypi", - "version": "==1.2.1" + "version": "==1.3.1" }, "flask-marshmallow": { "hashes": [ @@ -87,11 +87,11 @@ }, "flask-sqlalchemy": { "hashes": [ - "sha256:0078d8663330dc05a74bc72b3b6ddc441b9a744e2f56fe60af1a5bfc81334327", - "sha256:6974785d913666587949f7c2946f7001e4fa2cb2d19f4e69ead02e4b8f50b33d" + "sha256:0b656fbf87c5f24109d859bafa791d29751fabbda2302b606881ae5485b557a5", + "sha256:fcfe6df52cd2ed8a63008ca36b86a51fa7a4b70cef1c39e5625f722fca32308e" ], "index": "pypi", - "version": "==2.4.1" + "version": "==2.4.3" }, "gunicorn": { "hashes": [ @@ -117,11 +117,11 @@ }, "json-api-doc": { "hashes": [ - "sha256:1d2718da739845d65f994a7de727ff7d38bc69f5defa1f7cf6f8df114b0d5879", - "sha256:ead8275f5d77f2d67493d37b78a61c23a4157abf97ee91b70890e13534c2707e" + "sha256:58eb2363ef1b05e0ff91c4977bf891d0f80f7253f2029b4b94e4ac442be87e61", + "sha256:79126b05bff342ba293eba782d199e69599ebe30f1b53713bf7760823c054cd7" ], "index": "pypi", - "version": "==0.13.0" + "version": "==0.14.0" }, "jsonschema": { "hashes": [ @@ -177,18 +177,10 @@ }, "marshmallow": { "hashes": [ - "sha256:56663fa1d5385c14c6a1236badd166d6dee987a5f64d2b6cc099dadf96eb4f09", - "sha256:f12203bf8d94c410ab4b8d66edfde4f8a364892bde1f6747179765559f93d62a" + "sha256:c2673233aa21dde264b84349dc2fd1dce5f30ed724a0a00e75426734de5b84ab", + "sha256:f88fe96434b1f0f476d54224d59333eba8ca1a203a2695683c1855675c4049a7" ], - "version": "==3.5.2" - }, - "marshmallow-jsonapi": { - "hashes": [ - "sha256:0d5567ad98d834149e4329d244732bda0185dc51b5fef0ec7dc58e9d1d7c0493", - "sha256:289ac50cc65d9febfe432892345f44b99d4520d48538a86cf274549712fa6a82" - ], - "index": "pypi", - "version": "==0.23.1" + "version": "==3.6.0" }, "marshmallow-sqlalchemy": { "hashes": [ @@ -266,36 +258,45 @@ }, "six": { "hashes": [ - "sha256:236bdbdce46e6e6a3d61a337c0f8b763ca1e8717c03b369e87a7ec7ce1319c0a", - "sha256:8f3cd2e254d8f793e7f3d6d9df77b92252b52637291d0f0da013c76ea2724b6c" + "sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259", + "sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced" ], "index": "pypi", - "version": "==1.14.0" + "version": "==1.15.0" }, "sqlalchemy": { "hashes": [ - "sha256:083e383a1dca8384d0ea6378bd182d83c600ed4ff4ec8247d3b2442cf70db1ad", - "sha256:0a690a6486658d03cc6a73536d46e796b6570ac1f8a7ec133f9e28c448b69828", - "sha256:114b6ace30001f056e944cebd46daef38fdb41ebb98f5e5940241a03ed6cad43", - "sha256:128f6179325f7597a46403dde0bf148478f868df44841348dfc8d158e00db1f9", - "sha256:13d48cd8b925b6893a4e59b2dfb3e59a5204fd8c98289aad353af78bd214db49", - "sha256:211a1ce7e825f7142121144bac76f53ac28b12172716a710f4bf3eab477e730b", - "sha256:2dc57ee80b76813759cccd1a7affedf9c4dbe5b065a91fb6092c9d8151d66078", - "sha256:3e625e283eecc15aee5b1ef77203bfb542563fa4a9aa622c7643c7b55438ff49", - "sha256:43078c7ec0457387c79b8d52fff90a7ad352ca4c7aa841c366238c3e2cf52fdf", - "sha256:5b1bf3c2c2dca738235ce08079783ef04f1a7fc5b21cf24adaae77f2da4e73c3", - "sha256:6056b671aeda3fc451382e52ab8a753c0d5f66ef2a5ccc8fa5ba7abd20988b4d", - "sha256:68d78cf4a9dfade2e6cf57c4be19f7b82ed66e67dacf93b32bb390c9bed12749", - "sha256:7025c639ce7e170db845e94006cf5f404e243e6fc00d6c86fa19e8ad8d411880", - "sha256:7224e126c00b8178dfd227bc337ba5e754b197a3867d33b9f30dc0208f773d70", - "sha256:7d98e0785c4cd7ae30b4a451416db71f5724a1839025544b4edbd92e00b91f0f", - "sha256:8d8c21e9d4efef01351bf28513648ceb988031be4159745a7ad1b3e28c8ff68a", - "sha256:bbb545da054e6297242a1bb1ba88e7a8ffb679f518258d66798ec712b82e4e07", - "sha256:d00b393f05dbd4ecd65c989b7f5a81110eae4baea7a6a4cdd94c20a908d1456e", - "sha256:e18752cecaef61031252ca72031d4d6247b3212ebb84748fc5d1a0d2029c23ea" + "sha256:128bc917ed20d78143a45024455ff0aed7d3b96772eba13d5dbaf9cc57e5c41b", + "sha256:156a27548ba4e1fed944ff9fcdc150633e61d350d673ae7baaf6c25c04ac1f71", + "sha256:27e2efc8f77661c9af2681755974205e7462f1ae126f498f4fe12a8b24761d15", + "sha256:2a12f8be25b9ea3d1d5b165202181f2b7da4b3395289000284e5bb86154ce87c", + "sha256:31c043d5211aa0e0773821fcc318eb5cbe2ec916dfbc4c6eea0c5188971988eb", + "sha256:65eb3b03229f684af0cf0ad3bcc771970c1260a82a791a8d07bffb63d8c95bcc", + "sha256:6cd157ce74a911325e164441ff2d9b4e244659a25b3146310518d83202f15f7a", + "sha256:703c002277f0fbc3c04d0ae4989a174753a7554b2963c584ce2ec0cddcf2bc53", + "sha256:869bbb637de58ab0a912b7f20e9192132f9fbc47fc6b5111cd1e0f6cdf5cf9b0", + "sha256:8a0e0cd21da047ea10267c37caf12add400a92f0620c8bc09e4a6531a765d6d7", + "sha256:8d01e949a5d22e5c4800d59b50617c56125fc187fbeb8fa423e99858546de616", + "sha256:925b4fe5e7c03ed76912b75a9a41dfd682d59c0be43bce88d3b27f7f5ba028fb", + "sha256:9cb1819008f0225a7c066cac8bb0cf90847b2c4a6eb9ebb7431dbd00c56c06c5", + "sha256:a87d496884f40c94c85a647c385f4fd5887941d2609f71043e2b73f2436d9c65", + "sha256:a9030cd30caf848a13a192c5e45367e3c6f363726569a56e75dc1151ee26d859", + "sha256:a9e75e49a0f1583eee0ce93270232b8e7bb4b1edc89cc70b07600d525aef4f43", + "sha256:b50f45d0e82b4562f59f0e0ca511f65e412f2a97d790eea5f60e34e5f1aabc9a", + "sha256:b7878e59ec31f12d54b3797689402ee3b5cfcb5598f2ebf26491732758751908", + "sha256:ce1ddaadee913543ff0154021d31b134551f63428065168e756d90bdc4c686f5", + "sha256:ce2646e4c0807f3461be0653502bb48c6e91a5171d6e450367082c79e12868bf", + "sha256:ce6c3d18b2a8ce364013d47b9cad71db815df31d55918403f8db7d890c9d07ae", + "sha256:e4e2664232005bd306f878b0f167a31f944a07c4de0152c444f8c61bbe3cfb38", + "sha256:e8aa395482728de8bdcca9cc0faf3765ab483e81e01923aaa736b42f0294f570", + "sha256:eb4fcf7105bf071c71068c6eee47499ab8d4b8f5a11fc35147c934f0faa60f23", + "sha256:ed375a79f06cad285166e5be74745df1ed6845c5624aafadec4b7a29c25866ef", + "sha256:f35248f7e0d63b234a109dd72fbfb4b5cb6cb6840b221d0df0ecbf54ab087654", + "sha256:f502ef245c492b391e0e23e94cba030ab91722dcc56963c85bfd7f3441ea2bbe", + "sha256:fe01bac7226499aedf472c62fa3b85b2c619365f3f14dd222ffe4f3aa91e5f98" ], "index": "pypi", - "version": "==1.3.16" + "version": "==1.3.17" }, "werkzeug": { "hashes": [ From a3bbb1f6307a8b54c063a25b4eb35af858154879 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Thu, 28 May 2020 23:34:35 -0700 Subject: [PATCH 013/206] more removing old crap --- common/exceptions.py | 28 ---------------------------- common/helpers.py | 2 -- common/schemas.py | 1 - 3 files changed, 31 deletions(-) diff --git a/common/exceptions.py b/common/exceptions.py index 077b25e..ff5cbcf 100644 --- a/common/exceptions.py +++ b/common/exceptions.py @@ -1,31 +1,3 @@ -""" -Custom exceptions for our marshmallow -""" -from marshmallow_jsonapi.exceptions import IncorrectTypeError - -class ForbiddenIdError(IncorrectTypeError): - """ - Raised when a client attempts to provide an id when creating a resource. Special case so we can - return the correct response code. - """ - pointer = '/data/id' - default_message = '`data` object must not include `id` key.' - - -class MismatchIdError(IncorrectTypeError): - """ - Raised when a client provides an id that doesn't match the request. Special case so we can - return the correct response code. - """ - pointer = '/data/id' - default_message = 'Mismatched id. Expected "{expected}".' - - -class NullPrimaryData(Exception): - """ Raised by Schema.unwrap_request when the primary data object is null/None. """ - pass - - # Format error response and append status code. class AuthError(Exception): diff --git a/common/helpers.py b/common/helpers.py index 822a5d8..46a4767 100644 --- a/common/helpers.py +++ b/common/helpers.py @@ -13,8 +13,6 @@ import re import marshmallow -import marshmallow_jsonapi -import marshmallow_jsonapi.flask import marshmallow_sqlalchemy from common.constants import AuthType diff --git a/common/schemas.py b/common/schemas.py index 1a0f4cb..da6461c 100644 --- a/common/schemas.py +++ b/common/schemas.py @@ -7,7 +7,6 @@ from common.helpers import camel_to_delimiter_separated from common.db_schema import db -from .exceptions import ForbiddenIdError, MismatchIdError, NullPrimaryData from common.db_schema import BellSchedule, BellScheduleMeetingTime, School, BellScheduleDate From a8bf4d15044aef4e735e043e3f48afded91d8928 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Thu, 28 May 2020 23:57:06 -0700 Subject: [PATCH 014/206] update endpoints to be less stacked and change back to normal JSON --- versions/v0.py | 73 ++++++++++++++++++++++++-------------------------- 1 file changed, 35 insertions(+), 38 deletions(-) diff --git a/versions/v0.py b/versions/v0.py index 170d4e3..870ac31 100644 --- a/versions/v0.py +++ b/versions/v0.py @@ -213,46 +213,46 @@ def delete_school(school_id): return None, 204 -@blueprint.route("/school//bellschedules/", methods=['GET']) -@check_headers -def list_bellschedules(school_id): - check_permissions([APIScopes.LIST_BELL_SCHEDULES]) +# @blueprint.route("/school//bellschedules/", methods=['GET']) +# @check_headers +# def list_bellschedules(school_id): +# check_permissions([APIScopes.LIST_BELL_SCHEDULES]) - schedule_list = [] - schedules = BellScheduleDB.query.filter_by(school_id=school_id) +# schedule_list = [] +# schedules = BellScheduleDB.query.filter_by(school_id=school_id) - for schedule in schedules: - schedule_list.append(schedule) - return BellScheduleSchema(exclude=('school_id',)).dump(schedule_list, many=True) +# for schedule in schedules: +# schedule_list.append(schedule) +# return BellScheduleSchema(exclude=('school_id',)).dump(schedule_list, many=True) -@blueprint.route("/school//bellschedule//", methods=['GET']) +@blueprint.route("/bellschedule//", methods=['GET']) @check_headers -def get_bellschedule(school_id, bell_schedule_id): +def get_bellschedule(bell_schedule_id): check_permissions([APIScopes.READ_BELL_SCHEDULE]) schedule = BellScheduleDB.query.filter_by( - id=bell_schedule_id, school_id=school_id).first() + id=bell_schedule_id).first() #double check this if schedule is None: - raise Oops("No school was found with the specified id.", + raise Oops("No bell schedule was found with the specified id.", 404, title="Resource Not Found") return BellScheduleSchema(exclude=('school_id',)).dump(schedule) -@blueprint.route("/school//bellschedule/", methods=['POST']) +@blueprint.route("/bellschedule/", methods=['POST']) @check_headers @requires_auth @requires_admin -def create_bellschedule(school_id): +def create_bellschedule(): check_permissions([APIScopes.CREATE_BELL_SCHEDULE]) + # get school_id from a data parameter school = SchoolDB.query.filter_by(id=school_id).first() - check_ownership(school) new_schedule = BellScheduleSchema().load(request.get_json()["data"]).data @@ -264,26 +264,25 @@ def create_bellschedule(school_id): return BellScheduleSchema(exclude=('school_id',)).dump(new_schedule) -@blueprint.route("/school//bellschedule/", methods=['PATCH']) +@blueprint.route("/bellschedule/", methods=['PATCH']) @check_headers @requires_auth @requires_admin -def update_bellschedule(school_id, bell_schedule_id): +def update_bellschedule(bell_schedule_id): check_permissions([APIScopes.EDIT_BELL_SCHEDULE]) - school = SchoolDB.query.filter_by(id=school_id).first() - + schedule = BellScheduleDB.query.filter_by(id=bell_schedule_id).first() + school = SchoolDB.query.filter_by(id=schedule.school_id).first() check_ownership(school) - schedule = school.schedules.filter_by(id=bell_schedule_id).first() - updated_schedule = BellScheduleSchema().load( request.get_json()["data"]).data - if not updated_schedule.id or updated_schedule.id.lower() != bell_schedule_id.lower(): - raise Oops("The identifier provided in the request body must match the identifier specified in the URL", - 400, title="Identifier Mismatch") +# no need to check for this. just overwrite the id value with the url-provided one + # if not updated_schedule.id or updated_schedule.id.lower() != bell_schedule_id.lower(): + # raise Oops("The identifier provided in the request body must match the identifier specified in the URL", + # 400, title="Identifier Mismatch") schedule.name = new_patch_val(updated_schedule.name, schedule.name) schedule.display_name = new_patch_val( @@ -294,20 +293,18 @@ def update_bellschedule(school_id, bell_schedule_id): return BellScheduleSchema(exclude=('school_id',)).dump(schedule) -@blueprint.route("/school//bellschedule/", methods=['DELETE']) +@blueprint.route("/bellschedule/", methods=['DELETE']) @check_headers @requires_auth @requires_admin -def delete_bellschedule(school_id, bell_schedule_id): +def delete_bellschedule(bell_schedule_id): check_permissions([APIScopes.DELETE_BELL_SCHEDULE]) - - school = SchoolDB.query.filter_by(id=school_id).first() + schedule = BellScheduleDB.query.filter_by(id=bell_schedule_id).first() + school = SchoolDB.query.filter_by(id=schedule.school_id).first() check_ownership(school) - schedule = school.schedules.filter_by(id=bell_schedule_id).first() - db.session.delete(schedule) return None, 204 @@ -332,7 +329,7 @@ def before(): @blueprint.after_request def after_request(response): - response.headers['Content-Type'] = 'application/vnd.api+json' + response.headers['Content-Type'] = 'application/json' return response # @@ -349,14 +346,14 @@ def ratelimit_handler(e): return make_jsonapi_response( make_jsonapi_error_object(429, title="Ratelimit Exceeded", message="ratelimit of " + e.description + " exceeded"), - code=429, headers={'Content-Type': 'application/vnd.api+json'} + code=429, headers={'Content-Type': 'application/json'} ) @blueprint.errorhandler(AuthError) def handle_auth_error(e): return make_jsonapi_response( - make_jsonapi_error_object(e.status_code, message=e.error), code=e.status_code, headers={'Content-Type': 'application/vnd.api+json'} + make_jsonapi_error_object(e.status_code, message=e.error), code=e.status_code, headers={'Content-Type': 'application/json'} ) @@ -364,11 +361,11 @@ def handle_auth_error(e): def handle_error(e): if e.title is not None: return make_jsonapi_response( - make_jsonapi_error_object(e.status_code, message=e.message, title=e.title), code=e.status_code, headers={'Content-Type': 'application/vnd.api+json'} + make_jsonapi_error_object(e.status_code, message=e.message, title=e.title), code=e.status_code, headers={'Content-Type': 'application/json'} ) else: return make_jsonapi_response( - make_jsonapi_error_object(e.status_code, message=e.message), code=e.status_code, headers={'Content-Type': 'application/vnd.api+json'} + make_jsonapi_error_object(e.status_code, message=e.message), code=e.status_code, headers={'Content-Type': 'application/json'} ) @@ -377,7 +374,7 @@ def handle_HTTP_error(e): return make_jsonapi_response( make_jsonapi_error_object( e.code, title=e.name(), message=e.description), - code=e.code, headers={'Content-Type': 'application/vnd.api+json'} + code=e.code, headers={'Content-Type': 'application/json'} ) @@ -387,5 +384,5 @@ def handle_HTTP_error(e): # print("an exception occurred") # print(e) # return make_jsonapi_response( -# make_jsonapi_error_object(500), code=500, headers={'Content-Type': 'application/vnd.api+json'} +# make_jsonapi_error_object(500), code=500, headers={'Content-Type': 'application/json'} # ) From 8677d460b0f54e9ade3cbb760dd4ed767cd6d58d Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 31 May 2020 14:01:55 -0700 Subject: [PATCH 015/206] rename make_response helper to respond and set a default response type --- common/helpers.py | 6 +++--- versions/v0.py | 22 +++++++++++----------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/common/helpers.py b/common/helpers.py index 46a4767..aa55d0f 100644 --- a/common/helpers.py +++ b/common/helpers.py @@ -135,7 +135,7 @@ def make_jsonapi_error_object(code, error_id=None, title=None, message=None): return error_data -def make_jsonapi_response(response_data=None, code=None, headers={}): +def respond(response_data=None, code=None, headers={'Content-Type': 'application/json'}): """ Forms a Flask-and-JSON:API-compatible JSON response Arguments: @@ -541,7 +541,7 @@ def wrapper(*args, **kwargs): error = make_jsonapi_error_object( message='Content-Type header must be application/vnd.api+json', title='Invalid request header', code=415) - return make_jsonapi_response(response_data=error, code=415, headers={'Content-Type': 'application/vnd.api+json'}) + return respond(response_data=error, code=415) if 'Accept' in request.headers: for accept in request.headers['Accept'].split(','): @@ -549,7 +549,7 @@ def wrapper(*args, **kwargs): error = make_jsonapi_error_object( message='Accept header must be application/vnd.api+json without media type parameters', title='Invalid request header', code=406) - return make_jsonapi_response(response_data=error, code=406, headers={'Content-Type': 'application/vnd.api+json'}) + return respond(response_data=error, code=406) return func(*args, **kwargs) diff --git a/versions/v0.py b/versions/v0.py index 870ac31..67f216b 100644 --- a/versions/v0.py +++ b/versions/v0.py @@ -343,38 +343,38 @@ def after_request(response): @blueprint.errorhandler(429) def ratelimit_handler(e): print(e) - return make_jsonapi_response( + return respond( make_jsonapi_error_object(429, title="Ratelimit Exceeded", message="ratelimit of " + e.description + " exceeded"), - code=429, headers={'Content-Type': 'application/json'} + code=429 ) @blueprint.errorhandler(AuthError) def handle_auth_error(e): - return make_jsonapi_response( - make_jsonapi_error_object(e.status_code, message=e.error), code=e.status_code, headers={'Content-Type': 'application/json'} + return respond( + make_jsonapi_error_object(e.status_code, message=e.error), code=e.status_code ) @blueprint.errorhandler(Oops) def handle_error(e): if e.title is not None: - return make_jsonapi_response( - make_jsonapi_error_object(e.status_code, message=e.message, title=e.title), code=e.status_code, headers={'Content-Type': 'application/json'} + return respond( + make_jsonapi_error_object(e.status_code, message=e.message, title=e.title), code=e.status_code ) else: - return make_jsonapi_response( - make_jsonapi_error_object(e.status_code, message=e.message), code=e.status_code, headers={'Content-Type': 'application/json'} + return respond( + make_jsonapi_error_object(e.status_code, message=e.message), code=e.status_code ) @blueprint.errorhandler(HTTPException) def handle_HTTP_error(e): - return make_jsonapi_response( + return respond( make_jsonapi_error_object( e.code, title=e.name(), message=e.description), - code=e.code, headers={'Content-Type': 'application/json'} + code=e.code ) @@ -383,6 +383,6 @@ def handle_HTTP_error(e): # # "We're sorry, but the electrons that were tasked with handling your request became terribly misguided and forgot what it is that they were supposed to be doing. Our team of scientists in the Electron Amnesia Recovery Ward is currently nursing them back to health; if you have any information about what it is these electrons were supposed to be doing at the time of this incident, please contact the maintainer of this service." # print("an exception occurred") # print(e) -# return make_jsonapi_response( +# return respond( # make_jsonapi_error_object(500), code=500, headers={'Content-Type': 'application/json'} # ) From 83a990bb882b8b09ef094c4831b8dba0a71ffe92 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 31 May 2020 14:09:18 -0700 Subject: [PATCH 016/206] remove JSONAPI specific stuff --- common/helpers.py | 125 +++++++++++++++++++++++----------------------- versions/v0.py | 12 ++--- 2 files changed, 68 insertions(+), 69 deletions(-) diff --git a/common/helpers.py b/common/helpers.py index aa55d0f..503ba4f 100644 --- a/common/helpers.py +++ b/common/helpers.py @@ -107,8 +107,8 @@ def register_api(api, resource, api_version, name_of_optional_param='id', type_o ) -def make_jsonapi_error_object(code, error_id=None, title=None, message=None): - """ Generates a JSON:API error response +def make_error_object(code, error_id=None, title=None, message=None): + """ Generates an error response object Arguments: code {number} -- The HTTP status code to return for the error; both through HTTP and in the JSON response. @@ -118,7 +118,7 @@ def make_jsonapi_error_object(code, error_id=None, title=None, message=None): message {string} -- An optional message giving more details about the error (default: {None}) Returns: - A flask Response object for the web server + an error JSON object """ error_data = {'status': str(code)} @@ -136,10 +136,10 @@ def make_jsonapi_error_object(code, error_id=None, title=None, message=None): def respond(response_data=None, code=None, headers={'Content-Type': 'application/json'}): - """ Forms a Flask-and-JSON:API-compatible JSON response + """ Forms the data into a JSON response Arguments: - response_data {dict} -- The jsonapi object dict to return in the JSON response + response_data {dict} -- The object dict to return in the JSON response Keyword Arguments: code {number} -- The optional HTTP status code to return with the response (used for errors) (default: {None}) @@ -150,7 +150,6 @@ def respond(response_data=None, code=None, headers={'Content-Type': 'application """ content = {} - content["jsonapi"] = {"version": "1.0"} if code is not None and (is_client_error(code) or is_server_error(code)): # error @@ -174,64 +173,64 @@ def J(*args, **kwargs): def filter_dict(dict, filter, is_whitelist=True): return {key: val for key, val in dict.items() if ((key in filter) if is_whitelist else (key not in filter))} -def make_jsonapi_links_object(**kwargs): - """Creates a JSON:API "links object" from a dict of data - Returns: - dict -- A links object dict with contents formatted per the JSON:API spec - """ - links_object = {} - for link_name in kwargs: - links_object[link_name] = kwargs[link_name] +# def make_jsonapi_links_object(**kwargs): +# """Creates a JSON:API "links object" from a dict of data +# Returns: +# dict -- A links object dict with contents formatted per the JSON:API spec +# """ +# links_object = {} +# for link_name in kwargs: +# links_object[link_name] = kwargs[link_name] - return links_object +# return links_object -def make_jsonapi_resource_object(resource, attributes_schema, blueprint_name): - """Creates a JSON:API "resource object" from a dict of data +# def make_jsonapi_resource_object(resource, attributes_schema, blueprint_name): +# """Creates a JSON:API "resource object" from a dict of data - Arguments: - data_dict {dict} -- The data to create the resource object from - data_domain {string} -- A string describing what the data in data_dict represents (i.e. "school", "schedule", etc.) - uri_function_name_mappings {dict} -- A mapping of the keys of identifiers in data_dict to the name of the function whose route should be used to generate URI's for responses - TODO: maybe make uri_function_name_mappings an enum or something - Raises: - e: A Key Error if the data_dict somehow does not contain an "id" field. should never happen +# Arguments: +# data_dict {dict} -- The data to create the resource object from +# data_domain {string} -- A string describing what the data in data_dict represents (i.e. "school", "schedule", etc.) +# uri_function_name_mappings {dict} -- A mapping of the keys of identifiers in data_dict to the name of the function whose route should be used to generate URI's for responses +# TODO: maybe make uri_function_name_mappings an enum or something +# Raises: +# e: A Key Error if the data_dict somehow does not contain an "id" field. should never happen - Returns: - dict -- A resource object dict with contents formatted per the JSON:API spec - """ - resource_object = {} - resource_object["type"] = resource.type - resource_object["id"] = resource.id +# Returns: +# dict -- A resource object dict with contents formatted per the JSON:API spec +# """ +# resource_object = {} +# resource_object["type"] = resource.type +# resource_object["id"] = resource.id - resource_object["links"] = make_jsonapi_links_object( - self=resource.get_uri(blueprint_name)) +# resource_object["links"] = make_jsonapi_links_object( +# self=resource.get_uri(blueprint_name)) - resource_object["attributes"] = attributes_schema.dump(resource) +# resource_object["attributes"] = attributes_schema.dump(resource) - if resource.type == "bellschedule": - resource_object["relationships"] = {} - resource_object["relationships"]["schools"] = {} - resource_object["relationships"]["schools"]["links"] = make_jsonapi_links_object(self=url_for( - blueprint_name + "." + blueprint_name + "_single_school", school_id=resource.school_id.hex, _external=True)) +# if resource.type == "bellschedule": +# resource_object["relationships"] = {} +# resource_object["relationships"]["schools"] = {} +# resource_object["relationships"]["schools"]["links"] = make_jsonapi_links_object(self=url_for( +# blueprint_name + "." + blueprint_name + "_single_school", school_id=resource.school_id.hex, _external=True)) - return resource_object +# return resource_object -def deconstruct_resource_object(resource_object): - """extracts a more processable dict from a JSON:API "resource object" +# def deconstruct_resource_object(resource_object): +# """extracts a more processable dict from a JSON:API "resource object" - Arguments: - resource_object {dict} -- a dict in JSON:API format +# Arguments: +# resource_object {dict} -- a dict in JSON:API format - Returns: - dict -- a flatter dict for easier processing - """ - resource = {} - resource["type"] = resource_object.get("type", None) - resource["id"] = UUID(resource_object.get("id", uuid4().hex)) +# Returns: +# dict -- a flatter dict for easier processing +# """ +# resource = {} +# resource["type"] = resource_object.get("type", None) +# resource["id"] = UUID(resource_object.get("id", uuid4().hex)) - return {**resource, **resource_object["attributes"]} +# return {**resource, **resource_object["attributes"]} def handle_marshmallow_errors(errors): @@ -245,7 +244,7 @@ def handle_marshmallow_errors(errors): message = input_error[:-1] + " provided to " + \ property_name + " of type " + value_type - error = make_jsonapi_error_object( + error = make_error_object( 400, title="Validation failure", message=message) error_list.append(error) @@ -530,26 +529,26 @@ def decorated(*args, **kwargs): # decorator modified from https://github.com/miLibris/flask-rest-jsonapi/blob/ad3f90f81955fa41aaf0fb8c49a75a5fbe334f5f/flask_rest_jsonapi/decorators.py def check_headers(func): - """Check headers according to jsonapi reference + """decorator that provides a place to check headers :param callable func: the function to decorate :return callable: the wrapped function """ @wraps(func) def wrapper(*args, **kwargs): - if request.method in ('POST', 'PATCH', 'PUT'): - if 'Content-Type' in request.headers and request.headers['Content-Type'] != 'application/vnd.api+json': + # if request.method in ('POST', 'PATCH', 'PUT'): + # if 'Content-Type' in request.headers and request.headers['Content-Type'] != 'application/vnd.api+json': - error = make_jsonapi_error_object( - message='Content-Type header must be application/vnd.api+json', title='Invalid request header', code=415) - return respond(response_data=error, code=415) + # error = make_error_object( + # message='Content-Type header must be application/vnd.api+json', title='Invalid request header', code=415) + # return respond(response_data=error, code=415) - if 'Accept' in request.headers: - for accept in request.headers['Accept'].split(','): - if accept.strip() != 'application/vnd.api+json': + # if 'Accept' in request.headers: + # for accept in request.headers['Accept'].split(','): + # if accept.strip() != 'application/vnd.api+json': - error = make_jsonapi_error_object( - message='Accept header must be application/vnd.api+json without media type parameters', title='Invalid request header', code=406) - return respond(response_data=error, code=406) + # error = make_error_object( + # message='Accept header must be application/vnd.api+json without media type parameters', title='Invalid request header', code=406) + # return respond(response_data=error, code=406) return func(*args, **kwargs) diff --git a/versions/v0.py b/versions/v0.py index 67f216b..63119a3 100644 --- a/versions/v0.py +++ b/versions/v0.py @@ -344,7 +344,7 @@ def after_request(response): def ratelimit_handler(e): print(e) return respond( - make_jsonapi_error_object(429, title="Ratelimit Exceeded", + make_error_object(429, title="Ratelimit Exceeded", message="ratelimit of " + e.description + " exceeded"), code=429 ) @@ -353,7 +353,7 @@ def ratelimit_handler(e): @blueprint.errorhandler(AuthError) def handle_auth_error(e): return respond( - make_jsonapi_error_object(e.status_code, message=e.error), code=e.status_code + make_error_object(e.status_code, message=e.error), code=e.status_code ) @@ -361,18 +361,18 @@ def handle_auth_error(e): def handle_error(e): if e.title is not None: return respond( - make_jsonapi_error_object(e.status_code, message=e.message, title=e.title), code=e.status_code + make_error_object(e.status_code, message=e.message, title=e.title), code=e.status_code ) else: return respond( - make_jsonapi_error_object(e.status_code, message=e.message), code=e.status_code + make_error_object(e.status_code, message=e.message), code=e.status_code ) @blueprint.errorhandler(HTTPException) def handle_HTTP_error(e): return respond( - make_jsonapi_error_object( + make_error_object( e.code, title=e.name(), message=e.description), code=e.code ) @@ -384,5 +384,5 @@ def handle_HTTP_error(e): # print("an exception occurred") # print(e) # return respond( -# make_jsonapi_error_object(500), code=500, headers={'Content-Type': 'application/json'} +# make_error_object(500), code=500, headers={'Content-Type': 'application/json'} # ) From 7dc9b5a72d5d1de4bfb71d7fc599e0b559db5661 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 31 May 2020 14:17:15 -0700 Subject: [PATCH 017/206] remove json-api-doc. (could have been useful) --- Pipfile | 1 - Pipfile.lock | 16 ++++------------ 2 files changed, 4 insertions(+), 13 deletions(-) diff --git a/Pipfile b/Pipfile index 62495f5..825bfce 100644 --- a/Pipfile +++ b/Pipfile @@ -18,7 +18,6 @@ Flask-Cors = "*" Flask-Limiter = "*" gunicorn = "*" sqlalchemy = "*" -json-api-doc = "*" flask-sqlalchemy = "*" marshmallow-sqlalchemy = "*" diff --git a/Pipfile.lock b/Pipfile.lock index 3188800..4b38a21 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "db83acf67cdf36f0d6afde39fe2aad3c4fad55e5b53149534e455fd45652f739" + "sha256": "18c999ee9f6994ca91ebf0f2a9d6cf9b1c9edc3b8fe8eaf6afd5275f4d343207" }, "pipfile-spec": 6, "requires": { @@ -115,14 +115,6 @@ ], "version": "==2.11.2" }, - "json-api-doc": { - "hashes": [ - "sha256:58eb2363ef1b05e0ff91c4977bf891d0f80f7253f2029b4b94e4ac442be87e61", - "sha256:79126b05bff342ba293eba782d199e69599ebe30f1b53713bf7760823c054cd7" - ], - "index": "pypi", - "version": "==0.14.0" - }, "jsonschema": { "hashes": [ "sha256:4e5b3cf8216f577bee9ce139cbe72eca3ea4f292ec60928ff24758ce626cd163", @@ -184,11 +176,11 @@ }, "marshmallow-sqlalchemy": { "hashes": [ - "sha256:3247e41e424146340b03a369f2b7c6f0364477ccedc4e2481e84d5f3a8d3c67f", - "sha256:dbbe51d28bb28e7ee2782e51310477f7a2c5a111a301f6dd8e264e11ab820427" + "sha256:03a555b610bb307689b821b64e2416593ec21a85925c8c436c2cd08ebc6bb85e", + "sha256:0ef59c8da8da2e18e808e3880158049e9d72f3031c84cc804b6c533a0eb668a9" ], "index": "pypi", - "version": "==0.23.0" + "version": "==0.23.1" }, "mistune": { "hashes": [ From 45f7fa952902256c70cf99134db24008d178fcb5 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Tue, 2 Jun 2020 16:08:17 -0700 Subject: [PATCH 018/206] add apispec dependency --- Pipfile | 2 ++ Pipfile.lock | 21 ++++++++++++++++++++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/Pipfile b/Pipfile index 825bfce..e5902c9 100644 --- a/Pipfile +++ b/Pipfile @@ -20,6 +20,8 @@ gunicorn = "*" sqlalchemy = "*" flask-sqlalchemy = "*" marshmallow-sqlalchemy = "*" +apispec = "*" +apispec-webframeworks = "*" [requires] python_version = "3.6" diff --git a/Pipfile.lock b/Pipfile.lock index 4b38a21..8240ed5 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "18c999ee9f6994ca91ebf0f2a9d6cf9b1c9edc3b8fe8eaf6afd5275f4d343207" + "sha256": "77cdedfc00958754792a068c23e7878dadd881fe9f8f93d48692cb4ddeb71562" }, "pipfile-spec": 6, "requires": { @@ -16,6 +16,25 @@ ] }, "default": { + "apispec": { + "extras": [ + "yaml" + ], + "hashes": [ + "sha256:419d0564b899e182c2af50483ea074db8cb05fee60838be58bb4542095d5c08d", + "sha256:9bf4e51d56c9067c60668b78210ae213894f060f85593dc2ad8805eb7d875a2a" + ], + "index": "pypi", + "version": "==3.3.0" + }, + "apispec-webframeworks": { + "hashes": [ + "sha256:0db35b267914b3f8c562aca0261957dbcb4176f255eacc22520277010818dcf3", + "sha256:482c563abbcc2a261439476cb3f1a7c7284cc997c322c574d48c111643e9c04e" + ], + "index": "pypi", + "version": "==0.5.2" + }, "attrs": { "hashes": [ "sha256:08a96c641c3a74e44eb59afb61a24f2cb9f4d7188748e76ba4bb5edfa3cb7d1c", From bcee58b11529bf0040cc625ae5365b7b881d48c5 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Tue, 2 Jun 2020 16:16:37 -0700 Subject: [PATCH 019/206] utilize respond function --- versions/v0.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/versions/v0.py b/versions/v0.py index 63119a3..12fb9c2 100644 --- a/versions/v0.py +++ b/versions/v0.py @@ -88,7 +88,7 @@ def list_schools(): for school in schools: school_list.append(school) - return SchoolSchema().dump(school_list, many=True) + return respond(response_data=SchoolSchema().dump(school_list, many=True), code=200) @blueprint.route("/school//", methods=['GET']) From bc60289e6c7a4a3fe60770ef549765b8dec94d37 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Tue, 2 Jun 2020 16:28:41 -0700 Subject: [PATCH 020/206] make 200 OK the default response code --- common/helpers.py | 2 +- versions/v0.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/common/helpers.py b/common/helpers.py index 503ba4f..43f99b5 100644 --- a/common/helpers.py +++ b/common/helpers.py @@ -135,7 +135,7 @@ def make_error_object(code, error_id=None, title=None, message=None): return error_data -def respond(response_data=None, code=None, headers={'Content-Type': 'application/json'}): +def respond(response_data=None, code=200, headers={'Content-Type': 'application/json'}): """ Forms the data into a JSON response Arguments: diff --git a/versions/v0.py b/versions/v0.py index 12fb9c2..8472ee2 100644 --- a/versions/v0.py +++ b/versions/v0.py @@ -88,7 +88,7 @@ def list_schools(): for school in schools: school_list.append(school) - return respond(response_data=SchoolSchema().dump(school_list, many=True), code=200) + return respond(response_data=SchoolSchema().dump(school_list, many=True)) @blueprint.route("/school//", methods=['GET']) From 8512000057dc08b129fd40363d3cf7ea02b2dac3 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Tue, 2 Jun 2020 16:29:13 -0700 Subject: [PATCH 021/206] add respond function to all relevent endpoints --- versions/v0.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/versions/v0.py b/versions/v0.py index 8472ee2..6394726 100644 --- a/versions/v0.py +++ b/versions/v0.py @@ -102,7 +102,7 @@ def get_school(school_id): raise Oops("No school was found with the specified id.", 404, title="Resource Not Found") - return SchoolSchema().dump(school) + return respond(response_data=SchoolSchema().dump(school)) @blueprint.route("/school/", methods=['POST']) @@ -133,7 +133,7 @@ def create_school(self): #TODO: need to verify that the insert worked? - return SchoolSchema().dump(new_object) + return respond(response_data=respond(response_data=SchoolSchema().dump(new_object)) #error checking @blueprint.route("/school//", methods=['PATCH']) @@ -187,7 +187,7 @@ def update_school(school_id): db.session.commit() #TODO: need to verify that the update worked? - return SchoolSchema().dump(school) + return respond(response_data=SchoolSchema().dump(school)) @blueprint.route("/school//", methods=['DELETE']) @@ -240,7 +240,7 @@ def get_bellschedule(bell_schedule_id): raise Oops("No bell schedule was found with the specified id.", 404, title="Resource Not Found") - return BellScheduleSchema(exclude=('school_id',)).dump(schedule) + return respond(response_data=BellScheduleSchema(exclude=('school_id',)).dump(schedule)) @blueprint.route("/bellschedule/", methods=['POST']) @@ -261,7 +261,7 @@ def create_bellschedule(): db.session.commit() - return BellScheduleSchema(exclude=('school_id',)).dump(new_schedule) + return respond(response_data=BellScheduleSchema(exclude=('school_id',)).dump(new_schedule)) @blueprint.route("/bellschedule/", methods=['PATCH']) @@ -290,7 +290,7 @@ def update_bellschedule(bell_schedule_id): db.session.commit() - return BellScheduleSchema(exclude=('school_id',)).dump(schedule) + return respond(response_data=BellScheduleSchema(exclude=('school_id',)).dump(schedule)) @blueprint.route("/bellschedule/", methods=['DELETE']) From db605f8aed5b1c1ba46e1ee81250eddcc9b4008c Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Tue, 2 Jun 2020 16:32:57 -0700 Subject: [PATCH 022/206] set up documentation with flasgger and Apispec --- api.py | 89 ++++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 59 insertions(+), 30 deletions(-) diff --git a/api.py b/api.py index ba94d63..bcc27d2 100644 --- a/api.py +++ b/api.py @@ -5,6 +5,10 @@ from flasgger import Swagger from common.helpers import get_request_origin_identifier from common.db_schema import db +from common.schemas import * +from flasgger import APISpec, Schema, Swagger, fields +from apispec.ext.marshmallow import MarshmallowPlugin +from apispec_webframeworks.flask import FlaskPlugin import os, sys, getpass from os import environ as env @@ -38,6 +42,59 @@ app.register_blueprint(v0.blueprint, url_prefix='/v0') +# "info": { +# "title": "ClassClock API", +# "version": "0.1", +# "description": "The first beta development version of the ClassClock API", +# "contact": { +# # "responsibleOrganization": "ME", +# # "responsibleDeveloper": "Me", +# # "email": "me@me.com", +# # "url": "www.me.com", +# }, +# "termsOfService": "http://me.com/terms", +# }, + +# # "host": "api.classclock.app", # overrides localhost:500 +# # "basePath": "/v0", # base bash for blueprint registration +# "schemes": [ +# "https" +# ] +# } +# Create an APISpec +spec = APISpec( + title="ClassClock API", + version="0.1", + openapi_version='2.0', + plugins=[ + FlaskPlugin(), + MarshmallowPlugin(), + ], + options= { + "description": "The development version of the ClassClock API", + "servers": [ + { + "url": "https://api.classclock.app/v0", + "description": "ClassClock API Server" + }, + { + "url": "https://localhost:8000/v0", + "description": "Dev server" + } + ], + "externalDocs": { + "description": "This API might loosely follow the JSON:API specofocation", + "url": "https://jsonapi.org" + } + } +) + +template = spec.to_flasgger( + app, + definitions=[SchoolSchema, BellScheduleDateSchema, BellScheduleMeetingTimeSchema, BellScheduleSchema], + paths=[] +) + swagger = Swagger(app, config={ "headers": [ ], @@ -54,36 +111,8 @@ "swagger_ui": True, "specs_route": "/docs/" }, - template={ - - "info": { - "title": "ClassClock API", - "version": "0.1", - "description": "The first beta development version of the ClassClock API", - "contact": { - # "responsibleOrganization": "ME", - # "responsibleDeveloper": "Me", - # "email": "me@me.com", - # "url": "www.me.com", - }, - "termsOfService": "http://me.com/terms", - }, - "servers": [ - { - "url": "https://api.classclock.app/", - "description": "ClassClock API Server" - }, - { - "url": "https://localhost:5000/", - "description": "Dev server" - } - ], - # "host": "api.classclock.app", # overrides localhost:500 - # "basePath": "/v0", # base bash for blueprint registration - "schemes": [ - "https" - ] -}) + template=template) + app.config.update(SQLALCHEMY_DATABASE_URI=db_connection_string,DEBUG=True, SQLALCHEMY_TRACK_MODIFICATIONS=False) db.init_app(app) From 5d6ffd303e59203d25fb7eddbe445bdd1a39a93d Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Tue, 2 Jun 2020 16:36:55 -0700 Subject: [PATCH 023/206] remove extra response wrap --- versions/v0.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/versions/v0.py b/versions/v0.py index 6394726..56330e9 100644 --- a/versions/v0.py +++ b/versions/v0.py @@ -133,7 +133,7 @@ def create_school(self): #TODO: need to verify that the insert worked? - return respond(response_data=respond(response_data=SchoolSchema().dump(new_object)) #error checking + return respond(response_data=SchoolSchema().dump(new_object)) #error checking @blueprint.route("/school//", methods=['PATCH']) From 24389d58170f4e234a043766967cba2fe7bb990b Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Wed, 3 Jun 2020 17:25:55 -0700 Subject: [PATCH 024/206] add homepage for api that directs to the docs --- api.py | 10 +++++++++- templates/home.html | 24 ++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 templates/home.html diff --git a/api.py b/api.py index bcc27d2..c829776 100644 --- a/api.py +++ b/api.py @@ -1,4 +1,4 @@ -from flask import Flask +from flask import Flask, render_template import logging from versions import v0 from flask_limiter import Limiter @@ -188,6 +188,14 @@ def today_plus(sch, num_days): exit(0) + + +@app.route("/", methods=['GET']) +def home(): + return render_template('home.html') + + + if __name__ == "__main__": app.run() else: diff --git a/templates/home.html b/templates/home.html new file mode 100644 index 0000000..2b7d844 --- /dev/null +++ b/templates/home.html @@ -0,0 +1,24 @@ + + + + ClassClock API + + +

ClassClock API

+

This is the API for ClassClock.

+

If you came here looking for API docs, you can find them at the links below:

+ + +

Source Code

+

+ The ClassClock API is licensed under the terms of the GNU AGPL and welcomes contributions. The source code is available at + https://github.com/MoralCode/ClassClockAPI + + +

+ + + \ No newline at end of file From 7c26f703b3774de345e78d41f6029a4c14d54483 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Wed, 3 Jun 2020 17:26:48 -0700 Subject: [PATCH 025/206] start documenting endpoints --- versions/v0.py | 61 +++++++++++++++++++++++++++++++++++++------------- 1 file changed, 45 insertions(+), 16 deletions(-) diff --git a/versions/v0.py b/versions/v0.py index 56330e9..e88f66c 100644 --- a/versions/v0.py +++ b/versions/v0.py @@ -81,6 +81,14 @@ @blueprint.route("/schools/", methods=['GET']) @check_headers def list_schools(): + """ Returns a list of schools + --- + responses: + 200: + description: A list of schools + schema: + $ref: '#/definitions/School' + """ check_permissions([APIScopes.LIST_SCHOOLS]) school_list = [] @@ -94,6 +102,14 @@ def list_schools(): @blueprint.route("/school//", methods=['GET']) @check_headers def get_school(school_id): + """ Returns a single school + --- + responses: + 200: + description: A single school object + schema: + $ref: '#/definitions/School' + """ check_permissions([APIScopes.LIST_SCHOOLS]) school = SchoolDB.query.filter_by(id=school_id).first() @@ -110,6 +126,22 @@ def get_school(school_id): @requires_auth @requires_admin def create_school(self): + """ Creates a new school + --- + parameters: + - name: school + in: body + type: object + schema: + $ref: '#/definitions/School' + security: + - ApiKeyAuth: [] + responses: + 200: + description: A list of schools + schema: + $ref: '#/definitions/School' + """ check_permissions([APIScopes.CREATE_SCHOOL]) # if len(list_owned_school_ids()) > 0: @@ -141,22 +173,12 @@ def create_school(self): @requires_auth @requires_admin def update_school(school_id): - """ input: - { - "data": { - "type": "school", - "id": "2C49E3159EE011E986F2181DEA92AD79", - "links": { - "self": "http://localhost:5000/v0/school/2C49E3159EE011E986F2181DEA92AD79" - }, - "attributes": { - "acronym": "LMHS", - "creation_date": "2019-07-04T21:48:46+00:00", - "alternate_freeperiod_name": null, - "full_name": "Lake Mosswego High School" - } - } - } + """ + updates a school + --- + security: + - ApiKeyAuth: [] + """ check_permissions([APIScopes.EDIT_SCHOOL]) @@ -195,6 +217,13 @@ def update_school(school_id): @requires_auth @requires_admin def delete_school(school_id): + """ + deletes a school + --- + security: + - ApiKeyAuth: [] + + """ check_permissions( [APIScopes.DELETE_SCHOOL, APIScopes.DELETE_BELL_SCHEDULE]) From c6a6941edc25e1f50a4b3c98cd875d8927b93069 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Wed, 3 Jun 2020 17:27:58 -0700 Subject: [PATCH 026/206] update swagger settings --- api.py | 47 +++++++++++++++++++++++++---------------------- 1 file changed, 25 insertions(+), 22 deletions(-) diff --git a/api.py b/api.py index c829776..fcb7dfe 100644 --- a/api.py +++ b/api.py @@ -42,26 +42,8 @@ app.register_blueprint(v0.blueprint, url_prefix='/v0') -# "info": { -# "title": "ClassClock API", -# "version": "0.1", -# "description": "The first beta development version of the ClassClock API", -# "contact": { -# # "responsibleOrganization": "ME", -# # "responsibleDeveloper": "Me", -# # "email": "me@me.com", -# # "url": "www.me.com", -# }, -# "termsOfService": "http://me.com/terms", -# }, - -# # "host": "api.classclock.app", # overrides localhost:500 -# # "basePath": "/v0", # base bash for blueprint registration -# "schemes": [ -# "https" -# ] -# } # Create an APISpec +#info: { spec = APISpec( title="ClassClock API", version="0.1", @@ -85,10 +67,18 @@ "externalDocs": { "description": "This API might loosely follow the JSON:API specofocation", "url": "https://jsonapi.org" - } + }#, +# "contact": { +# # "responsibleOrganization": "ME", +# # "responsibleDeveloper": "Me", +# # "email": "me@me.com", +# # "url": "www.me.com", +# }, +# "termsOfService": "http://me.com/terms", } ) + template = spec.to_flasgger( app, definitions=[SchoolSchema, BellScheduleDateSchema, BellScheduleMeetingTimeSchema, BellScheduleSchema], @@ -109,9 +99,22 @@ "static_url_path": "/flasgger_static", # "static_folder": "static", # must be set by user "swagger_ui": True, - "specs_route": "/docs/" + "specs_route": "/v0/docs/", + "basePath": "/v0", + "host": "api.classclock.app", # overrides localhost:500 + "schemes": [ + "https" + ], + "securityDefinitions": { + "ApiKeyAuth": { + "type": "apiKey", + "in": "header", + "name": "Authentication" + } + } }, - template=template) +template=template) + app.config.update(SQLALCHEMY_DATABASE_URI=db_connection_string,DEBUG=True, SQLALCHEMY_TRACK_MODIFICATIONS=False) From cb04de3a785127abc761dfd4bfff2fe4f94af887 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Wed, 3 Jun 2020 17:43:58 -0700 Subject: [PATCH 027/206] move parsing request body to a helper --- common/helpers.py | 6 ++++++ versions/v0.py | 8 ++++---- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/common/helpers.py b/common/helpers.py index 43f99b5..b694abe 100644 --- a/common/helpers.py +++ b/common/helpers.py @@ -251,6 +251,12 @@ def handle_marshmallow_errors(errors): return error_list, 400 +def get_request_body(request): + """ + provides a central place to modify the data in the request body + """ + return request.get_json() + def get_request_origin_identifier(): user_id_parts = get_api_user_id().split("|") return flask_limiter.util.get_remote_address() + get_api_client_id() + user_id_parts[1] if len(user_id_parts) > 2 else "" diff --git a/versions/v0.py b/versions/v0.py index e88f66c..88b26d5 100644 --- a/versions/v0.py +++ b/versions/v0.py @@ -148,7 +148,7 @@ def create_school(self): # raise Oops( # "Authorizing user is already the owner of another school", 401) - data = deconstruct_resource_object(request.get_json()["data"]) + data = deconstruct_resource_object(get_request_body(request)) new_object = SchoolDB( full_name=data['full_name'], @@ -183,7 +183,7 @@ def update_school(school_id): check_permissions([APIScopes.EDIT_SCHOOL]) - data = deconstruct_resource_object(request.get_json()["data"]) + data = deconstruct_resource_object(get_request_body(request)) # if new_object.errors != {}: # return handle_marshmallow_errors(new_object.errors) @@ -284,7 +284,7 @@ def create_bellschedule(): school = SchoolDB.query.filter_by(id=school_id).first() check_ownership(school) - new_schedule = BellScheduleSchema().load(request.get_json()["data"]).data + new_schedule = BellScheduleSchema().load(get_request_body(request)).data school.schedules.append(new_schedule) @@ -306,7 +306,7 @@ def update_bellschedule(bell_schedule_id): check_ownership(school) updated_schedule = BellScheduleSchema().load( - request.get_json()["data"]).data + get_request_body(request)).data # no need to check for this. just overwrite the id value with the url-provided one # if not updated_schedule.id or updated_schedule.id.lower() != bell_schedule_id.lower(): From 0c3614a10e83a17cc3d097d9c3818f0ab0b3c2a0 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Wed, 3 Jun 2020 21:18:53 -0700 Subject: [PATCH 028/206] remove deconstrust_resource_body function --- versions/v0.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/versions/v0.py b/versions/v0.py index 88b26d5..4ff893a 100644 --- a/versions/v0.py +++ b/versions/v0.py @@ -148,7 +148,7 @@ def create_school(self): # raise Oops( # "Authorizing user is already the owner of another school", 401) - data = deconstruct_resource_object(get_request_body(request)) + data = get_request_body(request) new_object = SchoolDB( full_name=data['full_name'], @@ -183,7 +183,7 @@ def update_school(school_id): check_permissions([APIScopes.EDIT_SCHOOL]) - data = deconstruct_resource_object(get_request_body(request)) + data = get_request_body(request) # if new_object.errors != {}: # return handle_marshmallow_errors(new_object.errors) From bfb8faab67be496b158f98ec8f5e8ca350bb1c4b Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Wed, 3 Jun 2020 21:57:00 -0700 Subject: [PATCH 029/206] remove unneeded named parameter when calling respond() --- versions/v0.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/versions/v0.py b/versions/v0.py index 4ff893a..5b3fa9c 100644 --- a/versions/v0.py +++ b/versions/v0.py @@ -96,7 +96,7 @@ def list_schools(): for school in schools: school_list.append(school) - return respond(response_data=SchoolSchema().dump(school_list, many=True)) + return respond(SchoolSchema().dump(school_list, many=True)) @blueprint.route("/school//", methods=['GET']) @@ -118,7 +118,7 @@ def get_school(school_id): raise Oops("No school was found with the specified id.", 404, title="Resource Not Found") - return respond(response_data=SchoolSchema().dump(school)) + return respond(SchoolSchema().dump(school)) @blueprint.route("/school/", methods=['POST']) @@ -165,7 +165,7 @@ def create_school(self): #TODO: need to verify that the insert worked? - return respond(response_data=SchoolSchema().dump(new_object)) #error checking + return respond(SchoolSchema().dump(new_object)) @blueprint.route("/school//", methods=['PATCH']) @@ -209,7 +209,7 @@ def update_school(school_id): db.session.commit() #TODO: need to verify that the update worked? - return respond(response_data=SchoolSchema().dump(school)) + return respond(SchoolSchema().dump(school)) @blueprint.route("/school//", methods=['DELETE']) @@ -269,7 +269,7 @@ def get_bellschedule(bell_schedule_id): raise Oops("No bell schedule was found with the specified id.", 404, title="Resource Not Found") - return respond(response_data=BellScheduleSchema(exclude=('school_id',)).dump(schedule)) + return respond(BellScheduleSchema(exclude=('school_id',)).dump(schedule)) @blueprint.route("/bellschedule/", methods=['POST']) @@ -290,7 +290,7 @@ def create_bellschedule(): db.session.commit() - return respond(response_data=BellScheduleSchema(exclude=('school_id',)).dump(new_schedule)) + return respond(BellScheduleSchema(exclude=('school_id',)).dump(new_schedule)) @blueprint.route("/bellschedule/", methods=['PATCH']) @@ -319,7 +319,7 @@ def update_bellschedule(bell_schedule_id): db.session.commit() - return respond(response_data=BellScheduleSchema(exclude=('school_id',)).dump(schedule)) + return respond(BellScheduleSchema(exclude=('school_id',)).dump(schedule)) @blueprint.route("/bellschedule/", methods=['DELETE']) From 5f7bf09fe50bfe0c356afb68ca4075340834ad31 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Wed, 3 Jun 2020 21:57:51 -0700 Subject: [PATCH 030/206] remove leftover self in create_school() call --- versions/v0.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/versions/v0.py b/versions/v0.py index 5b3fa9c..6506c19 100644 --- a/versions/v0.py +++ b/versions/v0.py @@ -125,7 +125,7 @@ def get_school(school_id): @check_headers @requires_auth @requires_admin -def create_school(self): +def create_school(): """ Creates a new school --- parameters: From 6eb52e073f25877437e52f2b020bdbbf21fce858 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Wed, 3 Jun 2020 21:59:20 -0700 Subject: [PATCH 031/206] add request body validation to create and update endpoints --- versions/v0.py | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/versions/v0.py b/versions/v0.py index 6506c19..56e7913 100644 --- a/versions/v0.py +++ b/versions/v0.py @@ -8,6 +8,7 @@ from flask import Blueprint, abort, jsonify, request from werkzeug.exceptions import HTTPException from flask_cors import CORS +from marshmallow.exceptions import ValidationError # from bson import json_util # from bson.objectid import ObjectId @@ -150,12 +151,17 @@ def create_school(): data = get_request_body(request) - new_object = SchoolDB( - full_name=data['full_name'], - alternate_freeperiod_name=data['alternate_freeperiod_name'], - acronym=data['acronym'], - owner_id=data['owner_id'] - ) + if data is None: + raise Oops("Invalid or non-JSON request body provided.", 400) + + new_object = None + try: + #Numbers, booleans, strings, and ``None`` are considered invalid input to `Schema.load + new_object = SchoolSchema().load(data, session=db.session)#, session=session + except ValidationError as err: + # print(err.messages) # => {"email": ['"foo" is not a valid email address.']} + # print(err.valid_data) + return respond(err.messages, code=400) # if new_object.errors != {}: # return handle_marshmallow_errors(new_object.errors) @@ -198,6 +204,11 @@ def update_school(school_id): if data.id.hex.lower() != school.id.lower(): raise Oops("The id provided in the request body must match the id specified in the URL", 400, title="Identifier Mismatch") + try: + new_object = SchoolSchema().load(data, session=session) + except ValidationError as err: + print(err.messages) # => {"email": ['"foo" is not a valid email address.']} + # print(err.valid_data) school.full_name = new_patch_val(data.full_name, school.full_name) school.acronym = new_patch_val(data.acronym, school.acronym) From 2a06f910fb5dfbc06c95f3ebc98bd668f6123101 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Wed, 3 Jun 2020 22:00:10 -0700 Subject: [PATCH 032/206] remove identifier mismatch error --- versions/v0.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/versions/v0.py b/versions/v0.py index 56e7913..95d41ba 100644 --- a/versions/v0.py +++ b/versions/v0.py @@ -181,6 +181,7 @@ def create_school(): def update_school(school_id): """ updates a school + the id field in the request body will be overwritten with the id value from the header upon receiving the request --- security: - ApiKeyAuth: [] @@ -201,9 +202,9 @@ def update_school(school_id): raise Oops("No records were found. Please make sure you are the owner for the school you are trying to modify", 404, title="No Records Updated") - if data.id.hex.lower() != school.id.lower(): - raise Oops("The id provided in the request body must match the id specified in the URL", - 400, title="Identifier Mismatch") + #only for updating + data['id'] = school_id + try: new_object = SchoolSchema().load(data, session=session) except ValidationError as err: From 57cdfbcd596f477de4b88c63750295be400f2485 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Thu, 4 Jun 2020 10:52:31 -0700 Subject: [PATCH 033/206] install python-dateutil --- Pipfile | 1 + Pipfile.lock | 16 ++++++++++++---- versions/v0.py | 1 + 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/Pipfile b/Pipfile index e5902c9..2bb4ee7 100644 --- a/Pipfile +++ b/Pipfile @@ -22,6 +22,7 @@ flask-sqlalchemy = "*" marshmallow-sqlalchemy = "*" apispec = "*" apispec-webframeworks = "*" +python-dateutil = "*" [requires] python_version = "3.6" diff --git a/Pipfile.lock b/Pipfile.lock index 8240ed5..2d4ffbe 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "77cdedfc00958754792a068c23e7878dadd881fe9f8f93d48692cb4ddeb71562" + "sha256": "d5afada0d044282d2c1615829ed9f74e77c3be618b3ab344a44614d74a4d10c1" }, "pipfile-spec": 6, "requires": { @@ -188,10 +188,10 @@ }, "marshmallow": { "hashes": [ - "sha256:c2673233aa21dde264b84349dc2fd1dce5f30ed724a0a00e75426734de5b84ab", - "sha256:f88fe96434b1f0f476d54224d59333eba8ca1a203a2695683c1855675c4049a7" + "sha256:35ee2fb188f0bd9fc1cf9ac35e45fd394bd1c153cee430745a465ea435514bd5", + "sha256:9aa20f9b71c992b4782dad07c51d92884fd0f7c5cb9d3c737bea17ec1bad765f" ], - "version": "==3.6.0" + "version": "==3.6.1" }, "marshmallow-sqlalchemy": { "hashes": [ @@ -228,6 +228,14 @@ ], "version": "==0.16.0" }, + "python-dateutil": { + "hashes": [ + "sha256:73ebfe9dbf22e832286dafa60473e4cd239f8592f699aa5adaf10050e6e1823c", + "sha256:75bb3f31ea686f1197762692a9ee6a7550b59fc6ca3a1f4b5d7e32fb98e2da2a" + ], + "index": "pypi", + "version": "==2.8.1" + }, "python-dotenv": { "hashes": [ "sha256:25c0ff1a3e12f4bde8d592cc254ab075cfe734fc5dd989036716fd17ee7e5ec7", diff --git a/versions/v0.py b/versions/v0.py index 95d41ba..2c78dfa 100644 --- a/versions/v0.py +++ b/versions/v0.py @@ -12,6 +12,7 @@ # from bson import json_util # from bson.objectid import ObjectId +from dateutil.parser import isoparse import http.client from common.db_schema import School as SchoolDB, db, BellSchedule as BellScheduleDB from sqlalchemy import create_engine From 2ec5f104f948fd63b421905e766f3d43c8bf8fe7 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Mon, 8 Jun 2020 17:04:48 -0700 Subject: [PATCH 034/206] add checks for If-Modified-Since Header --- common/helpers.py | 7 +++++++ versions/v0.py | 19 +++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/common/helpers.py b/common/helpers.py index b694abe..8a41b31 100644 --- a/common/helpers.py +++ b/common/helpers.py @@ -232,6 +232,13 @@ def filter_dict(dict, filter, is_whitelist=True): # return {**resource, **resource_object["attributes"]} +def trap_object_modified_since(obj_last_modification, since): + if since > datetime.now(): + raise Oops("The date provided to the If-Modified-Since header cannot be in the future", 412, title="No Future Modification Dates") + + if since < obj_last_modification: + raise Oops("The resource you are trying to change has been modified elsewhere", 412, title="Resource has been Modified") + def handle_marshmallow_errors(errors): error_list = [] diff --git a/versions/v0.py b/versions/v0.py index 2c78dfa..ef0ddae 100644 --- a/versions/v0.py +++ b/versions/v0.py @@ -203,6 +203,12 @@ def update_school(school_id): raise Oops("No records were found. Please make sure you are the owner for the school you are trying to modify", 404, title="No Records Updated") + # check modification times + # this needs to happen after the school is retreived from the DB for comparison + if 'If-Unmodified-Since' in request.headers: + since = isoparse(request.headers.get('If-Unmodified-Since')) + trap_object_modified_since(school.last_modified, since) + #only for updating data['id'] = school_id @@ -243,6 +249,11 @@ def delete_school(school_id): school = SchoolDB.query.filter_by( id=school_id, owner_id=get_api_user_id()).first() + # check modification times + # this needs to happen after the school is retreived from the DB for comparison + if 'If-Unmodified-Since' in request.headers: + since = isoparse(request.headers.get('If-Unmodified-Since')) + trap_object_modified_since(school.last_modified, since) if school == None: raise Oops("No records were found. Please make sure you are the owner for the school you are trying to delete", @@ -321,6 +332,10 @@ def update_bellschedule(bell_schedule_id): updated_schedule = BellScheduleSchema().load( get_request_body(request)).data + if 'If-Unmodified-Since' in request.headers: + since = isoparse(request.headers.get('If-Unmodified-Since')) + trap_object_modified_since(school.last_modified, since) + # no need to check for this. just overwrite the id value with the url-provided one # if not updated_schedule.id or updated_schedule.id.lower() != bell_schedule_id.lower(): # raise Oops("The identifier provided in the request body must match the identifier specified in the URL", @@ -346,6 +361,10 @@ def delete_bellschedule(bell_schedule_id): schedule = BellScheduleDB.query.filter_by(id=bell_schedule_id).first() school = SchoolDB.query.filter_by(id=schedule.school_id).first() check_ownership(school) + + if 'If-Unmodified-Since' in request.headers: + since = isoparse(request.headers.get('If-Unmodified-Since')) + trap_object_modified_since(school.last_modified, since) db.session.delete(schedule) From 2d38629bd9fc8cfb389e8515a5e49df6f190af6c Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Mon, 8 Jun 2020 17:12:54 -0700 Subject: [PATCH 035/206] update 404 errors --- versions/v0.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/versions/v0.py b/versions/v0.py index ef0ddae..86adcdf 100644 --- a/versions/v0.py +++ b/versions/v0.py @@ -199,9 +199,9 @@ def update_school(school_id): school = SchoolDB.query.filter_by( id=school_id, owner_id=get_api_user_id()).first() - if school == None: - raise Oops("No records were found. Please make sure you are the owner for the school you are trying to modify", - 404, title="No Records Updated") + if school is None: + raise Oops("No records could be updated because none were found", + 404, title="No Records Found") # check modification times # this needs to happen after the school is retreived from the DB for comparison @@ -249,15 +249,15 @@ def delete_school(school_id): school = SchoolDB.query.filter_by( id=school_id, owner_id=get_api_user_id()).first() + if school is None: + raise Oops("No records could be deleted because none were found", + 404, title="No Records Found") + # check modification times # this needs to happen after the school is retreived from the DB for comparison if 'If-Unmodified-Since' in request.headers: since = isoparse(request.headers.get('If-Unmodified-Since')) trap_object_modified_since(school.last_modified, since) - - if school == None: - raise Oops("No records were found. Please make sure you are the owner for the school you are trying to delete", - 404, title="No Records Updated") db.session.delete(school) db.session.commit() From eee6f6ebac6ce2c4d32613d92954a13860c63547 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Mon, 8 Jun 2020 17:13:58 -0700 Subject: [PATCH 036/206] update ownership checks --- versions/v0.py | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/versions/v0.py b/versions/v0.py index 86adcdf..499e1ec 100644 --- a/versions/v0.py +++ b/versions/v0.py @@ -196,12 +196,14 @@ def update_school(school_id): # if new_object.errors != {}: # return handle_marshmallow_errors(new_object.errors) - school = SchoolDB.query.filter_by( - id=school_id, owner_id=get_api_user_id()).first() + school = SchoolDB.query.filter_by(id=school_id).first() if school is None: raise Oops("No records could be updated because none were found", 404, title="No Records Found") + else: + check_ownership(school) + # check modification times # this needs to happen after the school is retreived from the DB for comparison @@ -247,11 +249,12 @@ def delete_school(school_id): check_permissions( [APIScopes.DELETE_SCHOOL, APIScopes.DELETE_BELL_SCHEDULE]) - school = SchoolDB.query.filter_by( - id=school_id, owner_id=get_api_user_id()).first() + school = SchoolDB.query.filter_by(id=school_id).first() if school is None: raise Oops("No records could be deleted because none were found", 404, title="No Records Found") + else: + check_ownership(school) # check modification times # this needs to happen after the school is retreived from the DB for comparison @@ -327,10 +330,11 @@ def update_bellschedule(bell_schedule_id): schedule = BellScheduleDB.query.filter_by(id=bell_schedule_id).first() school = SchoolDB.query.filter_by(id=schedule.school_id).first() - check_ownership(school) updated_schedule = BellScheduleSchema().load( get_request_body(request)).data + if school is not None: + check_ownership(school) if 'If-Unmodified-Since' in request.headers: since = isoparse(request.headers.get('If-Unmodified-Since')) @@ -360,7 +364,8 @@ def delete_bellschedule(bell_schedule_id): schedule = BellScheduleDB.query.filter_by(id=bell_schedule_id).first() school = SchoolDB.query.filter_by(id=schedule.school_id).first() - check_ownership(school) + if school is not None: + check_ownership(school) if 'If-Unmodified-Since' in request.headers: since = isoparse(request.headers.get('If-Unmodified-Since')) From 9135099b29b3b1f23b378189d220cdd75b13fa0b Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Mon, 8 Jun 2020 17:38:41 -0700 Subject: [PATCH 037/206] refactor check_permissions --- common/helpers.py | 27 +++++++++------------------ 1 file changed, 9 insertions(+), 18 deletions(-) diff --git a/common/helpers.py b/common/helpers.py index 8a41b31..6436550 100644 --- a/common/helpers.py +++ b/common/helpers.py @@ -318,23 +318,7 @@ def get_valid_auth_header_of_type(auth_header_type): return parts[1] # return the value provided with the token - -def has_permission(permission): - """Raises an AuthError if the specified scope is not present - - Arguments: - scope {string} -- The scope to check - - Raises: - AuthError: An authentication error - """ - return - if not permission in _request_ctx_stack.top.current_user.permissions: - raise AuthError( - "You do not have the necessary permission (" + permission.value + ") to access to this resource", 403) - - -def check_permissions(permissions_to_check): +def check_permissions(user, permissions_to_check): """Raises an AuthError if the specified scopes are not present Arguments: @@ -343,8 +327,15 @@ def check_permissions(permissions_to_check): Raises: AuthError: An authentication error """ +# _request_ctx_stack.top.current_user + perms_not_present = [] for perm in permissions_to_check: - has_permission(perm) + if not perm in user.permissions: + perms_not_present.append(perm) + if perms_not_present != []: + perms_needed = " ".join(perm.value for perm in perms_not_present) + raise AuthError( + "You have not been granted the necessary permissions to access to this resource. You are missing the following permissions: " + perms_needed, 403) def check_for_role(role): From c8345ef4400b85c1ecc63e0a2dcc2afec81d4427 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Mon, 8 Jun 2020 17:39:15 -0700 Subject: [PATCH 038/206] add a scope/perms check inside requires_auth decorator --- common/helpers.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/common/helpers.py b/common/helpers.py index 6436550..7d02368 100644 --- a/common/helpers.py +++ b/common/helpers.py @@ -465,7 +465,7 @@ def build_sql_column_update_list(input_object, updateable_fields_schema, colname # -def requires_auth(f): +def requires_auth(f, permissions=None): """Determines if the access token is valid """ @wraps(f) @@ -509,6 +509,11 @@ def decorated(*args, **kwargs): raise AuthError("Unable to parse authentication token.", 401) _request_ctx_stack.top.current_user = payload + + #this permissions check was added separately from the auth0 validation code + if permissions is not None: + check_permissions(payload, permissions) + return f(*args, **kwargs) raise AuthError("Unable to find appropriate key", 401) return decorated From 08f7e3602f7ea6dfe4cc0e93e9147ce974f66226 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Mon, 8 Jun 2020 17:40:32 -0700 Subject: [PATCH 039/206] move or remove checking for permission scopes --- versions/v0.py | 30 ++++++------------------------ 1 file changed, 6 insertions(+), 24 deletions(-) diff --git a/versions/v0.py b/versions/v0.py index 499e1ec..0b5d9cc 100644 --- a/versions/v0.py +++ b/versions/v0.py @@ -91,7 +91,6 @@ def list_schools(): schema: $ref: '#/definitions/School' """ - check_permissions([APIScopes.LIST_SCHOOLS]) school_list = [] schools = SchoolDB.query.all() @@ -112,7 +111,6 @@ def get_school(school_id): schema: $ref: '#/definitions/School' """ - check_permissions([APIScopes.LIST_SCHOOLS]) school = SchoolDB.query.filter_by(id=school_id).first() #double check this @@ -125,7 +123,7 @@ def get_school(school_id): @blueprint.route("/school/", methods=['POST']) @check_headers -@requires_auth +@requires_auth(permissions=[APIScopes.CREATE_SCHOOL]) @requires_admin def create_school(): """ Creates a new school @@ -144,8 +142,6 @@ def create_school(): schema: $ref: '#/definitions/School' """ - - check_permissions([APIScopes.CREATE_SCHOOL]) # if len(list_owned_school_ids()) > 0: # raise Oops( # "Authorizing user is already the owner of another school", 401) @@ -177,7 +173,7 @@ def create_school(): @blueprint.route("/school//", methods=['PATCH']) @check_headers -@requires_auth +@requires_auth(permissions=[APIScopes.EDIT_SCHOOL]) @requires_admin def update_school(school_id): """ @@ -189,8 +185,6 @@ def update_school(school_id): """ - check_permissions([APIScopes.EDIT_SCHOOL]) - data = get_request_body(request) # if new_object.errors != {}: @@ -235,7 +229,7 @@ def update_school(school_id): @blueprint.route("/school//", methods=['DELETE']) @check_headers -@requires_auth +@requires_auth(permissions=[APIScopes.DELETE_SCHOOL, APIScopes.DELETE_BELL_SCHEDULE]) @requires_admin def delete_school(school_id): """ @@ -246,9 +240,6 @@ def delete_school(school_id): """ - check_permissions( - [APIScopes.DELETE_SCHOOL, APIScopes.DELETE_BELL_SCHEDULE]) - school = SchoolDB.query.filter_by(id=school_id).first() if school is None: raise Oops("No records could be deleted because none were found", @@ -272,7 +263,6 @@ def delete_school(school_id): # @blueprint.route("/school//bellschedules/", methods=['GET']) # @check_headers # def list_bellschedules(school_id): -# check_permissions([APIScopes.LIST_BELL_SCHEDULES]) # schedule_list = [] # schedules = BellScheduleDB.query.filter_by(school_id=school_id) @@ -286,8 +276,6 @@ def delete_school(school_id): @check_headers def get_bellschedule(bell_schedule_id): - check_permissions([APIScopes.READ_BELL_SCHEDULE]) - schedule = BellScheduleDB.query.filter_by( id=bell_schedule_id).first() @@ -301,12 +289,10 @@ def get_bellschedule(bell_schedule_id): @blueprint.route("/bellschedule/", methods=['POST']) @check_headers -@requires_auth +@requires_auth(permissions=[APIScopes.CREATE_BELL_SCHEDULE]) @requires_admin def create_bellschedule(): - check_permissions([APIScopes.CREATE_BELL_SCHEDULE]) - # get school_id from a data parameter school = SchoolDB.query.filter_by(id=school_id).first() check_ownership(school) @@ -322,12 +308,10 @@ def create_bellschedule(): @blueprint.route("/bellschedule/", methods=['PATCH']) @check_headers -@requires_auth +@requires_auth(permissions=[APIScopes.CREATE_BELL_SCHEDULE]) @requires_admin def update_bellschedule(bell_schedule_id): - check_permissions([APIScopes.EDIT_BELL_SCHEDULE]) - schedule = BellScheduleDB.query.filter_by(id=bell_schedule_id).first() school = SchoolDB.query.filter_by(id=schedule.school_id).first() @@ -356,12 +340,10 @@ def update_bellschedule(bell_schedule_id): @blueprint.route("/bellschedule/", methods=['DELETE']) @check_headers -@requires_auth +@requires_auth(permissions=[APIScopes.DELETE_BELL_SCHEDULE]) @requires_admin def delete_bellschedule(bell_schedule_id): - check_permissions([APIScopes.DELETE_BELL_SCHEDULE]) - schedule = BellScheduleDB.query.filter_by(id=bell_schedule_id).first() school = SchoolDB.query.filter_by(id=schedule.school_id).first() if school is not None: From d9b7b8fc0d3fe92ee616c82036298e72fb7618c8 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Mon, 8 Jun 2020 17:44:00 -0700 Subject: [PATCH 040/206] update validation for update_school endpoint --- versions/v0.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/versions/v0.py b/versions/v0.py index 0b5d9cc..f3079c3 100644 --- a/versions/v0.py +++ b/versions/v0.py @@ -209,10 +209,11 @@ def update_school(school_id): data['id'] = school_id try: - new_object = SchoolSchema().load(data, session=session) + new_object = SchoolSchema().load(data, session=db.session) except ValidationError as err: - print(err.messages) # => {"email": ['"foo" is not a valid email address.']} + # print(err.messages) # => {"email": ['"foo" is not a valid email address.']} # print(err.valid_data) + return respond(err.messages, code=400) school.full_name = new_patch_val(data.full_name, school.full_name) school.acronym = new_patch_val(data.acronym, school.acronym) From f041df6cc03fd4cb9ef40c9bde98823c7b1cdff9 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Tue, 9 Jun 2020 11:53:35 -0700 Subject: [PATCH 041/206] fix error when calling requires_auth with no arguments https://realpython.com/primer-on-python-decorators/#decorators-with-arguments --- common/helpers.py | 103 +++++++++++++++++++++++++--------------------- 1 file changed, 56 insertions(+), 47 deletions(-) diff --git a/common/helpers.py b/common/helpers.py index 7d02368..2e43e48 100644 --- a/common/helpers.py +++ b/common/helpers.py @@ -465,58 +465,67 @@ def build_sql_column_update_list(input_object, updateable_fields_schema, colname # -def requires_auth(f, permissions=None): +def requires_auth(_func=None, *, permissions=None): """Determines if the access token is valid """ - @wraps(f) - def decorated(*args, **kwargs): - token = get_token_auth_header() - jsonurl = urlopen("https://"+AUTH0_DOMAIN+"/.well-known/jwks.json") - jwks = json.loads(jsonurl.read()) - try: - unverified_header = jwt.get_unverified_header(token) - except jwt.JWTError: - raise AuthError( - "Invalid token. Use an RS256 signed JWT Access Token", 401) - if unverified_header["alg"] == "HS256": - raise AuthError( - "Invalid token algorithm. Use an RS256 signed JWT Access Token", 401) - rsa_key = {} - for key in jwks["keys"]: - if key["kid"] == unverified_header["kid"]: - rsa_key = { - "kty": key["kty"], - "kid": key["kid"], - "use": key["use"], - "n": key["n"], - "e": key["e"] - } - if rsa_key: + # https://realpython.com/primer-on-python-decorators/#decorators-with-arguments + def args_or_no(func): + @wraps(func) + def decorated(*args, **kwargs): + token = get_token_auth_header() + jsonurl = urlopen("https://"+AUTH0_DOMAIN+"/.well-known/jwks.json") + jwks = json.loads(jsonurl.read()) try: - payload = jwt.decode( - token, - rsa_key, - algorithms=ALGORITHMS, - audience=API_IDENTIFIER, - issuer="https://"+AUTH0_DOMAIN+"/" - ) - except jwt.ExpiredSignatureError: - raise AuthError("Token has expired", 401) - except jwt.JWTClaimsError: + unverified_header = jwt.get_unverified_header(token) + except jwt.JWTError: raise AuthError( - "Incorrect JWT claims. Please check the audience and issuer", 401) - except Exception: - raise AuthError("Unable to parse authentication token.", 401) - - _request_ctx_stack.top.current_user = payload - - #this permissions check was added separately from the auth0 validation code - if permissions is not None: - check_permissions(payload, permissions) + "Invalid token. Use an RS256 signed JWT Access Token", 401) + if unverified_header["alg"] == "HS256": + raise AuthError( + "Invalid token algorithm. Use an RS256 signed JWT Access Token", 401) + rsa_key = {} + for key in jwks["keys"]: + if key["kid"] == unverified_header["kid"]: + rsa_key = { + "kty": key["kty"], + "kid": key["kid"], + "use": key["use"], + "n": key["n"], + "e": key["e"] + } + if rsa_key: + try: + payload = jwt.decode( + token, + rsa_key, + algorithms=ALGORITHMS, + audience=API_IDENTIFIER, + issuer="https://"+AUTH0_DOMAIN+"/" + ) + except jwt.ExpiredSignatureError: + raise AuthError("Token has expired", 401) + except jwt.JWTClaimsError: + raise AuthError( + "Incorrect JWT claims. Please check the audience and issuer", 401) + except Exception: + raise AuthError("Unable to parse authentication token.", 401) + + _request_ctx_stack.top.current_user = payload + + #this permissions check was added separately from the auth0 validation code + if permissions is not None: + check_permissions(payload, permissions) + + return func(*args, **kwargs) + + raise AuthError("Unable to find appropriate key", 401) + return decorated + + if _func is None: + return args_or_no + else: + return args_or_no(_func) - return f(*args, **kwargs) - raise AuthError("Unable to find appropriate key", 401) - return decorated def requires_admin(f): From b6878ab136b9065eacde04f6f846940ca05a415e Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Thu, 11 Jun 2020 13:51:01 -0700 Subject: [PATCH 042/206] remove extra fields/relationships from schema --- common/db_schema.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/common/db_schema.py b/common/db_schema.py index 8c67d65..2590f6b 100644 --- a/common/db_schema.py +++ b/common/db_schema.py @@ -23,7 +23,7 @@ class School(db.Model): primary_key=True, default=get_uuid) owner_id = db.Column('owner_id', db.VARCHAR(length=35)) full_name = db.Column('school_name', db.VARCHAR(length=75)) - schedules = db.relationship("BellSchedule") + # schedules = db.relationship("BellSchedule") acronym = db.Column( 'school_acronym', db.VARCHAR(length=75), nullable=True) alternate_freeperiod_name = db.Column( @@ -63,8 +63,8 @@ class BellScheduleDate(db.Model): """ __tablename__ = "bellscheduledates" type = "bellscheduledate" - id = db.Column('bell_schedule_id', HashColumn(length=16), ForeignKey(BellSchedule.id), primary_key=True) - school_id = db.Column(HashColumn(length=16), ForeignKey(School.id)) + bell_schedule_id = db.Column('bell_schedule_id', HashColumn(length=16), ForeignKey(BellSchedule.id), primary_key=True) + # school_id = db.Column(HashColumn(length=16), ForeignKey(School.id)) date = db.Column('date', db.Date, primary_key=True) creation_date = db.Column('creation_date', db.DateTime, default=datetime.today().isoformat()) @@ -83,7 +83,7 @@ class BellScheduleMeetingTime(db.Model): __tablename__ = "bellschedulemeetingtimes" type = "bellschedulemeetingtime" schedule_id = db.Column(HashColumn(length=16), ForeignKey(BellSchedule.id), primary_key=True) - school_id = db.Column(HashColumn(length=16), ForeignKey(School.id)) + # school_id = db.Column(HashColumn(length=16), ForeignKey(School.id)) name = db.Column('classperiod_name', db.VARCHAR(length=75), primary_key=True) start_time = db.Column('start_time', db.Time, From 1f04405529c7526268523e4af4206233d35cafb8 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Thu, 11 Jun 2020 13:52:07 -0700 Subject: [PATCH 043/206] remove unused J() function for jsonifying output --- common/helpers.py | 7 ------- 1 file changed, 7 deletions(-) diff --git a/common/helpers.py b/common/helpers.py index 2e43e48..f2532aa 100644 --- a/common/helpers.py +++ b/common/helpers.py @@ -162,13 +162,6 @@ def respond(response_data=None, code=200, headers={'Content-Type': 'application/ else: return make_response(json.dumps(content, cls=JSONEncoder), code, headers) -def J(*args, **kwargs): - """Wrapper around jsonify that sets the Content-Type of the response to - application/vnd.api+json. - """ - response = jsonify(*args, **kwargs) - response.mimetype = "application/vnd.api+json" - return response def filter_dict(dict, filter, is_whitelist=True): return {key: val for key, val in dict.items() if ((key in filter) if is_whitelist else (key not in filter))} From 01e306e5b8dfe097247d1af1c02294abb3b3155f Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sat, 13 Jun 2020 11:41:24 -0700 Subject: [PATCH 044/206] comment out copy() function in UUID TypeDecorator (docs say it isn't needed) --- common/guid.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/common/guid.py b/common/guid.py index 3c21e24..8f1e53c 100644 --- a/common/guid.py +++ b/common/guid.py @@ -13,6 +13,6 @@ def process_bind_param(self, value, dialect): def process_result_value(self, value, dialect): return uuid.UUID(bytes=value).hex - - def copy(self, **kw): - return HashColumn(self.impl.length) \ No newline at end of file + # This is a shallow copy and is provided to fulfill part of the TypeEngine contract. It usually does not need to be overridden unless the user-defined TypeDecorator has local state that should be deep-copied. + # def copy(self, **kw): + # return HashColumn(32) \ No newline at end of file From a9f4c004bf0ac0cc2fddc13df82770385cad940c Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sat, 13 Jun 2020 11:42:26 -0700 Subject: [PATCH 045/206] add more robust checks for none in GUID TypeDecorator --- common/guid.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/common/guid.py b/common/guid.py index 8f1e53c..cab3cb9 100644 --- a/common/guid.py +++ b/common/guid.py @@ -7,11 +7,16 @@ class HashColumn(types.TypeDecorator): impl=types.BINARY def process_bind_param(self, value, dialect): - if value is not None: + if value is None: + return value + else: return uuid.UUID(hex=value).bytes def process_result_value(self, value, dialect): - return uuid.UUID(bytes=value).hex + if value is None: + return value + else: + return uuid.UUID(bytes=value).hex # This is a shallow copy and is provided to fulfill part of the TypeEngine contract. It usually does not need to be overridden unless the user-defined TypeDecorator has local state that should be deep-copied. # def copy(self, **kw): From d4f7b7082685d78c97c331431a54d4edff96576c Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sat, 13 Jun 2020 11:43:07 -0700 Subject: [PATCH 046/206] update GUID TypeDecorator Types to allow marshmallow validation to be happy --- common/db_schema.py | 2 +- common/guid.py | 9 ++++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/common/db_schema.py b/common/db_schema.py index 2590f6b..9d2ec38 100644 --- a/common/db_schema.py +++ b/common/db_schema.py @@ -19,7 +19,7 @@ class School(db.Model): """ __tablename__ = "schools" type="school" - id = db.Column('school_id', HashColumn(length=16), + id = db.Column('school_id', HashColumn(length=32), primary_key=True, default=get_uuid) owner_id = db.Column('owner_id', db.VARCHAR(length=35)) full_name = db.Column('school_name', db.VARCHAR(length=75)) diff --git a/common/guid.py b/common/guid.py index cab3cb9..ed95e8b 100644 --- a/common/guid.py +++ b/common/guid.py @@ -4,7 +4,14 @@ #https://docs.sqlalchemy.org/en/13/core/custom_types.html#backend-agnostic-guid-type class HashColumn(types.TypeDecorator): - impl=types.BINARY + impl=types.CHAR + + def load_dialect_impl(self, dialect): + if dialect.name == 'postgresql': + return dialect.type_descriptor(UUID()) + else: + return dialect.type_descriptor(types.BINARY(16)) + def process_bind_param(self, value, dialect): if value is None: From c7642220460cd6d3fbb6903981fe59f231f14aca Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sat, 13 Jun 2020 11:45:42 -0700 Subject: [PATCH 047/206] tweak logic for PATCH methods to make use of marshmallow's ability to update instances --- versions/v0.py | 35 ++++++++++++++--------------------- 1 file changed, 14 insertions(+), 21 deletions(-) diff --git a/versions/v0.py b/versions/v0.py index f3079c3..52b1679 100644 --- a/versions/v0.py +++ b/versions/v0.py @@ -205,23 +205,16 @@ def update_school(school_id): since = isoparse(request.headers.get('If-Unmodified-Since')) trap_object_modified_since(school.last_modified, since) - #only for updating - data['id'] = school_id + #dont allow the ID to be modified in any way + del data['id'] try: - new_object = SchoolSchema().load(data, session=db.session) + updated_school = SchoolSchema().load(data, session=db.session, instance=school) except ValidationError as err: # print(err.messages) # => {"email": ['"foo" is not a valid email address.']} # print(err.valid_data) return respond(err.messages, code=400) - school.full_name = new_patch_val(data.full_name, school.full_name) - school.acronym = new_patch_val(data.acronym, school.acronym) - school.alternate_freeperiod_name = new_patch_val( - data.alternate_freeperiod_name, school.alternate_freeperiod_name) - # last_modified is automatically set in db_schema - - db.session.commit() #TODO: need to verify that the update worked? @@ -315,9 +308,6 @@ def update_bellschedule(bell_schedule_id): schedule = BellScheduleDB.query.filter_by(id=bell_schedule_id).first() school = SchoolDB.query.filter_by(id=schedule.school_id).first() - - updated_schedule = BellScheduleSchema().load( - get_request_body(request)).data if school is not None: check_ownership(school) @@ -325,15 +315,18 @@ def update_bellschedule(bell_schedule_id): since = isoparse(request.headers.get('If-Unmodified-Since')) trap_object_modified_since(school.last_modified, since) -# no need to check for this. just overwrite the id value with the url-provided one - # if not updated_schedule.id or updated_schedule.id.lower() != bell_schedule_id.lower(): - # raise Oops("The identifier provided in the request body must match the identifier specified in the URL", - # 400, title="Identifier Mismatch") + data = get_request_body(request) + + #dont allow the ID to be modified in any way + del data['id'] - schedule.name = new_patch_val(updated_schedule.name, schedule.name) - schedule.display_name = new_patch_val( - updated_schedule.display_name, schedule.display_name) - + try: + updated_schedule = BellScheduleSchema().load(data, session=db.session, instance=schedule) + except ValidationError as err: + # print(err.messages) # => {"email": ['"foo" is not a valid email address.']} + # print(err.valid_data) + return respond(err.messages, code=400) + db.session.commit() return respond(BellScheduleSchema(exclude=('school_id',)).dump(schedule)) From 50d5233a4fb15c3a87ff03fa57c814ce002448ce Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sat, 13 Jun 2020 14:47:54 -0700 Subject: [PATCH 048/206] find and replace all HashColumn(length=16) to HashColumn(length=32) --- common/db_schema.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/common/db_schema.py b/common/db_schema.py index 9d2ec38..048d255 100644 --- a/common/db_schema.py +++ b/common/db_schema.py @@ -39,9 +39,9 @@ class BellSchedule(db.Model): """ __tablename__ = "bellschedules" type = "bellschedule" - id = db.Column('bell_schedule_id', HashColumn(length=16), + id = db.Column('bell_schedule_id', HashColumn(length=32), primary_key=True, default=get_uuid) - school_id = db.Column(HashColumn(length=16), ForeignKey(School.id)) + school_id = db.Column(HashColumn(length=32), ForeignKey(School.id)) name = db.Column('bell_schedule_name', db.VARCHAR(length=75)) dates = db.relationship("BellScheduleDate") #meetingtimes = db.relationship("BellScheduleMeetingTime") @@ -63,8 +63,9 @@ class BellScheduleDate(db.Model): """ __tablename__ = "bellscheduledates" type = "bellscheduledate" - bell_schedule_id = db.Column('bell_schedule_id', HashColumn(length=16), ForeignKey(BellSchedule.id), primary_key=True) - # school_id = db.Column(HashColumn(length=16), ForeignKey(School.id)) + type = "date" + bell_schedule_id = db.Column('bell_schedule_id', HashColumn(length=32), ForeignKey(BellSchedule.id), primary_key=True) + # school_id = db.Column(HashColumn(length=32), ForeignKey(School.id)) date = db.Column('date', db.Date, primary_key=True) creation_date = db.Column('creation_date', db.DateTime, default=datetime.today().isoformat()) @@ -82,8 +83,8 @@ class BellScheduleMeetingTime(db.Model): """ __tablename__ = "bellschedulemeetingtimes" type = "bellschedulemeetingtime" - schedule_id = db.Column(HashColumn(length=16), ForeignKey(BellSchedule.id), primary_key=True) - # school_id = db.Column(HashColumn(length=16), ForeignKey(School.id)) + schedule_id = db.Column(HashColumn(length=32), ForeignKey(BellSchedule.id), primary_key=True) + # school_id = db.Column(HashColumn(length=32), ForeignKey(School.id)) name = db.Column('classperiod_name', db.VARCHAR(length=75), primary_key=True) start_time = db.Column('start_time', db.Time, From bdabe79ee0a49248dab254db8124fac2c4c71653 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 14 Jun 2020 10:46:07 -0700 Subject: [PATCH 049/206] remove unused functions --- common/helpers.py | 181 ---------------------------------------------- common/schemas.py | 1 - 2 files changed, 182 deletions(-) diff --git a/common/helpers.py b/common/helpers.py index f2532aa..e39ca3f 100644 --- a/common/helpers.py +++ b/common/helpers.py @@ -58,26 +58,6 @@ def is_client_error(code): def is_server_error(code): return code >= 500 and code <= 599 -def new_patch_val(body_val, db_val): - if body_val is not None and body_val != db_val: - return body_val - return db_val - -#https: // github.com/rgant/saas-api-boilerplate/blob/d1599716eb77b4994781b465fec27c91f8721cb5/common/utilities.py # L16 -def camel_to_delimiter_separated(name, glue='_'): - """ - Convert CamelCase to a delimiter-separated naming convention. Snake_case by default. - :param str name: CamelCase name to convert - :param str glue: Delimiter to use, default is an underscore for snake_case. - :return str: delimiter-separated version of name - """ - # From https://stackoverflow.com/a/1176023 - first_cap_re = re.compile('(.)([A-Z][a-z]+)') - all_cap_re = re.compile('([a-z0-9])([A-Z])') - replacement = fr'\1{glue}\2' - ex = first_cap_re.sub(replacement, name) - return all_cap_re.sub(replacement, ex).lower() - def register_api(api, resource, api_version, name_of_optional_param='id', type_of_optional_param='string', url_prefix=""): name = resource.__name__.lower() url = "/" + name + "/" @@ -163,68 +143,6 @@ def respond(response_data=None, code=200, headers={'Content-Type': 'application/ return make_response(json.dumps(content, cls=JSONEncoder), code, headers) -def filter_dict(dict, filter, is_whitelist=True): - return {key: val for key, val in dict.items() if ((key in filter) if is_whitelist else (key not in filter))} - -# def make_jsonapi_links_object(**kwargs): -# """Creates a JSON:API "links object" from a dict of data -# Returns: -# dict -- A links object dict with contents formatted per the JSON:API spec -# """ -# links_object = {} -# for link_name in kwargs: -# links_object[link_name] = kwargs[link_name] - -# return links_object - - -# def make_jsonapi_resource_object(resource, attributes_schema, blueprint_name): -# """Creates a JSON:API "resource object" from a dict of data - -# Arguments: -# data_dict {dict} -- The data to create the resource object from -# data_domain {string} -- A string describing what the data in data_dict represents (i.e. "school", "schedule", etc.) -# uri_function_name_mappings {dict} -- A mapping of the keys of identifiers in data_dict to the name of the function whose route should be used to generate URI's for responses -# TODO: maybe make uri_function_name_mappings an enum or something -# Raises: -# e: A Key Error if the data_dict somehow does not contain an "id" field. should never happen - -# Returns: -# dict -- A resource object dict with contents formatted per the JSON:API spec -# """ -# resource_object = {} -# resource_object["type"] = resource.type -# resource_object["id"] = resource.id - -# resource_object["links"] = make_jsonapi_links_object( -# self=resource.get_uri(blueprint_name)) - -# resource_object["attributes"] = attributes_schema.dump(resource) - -# if resource.type == "bellschedule": -# resource_object["relationships"] = {} -# resource_object["relationships"]["schools"] = {} -# resource_object["relationships"]["schools"]["links"] = make_jsonapi_links_object(self=url_for( -# blueprint_name + "." + blueprint_name + "_single_school", school_id=resource.school_id.hex, _external=True)) - -# return resource_object - - -# def deconstruct_resource_object(resource_object): -# """extracts a more processable dict from a JSON:API "resource object" - -# Arguments: -# resource_object {dict} -- a dict in JSON:API format - -# Returns: -# dict -- a flatter dict for easier processing -# """ -# resource = {} -# resource["type"] = resource_object.get("type", None) -# resource["id"] = UUID(resource_object.get("id", uuid4().hex)) - -# return {**resource, **resource_object["attributes"]} - def trap_object_modified_since(obj_last_modification, since): if since > datetime.now(): raise Oops("The date provided to the If-Modified-Since header cannot be in the future", 412, title="No Future Modification Dates") @@ -352,105 +270,6 @@ def list_owned_school_ids(cursor, school_id): return [sch_id[0] for sch_id in cursor] -# from https://stackoverflow.com/a/3675423 - - -def replace_last(source_string, replace_what, replace_with): - """Replaces only the last occurrence of a substring in a source string with a different string - - Arguments: - source_string {string} -- The string perform the search on - replace_what {string} -- The string to search for in the source string - replace_with {string} -- The string to replace the search string for - - Returns: - string -- The source string with the last occurrence of the replacement string replaces with the search string - """ - head, _sep, tail = source_string.rpartition(replace_what) - return head + replace_with + tail - - -def make_dict(the_tuple, keys): - """Creates a dict from a pair of tuples of equal length - - Arguments: - the_tuple {tuple} -- A tuple containing the data/values for the resulting dict - keys {tuple (or maybe list)} -- A tuple containing the keys for the resulting dict - - Returns: - A dict containing the data from both inputs - """ - the_dict = {} - for index, value in enumerate(the_tuple): - key = keys[index] - the_dict[key] = value - - return the_dict - - -def time_from_delta(delta): - # print(type(delta)) - # print(type((datetime.min + delta))) - return (datetime.min + delta).time().isoformat('minutes') - - -def extract_valid_credentials(encoded_credentials): - """Extracts a username and password from a base64 encoded HTTP Authorization header - - Arguments: - encoded_credentials {string} -- The raw/encoded HTTP Authorization header value - - Raises: - Oops: A general Exception - Oops: A general Exception - - Returns: - list -- A list containing the decoded credentials in the form of [username, password] - """ - try: - decoded = base64.b64decode( - encoded_credentials).decode("utf-8").split(":") - except: - raise Oops("An error occured while decoding the credentials", 401) - - if len(decoded) != 2: - raise Oops("credentials must not contain the ':' character", 401) - - return decoded - - -def get_comma_separated_string(the_list): - """creates a string of comma-sepatated values from an input list - - Arguments: - dictionary {[type]} -- [description] - """ - output = "" - - for index, value in enumerate(the_list): - output += value - - if index < len(the_list)-1: - output += ", " - return output - - -def build_sql_column_update_list(input_object, updateable_fields_schema, colname_mappings): - - sql_set = [] - values = () - - json = updateable_fields_schema.dump(input_object).data - # print(json) - for field in json: - if json[field] is not None: - sql_set.append( - (colname_mappings[field] - if field in colname_mappings else field) + "=%s" - ) - values += (json[field],) - - return get_comma_separated_string(sql_set), values # diff --git a/common/schemas.py b/common/schemas.py index da6461c..fdba2fc 100644 --- a/common/schemas.py +++ b/common/schemas.py @@ -4,7 +4,6 @@ import marshmallow as ma from marshmallow_sqlalchemy import SQLAlchemyAutoSchema -from common.helpers import camel_to_delimiter_separated from common.db_schema import db from common.db_schema import BellSchedule, BellScheduleMeetingTime, School, BellScheduleDate From 1603209737df4099c5554e8fcf93ee966da918c1 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 14 Jun 2020 13:03:21 -0700 Subject: [PATCH 050/206] use marshmallow to reject the ID field --- common/schemas.py | 5 ++++- versions/v0.py | 6 ------ 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/common/schemas.py b/common/schemas.py index fdba2fc..bd23171 100644 --- a/common/schemas.py +++ b/common/schemas.py @@ -2,7 +2,7 @@ Customized Marshmallow-SQLAlchemy and Marshmallow-JSONAPI Schemas to combine Schema Meta data. """ import marshmallow as ma -from marshmallow_sqlalchemy import SQLAlchemyAutoSchema +from marshmallow_sqlalchemy import SQLAlchemyAutoSchema, auto_field from common.db_schema import db @@ -15,6 +15,7 @@ class Meta: include_relationships = True load_instance = True include_fk = True + id = auto_field(dump_only=True) class BellScheduleDateSchema(SQLAlchemyAutoSchema): @@ -38,5 +39,7 @@ class Meta: include_relationships = True load_instance = True include_fk = True + + id = auto_field(dump_only=True) # Pluck dates and meeting times? diff --git a/versions/v0.py b/versions/v0.py index 52b1679..d58fe10 100644 --- a/versions/v0.py +++ b/versions/v0.py @@ -178,7 +178,6 @@ def create_school(): def update_school(school_id): """ updates a school - the id field in the request body will be overwritten with the id value from the header upon receiving the request --- security: - ApiKeyAuth: [] @@ -205,8 +204,6 @@ def update_school(school_id): since = isoparse(request.headers.get('If-Unmodified-Since')) trap_object_modified_since(school.last_modified, since) - #dont allow the ID to be modified in any way - del data['id'] try: updated_school = SchoolSchema().load(data, session=db.session, instance=school) @@ -317,9 +314,6 @@ def update_bellschedule(bell_schedule_id): data = get_request_body(request) - #dont allow the ID to be modified in any way - del data['id'] - try: updated_schedule = BellScheduleSchema().load(data, session=db.session, instance=schedule) except ValidationError as err: From 1f5ba08aed0556600c4904125f2d2c45514a424e Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 14 Jun 2020 13:15:29 -0700 Subject: [PATCH 051/206] replace dateutil with parsing HTTP dates as per spec --- versions/v0.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/versions/v0.py b/versions/v0.py index d58fe10..1276e83 100644 --- a/versions/v0.py +++ b/versions/v0.py @@ -12,7 +12,6 @@ # from bson import json_util # from bson.objectid import ObjectId -from dateutil.parser import isoparse import http.client from common.db_schema import School as SchoolDB, db, BellSchedule as BellScheduleDB from sqlalchemy import create_engine @@ -201,7 +200,7 @@ def update_school(school_id): # check modification times # this needs to happen after the school is retreived from the DB for comparison if 'If-Unmodified-Since' in request.headers: - since = isoparse(request.headers.get('If-Unmodified-Since')) + since = datetime.datetime.strptime(request.headers.get('If-Unmodified-Since'), '%a, %d %b %Y %H:%M:%S GMT') trap_object_modified_since(school.last_modified, since) @@ -241,7 +240,7 @@ def delete_school(school_id): # check modification times # this needs to happen after the school is retreived from the DB for comparison if 'If-Unmodified-Since' in request.headers: - since = isoparse(request.headers.get('If-Unmodified-Since')) + since = datetime.datetime.strptime(request.headers.get('If-Unmodified-Since'), '%a, %d %b %Y %H:%M:%S GMT') trap_object_modified_since(school.last_modified, since) db.session.delete(school) @@ -309,7 +308,7 @@ def update_bellschedule(bell_schedule_id): check_ownership(school) if 'If-Unmodified-Since' in request.headers: - since = isoparse(request.headers.get('If-Unmodified-Since')) + since = datetime.datetime.strptime(request.headers.get('If-Unmodified-Since'), '%a, %d %b %Y %H:%M:%S GMT') trap_object_modified_since(school.last_modified, since) data = get_request_body(request) @@ -338,7 +337,7 @@ def delete_bellschedule(bell_schedule_id): check_ownership(school) if 'If-Unmodified-Since' in request.headers: - since = isoparse(request.headers.get('If-Unmodified-Since')) + since = datetime.datetime.strptime(request.headers.get('If-Unmodified-Since'), '%a, %d %b %Y %H:%M:%S GMT') trap_object_modified_since(school.last_modified, since) db.session.delete(schedule) From 2559026119ee6f8f7c757445762255f96ba1a4e5 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 14 Jun 2020 13:15:44 -0700 Subject: [PATCH 052/206] update dependencies --- Pipfile.lock | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/Pipfile.lock b/Pipfile.lock index 2d4ffbe..76dfe24 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -21,11 +21,11 @@ "yaml" ], "hashes": [ - "sha256:419d0564b899e182c2af50483ea074db8cb05fee60838be58bb4542095d5c08d", - "sha256:9bf4e51d56c9067c60668b78210ae213894f060f85593dc2ad8805eb7d875a2a" + "sha256:b65063e11968a8c26dbbe9b4100ee24026a41cc358dd204df279bdedd7d8dea2", + "sha256:f5244ccca33f7a81309f6b3c9d458e33e869050c2d861b9f8cee24b3ad739d2b" ], "index": "pypi", - "version": "==3.3.0" + "version": "==3.3.1" }, "apispec-webframeworks": { "hashes": [ @@ -98,11 +98,11 @@ }, "flask-marshmallow": { "hashes": [ - "sha256:6e6aec171b8e092e0eafaf035ff5b8637bf3a58ab46f568c4c1bab02f2a3c196", - "sha256:a1685536e7ab5abdc712bbc1ac1a6b0b50951a368502f7985e7d1c27b3c21e59" + "sha256:1da1e6454a56a3e15107b987121729f152325bdef23f3df2f9b52bbd074af38e", + "sha256:aefc1f1d96256c430a409f08241bab75ffe97e5d14ac5d1f000764e39bf4873a" ], "index": "pypi", - "version": "==0.12.0" + "version": "==0.13.0" }, "flask-sqlalchemy": { "hashes": [ @@ -270,10 +270,10 @@ }, "rsa": { "hashes": [ - "sha256:14ba45700ff1ec9eeb206a2ce76b32814958a98e372006c8fb76ba820211be66", - "sha256:1a836406405730121ae9823e19c6e806c62bbad73f890574fff50efa4122c487" + "sha256:109ea5a66744dd859bf16fe904b8d8b627adafb9408753161e766a92e7d681fa", + "sha256:23778f5523461cf86ae075f9482a99317f362bca752ae57cb118044066f4026f" ], - "version": "==4.0" + "version": "==4.6" }, "six": { "hashes": [ From 9d16470b47062baa733104ece236e3b237617f0e Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 14 Jun 2020 13:16:23 -0700 Subject: [PATCH 053/206] uninstall python-dateutil dependency --- Pipfile | 1 - Pipfile.lock | 10 +--------- 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/Pipfile b/Pipfile index 2bb4ee7..e5902c9 100644 --- a/Pipfile +++ b/Pipfile @@ -22,7 +22,6 @@ flask-sqlalchemy = "*" marshmallow-sqlalchemy = "*" apispec = "*" apispec-webframeworks = "*" -python-dateutil = "*" [requires] python_version = "3.6" diff --git a/Pipfile.lock b/Pipfile.lock index 76dfe24..e558d4b 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "d5afada0d044282d2c1615829ed9f74e77c3be618b3ab344a44614d74a4d10c1" + "sha256": "77cdedfc00958754792a068c23e7878dadd881fe9f8f93d48692cb4ddeb71562" }, "pipfile-spec": 6, "requires": { @@ -228,14 +228,6 @@ ], "version": "==0.16.0" }, - "python-dateutil": { - "hashes": [ - "sha256:73ebfe9dbf22e832286dafa60473e4cd239f8592f699aa5adaf10050e6e1823c", - "sha256:75bb3f31ea686f1197762692a9ee6a7550b59fc6ca3a1f4b5d7e32fb98e2da2a" - ], - "index": "pypi", - "version": "==2.8.1" - }, "python-dotenv": { "hashes": [ "sha256:25c0ff1a3e12f4bde8d592cc254ab075cfe734fc5dd989036716fd17ee7e5ec7", From ae8c5d5a7715cffd06e1b9347b7e8c07d2e7a6e6 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 14 Jun 2020 13:19:13 -0700 Subject: [PATCH 054/206] move HTTP date format string to constants --- common/constants.py | 1 + versions/v0.py | 10 +++++----- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/common/constants.py b/common/constants.py index 392453c..53c4754 100644 --- a/common/constants.py +++ b/common/constants.py @@ -1,5 +1,6 @@ from enum import Enum +HTTP_DATE_FORMAT = '%a, %d %b %Y %H:%M:%S GMT' class AuthType(Enum): TOKEN = "Bearer" diff --git a/versions/v0.py b/versions/v0.py index 1276e83..79df7e8 100644 --- a/versions/v0.py +++ b/versions/v0.py @@ -17,7 +17,7 @@ from sqlalchemy import create_engine from common.helpers import * -from common.constants import APIScopes +from common.constants import APIScopes, HTTP_DATE_FORMAT from common.schemas import SchoolSchema, BellScheduleSchema from common.services import auth0management import common.exceptions @@ -200,7 +200,7 @@ def update_school(school_id): # check modification times # this needs to happen after the school is retreived from the DB for comparison if 'If-Unmodified-Since' in request.headers: - since = datetime.datetime.strptime(request.headers.get('If-Unmodified-Since'), '%a, %d %b %Y %H:%M:%S GMT') + since = datetime.datetime.strptime(request.headers.get('If-Unmodified-Since'), HTTP_DATE_FORMAT) trap_object_modified_since(school.last_modified, since) @@ -240,7 +240,7 @@ def delete_school(school_id): # check modification times # this needs to happen after the school is retreived from the DB for comparison if 'If-Unmodified-Since' in request.headers: - since = datetime.datetime.strptime(request.headers.get('If-Unmodified-Since'), '%a, %d %b %Y %H:%M:%S GMT') + since = datetime.datetime.strptime(request.headers.get('If-Unmodified-Since'), HTTP_DATE_FORMAT) trap_object_modified_since(school.last_modified, since) db.session.delete(school) @@ -308,7 +308,7 @@ def update_bellschedule(bell_schedule_id): check_ownership(school) if 'If-Unmodified-Since' in request.headers: - since = datetime.datetime.strptime(request.headers.get('If-Unmodified-Since'), '%a, %d %b %Y %H:%M:%S GMT') + since = datetime.datetime.strptime(request.headers.get('If-Unmodified-Since'), HTTP_DATE_FORMAT) trap_object_modified_since(school.last_modified, since) data = get_request_body(request) @@ -337,7 +337,7 @@ def delete_bellschedule(bell_schedule_id): check_ownership(school) if 'If-Unmodified-Since' in request.headers: - since = datetime.datetime.strptime(request.headers.get('If-Unmodified-Since'), '%a, %d %b %Y %H:%M:%S GMT') + since = datetime.datetime.strptime(request.headers.get('If-Unmodified-Since'), HTTP_DATE_FORMAT) trap_object_modified_since(school.last_modified, since) db.session.delete(schedule) From 75046609dd50a85158b8c24a8a6ab0472bec262c Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 14 Jun 2020 13:21:16 -0700 Subject: [PATCH 055/206] move HTTP Content-type header to constants --- common/constants.py | 4 ++++ common/helpers.py | 14 ++++++-------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/common/constants.py b/common/constants.py index 53c4754..6d7ca89 100644 --- a/common/constants.py +++ b/common/constants.py @@ -1,5 +1,9 @@ from enum import Enum +API_DATATYPE ='application/json' + +API_DATATYPE_HEADER = {'Content-Type': API_DATATYPE} + HTTP_DATE_FORMAT = '%a, %d %b %Y %H:%M:%S GMT' class AuthType(Enum): diff --git a/common/helpers.py b/common/helpers.py index e39ca3f..0e4e13d 100644 --- a/common/helpers.py +++ b/common/helpers.py @@ -15,7 +15,7 @@ import marshmallow import marshmallow_sqlalchemy -from common.constants import AuthType +from common.constants import AuthType, API_DATATYPE_HEADER, API_DATATYPE from common.db_schema import db from common.exceptions import Oops, AuthError @@ -115,7 +115,7 @@ def make_error_object(code, error_id=None, title=None, message=None): return error_data -def respond(response_data=None, code=200, headers={'Content-Type': 'application/json'}): +def respond(response_data=None, code=200, headers=API_DATATYPE_HEADER): """ Forms the data into a JSON response Arguments: @@ -366,18 +366,16 @@ def check_headers(func): @wraps(func) def wrapper(*args, **kwargs): # if request.method in ('POST', 'PATCH', 'PUT'): - # if 'Content-Type' in request.headers and request.headers['Content-Type'] != 'application/vnd.api+json': - + # if 'Content-Type' in request.headers and request.headers['Content-Type'] != API_DATATYPE: # error = make_error_object( - # message='Content-Type header must be application/vnd.api+json', title='Invalid request header', code=415) + # message='Content-Type header must be ' + API_DATATYPE, title='Invalid request header', code=415) # return respond(response_data=error, code=415) # if 'Accept' in request.headers: # for accept in request.headers['Accept'].split(','): - # if accept.strip() != 'application/vnd.api+json': - + # if accept.strip() != API_DATATYPE: # error = make_error_object( - # message='Accept header must be application/vnd.api+json without media type parameters', title='Invalid request header', code=406) + # message='Accept header must be ' + API_DATATYPE, title='Invalid request header', code=406) # return respond(response_data=error, code=406) return func(*args, **kwargs) From d766362e2e614ba34a49749758a573aa0e14f39f Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 14 Jun 2020 13:21:47 -0700 Subject: [PATCH 056/206] re-add HTTP header checks --- common/helpers.py | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/common/helpers.py b/common/helpers.py index 0e4e13d..3b6a0ef 100644 --- a/common/helpers.py +++ b/common/helpers.py @@ -365,18 +365,18 @@ def check_headers(func): """ @wraps(func) def wrapper(*args, **kwargs): - # if request.method in ('POST', 'PATCH', 'PUT'): - # if 'Content-Type' in request.headers and request.headers['Content-Type'] != API_DATATYPE: - # error = make_error_object( - # message='Content-Type header must be ' + API_DATATYPE, title='Invalid request header', code=415) - # return respond(response_data=error, code=415) - - # if 'Accept' in request.headers: - # for accept in request.headers['Accept'].split(','): - # if accept.strip() != API_DATATYPE: - # error = make_error_object( - # message='Accept header must be ' + API_DATATYPE, title='Invalid request header', code=406) - # return respond(response_data=error, code=406) + if request.method in ('POST', 'PATCH', 'PUT'): + if 'Content-Type' in request.headers and request.headers['Content-Type'] != API_DATATYPE: + error = make_error_object( + message='Content-Type header must be ' + API_DATATYPE, title='Invalid request header', code=415) + return respond(response_data=error, code=415) + + if 'Accept' in request.headers: + for accept in request.headers['Accept'].split(','): + if accept.strip() != API_DATATYPE: + error = make_error_object( + message='Accept header must be ' + API_DATATYPE, title='Invalid request header', code=406) + return respond(response_data=error, code=406) return func(*args, **kwargs) From 95f6fe98eb11db381aadaed37afe312bb192cc96 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 14 Jun 2020 13:41:14 -0700 Subject: [PATCH 057/206] add support for If-Modified-Since and 304 Not Modified to make things easier for client --- versions/v0.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/versions/v0.py b/versions/v0.py index 79df7e8..0f0fca1 100644 --- a/versions/v0.py +++ b/versions/v0.py @@ -117,6 +117,12 @@ def get_school(school_id): raise Oops("No school was found with the specified id.", 404, title="Resource Not Found") + if 'If-Modified-Since' in request.headers: + since = datetime.strptime(request.headers.get('If-Modified-Since'), HTTP_DATE_FORMAT) + # TODO: make this a more robust check + if school.last_modified == since: + return respond(code=304) #Not Modified + return respond(SchoolSchema().dump(school)) @@ -274,6 +280,12 @@ def get_bellschedule(bell_schedule_id): raise Oops("No bell schedule was found with the specified id.", 404, title="Resource Not Found") + if 'If-Modified-Since' in request.headers: + since = datetime.strptime(request.headers.get('If-Modified-Since'), HTTP_DATE_FORMAT) + # TODO: make this a more robust check + if schedule.last_modified == since: + return respond(code=304) #Not Modified + return respond(BellScheduleSchema(exclude=('school_id',)).dump(schedule)) From db0dd4864ee2c89e5683c277c880130925b50fcb Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 14 Jun 2020 17:43:49 -0700 Subject: [PATCH 058/206] re-add relationships and just hide them from schemas --- common/db_schema.py | 4 ++-- common/schemas.py | 16 ++++++++-------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/common/db_schema.py b/common/db_schema.py index 048d255..67a2a07 100644 --- a/common/db_schema.py +++ b/common/db_schema.py @@ -23,7 +23,7 @@ class School(db.Model): primary_key=True, default=get_uuid) owner_id = db.Column('owner_id', db.VARCHAR(length=35)) full_name = db.Column('school_name', db.VARCHAR(length=75)) - # schedules = db.relationship("BellSchedule") + schedules = db.relationship("BellSchedule") acronym = db.Column( 'school_acronym', db.VARCHAR(length=75), nullable=True) alternate_freeperiod_name = db.Column( @@ -44,7 +44,7 @@ class BellSchedule(db.Model): school_id = db.Column(HashColumn(length=32), ForeignKey(School.id)) name = db.Column('bell_schedule_name', db.VARCHAR(length=75)) dates = db.relationship("BellScheduleDate") - #meetingtimes = db.relationship("BellScheduleMeetingTime") + meetingtimes = db.relationship("BellScheduleMeetingTime") display_name = db.Column('bell_schedule_display_name', db.VARCHAR(length=75)) creation_date = db.Column('creation_date', db.DateTime, default=datetime.utcnow()) diff --git a/common/schemas.py b/common/schemas.py index bd23171..b043037 100644 --- a/common/schemas.py +++ b/common/schemas.py @@ -12,33 +12,33 @@ class SchoolSchema(SQLAlchemyAutoSchema): class Meta: model = School - include_relationships = True + include_relationships = False load_instance = True - include_fk = True + include_fk = False id = auto_field(dump_only=True) class BellScheduleDateSchema(SQLAlchemyAutoSchema): class Meta: model = BellScheduleDate - include_relationships = True + include_relationships = False load_instance = True - include_fk = True + include_fk = False class BellScheduleMeetingTimeSchema(SQLAlchemyAutoSchema): class Meta: model = BellScheduleMeetingTime - include_relationships = True + include_relationships = False load_instance = True - include_fk = True + include_fk = False class BellScheduleSchema(SQLAlchemyAutoSchema): class Meta: model = BellSchedule - include_relationships = True + include_relationships = False load_instance = True - include_fk = True + include_fk = False id = auto_field(dump_only=True) From efcad67634755ab14e9056d0d1b80f85f757b83b Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 14 Jun 2020 17:52:36 -0700 Subject: [PATCH 059/206] set creation_date and last_modified as read-only too --- common/schemas.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/common/schemas.py b/common/schemas.py index b043037..4ab2c84 100644 --- a/common/schemas.py +++ b/common/schemas.py @@ -15,7 +15,10 @@ class Meta: include_relationships = False load_instance = True include_fk = False + id = auto_field(dump_only=True) + creation_date = auto_field(dump_only=True) + last_modified = auto_field(dump_only=True) class BellScheduleDateSchema(SQLAlchemyAutoSchema): @@ -41,5 +44,7 @@ class Meta: include_fk = False id = auto_field(dump_only=True) + creation_date = auto_field(dump_only=True) + last_modified = auto_field(dump_only=True) # Pluck dates and meeting times? From 48eb4427ef8f73c9588512a64b32312069a50345 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Mon, 15 Jun 2020 21:34:35 -0700 Subject: [PATCH 060/206] make creation_date fields dump-only for all schemas --- common/schemas.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/common/schemas.py b/common/schemas.py index 4ab2c84..5f17c1e 100644 --- a/common/schemas.py +++ b/common/schemas.py @@ -27,6 +27,9 @@ class Meta: include_relationships = False load_instance = True include_fk = False + + creation_date = auto_field(dump_only=True) + class BellScheduleMeetingTimeSchema(SQLAlchemyAutoSchema): class Meta: @@ -34,6 +37,8 @@ class Meta: include_relationships = False load_instance = True include_fk = False + + creation_date = auto_field(dump_only=True) class BellScheduleSchema(SQLAlchemyAutoSchema): From 574bcf1b600b2bcf07c356f584679a3009a986e0 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Mon, 15 Jun 2020 21:36:33 -0700 Subject: [PATCH 061/206] set up serialization for bell schedules as intended originally why did this literally take months to get right? --- common/schemas.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/common/schemas.py b/common/schemas.py index 5f17c1e..d6fa620 100644 --- a/common/schemas.py +++ b/common/schemas.py @@ -3,6 +3,7 @@ """ import marshmallow as ma from marshmallow_sqlalchemy import SQLAlchemyAutoSchema, auto_field +from marshmallow_sqlalchemy.fields import Nested from common.db_schema import db @@ -36,7 +37,7 @@ class Meta: model = BellScheduleMeetingTime include_relationships = False load_instance = True - include_fk = False + include_fk = True creation_date = auto_field(dump_only=True) @@ -44,12 +45,13 @@ class BellScheduleSchema(SQLAlchemyAutoSchema): class Meta: model = BellSchedule - include_relationships = False + include_relationships = True load_instance = True - include_fk = False + include_fk = True id = auto_field(dump_only=True) creation_date = auto_field(dump_only=True) last_modified = auto_field(dump_only=True) - # Pluck dates and meeting times? + meetingtimes = Nested(BellScheduleMeetingTimeSchema(), exclude=("schedule_id", "creation_date"), many=True) + dates = ma.fields.Pluck(BellScheduleDateSchema, "date", many=True) From bd52070939d47c3444b6f69c867aa92234463940 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Mon, 15 Jun 2020 21:37:35 -0700 Subject: [PATCH 062/206] add serialization for datetime.time objects --- common/helpers.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/common/helpers.py b/common/helpers.py index 3b6a0ef..7dfd113 100644 --- a/common/helpers.py +++ b/common/helpers.py @@ -7,7 +7,7 @@ from os import environ as env import json from uuid import UUID, uuid4 -from datetime import datetime +from datetime import datetime, time from common.services import auth0management import flask_limiter import re @@ -29,7 +29,7 @@ class JSONEncoder(json.JSONEncoder): # this was copied from https://github.com/miLibris/flask-rest-jsonapi/blob/ad3f90f81955fa41aaf0fb8c49a75a5fbe334f5f/flask_rest_jsonapi/utils.py under the terms of the MIT license. def default(self, obj): - if isinstance(obj, datetime): + if isinstance(obj, (datetime, time)): return obj.isoformat() elif isinstance(obj, UUID): return obj.hex From 1c64efc7144a0137a8baeb83a9d8057f37f9d2a0 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Mon, 15 Jun 2020 21:38:31 -0700 Subject: [PATCH 063/206] remove schemas that aren't directly used from apispec this prevents them from being processed twice --- api.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api.py b/api.py index fcb7dfe..edf3a26 100644 --- a/api.py +++ b/api.py @@ -81,7 +81,7 @@ template = spec.to_flasgger( app, - definitions=[SchoolSchema, BellScheduleDateSchema, BellScheduleMeetingTimeSchema, BellScheduleSchema], + definitions=[SchoolSchema, BellScheduleSchema], paths=[] ) From cc1c99ac342154f613b533cca11fbc5cbf156eb8 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Mon, 15 Jun 2020 21:40:17 -0700 Subject: [PATCH 064/206] remove type fields from schema --- common/db_schema.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/common/db_schema.py b/common/db_schema.py index 67a2a07..f253535 100644 --- a/common/db_schema.py +++ b/common/db_schema.py @@ -18,7 +18,6 @@ class School(db.Model): description: A School """ __tablename__ = "schools" - type="school" id = db.Column('school_id', HashColumn(length=32), primary_key=True, default=get_uuid) owner_id = db.Column('owner_id', db.VARCHAR(length=35)) @@ -38,7 +37,6 @@ class BellSchedule(db.Model): description: A BellSchedule """ __tablename__ = "bellschedules" - type = "bellschedule" id = db.Column('bell_schedule_id', HashColumn(length=32), primary_key=True, default=get_uuid) school_id = db.Column(HashColumn(length=32), ForeignKey(School.id)) @@ -62,8 +60,6 @@ class BellScheduleDate(db.Model): description: A date during which a particular bell schedule is in effect """ __tablename__ = "bellscheduledates" - type = "bellscheduledate" - type = "date" bell_schedule_id = db.Column('bell_schedule_id', HashColumn(length=32), ForeignKey(BellSchedule.id), primary_key=True) # school_id = db.Column(HashColumn(length=32), ForeignKey(School.id)) date = db.Column('date', db.Date, primary_key=True) @@ -82,7 +78,6 @@ class BellScheduleMeetingTime(db.Model): description: A meeting time for a particular bell schedule (aka a class period) """ __tablename__ = "bellschedulemeetingtimes" - type = "bellschedulemeetingtime" schedule_id = db.Column(HashColumn(length=32), ForeignKey(BellSchedule.id), primary_key=True) # school_id = db.Column(HashColumn(length=32), ForeignKey(School.id)) name = db.Column('classperiod_name', db.VARCHAR(length=75), From e10c1c71c1c7c39da3a5978e50d5bd00d14da509 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Mon, 15 Jun 2020 21:42:43 -0700 Subject: [PATCH 065/206] remove unnecessary iteration over school and bell schedule lists --- versions/v0.py | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/versions/v0.py b/versions/v0.py index 0f0fca1..2951d29 100644 --- a/versions/v0.py +++ b/versions/v0.py @@ -93,10 +93,8 @@ def list_schools(): school_list = [] schools = SchoolDB.query.all() - - for school in schools: - school_list.append(school) - return respond(SchoolSchema().dump(school_list, many=True)) + + return respond(SchoolSchema().dump(schools, many=True)) @blueprint.route("/school//", methods=['GET']) @@ -263,10 +261,7 @@ def delete_school(school_id): # schedule_list = [] # schedules = BellScheduleDB.query.filter_by(school_id=school_id) -# for schedule in schedules: -# schedule_list.append(schedule) -# return BellScheduleSchema(exclude=('school_id',)).dump(schedule_list, many=True) - +# return BellScheduleSchema(exclude=('school_id',)).dump(schedules, many=True) @blueprint.route("/bellschedule//", methods=['GET']) @check_headers From 942faf0d08b6a54efcd45d9ad0946829a6b98afa Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 12 Jul 2020 13:26:04 -0700 Subject: [PATCH 066/206] bring back list_bellschedules endpoint --- versions/v0.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/versions/v0.py b/versions/v0.py index 2951d29..ab43ea3 100644 --- a/versions/v0.py +++ b/versions/v0.py @@ -253,15 +253,15 @@ def delete_school(school_id): # sqlalchemy can be set to cascade deletes (i think). return None, 204 +#TODO: add filtering for return values to reduce size of response. i.e. filter dates by after today, exclude meeting times if they havent changed +@blueprint.route("/bellschedules//", methods=['GET']) +@check_headers +def list_bellschedules(school_id): -# @blueprint.route("/school//bellschedules/", methods=['GET']) -# @check_headers -# def list_bellschedules(school_id): -# schedule_list = [] -# schedules = BellScheduleDB.query.filter_by(school_id=school_id) + schedules = BellScheduleDB.query.filter_by(school_id=school_id) -# return BellScheduleSchema(exclude=('school_id',)).dump(schedules, many=True) + return respond(BellScheduleSchema(exclude=('school_id',)).dump(schedules, many=True)) @blueprint.route("/bellschedule//", methods=['GET']) @check_headers From 71d97c011840dbdd6ddcdca07ee782e1de88169a Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 12 Jul 2020 13:27:41 -0700 Subject: [PATCH 067/206] tweak API JSON keys for request and response data --- common/db_schema.py | 2 +- versions/v0.py | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/common/db_schema.py b/common/db_schema.py index f253535..8f13d67 100644 --- a/common/db_schema.py +++ b/common/db_schema.py @@ -40,7 +40,7 @@ class BellSchedule(db.Model): id = db.Column('bell_schedule_id', HashColumn(length=32), primary_key=True, default=get_uuid) school_id = db.Column(HashColumn(length=32), ForeignKey(School.id)) - name = db.Column('bell_schedule_name', db.VARCHAR(length=75)) + full_name = db.Column('bell_schedule_name', db.VARCHAR(length=75)) dates = db.relationship("BellScheduleDate") meetingtimes = db.relationship("BellScheduleMeetingTime") display_name = db.Column('bell_schedule_display_name', db.VARCHAR(length=75)) diff --git a/versions/v0.py b/versions/v0.py index ab43ea3..73d6a6a 100644 --- a/versions/v0.py +++ b/versions/v0.py @@ -281,7 +281,7 @@ def get_bellschedule(bell_schedule_id): if schedule.last_modified == since: return respond(code=304) #Not Modified - return respond(BellScheduleSchema(exclude=('school_id',)).dump(schedule)) + return respond(BellScheduleSchema().dump(schedule)) @blueprint.route("/bellschedule/", methods=['POST']) @@ -321,7 +321,8 @@ def update_bellschedule(bell_schedule_id): data = get_request_body(request) try: - updated_schedule = BellScheduleSchema().load(data, session=db.session, instance=schedule) + updated_schedule = BellScheduleSchema(exclude=('id', 'creation_date')).load( + data, session=db.session, instance=schedule) except ValidationError as err: # print(err.messages) # => {"email": ['"foo" is not a valid email address.']} # print(err.valid_data) From 70f33223a3ef358bf8b33066b887677ebdd95145 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 12 Jul 2020 13:31:26 -0700 Subject: [PATCH 068/206] Add documentation, comments, and TODO's --- common/helpers.py | 16 ++++++++++ versions/v0.py | 77 +++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 87 insertions(+), 6 deletions(-) diff --git a/common/helpers.py b/common/helpers.py index 7dfd113..f6c37cb 100644 --- a/common/helpers.py +++ b/common/helpers.py @@ -137,6 +137,7 @@ def respond(response_data=None, code=200, headers=API_DATATYPE_HEADER): else: content["data"] = response_data + #TODO: handle if response_data is none (i.e. in case of 304 not modified) if code is None: return make_response(json.dumps(content, cls=JSONEncoder), headers) else: @@ -144,6 +145,17 @@ def respond(response_data=None, code=200, headers=API_DATATYPE_HEADER): def trap_object_modified_since(obj_last_modification, since): + """ checks the If-Modified-Since header checks it to ensure that there is no data loss + :type obj_last_modification: datetime + :param obj_last_modification: the last modification time of the object being checked + + :type since: datetime + :param since: the value of the header + + :raises: Oops + + :rtype: None + """ if since > datetime.now(): raise Oops("The date provided to the If-Modified-Since header cannot be in the future", 412, title="No Future Modification Dates") @@ -251,6 +263,7 @@ def check_permissions(user, permissions_to_check): def check_for_role(role): user_id = get_api_user_id() + #TODO: make management API optional and check if it is present if user_id != "": return role in management_API.get_roles_for_user(user_id) else: @@ -262,6 +275,7 @@ def check_ownership(school): def list_owned_school_ids(cursor, school_id): + #TODO: remove manual SQL, also this is like horrifically broken cursor.execute( "SELECT UNHEX(school_id) as id FROM schools WHERE owner_id=%s", (school_id,)) # dict_keys_map defines the keys for the dictionary that is generated from the tuples returned from the database (so order matters) @@ -374,6 +388,8 @@ def wrapper(*args, **kwargs): if 'Accept' in request.headers: for accept in request.headers['Accept'].split(','): if accept.strip() != API_DATATYPE: + #this will error if any of the accept headers is not correct... + #TODO error = make_error_object( message='Accept header must be ' + API_DATATYPE, title='Invalid request header', code=406) return respond(response_data=error, code=406) diff --git a/versions/v0.py b/versions/v0.py index 73d6a6a..67e1c88 100644 --- a/versions/v0.py +++ b/versions/v0.py @@ -49,6 +49,9 @@ # responses: # '200': # description: A list of every publicly accessible ClassClock school +# content: +# application/json: +# ... # '400': # description: Unauthorized for some reason such as an invalid access token or incorrect scopes # """ @@ -78,7 +81,7 @@ # """ - +# TODO: add a search parameter @blueprint.route("/schools/", methods=['GET']) @check_headers def list_schools(): @@ -87,13 +90,15 @@ def list_schools(): responses: 200: description: A list of schools - schema: - $ref: '#/definitions/School' + content: + application/json: + schema: + $ref: '#/definitions/School' """ school_list = [] schools = SchoolDB.query.all() - + return respond(SchoolSchema().dump(schools, many=True)) @@ -107,6 +112,19 @@ def get_school(school_id): description: A single school object schema: $ref: '#/definitions/School' + parameters: + - in: path + name: school_id + schema: + type: string + length: 32 + required: true + - in: header + name: If-Modified-Since + schema: + type: string + format: date + required: false """ school = SchoolDB.query.filter_by(id=school_id).first() @@ -157,7 +175,7 @@ def create_school(): new_object = None try: #Numbers, booleans, strings, and ``None`` are considered invalid input to `Schema.load - new_object = SchoolSchema().load(data, session=db.session)#, session=session + new_object = SchoolSchema().load(data, session=db.session) except ValidationError as err: # print(err.messages) # => {"email": ['"foo" is not a valid email address.']} # print(err.valid_data) @@ -184,6 +202,13 @@ def update_school(school_id): --- security: - ApiKeyAuth: [] + parameters: + - in: header + name: If-Unmodified-Since + schema: + type: string + format: date + required: false """ @@ -231,6 +256,19 @@ def delete_school(school_id): --- security: - ApiKeyAuth: [] + parameters: + - in: path + name: school_id + schema: + type: string + length: 32 + required: true + - in: header + name: If-Unmodified-Since + schema: + type: string + format: date + required: false """ @@ -257,7 +295,17 @@ def delete_school(school_id): @blueprint.route("/bellschedules//", methods=['GET']) @check_headers def list_bellschedules(school_id): - + """ + gets a list of bell schedules + --- + parameters: + - in: path + name: school_id + schema: + type: string + length: 32 + required: true + """ schedules = BellScheduleDB.query.filter_by(school_id=school_id) @@ -266,6 +314,23 @@ def list_bellschedules(school_id): @blueprint.route("/bellschedule//", methods=['GET']) @check_headers def get_bellschedule(bell_schedule_id): + """ + gets a single bell schedule + --- + parameters: + - in: path + name: bell_schedule_id + schema: + type: string + length: 32 + required: true + - in: header + name: If-Modified-Since + schema: + type: string + format: date + required: false + """ schedule = BellScheduleDB.query.filter_by( id=bell_schedule_id).first() From 4a2cd7cbd7ce1f2468bcbc5f90e1d0c9fe2e2695 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 12 Jul 2020 14:07:11 -0700 Subject: [PATCH 069/206] make configuring the Auth0 management API optional --- common/helpers.py | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/common/helpers.py b/common/helpers.py index f6c37cb..472b474 100644 --- a/common/helpers.py +++ b/common/helpers.py @@ -24,7 +24,14 @@ API_IDENTIFIER = env.get("API_IDENTIFIER") ALGORITHMS = ["RS256"] -management_API = auth0management.Auth0ManagementService() +try: + #TODO: remove dependency on setting up auth0 to test the API + management_API = auth0management.Auth0ManagementService() +except: + #TODO: need to implement better logging. + print('Auth0 is not configured correctly. Access control for requests will not be enforced.') + management_API = None + class JSONEncoder(json.JSONEncoder): # this was copied from https://github.com/miLibris/flask-rest-jsonapi/blob/ad3f90f81955fa41aaf0fb8c49a75a5fbe334f5f/flask_rest_jsonapi/utils.py under the terms of the MIT license. @@ -264,6 +271,12 @@ def check_permissions(user, permissions_to_check): def check_for_role(role): user_id = get_api_user_id() #TODO: make management API optional and check if it is present + + if management_API is None: + #TODO: need to implement better logging. + print("Because Auth0 is not configured correctly, access control is not being enforced. All requests to check a users role will automatically pass.") + return True + if user_id != "": return role in management_API.get_roles_for_user(user_id) else: @@ -298,6 +311,11 @@ def requires_auth(_func=None, *, permissions=None): def args_or_no(func): @wraps(func) def decorated(*args, **kwargs): + if not management_API: + #TODO: need to implement better logging. + print("Because Auth0 is not configured correctly, access control is not being enforced. All requests to protected endpoints will automatically succeed.") + return func(*args, **kwargs) + token = get_token_auth_header() jsonurl = urlopen("https://"+AUTH0_DOMAIN+"/.well-known/jwks.json") jwks = json.loads(jsonurl.read()) From 03cedaf4d8443837904e100825763d8e9cca9a38 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 19 Jul 2020 13:09:53 -0700 Subject: [PATCH 070/206] move generic HTTP error handler to the api level --- api.py | 11 ++++++++++- versions/v0.py | 8 -------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/api.py b/api.py index edf3a26..2f047e7 100644 --- a/api.py +++ b/api.py @@ -3,7 +3,7 @@ from versions import v0 from flask_limiter import Limiter from flasgger import Swagger -from common.helpers import get_request_origin_identifier +from common.helpers import get_request_origin_identifier, make_error_object, respond from common.db_schema import db from common.schemas import * from flasgger import APISpec, Schema, Swagger, fields @@ -11,6 +11,8 @@ from apispec_webframeworks.flask import FlaskPlugin import os, sys, getpass from os import environ as env +from werkzeug.exceptions import HTTPException + #default values are only needed for some of these db_username = env.get("DB_USERNAME") @@ -191,6 +193,13 @@ def today_plus(sch, num_days): exit(0) +@app.errorhandler(HTTPException) +def handle_HTTP_error(e): + return respond( + make_error_object( + e.code, title=e.name, message=e.description), + code=e.code + ) @app.route("/", methods=['GET']) diff --git a/versions/v0.py b/versions/v0.py index 67e1c88..520865f 100644 --- a/versions/v0.py +++ b/versions/v0.py @@ -477,14 +477,6 @@ def handle_error(e): ) -@blueprint.errorhandler(HTTPException) -def handle_HTTP_error(e): - return respond( - make_error_object( - e.code, title=e.name(), message=e.description), - code=e.code - ) - # @blueprint.errorhandler(Exception) # def generic_exception_handler(e): From d3bccd71feb884bde85666de0f84d0e3418518cd Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 19 Jul 2020 13:10:28 -0700 Subject: [PATCH 071/206] use flask built-in json i guess --- versions/v0.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/versions/v0.py b/versions/v0.py index 520865f..f2aec24 100644 --- a/versions/v0.py +++ b/versions/v0.py @@ -1,8 +1,7 @@ -import json import uuid import datetime from flask_limiter import util -from flask import current_app +from flask import current_app, json from os import environ as env from flask import Blueprint, abort, jsonify, request From 00255a3a933b076ec78934e296db4f6f7f3ce968 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 19 Jul 2020 17:46:03 -0700 Subject: [PATCH 072/206] change name of meetingtimes field to be more consistent --- api.py | 4 ++-- common/db_schema.py | 2 +- common/schemas.py | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/api.py b/api.py index 2f047e7..31f2fb1 100644 --- a/api.py +++ b/api.py @@ -168,7 +168,7 @@ def today_plus(sch, num_days): s.schedules = [sc1,sc2] - sc1.meetingtimes = [ + sc1.meeting_times = [ BellScheduleMeetingTime( schedule_id =sc1.id, name="First Period", @@ -177,7 +177,7 @@ def today_plus(sch, num_days): ) ] - sc2.meetingtimes = [ + sc2.meeting_times = [ BellScheduleMeetingTime( schedule_id =sc2.id, name="First Period", diff --git a/common/db_schema.py b/common/db_schema.py index 8f13d67..8e65c0f 100644 --- a/common/db_schema.py +++ b/common/db_schema.py @@ -42,7 +42,7 @@ class BellSchedule(db.Model): school_id = db.Column(HashColumn(length=32), ForeignKey(School.id)) full_name = db.Column('bell_schedule_name', db.VARCHAR(length=75)) dates = db.relationship("BellScheduleDate") - meetingtimes = db.relationship("BellScheduleMeetingTime") + meeting_times = db.relationship("BellScheduleMeetingTime") display_name = db.Column('bell_schedule_display_name', db.VARCHAR(length=75)) creation_date = db.Column('creation_date', db.DateTime, default=datetime.utcnow()) diff --git a/common/schemas.py b/common/schemas.py index d6fa620..ae9a7d5 100644 --- a/common/schemas.py +++ b/common/schemas.py @@ -53,5 +53,5 @@ class Meta: creation_date = auto_field(dump_only=True) last_modified = auto_field(dump_only=True) - meetingtimes = Nested(BellScheduleMeetingTimeSchema(), exclude=("schedule_id", "creation_date"), many=True) + meeting_times = Nested(BellScheduleMeetingTimeSchema(), exclude=("schedule_id", "creation_date"), many=True) dates = ma.fields.Pluck(BellScheduleDateSchema, "date", many=True) From affe892a71128030d6538d62546c36de78fc998e Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 26 Jul 2020 13:36:37 -0700 Subject: [PATCH 073/206] fix permissions checking --- common/helpers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/helpers.py b/common/helpers.py index 472b474..b723889 100644 --- a/common/helpers.py +++ b/common/helpers.py @@ -260,7 +260,7 @@ def check_permissions(user, permissions_to_check): # _request_ctx_stack.top.current_user perms_not_present = [] for perm in permissions_to_check: - if not perm in user.permissions: + if perm.value not in user['permissions']: perms_not_present.append(perm) if perms_not_present != []: perms_needed = " ".join(perm.value for perm in perms_not_present) From bc4465a74f65d9fcf4fdde5f807326c6897ab2bd Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 26 Jul 2020 18:24:07 -0700 Subject: [PATCH 074/206] create custom pluck field to pass down the database session --- common/schemas.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/common/schemas.py b/common/schemas.py index ae9a7d5..eae3e70 100644 --- a/common/schemas.py +++ b/common/schemas.py @@ -4,12 +4,26 @@ import marshmallow as ma from marshmallow_sqlalchemy import SQLAlchemyAutoSchema, auto_field from marshmallow_sqlalchemy.fields import Nested +from marshmallow.fields import Pluck from common.db_schema import db from common.db_schema import BellSchedule, BellScheduleMeetingTime, School, BellScheduleDate +# Modified From https://github.com/marshmallow-code/marshmallow-sqlalchemy/commit/cf996b1f448d9b115b083489c8eb96be3bf1dd40#diff-7e28a06588f9d4acda3f3dd4224899afR136 +class SessionPluck(Pluck): + """Pluck field that inherits the session from its parent like Nested does.""" + + def _deserialize(self, *args, **kwargs): + if hasattr(self.schema, "session"): + try: + self.schema.session = self.root.session + except AttributeError: + # Marshmallow 2.0.0 has no root property. + self.schema.session = self.parent.session + return super(Pluck, self)._deserialize(*args, **kwargs) + class SchoolSchema(SQLAlchemyAutoSchema): class Meta: model = School From 138da0d84ca13d6218e3a7ff90bd841c1206dd71 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 26 Jul 2020 20:53:29 -0700 Subject: [PATCH 075/206] fix endpoint and permissions for edit_bellschedule endpoint --- versions/v0.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/versions/v0.py b/versions/v0.py index f2aec24..41f3d7e 100644 --- a/versions/v0.py +++ b/versions/v0.py @@ -367,9 +367,9 @@ def create_bellschedule(): return respond(BellScheduleSchema(exclude=('school_id',)).dump(new_schedule)) -@blueprint.route("/bellschedule/", methods=['PATCH']) +@blueprint.route("/bellschedule//", methods=['PATCH']) @check_headers -@requires_auth(permissions=[APIScopes.CREATE_BELL_SCHEDULE]) +@requires_auth(permissions=[APIScopes.EDIT_BELL_SCHEDULE]) @requires_admin def update_bellschedule(bell_schedule_id): From 0eef90d0acd646b4fbac48ee7f2cf05bd47d0813 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 2 Aug 2020 14:10:44 -0700 Subject: [PATCH 076/206] correct passing of sqalchemy session to Pluck-ed dates field --- common/schemas.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/common/schemas.py b/common/schemas.py index eae3e70..00bd4e7 100644 --- a/common/schemas.py +++ b/common/schemas.py @@ -22,7 +22,7 @@ def _deserialize(self, *args, **kwargs): except AttributeError: # Marshmallow 2.0.0 has no root property. self.schema.session = self.parent.session - return super(Pluck, self)._deserialize(*args, **kwargs) + return super(SessionPluck, self)._deserialize(*args, **kwargs) class SchoolSchema(SQLAlchemyAutoSchema): class Meta: @@ -68,4 +68,4 @@ class Meta: last_modified = auto_field(dump_only=True) meeting_times = Nested(BellScheduleMeetingTimeSchema(), exclude=("schedule_id", "creation_date"), many=True) - dates = ma.fields.Pluck(BellScheduleDateSchema, "date", many=True) + dates = SessionPluck(BellScheduleDateSchema, "date", many=True) From c9bb39926212ba4fd4648c5cdc7886e0539a2716 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 2 Aug 2020 14:11:38 -0700 Subject: [PATCH 077/206] fix errors regarding `_schema` keys in meeting_times field --- common/schemas.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/schemas.py b/common/schemas.py index 00bd4e7..57e2fca 100644 --- a/common/schemas.py +++ b/common/schemas.py @@ -67,5 +67,5 @@ class Meta: creation_date = auto_field(dump_only=True) last_modified = auto_field(dump_only=True) - meeting_times = Nested(BellScheduleMeetingTimeSchema(), exclude=("schedule_id", "creation_date"), many=True) + meeting_times = Nested(BellScheduleMeetingTimeSchema, exclude=("schedule_id", "creation_date"), many=True) dates = SessionPluck(BellScheduleDateSchema, "date", many=True) From 04e5c3ef69269fd055388350921b50af83b9dc8b Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 2 Aug 2020 15:30:09 -0700 Subject: [PATCH 078/206] add alias "name" for full_name field of BellSchedule Schema --- common/schemas.py | 1 + 1 file changed, 1 insertion(+) diff --git a/common/schemas.py b/common/schemas.py index 57e2fca..cc066c3 100644 --- a/common/schemas.py +++ b/common/schemas.py @@ -64,6 +64,7 @@ class Meta: include_fk = True id = auto_field(dump_only=True) + full_name = auto_field(data_key="name") creation_date = auto_field(dump_only=True) last_modified = auto_field(dump_only=True) From 824b63ca16ccd8a8d2a4cfe7bdc3e1e5233307f0 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 16 Aug 2020 14:01:31 -0700 Subject: [PATCH 079/206] fix cascading deletes when updating bellscheduledate's --- common/db_schema.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/common/db_schema.py b/common/db_schema.py index 8e65c0f..8018c9e 100644 --- a/common/db_schema.py +++ b/common/db_schema.py @@ -41,7 +41,6 @@ class BellSchedule(db.Model): primary_key=True, default=get_uuid) school_id = db.Column(HashColumn(length=32), ForeignKey(School.id)) full_name = db.Column('bell_schedule_name', db.VARCHAR(length=75)) - dates = db.relationship("BellScheduleDate") meeting_times = db.relationship("BellScheduleMeetingTime") display_name = db.Column('bell_schedule_display_name', db.VARCHAR(length=75)) creation_date = db.Column('creation_date', db.DateTime, @@ -65,6 +64,9 @@ class BellScheduleDate(db.Model): date = db.Column('date', db.Date, primary_key=True) creation_date = db.Column('creation_date', db.DateTime, default=datetime.today().isoformat()) + # This needs to be here because of he way that dates are updated. Since date entries are deleted and recreated instead of being modified, we need to also mark them for deletion when they are de-associated from the bell schedule. + # See: https://stackoverflow.com/a/23734727 + bellSchedule = db.relationship("BellSchedule", backref=db.backref("dates",cascade="save-update, merge,delete, delete-orphan")) # def get_uri(self, blueprint_name): From b9640217518871a8255773c5d052b1af04a55d17 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 16 Aug 2020 14:06:22 -0700 Subject: [PATCH 080/206] workaround to fix `id` and `classes` being seen as unknown fields --- common/schemas.py | 2 +- versions/v0.py | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/common/schemas.py b/common/schemas.py index cc066c3..901cadf 100644 --- a/common/schemas.py +++ b/common/schemas.py @@ -68,5 +68,5 @@ class Meta: creation_date = auto_field(dump_only=True) last_modified = auto_field(dump_only=True) - meeting_times = Nested(BellScheduleMeetingTimeSchema, exclude=("schedule_id", "creation_date"), many=True) + classes = Nested(BellScheduleMeetingTimeSchema, exclude=("schedule_id", "creation_date"), many=True) dates = SessionPluck(BellScheduleDateSchema, "date", many=True) diff --git a/versions/v0.py b/versions/v0.py index 41f3d7e..b4abad5 100644 --- a/versions/v0.py +++ b/versions/v0.py @@ -383,6 +383,9 @@ def update_bellschedule(bell_schedule_id): trap_object_modified_since(school.last_modified, since) data = get_request_body(request) + # remove ID from request body if provided because for some reason, the exclude parameter isnt working or may not be correctly getting passed down to the nested/plucked fields + if data['id']: + del data['id'] try: updated_schedule = BellScheduleSchema(exclude=('id', 'creation_date')).load( From c456b3e7cd9586f9d40553871f3e4684479fa6ec Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 24 Jan 2021 16:06:13 -0800 Subject: [PATCH 081/206] add beta URL to CORS allowed origins --- versions/v0.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/versions/v0.py b/versions/v0.py index b4abad5..710f2d8 100644 --- a/versions/v0.py +++ b/versions/v0.py @@ -33,7 +33,7 @@ blueprint = Blueprint('v0', __name__) -CORS(blueprint, origins="https://web.classclock.app", allow_headers=[ +CORS(blueprint, origins=["https://web.classclock.app", "https://beta.web.classclock.app"], allow_headers=[ "Accept", "Authorization"]) # supports_credentials=True) From 8c5632ef7718f194e9a2d7d5c1932a987c6190f1 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 24 Jan 2021 17:06:34 -0800 Subject: [PATCH 082/206] version lock packages to the state when they were installed --- Pipfile | 26 +++--- Pipfile.lock | 217 ++++++++++++++++++++++++++++++--------------------- 2 files changed, 143 insertions(+), 100 deletions(-) diff --git a/Pipfile b/Pipfile index e5902c9..82b79b5 100644 --- a/Pipfile +++ b/Pipfile @@ -9,19 +9,19 @@ verify_ssl = true python-dotenv = "*" python-jose = "*" six = "*" -mysql-connector = "*" -dnspython = "*" -flasgger = "*" -flask-marshmallow = "*" -Flask = "*" -Flask-Cors = "*" -Flask-Limiter = "*" -gunicorn = "*" -sqlalchemy = "*" -flask-sqlalchemy = "*" -marshmallow-sqlalchemy = "*" -apispec = "*" -apispec-webframeworks = "*" +mysql-connector = "~=2.2.9" +dnspython = "~=1.16.0" +flasgger = "~=0.9.3" +flask-marshmallow = "~=0.10.1" +Flask = "~=1.1.1" +Flask-Cors = "~=3.0.8" +Flask-Limiter = "~=1.0.1" +gunicorn = "~=19.9.0" +sqlalchemy = "~=1.3.13" +flask-sqlalchemy = "~=2.4.1" +marshmallow-sqlalchemy = "~=0.23" +apispec = "~=3.3.0" +apispec-webframeworks = "~=0.5.2" [requires] python_version = "3.6" diff --git a/Pipfile.lock b/Pipfile.lock index e558d4b..9de14e4 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "77cdedfc00958754792a068c23e7878dadd881fe9f8f93d48692cb4ddeb71562" + "sha256": "549ce7d9250c958a65abd02cc1ea6be0c9adbb2315dfc759cd97739d90f98a44" }, "pipfile-spec": 6, "requires": { @@ -21,11 +21,11 @@ "yaml" ], "hashes": [ - "sha256:b65063e11968a8c26dbbe9b4100ee24026a41cc358dd204df279bdedd7d8dea2", - "sha256:f5244ccca33f7a81309f6b3c9d458e33e869050c2d861b9f8cee24b3ad739d2b" + "sha256:a1df9ec6b2cd0edf45039ef025abd7f0660808fa2edf737d3ba1cf5ef1a4625b", + "sha256:d23ebd5b71e541e031b02a19db10b5e6d5ef8452c552833e3e1afc836b40b1ad" ], "index": "pypi", - "version": "==3.3.1" + "version": "==3.3.2" }, "apispec-webframeworks": { "hashes": [ @@ -37,10 +37,10 @@ }, "attrs": { "hashes": [ - "sha256:08a96c641c3a74e44eb59afb61a24f2cb9f4d7188748e76ba4bb5edfa3cb7d1c", - "sha256:f7b7ce16570fe9965acd6d30101a28f62fb4a7f9e926b3bbc9b61f8b04247e72" + "sha256:31b2eced602aa8423c2aea9c76a724617ed67cf9513173fd3a4f03e3a929c7e6", + "sha256:832aa3cde19744e49938b91fea06d69ecb9e649c93ba974535d08ad92164f700" ], - "version": "==19.3.0" + "version": "==20.3.0" }, "click": { "hashes": [ @@ -59,18 +59,18 @@ }, "ecdsa": { "hashes": [ - "sha256:867ec9cf6df0b03addc8ef66b56359643cb5d0c1dc329df76ba7ecfe256c8061", - "sha256:8f12ac317f8a1318efa75757ef0a651abe12e51fc1af8838fb91079445227277" + "sha256:64c613005f13efec6541bb0a33290d0d03c27abab5f15fbab20fb0ee162bdd8e", + "sha256:e108a5fe92c67639abae3260e43561af914e7fd0d27bae6d2ec1312ae7934dfe" ], - "version": "==0.15" + "version": "==0.14.1" }, "flasgger": { "hashes": [ - "sha256:37137b3292738580c42e03662bfb8731656a11d636e76f76d30e572c1fa5bd0d", - "sha256:7c187f7a7caeb42645f7de652335b794375925467407e40322620fb9d401b38c" + "sha256:0603941cf4003626b4ee551ca87331f1d17b8eecce500ccf1a1f1d3a332fc94a", + "sha256:6ebea406b5beecd77e8da42550f380d4d05a6107bc90b69ce9e77aee7612e2d0" ], "index": "pypi", - "version": "==0.9.4" + "version": "==0.9.5" }, "flask": { "hashes": [ @@ -82,43 +82,50 @@ }, "flask-cors": { "hashes": [ - "sha256:72170423eb4612f0847318afff8c247b38bd516b7737adfc10d1c2cdbb382d16", - "sha256:f4d97201660e6bbcff2d89d082b5b6d31abee04b1b3003ee073a6fd25ad1d69a" + "sha256:74efc975af1194fc7891ff5cd85b0f7478be4f7f59fe158102e91abb72bb4438", + "sha256:b60839393f3b84a0f3746f6cdca56c1ad7426aa738b70d6c61375857823181de" ], "index": "pypi", - "version": "==3.0.8" + "version": "==3.0.10" }, "flask-limiter": { "hashes": [ - "sha256:08d6d7534a847c532fd36d0df978f93908d8616813085941c862bbcfcf6811aa", - "sha256:82c154bd96c0a9c8307d9500876e72b247a35a5c7374a2c606fc32b647a6d8cb" + "sha256:8cce98dcf25bf2ddbb824c2b503b4fc8e1a139154240fd2c60d9306bad8a0db8" ], "index": "pypi", - "version": "==1.3.1" + "version": "==1.0.1" }, "flask-marshmallow": { "hashes": [ - "sha256:1da1e6454a56a3e15107b987121729f152325bdef23f3df2f9b52bbd074af38e", - "sha256:aefc1f1d96256c430a409f08241bab75ffe97e5d14ac5d1f000764e39bf4873a" + "sha256:4f507f883838b397638a3a36c7d36ee146b255a49db952f5d9de3f6f4522e8a8", + "sha256:69e99e3a123393894884a032ae2d11e6bdf4519a505819b66cec7eda32057741" ], "index": "pypi", - "version": "==0.13.0" + "version": "==0.10.1" }, "flask-sqlalchemy": { "hashes": [ - "sha256:0b656fbf87c5f24109d859bafa791d29751fabbda2302b606881ae5485b557a5", - "sha256:fcfe6df52cd2ed8a63008ca36b86a51fa7a4b70cef1c39e5625f722fca32308e" + "sha256:05b31d2034dd3f2a685cbbae4cfc4ed906b2a733cff7964ada450fd5e462b84e", + "sha256:bfc7150eaf809b1c283879302f04c42791136060c6eeb12c0c6674fb1291fae5" ], "index": "pypi", - "version": "==2.4.3" + "version": "==2.4.4" }, "gunicorn": { "hashes": [ - "sha256:1904bb2b8a43658807108d59c3f3d56c2b6121a701161de0ddf9ad140073c626", - "sha256:cd4a810dd51bf497552cf3f863b575dabd73d6ad6a91075b65936b151cbf4f9c" + "sha256:aa8e0b40b4157b36a5df5e599f45c9c76d6af43845ba3b3b0efe2c70473c2471", + "sha256:fa2662097c66f920f53f70621c6c58ca4a3c4d3434205e608e121b5b3b71f4f3" ], "index": "pypi", - "version": "==20.0.4" + "version": "==19.9.0" + }, + "importlib-metadata": { + "hashes": [ + "sha256:ace61d5fc652dc280e7b6b4ff732a9c2d40db2c0f92bc6cb74e07b73d53a1771", + "sha256:fa5daa4477a7414ae34e95942e4dd07f62adf589143c875c133c1e53c4eff38d" + ], + "markers": "python_version < '3.8'", + "version": "==3.4.0" }, "itsdangerous": { "hashes": [ @@ -188,18 +195,18 @@ }, "marshmallow": { "hashes": [ - "sha256:35ee2fb188f0bd9fc1cf9ac35e45fd394bd1c153cee430745a465ea435514bd5", - "sha256:9aa20f9b71c992b4782dad07c51d92884fd0f7c5cb9d3c737bea17ec1bad765f" + "sha256:4ab2fdb7f36eb61c3665da67a7ce281c8900db08d72ba6bf0e695828253581f7", + "sha256:eca81d53aa4aafbc0e20566973d0d2e50ce8bf0ee15165bb799bec0df1e50177" ], - "version": "==3.6.1" + "version": "==3.10.0" }, "marshmallow-sqlalchemy": { "hashes": [ - "sha256:03a555b610bb307689b821b64e2416593ec21a85925c8c436c2cd08ebc6bb85e", - "sha256:0ef59c8da8da2e18e808e3880158049e9d72f3031c84cc804b6c533a0eb668a9" + "sha256:93f47b880ac7070f7b34c8ac0a71eeec3f8582a22e5c0330c1c436e3f5f99a37", + "sha256:d051cf013c075c43e1ee5c4b01f8fab6dd6b140dab6825be45875f674a0d289c" ], "index": "pypi", - "version": "==0.23.1" + "version": "==0.24.1" }, "mistune": { "hashes": [ @@ -224,48 +231,58 @@ }, "pyrsistent": { "hashes": [ - "sha256:28669905fe725965daa16184933676547c5bb40a5153055a8dee2a4bd7933ad3" + "sha256:2e636185d9eb976a18a8a8e96efce62f2905fea90041958d8cc2a189756ebf3e" ], - "version": "==0.16.0" + "version": "==0.17.3" }, "python-dotenv": { "hashes": [ - "sha256:25c0ff1a3e12f4bde8d592cc254ab075cfe734fc5dd989036716fd17ee7e5ec7", - "sha256:3b9909bc96b0edc6b01586e1eed05e71174ef4e04c71da5786370cebea53ad74" + "sha256:0c8d1b80d1a1e91717ea7d526178e3882732420b03f08afea0406db6402e220e", + "sha256:587825ed60b1711daea4832cf37524dfd404325b7db5e25ebe88c495c9f807a0" ], "index": "pypi", - "version": "==0.13.0" + "version": "==0.15.0" }, "python-jose": { "hashes": [ - "sha256:1ac4caf4bfebd5a70cf5bd82702ed850db69b0b6e1d0ae7368e5f99ac01c9571", - "sha256:8484b7fdb6962e9d242cce7680469ecf92bda95d10bbcbbeb560cacdff3abfce" + "sha256:4e4192402e100b5fb09de5a8ea6bcc39c36ad4526341c123d401e2561720335b", + "sha256:67d7dfff599df676b04a996520d9be90d6cdb7e6dd10b4c7cacc0c3e2e92f2be" ], "index": "pypi", - "version": "==3.1.0" + "version": "==3.2.0" }, "pyyaml": { "hashes": [ - "sha256:06a0d7ba600ce0b2d2fe2e78453a470b5a6e000a985dd4a4e54e436cc36b0e97", - "sha256:240097ff019d7c70a4922b6869d8a86407758333f02203e0fc6ff79c5dcede76", - "sha256:4f4b913ca1a7319b33cfb1369e91e50354d6f07a135f3b901aca02aa95940bd2", - "sha256:69f00dca373f240f842b2931fb2c7e14ddbacd1397d57157a9b005a6a9942648", - "sha256:73f099454b799e05e5ab51423c7bcf361c58d3206fa7b0d555426b1f4d9a3eaf", - "sha256:74809a57b329d6cc0fdccee6318f44b9b8649961fa73144a98735b0aaf029f1f", - "sha256:7739fc0fa8205b3ee8808aea45e968bc90082c10aef6ea95e855e10abf4a37b2", - "sha256:95f71d2af0ff4227885f7a6605c37fd53d3a106fcab511b8860ecca9fcf400ee", - "sha256:b8eac752c5e14d3eca0e6dd9199cd627518cb5ec06add0de9d32baeee6fe645d", - "sha256:cc8955cfbfc7a115fa81d85284ee61147059a753344bc51098f3ccd69b0d7e0c", - "sha256:d13155f591e6fcc1ec3b30685d50bf0711574e2c0dfffd7644babf8b5102ca1a" - ], - "version": "==5.3.1" + "sha256:08682f6b72c722394747bddaf0aa62277e02557c0fd1c42cb853016a38f8dedf", + "sha256:0f5f5786c0e09baddcd8b4b45f20a7b5d61a7e7e99846e3c799b05c7c53fa696", + "sha256:129def1b7c1bf22faffd67b8f3724645203b79d8f4cc81f674654d9902cb4393", + "sha256:294db365efa064d00b8d1ef65d8ea2c3426ac366c0c4368d930bf1c5fb497f77", + "sha256:3b2b1824fe7112845700f815ff6a489360226a5609b96ec2190a45e62a9fc922", + "sha256:3bd0e463264cf257d1ffd2e40223b197271046d09dadf73a0fe82b9c1fc385a5", + "sha256:4465124ef1b18d9ace298060f4eccc64b0850899ac4ac53294547536533800c8", + "sha256:49d4cdd9065b9b6e206d0595fee27a96b5dd22618e7520c33204a4a3239d5b10", + "sha256:4e0583d24c881e14342eaf4ec5fbc97f934b999a6828693a99157fde912540cc", + "sha256:5accb17103e43963b80e6f837831f38d314a0495500067cb25afab2e8d7a4018", + "sha256:607774cbba28732bfa802b54baa7484215f530991055bb562efbed5b2f20a45e", + "sha256:6c78645d400265a062508ae399b60b8c167bf003db364ecb26dcab2bda048253", + "sha256:74c1485f7707cf707a7aef42ef6322b8f97921bd89be2ab6317fd782c2d53183", + "sha256:8c1be557ee92a20f184922c7b6424e8ab6691788e6d86137c5d93c1a6ec1b8fb", + "sha256:bb4191dfc9306777bc594117aee052446b3fa88737cd13b7188d0e7aa8162185", + "sha256:c20cfa2d49991c8b4147af39859b167664f2ad4561704ee74c1de03318e898db", + "sha256:d2d9808ea7b4af864f35ea216be506ecec180628aced0704e34aca0b040ffe46", + "sha256:dd5de0646207f053eb0d6c74ae45ba98c3395a571a2891858e87df7c9b9bd51b", + "sha256:e1d4970ea66be07ae37a3c2e48b5ec63f7ba6804bdddfdbd3cfd954d25a82e63", + "sha256:e4fac90784481d221a8e4b1162afa7c47ed953be40d31ab4629ae917510051df", + "sha256:fa5ae20527d8e831e8230cbffd9f8fe952815b2b7dae6ffec25318803a7528fc" + ], + "version": "==5.4.1" }, "rsa": { "hashes": [ - "sha256:109ea5a66744dd859bf16fe904b8d8b627adafb9408753161e766a92e7d681fa", - "sha256:23778f5523461cf86ae075f9482a99317f362bca752ae57cb118044066f4026f" + "sha256:69805d6b69f56eb05b62daea3a7dbd7aa44324ad1306445e05da8060232d00f4", + "sha256:a8774e55b59fd9fc893b0d05e9bfc6f47081f46ff5b46f39ccf24631b7be356b" ], - "version": "==4.6" + "version": "==4.7" }, "six": { "hashes": [ @@ -277,37 +294,56 @@ }, "sqlalchemy": { "hashes": [ - "sha256:128bc917ed20d78143a45024455ff0aed7d3b96772eba13d5dbaf9cc57e5c41b", - "sha256:156a27548ba4e1fed944ff9fcdc150633e61d350d673ae7baaf6c25c04ac1f71", - "sha256:27e2efc8f77661c9af2681755974205e7462f1ae126f498f4fe12a8b24761d15", - "sha256:2a12f8be25b9ea3d1d5b165202181f2b7da4b3395289000284e5bb86154ce87c", - "sha256:31c043d5211aa0e0773821fcc318eb5cbe2ec916dfbc4c6eea0c5188971988eb", - "sha256:65eb3b03229f684af0cf0ad3bcc771970c1260a82a791a8d07bffb63d8c95bcc", - "sha256:6cd157ce74a911325e164441ff2d9b4e244659a25b3146310518d83202f15f7a", - "sha256:703c002277f0fbc3c04d0ae4989a174753a7554b2963c584ce2ec0cddcf2bc53", - "sha256:869bbb637de58ab0a912b7f20e9192132f9fbc47fc6b5111cd1e0f6cdf5cf9b0", - "sha256:8a0e0cd21da047ea10267c37caf12add400a92f0620c8bc09e4a6531a765d6d7", - "sha256:8d01e949a5d22e5c4800d59b50617c56125fc187fbeb8fa423e99858546de616", - "sha256:925b4fe5e7c03ed76912b75a9a41dfd682d59c0be43bce88d3b27f7f5ba028fb", - "sha256:9cb1819008f0225a7c066cac8bb0cf90847b2c4a6eb9ebb7431dbd00c56c06c5", - "sha256:a87d496884f40c94c85a647c385f4fd5887941d2609f71043e2b73f2436d9c65", - "sha256:a9030cd30caf848a13a192c5e45367e3c6f363726569a56e75dc1151ee26d859", - "sha256:a9e75e49a0f1583eee0ce93270232b8e7bb4b1edc89cc70b07600d525aef4f43", - "sha256:b50f45d0e82b4562f59f0e0ca511f65e412f2a97d790eea5f60e34e5f1aabc9a", - "sha256:b7878e59ec31f12d54b3797689402ee3b5cfcb5598f2ebf26491732758751908", - "sha256:ce1ddaadee913543ff0154021d31b134551f63428065168e756d90bdc4c686f5", - "sha256:ce2646e4c0807f3461be0653502bb48c6e91a5171d6e450367082c79e12868bf", - "sha256:ce6c3d18b2a8ce364013d47b9cad71db815df31d55918403f8db7d890c9d07ae", - "sha256:e4e2664232005bd306f878b0f167a31f944a07c4de0152c444f8c61bbe3cfb38", - "sha256:e8aa395482728de8bdcca9cc0faf3765ab483e81e01923aaa736b42f0294f570", - "sha256:eb4fcf7105bf071c71068c6eee47499ab8d4b8f5a11fc35147c934f0faa60f23", - "sha256:ed375a79f06cad285166e5be74745df1ed6845c5624aafadec4b7a29c25866ef", - "sha256:f35248f7e0d63b234a109dd72fbfb4b5cb6cb6840b221d0df0ecbf54ab087654", - "sha256:f502ef245c492b391e0e23e94cba030ab91722dcc56963c85bfd7f3441ea2bbe", - "sha256:fe01bac7226499aedf472c62fa3b85b2c619365f3f14dd222ffe4f3aa91e5f98" + "sha256:04f995fcbf54e46cddeb4f75ce9dfc17075d6ae04ac23b2bacb44b3bc6f6bf11", + "sha256:0c6406a78a714a540d980a680b86654feadb81c8d0eecb59f3d6c554a4c69f19", + "sha256:0c72b90988be749e04eff0342dcc98c18a14461eb4b2ad59d611b57b31120f90", + "sha256:108580808803c7732f34798eb4a329d45b04c562ed83ee90f09f6a184a42b766", + "sha256:1418f5e71d6081aa1095a1d6b567a562d2761996710bdce9b6e6ba20a03d0864", + "sha256:17610d573e698bf395afbbff946544fbce7c5f4ee77b5bcb1f821b36345fae7a", + "sha256:216ba5b4299c95ed179b58f298bda885a476b16288ab7243e89f29f6aeced7e0", + "sha256:2ff132a379838b1abf83c065be54cef32b47c987aedd06b82fc76476c85225eb", + "sha256:314f5042c0b047438e19401d5f29757a511cfc2f0c40d28047ca0e4c95eabb5b", + "sha256:318b5b727e00662e5fc4b4cd2bf58a5116d7c1b4dd56ffaa7d68f43458a8d1ed", + "sha256:3ab5b44a07b8c562c6dcb7433c6a6c6e03266d19d64f87b3333eda34e3b9936b", + "sha256:426ece890153ccc52cc5151a1a0ed540a5a7825414139bb4c95a868d8da54a52", + "sha256:491fe48adc07d13e020a8b07ef82eefc227003a046809c121bea81d3dbf1832d", + "sha256:4a84c7c7658dd22a33dab2e2aa2d17c18cb004a42388246f2e87cb4085ef2811", + "sha256:54da615e5b92c339e339fe8536cce99fe823b6ed505d4ea344852aefa1c205fb", + "sha256:5a7f224cdb7233182cec2a45d4c633951268d6a9bcedac37abbf79dd07012aea", + "sha256:61628715931f4962e0cdb2a7c87ff39eea320d2aa96bd471a3c293d146f90394", + "sha256:62285607a5264d1f91590abd874d6a498e229d5840669bd7d9f654cfaa599bd0", + "sha256:62fb881ba51dbacba9af9b779211cf9acff3442d4f2993142015b22b3cd1f92a", + "sha256:68428818cf80c60dc04aa0f38da20ad39b28aba4d4d199f949e7d6e04444ea86", + "sha256:6aaa13ee40c4552d5f3a59f543f0db6e31712cc4009ec7385407be4627259d41", + "sha256:70121f0ae48b25ef3e56e477b88cd0b0af0e1f3a53b5554071aa6a93ef378a03", + "sha256:715b34578cc740b743361f7c3e5f584b04b0f1344f45afc4e87fbac4802eb0a0", + "sha256:758fc8c4d6c0336e617f9f6919f9daea3ab6bb9b07005eda9a1a682e24a6cacc", + "sha256:7d4b8de6bb0bc736161cb0bbd95366b11b3eb24dd6b814a143d8375e75af9990", + "sha256:81d8d099a49f83111cce55ec03cc87eef45eec0d90f9842b4fc674f860b857b0", + "sha256:888d5b4b5aeed0d3449de93ea80173653e939e916cc95fe8527079e50235c1d2", + "sha256:95bde07d19c146d608bccb9b16e144ec8f139bcfe7fd72331858698a71c9b4f5", + "sha256:9bf572e4f5aa23f88dd902f10bb103cb5979022a38eec684bfa6d61851173fec", + "sha256:bab5a1e15b9466a25c96cda19139f3beb3e669794373b9ce28c4cf158c6e841d", + "sha256:bd4b1af45fd322dcd1fb2a9195b4f93f570d1a5902a842e3e6051385fac88f9c", + "sha256:bde677047305fe76c7ee3e4492b545e0018918e44141cc154fe39e124e433991", + "sha256:c389d7cc2b821853fb018c85457da3e7941db64f4387720a329bc7ff06a27963", + "sha256:d055ff750fcab69ca4e57b656d9c6ad33682e9b8d564f2fbe667ab95c63591b0", + "sha256:d53f59744b01f1440a1b0973ed2c3a7de204135c593299ee997828aad5191693", + "sha256:f115150cc4361dd46153302a640c7fa1804ac207f9cc356228248e351a8b4676", + "sha256:f1e88b30da8163215eab643962ae9d9252e47b4ea53404f2c4f10f24e70ddc62", + "sha256:f8191fef303025879e6c3548ecd8a95aafc0728c764ab72ec51a0bdf0c91a341" ], "index": "pypi", - "version": "==1.3.17" + "version": "==1.3.22" + }, + "typing-extensions": { + "hashes": [ + "sha256:7cb407020f00f7bfc3cb3e7881628838e69d8f3fcab2f64742a5e76b2f841918", + "sha256:99d4073b617d30288f569d3f13d2bd7548c3a7e4c8de87db09a9d29bb3a4a60c", + "sha256:dafc7639cde7f1b6e1acc0f457842a83e722ccca8eef5270af2d74792619a89f" + ], + "markers": "python_version < '3.8'", + "version": "==3.7.4.3" }, "werkzeug": { "hashes": [ @@ -315,6 +351,13 @@ "sha256:6c80b1e5ad3665290ea39320b91e1be1e0d5f60652b964a3070216de83d2e47c" ], "version": "==1.0.1" + }, + "zipp": { + "hashes": [ + "sha256:102c24ef8f171fd729d46599845e95c7ab894a4cf45f5de11a44cc7444fb1108", + "sha256:ed5eee1974372595f9e416cc7bbeeb12335201d8081ca8a0743c954d4446e5cb" + ], + "version": "==3.4.0" } }, "develop": {} From 8208c99194890ac755a1263d70389589cbde0a53 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 24 Jan 2021 17:10:34 -0800 Subject: [PATCH 083/206] remove unused packages --- Pipfile | 3 --- Pipfile.lock | 47 +---------------------------------------------- 2 files changed, 1 insertion(+), 49 deletions(-) diff --git a/Pipfile b/Pipfile index 82b79b5..8913cd2 100644 --- a/Pipfile +++ b/Pipfile @@ -6,11 +6,8 @@ verify_ssl = true [dev-packages] [packages] -python-dotenv = "*" -python-jose = "*" six = "*" mysql-connector = "~=2.2.9" -dnspython = "~=1.16.0" flasgger = "~=0.9.3" flask-marshmallow = "~=0.10.1" Flask = "~=1.1.1" diff --git a/Pipfile.lock b/Pipfile.lock index 9de14e4..ecd5598 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "549ce7d9250c958a65abd02cc1ea6be0c9adbb2315dfc759cd97739d90f98a44" + "sha256": "52c0d0f4ec62c0b7629a629102ad6d276968b3250023e56ceeb508ad17aa8bba" }, "pipfile-spec": 6, "requires": { @@ -49,21 +49,6 @@ ], "version": "==7.1.2" }, - "dnspython": { - "hashes": [ - "sha256:36c5e8e38d4369a08b6780b7f27d790a292b2b08eea01607865bf0936c558e01", - "sha256:f69c21288a962f4da86e56c4905b49d11aba7938d3d740e80d9e366ee4f1632d" - ], - "index": "pypi", - "version": "==1.16.0" - }, - "ecdsa": { - "hashes": [ - "sha256:64c613005f13efec6541bb0a33290d0d03c27abab5f15fbab20fb0ee162bdd8e", - "sha256:e108a5fe92c67639abae3260e43561af914e7fd0d27bae6d2ec1312ae7934dfe" - ], - "version": "==0.14.1" - }, "flasgger": { "hashes": [ "sha256:0603941cf4003626b4ee551ca87331f1d17b8eecce500ccf1a1f1d3a332fc94a", @@ -222,35 +207,12 @@ "index": "pypi", "version": "==2.2.9" }, - "pyasn1": { - "hashes": [ - "sha256:39c7e2ec30515947ff4e87fb6f456dfc6e84857d34be479c9d4a4ba4bf46aa5d", - "sha256:aef77c9fb94a3ac588e87841208bdec464471d9871bd5050a287cc9a475cd0ba" - ], - "version": "==0.4.8" - }, "pyrsistent": { "hashes": [ "sha256:2e636185d9eb976a18a8a8e96efce62f2905fea90041958d8cc2a189756ebf3e" ], "version": "==0.17.3" }, - "python-dotenv": { - "hashes": [ - "sha256:0c8d1b80d1a1e91717ea7d526178e3882732420b03f08afea0406db6402e220e", - "sha256:587825ed60b1711daea4832cf37524dfd404325b7db5e25ebe88c495c9f807a0" - ], - "index": "pypi", - "version": "==0.15.0" - }, - "python-jose": { - "hashes": [ - "sha256:4e4192402e100b5fb09de5a8ea6bcc39c36ad4526341c123d401e2561720335b", - "sha256:67d7dfff599df676b04a996520d9be90d6cdb7e6dd10b4c7cacc0c3e2e92f2be" - ], - "index": "pypi", - "version": "==3.2.0" - }, "pyyaml": { "hashes": [ "sha256:08682f6b72c722394747bddaf0aa62277e02557c0fd1c42cb853016a38f8dedf", @@ -277,13 +239,6 @@ ], "version": "==5.4.1" }, - "rsa": { - "hashes": [ - "sha256:69805d6b69f56eb05b62daea3a7dbd7aa44324ad1306445e05da8060232d00f4", - "sha256:a8774e55b59fd9fc893b0d05e9bfc6f47081f46ff5b46f39ccf24631b7be356b" - ], - "version": "==4.7" - }, "six": { "hashes": [ "sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259", From 9f4491d33f70c3cf4551decb12828000b6721a16 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 24 Jan 2021 17:12:54 -0800 Subject: [PATCH 084/206] version lock six --- Pipfile | 2 +- Pipfile.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Pipfile b/Pipfile index 8913cd2..59696a9 100644 --- a/Pipfile +++ b/Pipfile @@ -6,7 +6,7 @@ verify_ssl = true [dev-packages] [packages] -six = "*" +six = "~=1.12.0" mysql-connector = "~=2.2.9" flasgger = "~=0.9.3" flask-marshmallow = "~=0.10.1" diff --git a/Pipfile.lock b/Pipfile.lock index ecd5598..39d9ff8 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "52c0d0f4ec62c0b7629a629102ad6d276968b3250023e56ceeb508ad17aa8bba" + "sha256": "87d7b3d7fa7b933c9050f5cdb190b10b5345ebe11490e014ecbfc64701017988" }, "pipfile-spec": 6, "requires": { @@ -241,11 +241,11 @@ }, "six": { "hashes": [ - "sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259", - "sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced" + "sha256:3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c", + "sha256:d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73" ], "index": "pypi", - "version": "==1.15.0" + "version": "==1.12.0" }, "sqlalchemy": { "hashes": [ From 849a1fabe5bdc4f66131098f171aca60394ae58b Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 24 Jan 2021 17:20:04 -0800 Subject: [PATCH 085/206] replace depreceted dependency mysql-connector with mysql-connector-python --- Pipfile | 2 +- Pipfile.lock | 53 ++++++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 50 insertions(+), 5 deletions(-) diff --git a/Pipfile b/Pipfile index 59696a9..89bf18a 100644 --- a/Pipfile +++ b/Pipfile @@ -7,7 +7,6 @@ verify_ssl = true [packages] six = "~=1.12.0" -mysql-connector = "~=2.2.9" flasgger = "~=0.9.3" flask-marshmallow = "~=0.10.1" Flask = "~=1.1.1" @@ -19,6 +18,7 @@ flask-sqlalchemy = "~=2.4.1" marshmallow-sqlalchemy = "~=0.23" apispec = "~=3.3.0" apispec-webframeworks = "~=0.5.2" +mysql-connector-python = "*" [requires] python_version = "3.6" diff --git a/Pipfile.lock b/Pipfile.lock index 39d9ff8..eb456f4 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "87d7b3d7fa7b933c9050f5cdb190b10b5345ebe11490e014ecbfc64701017988" + "sha256": "3a9d45b89372a588975df40b2c35b7f2802d4206d3ccf149dedece5ebf38f4b2" }, "pipfile-spec": 6, "requires": { @@ -200,12 +200,57 @@ ], "version": "==0.8.4" }, - "mysql-connector": { + "mysql-connector-python": { "hashes": [ - "sha256:1733e6ce52a049243de3264f1fbc22a852cb35458c4ad739ba88189285efdf32" + "sha256:0f41b3142fe5325e830a3420915a6cf652b9da1d3a8e0df11bade1c120c0fc2c", + "sha256:114ab771b6a1a98ea1e2e88c44fcf3ff713c65ac9fa8d3e88c0034e1fc0aed5d", + "sha256:2184f6b86c3981e5b2ffa82e946f12368a5f1758f022d9a30f43077950136114", + "sha256:2833d47ad04d08c1d3ab64b3b2b9203f84333f3463ca99332961c0ae1bf8101f", + "sha256:2eabe3f8a264efb3af04cb477943a8c8f04396fda0c5e2ad3450f9c044ddc603", + "sha256:2ed23de6c0a9e5769fc14f2930492b81629cb40f79381d79c679ddd04d5f3ddb", + "sha256:320a5929a39cae75a1cf0603b3baffdd7f36a0e520bfdd471d456f70973fc0ac", + "sha256:451120a964d3c56d983c7664f7c799bd92d5660085e3d8058defdec3e8a3b93a", + "sha256:49394f30e792a880ca2bd6e7e9d11eb86df0c316ab629b6d19185c9f5ca0811d", + "sha256:5e84dcc25d4b505118e0c28f07de496a41bc0ab121232a2aba83d0248cd49257", + "sha256:76758ee1d57b712bfbdae358506d578b955fda9dd91ae068a59e0fe02138ef0d", + "sha256:7b7fa9ed17a43164df2e203b25bf71f8679460795c055fb23f64a66f7ecde6be", + "sha256:7d55a446700bec300ec6a5b928b4700384bc2add43fa3b9ca124b03640db4e19", + "sha256:a37dff9d748d92134ea47ddbaafdfadb7f3bf9c8a66429ae247fb1ccaf6f7337", + "sha256:a5bf1979c126f475bc10c840d9464d5a2e4604bdc67b6be8bbaf9dbc4a3d8b89", + "sha256:a63658c518502736979dc1a79250c5e54ebbbd5ccfe9ec040cc591fcefbf1974", + "sha256:aa2307ddc30dd20dbca1165ffb1cf41dcf30ae1bcf46e74cb92c06a0eeeb0aac", + "sha256:c783e1dc8b78a1b1a9ebbf3ccb12d17e4513d91fafeb5b6c06a29f2d5619e285", + "sha256:dd7ed6baa35c3a89c6c8c8d6be0ebe1b089e77f41bb874b9dc4bc6db83ad654f", + "sha256:eb5d409df6e54c9a8f47dc901334d5e8b30a7967775d6eb3158494bf0534995d", + "sha256:efe72ce5e9d9051aeb99a4910949b3afb17570106a980a7a4f480d3894b1f426", + "sha256:f42516ef6b80ce70322f1fda63a8762f898df60df8ba621b2308d933216a8598", + "sha256:faf2aeb18725bb8bb6aae1e33b358d328cd35ded1b610d4c8608529b3051f634" ], "index": "pypi", - "version": "==2.2.9" + "version": "==8.0.23" + }, + "protobuf": { + "hashes": [ + "sha256:0e247612fadda953047f53301a7b0407cb0c3cb4ae25a6fde661597a04039b3c", + "sha256:0fc96785262042e4863b3f3b5c429d4636f10d90061e1840fce1baaf59b1a836", + "sha256:1c51fda1bbc9634246e7be6016d860be01747354ed7015ebe38acf4452f470d2", + "sha256:1d63eb389347293d8915fb47bee0951c7b5dab522a4a60118b9a18f33e21f8ce", + "sha256:22bcd2e284b3b1d969c12e84dc9b9a71701ec82d8ce975fdda19712e1cfd4e00", + "sha256:2a7e2fe101a7ace75e9327b9c946d247749e564a267b0515cf41dfe450b69bac", + "sha256:43b554b9e73a07ba84ed6cf25db0ff88b1e06be610b37656e292e3cbb5437472", + "sha256:4b74301b30513b1a7494d3055d95c714b560fbb630d8fb9956b6f27992c9f980", + "sha256:4e75105c9dfe13719b7293f75bd53033108f4ba03d44e71db0ec2a0e8401eafd", + "sha256:5b7a637212cc9b2bcf85dd828b1178d19efdf74dbfe1ddf8cd1b8e01fdaaa7f5", + "sha256:5e9806a43232a1fa0c9cf5da8dc06f6910d53e4390be1fa06f06454d888a9142", + "sha256:629b03fd3caae7f815b0c66b41273f6b1900a579e2ccb41ef4493a4f5fb84f3a", + "sha256:72230ed56f026dd664c21d73c5db73ebba50d924d7ba6b7c0d81a121e390406e", + "sha256:86a75477addde4918e9a1904e5c6af8d7b691f2a3f65587d73b16100fbe4c3b2", + "sha256:8971c421dbd7aad930c9bd2694122f332350b6ccb5202a8b7b06f3f1a5c41ed5", + "sha256:9616f0b65a30851e62f1713336c931fcd32c057202b7ff2cfbfca0fc7d5e3043", + "sha256:b0d5d35faeb07e22a1ddf8dce620860c8fe145426c02d1a0ae2688c6e8ede36d", + "sha256:ecc33531a213eee22ad60e0e2aaea6c8ba0021f0cce35dbf0ab03dee6e2a23a1" + ], + "version": "==3.14.0" }, "pyrsistent": { "hashes": [ From 25f5e95c8c1419b39185b624698666f237402c54 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Mon, 1 Feb 2021 17:04:07 -0800 Subject: [PATCH 086/206] bump to python 3.8 and update dependencies --- Pipfile | 2 +- Pipfile.lock | 142 ++++++++++++++++++++++++++------------------------- 2 files changed, 74 insertions(+), 70 deletions(-) diff --git a/Pipfile b/Pipfile index 89bf18a..46e6b03 100644 --- a/Pipfile +++ b/Pipfile @@ -21,4 +21,4 @@ apispec-webframeworks = "~=0.5.2" mysql-connector-python = "*" [requires] -python_version = "3.6" +python_version = "3.8" diff --git a/Pipfile.lock b/Pipfile.lock index eb456f4..1a148eb 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,11 +1,11 @@ { "_meta": { "hash": { - "sha256": "3a9d45b89372a588975df40b2c35b7f2802d4206d3ccf149dedece5ebf38f4b2" + "sha256": "b93251493d161beb7d73afe36452848cfc5d9c310277fee26dafd71fd933def5" }, "pipfile-spec": 6, "requires": { - "python_version": "3.6" + "python_version": "3.8" }, "sources": [ { @@ -40,6 +40,7 @@ "sha256:31b2eced602aa8423c2aea9c76a724617ed67cf9513173fd3a4f03e3a929c7e6", "sha256:832aa3cde19744e49938b91fea06d69ecb9e649c93ba974535d08ad92164f700" ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==20.3.0" }, "click": { @@ -47,6 +48,7 @@ "sha256:d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a", "sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc" ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", "version": "==7.1.2" }, "flasgger": { @@ -75,6 +77,7 @@ }, "flask-limiter": { "hashes": [ + "sha256:473aa5bc97310406aa8c12ab3dc080697bcfa8cd21a6d0aba30916911bbc673c", "sha256:8cce98dcf25bf2ddbb824c2b503b4fc8e1a139154240fd2c60d9306bad8a0db8" ], "index": "pypi", @@ -104,27 +107,21 @@ "index": "pypi", "version": "==19.9.0" }, - "importlib-metadata": { - "hashes": [ - "sha256:ace61d5fc652dc280e7b6b4ff732a9c2d40db2c0f92bc6cb74e07b73d53a1771", - "sha256:fa5daa4477a7414ae34e95942e4dd07f62adf589143c875c133c1e53c4eff38d" - ], - "markers": "python_version < '3.8'", - "version": "==3.4.0" - }, "itsdangerous": { "hashes": [ "sha256:321b033d07f2a4136d3ec762eac9f16a10ccd60f53c0c91af90217ace7ba1f19", "sha256:b12271b2047cb23eeb98c8b5622e2e5c5e9abd9784a153e9d8ef9cb4dd09d749" ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==1.1.0" }, "jinja2": { "hashes": [ - "sha256:89aab215427ef59c34ad58735269eb58b1a5808103067f7bb9d5836c651b3bb0", - "sha256:f0a4641d3cf955324a89c04f3d94663aa4d638abe8f733ecd3582848e1c37035" + "sha256:03e47ad063331dd6a3f04a43eddca8a966a26ba0c5b7207a9a9e4e08f1b29419", + "sha256:a6d58433de0ae800347cab1fa3043cebbabe8baa9d29e668f1c768cb87a333c6" ], - "version": "==2.11.2" + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", + "version": "==2.11.3" }, "jsonschema": { "hashes": [ @@ -147,8 +144,12 @@ "sha256:09c4b7f37d6c648cb13f9230d847adf22f8171b1ccc4d5682398e77f40309235", "sha256:1027c282dad077d0bae18be6794e6b6b8c91d58ed8a8d89a89d59693b9131db5", "sha256:13d3144e1e340870b25e7b10b98d779608c02016d5184cfb9927a9f10c689f42", + "sha256:195d7d2c4fbb0ee8139a6cf67194f3973a6b3042d742ebe0a9ed36d8b6f0c07f", + "sha256:22c178a091fc6630d0d045bdb5992d2dfe14e3259760e713c490da5323866c39", "sha256:24982cc2533820871eba85ba648cd53d8623687ff11cbb805be4ff7b4c971aff", "sha256:29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b", + "sha256:2beec1e0de6924ea551859edb9e7679da6e4870d32cb766240ce17e0a0ba2014", + "sha256:3b8a6499709d29c2e2399569d96719a1b21dcd94410a586a18526b143ec8470f", "sha256:43a55c2930bbc139570ac2452adf3d70cdbb3cfe5912c71cdce1c2c6bbd9c5d1", "sha256:46c99d2de99945ec5cb54f23c8cd5689f6d7177305ebff350a58ce5f8de1669e", "sha256:500d4957e52ddc3351cabf489e79c91c17f6e0899158447047588650b5e69183", @@ -157,25 +158,41 @@ "sha256:62fe6c95e3ec8a7fad637b7f3d372c15ec1caa01ab47926cfdf7a75b40e0eac1", "sha256:6788b695d50a51edb699cb55e35487e430fa21f1ed838122d722e0ff0ac5ba15", "sha256:6dd73240d2af64df90aa7c4e7481e23825ea70af4b4922f8ede5b9e35f78a3b1", + "sha256:6f1e273a344928347c1290119b493a1f0303c52f5a5eae5f16d74f48c15d4a85", + "sha256:6fffc775d90dcc9aed1b89219549b329a9250d918fd0b8fa8d93d154918422e1", "sha256:717ba8fe3ae9cc0006d7c451f0bb265ee07739daf76355d06366154ee68d221e", "sha256:79855e1c5b8da654cf486b830bd42c06e8780cea587384cf6545b7d9ac013a0b", "sha256:7c1699dfe0cf8ff607dbdcc1e9b9af1755371f92a68f706051cc8c37d447c905", + "sha256:7fed13866cf14bba33e7176717346713881f56d9d2bcebab207f7a036f41b850", + "sha256:84dee80c15f1b560d55bcfe6d47b27d070b4681c699c572af2e3c7cc90a3b8e0", "sha256:88e5fcfb52ee7b911e8bb6d6aa2fd21fbecc674eadd44118a9cc3863f938e735", "sha256:8defac2f2ccd6805ebf65f5eeb132adcf2ab57aa11fdf4c0dd5169a004710e7d", + "sha256:98bae9582248d6cf62321dcb52aaf5d9adf0bad3b40582925ef7c7f0ed85fceb", "sha256:98c7086708b163d425c67c7a91bad6e466bb99d797aa64f965e9d25c12111a5e", "sha256:9add70b36c5666a2ed02b43b335fe19002ee5235efd4b8a89bfcf9005bebac0d", "sha256:9bf40443012702a1d2070043cb6291650a0841ece432556f784f004937f0f32c", + "sha256:a6a744282b7718a2a62d2ed9d993cad6f5f585605ad352c11de459f4108df0a1", + "sha256:acf08ac40292838b3cbbb06cfe9b2cb9ec78fce8baca31ddb87aaac2e2dc3bc2", "sha256:ade5e387d2ad0d7ebf59146cc00c8044acbd863725f887353a10df825fc8ae21", "sha256:b00c1de48212e4cc9603895652c5c410df699856a2853135b3967591e4beebc2", "sha256:b1282f8c00509d99fef04d8ba936b156d419be841854fe901d8ae224c59f0be5", + "sha256:b1dba4527182c95a0db8b6060cc98ac49b9e2f5e64320e2b56e47cb2831978c7", "sha256:b2051432115498d3562c084a49bba65d97cf251f5a331c64a12ee7e04dacc51b", + "sha256:b7d644ddb4dbd407d31ffb699f1d140bc35478da613b441c582aeb7c43838dd8", "sha256:ba59edeaa2fc6114428f1637ffff42da1e311e29382d81b339c1817d37ec93c6", + "sha256:bf5aa3cbcfdf57fa2ee9cd1822c862ef23037f5c832ad09cfea57fa846dec193", "sha256:c8716a48d94b06bb3b2524c2b77e055fb313aeb4ea620c8dd03a105574ba704f", + "sha256:caabedc8323f1e93231b52fc32bdcde6db817623d33e100708d9a68e1f53b26b", "sha256:cd5df75523866410809ca100dc9681e301e3c27567cf498077e8551b6d20e42f", "sha256:cdb132fc825c38e1aeec2c8aa9338310d29d337bebbd7baa06889d09a60a1fa2", + "sha256:d53bc011414228441014aa71dbec320c66468c1030aae3a6e29778a3382d96e5", + "sha256:d73a845f227b0bfe8a7455ee623525ee656a9e2e749e4742706d80a6065d5e2c", + "sha256:d9be0ba6c527163cbed5e0857c451fcd092ce83947944d6c14bc95441203f032", "sha256:e249096428b3ae81b08327a63a485ad0878de3fb939049038579ac0ef61e17e7", - "sha256:e8313f01ba26fbbe36c7be1966a7b7424942f670f38e666995b88d012765b9be" + "sha256:e8313f01ba26fbbe36c7be1966a7b7424942f670f38e666995b88d012765b9be", + "sha256:feb7b34d6325451ef96bc0e36e1a6c0c1c64bc1fbec4b854f4529e51887b1621" ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==1.1.1" }, "marshmallow": { @@ -183,6 +200,7 @@ "sha256:4ab2fdb7f36eb61c3665da67a7ce281c8900db08d72ba6bf0e695828253581f7", "sha256:eca81d53aa4aafbc0e20566973d0d2e50ce8bf0ee15165bb799bec0df1e50177" ], + "markers": "python_version >= '3.5'", "version": "==3.10.0" }, "marshmallow-sqlalchemy": { @@ -256,6 +274,7 @@ "hashes": [ "sha256:2e636185d9eb976a18a8a8e96efce62f2905fea90041958d8cc2a189756ebf3e" ], + "markers": "python_version >= '3.5'", "version": "==0.17.3" }, "pyyaml": { @@ -294,70 +313,55 @@ }, "sqlalchemy": { "hashes": [ - "sha256:04f995fcbf54e46cddeb4f75ce9dfc17075d6ae04ac23b2bacb44b3bc6f6bf11", - "sha256:0c6406a78a714a540d980a680b86654feadb81c8d0eecb59f3d6c554a4c69f19", - "sha256:0c72b90988be749e04eff0342dcc98c18a14461eb4b2ad59d611b57b31120f90", - "sha256:108580808803c7732f34798eb4a329d45b04c562ed83ee90f09f6a184a42b766", - "sha256:1418f5e71d6081aa1095a1d6b567a562d2761996710bdce9b6e6ba20a03d0864", - "sha256:17610d573e698bf395afbbff946544fbce7c5f4ee77b5bcb1f821b36345fae7a", - "sha256:216ba5b4299c95ed179b58f298bda885a476b16288ab7243e89f29f6aeced7e0", - "sha256:2ff132a379838b1abf83c065be54cef32b47c987aedd06b82fc76476c85225eb", - "sha256:314f5042c0b047438e19401d5f29757a511cfc2f0c40d28047ca0e4c95eabb5b", - "sha256:318b5b727e00662e5fc4b4cd2bf58a5116d7c1b4dd56ffaa7d68f43458a8d1ed", - "sha256:3ab5b44a07b8c562c6dcb7433c6a6c6e03266d19d64f87b3333eda34e3b9936b", - "sha256:426ece890153ccc52cc5151a1a0ed540a5a7825414139bb4c95a868d8da54a52", - "sha256:491fe48adc07d13e020a8b07ef82eefc227003a046809c121bea81d3dbf1832d", - "sha256:4a84c7c7658dd22a33dab2e2aa2d17c18cb004a42388246f2e87cb4085ef2811", - "sha256:54da615e5b92c339e339fe8536cce99fe823b6ed505d4ea344852aefa1c205fb", - "sha256:5a7f224cdb7233182cec2a45d4c633951268d6a9bcedac37abbf79dd07012aea", - "sha256:61628715931f4962e0cdb2a7c87ff39eea320d2aa96bd471a3c293d146f90394", - "sha256:62285607a5264d1f91590abd874d6a498e229d5840669bd7d9f654cfaa599bd0", - "sha256:62fb881ba51dbacba9af9b779211cf9acff3442d4f2993142015b22b3cd1f92a", - "sha256:68428818cf80c60dc04aa0f38da20ad39b28aba4d4d199f949e7d6e04444ea86", - "sha256:6aaa13ee40c4552d5f3a59f543f0db6e31712cc4009ec7385407be4627259d41", - "sha256:70121f0ae48b25ef3e56e477b88cd0b0af0e1f3a53b5554071aa6a93ef378a03", - "sha256:715b34578cc740b743361f7c3e5f584b04b0f1344f45afc4e87fbac4802eb0a0", - "sha256:758fc8c4d6c0336e617f9f6919f9daea3ab6bb9b07005eda9a1a682e24a6cacc", - "sha256:7d4b8de6bb0bc736161cb0bbd95366b11b3eb24dd6b814a143d8375e75af9990", - "sha256:81d8d099a49f83111cce55ec03cc87eef45eec0d90f9842b4fc674f860b857b0", - "sha256:888d5b4b5aeed0d3449de93ea80173653e939e916cc95fe8527079e50235c1d2", - "sha256:95bde07d19c146d608bccb9b16e144ec8f139bcfe7fd72331858698a71c9b4f5", - "sha256:9bf572e4f5aa23f88dd902f10bb103cb5979022a38eec684bfa6d61851173fec", - "sha256:bab5a1e15b9466a25c96cda19139f3beb3e669794373b9ce28c4cf158c6e841d", - "sha256:bd4b1af45fd322dcd1fb2a9195b4f93f570d1a5902a842e3e6051385fac88f9c", - "sha256:bde677047305fe76c7ee3e4492b545e0018918e44141cc154fe39e124e433991", - "sha256:c389d7cc2b821853fb018c85457da3e7941db64f4387720a329bc7ff06a27963", - "sha256:d055ff750fcab69ca4e57b656d9c6ad33682e9b8d564f2fbe667ab95c63591b0", - "sha256:d53f59744b01f1440a1b0973ed2c3a7de204135c593299ee997828aad5191693", - "sha256:f115150cc4361dd46153302a640c7fa1804ac207f9cc356228248e351a8b4676", - "sha256:f1e88b30da8163215eab643962ae9d9252e47b4ea53404f2c4f10f24e70ddc62", - "sha256:f8191fef303025879e6c3548ecd8a95aafc0728c764ab72ec51a0bdf0c91a341" + "sha256:040bdfc1d76a9074717a3f43455685f781c581f94472b010cd6c4754754e1862", + "sha256:1fe5d8d39118c2b018c215c37b73fd6893c3e1d4895be745ca8ff6eb83333ed3", + "sha256:23927c3981d1ec6b4ea71eb99d28424b874d9c696a21e5fbd9fa322718be3708", + "sha256:24f9569e82a009a09ce2d263559acb3466eba2617203170e4a0af91e75b4f075", + "sha256:2578dbdbe4dbb0e5126fb37ffcd9793a25dcad769a95f171a2161030bea850ff", + "sha256:269990b3ab53cb035d662dcde51df0943c1417bdab707dc4a7e4114a710504b4", + "sha256:29cccc9606750fe10c5d0e8bd847f17a97f3850b8682aef1f56f5d5e1a5a64b1", + "sha256:37b83bf81b4b85dda273aaaed5f35ea20ad80606f672d94d2218afc565fb0173", + "sha256:63677d0c08524af4c5893c18dbe42141de7178001360b3de0b86217502ed3601", + "sha256:639940bbe1108ac667dcffc79925db2966826c270112e9159439ab6bb14f8d80", + "sha256:6a939a868fdaa4b504e8b9d4a61f21aac11e3fecc8a8214455e144939e3d2aea", + "sha256:6b8b8c80c7f384f06825612dd078e4a31f0185e8f1f6b8c19e188ff246334205", + "sha256:6c9e6cc9237de5660bcddea63f332428bb83c8e2015c26777281f7ffbd2efb84", + "sha256:6ec1044908414013ebfe363450c22f14698803ce97fbb47e53284d55c5165848", + "sha256:6fca33672578666f657c131552c4ef8979c1606e494f78cd5199742dfb26918b", + "sha256:751934967f5336a3e26fc5993ccad1e4fee982029f9317eb6153bc0bc3d2d2da", + "sha256:8be835aac18ec85351385e17b8665bd4d63083a7160a017bef3d640e8e65cadb", + "sha256:927ce09e49bff3104459e1451ce82983b0a3062437a07d883a4c66f0b344c9b5", + "sha256:94208867f34e60f54a33a37f1c117251be91a47e3bfdb9ab8a7847f20886ad06", + "sha256:94f667d86be82dd4cb17d08de0c3622e77ca865320e0b95eae6153faa7b4ecaf", + "sha256:9e9c25522933e569e8b53ccc644dc993cab87e922fb7e142894653880fdd419d", + "sha256:a0e306e9bb76fd93b29ae3a5155298e4c1b504c7cbc620c09c20858d32d16234", + "sha256:a8bfc1e1afe523e94974132d7230b82ca7fa2511aedde1f537ec54db0399541a", + "sha256:ac2244e64485c3778f012951fdc869969a736cd61375fde6096d08850d8be729", + "sha256:b4b0e44d586cd64b65b507fa116a3814a1a53d55dce4836d7c1a6eb2823ff8d1", + "sha256:baeb451ee23e264de3f577fee5283c73d9bbaa8cb921d0305c0bbf700094b65b", + "sha256:c7dc052432cd5d060d7437e217dd33c97025287f99a69a50e2dc1478dd610d64", + "sha256:d1a85dfc5dee741bf49cb9b6b6b8d2725a268e4992507cf151cba26b17d97c37", + "sha256:d90010304abb4102123d10cbad2cdf2c25a9f2e66a50974199b24b468509bad5", + "sha256:ddfb511e76d016c3a160910642d57f4587dc542ce5ee823b0d415134790eeeb9", + "sha256:e273367f4076bd7b9a8dc2e771978ef2bfd6b82526e80775a7db52bff8ca01dd", + "sha256:e5bb3463df697279e5459a7316ad5a60b04b0107f9392e88674d0ece70e9cf70", + "sha256:e8a1750b44ad6422ace82bf3466638f1aa0862dbb9689690d5f2f48cce3476c8", + "sha256:eab063a70cca4a587c28824e18be41d8ecc4457f8f15b2933584c6c6cccd30f0", + "sha256:ecce8c021894a77d89808222b1ff9687ad84db54d18e4bd0500ca766737faaf6", + "sha256:f4d972139d5000105fcda9539a76452039434013570d6059993120dc2a65e447", + "sha256:fd3b96f8c705af8e938eaa99cbd8fd1450f632d38cad55e7367c33b263bf98ec", + "sha256:fdd2ed7395df8ac2dbb10cefc44737b66c6a5cd7755c92524733d7a443e5b7e2" ], "index": "pypi", - "version": "==1.3.22" - }, - "typing-extensions": { - "hashes": [ - "sha256:7cb407020f00f7bfc3cb3e7881628838e69d8f3fcab2f64742a5e76b2f841918", - "sha256:99d4073b617d30288f569d3f13d2bd7548c3a7e4c8de87db09a9d29bb3a4a60c", - "sha256:dafc7639cde7f1b6e1acc0f457842a83e722ccca8eef5270af2d74792619a89f" - ], - "markers": "python_version < '3.8'", - "version": "==3.7.4.3" + "version": "==1.3.23" }, "werkzeug": { "hashes": [ "sha256:2de2a5db0baeae7b2d2664949077c2ac63fbd16d98da0ff71837f7d1dea3fd43", "sha256:6c80b1e5ad3665290ea39320b91e1be1e0d5f60652b964a3070216de83d2e47c" ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", "version": "==1.0.1" - }, - "zipp": { - "hashes": [ - "sha256:102c24ef8f171fd729d46599845e95c7ab894a4cf45f5de11a44cc7444fb1108", - "sha256:ed5eee1974372595f9e416cc7bbeeb12335201d8081ca8a0743c954d4446e5cb" - ], - "version": "==3.4.0" } }, "develop": {} From 066d2e336b17e3d63e03e8cefb71ec77cd3302b5 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Mon, 1 Feb 2021 17:22:42 -0800 Subject: [PATCH 087/206] oops apparrently jose was necessary after all --- Pipfile | 1 + Pipfile.lock | 44 +++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/Pipfile b/Pipfile index 46e6b03..5b7fcd4 100644 --- a/Pipfile +++ b/Pipfile @@ -19,6 +19,7 @@ marshmallow-sqlalchemy = "~=0.23" apispec = "~=3.3.0" apispec-webframeworks = "~=0.5.2" mysql-connector-python = "*" +python-jose = "*" [requires] python_version = "3.8" diff --git a/Pipfile.lock b/Pipfile.lock index 1a148eb..0539042 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "b93251493d161beb7d73afe36452848cfc5d9c310277fee26dafd71fd933def5" + "sha256": "33e8bcf3cfa282ec1216b09f8113cb15ecd0db28c79624d68c3278f2637cb67d" }, "pipfile-spec": 6, "requires": { @@ -51,6 +51,14 @@ "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", "version": "==7.1.2" }, + "ecdsa": { + "hashes": [ + "sha256:64c613005f13efec6541bb0a33290d0d03c27abab5f15fbab20fb0ee162bdd8e", + "sha256:e108a5fe92c67639abae3260e43561af914e7fd0d27bae6d2ec1312ae7934dfe" + ], + "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==0.14.1" + }, "flasgger": { "hashes": [ "sha256:0603941cf4003626b4ee551ca87331f1d17b8eecce500ccf1a1f1d3a332fc94a", @@ -270,6 +278,24 @@ ], "version": "==3.14.0" }, + "pyasn1": { + "hashes": [ + "sha256:014c0e9976956a08139dc0712ae195324a75e142284d5f87f1a87ee1b068a359", + "sha256:03840c999ba71680a131cfaee6fab142e1ed9bbd9c693e285cc6aca0d555e576", + "sha256:0458773cfe65b153891ac249bcf1b5f8f320b7c2ce462151f8fa74de8934becf", + "sha256:08c3c53b75eaa48d71cf8c710312316392ed40899cb34710d092e96745a358b7", + "sha256:39c7e2ec30515947ff4e87fb6f456dfc6e84857d34be479c9d4a4ba4bf46aa5d", + "sha256:5c9414dcfede6e441f7e8f81b43b34e834731003427e5b09e4e00e3172a10f00", + "sha256:6e7545f1a61025a4e58bb336952c5061697da694db1cae97b116e9c46abcf7c8", + "sha256:78fa6da68ed2727915c4767bb386ab32cdba863caa7dbe473eaae45f9959da86", + "sha256:7ab8a544af125fb704feadb008c99a88805126fb525280b2270bb25cc1d78a12", + "sha256:99fcc3c8d804d1bc6d9a099921e39d827026409a58f2a720dcdb89374ea0c776", + "sha256:aef77c9fb94a3ac588e87841208bdec464471d9871bd5050a287cc9a475cd0ba", + "sha256:e89bf84b5437b532b0803ba5c9a5e054d21fec423a89952a74f87fa2c9b7bce2", + "sha256:fec3e9d8e36808a28efb59b489e4528c10ad0f480e57dcc32b4de5c9d8c9fdf3" + ], + "version": "==0.4.8" + }, "pyrsistent": { "hashes": [ "sha256:2e636185d9eb976a18a8a8e96efce62f2905fea90041958d8cc2a189756ebf3e" @@ -277,6 +303,14 @@ "markers": "python_version >= '3.5'", "version": "==0.17.3" }, + "python-jose": { + "hashes": [ + "sha256:4e4192402e100b5fb09de5a8ea6bcc39c36ad4526341c123d401e2561720335b", + "sha256:67d7dfff599df676b04a996520d9be90d6cdb7e6dd10b4c7cacc0c3e2e92f2be" + ], + "index": "pypi", + "version": "==3.2.0" + }, "pyyaml": { "hashes": [ "sha256:08682f6b72c722394747bddaf0aa62277e02557c0fd1c42cb853016a38f8dedf", @@ -303,6 +337,14 @@ ], "version": "==5.4.1" }, + "rsa": { + "hashes": [ + "sha256:69805d6b69f56eb05b62daea3a7dbd7aa44324ad1306445e05da8060232d00f4", + "sha256:a8774e55b59fd9fc893b0d05e9bfc6f47081f46ff5b46f39ccf24631b7be356b" + ], + "markers": "python_version >= '3.5' and python_version < '4'", + "version": "==4.7" + }, "six": { "hashes": [ "sha256:3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c", From 61a8505c79677bd71a35c95e427fbdfb4ab34b28 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Wed, 10 Feb 2021 19:31:13 -0800 Subject: [PATCH 088/206] lock mysql-connector-python to version 8.0.12 closing connections from the connection pool was crashing the app. see https://stackoverflow.com/a/59539260 --- Pipfile | 2 +- Pipfile.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Pipfile b/Pipfile index 5b7fcd4..9bfc5d0 100644 --- a/Pipfile +++ b/Pipfile @@ -18,7 +18,7 @@ flask-sqlalchemy = "~=2.4.1" marshmallow-sqlalchemy = "~=0.23" apispec = "~=3.3.0" apispec-webframeworks = "~=0.5.2" -mysql-connector-python = "*" +mysql-connector-python = "8.0.12" python-jose = "*" [requires] diff --git a/Pipfile.lock b/Pipfile.lock index 0539042..6b7ae6c 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "33e8bcf3cfa282ec1216b09f8113cb15ecd0db28c79624d68c3278f2637cb67d" + "sha256": "3dbd4f805e11223de7a5d4e40c5266d4e0560004e9f52a58c2b5294197844eab" }, "pipfile-spec": 6, "requires": { @@ -213,11 +213,11 @@ }, "marshmallow-sqlalchemy": { "hashes": [ - "sha256:93f47b880ac7070f7b34c8ac0a71eeec3f8582a22e5c0330c1c436e3f5f99a37", - "sha256:d051cf013c075c43e1ee5c4b01f8fab6dd6b140dab6825be45875f674a0d289c" + "sha256:b217c6327bcf291e843dc1c2c20f0915061d4ecc303f0c5be40f23206607f702", + "sha256:ee3ead3b83de6608c6850ff60515691b0dc556ca226680f8a82b9f785cdb71b1" ], "index": "pypi", - "version": "==0.24.1" + "version": "==0.24.2" }, "mistune": { "hashes": [ From c51f058ff687264961f3e3811681f1b5ad3014f4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 24 Mar 2021 19:19:18 +0000 Subject: [PATCH 089/206] Bump rsa from 4.0 to 4.1 Bumps [rsa](https://github.com/sybrenstuvel/python-rsa) from 4.0 to 4.1. - [Release notes](https://github.com/sybrenstuvel/python-rsa/releases) - [Changelog](https://github.com/sybrenstuvel/python-rsa/blob/main/CHANGELOG.md) - [Commits](https://github.com/sybrenstuvel/python-rsa/compare/version-4.0...version-4.1) Signed-off-by: dependabot[bot] --- Pipfile.lock | 154 ++++++++++++++++++++++++++++++--------------------- 1 file changed, 91 insertions(+), 63 deletions(-) diff --git a/Pipfile.lock b/Pipfile.lock index 2801259..51b1b75 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -18,24 +18,17 @@ "default": { "aniso8601": { "hashes": [ - "sha256:513d2b6637b7853806ae79ffaca6f3e8754bdd547048f5ccc1420aec4b714f1e", - "sha256:d10a4bf949f619f719b227ef5386e31f49a2b6d453004b21f02661ccc8670c7b" + "sha256:1d2b7ef82963909e93c4f24ce48d4de9e66009a21bf1c1e1c85bdd0812fe412f", + "sha256:72e3117667eedf66951bb2d93f4296a56b94b078a8a95905a052611fb3f1b973" ], - "version": "==7.0.0" - }, - "attrs": { - "hashes": [ - "sha256:69c0dbf2ed392de1cb5ec704444b08a5ef81680a61cb899dc08127123af36a79", - "sha256:f0b870f674851ecbfbbbd364d6b5cbdff9dcedbc7f3f5e18a6891057f21fe399" - ], - "version": "==19.1.0" + "version": "==9.0.1" }, "click": { "hashes": [ - "sha256:2335065e6395b9e67ca716de5f7526736bfa6ceead690adf616d925bdc622b13", - "sha256:5b94b49521f6456670fdb30cd82a4eca9412788a93fa6dd6df72c94d5a8ff2d7" + "sha256:d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a", + "sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc" ], - "version": "==7.0" + "version": "==7.1.2" }, "dnspython": { "hashes": [ @@ -47,10 +40,10 @@ }, "ecdsa": { "hashes": [ - "sha256:20c17e527e75acad8f402290e158a6ac178b91b881f941fc6ea305bfdfb9657c", - "sha256:5c034ffa23413ac923541ceb3ac14ec15a0d2530690413bff58c12b80e56d884" + "sha256:881fa5e12bb992972d3d1b3d4dfbe149ab76a89f13da02daa5ea1ec7dea6e747", + "sha256:cfc046a2ddd425adbd1a78b3c46f0d1325c657811c0f45ecc3a0a6236c1e50ff" ], - "version": "==0.13.2" + "version": "==0.16.1" }, "flasgger": { "hashes": [ @@ -101,9 +94,9 @@ }, "future": { "hashes": [ - "sha256:67045236dcfd6816dc439556d009594abf643e5eb48992e36beac09c2ca659b8" + "sha256:b1bead90b70cf6ec3f0710ae53a525360fa360d306a86583adc6bf83a4db537d" ], - "version": "==0.17.1" + "version": "==0.18.2" }, "gunicorn": { "hashes": [ @@ -122,24 +115,24 @@ }, "jinja2": { "hashes": [ - "sha256:065c4f02ebe7f7cf559e49ee5a95fb800a9e4528727aec6f24402a5374c65013", - "sha256:14dd6caf1527abb21f08f86c784eac40853ba93edb79552aa1e4b8aef1b61c7b" + "sha256:03e47ad063331dd6a3f04a43eddca8a966a26ba0c5b7207a9a9e4e08f1b29419", + "sha256:a6d58433de0ae800347cab1fa3043cebbabe8baa9d29e668f1c768cb87a333c6" ], - "version": "==2.10.1" + "version": "==2.11.3" }, "jsonschema": { "hashes": [ - "sha256:5f9c0a719ca2ce14c5de2fd350a64fd2d13e8539db29836a86adc990bb1a068f", - "sha256:8d4a2b7b6c2237e0199c8ea1a6d3e05bf118e289ae2b9d7ba444182a2959560d" + "sha256:000e68abd33c972a5248544925a0cae7d1125f9bf6c58280d37546b946769a08", + "sha256:6ff5f3180870836cae40f06fa10419f557208175f13ad7bc26caa77beb1f6e02" ], - "version": "==3.0.2" + "version": "==2.6.0" }, "limits": { "hashes": [ - "sha256:9df578f4161017d79f5188609f1d65f6b639f8aad2914c3960c9252e56a0ff95", - "sha256:a017b8d9e9da6761f4574642149c337f8f540d4edfe573fb91ad2c4001a2bc76" + "sha256:0e5f8b10f18dd809eb2342f5046eb9aa5e4e69a0258567b5f4aa270647d438b3", + "sha256:f0c3319f032c4bfad68438ed1325c0fac86dac64582c7c25cddc87a0b658fa20" ], - "version": "==1.3" + "version": "==1.5.1" }, "markupsafe": { "hashes": [ @@ -147,39 +140,63 @@ "sha256:09027a7803a62ca78792ad89403b1b7a73a01c8cb65909cd876f7fcebd79b161", "sha256:09c4b7f37d6c648cb13f9230d847adf22f8171b1ccc4d5682398e77f40309235", "sha256:1027c282dad077d0bae18be6794e6b6b8c91d58ed8a8d89a89d59693b9131db5", + "sha256:13d3144e1e340870b25e7b10b98d779608c02016d5184cfb9927a9f10c689f42", + "sha256:195d7d2c4fbb0ee8139a6cf67194f3973a6b3042d742ebe0a9ed36d8b6f0c07f", + "sha256:22c178a091fc6630d0d045bdb5992d2dfe14e3259760e713c490da5323866c39", "sha256:24982cc2533820871eba85ba648cd53d8623687ff11cbb805be4ff7b4c971aff", "sha256:29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b", + "sha256:2beec1e0de6924ea551859edb9e7679da6e4870d32cb766240ce17e0a0ba2014", + "sha256:3b8a6499709d29c2e2399569d96719a1b21dcd94410a586a18526b143ec8470f", "sha256:43a55c2930bbc139570ac2452adf3d70cdbb3cfe5912c71cdce1c2c6bbd9c5d1", "sha256:46c99d2de99945ec5cb54f23c8cd5689f6d7177305ebff350a58ce5f8de1669e", "sha256:500d4957e52ddc3351cabf489e79c91c17f6e0899158447047588650b5e69183", "sha256:535f6fc4d397c1563d08b88e485c3496cf5784e927af890fb3c3aac7f933ec66", + "sha256:596510de112c685489095da617b5bcbbac7dd6384aeebeda4df6025d0256a81b", "sha256:62fe6c95e3ec8a7fad637b7f3d372c15ec1caa01ab47926cfdf7a75b40e0eac1", + "sha256:6788b695d50a51edb699cb55e35487e430fa21f1ed838122d722e0ff0ac5ba15", "sha256:6dd73240d2af64df90aa7c4e7481e23825ea70af4b4922f8ede5b9e35f78a3b1", + "sha256:6f1e273a344928347c1290119b493a1f0303c52f5a5eae5f16d74f48c15d4a85", + "sha256:6fffc775d90dcc9aed1b89219549b329a9250d918fd0b8fa8d93d154918422e1", "sha256:717ba8fe3ae9cc0006d7c451f0bb265ee07739daf76355d06366154ee68d221e", "sha256:79855e1c5b8da654cf486b830bd42c06e8780cea587384cf6545b7d9ac013a0b", "sha256:7c1699dfe0cf8ff607dbdcc1e9b9af1755371f92a68f706051cc8c37d447c905", + "sha256:7fed13866cf14bba33e7176717346713881f56d9d2bcebab207f7a036f41b850", + "sha256:84dee80c15f1b560d55bcfe6d47b27d070b4681c699c572af2e3c7cc90a3b8e0", "sha256:88e5fcfb52ee7b911e8bb6d6aa2fd21fbecc674eadd44118a9cc3863f938e735", "sha256:8defac2f2ccd6805ebf65f5eeb132adcf2ab57aa11fdf4c0dd5169a004710e7d", + "sha256:98bae9582248d6cf62321dcb52aaf5d9adf0bad3b40582925ef7c7f0ed85fceb", "sha256:98c7086708b163d425c67c7a91bad6e466bb99d797aa64f965e9d25c12111a5e", "sha256:9add70b36c5666a2ed02b43b335fe19002ee5235efd4b8a89bfcf9005bebac0d", "sha256:9bf40443012702a1d2070043cb6291650a0841ece432556f784f004937f0f32c", + "sha256:a6a744282b7718a2a62d2ed9d993cad6f5f585605ad352c11de459f4108df0a1", + "sha256:acf08ac40292838b3cbbb06cfe9b2cb9ec78fce8baca31ddb87aaac2e2dc3bc2", "sha256:ade5e387d2ad0d7ebf59146cc00c8044acbd863725f887353a10df825fc8ae21", "sha256:b00c1de48212e4cc9603895652c5c410df699856a2853135b3967591e4beebc2", "sha256:b1282f8c00509d99fef04d8ba936b156d419be841854fe901d8ae224c59f0be5", + "sha256:b1dba4527182c95a0db8b6060cc98ac49b9e2f5e64320e2b56e47cb2831978c7", "sha256:b2051432115498d3562c084a49bba65d97cf251f5a331c64a12ee7e04dacc51b", + "sha256:b7d644ddb4dbd407d31ffb699f1d140bc35478da613b441c582aeb7c43838dd8", "sha256:ba59edeaa2fc6114428f1637ffff42da1e311e29382d81b339c1817d37ec93c6", + "sha256:bf5aa3cbcfdf57fa2ee9cd1822c862ef23037f5c832ad09cfea57fa846dec193", "sha256:c8716a48d94b06bb3b2524c2b77e055fb313aeb4ea620c8dd03a105574ba704f", + "sha256:caabedc8323f1e93231b52fc32bdcde6db817623d33e100708d9a68e1f53b26b", "sha256:cd5df75523866410809ca100dc9681e301e3c27567cf498077e8551b6d20e42f", - "sha256:e249096428b3ae81b08327a63a485ad0878de3fb939049038579ac0ef61e17e7" + "sha256:cdb132fc825c38e1aeec2c8aa9338310d29d337bebbd7baa06889d09a60a1fa2", + "sha256:d53bc011414228441014aa71dbec320c66468c1030aae3a6e29778a3382d96e5", + "sha256:d73a845f227b0bfe8a7455ee623525ee656a9e2e749e4742706d80a6065d5e2c", + "sha256:d9be0ba6c527163cbed5e0857c451fcd092ce83947944d6c14bc95441203f032", + "sha256:e249096428b3ae81b08327a63a485ad0878de3fb939049038579ac0ef61e17e7", + "sha256:e8313f01ba26fbbe36c7be1966a7b7424942f670f38e666995b88d012765b9be", + "sha256:feb7b34d6325451ef96bc0e36e1a6c0c1c64bc1fbec4b854f4529e51887b1621" ], "version": "==1.1.1" }, "marshmallow": { "hashes": [ - "sha256:23f684b54b1955ebd5bdfbdda4062e438ef86218f14f1a356f570cdf0c016ab3", - "sha256:fcfc9ffd75a883da06f30f604a4e81dd0b56eb9438f4d0a8de6bbaa163ce9ec3" + "sha256:4ab2fdb7f36eb61c3665da67a7ce281c8900db08d72ba6bf0e695828253581f7", + "sha256:eca81d53aa4aafbc0e20566973d0d2e50ce8bf0ee15165bb799bec0df1e50177" ], - "version": "==3.0.1" + "version": "==3.10.0" }, "mistune": { "hashes": [ @@ -197,16 +214,10 @@ }, "pyasn1": { "hashes": [ - "sha256:3bb81821d47b17146049e7574ab4bf1e315eb7aead30efe5d6a9ca422c9710be", - "sha256:b773d5c9196ffbc3a1e13bdf909d446cad80a039aa3340bcad72f395b76ebc86" + "sha256:39c7e2ec30515947ff4e87fb6f456dfc6e84857d34be479c9d4a4ba4bf46aa5d", + "sha256:aef77c9fb94a3ac588e87841208bdec464471d9871bd5050a287cc9a475cd0ba" ], - "version": "==0.4.6" - }, - "pyrsistent": { - "hashes": [ - "sha256:34b47fa169d6006b32e99d4b3c4031f155e6e68ebcc107d6454852e8e0ee6533" - ], - "version": "==0.15.4" + "version": "==0.4.8" }, "python-dotenv": { "hashes": [ @@ -226,35 +237,52 @@ }, "pytz": { "hashes": [ - "sha256:26c0b32e437e54a18161324a2fca3c4b9846b74a8dccddd843113109e1116b32", - "sha256:c894d57500a4cd2d5c71114aaab77dbab5eabd9022308ce5ac9bb93a60a6f0c7" + "sha256:83a4a90894bf38e243cf052c8b58f381bfe9a7a483f6a9cab140bc7f702ac4da", + "sha256:eb10ce3e7736052ed3623d49975ce333bcd712c7bb19a58b9e2089d4057d0798" ], - "version": "==2019.2" + "version": "==2021.1" }, "pyyaml": { "hashes": [ - "sha256:0113bc0ec2ad727182326b61326afa3d1d8280ae1122493553fd6f4397f33df9", - "sha256:01adf0b6c6f61bd11af6e10ca52b7d4057dd0be0343eb9283c878cf3af56aee4", - "sha256:5124373960b0b3f4aa7df1707e63e9f109b5263eca5976c66e08b1c552d4eaf8", - "sha256:5ca4f10adbddae56d824b2c09668e91219bb178a1eee1faa56af6f99f11bf696", - "sha256:7907be34ffa3c5a32b60b95f4d95ea25361c951383a894fec31be7252b2b6f34", - "sha256:7ec9b2a4ed5cad025c2278a1e6a19c011c80a3caaac804fd2d329e9cc2c287c9", - "sha256:87ae4c829bb25b9fe99cf71fbb2140c448f534e24c998cc60f39ae4f94396a73", - "sha256:9de9919becc9cc2ff03637872a440195ac4241c80536632fffeb6a1e25a74299", - "sha256:a5a85b10e450c66b49f98846937e8cfca1db3127a9d5d1e31ca45c3d0bef4c5b", - "sha256:b0997827b4f6a7c286c01c5f60384d218dca4ed7d9efa945c3e1aa623d5709ae", - "sha256:b631ef96d3222e62861443cc89d6563ba3eeb816eeb96b2629345ab795e53681", - "sha256:bf47c0607522fdbca6c9e817a6e81b08491de50f3766a7a0e6a5be7905961b41", - "sha256:f81025eddd0327c7d4cfe9b62cf33190e1e736cc6e97502b3ec425f574b3e7a8" + "sha256:08682f6b72c722394747bddaf0aa62277e02557c0fd1c42cb853016a38f8dedf", + "sha256:0f5f5786c0e09baddcd8b4b45f20a7b5d61a7e7e99846e3c799b05c7c53fa696", + "sha256:129def1b7c1bf22faffd67b8f3724645203b79d8f4cc81f674654d9902cb4393", + "sha256:294db365efa064d00b8d1ef65d8ea2c3426ac366c0c4368d930bf1c5fb497f77", + "sha256:3b2b1824fe7112845700f815ff6a489360226a5609b96ec2190a45e62a9fc922", + "sha256:3bd0e463264cf257d1ffd2e40223b197271046d09dadf73a0fe82b9c1fc385a5", + "sha256:4465124ef1b18d9ace298060f4eccc64b0850899ac4ac53294547536533800c8", + "sha256:49d4cdd9065b9b6e206d0595fee27a96b5dd22618e7520c33204a4a3239d5b10", + "sha256:4e0583d24c881e14342eaf4ec5fbc97f934b999a6828693a99157fde912540cc", + "sha256:5accb17103e43963b80e6f837831f38d314a0495500067cb25afab2e8d7a4018", + "sha256:607774cbba28732bfa802b54baa7484215f530991055bb562efbed5b2f20a45e", + "sha256:6c78645d400265a062508ae399b60b8c167bf003db364ecb26dcab2bda048253", + "sha256:72a01f726a9c7851ca9bfad6fd09ca4e090a023c00945ea05ba1638c09dc3347", + "sha256:74c1485f7707cf707a7aef42ef6322b8f97921bd89be2ab6317fd782c2d53183", + "sha256:895f61ef02e8fed38159bb70f7e100e00f471eae2bc838cd0f4ebb21e28f8541", + "sha256:8c1be557ee92a20f184922c7b6424e8ab6691788e6d86137c5d93c1a6ec1b8fb", + "sha256:bb4191dfc9306777bc594117aee052446b3fa88737cd13b7188d0e7aa8162185", + "sha256:bfb51918d4ff3d77c1c856a9699f8492c612cde32fd3bcd344af9be34999bfdc", + "sha256:c20cfa2d49991c8b4147af39859b167664f2ad4561704ee74c1de03318e898db", + "sha256:cb333c16912324fd5f769fff6bc5de372e9e7a202247b48870bc251ed40239aa", + "sha256:d2d9808ea7b4af864f35ea216be506ecec180628aced0704e34aca0b040ffe46", + "sha256:d483ad4e639292c90170eb6f7783ad19490e7a8defb3e46f97dfe4bacae89122", + "sha256:dd5de0646207f053eb0d6c74ae45ba98c3395a571a2891858e87df7c9b9bd51b", + "sha256:e1d4970ea66be07ae37a3c2e48b5ec63f7ba6804bdddfdbd3cfd954d25a82e63", + "sha256:e4fac90784481d221a8e4b1162afa7c47ed953be40d31ab4629ae917510051df", + "sha256:fa5ae20527d8e831e8230cbffd9f8fe952815b2b7dae6ffec25318803a7528fc", + "sha256:fd7f6999a8070df521b6384004ef42833b9bd62cfee11a09bda1079b4b704247", + "sha256:fdc842473cd33f45ff6bce46aea678a54e3d21f1b61a7750ce3c498eedfe25d6", + "sha256:fe69978f3f768926cfa37b867e3843918e012cf83f680806599ddce33c2c68b0" ], - "version": "==5.1.2" + "version": "==5.4.1" }, "rsa": { "hashes": [ - "sha256:14ba45700ff1ec9eeb206a2ce76b32814958a98e372006c8fb76ba820211be66", - "sha256:1a836406405730121ae9823e19c6e806c62bbad73f890574fff50efa4122c487" + "sha256:2c7c8624ef9b55bacc3be8bdcec5cefc381ddc156e968d6437fe0fd08af00eb0", + "sha256:6fa6a54eb72bfc0abca7f27880b978b14a643ba2a6ad9f4a56a95be82129ca1b" ], - "version": "==4.0" + "index": "pypi", + "version": "==4.1" }, "six": { "hashes": [ @@ -266,10 +294,10 @@ }, "werkzeug": { "hashes": [ - "sha256:87ae4e5b5366da2347eb3116c0e6c681a0e939a33b2805e2c0cbd282664932c4", - "sha256:a13b74dd3c45f758d4ebdb224be8f1ab8ef58b3c0ffc1783a8c7d9f4f50227e6" + "sha256:2de2a5db0baeae7b2d2664949077c2ac63fbd16d98da0ff71837f7d1dea3fd43", + "sha256:6c80b1e5ad3665290ea39320b91e1be1e0d5f60652b964a3070216de83d2e47c" ], - "version": "==0.15.5" + "version": "==1.0.1" } }, "develop": {} From 1ee98b39237db099c3ad91461a14de3fdb98ab18 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 25 Apr 2021 00:29:44 -0700 Subject: [PATCH 090/206] allow content-type header to CORS allowlist --- versions/v0.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/versions/v0.py b/versions/v0.py index 710f2d8..8b5bea0 100644 --- a/versions/v0.py +++ b/versions/v0.py @@ -34,7 +34,7 @@ blueprint = Blueprint('v0', __name__) CORS(blueprint, origins=["https://web.classclock.app", "https://beta.web.classclock.app"], allow_headers=[ - "Accept", "Authorization"]) + "Accept", "Authorization", "Content-Type"]) # supports_credentials=True) From 1dd62edcec2d422c00c6ec79daa2d39622be00f0 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 25 Apr 2021 00:40:29 -0700 Subject: [PATCH 091/206] add ping endpoint --- versions/v0.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/versions/v0.py b/versions/v0.py index 8b5bea0..470747a 100644 --- a/versions/v0.py +++ b/versions/v0.py @@ -80,6 +80,10 @@ # """ +@blueprint.route("/ping/", methods=['GET']) +def ping(): + return "pong" + # TODO: add a search parameter @blueprint.route("/schools/", methods=['GET']) @check_headers From faf123198abb9e27d5aedb464f4866c5296c53d6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 30 Apr 2021 21:12:13 +0000 Subject: [PATCH 092/206] Bump rsa from 4.1 to 4.7 Bumps [rsa](https://github.com/sybrenstuvel/python-rsa) from 4.1 to 4.7. - [Release notes](https://github.com/sybrenstuvel/python-rsa/releases) - [Changelog](https://github.com/sybrenstuvel/python-rsa/blob/main/CHANGELOG.md) - [Commits](https://github.com/sybrenstuvel/python-rsa/compare/version-4.1...version-4.7) Signed-off-by: dependabot[bot] --- Pipfile.lock | 55 +++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 46 insertions(+), 9 deletions(-) diff --git a/Pipfile.lock b/Pipfile.lock index 51b1b75..315c485 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -23,6 +23,13 @@ ], "version": "==9.0.1" }, + "attrs": { + "hashes": [ + "sha256:31b2eced602aa8423c2aea9c76a724617ed67cf9513173fd3a4f03e3a929c7e6", + "sha256:832aa3cde19744e49938b91fea06d69ecb9e649c93ba974535d08ad92164f700" + ], + "version": "==20.3.0" + }, "click": { "hashes": [ "sha256:d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a", @@ -106,6 +113,14 @@ "index": "pypi", "version": "==19.9.0" }, + "importlib-metadata": { + "hashes": [ + "sha256:8c501196e49fb9df5df43833bdb1e4328f64847763ec8a50703148b73784d581", + "sha256:d7eb1dea6d6a6086f8be21784cc9e3bcfa55872b52309bc5fad53a8ea444465d" + ], + "markers": "python_version < '3.8'", + "version": "==4.0.1" + }, "itsdangerous": { "hashes": [ "sha256:321b033d07f2a4136d3ec762eac9f16a10ccd60f53c0c91af90217ace7ba1f19", @@ -122,10 +137,10 @@ }, "jsonschema": { "hashes": [ - "sha256:000e68abd33c972a5248544925a0cae7d1125f9bf6c58280d37546b946769a08", - "sha256:6ff5f3180870836cae40f06fa10419f557208175f13ad7bc26caa77beb1f6e02" + "sha256:4e5b3cf8216f577bee9ce139cbe72eca3ea4f292ec60928ff24758ce626cd163", + "sha256:c8a85b28d377cc7737e46e2d9f2b4f44ee3c0e1deac6bf46ddefc7187d30797a" ], - "version": "==2.6.0" + "version": "==3.2.0" }, "limits": { "hashes": [ @@ -193,10 +208,10 @@ }, "marshmallow": { "hashes": [ - "sha256:4ab2fdb7f36eb61c3665da67a7ce281c8900db08d72ba6bf0e695828253581f7", - "sha256:eca81d53aa4aafbc0e20566973d0d2e50ce8bf0ee15165bb799bec0df1e50177" + "sha256:0dd42891a5ef288217ed6410917f3c6048f585f8692075a0052c24f9bfff9dfd", + "sha256:16e99cb7f630c0ef4d7d364ed0109ac194268dde123966076ab3dafb9ae3906b" ], - "version": "==3.10.0" + "version": "==3.11.1" }, "mistune": { "hashes": [ @@ -219,6 +234,12 @@ ], "version": "==0.4.8" }, + "pyrsistent": { + "hashes": [ + "sha256:2e636185d9eb976a18a8a8e96efce62f2905fea90041958d8cc2a189756ebf3e" + ], + "version": "==0.17.3" + }, "python-dotenv": { "hashes": [ "sha256:debd928b49dbc2bf68040566f55cdb3252458036464806f4094487244e2a4093", @@ -278,11 +299,11 @@ }, "rsa": { "hashes": [ - "sha256:2c7c8624ef9b55bacc3be8bdcec5cefc381ddc156e968d6437fe0fd08af00eb0", - "sha256:6fa6a54eb72bfc0abca7f27880b978b14a643ba2a6ad9f4a56a95be82129ca1b" + "sha256:69805d6b69f56eb05b62daea3a7dbd7aa44324ad1306445e05da8060232d00f4", + "sha256:a8774e55b59fd9fc893b0d05e9bfc6f47081f46ff5b46f39ccf24631b7be356b" ], "index": "pypi", - "version": "==4.1" + "version": "==4.7" }, "six": { "hashes": [ @@ -292,12 +313,28 @@ "index": "pypi", "version": "==1.12.0" }, + "typing-extensions": { + "hashes": [ + "sha256:7cb407020f00f7bfc3cb3e7881628838e69d8f3fcab2f64742a5e76b2f841918", + "sha256:99d4073b617d30288f569d3f13d2bd7548c3a7e4c8de87db09a9d29bb3a4a60c", + "sha256:dafc7639cde7f1b6e1acc0f457842a83e722ccca8eef5270af2d74792619a89f" + ], + "markers": "python_version < '3.8'", + "version": "==3.7.4.3" + }, "werkzeug": { "hashes": [ "sha256:2de2a5db0baeae7b2d2664949077c2ac63fbd16d98da0ff71837f7d1dea3fd43", "sha256:6c80b1e5ad3665290ea39320b91e1be1e0d5f60652b964a3070216de83d2e47c" ], "version": "==1.0.1" + }, + "zipp": { + "hashes": [ + "sha256:3607921face881ba3e026887d8150cca609d517579abe052ac81fc5aeffdbd76", + "sha256:51cb66cc54621609dd593d1787f286ee42a5c0adbb4b29abea5a63edc3e03098" + ], + "version": "==3.4.1" } }, "develop": {} From dc55c519dfc27467c1e49c49d103485fc5a0328f Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sat, 8 May 2021 01:05:41 -0700 Subject: [PATCH 093/206] update mysql connector --- Pipfile | 2 +- Pipfile.lock | 194 +++++++++++++++++++++++++-------------------------- 2 files changed, 98 insertions(+), 98 deletions(-) diff --git a/Pipfile b/Pipfile index 9bfc5d0..ba03989 100644 --- a/Pipfile +++ b/Pipfile @@ -18,7 +18,7 @@ flask-sqlalchemy = "~=2.4.1" marshmallow-sqlalchemy = "~=0.23" apispec = "~=3.3.0" apispec-webframeworks = "~=0.5.2" -mysql-connector-python = "8.0.12" +mysql-connector-python = "8.0.24" python-jose = "*" [requires] diff --git a/Pipfile.lock b/Pipfile.lock index 6b7ae6c..dc27fa4 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "3dbd4f805e11223de7a5d4e40c5266d4e0560004e9f52a58c2b5294197844eab" + "sha256": "6f00ba8a80f0a867eee207baf88da038679febf4545c4d47888187769a5766ed" }, "pipfile-spec": 6, "requires": { @@ -37,11 +37,11 @@ }, "attrs": { "hashes": [ - "sha256:31b2eced602aa8423c2aea9c76a724617ed67cf9513173fd3a4f03e3a929c7e6", - "sha256:832aa3cde19744e49938b91fea06d69ecb9e649c93ba974535d08ad92164f700" + "sha256:149e90d6d8ac20db7a955ad60cf0e6881a3f20d37096140088356da6c716b0b1", + "sha256:ef6aaac3ca6cd92904cdd0d83f629a15f18053ec84e6432106f7a4d04ae4f5fb" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==20.3.0" + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", + "version": "==21.2.0" }, "click": { "hashes": [ @@ -205,19 +205,19 @@ }, "marshmallow": { "hashes": [ - "sha256:4ab2fdb7f36eb61c3665da67a7ce281c8900db08d72ba6bf0e695828253581f7", - "sha256:eca81d53aa4aafbc0e20566973d0d2e50ce8bf0ee15165bb799bec0df1e50177" + "sha256:0dd42891a5ef288217ed6410917f3c6048f585f8692075a0052c24f9bfff9dfd", + "sha256:16e99cb7f630c0ef4d7d364ed0109ac194268dde123966076ab3dafb9ae3906b" ], "markers": "python_version >= '3.5'", - "version": "==3.10.0" + "version": "==3.11.1" }, "marshmallow-sqlalchemy": { "hashes": [ - "sha256:b217c6327bcf291e843dc1c2c20f0915061d4ecc303f0c5be40f23206607f702", - "sha256:ee3ead3b83de6608c6850ff60515691b0dc556ca226680f8a82b9f785cdb71b1" + "sha256:f1491f83833ac9c8406ba603458b1447fdfd904194833aab4b3cc01ef3646944", + "sha256:f861888ae3299f2c1f18cd94f02147ced70cd1b4986b2c5077e4a1036018d2a2" ], "index": "pypi", - "version": "==0.24.2" + "version": "==0.25.0" }, "mistune": { "hashes": [ @@ -228,55 +228,51 @@ }, "mysql-connector-python": { "hashes": [ - "sha256:0f41b3142fe5325e830a3420915a6cf652b9da1d3a8e0df11bade1c120c0fc2c", - "sha256:114ab771b6a1a98ea1e2e88c44fcf3ff713c65ac9fa8d3e88c0034e1fc0aed5d", - "sha256:2184f6b86c3981e5b2ffa82e946f12368a5f1758f022d9a30f43077950136114", - "sha256:2833d47ad04d08c1d3ab64b3b2b9203f84333f3463ca99332961c0ae1bf8101f", - "sha256:2eabe3f8a264efb3af04cb477943a8c8f04396fda0c5e2ad3450f9c044ddc603", - "sha256:2ed23de6c0a9e5769fc14f2930492b81629cb40f79381d79c679ddd04d5f3ddb", - "sha256:320a5929a39cae75a1cf0603b3baffdd7f36a0e520bfdd471d456f70973fc0ac", - "sha256:451120a964d3c56d983c7664f7c799bd92d5660085e3d8058defdec3e8a3b93a", - "sha256:49394f30e792a880ca2bd6e7e9d11eb86df0c316ab629b6d19185c9f5ca0811d", - "sha256:5e84dcc25d4b505118e0c28f07de496a41bc0ab121232a2aba83d0248cd49257", - "sha256:76758ee1d57b712bfbdae358506d578b955fda9dd91ae068a59e0fe02138ef0d", - "sha256:7b7fa9ed17a43164df2e203b25bf71f8679460795c055fb23f64a66f7ecde6be", - "sha256:7d55a446700bec300ec6a5b928b4700384bc2add43fa3b9ca124b03640db4e19", - "sha256:a37dff9d748d92134ea47ddbaafdfadb7f3bf9c8a66429ae247fb1ccaf6f7337", - "sha256:a5bf1979c126f475bc10c840d9464d5a2e4604bdc67b6be8bbaf9dbc4a3d8b89", - "sha256:a63658c518502736979dc1a79250c5e54ebbbd5ccfe9ec040cc591fcefbf1974", - "sha256:aa2307ddc30dd20dbca1165ffb1cf41dcf30ae1bcf46e74cb92c06a0eeeb0aac", - "sha256:c783e1dc8b78a1b1a9ebbf3ccb12d17e4513d91fafeb5b6c06a29f2d5619e285", - "sha256:dd7ed6baa35c3a89c6c8c8d6be0ebe1b089e77f41bb874b9dc4bc6db83ad654f", - "sha256:eb5d409df6e54c9a8f47dc901334d5e8b30a7967775d6eb3158494bf0534995d", - "sha256:efe72ce5e9d9051aeb99a4910949b3afb17570106a980a7a4f480d3894b1f426", - "sha256:f42516ef6b80ce70322f1fda63a8762f898df60df8ba621b2308d933216a8598", - "sha256:faf2aeb18725bb8bb6aae1e33b358d328cd35ded1b610d4c8608529b3051f634" + "sha256:13acb968c2b9ed165a569d5144a6fe6bb2b3073385b43387a2568e97979157d1", + "sha256:1be5cbb864c43ab86618e8bff0a489c2393fb788b9b789ce357933c8d56a64a8", + "sha256:1cf8e667e16fa02c31ff83e8069f6e99d0a61f99e2a6b2ed364e48591d83fb52", + "sha256:23a327e20dd048ad421465f6f946127b316b9c5aeb9fb85a037703fe71ccf6de", + "sha256:2665ccdf682bdf12f09fa40bad96167014c3ff53250483fa19068dd465ad5821", + "sha256:2a6d672b5ec7860977c9c7c3ab55d57227157853b7dac035d04e5d869d41b45f", + "sha256:3aa9366e4ef69f5a4349719d4ec2a7c59dac584de7e01cec5bb1c34b557377a5", + "sha256:41b1c1992181dd2f2c3ee8f4f13230baa22cf2872d40ba94bc8790a07aa27dc9", + "sha256:528fbdf2f4ee700b38579aad6969939cce294aa9644a1ba8479aa2c169804074", + "sha256:5f5d49ffb563c6c0fe9b607cab02a7cf98814677f8d4a66e0acdfec521f91db2", + "sha256:644f3ec2da1b36acfba5f286b36422aad42760284d6fd9585c17a93e5c667663", + "sha256:73f0fb24ff5ffc49811efd6514ce48393ced8615d070dfefe2c4cddb9302a2e7", + "sha256:9bb84e8cee2668d4f202ed7298bb52c08b85e22aee9a05f2b2176cb0ca786cc3", + "sha256:b3d92d57f145a79cf8e57ab9ecdae8acf3c5c631a9483a3e52450b473e08a8dd", + "sha256:e2734f01b8416aec9d0e506889522ee2ea8666afee433f3595df1e9c57057cdf", + "sha256:e39a72bb3e9c2082be16396838dd905f2fa0a545898cd06c913d0519b58b5619", + "sha256:e46ea2b7df8e3a525b3121f831290fac32a94553ef91d56ed02557236dbd14c0" ], "index": "pypi", - "version": "==8.0.23" + "version": "==8.0.24" }, "protobuf": { "hashes": [ - "sha256:0e247612fadda953047f53301a7b0407cb0c3cb4ae25a6fde661597a04039b3c", - "sha256:0fc96785262042e4863b3f3b5c429d4636f10d90061e1840fce1baaf59b1a836", - "sha256:1c51fda1bbc9634246e7be6016d860be01747354ed7015ebe38acf4452f470d2", - "sha256:1d63eb389347293d8915fb47bee0951c7b5dab522a4a60118b9a18f33e21f8ce", - "sha256:22bcd2e284b3b1d969c12e84dc9b9a71701ec82d8ce975fdda19712e1cfd4e00", - "sha256:2a7e2fe101a7ace75e9327b9c946d247749e564a267b0515cf41dfe450b69bac", - "sha256:43b554b9e73a07ba84ed6cf25db0ff88b1e06be610b37656e292e3cbb5437472", - "sha256:4b74301b30513b1a7494d3055d95c714b560fbb630d8fb9956b6f27992c9f980", - "sha256:4e75105c9dfe13719b7293f75bd53033108f4ba03d44e71db0ec2a0e8401eafd", - "sha256:5b7a637212cc9b2bcf85dd828b1178d19efdf74dbfe1ddf8cd1b8e01fdaaa7f5", - "sha256:5e9806a43232a1fa0c9cf5da8dc06f6910d53e4390be1fa06f06454d888a9142", - "sha256:629b03fd3caae7f815b0c66b41273f6b1900a579e2ccb41ef4493a4f5fb84f3a", - "sha256:72230ed56f026dd664c21d73c5db73ebba50d924d7ba6b7c0d81a121e390406e", - "sha256:86a75477addde4918e9a1904e5c6af8d7b691f2a3f65587d73b16100fbe4c3b2", - "sha256:8971c421dbd7aad930c9bd2694122f332350b6ccb5202a8b7b06f3f1a5c41ed5", - "sha256:9616f0b65a30851e62f1713336c931fcd32c057202b7ff2cfbfca0fc7d5e3043", - "sha256:b0d5d35faeb07e22a1ddf8dce620860c8fe145426c02d1a0ae2688c6e8ede36d", - "sha256:ecc33531a213eee22ad60e0e2aaea6c8ba0021f0cce35dbf0ab03dee6e2a23a1" + "sha256:11301f1993f67dc81fc5c4756623652c899f7b5574b1e095d63bfc78347b11f3", + "sha256:228eecbedd46d75010f1e0f8ce34dbcd11ae5a40c165a9fc9d330a58aa302818", + "sha256:2cec059f4821c8f58890920a5c8a828ea027d46d5b18cb5e9dd4c727c65a2aa0", + "sha256:49dd3550bb42050d1676378c3fef91ff058d7023b77ac6f3179eb2a1c6c562d7", + "sha256:4bb7064727953d9187f6806230968b98e1ce4ec03bd737600e8380a9e5a6ac15", + "sha256:648178381d9dbbc736849443151533ab958e7b8bcbd658a62ad10906552fddcc", + "sha256:675d8e7463e03cf8343792935d62b80d90839d56a228c941dfdddda946eea066", + "sha256:80b233553ff500378becc372721541902c567e51b2654b68513d7b89c43dbc4b", + "sha256:8c0d3a5aa3412a440a9384349f6095991e8a5012e619cf5f57f042829f65cdb3", + "sha256:8ec649186f5443cab12692438190988bb9058dbfa5851d10d59a1c7214159a5f", + "sha256:9191e97d92b62424423ce5a5604047fd76c80a4f463fbd10c9d8b82928f152cf", + "sha256:b85ad5fe54163350067a53c0c170211c9f752dd4b4d8f339eb5aea8e987614a9", + "sha256:bc1ba824ff750c2ead1e7b8dd049bb5ddf8658d056cf4b989f04c68b049a47a7", + "sha256:be831508b9207156309a88b9d115dbae0caa4a987b05f1aa4fed4c5ac53ec51b", + "sha256:bf9a5caa0e0093552c2cc6051facef15b9c9ad4b1bde70430964edf99eaf2dad", + "sha256:c0f760adc1dd3dfe6d13af529b2ab42bb3fff1a2a00a6873b583b4ce0048ddff", + "sha256:c356d038a4e4cf52ccd7aff8022fc6a76daa0be5ecf2517ed75b87d32be0405d", + "sha256:c94ee9832fded92a11920b10d75c5aa7f4ef910b0bd463c039e102c8d7eb2c46", + "sha256:d3b9988f1a3591d900a090887ae4c41592e252bef5b249ad7e1fc46c21617534", + "sha256:ef9c2d0b3c0935725b547175745ceacb86f4d410b1e984d47e320c9efb1936c5" ], - "version": "==3.14.0" + "version": "==3.16.0" }, "pyasn1": { "hashes": [ @@ -325,25 +321,33 @@ "sha256:5accb17103e43963b80e6f837831f38d314a0495500067cb25afab2e8d7a4018", "sha256:607774cbba28732bfa802b54baa7484215f530991055bb562efbed5b2f20a45e", "sha256:6c78645d400265a062508ae399b60b8c167bf003db364ecb26dcab2bda048253", + "sha256:72a01f726a9c7851ca9bfad6fd09ca4e090a023c00945ea05ba1638c09dc3347", "sha256:74c1485f7707cf707a7aef42ef6322b8f97921bd89be2ab6317fd782c2d53183", + "sha256:895f61ef02e8fed38159bb70f7e100e00f471eae2bc838cd0f4ebb21e28f8541", "sha256:8c1be557ee92a20f184922c7b6424e8ab6691788e6d86137c5d93c1a6ec1b8fb", "sha256:bb4191dfc9306777bc594117aee052446b3fa88737cd13b7188d0e7aa8162185", + "sha256:bfb51918d4ff3d77c1c856a9699f8492c612cde32fd3bcd344af9be34999bfdc", "sha256:c20cfa2d49991c8b4147af39859b167664f2ad4561704ee74c1de03318e898db", + "sha256:cb333c16912324fd5f769fff6bc5de372e9e7a202247b48870bc251ed40239aa", "sha256:d2d9808ea7b4af864f35ea216be506ecec180628aced0704e34aca0b040ffe46", + "sha256:d483ad4e639292c90170eb6f7783ad19490e7a8defb3e46f97dfe4bacae89122", "sha256:dd5de0646207f053eb0d6c74ae45ba98c3395a571a2891858e87df7c9b9bd51b", "sha256:e1d4970ea66be07ae37a3c2e48b5ec63f7ba6804bdddfdbd3cfd954d25a82e63", "sha256:e4fac90784481d221a8e4b1162afa7c47ed953be40d31ab4629ae917510051df", - "sha256:fa5ae20527d8e831e8230cbffd9f8fe952815b2b7dae6ffec25318803a7528fc" + "sha256:fa5ae20527d8e831e8230cbffd9f8fe952815b2b7dae6ffec25318803a7528fc", + "sha256:fd7f6999a8070df521b6384004ef42833b9bd62cfee11a09bda1079b4b704247", + "sha256:fdc842473cd33f45ff6bce46aea678a54e3d21f1b61a7750ce3c498eedfe25d6", + "sha256:fe69978f3f768926cfa37b867e3843918e012cf83f680806599ddce33c2c68b0" ], "version": "==5.4.1" }, "rsa": { "hashes": [ - "sha256:69805d6b69f56eb05b62daea3a7dbd7aa44324ad1306445e05da8060232d00f4", - "sha256:a8774e55b59fd9fc893b0d05e9bfc6f47081f46ff5b46f39ccf24631b7be356b" + "sha256:78f9a9bf4e7be0c5ded4583326e7461e3a3c5aae24073648b4bdfa797d78c9d2", + "sha256:9d689e6ca1b3038bc82bf8d23e944b6b6037bc02301a574935b2dd946e0353b9" ], "markers": "python_version >= '3.5' and python_version < '4'", - "version": "==4.7" + "version": "==4.7.2" }, "six": { "hashes": [ @@ -355,47 +359,43 @@ }, "sqlalchemy": { "hashes": [ - "sha256:040bdfc1d76a9074717a3f43455685f781c581f94472b010cd6c4754754e1862", - "sha256:1fe5d8d39118c2b018c215c37b73fd6893c3e1d4895be745ca8ff6eb83333ed3", - "sha256:23927c3981d1ec6b4ea71eb99d28424b874d9c696a21e5fbd9fa322718be3708", - "sha256:24f9569e82a009a09ce2d263559acb3466eba2617203170e4a0af91e75b4f075", - "sha256:2578dbdbe4dbb0e5126fb37ffcd9793a25dcad769a95f171a2161030bea850ff", - "sha256:269990b3ab53cb035d662dcde51df0943c1417bdab707dc4a7e4114a710504b4", - "sha256:29cccc9606750fe10c5d0e8bd847f17a97f3850b8682aef1f56f5d5e1a5a64b1", - "sha256:37b83bf81b4b85dda273aaaed5f35ea20ad80606f672d94d2218afc565fb0173", - "sha256:63677d0c08524af4c5893c18dbe42141de7178001360b3de0b86217502ed3601", - "sha256:639940bbe1108ac667dcffc79925db2966826c270112e9159439ab6bb14f8d80", - "sha256:6a939a868fdaa4b504e8b9d4a61f21aac11e3fecc8a8214455e144939e3d2aea", - "sha256:6b8b8c80c7f384f06825612dd078e4a31f0185e8f1f6b8c19e188ff246334205", - "sha256:6c9e6cc9237de5660bcddea63f332428bb83c8e2015c26777281f7ffbd2efb84", - "sha256:6ec1044908414013ebfe363450c22f14698803ce97fbb47e53284d55c5165848", - "sha256:6fca33672578666f657c131552c4ef8979c1606e494f78cd5199742dfb26918b", - "sha256:751934967f5336a3e26fc5993ccad1e4fee982029f9317eb6153bc0bc3d2d2da", - "sha256:8be835aac18ec85351385e17b8665bd4d63083a7160a017bef3d640e8e65cadb", - "sha256:927ce09e49bff3104459e1451ce82983b0a3062437a07d883a4c66f0b344c9b5", - "sha256:94208867f34e60f54a33a37f1c117251be91a47e3bfdb9ab8a7847f20886ad06", - "sha256:94f667d86be82dd4cb17d08de0c3622e77ca865320e0b95eae6153faa7b4ecaf", - "sha256:9e9c25522933e569e8b53ccc644dc993cab87e922fb7e142894653880fdd419d", - "sha256:a0e306e9bb76fd93b29ae3a5155298e4c1b504c7cbc620c09c20858d32d16234", - "sha256:a8bfc1e1afe523e94974132d7230b82ca7fa2511aedde1f537ec54db0399541a", - "sha256:ac2244e64485c3778f012951fdc869969a736cd61375fde6096d08850d8be729", - "sha256:b4b0e44d586cd64b65b507fa116a3814a1a53d55dce4836d7c1a6eb2823ff8d1", - "sha256:baeb451ee23e264de3f577fee5283c73d9bbaa8cb921d0305c0bbf700094b65b", - "sha256:c7dc052432cd5d060d7437e217dd33c97025287f99a69a50e2dc1478dd610d64", - "sha256:d1a85dfc5dee741bf49cb9b6b6b8d2725a268e4992507cf151cba26b17d97c37", - "sha256:d90010304abb4102123d10cbad2cdf2c25a9f2e66a50974199b24b468509bad5", - "sha256:ddfb511e76d016c3a160910642d57f4587dc542ce5ee823b0d415134790eeeb9", - "sha256:e273367f4076bd7b9a8dc2e771978ef2bfd6b82526e80775a7db52bff8ca01dd", - "sha256:e5bb3463df697279e5459a7316ad5a60b04b0107f9392e88674d0ece70e9cf70", - "sha256:e8a1750b44ad6422ace82bf3466638f1aa0862dbb9689690d5f2f48cce3476c8", - "sha256:eab063a70cca4a587c28824e18be41d8ecc4457f8f15b2933584c6c6cccd30f0", - "sha256:ecce8c021894a77d89808222b1ff9687ad84db54d18e4bd0500ca766737faaf6", - "sha256:f4d972139d5000105fcda9539a76452039434013570d6059993120dc2a65e447", - "sha256:fd3b96f8c705af8e938eaa99cbd8fd1450f632d38cad55e7367c33b263bf98ec", - "sha256:fdd2ed7395df8ac2dbb10cefc44737b66c6a5cd7755c92524733d7a443e5b7e2" + "sha256:014ea143572fee1c18322b7908140ad23b3994036ef4c0d630110faf942652f8", + "sha256:0172423a27fbcae3751ef016663b72e1a516777de324a76e30efa170dbd3dd2d", + "sha256:01aa5f803db724447c1d423ed583e42bf5264c597fd55e4add4301f163b0be48", + "sha256:0352db1befcbed2f9282e72843f1963860bf0e0472a4fa5cf8ee084318e0e6ab", + "sha256:09083c2487ca3c0865dc588e07aeaa25416da3d95f7482c07e92f47e080aa17b", + "sha256:0d5d862b1cfbec5028ce1ecac06a3b42bc7703eb80e4b53fceb2738724311443", + "sha256:14f0eb5db872c231b20c18b1e5806352723a3a89fb4254af3b3e14f22eaaec75", + "sha256:1e2f89d2e5e3c7a88e25a3b0e43626dba8db2aa700253023b82e630d12b37109", + "sha256:26155ea7a243cbf23287f390dba13d7927ffa1586d3208e0e8d615d0c506f996", + "sha256:2ed6343b625b16bcb63c5b10523fd15ed8934e1ed0f772c534985e9f5e73d894", + "sha256:34fcec18f6e4b24b4a5f6185205a04f1eab1e56f8f1d028a2a03694ebcc2ddd4", + "sha256:4d0e3515ef98aa4f0dc289ff2eebb0ece6260bbf37c2ea2022aad63797eacf60", + "sha256:5de2464c254380d8a6c20a2746614d5a436260be1507491442cf1088e59430d2", + "sha256:6607ae6cd3a07f8a4c3198ffbf256c261661965742e2b5265a77cd5c679c9bba", + "sha256:8110e6c414d3efc574543109ee618fe2c1f96fa31833a1ff36cc34e968c4f233", + "sha256:816de75418ea0953b5eb7b8a74933ee5a46719491cd2b16f718afc4b291a9658", + "sha256:861e459b0e97673af6cc5e7f597035c2e3acdfb2608132665406cded25ba64c7", + "sha256:87a2725ad7d41cd7376373c15fd8bf674e9c33ca56d0b8036add2d634dba372e", + "sha256:a006d05d9aa052657ee3e4dc92544faae5fcbaafc6128217310945610d862d39", + "sha256:bce28277f308db43a6b4965734366f533b3ff009571ec7ffa583cb77539b84d6", + "sha256:c10ff6112d119f82b1618b6dc28126798481b9355d8748b64b9b55051eb4f01b", + "sha256:d375d8ccd3cebae8d90270f7aa8532fe05908f79e78ae489068f3b4eee5994e8", + "sha256:d37843fb8df90376e9e91336724d78a32b988d3d20ab6656da4eb8ee3a45b63c", + "sha256:e47e257ba5934550d7235665eee6c911dc7178419b614ba9e1fbb1ce6325b14f", + "sha256:e98d09f487267f1e8d1179bf3b9d7709b30a916491997137dd24d6ae44d18d79", + "sha256:ebbb777cbf9312359b897bf81ba00dae0f5cb69fba2a18265dcc18a6f5ef7519", + "sha256:ee5f5188edb20a29c1cc4a039b074fdc5575337c9a68f3063449ab47757bb064", + "sha256:f03bd97650d2e42710fbe4cf8a59fae657f191df851fc9fc683ecef10746a375", + "sha256:f1149d6e5c49d069163e58a3196865e4321bad1803d7886e07d8710de392c548", + "sha256:f3c5c52f7cb8b84bfaaf22d82cb9e6e9a8297f7c2ed14d806a0f5e4d22e83fb7", + "sha256:f597a243b8550a3a0b15122b14e49d8a7e622ba1c9d29776af741f1845478d79", + "sha256:fc1f2a5a5963e2e73bac4926bdaf7790c4d7d77e8fc0590817880e22dd9d0b8b", + "sha256:fc4cddb0b474b12ed7bdce6be1b9edc65352e8ce66bc10ff8cbbfb3d4047dbf4", + "sha256:fcb251305fa24a490b6a9ee2180e5f8252915fb778d3dafc70f9cc3f863827b9" ], "index": "pypi", - "version": "==1.3.23" + "version": "==1.3.24" }, "werkzeug": { "hashes": [ From 50bd03418f267c23072000cc8ce9d2050a3159cb Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sat, 8 May 2021 01:06:15 -0700 Subject: [PATCH 094/206] update name of bell schedule id column to match the DB --- api.py | 4 ++-- common/db_schema.py | 2 +- common/schemas.py | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/api.py b/api.py index 31f2fb1..faded8b 100644 --- a/api.py +++ b/api.py @@ -170,7 +170,7 @@ def today_plus(sch, num_days): sc1.meeting_times = [ BellScheduleMeetingTime( - schedule_id =sc1.id, + bell_schedule_id =sc1.id, name="First Period", start_time=datetime.time(hour=8, minute=25, second=0, microsecond=0), end_time=datetime.time(9,25) @@ -179,7 +179,7 @@ def today_plus(sch, num_days): sc2.meeting_times = [ BellScheduleMeetingTime( - schedule_id =sc2.id, + bell_schedule_id =sc2.id, name="First Period", start_time=datetime.time(8,45), end_time=datetime.time(9,45) diff --git a/common/db_schema.py b/common/db_schema.py index 8018c9e..74cdbc6 100644 --- a/common/db_schema.py +++ b/common/db_schema.py @@ -80,7 +80,7 @@ class BellScheduleMeetingTime(db.Model): description: A meeting time for a particular bell schedule (aka a class period) """ __tablename__ = "bellschedulemeetingtimes" - schedule_id = db.Column(HashColumn(length=32), ForeignKey(BellSchedule.id), primary_key=True) + bell_schedule_id = db.Column(HashColumn(length=32), ForeignKey(BellSchedule.id), primary_key=True) # school_id = db.Column(HashColumn(length=32), ForeignKey(School.id)) name = db.Column('classperiod_name', db.VARCHAR(length=75), primary_key=True) diff --git a/common/schemas.py b/common/schemas.py index 901cadf..46e5d23 100644 --- a/common/schemas.py +++ b/common/schemas.py @@ -68,5 +68,5 @@ class Meta: creation_date = auto_field(dump_only=True) last_modified = auto_field(dump_only=True) - classes = Nested(BellScheduleMeetingTimeSchema, exclude=("schedule_id", "creation_date"), many=True) + classes = Nested(BellScheduleMeetingTimeSchema, exclude=("bell_schedule_id", "creation_date"), many=True) dates = SessionPluck(BellScheduleDateSchema, "date", many=True) From 2d673bab76015368f7c6b7ded75a45fa6ab490c4 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Mon, 10 May 2021 09:16:58 -0700 Subject: [PATCH 095/206] pipenv update --- Pipfile.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Pipfile.lock b/Pipfile.lock index dc27fa4..009485a 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -205,11 +205,11 @@ }, "marshmallow": { "hashes": [ - "sha256:0dd42891a5ef288217ed6410917f3c6048f585f8692075a0052c24f9bfff9dfd", - "sha256:16e99cb7f630c0ef4d7d364ed0109ac194268dde123966076ab3dafb9ae3906b" + "sha256:77ce3097c06d93de37394e0e0bf217dacbb4eabe0b88129e315e10d8790b1354", + "sha256:822dfacdf6ac5c2f514182bcddde0cc60d943ca46e4006c1e14761a0605bfc0f" ], "markers": "python_version >= '3.5'", - "version": "==3.11.1" + "version": "==3.12.0" }, "marshmallow-sqlalchemy": { "hashes": [ From 4109ac1a30ebdf3c583b73787d31f0f2d2f2ab72 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 15 Aug 2021 12:52:48 -0700 Subject: [PATCH 096/206] add initial docker container config --- .dockerignore | 12 ++++++++++++ Dockerfile | 14 ++++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 .dockerignore create mode 100644 Dockerfile diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..9263423 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,12 @@ +*.tar +*.png +*.md +.env +.git/* +.gitignore +*.pyc +*.sh +tests/ +.vscode/ +__pycache__/ +.pytest_cache \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..0229ded --- /dev/null +++ b/Dockerfile @@ -0,0 +1,14 @@ +FROM python:3.8-slim-buster + +WORKDIR /classclock-api + +RUN pip install pipenv + + +COPY Pipfile Pipfile.lock /classclock-api/ + +RUN pipenv install + +COPY . /classclock-api/ + +ENTRYPOINT pipenv run gunicorn --workers 2 --bind 0.0.0.0 api:app From 4ad4aa226ba1f3aafa73081253014b344f48fe8b Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 15 Aug 2021 12:52:58 -0700 Subject: [PATCH 097/206] ignore env files --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index d773b90..79abf18 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,4 @@ classclockapi_venv/ prodstart\.sh *.pyc +*.env \ No newline at end of file From f4177a510bcf6dd5d65bf5722bbc28ee9d531f05 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 15 Aug 2021 12:57:50 -0700 Subject: [PATCH 098/206] document the docker --- README.md | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 0e98321..09f419c 100644 --- a/README.md +++ b/README.md @@ -20,4 +20,13 @@ This is the backend that provides access to the ClassClock database. ## Setup command -To run the setup script, first create an empty database and a new user that can access the database. Then, with the environment variables set appropriately as listed above, execute `python3 api.py setup`. If you have not specified the `DB_USERNAME` or `DB_PASSWORD` environment variables, you will be prompted for them interactively when the script runs. \ No newline at end of file +To run the setup script, first create an empty database and a new user that can access the database. Then, with the environment variables set appropriately as listed above, execute `python3 api.py setup`. If you have not specified the `DB_USERNAME` or `DB_PASSWORD` environment variables, you will be prompted for them interactively when the script runs. + +## Docker + +This API has been set up to run in a docker container. + +The simplest way to run it is to: +1. aquire the container either from a docker repository or by running `docker build . -t classclock-api` in a cloned version of this repo +2. set up the environment variables you want per the above table +3. use a command like `docker run -p 8000:8000 --rm --env-file dev.env classclock-api:latest` to run the container interactively using `dev.env` as the source of the environment variables. The app will start up on port 8000. \ No newline at end of file From 3263082ff8711b723e6f165f20133c586cbecb4c Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Tue, 7 Sep 2021 14:59:37 -0400 Subject: [PATCH 099/206] add vercel staging domains to CORS whitelist --- versions/v0.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/versions/v0.py b/versions/v0.py index 470747a..6f56380 100644 --- a/versions/v0.py +++ b/versions/v0.py @@ -33,7 +33,7 @@ blueprint = Blueprint('v0', __name__) -CORS(blueprint, origins=["https://web.classclock.app", "https://beta.web.classclock.app"], allow_headers=[ +CORS(blueprint, origins=["https://web.classclock.app", "https://beta.web.classclock.app", "classclock-*-moralcode.vercel.app"], allow_headers=[ "Accept", "Authorization", "Content-Type"]) # supports_credentials=True) From 79839684d9f35a6d118435e4e69bf348633d00e6 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sat, 5 Feb 2022 23:28:14 -0500 Subject: [PATCH 100/206] add endpoint for getting a list of all bell schedules that you own --- common/db_schema.py | 2 +- versions/v0.py | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/common/db_schema.py b/common/db_schema.py index 74cdbc6..9bb8847 100644 --- a/common/db_schema.py +++ b/common/db_schema.py @@ -22,7 +22,7 @@ class School(db.Model): primary_key=True, default=get_uuid) owner_id = db.Column('owner_id', db.VARCHAR(length=35)) full_name = db.Column('school_name', db.VARCHAR(length=75)) - schedules = db.relationship("BellSchedule") + schedules = db.relationship("BellSchedule",backref=db.backref("school")) acronym = db.Column( 'school_acronym', db.VARCHAR(length=75), nullable=True) alternate_freeperiod_name = db.Column( diff --git a/versions/v0.py b/versions/v0.py index 6f56380..dd8592a 100644 --- a/versions/v0.py +++ b/versions/v0.py @@ -293,6 +293,19 @@ def delete_school(school_id): # should this just archive the school? or delete it and all related records? # sqlalchemy can be set to cascade deletes (i think). return None, 204 + +@blueprint.route("/bellschedules", strict_slashes=False, methods=['GET']) +@check_headers +def list_owned_bellschedules(): + """ + gets a list of bell schedules + --- + """ + #if get_api_user_id() not in school.owner_id + + schedules = BellScheduleDB.query.join(BellScheduleDB.school).filter(SchoolDB.owner_id==get_api_user_id()) + + return respond(BellScheduleSchema(exclude=('school_id',)).dump(schedules, many=True)) #TODO: add filtering for return values to reduce size of response. i.e. filter dates by after today, exclude meeting times if they havent changed @blueprint.route("/bellschedules//", methods=['GET']) From 5d61bd34e77a54b32a003e6659e4a7317b4b946a Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Fri, 11 Feb 2022 07:46:29 -0500 Subject: [PATCH 101/206] require auth on bell schedules endpoint --- versions/v0.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/versions/v0.py b/versions/v0.py index dd8592a..93dd546 100644 --- a/versions/v0.py +++ b/versions/v0.py @@ -296,6 +296,8 @@ def delete_school(school_id): @blueprint.route("/bellschedules", strict_slashes=False, methods=['GET']) @check_headers +@requires_auth#(permissions=[APIScopes.DELETE_SCHOOL, APIScopes.DELETE_BELL_SCHEDULE]) +@requires_admin def list_owned_bellschedules(): """ gets a list of bell schedules From e8a64b802b70ef19ab24037a3291e024ef7c5f14 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Fri, 11 Feb 2022 07:49:31 -0500 Subject: [PATCH 102/206] disable strict slashes on all endpoints --- versions/v0.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/versions/v0.py b/versions/v0.py index 93dd546..74ce291 100644 --- a/versions/v0.py +++ b/versions/v0.py @@ -80,12 +80,12 @@ # """ -@blueprint.route("/ping/", methods=['GET']) +@blueprint.route("/ping", strict_slashes=False, methods=['GET']) def ping(): return "pong" # TODO: add a search parameter -@blueprint.route("/schools/", methods=['GET']) +@blueprint.route("/schools", strict_slashes=False, methods=['GET']) @check_headers def list_schools(): """ Returns a list of schools @@ -105,7 +105,7 @@ def list_schools(): return respond(SchoolSchema().dump(schools, many=True)) -@blueprint.route("/school//", methods=['GET']) +@blueprint.route("/school/", strict_slashes=False, methods=['GET']) @check_headers def get_school(school_id): """ Returns a single school @@ -145,7 +145,7 @@ def get_school(school_id): return respond(SchoolSchema().dump(school)) -@blueprint.route("/school/", methods=['POST']) +@blueprint.route("/school", strict_slashes=False, methods=['POST']) @check_headers @requires_auth(permissions=[APIScopes.CREATE_SCHOOL]) @requires_admin @@ -195,7 +195,7 @@ def create_school(): return respond(SchoolSchema().dump(new_object)) -@blueprint.route("/school//", methods=['PATCH']) +@blueprint.route("/school/", strict_slashes=False, methods=['PATCH']) @check_headers @requires_auth(permissions=[APIScopes.EDIT_SCHOOL]) @requires_admin @@ -249,7 +249,7 @@ def update_school(school_id): return respond(SchoolSchema().dump(school)) -@blueprint.route("/school//", methods=['DELETE']) +@blueprint.route("/school/", strict_slashes=False, methods=['DELETE']) @check_headers @requires_auth(permissions=[APIScopes.DELETE_SCHOOL, APIScopes.DELETE_BELL_SCHEDULE]) @requires_admin @@ -310,7 +310,7 @@ def list_owned_bellschedules(): return respond(BellScheduleSchema(exclude=('school_id',)).dump(schedules, many=True)) #TODO: add filtering for return values to reduce size of response. i.e. filter dates by after today, exclude meeting times if they havent changed -@blueprint.route("/bellschedules//", methods=['GET']) +@blueprint.route("/bellschedules/", strict_slashes=False, methods=['GET']) @check_headers def list_bellschedules(school_id): """ @@ -329,7 +329,7 @@ def list_bellschedules(school_id): return respond(BellScheduleSchema(exclude=('school_id',)).dump(schedules, many=True)) -@blueprint.route("/bellschedule//", methods=['GET']) +@blueprint.route("/bellschedule/", strict_slashes=False, methods=['GET']) @check_headers def get_bellschedule(bell_schedule_id): """ @@ -367,7 +367,7 @@ def get_bellschedule(bell_schedule_id): return respond(BellScheduleSchema().dump(schedule)) -@blueprint.route("/bellschedule/", methods=['POST']) +@blueprint.route("/bellschedule", strict_slashes=False, methods=['POST']) @check_headers @requires_auth(permissions=[APIScopes.CREATE_BELL_SCHEDULE]) @requires_admin @@ -386,7 +386,7 @@ def create_bellschedule(): return respond(BellScheduleSchema(exclude=('school_id',)).dump(new_schedule)) -@blueprint.route("/bellschedule//", methods=['PATCH']) +@blueprint.route("/bellschedule/", strict_slashes=False, methods=['PATCH']) @check_headers @requires_auth(permissions=[APIScopes.EDIT_BELL_SCHEDULE]) @requires_admin From 7e6cc1189ee26d9196a45b0c756ef70c477c0d82 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Fri, 11 Feb 2022 19:30:39 -0500 Subject: [PATCH 103/206] determine CORS based on development mode or prod mode --- versions/v0.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/versions/v0.py b/versions/v0.py index 74ce291..134a3bd 100644 --- a/versions/v0.py +++ b/versions/v0.py @@ -33,7 +33,10 @@ blueprint = Blueprint('v0', __name__) -CORS(blueprint, origins=["https://web.classclock.app", "https://beta.web.classclock.app", "classclock-*-moralcode.vercel.app"], allow_headers=[ +flex_url = "http://localhost:3000" if env.get("FLASK_ENV") == 'development' else "classclock-*-moralcode.vercel.app" + + +CORS(blueprint, origins=["https://web.classclock.app", "https://beta.web.classclock.app", flex_url], allow_headers=[ "Accept", "Authorization", "Content-Type"]) # supports_credentials=True) From 951d873266eaea91e640128f72f37fbbaa15e651 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 13 Feb 2022 16:32:45 -0500 Subject: [PATCH 104/206] install flask-migrate as a devdependency --- Pipfile | 1 + Pipfile.lock | 774 +++++++++++++++++++++++++++++++++++++++------------ 2 files changed, 594 insertions(+), 181 deletions(-) diff --git a/Pipfile b/Pipfile index ba03989..69c9685 100644 --- a/Pipfile +++ b/Pipfile @@ -4,6 +4,7 @@ url = "https://pypi.org/simple" verify_ssl = true [dev-packages] +flask-migrate = "*" [packages] six = "~=1.12.0" diff --git a/Pipfile.lock b/Pipfile.lock index 315c485..e7e4cee 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,11 +1,11 @@ { "_meta": { "hash": { - "sha256": "bef3db461e595e2e2b157851bbb3f5904dbd47887de755ae5b48e51c32434202" + "sha256": "c37f67a03e97e4a1f975c2eda698d57193244d08c5602fc5060eaf19c3a07d15" }, "pipfile-spec": 6, "requires": { - "python_version": "3.6" + "python_version": "3.8" }, "sources": [ { @@ -16,68 +16,76 @@ ] }, "default": { - "aniso8601": { + "apispec": { + "extras": [ + "yaml" + ], + "hashes": [ + "sha256:a1df9ec6b2cd0edf45039ef025abd7f0660808fa2edf737d3ba1cf5ef1a4625b", + "sha256:d23ebd5b71e541e031b02a19db10b5e6d5ef8452c552833e3e1afc836b40b1ad" + ], + "index": "pypi", + "version": "==3.3.2" + }, + "apispec-webframeworks": { "hashes": [ - "sha256:1d2b7ef82963909e93c4f24ce48d4de9e66009a21bf1c1e1c85bdd0812fe412f", - "sha256:72e3117667eedf66951bb2d93f4296a56b94b078a8a95905a052611fb3f1b973" + "sha256:0db35b267914b3f8c562aca0261957dbcb4176f255eacc22520277010818dcf3", + "sha256:482c563abbcc2a261439476cb3f1a7c7284cc997c322c574d48c111643e9c04e" ], - "version": "==9.0.1" + "index": "pypi", + "version": "==0.5.2" }, "attrs": { "hashes": [ - "sha256:31b2eced602aa8423c2aea9c76a724617ed67cf9513173fd3a4f03e3a929c7e6", - "sha256:832aa3cde19744e49938b91fea06d69ecb9e649c93ba974535d08ad92164f700" + "sha256:2d27e3784d7a565d36ab851fe94887c5eccd6a463168875832a1be79c82828b4", + "sha256:626ba8234211db98e869df76230a137c4c40a12d72445c45d5f5b716f076e2fd" ], - "version": "==20.3.0" + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", + "version": "==21.4.0" }, "click": { "hashes": [ "sha256:d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a", "sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc" ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", "version": "==7.1.2" }, - "dnspython": { - "hashes": [ - "sha256:36c5e8e38d4369a08b6780b7f27d790a292b2b08eea01607865bf0936c558e01", - "sha256:f69c21288a962f4da86e56c4905b49d11aba7938d3d740e80d9e366ee4f1632d" - ], - "index": "pypi", - "version": "==1.16.0" - }, "ecdsa": { "hashes": [ - "sha256:881fa5e12bb992972d3d1b3d4dfbe149ab76a89f13da02daa5ea1ec7dea6e747", - "sha256:cfc046a2ddd425adbd1a78b3c46f0d1325c657811c0f45ecc3a0a6236c1e50ff" + "sha256:5cf31d5b33743abe0dfc28999036c849a69d548f994b535e527ee3cb7f3ef676", + "sha256:b9f500bb439e4153d0330610f5d26baaf18d17b8ced1bc54410d189385ea68aa" ], - "version": "==0.16.1" + "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==0.17.0" }, "flasgger": { "hashes": [ - "sha256:45ce85bf826f71e07d734e52a1af000b3fef82bd1a2337ea5bc4585a3383c56d", - "sha256:fe62d086ca341f71072fd21c2d4f993b6958ce47ee8f0a4ae716e7c901afeb21" + "sha256:0603941cf4003626b4ee551ca87331f1d17b8eecce500ccf1a1f1d3a332fc94a", + "sha256:6ebea406b5beecd77e8da42550f380d4d05a6107bc90b69ce9e77aee7612e2d0" ], "index": "pypi", - "version": "==0.9.3" + "version": "==0.9.5" }, "flask": { "hashes": [ - "sha256:13f9f196f330c7c2c5d7a5cf91af894110ca0215ac051b5844701f2bfd934d52", - "sha256:45eb5a6fd193d6cf7e0cf5d8a5b31f83d5faae0293695626f539a823e93b13f6" + "sha256:0fbeb6180d383a9186d0d6ed954e0042ad9f18e0e8de088b2b419d526927d196", + "sha256:c34f04500f2cbbea882b1acb02002ad6fe6b7ffa64a6164577995657f50aed22" ], "index": "pypi", - "version": "==1.1.1" + "version": "==1.1.4" }, "flask-cors": { "hashes": [ - "sha256:72170423eb4612f0847318afff8c247b38bd516b7737adfc10d1c2cdbb382d16", - "sha256:f4d97201660e6bbcff2d89d082b5b6d31abee04b1b3003ee073a6fd25ad1d69a" + "sha256:74efc975af1194fc7891ff5cd85b0f7478be4f7f59fe158102e91abb72bb4438", + "sha256:b60839393f3b84a0f3746f6cdca56c1ad7426aa738b70d6c61375857823181de" ], "index": "pypi", - "version": "==3.0.8" + "version": "==3.0.10" }, "flask-limiter": { "hashes": [ + "sha256:473aa5bc97310406aa8c12ab3dc080697bcfa8cd21a6d0aba30916911bbc673c", "sha256:8cce98dcf25bf2ddbb824c2b503b4fc8e1a139154240fd2c60d9306bad8a0db8" ], "index": "pypi", @@ -91,19 +99,13 @@ "index": "pypi", "version": "==0.10.1" }, - "flask-restful": { + "flask-sqlalchemy": { "hashes": [ - "sha256:ecd620c5cc29f663627f99e04f17d1f16d095c83dc1d618426e2ad68b03092f8", - "sha256:f8240ec12349afe8df1db168ea7c336c4e5b0271a36982bff7394f93275f2ca9" + "sha256:05b31d2034dd3f2a685cbbae4cfc4ed906b2a733cff7964ada450fd5e462b84e", + "sha256:bfc7150eaf809b1c283879302f04c42791136060c6eeb12c0c6674fb1291fae5" ], "index": "pypi", - "version": "==0.3.7" - }, - "future": { - "hashes": [ - "sha256:b1bead90b70cf6ec3f0710ae53a525360fa360d306a86583adc6bf83a4db537d" - ], - "version": "==0.18.2" + "version": "==2.4.4" }, "gunicorn": { "hashes": [ @@ -113,19 +115,20 @@ "index": "pypi", "version": "==19.9.0" }, - "importlib-metadata": { + "importlib-resources": { "hashes": [ - "sha256:8c501196e49fb9df5df43833bdb1e4328f64847763ec8a50703148b73784d581", - "sha256:d7eb1dea6d6a6086f8be21784cc9e3bcfa55872b52309bc5fad53a8ea444465d" + "sha256:33a95faed5fc19b4bc16b29a6eeae248a3fe69dd55d4d229d2b480e23eeaad45", + "sha256:d756e2f85dd4de2ba89be0b21dba2a3bbec2e871a42a3a16719258a11f87506b" ], - "markers": "python_version < '3.8'", - "version": "==4.0.1" + "markers": "python_version < '3.9'", + "version": "==5.4.0" }, "itsdangerous": { "hashes": [ "sha256:321b033d07f2a4136d3ec762eac9f16a10ccd60f53c0c91af90217ace7ba1f19", "sha256:b12271b2047cb23eeb98c8b5622e2e5c5e9abd9784a153e9d8ef9cb4dd09d749" ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==1.1.0" }, "jinja2": { @@ -133,209 +136,618 @@ "sha256:03e47ad063331dd6a3f04a43eddca8a966a26ba0c5b7207a9a9e4e08f1b29419", "sha256:a6d58433de0ae800347cab1fa3043cebbabe8baa9d29e668f1c768cb87a333c6" ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", "version": "==2.11.3" }, "jsonschema": { "hashes": [ - "sha256:4e5b3cf8216f577bee9ce139cbe72eca3ea4f292ec60928ff24758ce626cd163", - "sha256:c8a85b28d377cc7737e46e2d9f2b4f44ee3c0e1deac6bf46ddefc7187d30797a" + "sha256:636694eb41b3535ed608fe04129f26542b59ed99808b4f688aa32dcf55317a83", + "sha256:77281a1f71684953ee8b3d488371b162419767973789272434bbc3f29d9c8823" ], - "version": "==3.2.0" + "markers": "python_version >= '3.7'", + "version": "==4.4.0" }, "limits": { "hashes": [ - "sha256:0e5f8b10f18dd809eb2342f5046eb9aa5e4e69a0258567b5f4aa270647d438b3", - "sha256:f0c3319f032c4bfad68438ed1325c0fac86dac64582c7c25cddc87a0b658fa20" + "sha256:9ead6236a71eb1d9a18d7e3b1faa58d588ea3510e55514fae58babc0a3223986", + "sha256:d4270d29591cc5eceab19be053455a4e619ba395062502bde2b5681af7dc1be8" ], - "version": "==1.5.1" + "markers": "python_version >= '3.7'", + "version": "==2.3.3" }, "markupsafe": { "hashes": [ - "sha256:00bc623926325b26bb9605ae9eae8a215691f33cae5df11ca5424f06f2d1f473", - "sha256:09027a7803a62ca78792ad89403b1b7a73a01c8cb65909cd876f7fcebd79b161", - "sha256:09c4b7f37d6c648cb13f9230d847adf22f8171b1ccc4d5682398e77f40309235", - "sha256:1027c282dad077d0bae18be6794e6b6b8c91d58ed8a8d89a89d59693b9131db5", - "sha256:13d3144e1e340870b25e7b10b98d779608c02016d5184cfb9927a9f10c689f42", - "sha256:195d7d2c4fbb0ee8139a6cf67194f3973a6b3042d742ebe0a9ed36d8b6f0c07f", - "sha256:22c178a091fc6630d0d045bdb5992d2dfe14e3259760e713c490da5323866c39", - "sha256:24982cc2533820871eba85ba648cd53d8623687ff11cbb805be4ff7b4c971aff", - "sha256:29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b", - "sha256:2beec1e0de6924ea551859edb9e7679da6e4870d32cb766240ce17e0a0ba2014", - "sha256:3b8a6499709d29c2e2399569d96719a1b21dcd94410a586a18526b143ec8470f", - "sha256:43a55c2930bbc139570ac2452adf3d70cdbb3cfe5912c71cdce1c2c6bbd9c5d1", - "sha256:46c99d2de99945ec5cb54f23c8cd5689f6d7177305ebff350a58ce5f8de1669e", - "sha256:500d4957e52ddc3351cabf489e79c91c17f6e0899158447047588650b5e69183", - "sha256:535f6fc4d397c1563d08b88e485c3496cf5784e927af890fb3c3aac7f933ec66", - "sha256:596510de112c685489095da617b5bcbbac7dd6384aeebeda4df6025d0256a81b", - "sha256:62fe6c95e3ec8a7fad637b7f3d372c15ec1caa01ab47926cfdf7a75b40e0eac1", - "sha256:6788b695d50a51edb699cb55e35487e430fa21f1ed838122d722e0ff0ac5ba15", - "sha256:6dd73240d2af64df90aa7c4e7481e23825ea70af4b4922f8ede5b9e35f78a3b1", - "sha256:6f1e273a344928347c1290119b493a1f0303c52f5a5eae5f16d74f48c15d4a85", - "sha256:6fffc775d90dcc9aed1b89219549b329a9250d918fd0b8fa8d93d154918422e1", - "sha256:717ba8fe3ae9cc0006d7c451f0bb265ee07739daf76355d06366154ee68d221e", - "sha256:79855e1c5b8da654cf486b830bd42c06e8780cea587384cf6545b7d9ac013a0b", - "sha256:7c1699dfe0cf8ff607dbdcc1e9b9af1755371f92a68f706051cc8c37d447c905", - "sha256:7fed13866cf14bba33e7176717346713881f56d9d2bcebab207f7a036f41b850", - "sha256:84dee80c15f1b560d55bcfe6d47b27d070b4681c699c572af2e3c7cc90a3b8e0", - "sha256:88e5fcfb52ee7b911e8bb6d6aa2fd21fbecc674eadd44118a9cc3863f938e735", - "sha256:8defac2f2ccd6805ebf65f5eeb132adcf2ab57aa11fdf4c0dd5169a004710e7d", - "sha256:98bae9582248d6cf62321dcb52aaf5d9adf0bad3b40582925ef7c7f0ed85fceb", - "sha256:98c7086708b163d425c67c7a91bad6e466bb99d797aa64f965e9d25c12111a5e", - "sha256:9add70b36c5666a2ed02b43b335fe19002ee5235efd4b8a89bfcf9005bebac0d", - "sha256:9bf40443012702a1d2070043cb6291650a0841ece432556f784f004937f0f32c", - "sha256:a6a744282b7718a2a62d2ed9d993cad6f5f585605ad352c11de459f4108df0a1", - "sha256:acf08ac40292838b3cbbb06cfe9b2cb9ec78fce8baca31ddb87aaac2e2dc3bc2", - "sha256:ade5e387d2ad0d7ebf59146cc00c8044acbd863725f887353a10df825fc8ae21", - "sha256:b00c1de48212e4cc9603895652c5c410df699856a2853135b3967591e4beebc2", - "sha256:b1282f8c00509d99fef04d8ba936b156d419be841854fe901d8ae224c59f0be5", - "sha256:b1dba4527182c95a0db8b6060cc98ac49b9e2f5e64320e2b56e47cb2831978c7", - "sha256:b2051432115498d3562c084a49bba65d97cf251f5a331c64a12ee7e04dacc51b", - "sha256:b7d644ddb4dbd407d31ffb699f1d140bc35478da613b441c582aeb7c43838dd8", - "sha256:ba59edeaa2fc6114428f1637ffff42da1e311e29382d81b339c1817d37ec93c6", - "sha256:bf5aa3cbcfdf57fa2ee9cd1822c862ef23037f5c832ad09cfea57fa846dec193", - "sha256:c8716a48d94b06bb3b2524c2b77e055fb313aeb4ea620c8dd03a105574ba704f", - "sha256:caabedc8323f1e93231b52fc32bdcde6db817623d33e100708d9a68e1f53b26b", - "sha256:cd5df75523866410809ca100dc9681e301e3c27567cf498077e8551b6d20e42f", - "sha256:cdb132fc825c38e1aeec2c8aa9338310d29d337bebbd7baa06889d09a60a1fa2", - "sha256:d53bc011414228441014aa71dbec320c66468c1030aae3a6e29778a3382d96e5", - "sha256:d73a845f227b0bfe8a7455ee623525ee656a9e2e749e4742706d80a6065d5e2c", - "sha256:d9be0ba6c527163cbed5e0857c451fcd092ce83947944d6c14bc95441203f032", - "sha256:e249096428b3ae81b08327a63a485ad0878de3fb939049038579ac0ef61e17e7", - "sha256:e8313f01ba26fbbe36c7be1966a7b7424942f670f38e666995b88d012765b9be", - "sha256:feb7b34d6325451ef96bc0e36e1a6c0c1c64bc1fbec4b854f4529e51887b1621" - ], - "version": "==1.1.1" + "sha256:01a9b8ea66f1658938f65b93a85ebe8bc016e6769611be228d797c9d998dd298", + "sha256:023cb26ec21ece8dc3907c0e8320058b2e0cb3c55cf9564da612bc325bed5e64", + "sha256:0446679737af14f45767963a1a9ef7620189912317d095f2d9ffa183a4d25d2b", + "sha256:04635854b943835a6ea959e948d19dcd311762c5c0c6e1f0e16ee57022669194", + "sha256:0717a7390a68be14b8c793ba258e075c6f4ca819f15edfc2a3a027c823718567", + "sha256:0955295dd5eec6cb6cc2fe1698f4c6d84af2e92de33fbcac4111913cd100a6ff", + "sha256:0d4b31cc67ab36e3392bbf3862cfbadac3db12bdd8b02a2731f509ed5b829724", + "sha256:10f82115e21dc0dfec9ab5c0223652f7197feb168c940f3ef61563fc2d6beb74", + "sha256:168cd0a3642de83558a5153c8bd34f175a9a6e7f6dc6384b9655d2697312a646", + "sha256:1d609f577dc6e1aa17d746f8bd3c31aa4d258f4070d61b2aa5c4166c1539de35", + "sha256:1f2ade76b9903f39aa442b4aadd2177decb66525062db244b35d71d0ee8599b6", + "sha256:20dca64a3ef2d6e4d5d615a3fd418ad3bde77a47ec8a23d984a12b5b4c74491a", + "sha256:2a7d351cbd8cfeb19ca00de495e224dea7e7d919659c2841bbb7f420ad03e2d6", + "sha256:2d7d807855b419fc2ed3e631034685db6079889a1f01d5d9dac950f764da3dad", + "sha256:2ef54abee730b502252bcdf31b10dacb0a416229b72c18b19e24a4509f273d26", + "sha256:36bc903cbb393720fad60fc28c10de6acf10dc6cc883f3e24ee4012371399a38", + "sha256:37205cac2a79194e3750b0af2a5720d95f786a55ce7df90c3af697bfa100eaac", + "sha256:3c112550557578c26af18a1ccc9e090bfe03832ae994343cfdacd287db6a6ae7", + "sha256:3dd007d54ee88b46be476e293f48c85048603f5f516008bee124ddd891398ed6", + "sha256:4296f2b1ce8c86a6aea78613c34bb1a672ea0e3de9c6ba08a960efe0b0a09047", + "sha256:47ab1e7b91c098ab893b828deafa1203de86d0bc6ab587b160f78fe6c4011f75", + "sha256:49e3ceeabbfb9d66c3aef5af3a60cc43b85c33df25ce03d0031a608b0a8b2e3f", + "sha256:4dc8f9fb58f7364b63fd9f85013b780ef83c11857ae79f2feda41e270468dd9b", + "sha256:4efca8f86c54b22348a5467704e3fec767b2db12fc39c6d963168ab1d3fc9135", + "sha256:53edb4da6925ad13c07b6d26c2a852bd81e364f95301c66e930ab2aef5b5ddd8", + "sha256:5855f8438a7d1d458206a2466bf82b0f104a3724bf96a1c781ab731e4201731a", + "sha256:594c67807fb16238b30c44bdf74f36c02cdf22d1c8cda91ef8a0ed8dabf5620a", + "sha256:5b6d930f030f8ed98e3e6c98ffa0652bdb82601e7a016ec2ab5d7ff23baa78d1", + "sha256:5bb28c636d87e840583ee3adeb78172efc47c8b26127267f54a9c0ec251d41a9", + "sha256:60bf42e36abfaf9aff1f50f52644b336d4f0a3fd6d8a60ca0d054ac9f713a864", + "sha256:611d1ad9a4288cf3e3c16014564df047fe08410e628f89805e475368bd304914", + "sha256:6300b8454aa6930a24b9618fbb54b5a68135092bc666f7b06901f897fa5c2fee", + "sha256:63f3268ba69ace99cab4e3e3b5840b03340efed0948ab8f78d2fd87ee5442a4f", + "sha256:6557b31b5e2c9ddf0de32a691f2312a32f77cd7681d8af66c2692efdbef84c18", + "sha256:693ce3f9e70a6cf7d2fb9e6c9d8b204b6b39897a2c4a1aa65728d5ac97dcc1d8", + "sha256:6a7fae0dd14cf60ad5ff42baa2e95727c3d81ded453457771d02b7d2b3f9c0c2", + "sha256:6c4ca60fa24e85fe25b912b01e62cb969d69a23a5d5867682dd3e80b5b02581d", + "sha256:6fcf051089389abe060c9cd7caa212c707e58153afa2c649f00346ce6d260f1b", + "sha256:7d91275b0245b1da4d4cfa07e0faedd5b0812efc15b702576d103293e252af1b", + "sha256:89c687013cb1cd489a0f0ac24febe8c7a666e6e221b783e53ac50ebf68e45d86", + "sha256:8d206346619592c6200148b01a2142798c989edcb9c896f9ac9722a99d4e77e6", + "sha256:905fec760bd2fa1388bb5b489ee8ee5f7291d692638ea5f67982d968366bef9f", + "sha256:97383d78eb34da7e1fa37dd273c20ad4320929af65d156e35a5e2d89566d9dfb", + "sha256:984d76483eb32f1bcb536dc27e4ad56bba4baa70be32fa87152832cdd9db0833", + "sha256:99df47edb6bda1249d3e80fdabb1dab8c08ef3975f69aed437cb69d0a5de1e28", + "sha256:9f02365d4e99430a12647f09b6cc8bab61a6564363f313126f775eb4f6ef798e", + "sha256:a30e67a65b53ea0a5e62fe23682cfe22712e01f453b95233b25502f7c61cb415", + "sha256:ab3ef638ace319fa26553db0624c4699e31a28bb2a835c5faca8f8acf6a5a902", + "sha256:aca6377c0cb8a8253e493c6b451565ac77e98c2951c45f913e0b52facdcff83f", + "sha256:add36cb2dbb8b736611303cd3bfcee00afd96471b09cda130da3581cbdc56a6d", + "sha256:b2f4bf27480f5e5e8ce285a8c8fd176c0b03e93dcc6646477d4630e83440c6a9", + "sha256:b7f2d075102dc8c794cbde1947378051c4e5180d52d276987b8d28a3bd58c17d", + "sha256:baa1a4e8f868845af802979fcdbf0bb11f94f1cb7ced4c4b8a351bb60d108145", + "sha256:be98f628055368795d818ebf93da628541e10b75b41c559fdf36d104c5787066", + "sha256:bf5d821ffabf0ef3533c39c518f3357b171a1651c1ff6827325e4489b0e46c3c", + "sha256:c47adbc92fc1bb2b3274c4b3a43ae0e4573d9fbff4f54cd484555edbf030baf1", + "sha256:cdfba22ea2f0029c9261a4bd07e830a8da012291fbe44dc794e488b6c9bb353a", + "sha256:d6c7ebd4e944c85e2c3421e612a7057a2f48d478d79e61800d81468a8d842207", + "sha256:d7f9850398e85aba693bb640262d3611788b1f29a79f0c93c565694658f4071f", + "sha256:d8446c54dc28c01e5a2dbac5a25f071f6653e6e40f3a8818e8b45d790fe6ef53", + "sha256:deb993cacb280823246a026e3b2d81c493c53de6acfd5e6bfe31ab3402bb37dd", + "sha256:e0f138900af21926a02425cf736db95be9f4af72ba1bb21453432a07f6082134", + "sha256:e9936f0b261d4df76ad22f8fee3ae83b60d7c3e871292cd42f40b81b70afae85", + "sha256:f0567c4dc99f264f49fe27da5f735f414c4e7e7dd850cfd8e69f0862d7c74ea9", + "sha256:f5653a225f31e113b152e56f154ccbe59eeb1c7487b39b9d9f9cdb58e6c79dc5", + "sha256:f826e31d18b516f653fe296d967d700fddad5901ae07c622bb3705955e1faa94", + "sha256:f8ba0e8349a38d3001fae7eadded3f6606f0da5d748ee53cc1dab1d6527b9509", + "sha256:f9081981fe268bd86831e5c75f7de206ef275defcb82bc70740ae6dc507aee51", + "sha256:fa130dd50c57d53368c9d59395cb5526eda596d3ffe36666cd81a44d56e48872" + ], + "markers": "python_version >= '3.6'", + "version": "==2.0.1" }, "marshmallow": { "hashes": [ - "sha256:0dd42891a5ef288217ed6410917f3c6048f585f8692075a0052c24f9bfff9dfd", - "sha256:16e99cb7f630c0ef4d7d364ed0109ac194268dde123966076ab3dafb9ae3906b" + "sha256:04438610bc6dadbdddb22a4a55bcc7f6f8099e69580b2e67f5a681933a1f4400", + "sha256:4c05c1684e0e97fe779c62b91878f173b937fe097b356cd82f793464f5bc6138" ], - "version": "==3.11.1" + "markers": "python_version >= '3.6'", + "version": "==3.14.1" }, - "mistune": { + "marshmallow-sqlalchemy": { "hashes": [ - "sha256:59a3429db53c50b5c6bcc8a07f8848cb00d7dc8bdb431a4ab41920d201d4756e", - "sha256:88a1051873018da288eee8538d476dffe1262495144b33ecb586c4ab266bb8d4" + "sha256:1521b129564444648c523a38f6446c137f1aae5c9c7de1ec151d5ebf03fd407d", + "sha256:a11fdb628e78c70853646cd7d6d56e07fd56cc702e9675f9abb34832ea055ffe" ], - "version": "==0.8.4" + "index": "pypi", + "version": "==0.27.0" }, - "mysql-connector": { + "mistune": { "hashes": [ - "sha256:1733e6ce52a049243de3264f1fbc22a852cb35458c4ad739ba88189285efdf32" + "sha256:6bab6c6abd711c4604206c7d8cad5cd48b28f072b4bb75797d74146ba393a049", + "sha256:6fc88c3cb49dba8b16687b41725e661cf85784c12e8974a29b9d336dd596c3a1" + ], + "version": "==2.0.2" + }, + "mysql-connector-python": { + "hashes": [ + "sha256:04d75ec7c181e7907df3d40c2a573063f25ecfc5a95a7a90374861c02ce738a9", + "sha256:47f059bc2a7378acd56ac7a60b0526a2ba95d96b696a875b5b233a0feae30980", + "sha256:4d126ce5e03675d926a9e49ce1638d06af43ca7bac2b502d93373dc9425d386f", + "sha256:50c87ff50762f4a0cc0816365dde0e7de763949e125488b8e872de6471e0e427", + "sha256:687071dc9e51892d0861bbcbcbd48e0f3579e3155f2a0ec310198704137c775a", + "sha256:73c5149b33401610e28589d1fc669cba11d3b16215a8f6a75f63ece1f3af5f88", + "sha256:77ec293e265d01db1896a8e63a16b3d5c848a885cf76c77148adfed8453846e8", + "sha256:78bb1abb57bbb85263d65a240a901195e3de0e0992f25e42c48af0869079bb74", + "sha256:7d518491d6d51b186b3182b3698b1560d9bd80675c055163359d0aeea0001de1", + "sha256:8d8dd02e0e6bb7262156a836c3e83582d1a1a1ebb9d72e777a46813709404601", + "sha256:91be638d1b084835edf7aa426d85228174611a1cd6f016ca0f6d4339ac3d9d7b", + "sha256:aaec9d13fc0177e421a3c4392f0eaf86347b825949d5dfc202d535cdb1e07f04", + "sha256:b3a747c5efd6de7b76686ab93834186e2276a62684600dbede615537040436ca", + "sha256:b4c5ce835078555b6640921cae036daad46884dd21027f43c742fb505221e4e6", + "sha256:bb317b179bfbb3e86c771bb2b34794188a2d2b010cdaa1b4d1b5ea0961d0812c", + "sha256:bd89598b173aa0fc525b59fff6e3598ff3cabad4260a3bb49cf420eac10d3b3b", + "sha256:bdb4f187f737316d1c403085b2fb7c91717268d052ecbfc86066cef59f6d72a4", + "sha256:c76d771fdce1314b07619efff184ec03f56abef6b4ccdc686d3a995f5b225fec", + "sha256:d559f69e8b58ac248e37d30e5676718adf69eeff56ed8a7c03f064d74af68f99", + "sha256:e008127430c8dc66bb1b6d6c7a17498ec57ffa81188fc1f8c9f764363c01d12e", + "sha256:f5da43c77d409c8135132f5b5aee9ac91c2e97c3f87352e1b3017438a9cb9b82" ], "index": "pypi", - "version": "==2.2.9" + "version": "==8.0.28" + }, + "protobuf": { + "hashes": [ + "sha256:072fbc78d705d3edc7ccac58a62c4c8e0cec856987da7df8aca86e647be4e35c", + "sha256:09297b7972da685ce269ec52af761743714996b4381c085205914c41fcab59fb", + "sha256:16f519de1313f1b7139ad70772e7db515b1420d208cb16c6d7858ea989fc64a9", + "sha256:1c91ef4110fdd2c590effb5dca8fdbdcb3bf563eece99287019c4204f53d81a4", + "sha256:3112b58aac3bac9c8be2b60a9daf6b558ca3f7681c130dcdd788ade7c9ffbdca", + "sha256:36cecbabbda242915529b8ff364f2263cd4de7c46bbe361418b5ed859677ba58", + "sha256:4276cdec4447bd5015453e41bdc0c0c1234eda08420b7c9a18b8d647add51e4b", + "sha256:435bb78b37fc386f9275a7035fe4fb1364484e38980d0dd91bc834a02c5ec909", + "sha256:48ed3877fa43e22bcacc852ca76d4775741f9709dd9575881a373bd3e85e54b2", + "sha256:54a1473077f3b616779ce31f477351a45b4fef8c9fd7892d6d87e287a38df368", + "sha256:69da7d39e39942bd52848438462674c463e23963a1fdaa84d88df7fbd7e749b2", + "sha256:6cbc312be5e71869d9d5ea25147cdf652a6781cf4d906497ca7690b7b9b5df13", + "sha256:7bb03bc2873a2842e5ebb4801f5c7ff1bfbdf426f85d0172f7644fcda0671ae0", + "sha256:7ca7da9c339ca8890d66958f5462beabd611eca6c958691a8fe6eccbd1eb0c6e", + "sha256:835a9c949dc193953c319603b2961c5c8f4327957fe23d914ca80d982665e8ee", + "sha256:84123274d982b9e248a143dadd1b9815049f4477dc783bf84efe6250eb4b836a", + "sha256:8961c3a78ebfcd000920c9060a262f082f29838682b1f7201889300c1fbe0616", + "sha256:96bd766831596d6014ca88d86dc8fe0fb2e428c0b02432fd9db3943202bf8c5e", + "sha256:9df0c10adf3e83015ced42a9a7bd64e13d06c4cf45c340d2c63020ea04499d0a", + "sha256:b38057450a0c566cbd04890a40edf916db890f2818e8682221611d78dc32ae26", + "sha256:bd95d1dfb9c4f4563e6093a9aa19d9c186bf98fa54da5252531cc0d3a07977e7", + "sha256:c1068287025f8ea025103e37d62ffd63fec8e9e636246b89c341aeda8a67c934", + "sha256:c438268eebb8cf039552897d78f402d734a404f1360592fef55297285f7f953f", + "sha256:cdc076c03381f5c1d9bb1abdcc5503d9ca8b53cf0a9d31a9f6754ec9e6c8af0f", + "sha256:f358aa33e03b7a84e0d91270a4d4d8f5df6921abe99a377828839e8ed0c04e07", + "sha256:f51d5a9f137f7a2cec2d326a74b6e3fc79d635d69ffe1b036d39fc7d75430d37" + ], + "markers": "python_version >= '3.5'", + "version": "==3.19.4" }, "pyasn1": { "hashes": [ + "sha256:014c0e9976956a08139dc0712ae195324a75e142284d5f87f1a87ee1b068a359", + "sha256:03840c999ba71680a131cfaee6fab142e1ed9bbd9c693e285cc6aca0d555e576", + "sha256:0458773cfe65b153891ac249bcf1b5f8f320b7c2ce462151f8fa74de8934becf", + "sha256:08c3c53b75eaa48d71cf8c710312316392ed40899cb34710d092e96745a358b7", "sha256:39c7e2ec30515947ff4e87fb6f456dfc6e84857d34be479c9d4a4ba4bf46aa5d", - "sha256:aef77c9fb94a3ac588e87841208bdec464471d9871bd5050a287cc9a475cd0ba" + "sha256:5c9414dcfede6e441f7e8f81b43b34e834731003427e5b09e4e00e3172a10f00", + "sha256:6e7545f1a61025a4e58bb336952c5061697da694db1cae97b116e9c46abcf7c8", + "sha256:78fa6da68ed2727915c4767bb386ab32cdba863caa7dbe473eaae45f9959da86", + "sha256:7ab8a544af125fb704feadb008c99a88805126fb525280b2270bb25cc1d78a12", + "sha256:99fcc3c8d804d1bc6d9a099921e39d827026409a58f2a720dcdb89374ea0c776", + "sha256:aef77c9fb94a3ac588e87841208bdec464471d9871bd5050a287cc9a475cd0ba", + "sha256:e89bf84b5437b532b0803ba5c9a5e054d21fec423a89952a74f87fa2c9b7bce2", + "sha256:fec3e9d8e36808a28efb59b489e4528c10ad0f480e57dcc32b4de5c9d8c9fdf3" ], "version": "==0.4.8" }, "pyrsistent": { "hashes": [ - "sha256:2e636185d9eb976a18a8a8e96efce62f2905fea90041958d8cc2a189756ebf3e" - ], - "version": "==0.17.3" + "sha256:0e3e1fcc45199df76053026a51cc59ab2ea3fc7c094c6627e93b7b44cdae2c8c", + "sha256:1b34eedd6812bf4d33814fca1b66005805d3640ce53140ab8bbb1e2651b0d9bc", + "sha256:4ed6784ceac462a7d6fcb7e9b663e93b9a6fb373b7f43594f9ff68875788e01e", + "sha256:5d45866ececf4a5fff8742c25722da6d4c9e180daa7b405dc0a2a2790d668c26", + "sha256:636ce2dc235046ccd3d8c56a7ad54e99d5c1cd0ef07d9ae847306c91d11b5fec", + "sha256:6455fc599df93d1f60e1c5c4fe471499f08d190d57eca040c0ea182301321286", + "sha256:6bc66318fb7ee012071b2792024564973ecc80e9522842eb4e17743604b5e045", + "sha256:7bfe2388663fd18bd8ce7db2c91c7400bf3e1a9e8bd7d63bf7e77d39051b85ec", + "sha256:7ec335fc998faa4febe75cc5268a9eac0478b3f681602c1f27befaf2a1abe1d8", + "sha256:914474c9f1d93080338ace89cb2acee74f4f666fb0424896fcfb8d86058bf17c", + "sha256:b568f35ad53a7b07ed9b1b2bae09eb15cdd671a5ba5d2c66caee40dbf91c68ca", + "sha256:cdfd2c361b8a8e5d9499b9082b501c452ade8bbf42aef97ea04854f4a3f43b22", + "sha256:d1b96547410f76078eaf66d282ddca2e4baae8964364abb4f4dcdde855cd123a", + "sha256:d4d61f8b993a7255ba714df3aca52700f8125289f84f704cf80916517c46eb96", + "sha256:d7a096646eab884bf8bed965bad63ea327e0d0c38989fc83c5ea7b8a87037bfc", + "sha256:df46c854f490f81210870e509818b729db4488e1f30f2a1ce1698b2295a878d1", + "sha256:e24a828f57e0c337c8d8bb9f6b12f09dfdf0273da25fda9e314f0b684b415a07", + "sha256:e4f3149fd5eb9b285d6bfb54d2e5173f6a116fe19172686797c056672689daf6", + "sha256:e92a52c166426efbe0d1ec1332ee9119b6d32fc1f0bbfd55d5c1088070e7fc1b", + "sha256:f87cc2863ef33c709e237d4b5f4502a62a00fab450c9e020892e8e2ede5847f5", + "sha256:fd8da6d0124efa2f67d86fa70c851022f87c98e205f0594e1fae044e7119a5a6" + ], + "markers": "python_version >= '3.7'", + "version": "==0.18.1" }, - "python-dotenv": { + "python-jose": { "hashes": [ - "sha256:debd928b49dbc2bf68040566f55cdb3252458036464806f4094487244e2a4093", - "sha256:f157d71d5fec9d4bd5f51c82746b6344dffa680ee85217c123f4a0c8117c4544" + "sha256:55779b5e6ad599c6336191246e95eb2293a9ddebd555f796a65f838f07e5d78a", + "sha256:9b1376b023f8b298536eedd47ae1089bcdb848f1535ab30555cd92002d78923a" ], "index": "pypi", - "version": "==0.10.3" + "version": "==3.3.0" }, - "python-jose": { + "pyyaml": { "hashes": [ - "sha256:29701d998fe560e52f17246c3213a882a4a39da7e42c7015bcc1f7823ceaff1c", - "sha256:ed7387f0f9af2ea0ddc441d83a6eb47a5909bd0c8a72ac3250e75afec2cc1371" + "sha256:0283c35a6a9fbf047493e3a0ce8d79ef5030852c51e9d911a27badfde0605293", + "sha256:055d937d65826939cb044fc8c9b08889e8c743fdc6a32b33e2390f66013e449b", + "sha256:07751360502caac1c067a8132d150cf3d61339af5691fe9e87803040dbc5db57", + "sha256:0b4624f379dab24d3725ffde76559cff63d9ec94e1736b556dacdfebe5ab6d4b", + "sha256:0ce82d761c532fe4ec3f87fc45688bdd3a4c1dc5e0b4a19814b9009a29baefd4", + "sha256:1e4747bc279b4f613a09eb64bba2ba602d8a6664c6ce6396a4d0cd413a50ce07", + "sha256:213c60cd50106436cc818accf5baa1aba61c0189ff610f64f4a3e8c6726218ba", + "sha256:231710d57adfd809ef5d34183b8ed1eeae3f76459c18fb4a0b373ad56bedcdd9", + "sha256:277a0ef2981ca40581a47093e9e2d13b3f1fbbeffae064c1d21bfceba2030287", + "sha256:2cd5df3de48857ed0544b34e2d40e9fac445930039f3cfe4bcc592a1f836d513", + "sha256:40527857252b61eacd1d9af500c3337ba8deb8fc298940291486c465c8b46ec0", + "sha256:473f9edb243cb1935ab5a084eb238d842fb8f404ed2193a915d1784b5a6b5fc0", + "sha256:48c346915c114f5fdb3ead70312bd042a953a8ce5c7106d5bfb1a5254e47da92", + "sha256:50602afada6d6cbfad699b0c7bb50d5ccffa7e46a3d738092afddc1f9758427f", + "sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2", + "sha256:77f396e6ef4c73fdc33a9157446466f1cff553d979bd00ecb64385760c6babdc", + "sha256:819b3830a1543db06c4d4b865e70ded25be52a2e0631ccd2f6a47a2822f2fd7c", + "sha256:897b80890765f037df3403d22bab41627ca8811ae55e9a722fd0392850ec4d86", + "sha256:98c4d36e99714e55cfbaaee6dd5badbc9a1ec339ebfc3b1f52e293aee6bb71a4", + "sha256:9df7ed3b3d2e0ecfe09e14741b857df43adb5a3ddadc919a2d94fbdf78fea53c", + "sha256:9fa600030013c4de8165339db93d182b9431076eb98eb40ee068700c9c813e34", + "sha256:a80a78046a72361de73f8f395f1f1e49f956c6be882eed58505a15f3e430962b", + "sha256:b3d267842bf12586ba6c734f89d1f5b871df0273157918b0ccefa29deb05c21c", + "sha256:b5b9eccad747aabaaffbc6064800670f0c297e52c12754eb1d976c57e4f74dcb", + "sha256:c5687b8d43cf58545ade1fe3e055f70eac7a5a1a0bf42824308d868289a95737", + "sha256:cba8c411ef271aa037d7357a2bc8f9ee8b58b9965831d9e51baf703280dc73d3", + "sha256:d15a181d1ecd0d4270dc32edb46f7cb7733c7c508857278d3d378d14d606db2d", + "sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53", + "sha256:d4eccecf9adf6fbcc6861a38015c2a64f38b9d94838ac1810a9023a0609e1b78", + "sha256:d67d839ede4ed1b28a4e8909735fc992a923cdb84e618544973d7dfc71540803", + "sha256:daf496c58a8c52083df09b80c860005194014c3698698d1a57cbcfa182142a3a", + "sha256:e61ceaab6f49fb8bdfaa0f92c4b57bcfbea54c09277b1b4f7ac376bfb7a7c174", + "sha256:f84fbc98b019fef2ee9a1cb3ce93e3187a6df0b2538a651bfb890254ba9f90b5" + ], + "version": "==6.0" + }, + "rsa": { + "hashes": [ + "sha256:5c6bd9dc7a543b7fe4304a631f8a8a3b674e2bbfc49c2ae96200cdbe55df6b17", + "sha256:95c5d300c4e879ee69708c428ba566c59478fd653cc3a22243eeb8ed846950bb" + ], + "markers": "python_version >= '3.6' and python_version < '4'", + "version": "==4.8" + }, + "six": { + "hashes": [ + "sha256:3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c", + "sha256:d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73" + ], + "index": "pypi", + "version": "==1.12.0" + }, + "sqlalchemy": { + "hashes": [ + "sha256:014ea143572fee1c18322b7908140ad23b3994036ef4c0d630110faf942652f8", + "sha256:0172423a27fbcae3751ef016663b72e1a516777de324a76e30efa170dbd3dd2d", + "sha256:01aa5f803db724447c1d423ed583e42bf5264c597fd55e4add4301f163b0be48", + "sha256:0352db1befcbed2f9282e72843f1963860bf0e0472a4fa5cf8ee084318e0e6ab", + "sha256:09083c2487ca3c0865dc588e07aeaa25416da3d95f7482c07e92f47e080aa17b", + "sha256:0d5d862b1cfbec5028ce1ecac06a3b42bc7703eb80e4b53fceb2738724311443", + "sha256:14f0eb5db872c231b20c18b1e5806352723a3a89fb4254af3b3e14f22eaaec75", + "sha256:1e2f89d2e5e3c7a88e25a3b0e43626dba8db2aa700253023b82e630d12b37109", + "sha256:26155ea7a243cbf23287f390dba13d7927ffa1586d3208e0e8d615d0c506f996", + "sha256:2ed6343b625b16bcb63c5b10523fd15ed8934e1ed0f772c534985e9f5e73d894", + "sha256:34fcec18f6e4b24b4a5f6185205a04f1eab1e56f8f1d028a2a03694ebcc2ddd4", + "sha256:4d0e3515ef98aa4f0dc289ff2eebb0ece6260bbf37c2ea2022aad63797eacf60", + "sha256:5de2464c254380d8a6c20a2746614d5a436260be1507491442cf1088e59430d2", + "sha256:6607ae6cd3a07f8a4c3198ffbf256c261661965742e2b5265a77cd5c679c9bba", + "sha256:8110e6c414d3efc574543109ee618fe2c1f96fa31833a1ff36cc34e968c4f233", + "sha256:816de75418ea0953b5eb7b8a74933ee5a46719491cd2b16f718afc4b291a9658", + "sha256:861e459b0e97673af6cc5e7f597035c2e3acdfb2608132665406cded25ba64c7", + "sha256:87a2725ad7d41cd7376373c15fd8bf674e9c33ca56d0b8036add2d634dba372e", + "sha256:a006d05d9aa052657ee3e4dc92544faae5fcbaafc6128217310945610d862d39", + "sha256:bce28277f308db43a6b4965734366f533b3ff009571ec7ffa583cb77539b84d6", + "sha256:c10ff6112d119f82b1618b6dc28126798481b9355d8748b64b9b55051eb4f01b", + "sha256:d375d8ccd3cebae8d90270f7aa8532fe05908f79e78ae489068f3b4eee5994e8", + "sha256:d37843fb8df90376e9e91336724d78a32b988d3d20ab6656da4eb8ee3a45b63c", + "sha256:e47e257ba5934550d7235665eee6c911dc7178419b614ba9e1fbb1ce6325b14f", + "sha256:e98d09f487267f1e8d1179bf3b9d7709b30a916491997137dd24d6ae44d18d79", + "sha256:ebbb777cbf9312359b897bf81ba00dae0f5cb69fba2a18265dcc18a6f5ef7519", + "sha256:ee5f5188edb20a29c1cc4a039b074fdc5575337c9a68f3063449ab47757bb064", + "sha256:f03bd97650d2e42710fbe4cf8a59fae657f191df851fc9fc683ecef10746a375", + "sha256:f1149d6e5c49d069163e58a3196865e4321bad1803d7886e07d8710de392c548", + "sha256:f3c5c52f7cb8b84bfaaf22d82cb9e6e9a8297f7c2ed14d806a0f5e4d22e83fb7", + "sha256:f597a243b8550a3a0b15122b14e49d8a7e622ba1c9d29776af741f1845478d79", + "sha256:fc1f2a5a5963e2e73bac4926bdaf7790c4d7d77e8fc0590817880e22dd9d0b8b", + "sha256:fc4cddb0b474b12ed7bdce6be1b9edc65352e8ce66bc10ff8cbbfb3d4047dbf4", + "sha256:fcb251305fa24a490b6a9ee2180e5f8252915fb778d3dafc70f9cc3f863827b9" ], "index": "pypi", - "version": "==3.0.1" + "version": "==1.3.24" }, - "pytz": { + "werkzeug": { "hashes": [ - "sha256:83a4a90894bf38e243cf052c8b58f381bfe9a7a483f6a9cab140bc7f702ac4da", - "sha256:eb10ce3e7736052ed3623d49975ce333bcd712c7bb19a58b9e2089d4057d0798" + "sha256:2de2a5db0baeae7b2d2664949077c2ac63fbd16d98da0ff71837f7d1dea3fd43", + "sha256:6c80b1e5ad3665290ea39320b91e1be1e0d5f60652b964a3070216de83d2e47c" ], - "version": "==2021.1" + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", + "version": "==1.0.1" }, - "pyyaml": { + "zipp": { "hashes": [ - "sha256:08682f6b72c722394747bddaf0aa62277e02557c0fd1c42cb853016a38f8dedf", - "sha256:0f5f5786c0e09baddcd8b4b45f20a7b5d61a7e7e99846e3c799b05c7c53fa696", - "sha256:129def1b7c1bf22faffd67b8f3724645203b79d8f4cc81f674654d9902cb4393", - "sha256:294db365efa064d00b8d1ef65d8ea2c3426ac366c0c4368d930bf1c5fb497f77", - "sha256:3b2b1824fe7112845700f815ff6a489360226a5609b96ec2190a45e62a9fc922", - "sha256:3bd0e463264cf257d1ffd2e40223b197271046d09dadf73a0fe82b9c1fc385a5", - "sha256:4465124ef1b18d9ace298060f4eccc64b0850899ac4ac53294547536533800c8", - "sha256:49d4cdd9065b9b6e206d0595fee27a96b5dd22618e7520c33204a4a3239d5b10", - "sha256:4e0583d24c881e14342eaf4ec5fbc97f934b999a6828693a99157fde912540cc", - "sha256:5accb17103e43963b80e6f837831f38d314a0495500067cb25afab2e8d7a4018", - "sha256:607774cbba28732bfa802b54baa7484215f530991055bb562efbed5b2f20a45e", - "sha256:6c78645d400265a062508ae399b60b8c167bf003db364ecb26dcab2bda048253", - "sha256:72a01f726a9c7851ca9bfad6fd09ca4e090a023c00945ea05ba1638c09dc3347", - "sha256:74c1485f7707cf707a7aef42ef6322b8f97921bd89be2ab6317fd782c2d53183", - "sha256:895f61ef02e8fed38159bb70f7e100e00f471eae2bc838cd0f4ebb21e28f8541", - "sha256:8c1be557ee92a20f184922c7b6424e8ab6691788e6d86137c5d93c1a6ec1b8fb", - "sha256:bb4191dfc9306777bc594117aee052446b3fa88737cd13b7188d0e7aa8162185", - "sha256:bfb51918d4ff3d77c1c856a9699f8492c612cde32fd3bcd344af9be34999bfdc", - "sha256:c20cfa2d49991c8b4147af39859b167664f2ad4561704ee74c1de03318e898db", - "sha256:cb333c16912324fd5f769fff6bc5de372e9e7a202247b48870bc251ed40239aa", - "sha256:d2d9808ea7b4af864f35ea216be506ecec180628aced0704e34aca0b040ffe46", - "sha256:d483ad4e639292c90170eb6f7783ad19490e7a8defb3e46f97dfe4bacae89122", - "sha256:dd5de0646207f053eb0d6c74ae45ba98c3395a571a2891858e87df7c9b9bd51b", - "sha256:e1d4970ea66be07ae37a3c2e48b5ec63f7ba6804bdddfdbd3cfd954d25a82e63", - "sha256:e4fac90784481d221a8e4b1162afa7c47ed953be40d31ab4629ae917510051df", - "sha256:fa5ae20527d8e831e8230cbffd9f8fe952815b2b7dae6ffec25318803a7528fc", - "sha256:fd7f6999a8070df521b6384004ef42833b9bd62cfee11a09bda1079b4b704247", - "sha256:fdc842473cd33f45ff6bce46aea678a54e3d21f1b61a7750ce3c498eedfe25d6", - "sha256:fe69978f3f768926cfa37b867e3843918e012cf83f680806599ddce33c2c68b0" - ], - "version": "==5.4.1" + "sha256:9f50f446828eb9d45b267433fd3e9da8d801f614129124863f9c51ebceafb87d", + "sha256:b47250dd24f92b7dd6a0a8fc5244da14608f3ca90a5efcd37a3b1642fac9a375" + ], + "markers": "python_version < '3.10'", + "version": "==3.7.0" + } + }, + "develop": { + "alembic": { + "hashes": [ + "sha256:6c0c05e9768a896d804387e20b299880fe01bc56484246b0dffe8075d6d3d847", + "sha256:ad842f2c3ab5c5d4861232730779c05e33db4ba880a08b85eb505e87c01095bc" + ], + "markers": "python_version >= '3.6'", + "version": "==1.7.6" }, - "rsa": { + "click": { "hashes": [ - "sha256:69805d6b69f56eb05b62daea3a7dbd7aa44324ad1306445e05da8060232d00f4", - "sha256:a8774e55b59fd9fc893b0d05e9bfc6f47081f46ff5b46f39ccf24631b7be356b" + "sha256:d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a", + "sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", + "version": "==7.1.2" + }, + "flask": { + "hashes": [ + "sha256:0fbeb6180d383a9186d0d6ed954e0042ad9f18e0e8de088b2b419d526927d196", + "sha256:c34f04500f2cbbea882b1acb02002ad6fe6b7ffa64a6164577995657f50aed22" ], "index": "pypi", - "version": "==4.7" + "version": "==1.1.4" }, - "six": { + "flask-migrate": { "hashes": [ - "sha256:3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c", - "sha256:d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73" + "sha256:57d6060839e3a7f150eaab6fe4e726d9e3e7cffe2150fb223d73f92421c6d1d9", + "sha256:a6498706241aba6be7a251078de9cf166d74307bca41a4ca3e403c9d39e2f897" ], "index": "pypi", - "version": "==1.12.0" + "version": "==3.1.0" + }, + "flask-sqlalchemy": { + "hashes": [ + "sha256:05b31d2034dd3f2a685cbbae4cfc4ed906b2a733cff7964ada450fd5e462b84e", + "sha256:bfc7150eaf809b1c283879302f04c42791136060c6eeb12c0c6674fb1291fae5" + ], + "index": "pypi", + "version": "==2.4.4" + }, + "greenlet": { + "hashes": [ + "sha256:0051c6f1f27cb756ffc0ffbac7d2cd48cb0362ac1736871399a739b2885134d3", + "sha256:00e44c8afdbe5467e4f7b5851be223be68adb4272f44696ee71fe46b7036a711", + "sha256:013d61294b6cd8fe3242932c1c5e36e5d1db2c8afb58606c5a67efce62c1f5fd", + "sha256:049fe7579230e44daef03a259faa24511d10ebfa44f69411d99e6a184fe68073", + "sha256:14d4f3cd4e8b524ae9b8aa567858beed70c392fdec26dbdb0a8a418392e71708", + "sha256:166eac03e48784a6a6e0e5f041cfebb1ab400b394db188c48b3a84737f505b67", + "sha256:17ff94e7a83aa8671a25bf5b59326ec26da379ace2ebc4411d690d80a7fbcf23", + "sha256:1e12bdc622676ce47ae9abbf455c189e442afdde8818d9da983085df6312e7a1", + "sha256:21915eb821a6b3d9d8eefdaf57d6c345b970ad722f856cd71739493ce003ad08", + "sha256:288c6a76705dc54fba69fbcb59904ae4ad768b4c768839b8ca5fdadec6dd8cfd", + "sha256:2bde6792f313f4e918caabc46532aa64aa27a0db05d75b20edfc5c6f46479de2", + "sha256:32ca72bbc673adbcfecb935bb3fb1b74e663d10a4b241aaa2f5a75fe1d1f90aa", + "sha256:356b3576ad078c89a6107caa9c50cc14e98e3a6c4874a37c3e0273e4baf33de8", + "sha256:40b951f601af999a8bf2ce8c71e8aaa4e8c6f78ff8afae7b808aae2dc50d4c40", + "sha256:572e1787d1460da79590bf44304abbc0a2da944ea64ec549188fa84d89bba7ab", + "sha256:58df5c2a0e293bf665a51f8a100d3e9956febfbf1d9aaf8c0677cf70218910c6", + "sha256:64e6175c2e53195278d7388c454e0b30997573f3f4bd63697f88d855f7a6a1fc", + "sha256:7227b47e73dedaa513cdebb98469705ef0d66eb5a1250144468e9c3097d6b59b", + "sha256:7418b6bfc7fe3331541b84bb2141c9baf1ec7132a7ecd9f375912eca810e714e", + "sha256:7cbd7574ce8e138bda9df4efc6bf2ab8572c9aff640d8ecfece1b006b68da963", + "sha256:7ff61ff178250f9bb3cd89752df0f1dd0e27316a8bd1465351652b1b4a4cdfd3", + "sha256:833e1551925ed51e6b44c800e71e77dacd7e49181fdc9ac9a0bf3714d515785d", + "sha256:8639cadfda96737427330a094476d4c7a56ac03de7265622fcf4cfe57c8ae18d", + "sha256:8c5d5b35f789a030ebb95bff352f1d27a93d81069f2adb3182d99882e095cefe", + "sha256:8c790abda465726cfb8bb08bd4ca9a5d0a7bd77c7ac1ca1b839ad823b948ea28", + "sha256:8d2f1fb53a421b410751887eb4ff21386d119ef9cde3797bf5e7ed49fb51a3b3", + "sha256:903bbd302a2378f984aef528f76d4c9b1748f318fe1294961c072bdc7f2ffa3e", + "sha256:93f81b134a165cc17123626ab8da2e30c0455441d4ab5576eed73a64c025b25c", + "sha256:95e69877983ea39b7303570fa6760f81a3eec23d0e3ab2021b7144b94d06202d", + "sha256:9633b3034d3d901f0a46b7939f8c4d64427dfba6bbc5a36b1a67364cf148a1b0", + "sha256:97e5306482182170ade15c4b0d8386ded995a07d7cc2ca8f27958d34d6736497", + "sha256:9f3cba480d3deb69f6ee2c1825060177a22c7826431458c697df88e6aeb3caee", + "sha256:aa5b467f15e78b82257319aebc78dd2915e4c1436c3c0d1ad6f53e47ba6e2713", + "sha256:abb7a75ed8b968f3061327c433a0fbd17b729947b400747c334a9c29a9af6c58", + "sha256:aec52725173bd3a7b56fe91bc56eccb26fbdff1386ef123abb63c84c5b43b63a", + "sha256:b11548073a2213d950c3f671aa88e6f83cda6e2fb97a8b6317b1b5b33d850e06", + "sha256:b1692f7d6bc45e3200844be0dba153612103db241691088626a33ff1f24a0d88", + "sha256:b336501a05e13b616ef81ce329c0e09ac5ed8c732d9ba7e3e983fcc1a9e86965", + "sha256:b8c008de9d0daba7b6666aa5bbfdc23dcd78cafc33997c9b7741ff6353bafb7f", + "sha256:b92e29e58bef6d9cfd340c72b04d74c4b4e9f70c9fa7c78b674d1fec18896dc4", + "sha256:be5f425ff1f5f4b3c1e33ad64ab994eed12fc284a6ea71c5243fd564502ecbe5", + "sha256:dd0b1e9e891f69e7675ba5c92e28b90eaa045f6ab134ffe70b52e948aa175b3c", + "sha256:e30f5ea4ae2346e62cedde8794a56858a67b878dd79f7df76a0767e356b1744a", + "sha256:e6a36bb9474218c7a5b27ae476035497a6990e21d04c279884eb10d9b290f1b1", + "sha256:e859fcb4cbe93504ea18008d1df98dee4f7766db66c435e4882ab35cf70cac43", + "sha256:eb6ea6da4c787111adf40f697b4e58732ee0942b5d3bd8f435277643329ba627", + "sha256:ec8c433b3ab0419100bd45b47c9c8551248a5aee30ca5e9d399a0b57ac04651b", + "sha256:eff9d20417ff9dcb0d25e2defc2574d10b491bf2e693b4e491914738b7908168", + "sha256:f0214eb2a23b85528310dad848ad2ac58e735612929c8072f6093f3585fd342d", + "sha256:f276df9830dba7a333544bd41070e8175762a7ac20350786b322b714b0e654f5", + "sha256:f3acda1924472472ddd60c29e5b9db0cec629fbe3c5c5accb74d6d6d14773478", + "sha256:f70a9e237bb792c7cc7e44c531fd48f5897961701cdaa06cf22fc14965c496cf", + "sha256:f9d29ca8a77117315101425ec7ec2a47a22ccf59f5593378fc4077ac5b754fce", + "sha256:fa877ca7f6b48054f847b61d6fa7bed5cebb663ebc55e018fda12db09dcc664c", + "sha256:fdcec0b8399108577ec290f55551d926d9a1fa6cad45882093a7a07ac5ec147b" + ], + "markers": "python_version >= '3' and platform_machine == 'aarch64' or (platform_machine == 'ppc64le' or (platform_machine == 'x86_64' or (platform_machine == 'amd64' or (platform_machine == 'AMD64' or (platform_machine == 'win32' or platform_machine == 'WIN32')))))", + "version": "==1.1.2" + }, + "importlib-metadata": { + "hashes": [ + "sha256:6affcdb3aec542dd98df8211e730bba6c5f2bec8288d47bacacde898f548c9ad", + "sha256:9e5e553bbba1843cb4a00823014b907616be46ee503d2b9ba001d214a8da218f" + ], + "markers": "python_version < '3.9'", + "version": "==4.11.0" + }, + "importlib-resources": { + "hashes": [ + "sha256:33a95faed5fc19b4bc16b29a6eeae248a3fe69dd55d4d229d2b480e23eeaad45", + "sha256:d756e2f85dd4de2ba89be0b21dba2a3bbec2e871a42a3a16719258a11f87506b" + ], + "markers": "python_version < '3.9'", + "version": "==5.4.0" + }, + "itsdangerous": { + "hashes": [ + "sha256:321b033d07f2a4136d3ec762eac9f16a10ccd60f53c0c91af90217ace7ba1f19", + "sha256:b12271b2047cb23eeb98c8b5622e2e5c5e9abd9784a153e9d8ef9cb4dd09d749" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==1.1.0" + }, + "jinja2": { + "hashes": [ + "sha256:03e47ad063331dd6a3f04a43eddca8a966a26ba0c5b7207a9a9e4e08f1b29419", + "sha256:a6d58433de0ae800347cab1fa3043cebbabe8baa9d29e668f1c768cb87a333c6" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", + "version": "==2.11.3" }, - "typing-extensions": { + "mako": { "hashes": [ - "sha256:7cb407020f00f7bfc3cb3e7881628838e69d8f3fcab2f64742a5e76b2f841918", - "sha256:99d4073b617d30288f569d3f13d2bd7548c3a7e4c8de87db09a9d29bb3a4a60c", - "sha256:dafc7639cde7f1b6e1acc0f457842a83e722ccca8eef5270af2d74792619a89f" + "sha256:4e9e345a41924a954251b95b4b28e14a301145b544901332e658907a7464b6b2", + "sha256:afaf8e515d075b22fad7d7b8b30e4a1c90624ff2f3733a06ec125f5a5f043a57" ], - "markers": "python_version < '3.8'", - "version": "==3.7.4.3" + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==1.1.6" + }, + "markupsafe": { + "hashes": [ + "sha256:01a9b8ea66f1658938f65b93a85ebe8bc016e6769611be228d797c9d998dd298", + "sha256:023cb26ec21ece8dc3907c0e8320058b2e0cb3c55cf9564da612bc325bed5e64", + "sha256:0446679737af14f45767963a1a9ef7620189912317d095f2d9ffa183a4d25d2b", + "sha256:04635854b943835a6ea959e948d19dcd311762c5c0c6e1f0e16ee57022669194", + "sha256:0717a7390a68be14b8c793ba258e075c6f4ca819f15edfc2a3a027c823718567", + "sha256:0955295dd5eec6cb6cc2fe1698f4c6d84af2e92de33fbcac4111913cd100a6ff", + "sha256:0d4b31cc67ab36e3392bbf3862cfbadac3db12bdd8b02a2731f509ed5b829724", + "sha256:10f82115e21dc0dfec9ab5c0223652f7197feb168c940f3ef61563fc2d6beb74", + "sha256:168cd0a3642de83558a5153c8bd34f175a9a6e7f6dc6384b9655d2697312a646", + "sha256:1d609f577dc6e1aa17d746f8bd3c31aa4d258f4070d61b2aa5c4166c1539de35", + "sha256:1f2ade76b9903f39aa442b4aadd2177decb66525062db244b35d71d0ee8599b6", + "sha256:20dca64a3ef2d6e4d5d615a3fd418ad3bde77a47ec8a23d984a12b5b4c74491a", + "sha256:2a7d351cbd8cfeb19ca00de495e224dea7e7d919659c2841bbb7f420ad03e2d6", + "sha256:2d7d807855b419fc2ed3e631034685db6079889a1f01d5d9dac950f764da3dad", + "sha256:2ef54abee730b502252bcdf31b10dacb0a416229b72c18b19e24a4509f273d26", + "sha256:36bc903cbb393720fad60fc28c10de6acf10dc6cc883f3e24ee4012371399a38", + "sha256:37205cac2a79194e3750b0af2a5720d95f786a55ce7df90c3af697bfa100eaac", + "sha256:3c112550557578c26af18a1ccc9e090bfe03832ae994343cfdacd287db6a6ae7", + "sha256:3dd007d54ee88b46be476e293f48c85048603f5f516008bee124ddd891398ed6", + "sha256:4296f2b1ce8c86a6aea78613c34bb1a672ea0e3de9c6ba08a960efe0b0a09047", + "sha256:47ab1e7b91c098ab893b828deafa1203de86d0bc6ab587b160f78fe6c4011f75", + "sha256:49e3ceeabbfb9d66c3aef5af3a60cc43b85c33df25ce03d0031a608b0a8b2e3f", + "sha256:4dc8f9fb58f7364b63fd9f85013b780ef83c11857ae79f2feda41e270468dd9b", + "sha256:4efca8f86c54b22348a5467704e3fec767b2db12fc39c6d963168ab1d3fc9135", + "sha256:53edb4da6925ad13c07b6d26c2a852bd81e364f95301c66e930ab2aef5b5ddd8", + "sha256:5855f8438a7d1d458206a2466bf82b0f104a3724bf96a1c781ab731e4201731a", + "sha256:594c67807fb16238b30c44bdf74f36c02cdf22d1c8cda91ef8a0ed8dabf5620a", + "sha256:5b6d930f030f8ed98e3e6c98ffa0652bdb82601e7a016ec2ab5d7ff23baa78d1", + "sha256:5bb28c636d87e840583ee3adeb78172efc47c8b26127267f54a9c0ec251d41a9", + "sha256:60bf42e36abfaf9aff1f50f52644b336d4f0a3fd6d8a60ca0d054ac9f713a864", + "sha256:611d1ad9a4288cf3e3c16014564df047fe08410e628f89805e475368bd304914", + "sha256:6300b8454aa6930a24b9618fbb54b5a68135092bc666f7b06901f897fa5c2fee", + "sha256:63f3268ba69ace99cab4e3e3b5840b03340efed0948ab8f78d2fd87ee5442a4f", + "sha256:6557b31b5e2c9ddf0de32a691f2312a32f77cd7681d8af66c2692efdbef84c18", + "sha256:693ce3f9e70a6cf7d2fb9e6c9d8b204b6b39897a2c4a1aa65728d5ac97dcc1d8", + "sha256:6a7fae0dd14cf60ad5ff42baa2e95727c3d81ded453457771d02b7d2b3f9c0c2", + "sha256:6c4ca60fa24e85fe25b912b01e62cb969d69a23a5d5867682dd3e80b5b02581d", + "sha256:6fcf051089389abe060c9cd7caa212c707e58153afa2c649f00346ce6d260f1b", + "sha256:7d91275b0245b1da4d4cfa07e0faedd5b0812efc15b702576d103293e252af1b", + "sha256:89c687013cb1cd489a0f0ac24febe8c7a666e6e221b783e53ac50ebf68e45d86", + "sha256:8d206346619592c6200148b01a2142798c989edcb9c896f9ac9722a99d4e77e6", + "sha256:905fec760bd2fa1388bb5b489ee8ee5f7291d692638ea5f67982d968366bef9f", + "sha256:97383d78eb34da7e1fa37dd273c20ad4320929af65d156e35a5e2d89566d9dfb", + "sha256:984d76483eb32f1bcb536dc27e4ad56bba4baa70be32fa87152832cdd9db0833", + "sha256:99df47edb6bda1249d3e80fdabb1dab8c08ef3975f69aed437cb69d0a5de1e28", + "sha256:9f02365d4e99430a12647f09b6cc8bab61a6564363f313126f775eb4f6ef798e", + "sha256:a30e67a65b53ea0a5e62fe23682cfe22712e01f453b95233b25502f7c61cb415", + "sha256:ab3ef638ace319fa26553db0624c4699e31a28bb2a835c5faca8f8acf6a5a902", + "sha256:aca6377c0cb8a8253e493c6b451565ac77e98c2951c45f913e0b52facdcff83f", + "sha256:add36cb2dbb8b736611303cd3bfcee00afd96471b09cda130da3581cbdc56a6d", + "sha256:b2f4bf27480f5e5e8ce285a8c8fd176c0b03e93dcc6646477d4630e83440c6a9", + "sha256:b7f2d075102dc8c794cbde1947378051c4e5180d52d276987b8d28a3bd58c17d", + "sha256:baa1a4e8f868845af802979fcdbf0bb11f94f1cb7ced4c4b8a351bb60d108145", + "sha256:be98f628055368795d818ebf93da628541e10b75b41c559fdf36d104c5787066", + "sha256:bf5d821ffabf0ef3533c39c518f3357b171a1651c1ff6827325e4489b0e46c3c", + "sha256:c47adbc92fc1bb2b3274c4b3a43ae0e4573d9fbff4f54cd484555edbf030baf1", + "sha256:cdfba22ea2f0029c9261a4bd07e830a8da012291fbe44dc794e488b6c9bb353a", + "sha256:d6c7ebd4e944c85e2c3421e612a7057a2f48d478d79e61800d81468a8d842207", + "sha256:d7f9850398e85aba693bb640262d3611788b1f29a79f0c93c565694658f4071f", + "sha256:d8446c54dc28c01e5a2dbac5a25f071f6653e6e40f3a8818e8b45d790fe6ef53", + "sha256:deb993cacb280823246a026e3b2d81c493c53de6acfd5e6bfe31ab3402bb37dd", + "sha256:e0f138900af21926a02425cf736db95be9f4af72ba1bb21453432a07f6082134", + "sha256:e9936f0b261d4df76ad22f8fee3ae83b60d7c3e871292cd42f40b81b70afae85", + "sha256:f0567c4dc99f264f49fe27da5f735f414c4e7e7dd850cfd8e69f0862d7c74ea9", + "sha256:f5653a225f31e113b152e56f154ccbe59eeb1c7487b39b9d9f9cdb58e6c79dc5", + "sha256:f826e31d18b516f653fe296d967d700fddad5901ae07c622bb3705955e1faa94", + "sha256:f8ba0e8349a38d3001fae7eadded3f6606f0da5d748ee53cc1dab1d6527b9509", + "sha256:f9081981fe268bd86831e5c75f7de206ef275defcb82bc70740ae6dc507aee51", + "sha256:fa130dd50c57d53368c9d59395cb5526eda596d3ffe36666cd81a44d56e48872" + ], + "markers": "python_version >= '3.6'", + "version": "==2.0.1" + }, + "sqlalchemy": { + "hashes": [ + "sha256:014ea143572fee1c18322b7908140ad23b3994036ef4c0d630110faf942652f8", + "sha256:0172423a27fbcae3751ef016663b72e1a516777de324a76e30efa170dbd3dd2d", + "sha256:01aa5f803db724447c1d423ed583e42bf5264c597fd55e4add4301f163b0be48", + "sha256:0352db1befcbed2f9282e72843f1963860bf0e0472a4fa5cf8ee084318e0e6ab", + "sha256:09083c2487ca3c0865dc588e07aeaa25416da3d95f7482c07e92f47e080aa17b", + "sha256:0d5d862b1cfbec5028ce1ecac06a3b42bc7703eb80e4b53fceb2738724311443", + "sha256:14f0eb5db872c231b20c18b1e5806352723a3a89fb4254af3b3e14f22eaaec75", + "sha256:1e2f89d2e5e3c7a88e25a3b0e43626dba8db2aa700253023b82e630d12b37109", + "sha256:26155ea7a243cbf23287f390dba13d7927ffa1586d3208e0e8d615d0c506f996", + "sha256:2ed6343b625b16bcb63c5b10523fd15ed8934e1ed0f772c534985e9f5e73d894", + "sha256:34fcec18f6e4b24b4a5f6185205a04f1eab1e56f8f1d028a2a03694ebcc2ddd4", + "sha256:4d0e3515ef98aa4f0dc289ff2eebb0ece6260bbf37c2ea2022aad63797eacf60", + "sha256:5de2464c254380d8a6c20a2746614d5a436260be1507491442cf1088e59430d2", + "sha256:6607ae6cd3a07f8a4c3198ffbf256c261661965742e2b5265a77cd5c679c9bba", + "sha256:8110e6c414d3efc574543109ee618fe2c1f96fa31833a1ff36cc34e968c4f233", + "sha256:816de75418ea0953b5eb7b8a74933ee5a46719491cd2b16f718afc4b291a9658", + "sha256:861e459b0e97673af6cc5e7f597035c2e3acdfb2608132665406cded25ba64c7", + "sha256:87a2725ad7d41cd7376373c15fd8bf674e9c33ca56d0b8036add2d634dba372e", + "sha256:a006d05d9aa052657ee3e4dc92544faae5fcbaafc6128217310945610d862d39", + "sha256:bce28277f308db43a6b4965734366f533b3ff009571ec7ffa583cb77539b84d6", + "sha256:c10ff6112d119f82b1618b6dc28126798481b9355d8748b64b9b55051eb4f01b", + "sha256:d375d8ccd3cebae8d90270f7aa8532fe05908f79e78ae489068f3b4eee5994e8", + "sha256:d37843fb8df90376e9e91336724d78a32b988d3d20ab6656da4eb8ee3a45b63c", + "sha256:e47e257ba5934550d7235665eee6c911dc7178419b614ba9e1fbb1ce6325b14f", + "sha256:e98d09f487267f1e8d1179bf3b9d7709b30a916491997137dd24d6ae44d18d79", + "sha256:ebbb777cbf9312359b897bf81ba00dae0f5cb69fba2a18265dcc18a6f5ef7519", + "sha256:ee5f5188edb20a29c1cc4a039b074fdc5575337c9a68f3063449ab47757bb064", + "sha256:f03bd97650d2e42710fbe4cf8a59fae657f191df851fc9fc683ecef10746a375", + "sha256:f1149d6e5c49d069163e58a3196865e4321bad1803d7886e07d8710de392c548", + "sha256:f3c5c52f7cb8b84bfaaf22d82cb9e6e9a8297f7c2ed14d806a0f5e4d22e83fb7", + "sha256:f597a243b8550a3a0b15122b14e49d8a7e622ba1c9d29776af741f1845478d79", + "sha256:fc1f2a5a5963e2e73bac4926bdaf7790c4d7d77e8fc0590817880e22dd9d0b8b", + "sha256:fc4cddb0b474b12ed7bdce6be1b9edc65352e8ce66bc10ff8cbbfb3d4047dbf4", + "sha256:fcb251305fa24a490b6a9ee2180e5f8252915fb778d3dafc70f9cc3f863827b9" + ], + "index": "pypi", + "version": "==1.3.24" }, "werkzeug": { "hashes": [ "sha256:2de2a5db0baeae7b2d2664949077c2ac63fbd16d98da0ff71837f7d1dea3fd43", "sha256:6c80b1e5ad3665290ea39320b91e1be1e0d5f60652b964a3070216de83d2e47c" ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", "version": "==1.0.1" }, "zipp": { "hashes": [ - "sha256:3607921face881ba3e026887d8150cca609d517579abe052ac81fc5aeffdbd76", - "sha256:51cb66cc54621609dd593d1787f286ee42a5c0adbb4b29abea5a63edc3e03098" + "sha256:9f50f446828eb9d45b267433fd3e9da8d801f614129124863f9c51ebceafb87d", + "sha256:b47250dd24f92b7dd6a0a8fc5244da14608f3ca90a5efcd37a3b1642fac9a375" ], - "version": "==3.4.1" + "markers": "python_version < '3.10'", + "version": "==3.7.0" } - }, - "develop": {} + } } From 9f01854c68f29b4b2a9cb8c76a5a26b9174ec465 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 13 Feb 2022 16:35:07 -0500 Subject: [PATCH 105/206] move auth and demo stuff to a separate file --- api.py | 98 ++------------------------------------------------------- auth.py | 97 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 99 insertions(+), 96 deletions(-) create mode 100644 auth.py diff --git a/api.py b/api.py index faded8b..a20b78c 100644 --- a/api.py +++ b/api.py @@ -9,33 +9,10 @@ from flasgger import APISpec, Schema, Swagger, fields from apispec.ext.marshmallow import MarshmallowPlugin from apispec_webframeworks.flask import FlaskPlugin -import os, sys, getpass -from os import environ as env -from werkzeug.exceptions import HTTPException - - -#default values are only needed for some of these -db_username = env.get("DB_USERNAME") -db_password = env.get("DB_PASSWORD") -db_host = os.getenv("DB_HOST", "localhost") -db_name = os.getenv("DB_NAME", "classclock") - -if sys.argv[1] in ("setup", "demo"): - if not env.get("DB_CONNECTION_URL"): - if not db_username: - db_username = input('database username: ') - if not db_password: - db_password = getpass.getpass('database password (input not shown): ') +from auth import db_connection_string +from werkzeug.exceptions import HTTPException -db_connection_string=os.getenv("DB_CONNECTION_URL", - 'mysql+mysqlconnector://{user}:{pw}@{url}/{db}'.format( - user=db_username, - pw=db_password, - url=db_host, - db=db_name - ) -) app = Flask(__name__) limiter = Limiter(app, default_limits=[ @@ -122,77 +99,6 @@ app.config.update(SQLALCHEMY_DATABASE_URI=db_connection_string,DEBUG=True, SQLALCHEMY_TRACK_MODIFICATIONS=False) db.init_app(app) -if sys.argv[1] == "setup": -# https://stackoverflow.com/a/46541219 - with app.app_context(): - db.create_all() - db.session.commit() - print("Done.") - exit(0) -elif sys.argv[1] == "demo": -# https://stackoverflow.com/a/46541219 - with app.app_context(): - from common.db_schema import * - import datetime - import time - - - def today_plus(sch, num_days): - return BellScheduleDate(school_id = sch, date=datetime.date.today() + datetime.timedelta(days=num_days)) - - s = School(owner_id="1234567890", full_name="Demonstration High School", acronym="DHS") - - - sc1 = BellSchedule( - school_id = s.id, - name="Even Day", - display_name= "Even", - dates=[ - today_plus(s.id, 0), - today_plus(s.id, 2), - today_plus(s.id, 4) - ] - ) - - sc2 = BellSchedule( - school_id = s.id, - name="Odd Day", - display_name="Odd", - dates=[ - today_plus(s.id, 1), - today_plus(s.id, 3) - ] - ) - - - s.schedules = [sc1,sc2] - - - sc1.meeting_times = [ - BellScheduleMeetingTime( - bell_schedule_id =sc1.id, - name="First Period", - start_time=datetime.time(hour=8, minute=25, second=0, microsecond=0), - end_time=datetime.time(9,25) - ) - ] - - sc2.meeting_times = [ - BellScheduleMeetingTime( - bell_schedule_id =sc2.id, - name="First Period", - start_time=datetime.time(8,45), - end_time=datetime.time(9,45) - ) - - ] - - db.session.add(s) - db.session.commit() - print("Done.") - exit(0) - - @app.errorhandler(HTTPException) def handle_HTTP_error(e): return respond( diff --git a/auth.py b/auth.py new file mode 100644 index 0000000..16aa63a --- /dev/null +++ b/auth.py @@ -0,0 +1,97 @@ + + +import os, sys, getpass +from os import environ as env + +#default values are only needed for some of these +db_username = env.get("DB_USERNAME") +db_password = env.get("DB_PASSWORD") +db_host = os.getenv("DB_HOST", "localhost") +db_name = os.getenv("DB_NAME", "classclock") + +if sys.argv[1] in ("setup", "demo"): + if not env.get("DB_CONNECTION_URL"): + if not db_username: + db_username = input('database username: ') + if not db_password: + db_password = getpass.getpass('database password (input not shown): ') + + +db_connection_string=os.getenv("DB_CONNECTION_URL", + 'mysql+mysqlconnector://{user}:{pw}@{url}/{db}'.format( + user=db_username, + pw=db_password, + url=db_host, + db=db_name + ) +) +if sys.argv[1] == "setup": +# https://stackoverflow.com/a/46541219 + with app.app_context(): + db.create_all() + db.session.commit() + print("Done.") + exit(0) +# elif sys.argv[1] == "demo": +# # https://stackoverflow.com/a/46541219 +# with app.app_context(): +# from common.db_schema import * +# import datetime +# import time + + +# def today_plus(sch, num_days): +# return BellScheduleDate(school_id = sch, date=datetime.date.today() + datetime.timedelta(days=num_days)) + +# s = School(owner_id="1234567890", full_name="Demonstration High School", acronym="DHS") + + +# sc1 = BellSchedule( +# school_id = s.id, +# name="Even Day", +# display_name= "Even", +# dates=[ +# today_plus(s.id, 0), +# today_plus(s.id, 2), +# today_plus(s.id, 4) +# ] +# ) + +# sc2 = BellSchedule( +# school_id = s.id, +# name="Odd Day", +# display_name="Odd", +# dates=[ +# today_plus(s.id, 1), +# today_plus(s.id, 3) +# ] +# ) + + +# s.schedules = [sc1,sc2] + + +# sc1.meeting_times = [ +# BellScheduleMeetingTime( +# bell_schedule_id =sc1.id, +# name="First Period", +# start_time=datetime.time(hour=8, minute=25, second=0, microsecond=0), +# end_time=datetime.time(9,25) +# ) +# ] + +# sc2.meeting_times = [ +# BellScheduleMeetingTime( +# bell_schedule_id =sc2.id, +# name="First Period", +# start_time=datetime.time(8,45), +# end_time=datetime.time(9,45) +# ) + +# ] + +# db.session.add(s) +# db.session.commit() +# print("Done.") +# exit(0) + \ No newline at end of file From edf1566add84b69e0d44ab510a2575d1bab6e067 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 13 Feb 2022 16:35:50 -0500 Subject: [PATCH 106/206] init the migration object --- api.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/api.py b/api.py index a20b78c..9acae40 100644 --- a/api.py +++ b/api.py @@ -10,6 +10,7 @@ from apispec.ext.marshmallow import MarshmallowPlugin from apispec_webframeworks.flask import FlaskPlugin from auth import db_connection_string +from flask_migrate import Migrate from werkzeug.exceptions import HTTPException @@ -98,6 +99,7 @@ app.config.update(SQLALCHEMY_DATABASE_URI=db_connection_string,DEBUG=True, SQLALCHEMY_TRACK_MODIFICATIONS=False) db.init_app(app) +migrate = Migrate(app, db) @app.errorhandler(HTTPException) def handle_HTTP_error(e): From f066aa3921c6aaf45caf5f51c833c48a3a2bbfc8 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 13 Feb 2022 16:36:01 -0500 Subject: [PATCH 107/206] create migration dir with `FLASK_APP=api.py pipenv run flask db init` --- migrations/README | 1 + migrations/alembic.ini | 50 +++++++++++++++++++++ migrations/env.py | 91 +++++++++++++++++++++++++++++++++++++++ migrations/script.py.mako | 24 +++++++++++ 4 files changed, 166 insertions(+) create mode 100644 migrations/README create mode 100644 migrations/alembic.ini create mode 100644 migrations/env.py create mode 100644 migrations/script.py.mako diff --git a/migrations/README b/migrations/README new file mode 100644 index 0000000..0e04844 --- /dev/null +++ b/migrations/README @@ -0,0 +1 @@ +Single-database configuration for Flask. diff --git a/migrations/alembic.ini b/migrations/alembic.ini new file mode 100644 index 0000000..ec9d45c --- /dev/null +++ b/migrations/alembic.ini @@ -0,0 +1,50 @@ +# A generic, single database configuration. + +[alembic] +# template used to generate migration files +# file_template = %%(rev)s_%%(slug)s + +# set to 'true' to run the environment during +# the 'revision' command, regardless of autogenerate +# revision_environment = false + + +# Logging configuration +[loggers] +keys = root,sqlalchemy,alembic,flask_migrate + +[handlers] +keys = console + +[formatters] +keys = generic + +[logger_root] +level = WARN +handlers = console +qualname = + +[logger_sqlalchemy] +level = WARN +handlers = +qualname = sqlalchemy.engine + +[logger_alembic] +level = INFO +handlers = +qualname = alembic + +[logger_flask_migrate] +level = INFO +handlers = +qualname = flask_migrate + +[handler_console] +class = StreamHandler +args = (sys.stderr,) +level = NOTSET +formatter = generic + +[formatter_generic] +format = %(levelname)-5.5s [%(name)s] %(message)s +datefmt = %H:%M:%S diff --git a/migrations/env.py b/migrations/env.py new file mode 100644 index 0000000..68feded --- /dev/null +++ b/migrations/env.py @@ -0,0 +1,91 @@ +from __future__ import with_statement + +import logging +from logging.config import fileConfig + +from flask import current_app + +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) +logger = logging.getLogger('alembic.env') + +# add your model's MetaData object here +# for 'autogenerate' support +# from myapp import mymodel +# target_metadata = mymodel.Base.metadata +config.set_main_option( + 'sqlalchemy.url', + str(current_app.extensions['migrate'].db.get_engine().url).replace( + '%', '%%')) +target_metadata = current_app.extensions['migrate'].db.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. + + """ + + # this callback is used to prevent an auto-migration from being generated + # when there are no changes to the schema + # reference: http://alembic.zzzcomputing.com/en/latest/cookbook.html + def process_revision_directives(context, revision, directives): + if getattr(config.cmd_opts, 'autogenerate', False): + script = directives[0] + if script.upgrade_ops.is_empty(): + directives[:] = [] + logger.info('No changes in schema detected.') + + connectable = current_app.extensions['migrate'].db.get_engine() + + with connectable.connect() as connection: + context.configure( + connection=connection, + target_metadata=target_metadata, + process_revision_directives=process_revision_directives, + **current_app.extensions['migrate'].configure_args + ) + + with context.begin_transaction(): + context.run_migrations() + + +if context.is_offline_mode(): + run_migrations_offline() +else: + run_migrations_online() diff --git a/migrations/script.py.mako b/migrations/script.py.mako new file mode 100644 index 0000000..2c01563 --- /dev/null +++ b/migrations/script.py.mako @@ -0,0 +1,24 @@ +"""${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"} From 00caf43a64c8c53af432faff74a29ff358a6746b Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 13 Feb 2022 16:51:21 -0500 Subject: [PATCH 108/206] install dotenv --- Pipfile | 1 + Pipfile.lock | 10 +++++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/Pipfile b/Pipfile index 69c9685..437db4b 100644 --- a/Pipfile +++ b/Pipfile @@ -21,6 +21,7 @@ apispec = "~=3.3.0" apispec-webframeworks = "~=0.5.2" mysql-connector-python = "8.0.24" python-jose = "*" +python-dotenv = "*" [requires] python_version = "3.8" diff --git a/Pipfile.lock b/Pipfile.lock index e7e4cee..deba527 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "c37f67a03e97e4a1f975c2eda698d57193244d08c5602fc5060eaf19c3a07d15" + "sha256": "a3124aaeb49267859e81647582eea7a2d511ba9ee4e211b411768af7415f1a9e" }, "pipfile-spec": 6, "requires": { @@ -357,6 +357,14 @@ "markers": "python_version >= '3.7'", "version": "==0.18.1" }, + "python-dotenv": { + "hashes": [ + "sha256:32b2bdc1873fd3a3c346da1c6db83d0053c3c62f28f1f38516070c4c8971b1d3", + "sha256:a5de49a31e953b45ff2d2fd434bbc2670e8db5273606c1e737cc6b93eff3655f" + ], + "index": "pypi", + "version": "==0.19.2" + }, "python-jose": { "hashes": [ "sha256:55779b5e6ad599c6336191246e95eb2293a9ddebd555f796a65f838f07e5d78a", From 572b84a0f1b2e45dc9e74c85e6b839321ce450ac Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 13 Feb 2022 17:18:31 -0500 Subject: [PATCH 109/206] add more complete python gitignore --- .gitignore | 157 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 156 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 79abf18..ab7140e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,160 @@ -__pycache__ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# poetry +# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. +# This is especially recommended for binary packages to ensure reproducibility, and is more +# commonly ignored for libraries. +# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control +#poetry.lock + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ + +# PyCharm +# JetBrains specific template is maintained in a separate JetBrains.gitignore that can +# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore +# and can be added to the global gitignore or merged into this file. For a more nuclear +# option (not recommended) you can uncomment the following to ignore the entire idea folder. +#.idea/ + + + + /startserver.sh classclockapi_venv/ From 4c39850c61859c8c3510842b47039c8295701c49 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 13 Feb 2022 17:20:07 -0500 Subject: [PATCH 110/206] rename versions folder to blueprints --- {versions => blueprints}/__init__.py | 0 {versions => blueprints}/v0.py | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename {versions => blueprints}/__init__.py (100%) rename {versions => blueprints}/v0.py (100%) diff --git a/versions/__init__.py b/blueprints/__init__.py similarity index 100% rename from versions/__init__.py rename to blueprints/__init__.py diff --git a/versions/v0.py b/blueprints/v0.py similarity index 100% rename from versions/v0.py rename to blueprints/v0.py From 8b6e9a8e5ae5a3f9116527cfd52c549d25dfeead Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 13 Feb 2022 17:22:42 -0500 Subject: [PATCH 111/206] move routes on the app to a blueprint --- api.py | 13 ------------- blueprints/main.py | 20 ++++++++++++++++++++ 2 files changed, 20 insertions(+), 13 deletions(-) create mode 100644 blueprints/main.py diff --git a/api.py b/api.py index 9acae40..b0c9556 100644 --- a/api.py +++ b/api.py @@ -12,7 +12,6 @@ from auth import db_connection_string from flask_migrate import Migrate -from werkzeug.exceptions import HTTPException app = Flask(__name__) @@ -101,18 +100,6 @@ db.init_app(app) migrate = Migrate(app, db) -@app.errorhandler(HTTPException) -def handle_HTTP_error(e): - return respond( - make_error_object( - e.code, title=e.name, message=e.description), - code=e.code - ) - - -@app.route("/", methods=['GET']) -def home(): - return render_template('home.html') diff --git a/blueprints/main.py b/blueprints/main.py new file mode 100644 index 0000000..ea23271 --- /dev/null +++ b/blueprints/main.py @@ -0,0 +1,20 @@ +from flask import Blueprint, render_template, abort +from jinja2 import TemplateNotFound +from werkzeug.exceptions import HTTPException + + +main_pages = Blueprint('main_pages', __name__, + template_folder='templates') + +@main_pages.route("/", methods=['GET']) +def home(): + return render_template('home.html') + + +@main_pages.errorhandler(HTTPException) +def handle_HTTP_error(e): + return respond( + make_error_object( + e.code, title=e.name, message=e.description), + code=e.code + ) \ No newline at end of file From af33750f6b71244a0f05c0aa229a6b666206391b Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 13 Feb 2022 17:24:19 -0500 Subject: [PATCH 112/206] rename versions import --- api.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api.py b/api.py index b0c9556..2f06328 100644 --- a/api.py +++ b/api.py @@ -1,6 +1,6 @@ from flask import Flask, render_template import logging -from versions import v0 +from blueprints import v0 from flask_limiter import Limiter from flasgger import Swagger from common.helpers import get_request_origin_identifier, make_error_object, respond From eaa9bdbe5a2af3c08cafa1317b7eda7e3d403acd Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 13 Feb 2022 17:25:08 -0500 Subject: [PATCH 113/206] refactor app into factory pattern https://flask.palletsprojects.com/en/2.0.x/patterns/appfactories/ --- api.py | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/api.py b/api.py index 2f06328..1c0ee23 100644 --- a/api.py +++ b/api.py @@ -1,6 +1,6 @@ from flask import Flask, render_template import logging -from blueprints import v0 +from blueprints import v0, main from flask_limiter import Limiter from flasgger import Swagger from common.helpers import get_request_origin_identifier, make_error_object, respond @@ -12,13 +12,21 @@ from auth import db_connection_string from flask_migrate import Migrate +def create_app(config_filename): + app = Flask(__name__) + app.config.from_pyfile(config_filename) - -app = Flask(__name__) -limiter = Limiter(app, default_limits=[ + limiter = Limiter(app, default_limits=[ "25/hour", "5/minute"], key_func=get_request_origin_identifier, headers_enabled=True) -app.register_blueprint(v0.blueprint, url_prefix='/v0') + app.register_blueprint(v0.blueprint, url_prefix='/v0') + app.register_blueprint(main.main_pages) + + app.config.update(SQLALCHEMY_DATABASE_URI=db_connection_string,DEBUG=True, SQLALCHEMY_TRACK_MODIFICATIONS=False) + db.init_app(app) + migrate = Migrate(app, db) + + return app # Create an APISpec @@ -96,9 +104,6 @@ -app.config.update(SQLALCHEMY_DATABASE_URI=db_connection_string,DEBUG=True, SQLALCHEMY_TRACK_MODIFICATIONS=False) -db.init_app(app) -migrate = Migrate(app, db) From 357c394f11f40a828b4992185d14d331fc7ef848 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 13 Feb 2022 18:00:59 -0500 Subject: [PATCH 114/206] move docs stuff to its own file --- api.py | 86 ++----------------------------------------- blueprints/docs.py | 91 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 94 insertions(+), 83 deletions(-) create mode 100644 blueprints/docs.py diff --git a/api.py b/api.py index 1c0ee23..22214ef 100644 --- a/api.py +++ b/api.py @@ -1,14 +1,11 @@ from flask import Flask, render_template import logging from blueprints import v0, main +from docs import create_docs from flask_limiter import Limiter -from flasgger import Swagger from common.helpers import get_request_origin_identifier, make_error_object, respond from common.db_schema import db from common.schemas import * -from flasgger import APISpec, Schema, Swagger, fields -from apispec.ext.marshmallow import MarshmallowPlugin -from apispec_webframeworks.flask import FlaskPlugin from auth import db_connection_string from flask_migrate import Migrate @@ -26,86 +23,9 @@ def create_app(config_filename): db.init_app(app) migrate = Migrate(app, db) - return app - - -# Create an APISpec -#info: { -spec = APISpec( - title="ClassClock API", - version="0.1", - openapi_version='2.0', - plugins=[ - FlaskPlugin(), - MarshmallowPlugin(), - ], - options= { - "description": "The development version of the ClassClock API", - "servers": [ - { - "url": "https://api.classclock.app/v0", - "description": "ClassClock API Server" - }, - { - "url": "https://localhost:8000/v0", - "description": "Dev server" - } - ], - "externalDocs": { - "description": "This API might loosely follow the JSON:API specofocation", - "url": "https://jsonapi.org" - }#, -# "contact": { -# # "responsibleOrganization": "ME", -# # "responsibleDeveloper": "Me", -# # "email": "me@me.com", -# # "url": "www.me.com", -# }, -# "termsOfService": "http://me.com/terms", - } -) - - -template = spec.to_flasgger( - app, - definitions=[SchoolSchema, BellScheduleSchema], - paths=[] -) - -swagger = Swagger(app, config={ - "headers": [ - ], - "specs": [ - { - "endpoint": 'apispec_v1', - "route": '/apispec_v1.json', - "rule_filter": lambda rule: True, # all in - "model_filter": lambda tag: True, # all in - } - ], - "static_url_path": "/flasgger_static", - # "static_folder": "static", # must be set by user - "swagger_ui": True, - "specs_route": "/v0/docs/", - "basePath": "/v0", - "host": "api.classclock.app", # overrides localhost:500 - "schemes": [ - "https" - ], - "securityDefinitions": { - "ApiKeyAuth": { - "type": "apiKey", - "in": "header", - "name": "Authentication" - } - } -}, -template=template) - - - - + create_docs(app) + return app if __name__ == "__main__": diff --git a/blueprints/docs.py b/blueprints/docs.py new file mode 100644 index 0000000..cf66f6d --- /dev/null +++ b/blueprints/docs.py @@ -0,0 +1,91 @@ +from flask import Blueprint, render_template, abort +from jinja2 import TemplateNotFound +from flasgger import APISpec, Schema, Swagger, fields +from apispec.ext.marshmallow import MarshmallowPlugin +from apispec_webframeworks.flask import FlaskPlugin +from common.schemas import * +from blueprints.v0 import * + + + +# docs = Blueprint('docs_pages', __name__, ) + +def create_docs(app): + + # Create an APISpec + # info: { + spec = APISpec( + title="ClassClock API", + version="0.1", + openapi_version='2.0', + + plugins=[ + FlaskPlugin(), + MarshmallowPlugin(), + ], + # options= { + # "description": "The development version of the ClassClock API", + # "servers": [ + # { + # "url": "https://api.classclock.app/v0", + # "description": "ClassClock API Server" + # }, + # { + # "url": "https://localhost:8000/v0", + # "description": "Dev server" + # } + # ], + # "externalDocs": { + # "description": "This API might loosely follow the JSON:API specofocation", + # "url": "https://jsonapi.org" + # }#, + # "contact": { + # # "responsibleOrganization": "ME", + # # "responsibleDeveloper": "Me", + # # "email": "me@me.com", + # # "url": "www.me.com", + # }, + # "termsOfService": "http://me.com/terms", + # } + ) + + + template = spec.to_flasgger( + app, + definitions=[SchoolSchema, BellScheduleSchema], + paths=[get_school, get_bellschedule ] + ) + + + # config={ + # "headers": [ + # ], + # "specs": [ + # { + # "endpoint": 'apispec_v1', + # "route": '/apispec_v1.json', + # "rule_filter": lambda rule: True, # all in + # "model_filter": lambda tag: True, # all in + # } + # ], + # "static_url_path": "/flasgger_static", + # # "static_folder": "static", # must be set by user + # "swagger_ui": True, + # # "specs_route": "/v0/docs/", + # "basePath": "/docs", + # "host": "api.classclock.app", # overrides localhost:500 + # "schemes": [ + # "https" + # ], + # "securityDefinitions": { + # "ApiKeyAuth": { + # "type": "apiKey", + # "in": "header", + # "name": "Authentication" + # } + # } + # }, + + # template["basePath"] = "/docs" + swagger = Swagger(app, template=template) + return swagger From d3c50dd4b0d265c21976c206024b44621510bf76 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 13 Feb 2022 18:01:23 -0500 Subject: [PATCH 115/206] make config_filename optional --- api.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/api.py b/api.py index 22214ef..bef29d6 100644 --- a/api.py +++ b/api.py @@ -9,9 +9,10 @@ from auth import db_connection_string from flask_migrate import Migrate -def create_app(config_filename): +def create_app(config_filename=None): app = Flask(__name__) - app.config.from_pyfile(config_filename) + if config_filename: + app.config.from_pyfile(config_filename) limiter = Limiter(app, default_limits=[ "25/hour", "5/minute"], key_func=get_request_origin_identifier, headers_enabled=True) From 7376c4a87fd1529cf655a8b20b714e26129ab1c6 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 13 Feb 2022 18:01:33 -0500 Subject: [PATCH 116/206] create an app to run when running manually --- api.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api.py b/api.py index bef29d6..c003464 100644 --- a/api.py +++ b/api.py @@ -30,7 +30,7 @@ def create_app(config_filename=None): if __name__ == "__main__": - app.run() + create_app().run() else: gunicorn_logger = logging.getLogger('gunicorn.error') app.logger.handlers = gunicorn_logger.handlers From 0c76c570e249bf6b056db9e5d04ac7fae3e9da71 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 13 Feb 2022 18:32:06 -0500 Subject: [PATCH 117/206] move docs file up a level since it isnt technically a blueprint --- blueprints/docs.py => docs.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename blueprints/docs.py => docs.py (100%) diff --git a/blueprints/docs.py b/docs.py similarity index 100% rename from blueprints/docs.py rename to docs.py From c96725329a75761f925759cba7a74bfbb447085d Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 13 Feb 2022 18:32:30 -0500 Subject: [PATCH 118/206] fix docs formatting --- blueprints/v0.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/blueprints/v0.py b/blueprints/v0.py index 134a3bd..4291c27 100644 --- a/blueprints/v0.py +++ b/blueprints/v0.py @@ -209,11 +209,11 @@ def update_school(school_id): security: - ApiKeyAuth: [] parameters: - - in: header + - in: header name: If-Unmodified-Since schema: - type: string - format: date + type: string + format: date required: false """ From 4f247c9e624426800ce7d64e5f1cb3a2f867429f Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 13 Feb 2022 18:33:45 -0500 Subject: [PATCH 119/206] remove db init stuff from auth --- auth.py | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/auth.py b/auth.py index 16aa63a..4be31af 100644 --- a/auth.py +++ b/auth.py @@ -9,12 +9,6 @@ db_host = os.getenv("DB_HOST", "localhost") db_name = os.getenv("DB_NAME", "classclock") -if sys.argv[1] in ("setup", "demo"): - if not env.get("DB_CONNECTION_URL"): - if not db_username: - db_username = input('database username: ') - if not db_password: - db_password = getpass.getpass('database password (input not shown): ') db_connection_string=os.getenv("DB_CONNECTION_URL", @@ -25,13 +19,6 @@ db=db_name ) ) -if sys.argv[1] == "setup": -# https://stackoverflow.com/a/46541219 - with app.app_context(): - db.create_all() - db.session.commit() - print("Done.") - exit(0) # elif sys.argv[1] == "demo": # # https://stackoverflow.com/a/46541219 # with app.app_context(): From 64c1fdca0c8c826a6d1f5e79dd7bd26f701a21c4 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 13 Feb 2022 18:43:15 -0500 Subject: [PATCH 120/206] fix app does not exist when not directly instantiating --- api.py | 1 + 1 file changed, 1 insertion(+) diff --git a/api.py b/api.py index c003464..df9e10e 100644 --- a/api.py +++ b/api.py @@ -32,6 +32,7 @@ def create_app(config_filename=None): if __name__ == "__main__": create_app().run() else: + app=create_app() gunicorn_logger = logging.getLogger('gunicorn.error') app.logger.handlers = gunicorn_logger.handlers app.logger.setLevel(gunicorn_logger.level) From c2b965c1545458979959b7d0c56c1b4f22f617b0 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 13 Feb 2022 18:48:23 -0500 Subject: [PATCH 121/206] add createdb script --- createdb.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100755 createdb.py diff --git a/createdb.py b/createdb.py new file mode 100755 index 0000000..f36c8d9 --- /dev/null +++ b/createdb.py @@ -0,0 +1,17 @@ +from common.db_schema import db +import argparse +from api import create_app +from flask_migrate import stamp +print("Beginning database creation...") +with create_app().app_context(): + print("Creating tables...") + db.create_all() + print("Committing...") + db.session.commit() + + + # then, load the migration configuration and generate the + # version table, "stamping" it with the most recent rev: + print("Stamping db version for future upgrades...") + stamp() + print("Done creating DB.") \ No newline at end of file From fa7331f770ac2d4870ff15407df9231bc35226bc Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 13 Feb 2022 18:55:01 -0500 Subject: [PATCH 122/206] add demo data loader to createdb --- createdb.py | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 70 insertions(+), 1 deletion(-) diff --git a/createdb.py b/createdb.py index f36c8d9..3c3e99e 100755 --- a/createdb.py +++ b/createdb.py @@ -2,6 +2,15 @@ import argparse from api import create_app from flask_migrate import stamp + +parser = argparse.ArgumentParser(description='Set up a fresh ClassClock database.') +parser.add_argument('--demo', action='store_true', + help='Add some demo data to the database after creation') + +args = parser.parse_args() + + + print("Beginning database creation...") with create_app().app_context(): print("Creating tables...") @@ -14,4 +23,64 @@ # version table, "stamping" it with the most recent rev: print("Stamping db version for future upgrades...") stamp() - print("Done creating DB.") \ No newline at end of file + print("Done creating DB.") + + if args.demo: + print("Loading Demo Data...") + from common.db_schema import * + import datetime + import time + + + def today_plus(sch, num_days): + return BellScheduleDate(date=datetime.date.today() + datetime.timedelta(days=num_days)) + + s = School(owner_id="1234567890", full_name="Demonstration High School", acronym="DHS") + + + sc1 = BellSchedule( + full_name="Even Day", + display_name= "Even", + dates=[ + today_plus(s.id, 0), + today_plus(s.id, 2), + today_plus(s.id, 4) + ] + ) + + sc2 = BellSchedule( + full_name="Odd Day", + display_name="Odd", + dates=[ + today_plus(s.id, 1), + today_plus(s.id, 3) + ] + ) + + + s.schedules = [sc1,sc2] + + + sc1.meeting_times = [ + BellScheduleMeetingTime( + bell_schedule_id =sc1.id, + name="First Period", + start_time=datetime.time(hour=8, minute=25, second=0, microsecond=0), + end_time=datetime.time(9,25) + ) + ] + + sc2.meeting_times = [ + BellScheduleMeetingTime( + bell_schedule_id =sc2.id, + name="First Period", + start_time=datetime.time(8,45), + end_time=datetime.time(9,45) + ) + + ] + + db.session.add(s) + db.session.commit() + print("Done loading demo data.") + print("Done") \ No newline at end of file From 8a001ad9b3c6d76f80447c7560fd19c3a369c90b Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 13 Feb 2022 18:55:42 -0500 Subject: [PATCH 123/206] update docs about setting up a DB --- README.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 09f419c..a583712 100644 --- a/README.md +++ b/README.md @@ -18,9 +18,14 @@ This is the backend that provides access to the ClassClock database. -## Setup command +## First time Setup -To run the setup script, first create an empty database and a new user that can access the database. Then, with the environment variables set appropriately as listed above, execute `python3 api.py setup`. If you have not specified the `DB_USERNAME` or `DB_PASSWORD` environment variables, you will be prompted for them interactively when the script runs. +1. Prepare an empty database and have its configuration information handy (login, hostname/port, db name .etc) +2. Install all dependencies (including dev dependencies) using `pipenv install -d` +3. set up a `.env` file with your database configuration settings from earlier +4. create the db by running `pipenv run python3 createdb.py`. add the `--demo` flag to createdb if you want to include demo data. + +After this you should be ready to run the API. ## Docker From b9ca737aca16694a290bcf903492c67a1a5a9bee Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 13 Feb 2022 19:02:48 -0500 Subject: [PATCH 124/206] update link to API docs --- templates/home.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/home.html b/templates/home.html index 2b7d844..f6cb578 100644 --- a/templates/home.html +++ b/templates/home.html @@ -8,7 +8,7 @@

ClassClock API

This is the API for ClassClock.

If you came here looking for API docs, you can find them at the links below:

From b6f2d25dbb6f62c64b7c4b366fbe2c97f528f4e1 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 13 Feb 2022 19:35:56 -0500 Subject: [PATCH 125/206] add to api documentation --- blueprints/v0.py | 97 ++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 90 insertions(+), 7 deletions(-) diff --git a/blueprints/v0.py b/blueprints/v0.py index 4291c27..cc94a85 100644 --- a/blueprints/v0.py +++ b/blueprints/v0.py @@ -85,6 +85,12 @@ @blueprint.route("/ping", strict_slashes=False, methods=['GET']) def ping(): + """ Returns the text "pong" as a connectivity check + --- + responses: + 200: + description: the text "pong" + """ return "pong" # TODO: add a search parameter @@ -209,13 +215,17 @@ def update_school(school_id): security: - ApiKeyAuth: [] parameters: - - in: header - name: If-Unmodified-Since + - in: path + name: school_id schema: - type: string - format: date - required: false - + type: string + length: 32 + required: true + - in: body + name: school + schema: + $ref: '#/definitions/School' + required: true """ data = get_request_body(request) @@ -303,8 +313,15 @@ def delete_school(school_id): @requires_admin def list_owned_bellschedules(): """ - gets a list of bell schedules + gets a list of bell schedules that are part of schools that the current user owns --- + security: + - ApiKeyAuth: [] + responses: + 200: + description: A list of bell schedules + schema: + $ref: '#/definitions/BellSchedule' """ #if get_api_user_id() not in school.owner_id @@ -326,6 +343,12 @@ def list_bellschedules(school_id): type: string length: 32 required: true + responses: + 200: + description: A list of bell schedules + schema: + $ref: '#/definitions/BellSchedule' + """ schedules = BellScheduleDB.query.filter_by(school_id=school_id) @@ -351,6 +374,11 @@ def get_bellschedule(bell_schedule_id): type: string format: date required: false + responses: + 200: + description: A single of bell schedule + schema: + $ref: '#/definitions/BellSchedule' """ schedule = BellScheduleDB.query.filter_by( @@ -375,6 +403,18 @@ def get_bellschedule(bell_schedule_id): @requires_auth(permissions=[APIScopes.CREATE_BELL_SCHEDULE]) @requires_admin def create_bellschedule(): + """ + Create a new bell schedule + --- + security: + - ApiKeyAuth: [] + parameters: + - in: body + name: schedule + schema: + $ref: '#/definitions/BellSchedule' + required: true + """ # get school_id from a data parameter school = SchoolDB.query.filter_by(id=school_id).first() @@ -394,6 +434,30 @@ def create_bellschedule(): @requires_auth(permissions=[APIScopes.EDIT_BELL_SCHEDULE]) @requires_admin def update_bellschedule(bell_schedule_id): + """ + Updates a bell schedule + --- + security: + - ApiKeyAuth: [] + parameters: + - in: path + name: bell_schedule_id + schema: + type: string + length: 32 + required: true + - in: body + name: schedule + schema: + $ref: '#/definitions/BellSchedule' + required: true + - in: header + name: If-Unmodified-Since + schema: + type: string + format: date + required: false + """ schedule = BellScheduleDB.query.filter_by(id=bell_schedule_id).first() school = SchoolDB.query.filter_by(id=schedule.school_id).first() @@ -427,6 +491,25 @@ def update_bellschedule(bell_schedule_id): @requires_auth(permissions=[APIScopes.DELETE_BELL_SCHEDULE]) @requires_admin def delete_bellschedule(bell_schedule_id): + """ + deletes a bell schedule + --- + security: + - ApiKeyAuth: [] + parameters: + - in: path + name: bell_schedule_id + schema: + type: string + length: 32 + required: true + - in: header + name: If-Unmodified-Since + schema: + type: string + format: date + required: false + """ schedule = BellScheduleDB.query.filter_by(id=bell_schedule_id).first() school = SchoolDB.query.filter_by(id=schedule.school_id).first() From a4abfb8afb18619708107ee31d5a97d3f376fa55 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 5 Jun 2022 20:23:21 -0400 Subject: [PATCH 126/206] try/catch the management API. maybe it needs keep-alive headers? --- common/services/auth0management.py | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/common/services/auth0management.py b/common/services/auth0management.py index 9b1ed46..04c3518 100644 --- a/common/services/auth0management.py +++ b/common/services/auth0management.py @@ -31,11 +31,18 @@ def get_roles_for_user(self, user_id): heads = {**Auth0ManagementService.headers, ** {"Authorization": "Bearer " + self.access_token}} self.conn.request("GET", url, "", heads) + try: + res = self.conn.getresponse() + data = res.read() + + return data.decode("utf-8") + except http.client.RemoteDisconnected as e: + # this tends to fail and then break all future auth0 stuff + # maybe its a connection keep alive problem? + # + print(e) + return [] - res = self.conn.getresponse() - data = res.read() - - return data.decode("utf-8") def get_token(self): payload = "{\"client_id\": \"" + env.get("AUTH0_CLIENT_ID") + "\" ,\"client_secret\": \"" + env.get( From ec42721ada00c56061a52b0d79ad6150dd59cb75 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 5 Jun 2022 20:33:17 -0400 Subject: [PATCH 127/206] commit deleted schools to the DB --- blueprints/v0.py | 1 + 1 file changed, 1 insertion(+) diff --git a/blueprints/v0.py b/blueprints/v0.py index cc94a85..77a4ae1 100644 --- a/blueprints/v0.py +++ b/blueprints/v0.py @@ -521,6 +521,7 @@ def delete_bellschedule(bell_schedule_id): trap_object_modified_since(school.last_modified, since) db.session.delete(schedule) + db.session.commit() return None, 204 From eae6e42abb38025f5d55808f380d0fb5be9413ac Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 5 Jun 2022 20:37:46 -0400 Subject: [PATCH 128/206] create initial migration --- .../93d6649210e1_initial_migration.py | 88 +++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 migrations/versions/93d6649210e1_initial_migration.py diff --git a/migrations/versions/93d6649210e1_initial_migration.py b/migrations/versions/93d6649210e1_initial_migration.py new file mode 100644 index 0000000..87e0be1 --- /dev/null +++ b/migrations/versions/93d6649210e1_initial_migration.py @@ -0,0 +1,88 @@ +"""Initial migration. + +Revision ID: 93d6649210e1 +Revises: +Create Date: 2022-06-05 20:34:41.432858 + +""" +from alembic import op +import sqlalchemy as sa +from sqlalchemy.dialects import mysql + +# revision identifiers, used by Alembic. +revision = '93d6649210e1' +down_revision = None +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.alter_column('bellscheduledates', 'creation_date', + existing_type=mysql.DATETIME(), + nullable=True) + op.drop_constraint('bellscheduledates_FK', 'bellscheduledates', type_='foreignkey') + op.drop_column('bellscheduledates', 'school_id') + op.alter_column('bellschedulemeetingtimes', 'creation_date', + existing_type=mysql.DATETIME(), + nullable=True) + op.drop_constraint('bellschedulemeetingtimes_FK', 'bellschedulemeetingtimes', type_='foreignkey') + op.drop_column('bellschedulemeetingtimes', 'school_id') + op.alter_column('bellschedules', 'bell_schedule_name', + existing_type=mysql.VARCHAR(charset='latin1', length=60), + nullable=True) + op.alter_column('bellschedules', 'creation_date', + existing_type=mysql.DATETIME(), + nullable=True) + op.alter_column('bellschedules', 'last_modified', + existing_type=mysql.DATETIME(), + nullable=True) + op.alter_column('schools', 'owner_id', + existing_type=mysql.VARCHAR(length=35), + nullable=True) + op.alter_column('schools', 'school_name', + existing_type=mysql.VARCHAR(charset='latin1', length=75), + nullable=True) + op.alter_column('schools', 'creation_date', + existing_type=mysql.DATETIME(), + nullable=True) + op.alter_column('schools', 'last_modified', + existing_type=mysql.DATETIME(), + nullable=True) + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.alter_column('schools', 'last_modified', + existing_type=mysql.DATETIME(), + nullable=False) + op.alter_column('schools', 'creation_date', + existing_type=mysql.DATETIME(), + nullable=False) + op.alter_column('schools', 'school_name', + existing_type=mysql.VARCHAR(charset='latin1', length=75), + nullable=False) + op.alter_column('schools', 'owner_id', + existing_type=mysql.VARCHAR(length=35), + nullable=False) + op.alter_column('bellschedules', 'last_modified', + existing_type=mysql.DATETIME(), + nullable=False) + op.alter_column('bellschedules', 'creation_date', + existing_type=mysql.DATETIME(), + nullable=False) + op.alter_column('bellschedules', 'bell_schedule_name', + existing_type=mysql.VARCHAR(charset='latin1', length=60), + nullable=False) + op.add_column('bellschedulemeetingtimes', sa.Column('school_id', sa.BINARY(length=16), nullable=False)) + op.create_foreign_key('bellschedulemeetingtimes_FK', 'bellschedulemeetingtimes', 'schools', ['school_id'], ['school_id']) + op.alter_column('bellschedulemeetingtimes', 'creation_date', + existing_type=mysql.DATETIME(), + nullable=False) + op.add_column('bellscheduledates', sa.Column('school_id', sa.BINARY(length=16), nullable=False)) + op.create_foreign_key('bellscheduledates_FK', 'bellscheduledates', 'schools', ['school_id'], ['school_id']) + op.alter_column('bellscheduledates', 'creation_date', + existing_type=mysql.DATETIME(), + nullable=False) + # ### end Alembic commands ### From 2921319dd02036a3cd2956dc8b7218a0251c0bd7 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 5 Jun 2022 20:38:27 -0400 Subject: [PATCH 129/206] fix response to deleting schedules --- blueprints/v0.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/blueprints/v0.py b/blueprints/v0.py index 77a4ae1..3e9a078 100644 --- a/blueprints/v0.py +++ b/blueprints/v0.py @@ -523,7 +523,7 @@ def delete_bellschedule(bell_schedule_id): db.session.delete(schedule) db.session.commit() - return None, 204 + return respond("success", code=204) # # Routes From 4d50b300ab34c5c70d49b77cf965c7ec961f5d59 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 5 Jun 2022 20:38:52 -0400 Subject: [PATCH 130/206] add soft deletion --- blueprints/v0.py | 11 ++++++----- common/db_schema.py | 2 ++ 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/blueprints/v0.py b/blueprints/v0.py index 3e9a078..b598dd8 100644 --- a/blueprints/v0.py +++ b/blueprints/v0.py @@ -325,7 +325,7 @@ def list_owned_bellschedules(): """ #if get_api_user_id() not in school.owner_id - schedules = BellScheduleDB.query.join(BellScheduleDB.school).filter(SchoolDB.owner_id==get_api_user_id()) + schedules = BellScheduleDB.query.join(BellScheduleDB.school).filter(SchoolDB.owner_id==get_api_user_id(), soft_deleted=False) return respond(BellScheduleSchema(exclude=('school_id',)).dump(schedules, many=True)) @@ -351,7 +351,7 @@ def list_bellschedules(school_id): """ - schedules = BellScheduleDB.query.filter_by(school_id=school_id) + schedules = BellScheduleDB.query.filter_by(school_id=school_id, soft_deleted=False) return respond(BellScheduleSchema(exclude=('school_id',)).dump(schedules, many=True)) @@ -382,7 +382,7 @@ def get_bellschedule(bell_schedule_id): """ schedule = BellScheduleDB.query.filter_by( - id=bell_schedule_id).first() + id=bell_schedule_id, soft_deleted=False).first() #double check this if schedule is None: @@ -511,7 +511,7 @@ def delete_bellschedule(bell_schedule_id): required: false """ - schedule = BellScheduleDB.query.filter_by(id=bell_schedule_id).first() + schedule = BellScheduleDB.query.filter_by(id=bell_schedule_id, soft_deleted=False).first() school = SchoolDB.query.filter_by(id=schedule.school_id).first() if school is not None: check_ownership(school) @@ -520,7 +520,8 @@ def delete_bellschedule(bell_schedule_id): since = datetime.datetime.strptime(request.headers.get('If-Unmodified-Since'), HTTP_DATE_FORMAT) trap_object_modified_since(school.last_modified, since) - db.session.delete(schedule) + schedule.soft_deleted = True + # db.session.delete(schedule) db.session.commit() return respond("success", code=204) diff --git a/common/db_schema.py b/common/db_schema.py index 9bb8847..0e17566 100644 --- a/common/db_schema.py +++ b/common/db_schema.py @@ -31,6 +31,7 @@ class School(db.Model): default=datetime.utcnow()) last_modified = db.Column('last_modified', db.DateTime, default=datetime.utcnow(), onupdate=datetime.utcnow) + soft_deleted = db.Column('soft_deleted', db.Boolean, default=False) class BellSchedule(db.Model): """ @@ -47,6 +48,7 @@ class BellSchedule(db.Model): default=datetime.utcnow()) last_modified = db.Column('last_modified', db.DateTime, default=datetime.utcnow(), onupdate=datetime.utcnow) + soft_deleted = db.Column('soft_deleted', db.Boolean, default=False) def get_uri(self, blueprint_name): # here the second time blueprint_name is called, it is acting like the api version number From d3b5714635af4f1e886f418b344c5ea3b2919e58 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 5 Jun 2022 20:41:36 -0400 Subject: [PATCH 131/206] add soft deletion migration --- .../2399c50496f7_add_soft_deletion.py | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 migrations/versions/2399c50496f7_add_soft_deletion.py diff --git a/migrations/versions/2399c50496f7_add_soft_deletion.py b/migrations/versions/2399c50496f7_add_soft_deletion.py new file mode 100644 index 0000000..9105bbd --- /dev/null +++ b/migrations/versions/2399c50496f7_add_soft_deletion.py @@ -0,0 +1,30 @@ +"""Add Soft Deletion + +Revision ID: 2399c50496f7 +Revises: 93d6649210e1 +Create Date: 2022-06-05 20:40:27.591102 + +""" +from alembic import op +import sqlalchemy as sa +from sqlalchemy.dialects import mysql + +# revision identifiers, used by Alembic. +revision = '2399c50496f7' +down_revision = '93d6649210e1' +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.add_column('bellschedules', sa.Column('soft_deleted', sa.Boolean(), nullable=True)) + op.add_column('schools', sa.Column('soft_deleted', sa.Boolean(), nullable=True)) + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.drop_column('schools', 'soft_deleted') + op.drop_column('bellschedules', 'soft_deleted') + # ### end Alembic commands ### From 6357845e462eebf4af10a5827fab14e702edce48 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 5 Jun 2022 20:46:01 -0400 Subject: [PATCH 132/206] make the soft delete columns not nullable --- common/db_schema.py | 4 ++-- migrations/versions/2399c50496f7_add_soft_deletion.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/common/db_schema.py b/common/db_schema.py index 0e17566..85cd072 100644 --- a/common/db_schema.py +++ b/common/db_schema.py @@ -31,7 +31,7 @@ class School(db.Model): default=datetime.utcnow()) last_modified = db.Column('last_modified', db.DateTime, default=datetime.utcnow(), onupdate=datetime.utcnow) - soft_deleted = db.Column('soft_deleted', db.Boolean, default=False) + soft_deleted = db.Column('soft_deleted', db.Boolean, nullable=False, default=False) class BellSchedule(db.Model): """ @@ -48,7 +48,7 @@ class BellSchedule(db.Model): default=datetime.utcnow()) last_modified = db.Column('last_modified', db.DateTime, default=datetime.utcnow(), onupdate=datetime.utcnow) - soft_deleted = db.Column('soft_deleted', db.Boolean, default=False) + soft_deleted = db.Column('soft_deleted', db.Boolean, nullable=False, default=False) def get_uri(self, blueprint_name): # here the second time blueprint_name is called, it is acting like the api version number diff --git a/migrations/versions/2399c50496f7_add_soft_deletion.py b/migrations/versions/2399c50496f7_add_soft_deletion.py index 9105bbd..afd745b 100644 --- a/migrations/versions/2399c50496f7_add_soft_deletion.py +++ b/migrations/versions/2399c50496f7_add_soft_deletion.py @@ -18,8 +18,8 @@ def upgrade(): # ### commands auto generated by Alembic - please adjust! ### - op.add_column('bellschedules', sa.Column('soft_deleted', sa.Boolean(), nullable=True)) - op.add_column('schools', sa.Column('soft_deleted', sa.Boolean(), nullable=True)) + op.add_column('bellschedules', sa.Column('soft_deleted', sa.Boolean(), nullable=False, default=False)) + op.add_column('schools', sa.Column('soft_deleted', sa.Boolean(), nullable=False, default=False)) # ### end Alembic commands ### From 5d15e5ef6d13f463cefd32f95d219cdbd170a9bc Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 5 Jun 2022 20:54:37 -0400 Subject: [PATCH 133/206] more filtering and exclusion of soft delete stuff --- blueprints/v0.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/blueprints/v0.py b/blueprints/v0.py index b598dd8..36fb1b7 100644 --- a/blueprints/v0.py +++ b/blueprints/v0.py @@ -109,9 +109,9 @@ def list_schools(): """ school_list = [] - schools = SchoolDB.query.all() + schools = SchoolDB.query.filter_by(soft_deleted=False).all() - return respond(SchoolSchema().dump(schools, many=True)) + return respond(SchoolSchema(exclude=('soft_deleted',)).dump(schools, many=True)) @blueprint.route("/school/", strict_slashes=False, methods=['GET']) @@ -139,7 +139,7 @@ def get_school(school_id): required: false """ - school = SchoolDB.query.filter_by(id=school_id).first() + school = SchoolDB.query.filter_by(id=school_id, soft_deleted=False).first() #double check this if school is None: raise Oops("No school was found with the specified id.", @@ -151,7 +151,7 @@ def get_school(school_id): if school.last_modified == since: return respond(code=304) #Not Modified - return respond(SchoolSchema().dump(school)) + return respond(SchoolSchema(exclude=('soft_deleted',)).dump(school)) @blueprint.route("/school", strict_slashes=False, methods=['POST']) @@ -201,7 +201,7 @@ def create_school(): #TODO: need to verify that the insert worked? - return respond(SchoolSchema().dump(new_object)) + return respond(SchoolSchema(exclude=('soft_deleted',)).dump(new_object)) @blueprint.route("/school/", strict_slashes=False, methods=['PATCH']) @@ -233,7 +233,7 @@ def update_school(school_id): # if new_object.errors != {}: # return handle_marshmallow_errors(new_object.errors) - school = SchoolDB.query.filter_by(id=school_id).first() + school = SchoolDB.query.filter_by(id=school_id, soft_deleted=False).first() if school is None: raise Oops("No records could be updated because none were found", @@ -259,7 +259,7 @@ def update_school(school_id): db.session.commit() #TODO: need to verify that the update worked? - return respond(SchoolSchema().dump(school)) + return respond(SchoolSchema(exclude=('soft_deleted',)).dump(school)) @blueprint.route("/school/", strict_slashes=False, methods=['DELETE']) @@ -288,7 +288,7 @@ def delete_school(school_id): """ - school = SchoolDB.query.filter_by(id=school_id).first() + school = SchoolDB.query.filter_by(id=school_id, soft_deleted=False).first() if school is None: raise Oops("No records could be deleted because none were found", 404, title="No Records Found") @@ -325,9 +325,9 @@ def list_owned_bellschedules(): """ #if get_api_user_id() not in school.owner_id - schedules = BellScheduleDB.query.join(BellScheduleDB.school).filter(SchoolDB.owner_id==get_api_user_id(), soft_deleted=False) + schedules = BellScheduleDB.query.join(BellScheduleDB.school).filter(SchoolDB.owner_id==get_api_user_id(), SchoolDB.soft_deleted==False, BellScheduleDB.soft_deleted==False) - return respond(BellScheduleSchema(exclude=('school_id',)).dump(schedules, many=True)) + return respond(BellScheduleSchema(exclude=('school_id','soft_deleted')).dump(schedules, many=True)) #TODO: add filtering for return values to reduce size of response. i.e. filter dates by after today, exclude meeting times if they havent changed @blueprint.route("/bellschedules/", strict_slashes=False, methods=['GET']) @@ -395,7 +395,7 @@ def get_bellschedule(bell_schedule_id): if schedule.last_modified == since: return respond(code=304) #Not Modified - return respond(BellScheduleSchema().dump(schedule)) + return respond(BellScheduleSchema(exclude=('soft_deleted',)).dump(schedule)) @blueprint.route("/bellschedule", strict_slashes=False, methods=['POST']) From e8ae1315ea62813db8c27b722b07e4d2468f3684 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 5 Jun 2022 21:06:42 -0400 Subject: [PATCH 134/206] set ID based on URL for incoming schedule updates --- blueprints/v0.py | 1 + 1 file changed, 1 insertion(+) diff --git a/blueprints/v0.py b/blueprints/v0.py index 36fb1b7..cdea0eb 100644 --- a/blueprints/v0.py +++ b/blueprints/v0.py @@ -476,6 +476,7 @@ def update_bellschedule(bell_schedule_id): try: updated_schedule = BellScheduleSchema(exclude=('id', 'creation_date')).load( data, session=db.session, instance=schedule) + updated_schedule.id = bell_schedule_id except ValidationError as err: # print(err.messages) # => {"email": ['"foo" is not a valid email address.']} # print(err.valid_data) From 55faeb462e8102a7825bb5502ee79b790326742b Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 5 Jun 2022 21:31:05 -0400 Subject: [PATCH 135/206] more soft delete stuff --- blueprints/v0.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/blueprints/v0.py b/blueprints/v0.py index cdea0eb..28c0f56 100644 --- a/blueprints/v0.py +++ b/blueprints/v0.py @@ -426,7 +426,7 @@ def create_bellschedule(): db.session.commit() - return respond(BellScheduleSchema(exclude=('school_id',)).dump(new_schedule)) + return respond(BellScheduleSchema(exclude=('school_id','soft_deleted')).dump(new_schedule)) @blueprint.route("/bellschedule/", strict_slashes=False, methods=['PATCH']) @@ -484,7 +484,7 @@ def update_bellschedule(bell_schedule_id): db.session.commit() - return respond(BellScheduleSchema(exclude=('school_id',)).dump(schedule)) + return respond(BellScheduleSchema(exclude=('school_id','soft_deleted')).dump(schedule)) @blueprint.route("/bellschedule/", methods=['DELETE']) From 773591c622a023dd5507d73a1430cdb67a5d9118 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 5 Jun 2022 22:33:55 -0400 Subject: [PATCH 136/206] add cascade rules to bellschedulemeetingtime too --- common/db_schema.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/db_schema.py b/common/db_schema.py index 85cd072..0457560 100644 --- a/common/db_schema.py +++ b/common/db_schema.py @@ -42,7 +42,7 @@ class BellSchedule(db.Model): primary_key=True, default=get_uuid) school_id = db.Column(HashColumn(length=32), ForeignKey(School.id)) full_name = db.Column('bell_schedule_name', db.VARCHAR(length=75)) - meeting_times = db.relationship("BellScheduleMeetingTime") + meeting_times = db.relationship("BellScheduleMeetingTime", cascade="save-update, merge,delete, delete-orphan") display_name = db.Column('bell_schedule_display_name', db.VARCHAR(length=75)) creation_date = db.Column('creation_date', db.DateTime, default=datetime.utcnow()) From 6e808d38c63a368c05ae270af60887e6078b9fbc Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 5 Jun 2022 22:34:38 -0400 Subject: [PATCH 137/206] update error message for management api error --- common/services/auth0management.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/services/auth0management.py b/common/services/auth0management.py index 04c3518..41a6663 100644 --- a/common/services/auth0management.py +++ b/common/services/auth0management.py @@ -40,7 +40,7 @@ def get_roles_for_user(self, user_id): # this tends to fail and then break all future auth0 stuff # maybe its a connection keep alive problem? # - print(e) + print("Auth0 Management API error: ", e) return [] From a287cd45caad82fed474c51c97ee8a260e390554 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 5 Jun 2022 22:37:20 -0400 Subject: [PATCH 138/206] no need to set the id --- blueprints/v0.py | 1 - 1 file changed, 1 deletion(-) diff --git a/blueprints/v0.py b/blueprints/v0.py index 28c0f56..6d2f547 100644 --- a/blueprints/v0.py +++ b/blueprints/v0.py @@ -476,7 +476,6 @@ def update_bellschedule(bell_schedule_id): try: updated_schedule = BellScheduleSchema(exclude=('id', 'creation_date')).load( data, session=db.session, instance=schedule) - updated_schedule.id = bell_schedule_id except ValidationError as err: # print(err.messages) # => {"email": ['"foo" is not a valid email address.']} # print(err.valid_data) From fa35cfe710ab55596c1a5742a5ff4015d9c5dc20 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 5 Jun 2022 23:03:47 -0400 Subject: [PATCH 139/206] add migration for deleting the school_id column --- ...fb763_remove_school_id_on_meeting_times.py | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 migrations/versions/9a408a3fb763_remove_school_id_on_meeting_times.py diff --git a/migrations/versions/9a408a3fb763_remove_school_id_on_meeting_times.py b/migrations/versions/9a408a3fb763_remove_school_id_on_meeting_times.py new file mode 100644 index 0000000..985225b --- /dev/null +++ b/migrations/versions/9a408a3fb763_remove_school_id_on_meeting_times.py @@ -0,0 +1,30 @@ +"""remove school_id on meeting times + +Revision ID: 9a408a3fb763 +Revises: 2399c50496f7 +Create Date: 2022-06-05 22:45:11.620997 + +""" +from alembic import op +import sqlalchemy as sa +from sqlalchemy.dialects import mysql + +# revision identifiers, used by Alembic. +revision = '9a408a3fb763' +down_revision = '2399c50496f7' +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.drop_index('bellschedulemeetingtimes_FK', table_name='bellschedulemeetingtimes') + op.drop_column('bellschedulemeetingtimes', 'school_id') + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.add_column('bellschedulemeetingtimes', sa.Column('school_id', sa.BINARY(length=16), nullable=False)) + op.create_index('bellschedulemeetingtimes_FK', 'bellschedulemeetingtimes', ['school_id'], unique=False) + # ### end Alembic commands ### From 076be2df96a082ed90ef7faacc0a78ac8fea2769 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Wed, 17 Aug 2022 12:51:25 -0400 Subject: [PATCH 140/206] version bump i guess --- docs.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs.py b/docs.py index cf66f6d..f9f9fe6 100644 --- a/docs.py +++ b/docs.py @@ -16,7 +16,7 @@ def create_docs(app): # info: { spec = APISpec( title="ClassClock API", - version="0.1", + version="0.2.1", openapi_version='2.0', plugins=[ From 5f8b9398b5b3a0f208a84345bc4053beb3403d4f Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Wed, 17 Aug 2022 17:41:10 -0400 Subject: [PATCH 141/206] install flask-migrate --- Pipfile | 1 + Pipfile.lock | 585 +++++++++++++++++++++++++++++---------------------- 2 files changed, 338 insertions(+), 248 deletions(-) diff --git a/Pipfile b/Pipfile index 437db4b..11ed576 100644 --- a/Pipfile +++ b/Pipfile @@ -22,6 +22,7 @@ apispec-webframeworks = "~=0.5.2" mysql-connector-python = "8.0.24" python-jose = "*" python-dotenv = "*" +flask-migrate = "*" [requires] python_version = "3.8" diff --git a/Pipfile.lock b/Pipfile.lock index deba527..be4e2f9 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "a3124aaeb49267859e81647582eea7a2d511ba9ee4e211b411768af7415f1a9e" + "sha256": "8e88cb8643cc35106d3a225420f4e8cfbd39419986dbb60b23360aed145f5966" }, "pipfile-spec": 6, "requires": { @@ -16,10 +16,16 @@ ] }, "default": { - "apispec": { - "extras": [ - "yaml" + "alembic": { + "hashes": [ + "sha256:0a024d7f2de88d738d7395ff866997314c837be6104e90c5724350313dee4da4", + "sha256:cd0b5e45b14b706426b833f06369b9a6d5ee03f826ec3238723ce8caaf6e5ffa" ], + "markers": "python_version >= '3.7'", + "version": "==1.8.1" + }, + "apispec": { + "extras": [], "hashes": [ "sha256:a1df9ec6b2cd0edf45039ef025abd7f0660808fa2edf737d3ba1cf5ef1a4625b", "sha256:d23ebd5b71e541e031b02a19db10b5e6d5ef8452c552833e3e1afc836b40b1ad" @@ -37,11 +43,11 @@ }, "attrs": { "hashes": [ - "sha256:2d27e3784d7a565d36ab851fe94887c5eccd6a463168875832a1be79c82828b4", - "sha256:626ba8234211db98e869df76230a137c4c40a12d72445c45d5f5b716f076e2fd" + "sha256:29adc2665447e5191d0e7c568fde78b21f9672d344281d0c6e1ab085429b22b6", + "sha256:86efa402f67bf2df34f51a335487cf46b1ec130d02b8d39fd248abfd30da551c" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==21.4.0" + "markers": "python_version >= '3.5'", + "version": "==22.1.0" }, "click": { "hashes": [ @@ -51,13 +57,21 @@ "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", "version": "==7.1.2" }, + "deprecated": { + "hashes": [ + "sha256:43ac5335da90c31c24ba028af536a91d41d53f9e6901ddb021bcc572ce44e38d", + "sha256:64756e3e14c8c5eea9795d93c524551432a0be75629f8f29e67ab8caf076c76d" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==1.2.13" + }, "ecdsa": { "hashes": [ - "sha256:5cf31d5b33743abe0dfc28999036c849a69d548f994b535e527ee3cb7f3ef676", - "sha256:b9f500bb439e4153d0330610f5d26baaf18d17b8ced1bc54410d189385ea68aa" + "sha256:190348041559e21b22a1d65cee485282ca11a6f81d503fddb84d5017e9ed1e49", + "sha256:80600258e7ed2f16b9aa1d7c295bd70194109ad5a30fdee0eaeefef1d4c559dd" ], "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==0.17.0" + "version": "==0.18.0" }, "flasgger": { "hashes": [ @@ -99,6 +113,14 @@ "index": "pypi", "version": "==0.10.1" }, + "flask-migrate": { + "hashes": [ + "sha256:57d6060839e3a7f150eaab6fe4e726d9e3e7cffe2150fb223d73f92421c6d1d9", + "sha256:a6498706241aba6be7a251078de9cf166d74307bca41a4ca3e403c9d39e2f897" + ], + "index": "pypi", + "version": "==3.1.0" + }, "flask-sqlalchemy": { "hashes": [ "sha256:05b31d2034dd3f2a685cbbae4cfc4ed906b2a733cff7964ada450fd5e462b84e", @@ -115,13 +137,21 @@ "index": "pypi", "version": "==19.9.0" }, + "importlib-metadata": { + "hashes": [ + "sha256:637245b8bab2b6502fcbc752cc4b7a6f6243bb02b31c5c26156ad103d3d45670", + "sha256:7401a975809ea1fdc658c3aa4f78cc2195a0e019c5cbc4c06122884e9ae80c23" + ], + "markers": "python_version < '3.9'", + "version": "==4.12.0" + }, "importlib-resources": { "hashes": [ - "sha256:33a95faed5fc19b4bc16b29a6eeae248a3fe69dd55d4d229d2b480e23eeaad45", - "sha256:d756e2f85dd4de2ba89be0b21dba2a3bbec2e871a42a3a16719258a11f87506b" + "sha256:5481e97fb45af8dcf2f798952625591c58fe599d0735d86b10f54de086a61681", + "sha256:f78a8df21a79bcc30cfd400bdc38f314333de7c0fb619763f6b9dabab8268bb7" ], "markers": "python_version < '3.9'", - "version": "==5.4.0" + "version": "==5.9.0" }, "itsdangerous": { "hashes": [ @@ -141,176 +171,169 @@ }, "jsonschema": { "hashes": [ - "sha256:636694eb41b3535ed608fe04129f26542b59ed99808b4f688aa32dcf55317a83", - "sha256:77281a1f71684953ee8b3d488371b162419767973789272434bbc3f29d9c8823" + "sha256:09a0c8547c0d5c3651e43889dcf6626d35965cc2b4924d3fb0d66cdd9e038101", + "sha256:1a500bb42bd96f54a00aa61213d8595ee9d07c06150c5cd74cb9d307a4a8e40a" ], "markers": "python_version >= '3.7'", - "version": "==4.4.0" + "version": "==4.10.2" }, "limits": { "hashes": [ - "sha256:9ead6236a71eb1d9a18d7e3b1faa58d588ea3510e55514fae58babc0a3223986", - "sha256:d4270d29591cc5eceab19be053455a4e619ba395062502bde2b5681af7dc1be8" + "sha256:847a78b24a47e822a8f8713028a1340db44003763ab1cb90e798ccf462880355", + "sha256:cf043c376f14208a8204dc4cd74af1210fcaf24082bf7e3a38028706aa129899" ], "markers": "python_version >= '3.7'", - "version": "==2.3.3" + "version": "==2.7.0" + }, + "mako": { + "hashes": [ + "sha256:df3921c3081b013c8a2d5ff03c18375651684921ae83fd12e64800b7da923257", + "sha256:f054a5ff4743492f1aa9ecc47172cb33b42b9d993cffcc146c9de17e717b0307" + ], + "markers": "python_version >= '3.7'", + "version": "==1.2.1" }, "markupsafe": { "hashes": [ - "sha256:01a9b8ea66f1658938f65b93a85ebe8bc016e6769611be228d797c9d998dd298", - "sha256:023cb26ec21ece8dc3907c0e8320058b2e0cb3c55cf9564da612bc325bed5e64", - "sha256:0446679737af14f45767963a1a9ef7620189912317d095f2d9ffa183a4d25d2b", - "sha256:04635854b943835a6ea959e948d19dcd311762c5c0c6e1f0e16ee57022669194", - "sha256:0717a7390a68be14b8c793ba258e075c6f4ca819f15edfc2a3a027c823718567", - "sha256:0955295dd5eec6cb6cc2fe1698f4c6d84af2e92de33fbcac4111913cd100a6ff", - "sha256:0d4b31cc67ab36e3392bbf3862cfbadac3db12bdd8b02a2731f509ed5b829724", - "sha256:10f82115e21dc0dfec9ab5c0223652f7197feb168c940f3ef61563fc2d6beb74", - "sha256:168cd0a3642de83558a5153c8bd34f175a9a6e7f6dc6384b9655d2697312a646", - "sha256:1d609f577dc6e1aa17d746f8bd3c31aa4d258f4070d61b2aa5c4166c1539de35", - "sha256:1f2ade76b9903f39aa442b4aadd2177decb66525062db244b35d71d0ee8599b6", - "sha256:20dca64a3ef2d6e4d5d615a3fd418ad3bde77a47ec8a23d984a12b5b4c74491a", - "sha256:2a7d351cbd8cfeb19ca00de495e224dea7e7d919659c2841bbb7f420ad03e2d6", - "sha256:2d7d807855b419fc2ed3e631034685db6079889a1f01d5d9dac950f764da3dad", - "sha256:2ef54abee730b502252bcdf31b10dacb0a416229b72c18b19e24a4509f273d26", - "sha256:36bc903cbb393720fad60fc28c10de6acf10dc6cc883f3e24ee4012371399a38", - "sha256:37205cac2a79194e3750b0af2a5720d95f786a55ce7df90c3af697bfa100eaac", - "sha256:3c112550557578c26af18a1ccc9e090bfe03832ae994343cfdacd287db6a6ae7", - "sha256:3dd007d54ee88b46be476e293f48c85048603f5f516008bee124ddd891398ed6", - "sha256:4296f2b1ce8c86a6aea78613c34bb1a672ea0e3de9c6ba08a960efe0b0a09047", - "sha256:47ab1e7b91c098ab893b828deafa1203de86d0bc6ab587b160f78fe6c4011f75", - "sha256:49e3ceeabbfb9d66c3aef5af3a60cc43b85c33df25ce03d0031a608b0a8b2e3f", - "sha256:4dc8f9fb58f7364b63fd9f85013b780ef83c11857ae79f2feda41e270468dd9b", - "sha256:4efca8f86c54b22348a5467704e3fec767b2db12fc39c6d963168ab1d3fc9135", - "sha256:53edb4da6925ad13c07b6d26c2a852bd81e364f95301c66e930ab2aef5b5ddd8", - "sha256:5855f8438a7d1d458206a2466bf82b0f104a3724bf96a1c781ab731e4201731a", - "sha256:594c67807fb16238b30c44bdf74f36c02cdf22d1c8cda91ef8a0ed8dabf5620a", - "sha256:5b6d930f030f8ed98e3e6c98ffa0652bdb82601e7a016ec2ab5d7ff23baa78d1", - "sha256:5bb28c636d87e840583ee3adeb78172efc47c8b26127267f54a9c0ec251d41a9", - "sha256:60bf42e36abfaf9aff1f50f52644b336d4f0a3fd6d8a60ca0d054ac9f713a864", - "sha256:611d1ad9a4288cf3e3c16014564df047fe08410e628f89805e475368bd304914", - "sha256:6300b8454aa6930a24b9618fbb54b5a68135092bc666f7b06901f897fa5c2fee", - "sha256:63f3268ba69ace99cab4e3e3b5840b03340efed0948ab8f78d2fd87ee5442a4f", - "sha256:6557b31b5e2c9ddf0de32a691f2312a32f77cd7681d8af66c2692efdbef84c18", - "sha256:693ce3f9e70a6cf7d2fb9e6c9d8b204b6b39897a2c4a1aa65728d5ac97dcc1d8", - "sha256:6a7fae0dd14cf60ad5ff42baa2e95727c3d81ded453457771d02b7d2b3f9c0c2", - "sha256:6c4ca60fa24e85fe25b912b01e62cb969d69a23a5d5867682dd3e80b5b02581d", - "sha256:6fcf051089389abe060c9cd7caa212c707e58153afa2c649f00346ce6d260f1b", - "sha256:7d91275b0245b1da4d4cfa07e0faedd5b0812efc15b702576d103293e252af1b", - "sha256:89c687013cb1cd489a0f0ac24febe8c7a666e6e221b783e53ac50ebf68e45d86", - "sha256:8d206346619592c6200148b01a2142798c989edcb9c896f9ac9722a99d4e77e6", - "sha256:905fec760bd2fa1388bb5b489ee8ee5f7291d692638ea5f67982d968366bef9f", - "sha256:97383d78eb34da7e1fa37dd273c20ad4320929af65d156e35a5e2d89566d9dfb", - "sha256:984d76483eb32f1bcb536dc27e4ad56bba4baa70be32fa87152832cdd9db0833", - "sha256:99df47edb6bda1249d3e80fdabb1dab8c08ef3975f69aed437cb69d0a5de1e28", - "sha256:9f02365d4e99430a12647f09b6cc8bab61a6564363f313126f775eb4f6ef798e", - "sha256:a30e67a65b53ea0a5e62fe23682cfe22712e01f453b95233b25502f7c61cb415", - "sha256:ab3ef638ace319fa26553db0624c4699e31a28bb2a835c5faca8f8acf6a5a902", - "sha256:aca6377c0cb8a8253e493c6b451565ac77e98c2951c45f913e0b52facdcff83f", - "sha256:add36cb2dbb8b736611303cd3bfcee00afd96471b09cda130da3581cbdc56a6d", - "sha256:b2f4bf27480f5e5e8ce285a8c8fd176c0b03e93dcc6646477d4630e83440c6a9", - "sha256:b7f2d075102dc8c794cbde1947378051c4e5180d52d276987b8d28a3bd58c17d", - "sha256:baa1a4e8f868845af802979fcdbf0bb11f94f1cb7ced4c4b8a351bb60d108145", - "sha256:be98f628055368795d818ebf93da628541e10b75b41c559fdf36d104c5787066", - "sha256:bf5d821ffabf0ef3533c39c518f3357b171a1651c1ff6827325e4489b0e46c3c", - "sha256:c47adbc92fc1bb2b3274c4b3a43ae0e4573d9fbff4f54cd484555edbf030baf1", - "sha256:cdfba22ea2f0029c9261a4bd07e830a8da012291fbe44dc794e488b6c9bb353a", - "sha256:d6c7ebd4e944c85e2c3421e612a7057a2f48d478d79e61800d81468a8d842207", - "sha256:d7f9850398e85aba693bb640262d3611788b1f29a79f0c93c565694658f4071f", - "sha256:d8446c54dc28c01e5a2dbac5a25f071f6653e6e40f3a8818e8b45d790fe6ef53", - "sha256:deb993cacb280823246a026e3b2d81c493c53de6acfd5e6bfe31ab3402bb37dd", - "sha256:e0f138900af21926a02425cf736db95be9f4af72ba1bb21453432a07f6082134", - "sha256:e9936f0b261d4df76ad22f8fee3ae83b60d7c3e871292cd42f40b81b70afae85", - "sha256:f0567c4dc99f264f49fe27da5f735f414c4e7e7dd850cfd8e69f0862d7c74ea9", - "sha256:f5653a225f31e113b152e56f154ccbe59eeb1c7487b39b9d9f9cdb58e6c79dc5", - "sha256:f826e31d18b516f653fe296d967d700fddad5901ae07c622bb3705955e1faa94", - "sha256:f8ba0e8349a38d3001fae7eadded3f6606f0da5d748ee53cc1dab1d6527b9509", - "sha256:f9081981fe268bd86831e5c75f7de206ef275defcb82bc70740ae6dc507aee51", - "sha256:fa130dd50c57d53368c9d59395cb5526eda596d3ffe36666cd81a44d56e48872" + "sha256:0212a68688482dc52b2d45013df70d169f542b7394fc744c02a57374a4207003", + "sha256:089cf3dbf0cd6c100f02945abeb18484bd1ee57a079aefd52cffd17fba910b88", + "sha256:10c1bfff05d95783da83491be968e8fe789263689c02724e0c691933c52994f5", + "sha256:33b74d289bd2f5e527beadcaa3f401e0df0a89927c1559c8566c066fa4248ab7", + "sha256:3799351e2336dc91ea70b034983ee71cf2f9533cdff7c14c90ea126bfd95d65a", + "sha256:3ce11ee3f23f79dbd06fb3d63e2f6af7b12db1d46932fe7bd8afa259a5996603", + "sha256:421be9fbf0ffe9ffd7a378aafebbf6f4602d564d34be190fc19a193232fd12b1", + "sha256:43093fb83d8343aac0b1baa75516da6092f58f41200907ef92448ecab8825135", + "sha256:46d00d6cfecdde84d40e572d63735ef81423ad31184100411e6e3388d405e247", + "sha256:4a33dea2b688b3190ee12bd7cfa29d39c9ed176bda40bfa11099a3ce5d3a7ac6", + "sha256:4b9fe39a2ccc108a4accc2676e77da025ce383c108593d65cc909add5c3bd601", + "sha256:56442863ed2b06d19c37f94d999035e15ee982988920e12a5b4ba29b62ad1f77", + "sha256:671cd1187ed5e62818414afe79ed29da836dde67166a9fac6d435873c44fdd02", + "sha256:694deca8d702d5db21ec83983ce0bb4b26a578e71fbdbd4fdcd387daa90e4d5e", + "sha256:6a074d34ee7a5ce3effbc526b7083ec9731bb3cbf921bbe1d3005d4d2bdb3a63", + "sha256:6d0072fea50feec76a4c418096652f2c3238eaa014b2f94aeb1d56a66b41403f", + "sha256:6fbf47b5d3728c6aea2abb0589b5d30459e369baa772e0f37a0320185e87c980", + "sha256:7f91197cc9e48f989d12e4e6fbc46495c446636dfc81b9ccf50bb0ec74b91d4b", + "sha256:86b1f75c4e7c2ac2ccdaec2b9022845dbb81880ca318bb7a0a01fbf7813e3812", + "sha256:8dc1c72a69aa7e082593c4a203dcf94ddb74bb5c8a731e4e1eb68d031e8498ff", + "sha256:8e3dcf21f367459434c18e71b2a9532d96547aef8a871872a5bd69a715c15f96", + "sha256:8e576a51ad59e4bfaac456023a78f6b5e6e7651dcd383bcc3e18d06f9b55d6d1", + "sha256:96e37a3dc86e80bf81758c152fe66dbf60ed5eca3d26305edf01892257049925", + "sha256:97a68e6ada378df82bc9f16b800ab77cbf4b2fada0081794318520138c088e4a", + "sha256:99a2a507ed3ac881b975a2976d59f38c19386d128e7a9a18b7df6fff1fd4c1d6", + "sha256:a49907dd8420c5685cfa064a1335b6754b74541bbb3706c259c02ed65b644b3e", + "sha256:b09bf97215625a311f669476f44b8b318b075847b49316d3e28c08e41a7a573f", + "sha256:b7bd98b796e2b6553da7225aeb61f447f80a1ca64f41d83612e6139ca5213aa4", + "sha256:b87db4360013327109564f0e591bd2a3b318547bcef31b468a92ee504d07ae4f", + "sha256:bcb3ed405ed3222f9904899563d6fc492ff75cce56cba05e32eff40e6acbeaa3", + "sha256:d4306c36ca495956b6d568d276ac11fdd9c30a36f1b6eb928070dc5360b22e1c", + "sha256:d5ee4f386140395a2c818d149221149c54849dfcfcb9f1debfe07a8b8bd63f9a", + "sha256:dda30ba7e87fbbb7eab1ec9f58678558fd9a6b8b853530e176eabd064da81417", + "sha256:e04e26803c9c3851c931eac40c695602c6295b8d432cbe78609649ad9bd2da8a", + "sha256:e1c0b87e09fa55a220f058d1d49d3fb8df88fbfab58558f1198e08c1e1de842a", + "sha256:e72591e9ecd94d7feb70c1cbd7be7b3ebea3f548870aa91e2732960fa4d57a37", + "sha256:e8c843bbcda3a2f1e3c2ab25913c80a3c5376cd00c6e8c4a86a89a28c8dc5452", + "sha256:efc1913fd2ca4f334418481c7e595c00aad186563bbc1ec76067848c7ca0a933", + "sha256:f121a1420d4e173a5d96e47e9a0c0dcff965afdf1626d28de1460815f7c4ee7a", + "sha256:fc7b548b17d238737688817ab67deebb30e8073c95749d55538ed473130ec0c7" ], - "markers": "python_version >= '3.6'", - "version": "==2.0.1" + "markers": "python_version >= '3.7'", + "version": "==2.1.1" }, "marshmallow": { "hashes": [ - "sha256:04438610bc6dadbdddb22a4a55bcc7f6f8099e69580b2e67f5a681933a1f4400", - "sha256:4c05c1684e0e97fe779c62b91878f173b937fe097b356cd82f793464f5bc6138" + "sha256:00040ab5ea0c608e8787137627a8efae97fabd60552a05dc889c888f814e75eb", + "sha256:635fb65a3285a31a30f276f30e958070f5214c7196202caa5c7ecf28f5274bc7" ], - "markers": "python_version >= '3.6'", - "version": "==3.14.1" + "markers": "python_version >= '3.7'", + "version": "==3.17.0" }, "marshmallow-sqlalchemy": { "hashes": [ - "sha256:1521b129564444648c523a38f6446c137f1aae5c9c7de1ec151d5ebf03fd407d", - "sha256:a11fdb628e78c70853646cd7d6d56e07fd56cc702e9675f9abb34832ea055ffe" + "sha256:aa376747296780a56355e3067b9c8bf43a2a1c44ff985de82b3a5d9e161ca2b8", + "sha256:dbb061c19375eca3a7d18358d2ca8bbaee825fc3000a3f114e2698282362b536" ], "index": "pypi", - "version": "==0.27.0" + "version": "==0.28.1" }, "mistune": { "hashes": [ - "sha256:6bab6c6abd711c4604206c7d8cad5cd48b28f072b4bb75797d74146ba393a049", - "sha256:6fc88c3cb49dba8b16687b41725e661cf85784c12e8974a29b9d336dd596c3a1" + "sha256:182cc5ee6f8ed1b807de6b7bb50155df7b66495412836b9a74c8fbdfc75fe36d", + "sha256:9ee0a66053e2267aba772c71e06891fa8f1af6d4b01d5e84e267b4570d4d9808" ], - "version": "==2.0.2" + "version": "==2.0.4" }, "mysql-connector-python": { "hashes": [ - "sha256:04d75ec7c181e7907df3d40c2a573063f25ecfc5a95a7a90374861c02ce738a9", - "sha256:47f059bc2a7378acd56ac7a60b0526a2ba95d96b696a875b5b233a0feae30980", - "sha256:4d126ce5e03675d926a9e49ce1638d06af43ca7bac2b502d93373dc9425d386f", - "sha256:50c87ff50762f4a0cc0816365dde0e7de763949e125488b8e872de6471e0e427", - "sha256:687071dc9e51892d0861bbcbcbd48e0f3579e3155f2a0ec310198704137c775a", - "sha256:73c5149b33401610e28589d1fc669cba11d3b16215a8f6a75f63ece1f3af5f88", - "sha256:77ec293e265d01db1896a8e63a16b3d5c848a885cf76c77148adfed8453846e8", - "sha256:78bb1abb57bbb85263d65a240a901195e3de0e0992f25e42c48af0869079bb74", - "sha256:7d518491d6d51b186b3182b3698b1560d9bd80675c055163359d0aeea0001de1", - "sha256:8d8dd02e0e6bb7262156a836c3e83582d1a1a1ebb9d72e777a46813709404601", - "sha256:91be638d1b084835edf7aa426d85228174611a1cd6f016ca0f6d4339ac3d9d7b", - "sha256:aaec9d13fc0177e421a3c4392f0eaf86347b825949d5dfc202d535cdb1e07f04", - "sha256:b3a747c5efd6de7b76686ab93834186e2276a62684600dbede615537040436ca", - "sha256:b4c5ce835078555b6640921cae036daad46884dd21027f43c742fb505221e4e6", - "sha256:bb317b179bfbb3e86c771bb2b34794188a2d2b010cdaa1b4d1b5ea0961d0812c", - "sha256:bd89598b173aa0fc525b59fff6e3598ff3cabad4260a3bb49cf420eac10d3b3b", - "sha256:bdb4f187f737316d1c403085b2fb7c91717268d052ecbfc86066cef59f6d72a4", - "sha256:c76d771fdce1314b07619efff184ec03f56abef6b4ccdc686d3a995f5b225fec", - "sha256:d559f69e8b58ac248e37d30e5676718adf69eeff56ed8a7c03f064d74af68f99", - "sha256:e008127430c8dc66bb1b6d6c7a17498ec57ffa81188fc1f8c9f764363c01d12e", - "sha256:f5da43c77d409c8135132f5b5aee9ac91c2e97c3f87352e1b3017438a9cb9b82" + "sha256:1d9d3af14594aceda2c3096564b4c87ffac21e375806a802daeaf7adcd18d36b", + "sha256:234c6b156a1989bebca6eb564dc8f2e9d352f90a51bd228ccd68eb66fcd5fd7a", + "sha256:33c4e567547a9a1868462fda8f2b19ea186a7b1afe498171dca39c0f3aa43a75", + "sha256:36e763f21e62b3c9623a264f2513ee11924ea1c9cc8640c115a279d3087064be", + "sha256:41a04d1900e366bf6c2a645ead89ab9a567806d5ada7d417a3a31f170321dd14", + "sha256:47deb8c3324db7eb2bfb720ec8084d547b1bce457672ea261bc21836024249db", + "sha256:59a8592e154c874c299763bb8aa12c518384c364bcfd0d193e85c869ea81a895", + "sha256:611c6945805216104575f7143ff6497c87396ce82d3257e6da7257b65406f13e", + "sha256:62266d1b18cb4e286a05df0e1c99163a4955c82d41045305bcf0ab2aac107843", + "sha256:712cdfa97f35fec715e8d7aaa15ed9ce04f3cf71b3c177fcca273047040de9f2", + "sha256:7f771bd5cba3ade6d9f7a649e65d7c030f69f0e69980632b5cbbd3d19c39cee5", + "sha256:8876b1d51cae33cdfe7021d68206661e94dcd2666e5e14a743f8321e2b068e84", + "sha256:8b7d50c221320b0e609dce9ca8801ab2f2a748dfee65cd76b1e4c6940757734a", + "sha256:954a1fc2e9a811662c5b17cea24819c020ff9d56b2ff8e583dd0a233fb2399f6", + "sha256:a130c5489861c7ff2990e5b503c37beb2fb7b32211b92f9107ad864ee90654c0", + "sha256:b5dc0f3295e404f93b674bfaff7589a9fbb8b5ae6c1c134112a1d1beb2f664b2", + "sha256:ce23ca9c27e1f7b4707b3299ce515125f312736d86a7e5b2aa778484fa3ffa10", + "sha256:d8f74c9388176635f75c01d47d0abc783a47e58d7f36d04fb6ee40ab6fb35c9b", + "sha256:f1d40cac9c786e292433716c1ade7a8968cbc3ea177026697b86a63188ddba34", + "sha256:f1eb74eb30bb04ff314f5e19af5421d23b504e41d16ddcee2603b4100d18fd68", + "sha256:f5d812245754d4759ebc8c075662fef65397e1e2a438a3c391eac9d545077b8b" ], "index": "pypi", - "version": "==8.0.28" + "version": "==8.0.30" + }, + "packaging": { + "hashes": [ + "sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb", + "sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522" + ], + "markers": "python_version >= '3.6'", + "version": "==21.3" + }, + "pkgutil-resolve-name": { + "hashes": [ + "sha256:357d6c9e6a755653cfd78893817c0853af365dd51ec97f3d358a819373bbd174", + "sha256:ca27cc078d25c5ad71a9de0a7a330146c4e014c2462d9af19c6b828280649c5e" + ], + "markers": "python_version < '3.9'", + "version": "==1.3.10" }, "protobuf": { "hashes": [ - "sha256:072fbc78d705d3edc7ccac58a62c4c8e0cec856987da7df8aca86e647be4e35c", - "sha256:09297b7972da685ce269ec52af761743714996b4381c085205914c41fcab59fb", - "sha256:16f519de1313f1b7139ad70772e7db515b1420d208cb16c6d7858ea989fc64a9", - "sha256:1c91ef4110fdd2c590effb5dca8fdbdcb3bf563eece99287019c4204f53d81a4", - "sha256:3112b58aac3bac9c8be2b60a9daf6b558ca3f7681c130dcdd788ade7c9ffbdca", - "sha256:36cecbabbda242915529b8ff364f2263cd4de7c46bbe361418b5ed859677ba58", - "sha256:4276cdec4447bd5015453e41bdc0c0c1234eda08420b7c9a18b8d647add51e4b", - "sha256:435bb78b37fc386f9275a7035fe4fb1364484e38980d0dd91bc834a02c5ec909", - "sha256:48ed3877fa43e22bcacc852ca76d4775741f9709dd9575881a373bd3e85e54b2", - "sha256:54a1473077f3b616779ce31f477351a45b4fef8c9fd7892d6d87e287a38df368", - "sha256:69da7d39e39942bd52848438462674c463e23963a1fdaa84d88df7fbd7e749b2", - "sha256:6cbc312be5e71869d9d5ea25147cdf652a6781cf4d906497ca7690b7b9b5df13", - "sha256:7bb03bc2873a2842e5ebb4801f5c7ff1bfbdf426f85d0172f7644fcda0671ae0", - "sha256:7ca7da9c339ca8890d66958f5462beabd611eca6c958691a8fe6eccbd1eb0c6e", - "sha256:835a9c949dc193953c319603b2961c5c8f4327957fe23d914ca80d982665e8ee", - "sha256:84123274d982b9e248a143dadd1b9815049f4477dc783bf84efe6250eb4b836a", - "sha256:8961c3a78ebfcd000920c9060a262f082f29838682b1f7201889300c1fbe0616", - "sha256:96bd766831596d6014ca88d86dc8fe0fb2e428c0b02432fd9db3943202bf8c5e", - "sha256:9df0c10adf3e83015ced42a9a7bd64e13d06c4cf45c340d2c63020ea04499d0a", - "sha256:b38057450a0c566cbd04890a40edf916db890f2818e8682221611d78dc32ae26", - "sha256:bd95d1dfb9c4f4563e6093a9aa19d9c186bf98fa54da5252531cc0d3a07977e7", - "sha256:c1068287025f8ea025103e37d62ffd63fec8e9e636246b89c341aeda8a67c934", - "sha256:c438268eebb8cf039552897d78f402d734a404f1360592fef55297285f7f953f", - "sha256:cdc076c03381f5c1d9bb1abdcc5503d9ca8b53cf0a9d31a9f6754ec9e6c8af0f", - "sha256:f358aa33e03b7a84e0d91270a4d4d8f5df6921abe99a377828839e8ed0c04e07", - "sha256:f51d5a9f137f7a2cec2d326a74b6e3fc79d635d69ffe1b036d39fc7d75430d37" + "sha256:06059eb6953ff01e56a25cd02cca1a9649a75a7e65397b5b9b4e929ed71d10cf", + "sha256:097c5d8a9808302fb0da7e20edf0b8d4703274d140fd25c5edabddcde43e081f", + "sha256:284f86a6207c897542d7e956eb243a36bb8f9564c1742b253462386e96c6b78f", + "sha256:32ca378605b41fd180dfe4e14d3226386d8d1b002ab31c969c366549e66a2bb7", + "sha256:3cc797c9d15d7689ed507b165cd05913acb992d78b379f6014e013f9ecb20996", + "sha256:62f1b5c4cd6c5402b4e2d63804ba49a327e0c386c99b1675c8a0fefda23b2067", + "sha256:69ccfdf3657ba59569c64295b7d51325f91af586f8d5793b734260dfe2e94e2c", + "sha256:6f50601512a3d23625d8a85b1638d914a0970f17920ff39cec63aaef80a93fb7", + "sha256:7403941f6d0992d40161aa8bb23e12575637008a5a02283a930addc0508982f9", + "sha256:755f3aee41354ae395e104d62119cb223339a8f3276a0cd009ffabfcdd46bb0c", + "sha256:77053d28427a29987ca9caf7b72ccafee011257561259faba8dd308fda9a8739", + "sha256:7e371f10abe57cee5021797126c93479f59fccc9693dafd6bd5633ab67808a91", + "sha256:9016d01c91e8e625141d24ec1b20fed584703e527d28512aa8c8707f105a683c", + "sha256:9be73ad47579abc26c12024239d3540e6b765182a91dbc88e23658ab71767153", + "sha256:adc31566d027f45efe3f44eeb5b1f329da43891634d61c75a5944e9be6dd42c9", + "sha256:adfc6cf69c7f8c50fd24c793964eef18f0ac321315439d94945820612849c388", + "sha256:af0ebadc74e281a517141daad9d0f2c5d93ab78e9d455113719a45a49da9db4e", + "sha256:cb29edb9eab15742d791e1025dd7b6a8f6fcb53802ad2f6e3adcb102051063ab", + "sha256:cd68be2559e2a3b84f517fb029ee611546f7812b1fdd0aa2ecc9bc6ec0e4fdde", + "sha256:cdee09140e1cd184ba9324ec1df410e7147242b94b5f8b0c64fc89e38a8ba531", + "sha256:db977c4ca738dd9ce508557d4fce0f5aebd105e158c725beec86feb1f6bc20d8", + "sha256:dd5789b2948ca702c17027c84c2accb552fc30f4622a98ab5c51fcfe8c50d3e7", + "sha256:e250a42f15bf9d5b09fe1b293bdba2801cd520a9f5ea2d7fb7536d4441811d20", + "sha256:ff8d8fa42675249bb456f5db06c00de6c2f4c27a065955917b28c4f15978b9c3" ], - "markers": "python_version >= '3.5'", - "version": "==3.19.4" + "markers": "python_version >= '3.7'", + "version": "==3.20.1" }, "pyasn1": { "hashes": [ @@ -330,6 +353,14 @@ ], "version": "==0.4.8" }, + "pyparsing": { + "hashes": [ + "sha256:2b020ecf7d21b687f219b71ecad3631f644a47f01403fa1d1036b0c6416d70fb", + "sha256:5026bae9a10eeaefb61dab2f09052b9f4307d44aee4eda64b309723d8d206bbc" + ], + "markers": "python_full_version >= '3.6.8'", + "version": "==3.0.9" + }, "pyrsistent": { "hashes": [ "sha256:0e3e1fcc45199df76053026a51cc59ab2ea3fc7c094c6627e93b7b44cdae2c8c", @@ -359,11 +390,11 @@ }, "python-dotenv": { "hashes": [ - "sha256:32b2bdc1873fd3a3c346da1c6db83d0053c3c62f28f1f38516070c4c8971b1d3", - "sha256:a5de49a31e953b45ff2d2fd434bbc2670e8db5273606c1e737cc6b93eff3655f" + "sha256:b7e3b04a59693c42c36f9ab1cc2acc46fa5df8c78e178fc33a8d4cd05c8d498f", + "sha256:d92a187be61fe482e4fd675b6d52200e7be63a12b724abbf931a40ce4fa92938" ], "index": "pypi", - "version": "==0.19.2" + "version": "==0.20.0" }, "python-jose": { "hashes": [ @@ -409,15 +440,24 @@ "sha256:e61ceaab6f49fb8bdfaa0f92c4b57bcfbea54c09277b1b4f7ac376bfb7a7c174", "sha256:f84fbc98b019fef2ee9a1cb3ce93e3187a6df0b2538a651bfb890254ba9f90b5" ], + "markers": "python_version >= '3.6'", "version": "==6.0" }, "rsa": { "hashes": [ - "sha256:5c6bd9dc7a543b7fe4304a631f8a8a3b674e2bbfc49c2ae96200cdbe55df6b17", - "sha256:95c5d300c4e879ee69708c428ba566c59478fd653cc3a22243eeb8ed846950bb" + "sha256:90260d9058e514786967344d0ef75fa8727eed8a7d2e43ce9f4bcf1b536174f7", + "sha256:e38464a49c6c85d7f1351b0126661487a7e0a14a50f1675ec50eb34d4f20ef21" ], "markers": "python_version >= '3.6' and python_version < '4'", - "version": "==4.8" + "version": "==4.9" + }, + "setuptools": { + "hashes": [ + "sha256:101bf15ca723beef42c8db91a761f3748d4d697e17fae904db60c0b619d8d094", + "sha256:39275e7aafa4a4f0f4308f2302c6ee384dcdacdbaacc1e30dcbb6fd824c625bb" + ], + "markers": "python_version >= '3.7'", + "version": "==65.0.2" }, "six": { "hashes": [ @@ -467,6 +507,14 @@ "index": "pypi", "version": "==1.3.24" }, + "typing-extensions": { + "hashes": [ + "sha256:25642c956049920a5aa49edcdd6ab1e06d7e5d467fc00e0506c44ac86fbfca02", + "sha256:e6d2677a32f47fc7eb2795db1dd15c1f34eff616bcaf2cfb5e997f854fa1c4a6" + ], + "markers": "python_version >= '3.7'", + "version": "==4.3.0" + }, "werkzeug": { "hashes": [ "sha256:2de2a5db0baeae7b2d2664949077c2ac63fbd16d98da0ff71837f7d1dea3fd43", @@ -475,23 +523,93 @@ "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", "version": "==1.0.1" }, + "wrapt": { + "hashes": [ + "sha256:00b6d4ea20a906c0ca56d84f93065b398ab74b927a7a3dbd470f6fc503f95dc3", + "sha256:01c205616a89d09827986bc4e859bcabd64f5a0662a7fe95e0d359424e0e071b", + "sha256:02b41b633c6261feff8ddd8d11c711df6842aba629fdd3da10249a53211a72c4", + "sha256:07f7a7d0f388028b2df1d916e94bbb40624c59b48ecc6cbc232546706fac74c2", + "sha256:11871514607b15cfeb87c547a49bca19fde402f32e2b1c24a632506c0a756656", + "sha256:1b376b3f4896e7930f1f772ac4b064ac12598d1c38d04907e696cc4d794b43d3", + "sha256:21ac0156c4b089b330b7666db40feee30a5d52634cc4560e1905d6529a3897ff", + "sha256:257fd78c513e0fb5cdbe058c27a0624c9884e735bbd131935fd49e9fe719d310", + "sha256:2b39d38039a1fdad98c87279b48bc5dce2c0ca0d73483b12cb72aa9609278e8a", + "sha256:2cf71233a0ed05ccdabe209c606fe0bac7379fdcf687f39b944420d2a09fdb57", + "sha256:2fe803deacd09a233e4762a1adcea5db5d31e6be577a43352936179d14d90069", + "sha256:3232822c7d98d23895ccc443bbdf57c7412c5a65996c30442ebe6ed3df335383", + "sha256:34aa51c45f28ba7f12accd624225e2b1e5a3a45206aa191f6f9aac931d9d56fe", + "sha256:36f582d0c6bc99d5f39cd3ac2a9062e57f3cf606ade29a0a0d6b323462f4dd87", + "sha256:380a85cf89e0e69b7cfbe2ea9f765f004ff419f34194018a6827ac0e3edfed4d", + "sha256:40e7bc81c9e2b2734ea4bc1aceb8a8f0ceaac7c5299bc5d69e37c44d9081d43b", + "sha256:43ca3bbbe97af00f49efb06e352eae40434ca9d915906f77def219b88e85d907", + "sha256:4fcc4649dc762cddacd193e6b55bc02edca674067f5f98166d7713b193932b7f", + "sha256:5a0f54ce2c092aaf439813735584b9537cad479575a09892b8352fea5e988dc0", + "sha256:5a9a0d155deafd9448baff28c08e150d9b24ff010e899311ddd63c45c2445e28", + "sha256:5b02d65b9ccf0ef6c34cba6cf5bf2aab1bb2f49c6090bafeecc9cd81ad4ea1c1", + "sha256:60db23fa423575eeb65ea430cee741acb7c26a1365d103f7b0f6ec412b893853", + "sha256:642c2e7a804fcf18c222e1060df25fc210b9c58db7c91416fb055897fc27e8cc", + "sha256:6a9a25751acb379b466ff6be78a315e2b439d4c94c1e99cb7266d40a537995d3", + "sha256:6b1a564e6cb69922c7fe3a678b9f9a3c54e72b469875aa8018f18b4d1dd1adf3", + "sha256:6d323e1554b3d22cfc03cd3243b5bb815a51f5249fdcbb86fda4bf62bab9e164", + "sha256:6e743de5e9c3d1b7185870f480587b75b1cb604832e380d64f9504a0535912d1", + "sha256:709fe01086a55cf79d20f741f39325018f4df051ef39fe921b1ebe780a66184c", + "sha256:7b7c050ae976e286906dd3f26009e117eb000fb2cf3533398c5ad9ccc86867b1", + "sha256:7d2872609603cb35ca513d7404a94d6d608fc13211563571117046c9d2bcc3d7", + "sha256:7ef58fb89674095bfc57c4069e95d7a31cfdc0939e2a579882ac7d55aadfd2a1", + "sha256:80bb5c256f1415f747011dc3604b59bc1f91c6e7150bd7db03b19170ee06b320", + "sha256:81b19725065dcb43df02b37e03278c011a09e49757287dca60c5aecdd5a0b8ed", + "sha256:833b58d5d0b7e5b9832869f039203389ac7cbf01765639c7309fd50ef619e0b1", + "sha256:88bd7b6bd70a5b6803c1abf6bca012f7ed963e58c68d76ee20b9d751c74a3248", + "sha256:8ad85f7f4e20964db4daadcab70b47ab05c7c1cf2a7c1e51087bfaa83831854c", + "sha256:8c0ce1e99116d5ab21355d8ebe53d9460366704ea38ae4d9f6933188f327b456", + "sha256:8d649d616e5c6a678b26d15ece345354f7c2286acd6db868e65fcc5ff7c24a77", + "sha256:903500616422a40a98a5a3c4ff4ed9d0066f3b4c951fa286018ecdf0750194ef", + "sha256:9736af4641846491aedb3c3f56b9bc5568d92b0692303b5a305301a95dfd38b1", + "sha256:988635d122aaf2bdcef9e795435662bcd65b02f4f4c1ae37fbee7401c440b3a7", + "sha256:9cca3c2cdadb362116235fdbd411735de4328c61425b0aa9f872fd76d02c4e86", + "sha256:9e0fd32e0148dd5dea6af5fee42beb949098564cc23211a88d799e434255a1f4", + "sha256:9f3e6f9e05148ff90002b884fbc2a86bd303ae847e472f44ecc06c2cd2fcdb2d", + "sha256:a85d2b46be66a71bedde836d9e41859879cc54a2a04fad1191eb50c2066f6e9d", + "sha256:a9a52172be0b5aae932bef82a79ec0a0ce87288c7d132946d645eba03f0ad8a8", + "sha256:aa31fdcc33fef9eb2552cbcbfee7773d5a6792c137b359e82879c101e98584c5", + "sha256:b014c23646a467558be7da3d6b9fa409b2c567d2110599b7cf9a0c5992b3b471", + "sha256:b21bb4c09ffabfa0e85e3a6b623e19b80e7acd709b9f91452b8297ace2a8ab00", + "sha256:b5901a312f4d14c59918c221323068fad0540e34324925c8475263841dbdfe68", + "sha256:b9b7a708dd92306328117d8c4b62e2194d00c365f18eff11a9b53c6f923b01e3", + "sha256:d1967f46ea8f2db647c786e78d8cc7e4313dbd1b0aca360592d8027b8508e24d", + "sha256:d52a25136894c63de15a35bc0bdc5adb4b0e173b9c0d07a2be9d3ca64a332735", + "sha256:d77c85fedff92cf788face9bfa3ebaa364448ebb1d765302e9af11bf449ca36d", + "sha256:d79d7d5dc8a32b7093e81e97dad755127ff77bcc899e845f41bf71747af0c569", + "sha256:dbcda74c67263139358f4d188ae5faae95c30929281bc6866d00573783c422b7", + "sha256:ddaea91abf8b0d13443f6dac52e89051a5063c7d014710dcb4d4abb2ff811a59", + "sha256:dee0ce50c6a2dd9056c20db781e9c1cfd33e77d2d569f5d1d9321c641bb903d5", + "sha256:dee60e1de1898bde3b238f18340eec6148986da0455d8ba7848d50470a7a32fb", + "sha256:e2f83e18fe2f4c9e7db597e988f72712c0c3676d337d8b101f6758107c42425b", + "sha256:e3fb1677c720409d5f671e39bac6c9e0e422584e5f518bfd50aa4cbbea02433f", + "sha256:ee2b1b1769f6707a8a445162ea16dddf74285c3964f605877a20e38545c3c462", + "sha256:ee6acae74a2b91865910eef5e7de37dc6895ad96fa23603d1d27ea69df545015", + "sha256:ef3f72c9666bba2bab70d2a8b79f2c6d2c1a42a7f7e2b0ec83bb2f9e383950af" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", + "version": "==1.14.1" + }, "zipp": { "hashes": [ - "sha256:9f50f446828eb9d45b267433fd3e9da8d801f614129124863f9c51ebceafb87d", - "sha256:b47250dd24f92b7dd6a0a8fc5244da14608f3ca90a5efcd37a3b1642fac9a375" + "sha256:05b45f1ee8f807d0cc928485ca40a07cb491cf092ff587c0df9cb1fd154848d2", + "sha256:47c40d7fe183a6f21403a199b3e4192cca5774656965b0a4988ad2f8feb5f009" ], "markers": "python_version < '3.10'", - "version": "==3.7.0" + "version": "==3.8.1" } }, "develop": { "alembic": { "hashes": [ - "sha256:6c0c05e9768a896d804387e20b299880fe01bc56484246b0dffe8075d6d3d847", - "sha256:ad842f2c3ab5c5d4861232730779c05e33db4ba880a08b85eb505e87c01095bc" + "sha256:0a024d7f2de88d738d7395ff866997314c837be6104e90c5724350313dee4da4", + "sha256:cd0b5e45b14b706426b833f06369b9a6d5ee03f826ec3238723ce8caaf6e5ffa" ], - "markers": "python_version >= '3.6'", - "version": "==1.7.6" + "markers": "python_version >= '3.7'", + "version": "==1.8.1" }, "click": { "hashes": [ @@ -588,19 +706,19 @@ }, "importlib-metadata": { "hashes": [ - "sha256:6affcdb3aec542dd98df8211e730bba6c5f2bec8288d47bacacde898f548c9ad", - "sha256:9e5e553bbba1843cb4a00823014b907616be46ee503d2b9ba001d214a8da218f" + "sha256:637245b8bab2b6502fcbc752cc4b7a6f6243bb02b31c5c26156ad103d3d45670", + "sha256:7401a975809ea1fdc658c3aa4f78cc2195a0e019c5cbc4c06122884e9ae80c23" ], "markers": "python_version < '3.9'", - "version": "==4.11.0" + "version": "==4.12.0" }, "importlib-resources": { "hashes": [ - "sha256:33a95faed5fc19b4bc16b29a6eeae248a3fe69dd55d4d229d2b480e23eeaad45", - "sha256:d756e2f85dd4de2ba89be0b21dba2a3bbec2e871a42a3a16719258a11f87506b" + "sha256:5481e97fb45af8dcf2f798952625591c58fe599d0735d86b10f54de086a61681", + "sha256:f78a8df21a79bcc30cfd400bdc38f314333de7c0fb619763f6b9dabab8268bb7" ], "markers": "python_version < '3.9'", - "version": "==5.4.0" + "version": "==5.9.0" }, "itsdangerous": { "hashes": [ @@ -620,86 +738,57 @@ }, "mako": { "hashes": [ - "sha256:4e9e345a41924a954251b95b4b28e14a301145b544901332e658907a7464b6b2", - "sha256:afaf8e515d075b22fad7d7b8b30e4a1c90624ff2f3733a06ec125f5a5f043a57" + "sha256:df3921c3081b013c8a2d5ff03c18375651684921ae83fd12e64800b7da923257", + "sha256:f054a5ff4743492f1aa9ecc47172cb33b42b9d993cffcc146c9de17e717b0307" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==1.1.6" + "markers": "python_version >= '3.7'", + "version": "==1.2.1" }, "markupsafe": { "hashes": [ - "sha256:01a9b8ea66f1658938f65b93a85ebe8bc016e6769611be228d797c9d998dd298", - "sha256:023cb26ec21ece8dc3907c0e8320058b2e0cb3c55cf9564da612bc325bed5e64", - "sha256:0446679737af14f45767963a1a9ef7620189912317d095f2d9ffa183a4d25d2b", - "sha256:04635854b943835a6ea959e948d19dcd311762c5c0c6e1f0e16ee57022669194", - "sha256:0717a7390a68be14b8c793ba258e075c6f4ca819f15edfc2a3a027c823718567", - "sha256:0955295dd5eec6cb6cc2fe1698f4c6d84af2e92de33fbcac4111913cd100a6ff", - "sha256:0d4b31cc67ab36e3392bbf3862cfbadac3db12bdd8b02a2731f509ed5b829724", - "sha256:10f82115e21dc0dfec9ab5c0223652f7197feb168c940f3ef61563fc2d6beb74", - "sha256:168cd0a3642de83558a5153c8bd34f175a9a6e7f6dc6384b9655d2697312a646", - "sha256:1d609f577dc6e1aa17d746f8bd3c31aa4d258f4070d61b2aa5c4166c1539de35", - "sha256:1f2ade76b9903f39aa442b4aadd2177decb66525062db244b35d71d0ee8599b6", - "sha256:20dca64a3ef2d6e4d5d615a3fd418ad3bde77a47ec8a23d984a12b5b4c74491a", - "sha256:2a7d351cbd8cfeb19ca00de495e224dea7e7d919659c2841bbb7f420ad03e2d6", - "sha256:2d7d807855b419fc2ed3e631034685db6079889a1f01d5d9dac950f764da3dad", - "sha256:2ef54abee730b502252bcdf31b10dacb0a416229b72c18b19e24a4509f273d26", - "sha256:36bc903cbb393720fad60fc28c10de6acf10dc6cc883f3e24ee4012371399a38", - "sha256:37205cac2a79194e3750b0af2a5720d95f786a55ce7df90c3af697bfa100eaac", - "sha256:3c112550557578c26af18a1ccc9e090bfe03832ae994343cfdacd287db6a6ae7", - "sha256:3dd007d54ee88b46be476e293f48c85048603f5f516008bee124ddd891398ed6", - "sha256:4296f2b1ce8c86a6aea78613c34bb1a672ea0e3de9c6ba08a960efe0b0a09047", - "sha256:47ab1e7b91c098ab893b828deafa1203de86d0bc6ab587b160f78fe6c4011f75", - "sha256:49e3ceeabbfb9d66c3aef5af3a60cc43b85c33df25ce03d0031a608b0a8b2e3f", - "sha256:4dc8f9fb58f7364b63fd9f85013b780ef83c11857ae79f2feda41e270468dd9b", - "sha256:4efca8f86c54b22348a5467704e3fec767b2db12fc39c6d963168ab1d3fc9135", - "sha256:53edb4da6925ad13c07b6d26c2a852bd81e364f95301c66e930ab2aef5b5ddd8", - "sha256:5855f8438a7d1d458206a2466bf82b0f104a3724bf96a1c781ab731e4201731a", - "sha256:594c67807fb16238b30c44bdf74f36c02cdf22d1c8cda91ef8a0ed8dabf5620a", - "sha256:5b6d930f030f8ed98e3e6c98ffa0652bdb82601e7a016ec2ab5d7ff23baa78d1", - "sha256:5bb28c636d87e840583ee3adeb78172efc47c8b26127267f54a9c0ec251d41a9", - "sha256:60bf42e36abfaf9aff1f50f52644b336d4f0a3fd6d8a60ca0d054ac9f713a864", - "sha256:611d1ad9a4288cf3e3c16014564df047fe08410e628f89805e475368bd304914", - "sha256:6300b8454aa6930a24b9618fbb54b5a68135092bc666f7b06901f897fa5c2fee", - "sha256:63f3268ba69ace99cab4e3e3b5840b03340efed0948ab8f78d2fd87ee5442a4f", - "sha256:6557b31b5e2c9ddf0de32a691f2312a32f77cd7681d8af66c2692efdbef84c18", - "sha256:693ce3f9e70a6cf7d2fb9e6c9d8b204b6b39897a2c4a1aa65728d5ac97dcc1d8", - "sha256:6a7fae0dd14cf60ad5ff42baa2e95727c3d81ded453457771d02b7d2b3f9c0c2", - "sha256:6c4ca60fa24e85fe25b912b01e62cb969d69a23a5d5867682dd3e80b5b02581d", - "sha256:6fcf051089389abe060c9cd7caa212c707e58153afa2c649f00346ce6d260f1b", - "sha256:7d91275b0245b1da4d4cfa07e0faedd5b0812efc15b702576d103293e252af1b", - "sha256:89c687013cb1cd489a0f0ac24febe8c7a666e6e221b783e53ac50ebf68e45d86", - "sha256:8d206346619592c6200148b01a2142798c989edcb9c896f9ac9722a99d4e77e6", - "sha256:905fec760bd2fa1388bb5b489ee8ee5f7291d692638ea5f67982d968366bef9f", - "sha256:97383d78eb34da7e1fa37dd273c20ad4320929af65d156e35a5e2d89566d9dfb", - "sha256:984d76483eb32f1bcb536dc27e4ad56bba4baa70be32fa87152832cdd9db0833", - "sha256:99df47edb6bda1249d3e80fdabb1dab8c08ef3975f69aed437cb69d0a5de1e28", - "sha256:9f02365d4e99430a12647f09b6cc8bab61a6564363f313126f775eb4f6ef798e", - "sha256:a30e67a65b53ea0a5e62fe23682cfe22712e01f453b95233b25502f7c61cb415", - "sha256:ab3ef638ace319fa26553db0624c4699e31a28bb2a835c5faca8f8acf6a5a902", - "sha256:aca6377c0cb8a8253e493c6b451565ac77e98c2951c45f913e0b52facdcff83f", - "sha256:add36cb2dbb8b736611303cd3bfcee00afd96471b09cda130da3581cbdc56a6d", - "sha256:b2f4bf27480f5e5e8ce285a8c8fd176c0b03e93dcc6646477d4630e83440c6a9", - "sha256:b7f2d075102dc8c794cbde1947378051c4e5180d52d276987b8d28a3bd58c17d", - "sha256:baa1a4e8f868845af802979fcdbf0bb11f94f1cb7ced4c4b8a351bb60d108145", - "sha256:be98f628055368795d818ebf93da628541e10b75b41c559fdf36d104c5787066", - "sha256:bf5d821ffabf0ef3533c39c518f3357b171a1651c1ff6827325e4489b0e46c3c", - "sha256:c47adbc92fc1bb2b3274c4b3a43ae0e4573d9fbff4f54cd484555edbf030baf1", - "sha256:cdfba22ea2f0029c9261a4bd07e830a8da012291fbe44dc794e488b6c9bb353a", - "sha256:d6c7ebd4e944c85e2c3421e612a7057a2f48d478d79e61800d81468a8d842207", - "sha256:d7f9850398e85aba693bb640262d3611788b1f29a79f0c93c565694658f4071f", - "sha256:d8446c54dc28c01e5a2dbac5a25f071f6653e6e40f3a8818e8b45d790fe6ef53", - "sha256:deb993cacb280823246a026e3b2d81c493c53de6acfd5e6bfe31ab3402bb37dd", - "sha256:e0f138900af21926a02425cf736db95be9f4af72ba1bb21453432a07f6082134", - "sha256:e9936f0b261d4df76ad22f8fee3ae83b60d7c3e871292cd42f40b81b70afae85", - "sha256:f0567c4dc99f264f49fe27da5f735f414c4e7e7dd850cfd8e69f0862d7c74ea9", - "sha256:f5653a225f31e113b152e56f154ccbe59eeb1c7487b39b9d9f9cdb58e6c79dc5", - "sha256:f826e31d18b516f653fe296d967d700fddad5901ae07c622bb3705955e1faa94", - "sha256:f8ba0e8349a38d3001fae7eadded3f6606f0da5d748ee53cc1dab1d6527b9509", - "sha256:f9081981fe268bd86831e5c75f7de206ef275defcb82bc70740ae6dc507aee51", - "sha256:fa130dd50c57d53368c9d59395cb5526eda596d3ffe36666cd81a44d56e48872" + "sha256:0212a68688482dc52b2d45013df70d169f542b7394fc744c02a57374a4207003", + "sha256:089cf3dbf0cd6c100f02945abeb18484bd1ee57a079aefd52cffd17fba910b88", + "sha256:10c1bfff05d95783da83491be968e8fe789263689c02724e0c691933c52994f5", + "sha256:33b74d289bd2f5e527beadcaa3f401e0df0a89927c1559c8566c066fa4248ab7", + "sha256:3799351e2336dc91ea70b034983ee71cf2f9533cdff7c14c90ea126bfd95d65a", + "sha256:3ce11ee3f23f79dbd06fb3d63e2f6af7b12db1d46932fe7bd8afa259a5996603", + "sha256:421be9fbf0ffe9ffd7a378aafebbf6f4602d564d34be190fc19a193232fd12b1", + "sha256:43093fb83d8343aac0b1baa75516da6092f58f41200907ef92448ecab8825135", + "sha256:46d00d6cfecdde84d40e572d63735ef81423ad31184100411e6e3388d405e247", + "sha256:4a33dea2b688b3190ee12bd7cfa29d39c9ed176bda40bfa11099a3ce5d3a7ac6", + "sha256:4b9fe39a2ccc108a4accc2676e77da025ce383c108593d65cc909add5c3bd601", + "sha256:56442863ed2b06d19c37f94d999035e15ee982988920e12a5b4ba29b62ad1f77", + "sha256:671cd1187ed5e62818414afe79ed29da836dde67166a9fac6d435873c44fdd02", + "sha256:694deca8d702d5db21ec83983ce0bb4b26a578e71fbdbd4fdcd387daa90e4d5e", + "sha256:6a074d34ee7a5ce3effbc526b7083ec9731bb3cbf921bbe1d3005d4d2bdb3a63", + "sha256:6d0072fea50feec76a4c418096652f2c3238eaa014b2f94aeb1d56a66b41403f", + "sha256:6fbf47b5d3728c6aea2abb0589b5d30459e369baa772e0f37a0320185e87c980", + "sha256:7f91197cc9e48f989d12e4e6fbc46495c446636dfc81b9ccf50bb0ec74b91d4b", + "sha256:86b1f75c4e7c2ac2ccdaec2b9022845dbb81880ca318bb7a0a01fbf7813e3812", + "sha256:8dc1c72a69aa7e082593c4a203dcf94ddb74bb5c8a731e4e1eb68d031e8498ff", + "sha256:8e3dcf21f367459434c18e71b2a9532d96547aef8a871872a5bd69a715c15f96", + "sha256:8e576a51ad59e4bfaac456023a78f6b5e6e7651dcd383bcc3e18d06f9b55d6d1", + "sha256:96e37a3dc86e80bf81758c152fe66dbf60ed5eca3d26305edf01892257049925", + "sha256:97a68e6ada378df82bc9f16b800ab77cbf4b2fada0081794318520138c088e4a", + "sha256:99a2a507ed3ac881b975a2976d59f38c19386d128e7a9a18b7df6fff1fd4c1d6", + "sha256:a49907dd8420c5685cfa064a1335b6754b74541bbb3706c259c02ed65b644b3e", + "sha256:b09bf97215625a311f669476f44b8b318b075847b49316d3e28c08e41a7a573f", + "sha256:b7bd98b796e2b6553da7225aeb61f447f80a1ca64f41d83612e6139ca5213aa4", + "sha256:b87db4360013327109564f0e591bd2a3b318547bcef31b468a92ee504d07ae4f", + "sha256:bcb3ed405ed3222f9904899563d6fc492ff75cce56cba05e32eff40e6acbeaa3", + "sha256:d4306c36ca495956b6d568d276ac11fdd9c30a36f1b6eb928070dc5360b22e1c", + "sha256:d5ee4f386140395a2c818d149221149c54849dfcfcb9f1debfe07a8b8bd63f9a", + "sha256:dda30ba7e87fbbb7eab1ec9f58678558fd9a6b8b853530e176eabd064da81417", + "sha256:e04e26803c9c3851c931eac40c695602c6295b8d432cbe78609649ad9bd2da8a", + "sha256:e1c0b87e09fa55a220f058d1d49d3fb8df88fbfab58558f1198e08c1e1de842a", + "sha256:e72591e9ecd94d7feb70c1cbd7be7b3ebea3f548870aa91e2732960fa4d57a37", + "sha256:e8c843bbcda3a2f1e3c2ab25913c80a3c5376cd00c6e8c4a86a89a28c8dc5452", + "sha256:efc1913fd2ca4f334418481c7e595c00aad186563bbc1ec76067848c7ca0a933", + "sha256:f121a1420d4e173a5d96e47e9a0c0dcff965afdf1626d28de1460815f7c4ee7a", + "sha256:fc7b548b17d238737688817ab67deebb30e8073c95749d55538ed473130ec0c7" ], - "markers": "python_version >= '3.6'", - "version": "==2.0.1" + "markers": "python_version >= '3.7'", + "version": "==2.1.1" }, "sqlalchemy": { "hashes": [ @@ -751,11 +840,11 @@ }, "zipp": { "hashes": [ - "sha256:9f50f446828eb9d45b267433fd3e9da8d801f614129124863f9c51ebceafb87d", - "sha256:b47250dd24f92b7dd6a0a8fc5244da14608f3ca90a5efcd37a3b1642fac9a375" + "sha256:05b45f1ee8f807d0cc928485ca40a07cb491cf092ff587c0df9cb1fd154848d2", + "sha256:47c40d7fe183a6f21403a199b3e4192cca5774656965b0a4988ad2f8feb5f009" ], "markers": "python_version < '3.10'", - "version": "==3.7.0" + "version": "==3.8.1" } } } From 911468c35f33d85b9242f720ea83b4c3424451ce Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Wed, 17 Aug 2022 18:05:24 -0400 Subject: [PATCH 142/206] update flask markupsafe changed something https://flask.palletsprojects.com/en/2.0.x/changes/#version-2-0-0 https://stackoverflow.com/questions/72191560/importerror-cannot-import-name-soft-unicode-from-markupsafe --- Pipfile | 2 +- Pipfile.lock | 79 ++++++++++++++++++++++++++-------------------------- 2 files changed, 40 insertions(+), 41 deletions(-) diff --git a/Pipfile b/Pipfile index 11ed576..e0fe5ee 100644 --- a/Pipfile +++ b/Pipfile @@ -10,7 +10,7 @@ flask-migrate = "*" six = "~=1.12.0" flasgger = "~=0.9.3" flask-marshmallow = "~=0.10.1" -Flask = "~=1.1.1" +Flask = "~=2.0.0" Flask-Cors = "~=3.0.8" Flask-Limiter = "~=1.0.1" gunicorn = "~=19.9.0" diff --git a/Pipfile.lock b/Pipfile.lock index be4e2f9..9a08746 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "8e88cb8643cc35106d3a225420f4e8cfbd39419986dbb60b23360aed145f5966" + "sha256": "4c924b89949c4f75bea18115587ff2b87a5cc696a6d19f06e656e649debac778" }, "pipfile-spec": 6, "requires": { @@ -25,7 +25,6 @@ "version": "==1.8.1" }, "apispec": { - "extras": [], "hashes": [ "sha256:a1df9ec6b2cd0edf45039ef025abd7f0660808fa2edf737d3ba1cf5ef1a4625b", "sha256:d23ebd5b71e541e031b02a19db10b5e6d5ef8452c552833e3e1afc836b40b1ad" @@ -51,11 +50,11 @@ }, "click": { "hashes": [ - "sha256:d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a", - "sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc" + "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e", + "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==7.1.2" + "markers": "python_version >= '3.7'", + "version": "==8.1.3" }, "deprecated": { "hashes": [ @@ -83,11 +82,11 @@ }, "flask": { "hashes": [ - "sha256:0fbeb6180d383a9186d0d6ed954e0042ad9f18e0e8de088b2b419d526927d196", - "sha256:c34f04500f2cbbea882b1acb02002ad6fe6b7ffa64a6164577995657f50aed22" + "sha256:59da8a3170004800a2837844bfa84d49b022550616070f7cb1a659682b2e7c9f", + "sha256:e1120c228ca2f553b470df4a5fa927ab66258467526069981b3eb0a91902687d" ], "index": "pypi", - "version": "==1.1.4" + "version": "==2.0.3" }, "flask-cors": { "hashes": [ @@ -155,19 +154,19 @@ }, "itsdangerous": { "hashes": [ - "sha256:321b033d07f2a4136d3ec762eac9f16a10ccd60f53c0c91af90217ace7ba1f19", - "sha256:b12271b2047cb23eeb98c8b5622e2e5c5e9abd9784a153e9d8ef9cb4dd09d749" + "sha256:2c2349112351b88699d8d4b6b075022c0808887cb7ad10069318a8b0bc88db44", + "sha256:5dbbc68b317e5e42f327f9021763545dc3fc3bfe22e6deb96aaf1fc38874156a" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==1.1.0" + "markers": "python_version >= '3.7'", + "version": "==2.1.2" }, "jinja2": { "hashes": [ - "sha256:03e47ad063331dd6a3f04a43eddca8a966a26ba0c5b7207a9a9e4e08f1b29419", - "sha256:a6d58433de0ae800347cab1fa3043cebbabe8baa9d29e668f1c768cb87a333c6" + "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852", + "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==2.11.3" + "markers": "python_version >= '3.7'", + "version": "==3.1.2" }, "jsonschema": { "hashes": [ @@ -517,11 +516,11 @@ }, "werkzeug": { "hashes": [ - "sha256:2de2a5db0baeae7b2d2664949077c2ac63fbd16d98da0ff71837f7d1dea3fd43", - "sha256:6c80b1e5ad3665290ea39320b91e1be1e0d5f60652b964a3070216de83d2e47c" + "sha256:7ea2d48322cc7c0f8b3a215ed73eabd7b5d75d0b50e31ab006286ccff9e00b8f", + "sha256:f979ab81f58d7318e064e99c4506445d60135ac5cd2e177a2de0089bfd4c9bd5" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==1.0.1" + "markers": "python_version >= '3.7'", + "version": "==2.2.2" }, "wrapt": { "hashes": [ @@ -613,19 +612,19 @@ }, "click": { "hashes": [ - "sha256:d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a", - "sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc" + "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e", + "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==7.1.2" + "markers": "python_version >= '3.7'", + "version": "==8.1.3" }, "flask": { "hashes": [ - "sha256:0fbeb6180d383a9186d0d6ed954e0042ad9f18e0e8de088b2b419d526927d196", - "sha256:c34f04500f2cbbea882b1acb02002ad6fe6b7ffa64a6164577995657f50aed22" + "sha256:59da8a3170004800a2837844bfa84d49b022550616070f7cb1a659682b2e7c9f", + "sha256:e1120c228ca2f553b470df4a5fa927ab66258467526069981b3eb0a91902687d" ], "index": "pypi", - "version": "==1.1.4" + "version": "==2.0.3" }, "flask-migrate": { "hashes": [ @@ -722,19 +721,19 @@ }, "itsdangerous": { "hashes": [ - "sha256:321b033d07f2a4136d3ec762eac9f16a10ccd60f53c0c91af90217ace7ba1f19", - "sha256:b12271b2047cb23eeb98c8b5622e2e5c5e9abd9784a153e9d8ef9cb4dd09d749" + "sha256:2c2349112351b88699d8d4b6b075022c0808887cb7ad10069318a8b0bc88db44", + "sha256:5dbbc68b317e5e42f327f9021763545dc3fc3bfe22e6deb96aaf1fc38874156a" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==1.1.0" + "markers": "python_version >= '3.7'", + "version": "==2.1.2" }, "jinja2": { "hashes": [ - "sha256:03e47ad063331dd6a3f04a43eddca8a966a26ba0c5b7207a9a9e4e08f1b29419", - "sha256:a6d58433de0ae800347cab1fa3043cebbabe8baa9d29e668f1c768cb87a333c6" + "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852", + "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==2.11.3" + "markers": "python_version >= '3.7'", + "version": "==3.1.2" }, "mako": { "hashes": [ @@ -832,11 +831,11 @@ }, "werkzeug": { "hashes": [ - "sha256:2de2a5db0baeae7b2d2664949077c2ac63fbd16d98da0ff71837f7d1dea3fd43", - "sha256:6c80b1e5ad3665290ea39320b91e1be1e0d5f60652b964a3070216de83d2e47c" + "sha256:7ea2d48322cc7c0f8b3a215ed73eabd7b5d75d0b50e31ab006286ccff9e00b8f", + "sha256:f979ab81f58d7318e064e99c4506445d60135ac5cd2e177a2de0089bfd4c9bd5" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==1.0.1" + "markers": "python_version >= '3.7'", + "version": "==2.2.2" }, "zipp": { "hashes": [ From 9e185f36ec8818c4cdc37aca3edcf50a55b67c6d Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Wed, 17 Aug 2022 18:12:58 -0400 Subject: [PATCH 143/206] update flask-sqlalchemy fixes: https://stackoverflow.com/questions/72256625/why-am-i-getting-this-error-attributeerror-localstack-object-has-no-attribu --- Pipfile | 2 +- Pipfile.lock | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Pipfile b/Pipfile index e0fe5ee..a4a9df3 100644 --- a/Pipfile +++ b/Pipfile @@ -15,7 +15,7 @@ Flask-Cors = "~=3.0.8" Flask-Limiter = "~=1.0.1" gunicorn = "~=19.9.0" sqlalchemy = "~=1.3.13" -flask-sqlalchemy = "~=2.4.1" +flask-sqlalchemy = "~=2.5.0" marshmallow-sqlalchemy = "~=0.23" apispec = "~=3.3.0" apispec-webframeworks = "~=0.5.2" diff --git a/Pipfile.lock b/Pipfile.lock index 9a08746..2de5a18 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "4c924b89949c4f75bea18115587ff2b87a5cc696a6d19f06e656e649debac778" + "sha256": "cf2cbbd0ff54b2cf99c20120134addbd1ee2fced7d335f222a227a69a9fd0d92" }, "pipfile-spec": 6, "requires": { @@ -122,11 +122,11 @@ }, "flask-sqlalchemy": { "hashes": [ - "sha256:05b31d2034dd3f2a685cbbae4cfc4ed906b2a733cff7964ada450fd5e462b84e", - "sha256:bfc7150eaf809b1c283879302f04c42791136060c6eeb12c0c6674fb1291fae5" + "sha256:2bda44b43e7cacb15d4e05ff3cc1f8bc97936cc464623424102bfc2c35e95912", + "sha256:f12c3d4cc5cc7fdcc148b9527ea05671718c3ea45d50c7e732cceb33f574b390" ], "index": "pypi", - "version": "==2.4.4" + "version": "==2.5.1" }, "gunicorn": { "hashes": [ @@ -636,11 +636,11 @@ }, "flask-sqlalchemy": { "hashes": [ - "sha256:05b31d2034dd3f2a685cbbae4cfc4ed906b2a733cff7964ada450fd5e462b84e", - "sha256:bfc7150eaf809b1c283879302f04c42791136060c6eeb12c0c6674fb1291fae5" + "sha256:2bda44b43e7cacb15d4e05ff3cc1f8bc97936cc464623424102bfc2c35e95912", + "sha256:f12c3d4cc5cc7fdcc148b9527ea05671718c3ea45d50c7e732cceb33f574b390" ], "index": "pypi", - "version": "==2.4.4" + "version": "==2.5.1" }, "greenlet": { "hashes": [ From a2fa39e50be67b117ab11f2bd04b8ee636f80f1b Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Wed, 17 Aug 2022 18:44:39 -0400 Subject: [PATCH 144/206] specify charset and collation so mysql-connector-python doesn't get confused https://forums.mysql.com/read.php?50,677424,677981#msg-677981 --- auth.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/auth.py b/auth.py index 4be31af..e515c56 100644 --- a/auth.py +++ b/auth.py @@ -12,7 +12,7 @@ db_connection_string=os.getenv("DB_CONNECTION_URL", - 'mysql+mysqlconnector://{user}:{pw}@{url}/{db}'.format( + 'mysql+mysqlconnector://{user}:{pw}@{url}/{db}?charset=utf8mb4&collation=utf8mb4_general_ci'.format( user=db_username, pw=db_password, url=db_host, From 7d59c3c580a8fd7027dcddd78aafad2b5a8acce7 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Wed, 17 Aug 2022 19:07:03 -0400 Subject: [PATCH 145/206] Revert "add migration for deleting the school_id column" This reverts commit fa35cfe710ab55596c1a5742a5ff4015d9c5dc20 because it's changes were already included in the initial migration --- ...fb763_remove_school_id_on_meeting_times.py | 30 ------------------- 1 file changed, 30 deletions(-) delete mode 100644 migrations/versions/9a408a3fb763_remove_school_id_on_meeting_times.py diff --git a/migrations/versions/9a408a3fb763_remove_school_id_on_meeting_times.py b/migrations/versions/9a408a3fb763_remove_school_id_on_meeting_times.py deleted file mode 100644 index 985225b..0000000 --- a/migrations/versions/9a408a3fb763_remove_school_id_on_meeting_times.py +++ /dev/null @@ -1,30 +0,0 @@ -"""remove school_id on meeting times - -Revision ID: 9a408a3fb763 -Revises: 2399c50496f7 -Create Date: 2022-06-05 22:45:11.620997 - -""" -from alembic import op -import sqlalchemy as sa -from sqlalchemy.dialects import mysql - -# revision identifiers, used by Alembic. -revision = '9a408a3fb763' -down_revision = '2399c50496f7' -branch_labels = None -depends_on = None - - -def upgrade(): - # ### commands auto generated by Alembic - please adjust! ### - op.drop_index('bellschedulemeetingtimes_FK', table_name='bellschedulemeetingtimes') - op.drop_column('bellschedulemeetingtimes', 'school_id') - # ### end Alembic commands ### - - -def downgrade(): - # ### commands auto generated by Alembic - please adjust! ### - op.add_column('bellschedulemeetingtimes', sa.Column('school_id', sa.BINARY(length=16), nullable=False)) - op.create_index('bellschedulemeetingtimes_FK', 'bellschedulemeetingtimes', ['school_id'], unique=False) - # ### end Alembic commands ### From a8f1f1de9820a003e87034491a1f80418c87ae1a Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Wed, 17 Aug 2022 19:24:21 -0400 Subject: [PATCH 146/206] version bump --- docs.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs.py b/docs.py index f9f9fe6..2694a70 100644 --- a/docs.py +++ b/docs.py @@ -16,7 +16,7 @@ def create_docs(app): # info: { spec = APISpec( title="ClassClock API", - version="0.2.1", + version="0.3.0", openapi_version='2.0', plugins=[ From b48db7aba01f6a326e3538b22018e47e3289e7aa Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Wed, 17 Aug 2022 19:35:27 -0400 Subject: [PATCH 147/206] add a changelog file --- CHANGELOG.md | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..9260f03 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,34 @@ + +## 0.3.0 +- Introduce database migrations using flask-migrate. +- Introduce crude soft-deletion +- Add a new endpoint at `/bellschedules` for logged-in admins to list the schedules for every school that they are the owner of +- disable strict slashes on all endpoints (`.../endpoint/` and `.../endpoint` should now act the same.) +- Updates to CORS settings +- Improvements to generated API documententation +- update dependencies and connection string settings to fix some crashing on startup + + +### Updating to 0.3.0 +The recommended/easiest way to update databases created prior to 0.3.0 is to create a new database. However, this may not be possible in all cases. + +Alternatively, databases created prior to 0.3.0 should be upgraded as follows: +1. perform a backup +2. determine what commit the database was created from +3. apply any database schema changes (as indicated by changes to the `db_schema.py` file) to get your database up to the same schema as version 0.2.0 +4. run the following command against your database: `flask db stamp 93d6649210e1` to set up the versioning table +5. run the migrations using `flask db upgrade`. This will update your database schema so that it contains the latest changes + +## 0.2.0 +- improved logging +- dependency updates +- begin using sqlalchemy ORM for managing DB queries +- add a mehcanism for populating the database with demo data +- Switch from JSONAPI to a more regular JSON output format +- Create an automatically-generated documentation page with swagger +- add a basic HTML homepage to the API's main URL for any visitors that come looking +- add beta and staging site URLs to CORS origins +- add a /ping endpoint to allow the frontend to check connectivity +- Dockerize the app +## 0.1.0 +Initial tagged version \ No newline at end of file From 38965e344bd609e4d5dd62f09dbc9fddbbad083c Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Mon, 5 Sep 2022 09:47:35 -0400 Subject: [PATCH 148/206] update docs for get_api_user_id to reflect when it actually works --- common/helpers.py | 1 + 1 file changed, 1 insertion(+) diff --git a/common/helpers.py b/common/helpers.py index b723889..c44eb85 100644 --- a/common/helpers.py +++ b/common/helpers.py @@ -213,6 +213,7 @@ def get_api_client_id(): def get_api_user_id(): """Returns the id of the user for whom data is being accessed on behalf of + This is only set for requests to endpoints using the @requires_auth decorator """ if hasattr(_request_ctx_stack.top, 'current_user'): raw_id = _request_ctx_stack.top.current_user["sub"] From 2f03c553a6dfc17f56fae2fe26019d96c5d7ce0f Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Mon, 5 Sep 2022 10:09:36 -0400 Subject: [PATCH 149/206] minor tweak to request logging so the user id is actually properly logged --- blueprints/v0.py | 3 +-- common/helpers.py | 4 +++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/blueprints/v0.py b/blueprints/v0.py index 6d2f547..7a1bfe7 100644 --- a/blueprints/v0.py +++ b/blueprints/v0.py @@ -540,8 +540,7 @@ def delete_bellschedule(bell_schedule_id): @blueprint.before_request def before(): - current_app.logger.info( "Handling " + request.method + " Request for endpoint " + request.path + " from API user '" + get_api_user_id() + "' from address " + util.get_remote_address() ) - pass + current_app.logger.info( "Received request " + request.method + " " + request.path + " for API client '" + get_api_client_id() + "' user '" + get_api_user_id() + "'" ) @blueprint.after_request diff --git a/common/helpers.py b/common/helpers.py index c44eb85..a5ca51a 100644 --- a/common/helpers.py +++ b/common/helpers.py @@ -1,4 +1,4 @@ -from flask import _request_ctx_stack, request, url_for, make_response, jsonify +from flask import _request_ctx_stack, request, url_for, make_response, jsonify, current_app from werkzeug.wrappers import Response from functools import wraps from jose import jwt @@ -357,6 +357,8 @@ def decorated(*args, **kwargs): _request_ctx_stack.top.current_user = payload + current_app.logger.info( "Successfully authenticated user '" + get_api_user_id() + "'" ) + #this permissions check was added separately from the auth0 validation code if permissions is not None: check_permissions(payload, permissions) From 2af37cdad1f1de1112cc71445b1832708e5b1ddc Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Mon, 5 Sep 2022 10:53:43 -0400 Subject: [PATCH 150/206] pipenv install requests --- Pipfile | 1 + Pipfile.lock | 139 ++++++++++++++++++++++----------------------------- 2 files changed, 60 insertions(+), 80 deletions(-) diff --git a/Pipfile b/Pipfile index a4a9df3..e4af36f 100644 --- a/Pipfile +++ b/Pipfile @@ -23,6 +23,7 @@ mysql-connector-python = "8.0.24" python-jose = "*" python-dotenv = "*" flask-migrate = "*" +requests = "*" [requires] python_version = "3.8" diff --git a/Pipfile.lock b/Pipfile.lock index 2de5a18..9338808 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "cf2cbbd0ff54b2cf99c20120134addbd1ee2fced7d335f222a227a69a9fd0d92" + "sha256": "88c63e5d755751699383a605685e354d0438f8ba0ec375aa98b51bc4124452ab" }, "pipfile-spec": 6, "requires": { @@ -48,6 +48,22 @@ "markers": "python_version >= '3.5'", "version": "==22.1.0" }, + "certifi": { + "hashes": [ + "sha256:84c85a9078b11105f04f3036a9482ae10e4621616db313fe045dd24743a0820d", + "sha256:fe86415d55e84719d75f8b69414f6438ac3547d2078ab91b67e779ef69378412" + ], + "markers": "python_version >= '3.6'", + "version": "==2022.6.15" + }, + "charset-normalizer": { + "hashes": [ + "sha256:5a3d016c7c547f69d6f81fb0db9449ce888b418b5b9952cc5e6e66843e9dd845", + "sha256:83e9a75d1911279afd89352c68b45348559d1fc0506b054b346651b5e7fee29f" + ], + "markers": "python_version >= '3.6'", + "version": "==2.1.1" + }, "click": { "hashes": [ "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e", @@ -136,6 +152,14 @@ "index": "pypi", "version": "==19.9.0" }, + "idna": { + "hashes": [ + "sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff", + "sha256:9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d" + ], + "markers": "python_version >= '3.5'", + "version": "==3.3" + }, "importlib-metadata": { "hashes": [ "sha256:637245b8bab2b6502fcbc752cc4b7a6f6243bb02b31c5c26156ad103d3d45670", @@ -170,11 +194,11 @@ }, "jsonschema": { "hashes": [ - "sha256:09a0c8547c0d5c3651e43889dcf6626d35965cc2b4924d3fb0d66cdd9e038101", - "sha256:1a500bb42bd96f54a00aa61213d8595ee9d07c06150c5cd74cb9d307a4a8e40a" + "sha256:21f4979391bdceb044e502fd8e79e738c0cdfbdc8773f9a49b5769461e82fe1e", + "sha256:2df0fab225abb3b41967bb3a46fd37dc74b1536b5296d0b1c2078cd072adf0f7" ], "markers": "python_version >= '3.7'", - "version": "==4.10.2" + "version": "==4.15.0" }, "limits": { "hashes": [ @@ -186,11 +210,11 @@ }, "mako": { "hashes": [ - "sha256:df3921c3081b013c8a2d5ff03c18375651684921ae83fd12e64800b7da923257", - "sha256:f054a5ff4743492f1aa9ecc47172cb33b42b9d993cffcc146c9de17e717b0307" + "sha256:3724869b363ba630a272a5f89f68c070352137b8fd1757650017b7e06fda163f", + "sha256:8efcb8004681b5f71d09c983ad5a9e6f5c40601a6ec469148753292abc0da534" ], "markers": "python_version >= '3.7'", - "version": "==1.2.1" + "version": "==1.2.2" }, "markupsafe": { "hashes": [ @@ -240,11 +264,11 @@ }, "marshmallow": { "hashes": [ - "sha256:00040ab5ea0c608e8787137627a8efae97fabd60552a05dc889c888f814e75eb", - "sha256:635fb65a3285a31a30f276f30e958070f5214c7196202caa5c7ecf28f5274bc7" + "sha256:1172ce82765bf26c24a3f9299ed6dbeeca4d213f638eaa39a37772656d7ce408", + "sha256:48e2d88d4ab431ad5a17c25556d9da529ea6e966876f2a38d274082e270287f0" ], "markers": "python_version >= '3.7'", - "version": "==3.17.0" + "version": "==3.17.1" }, "marshmallow-sqlalchemy": { "hashes": [ @@ -389,11 +413,11 @@ }, "python-dotenv": { "hashes": [ - "sha256:b7e3b04a59693c42c36f9ab1cc2acc46fa5df8c78e178fc33a8d4cd05c8d498f", - "sha256:d92a187be61fe482e4fd675b6d52200e7be63a12b724abbf931a40ce4fa92938" + "sha256:1684eb44636dd462b66c3ee016599815514527ad99965de77f43e0944634a7e5", + "sha256:b77d08274639e3d34145dfa6c7008e66df0f04b7be7a75fd0d5292c191d79045" ], "index": "pypi", - "version": "==0.20.0" + "version": "==0.21.0" }, "python-jose": { "hashes": [ @@ -442,6 +466,14 @@ "markers": "python_version >= '3.6'", "version": "==6.0" }, + "requests": { + "hashes": [ + "sha256:7c5599b102feddaa661c826c56ab4fee28bfd17f5abca1ebbe3e7f19d7c97983", + "sha256:8fefa2a1a1365bf5520aac41836fbee479da67864514bdb821f31ce07ce65349" + ], + "index": "pypi", + "version": "==2.28.1" + }, "rsa": { "hashes": [ "sha256:90260d9058e514786967344d0ef75fa8727eed8a7d2e43ce9f4bcf1b536174f7", @@ -452,11 +484,11 @@ }, "setuptools": { "hashes": [ - "sha256:101bf15ca723beef42c8db91a761f3748d4d697e17fae904db60c0b619d8d094", - "sha256:39275e7aafa4a4f0f4308f2302c6ee384dcdacdbaacc1e30dcbb6fd824c625bb" + "sha256:2e24e0bec025f035a2e72cdd1961119f557d78ad331bb00ff82efb2ab8da8e82", + "sha256:7732871f4f7fa58fb6bdcaeadb0161b2bd046c85905dbaa066bdcbcc81953b57" ], "markers": "python_version >= '3.7'", - "version": "==65.0.2" + "version": "==65.3.0" }, "six": { "hashes": [ @@ -514,6 +546,14 @@ "markers": "python_version >= '3.7'", "version": "==4.3.0" }, + "urllib3": { + "hashes": [ + "sha256:3fa96cf423e6987997fc326ae8df396db2a8b7c667747d47ddd8ecba91f4a74e", + "sha256:b930dd878d5a8afb066a637fbb35144fe7901e3b209d1cd4f524bd0e9deee997" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5' and python_version < '4'", + "version": "==1.26.12" + }, "werkzeug": { "hashes": [ "sha256:7ea2d48322cc7c0f8b3a215ed73eabd7b5d75d0b50e31ab006286ccff9e00b8f", @@ -642,67 +682,6 @@ "index": "pypi", "version": "==2.5.1" }, - "greenlet": { - "hashes": [ - "sha256:0051c6f1f27cb756ffc0ffbac7d2cd48cb0362ac1736871399a739b2885134d3", - "sha256:00e44c8afdbe5467e4f7b5851be223be68adb4272f44696ee71fe46b7036a711", - "sha256:013d61294b6cd8fe3242932c1c5e36e5d1db2c8afb58606c5a67efce62c1f5fd", - "sha256:049fe7579230e44daef03a259faa24511d10ebfa44f69411d99e6a184fe68073", - "sha256:14d4f3cd4e8b524ae9b8aa567858beed70c392fdec26dbdb0a8a418392e71708", - "sha256:166eac03e48784a6a6e0e5f041cfebb1ab400b394db188c48b3a84737f505b67", - "sha256:17ff94e7a83aa8671a25bf5b59326ec26da379ace2ebc4411d690d80a7fbcf23", - "sha256:1e12bdc622676ce47ae9abbf455c189e442afdde8818d9da983085df6312e7a1", - "sha256:21915eb821a6b3d9d8eefdaf57d6c345b970ad722f856cd71739493ce003ad08", - "sha256:288c6a76705dc54fba69fbcb59904ae4ad768b4c768839b8ca5fdadec6dd8cfd", - "sha256:2bde6792f313f4e918caabc46532aa64aa27a0db05d75b20edfc5c6f46479de2", - "sha256:32ca72bbc673adbcfecb935bb3fb1b74e663d10a4b241aaa2f5a75fe1d1f90aa", - "sha256:356b3576ad078c89a6107caa9c50cc14e98e3a6c4874a37c3e0273e4baf33de8", - "sha256:40b951f601af999a8bf2ce8c71e8aaa4e8c6f78ff8afae7b808aae2dc50d4c40", - "sha256:572e1787d1460da79590bf44304abbc0a2da944ea64ec549188fa84d89bba7ab", - "sha256:58df5c2a0e293bf665a51f8a100d3e9956febfbf1d9aaf8c0677cf70218910c6", - "sha256:64e6175c2e53195278d7388c454e0b30997573f3f4bd63697f88d855f7a6a1fc", - "sha256:7227b47e73dedaa513cdebb98469705ef0d66eb5a1250144468e9c3097d6b59b", - "sha256:7418b6bfc7fe3331541b84bb2141c9baf1ec7132a7ecd9f375912eca810e714e", - "sha256:7cbd7574ce8e138bda9df4efc6bf2ab8572c9aff640d8ecfece1b006b68da963", - "sha256:7ff61ff178250f9bb3cd89752df0f1dd0e27316a8bd1465351652b1b4a4cdfd3", - "sha256:833e1551925ed51e6b44c800e71e77dacd7e49181fdc9ac9a0bf3714d515785d", - "sha256:8639cadfda96737427330a094476d4c7a56ac03de7265622fcf4cfe57c8ae18d", - "sha256:8c5d5b35f789a030ebb95bff352f1d27a93d81069f2adb3182d99882e095cefe", - "sha256:8c790abda465726cfb8bb08bd4ca9a5d0a7bd77c7ac1ca1b839ad823b948ea28", - "sha256:8d2f1fb53a421b410751887eb4ff21386d119ef9cde3797bf5e7ed49fb51a3b3", - "sha256:903bbd302a2378f984aef528f76d4c9b1748f318fe1294961c072bdc7f2ffa3e", - "sha256:93f81b134a165cc17123626ab8da2e30c0455441d4ab5576eed73a64c025b25c", - "sha256:95e69877983ea39b7303570fa6760f81a3eec23d0e3ab2021b7144b94d06202d", - "sha256:9633b3034d3d901f0a46b7939f8c4d64427dfba6bbc5a36b1a67364cf148a1b0", - "sha256:97e5306482182170ade15c4b0d8386ded995a07d7cc2ca8f27958d34d6736497", - "sha256:9f3cba480d3deb69f6ee2c1825060177a22c7826431458c697df88e6aeb3caee", - "sha256:aa5b467f15e78b82257319aebc78dd2915e4c1436c3c0d1ad6f53e47ba6e2713", - "sha256:abb7a75ed8b968f3061327c433a0fbd17b729947b400747c334a9c29a9af6c58", - "sha256:aec52725173bd3a7b56fe91bc56eccb26fbdff1386ef123abb63c84c5b43b63a", - "sha256:b11548073a2213d950c3f671aa88e6f83cda6e2fb97a8b6317b1b5b33d850e06", - "sha256:b1692f7d6bc45e3200844be0dba153612103db241691088626a33ff1f24a0d88", - "sha256:b336501a05e13b616ef81ce329c0e09ac5ed8c732d9ba7e3e983fcc1a9e86965", - "sha256:b8c008de9d0daba7b6666aa5bbfdc23dcd78cafc33997c9b7741ff6353bafb7f", - "sha256:b92e29e58bef6d9cfd340c72b04d74c4b4e9f70c9fa7c78b674d1fec18896dc4", - "sha256:be5f425ff1f5f4b3c1e33ad64ab994eed12fc284a6ea71c5243fd564502ecbe5", - "sha256:dd0b1e9e891f69e7675ba5c92e28b90eaa045f6ab134ffe70b52e948aa175b3c", - "sha256:e30f5ea4ae2346e62cedde8794a56858a67b878dd79f7df76a0767e356b1744a", - "sha256:e6a36bb9474218c7a5b27ae476035497a6990e21d04c279884eb10d9b290f1b1", - "sha256:e859fcb4cbe93504ea18008d1df98dee4f7766db66c435e4882ab35cf70cac43", - "sha256:eb6ea6da4c787111adf40f697b4e58732ee0942b5d3bd8f435277643329ba627", - "sha256:ec8c433b3ab0419100bd45b47c9c8551248a5aee30ca5e9d399a0b57ac04651b", - "sha256:eff9d20417ff9dcb0d25e2defc2574d10b491bf2e693b4e491914738b7908168", - "sha256:f0214eb2a23b85528310dad848ad2ac58e735612929c8072f6093f3585fd342d", - "sha256:f276df9830dba7a333544bd41070e8175762a7ac20350786b322b714b0e654f5", - "sha256:f3acda1924472472ddd60c29e5b9db0cec629fbe3c5c5accb74d6d6d14773478", - "sha256:f70a9e237bb792c7cc7e44c531fd48f5897961701cdaa06cf22fc14965c496cf", - "sha256:f9d29ca8a77117315101425ec7ec2a47a22ccf59f5593378fc4077ac5b754fce", - "sha256:fa877ca7f6b48054f847b61d6fa7bed5cebb663ebc55e018fda12db09dcc664c", - "sha256:fdcec0b8399108577ec290f55551d926d9a1fa6cad45882093a7a07ac5ec147b" - ], - "markers": "python_version >= '3' and platform_machine == 'aarch64' or (platform_machine == 'ppc64le' or (platform_machine == 'x86_64' or (platform_machine == 'amd64' or (platform_machine == 'AMD64' or (platform_machine == 'win32' or platform_machine == 'WIN32')))))", - "version": "==1.1.2" - }, "importlib-metadata": { "hashes": [ "sha256:637245b8bab2b6502fcbc752cc4b7a6f6243bb02b31c5c26156ad103d3d45670", @@ -737,11 +716,11 @@ }, "mako": { "hashes": [ - "sha256:df3921c3081b013c8a2d5ff03c18375651684921ae83fd12e64800b7da923257", - "sha256:f054a5ff4743492f1aa9ecc47172cb33b42b9d993cffcc146c9de17e717b0307" + "sha256:3724869b363ba630a272a5f89f68c070352137b8fd1757650017b7e06fda163f", + "sha256:8efcb8004681b5f71d09c983ad5a9e6f5c40601a6ec469148753292abc0da534" ], "markers": "python_version >= '3.7'", - "version": "==1.2.1" + "version": "==1.2.2" }, "markupsafe": { "hashes": [ From f46880548908644c7a39a27cca48ef4f43bf3c09 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Mon, 5 Sep 2022 10:55:00 -0400 Subject: [PATCH 151/206] update management API code to use requests instead of manually using HTTP libs --- common/services/auth0management.py | 57 ++++++++++++++---------------- 1 file changed, 27 insertions(+), 30 deletions(-) diff --git a/common/services/auth0management.py b/common/services/auth0management.py index 41a6663..42681fb 100644 --- a/common/services/auth0management.py +++ b/common/services/auth0management.py @@ -1,56 +1,53 @@ -import http.client +import requests import json from os import environ as env - +import logging class Auth0ManagementService: base_path = "/api/v2" + base_url = "https://" + env.get("AUTH0_DOMAIN") + base_path headers = {"Content-Type": "application/json"} def __init__(self): - self.conn = http.client.HTTPSConnection("classclock.auth0.com") self.access_token = self.get_token() def get_user(self, user_id): - url = Auth0ManagementService.base_path + "/users/" + user_id + url = Auth0ManagementService.base_url + "/users/" + user_id heads = {**Auth0ManagementService.headers, ** {"Authorization": "Bearer " + self.access_token}} - self.conn.request("GET", url, "", heads) - - res = self.conn.getresponse() - data = res.read() + resp = requests.get(url, headers=heads) - return data.decode("utf-8") + data = resp.json() + return data # print(access_token) def get_roles_for_user(self, user_id): - url = Auth0ManagementService.base_path + "/users/" + user_id + "/roles" + url = Auth0ManagementService.base_url + "/users/" + user_id + "/roles" heads = {**Auth0ManagementService.headers, ** {"Authorization": "Bearer " + self.access_token}} - self.conn.request("GET", url, "", heads) - try: - res = self.conn.getresponse() - data = res.read() - - return data.decode("utf-8") - except http.client.RemoteDisconnected as e: - # this tends to fail and then break all future auth0 stuff - # maybe its a connection keep alive problem? - # - print("Auth0 Management API error: ", e) - return [] + resp = requests.get(url, headers=heads) + data = resp.json() + return data def get_token(self): - payload = "{\"client_id\": \"" + env.get("AUTH0_CLIENT_ID") + "\" ,\"client_secret\": \"" + env.get( - "AUTH0_CLIENT_SECRET") + "\" ,\"audience\": \"https://classclock.auth0.com/api/v2/\",\"grant_type\": \"client_credentials\"}" - - self.conn.request("POST", "/oauth/token", payload, - Auth0ManagementService.headers) - res = self.conn.getresponse() - data = res.read() - return json.loads(data.decode("utf-8"))["access_token"] + # TODO: use the auth0 python SDK/lib for this https://github.com/auth0/auth0-python#management-sdk + payload = { + "client_id": env.get("AUTH0_CLIENT_ID"), + "client_secret": env.get("AUTH0_CLIENT_SECRET"), + "audience": self.base_url, + "grant_type": "client_credentials" + } + resp = requests.post("https://" + env.get("AUTH0_DOMAIN") + "/oauth/token", data=json.dumps(payload), headers=Auth0ManagementService.headers) + + data = resp.json() + if data.get("error"): + logging.error("failed to get auth0 management API access token") + logging.error(data) + return "" + else: + return data["access_token"] From fd88957cb7c1a48ec5ce26902f473c334eb701a9 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Mon, 5 Sep 2022 15:14:09 -0400 Subject: [PATCH 152/206] some logging improvements --- common/helpers.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/common/helpers.py b/common/helpers.py index a5ca51a..aa42e02 100644 --- a/common/helpers.py +++ b/common/helpers.py @@ -27,9 +27,10 @@ try: #TODO: remove dependency on setting up auth0 to test the API management_API = auth0management.Auth0ManagementService() -except: +except Exception as e: + current_app.logger.error(e) #TODO: need to implement better logging. - print('Auth0 is not configured correctly. Access control for requests will not be enforced.') + current_app.logger.warning('Auth0 is not configured correctly. Access control for requests will not be enforced.') management_API = None @@ -275,7 +276,7 @@ def check_for_role(role): if management_API is None: #TODO: need to implement better logging. - print("Because Auth0 is not configured correctly, access control is not being enforced. All requests to check a users role will automatically pass.") + current_app.logger.warning("Because Auth0 is not configured correctly, access control is not being enforced. All requests to check a users role will automatically pass.") return True if user_id != "": @@ -314,7 +315,7 @@ def args_or_no(func): def decorated(*args, **kwargs): if not management_API: #TODO: need to implement better logging. - print("Because Auth0 is not configured correctly, access control is not being enforced. All requests to protected endpoints will automatically succeed.") + current_app.logger.warning("Because Auth0 is not configured correctly, access control is not being enforced. All requests to protected endpoints will automatically succeed.") return func(*args, **kwargs) token = get_token_auth_header() From e0f879257fe006c1ab0cfcde258ec0884de2ff13 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Tue, 13 Sep 2022 14:26:03 -0400 Subject: [PATCH 153/206] log HTTP status response --- blueprints/v0.py | 1 + 1 file changed, 1 insertion(+) diff --git a/blueprints/v0.py b/blueprints/v0.py index 7a1bfe7..bcb2da1 100644 --- a/blueprints/v0.py +++ b/blueprints/v0.py @@ -546,6 +546,7 @@ def before(): @blueprint.after_request def after_request(response): response.headers['Content-Type'] = 'application/json' + current_app.logger.info( "Handled request with HTTP status" + response.status_code) return response # From a77b35594458a91ee4d44e329296809c16035e0c Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 9 Oct 2022 20:46:04 -0400 Subject: [PATCH 154/206] fix auth0 management api stuff by adding the trailing slash to the auth0 audience value --- common/services/auth0management.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/common/services/auth0management.py b/common/services/auth0management.py index 42681fb..f332c3e 100644 --- a/common/services/auth0management.py +++ b/common/services/auth0management.py @@ -36,10 +36,11 @@ def get_roles_for_user(self, user_id): def get_token(self): # TODO: use the auth0 python SDK/lib for this https://github.com/auth0/auth0-python#management-sdk + # missing the trailing slash on the audience can cause problems: https://community.auth0.com/t/getting-service-not-enabled-within-domain-when-requesting-an-api-token/12634 payload = { "client_id": env.get("AUTH0_CLIENT_ID"), "client_secret": env.get("AUTH0_CLIENT_SECRET"), - "audience": self.base_url, + "audience": self.base_url + "/", "grant_type": "client_credentials" } resp = requests.post("https://" + env.get("AUTH0_DOMAIN") + "/oauth/token", data=json.dumps(payload), headers=Auth0ManagementService.headers) From c5d3ba29143235fe9c7db5942637267d88ee933a Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 9 Oct 2022 20:46:21 -0400 Subject: [PATCH 155/206] add space to the status code printout for a handled request --- blueprints/v0.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/blueprints/v0.py b/blueprints/v0.py index bcb2da1..4f8235d 100644 --- a/blueprints/v0.py +++ b/blueprints/v0.py @@ -546,7 +546,7 @@ def before(): @blueprint.after_request def after_request(response): response.headers['Content-Type'] = 'application/json' - current_app.logger.info( "Handled request with HTTP status" + response.status_code) + current_app.logger.info( "Handled request with HTTP status: " + str(response.status_code)) return response # From 43c738431c17bdf42a01b629b1f54c6e65d2c50c Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 9 Oct 2022 21:00:20 -0400 Subject: [PATCH 156/206] update role-checking to parse the JSON that the auth0 API returns not sure why this wasn't being done before --- common/helpers.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/common/helpers.py b/common/helpers.py index aa42e02..8fc2b3f 100644 --- a/common/helpers.py +++ b/common/helpers.py @@ -280,7 +280,10 @@ def check_for_role(role): return True if user_id != "": - return role in management_API.get_roles_for_user(user_id) + roles_json = management_API.get_roles_for_user(user_id) + role_names = [r["name"].lower() for r in roles_json] + + return role.lower() in role_names else: return None From 3e663b1eacd1895757f2b8c1d92d8144db2c8663 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 9 Oct 2022 21:00:33 -0400 Subject: [PATCH 157/206] document check_for_role --- common/helpers.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/common/helpers.py b/common/helpers.py index 8fc2b3f..35bc51c 100644 --- a/common/helpers.py +++ b/common/helpers.py @@ -269,8 +269,15 @@ def check_permissions(user, permissions_to_check): raise AuthError( "You have not been granted the necessary permissions to access to this resource. You are missing the following permissions: " + perms_needed, 403) +def check_for_role(role:str): + """Performs a simple, stupid, name-based check against the roles that a user has. -def check_for_role(role): + Args: + role (str): the name of the role to check if the user has + + Returns: + bool: true if the user has the role, false if they dont, and None if there is no currently authenticated user (this must be used after the @requires_auth decorator is applied) + """ user_id = get_api_user_id() #TODO: make management API optional and check if it is present From 4f46e662f7da395c192fdc644a8eb039564d8723 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Tue, 11 Oct 2022 13:45:40 -0400 Subject: [PATCH 158/206] version bump --- CHANGELOG.md | 5 +++++ docs.py | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9260f03..0ea049f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,9 @@ +## 0.3.1 +- Improvements to logging +- Improved interactions with Auth0 management API by using higher level HTTP libraries and correcting the URL path for accessing the API +- updated role checking for protected endpoints to be a little more robust and more reliably parse the data from the management API + ## 0.3.0 - Introduce database migrations using flask-migrate. - Introduce crude soft-deletion diff --git a/docs.py b/docs.py index 2694a70..9cb0ba0 100644 --- a/docs.py +++ b/docs.py @@ -16,7 +16,7 @@ def create_docs(app): # info: { spec = APISpec( title="ClassClock API", - version="0.3.0", + version="0.3.1", openapi_version='2.0', plugins=[ From d021d4ecaed72225947c175d3738dc66df7effd1 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Wed, 12 Oct 2022 14:38:16 -0400 Subject: [PATCH 159/206] Create docker-image.yml --- .github/workflows/docker-image.yml | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 .github/workflows/docker-image.yml diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml new file mode 100644 index 0000000..6a2eb84 --- /dev/null +++ b/.github/workflows/docker-image.yml @@ -0,0 +1,29 @@ +name: Docker Image CI + +on: + push: + branches: [ "main" ] +# tags: [ "main" ] + +jobs: + build: + runs-on: ubuntu-latest + steps: +# - +# name: Set up QEMU +# uses: docker/setup-qemu-action@v2 + - + name: Set up Docker Buildx + uses: docker/setup-buildx-action@v2 + - + name: Login to Docker Hub + uses: docker/login-action@v2 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + - + name: Build and push + uses: docker/build-push-action@v3 + with: + push: true + tags: moralcode/classclockapi:main From 2e324c8f4be50ba34a64a71de0745b981c20efde Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Wed, 12 Oct 2022 14:46:19 -0400 Subject: [PATCH 160/206] add action for deploying tags --- .github/workflows/docker-image-tag.yml | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 .github/workflows/docker-image-tag.yml diff --git a/.github/workflows/docker-image-tag.yml b/.github/workflows/docker-image-tag.yml new file mode 100644 index 0000000..8e78b43 --- /dev/null +++ b/.github/workflows/docker-image-tag.yml @@ -0,0 +1,25 @@ +name: Docker Image CI - tags + +on: + push: + tags: [ "*" ] + +jobs: + build: + runs-on: ubuntu-latest + steps: + - + name: Set up Docker Buildx + uses: docker/setup-buildx-action@v2 + - + name: Login to Docker Hub + uses: docker/login-action@v2 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + - + name: Build and push + uses: docker/build-push-action@v3 + with: + push: true + tags: moralcode/classclockapi:${{ github.ref_name }} From a292b4a78bbd58dea132ee970f6526489fbe216d Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 16 Oct 2022 11:02:11 -0400 Subject: [PATCH 161/206] update docker command to allow it to be interactive --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a583712..cbee392 100644 --- a/README.md +++ b/README.md @@ -34,4 +34,4 @@ This API has been set up to run in a docker container. The simplest way to run it is to: 1. aquire the container either from a docker repository or by running `docker build . -t classclock-api` in a cloned version of this repo 2. set up the environment variables you want per the above table -3. use a command like `docker run -p 8000:8000 --rm --env-file dev.env classclock-api:latest` to run the container interactively using `dev.env` as the source of the environment variables. The app will start up on port 8000. \ No newline at end of file +3. use a command like `docker run -p 8000:8000 --rm -it --env-file dev.env classclock-api:latest` to run the container interactively using `dev.env` as the source of the environment variables. The app will start up on port 8000. \ No newline at end of file From fb07bc449215fcaec7d56ce85e6dffa8b533f894 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 16 Oct 2022 11:02:40 -0400 Subject: [PATCH 162/206] add known issues to 0.3.1 changelog --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0ea049f..4f186c4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,9 @@ - Improved interactions with Auth0 management API by using higher level HTTP libraries and correcting the URL path for accessing the API - updated role checking for protected endpoints to be a little more robust and more reliably parse the data from the management API +Known issues: +- Will not start up if environment variables are quoted. + ## 0.3.0 - Introduce database migrations using flask-migrate. - Introduce crude soft-deletion From 0fd9f408e164f61e4996cd9c044ff16ed9bd8a59 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Sun, 20 Nov 2022 10:31:04 -0500 Subject: [PATCH 163/206] add CONTRIBUTING.md with some information on creating new migrations --- CONTRIBUTING.md | 9 +++++++++ README.md | 6 +++++- 2 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 CONTRIBUTING.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..1129ae8 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,9 @@ +# Contributing to the ClassClock API + + +Here are some things that may be helpful for maintainers or contributors + + +## making changes to the schema +If you make changes to the DB schema, generate a new migration to allow existing users to upgrade their databases. This can be done with the command `FLASK_APP=api.py pipenv run flask db migrate -m ""`. Use a short, descriptive message to describe what was changed. TO upgrade, run `FLASK_APP=api.py pipenv run flask db upgrade` to update your local db to the new schema. Don't forget to also document the changes in the changelog you made to the app and which app versions are compatible with which DB versions. + diff --git a/README.md b/README.md index cbee392..0928517 100644 --- a/README.md +++ b/README.md @@ -34,4 +34,8 @@ This API has been set up to run in a docker container. The simplest way to run it is to: 1. aquire the container either from a docker repository or by running `docker build . -t classclock-api` in a cloned version of this repo 2. set up the environment variables you want per the above table -3. use a command like `docker run -p 8000:8000 --rm -it --env-file dev.env classclock-api:latest` to run the container interactively using `dev.env` as the source of the environment variables. The app will start up on port 8000. \ No newline at end of file +3. use a command like `docker run -p 8000:8000 --rm -it --env-file dev.env classclock-api:latest` to run the container interactively using `dev.env` as the source of the environment variables. The app will start up on port 8000. + +## Contributing + +If you are interested in making changes to the ClassClock API, see the [CONTRIBUTING](./CONTRIBUTING.md) file for details on how to do so. \ No newline at end of file From c0d25bb21367486406518ba955dec1c6d264cc79 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Thu, 24 Nov 2022 16:43:44 -0500 Subject: [PATCH 164/206] fix process of creating a new schedule --- blueprints/v0.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/blueprints/v0.py b/blueprints/v0.py index 4f8235d..8c2d148 100644 --- a/blueprints/v0.py +++ b/blueprints/v0.py @@ -415,12 +415,13 @@ def create_bellschedule(): $ref: '#/definitions/BellSchedule' required: true """ - + request_data = get_request_body(request) + school_id= request_data["school_id"] # get school_id from a data parameter school = SchoolDB.query.filter_by(id=school_id).first() check_ownership(school) - new_schedule = BellScheduleSchema().load(get_request_body(request)).data + new_schedule = BellScheduleSchema().load(request_data, session=db.session) school.schedules.append(new_schedule) From 81c2129efc12cdf2dea73f7b683844e8695611f9 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Wed, 4 Jan 2023 11:34:03 -0800 Subject: [PATCH 165/206] allow the admin role check to check for multiple roles --- common/helpers.py | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/common/helpers.py b/common/helpers.py index 35bc51c..424269d 100644 --- a/common/helpers.py +++ b/common/helpers.py @@ -269,14 +269,17 @@ def check_permissions(user, permissions_to_check): raise AuthError( "You have not been granted the necessary permissions to access to this resource. You are missing the following permissions: " + perms_needed, 403) -def check_for_role(role:str): - """Performs a simple, stupid, name-based check against the roles that a user has. +def check_for_roles(roles:list, accept_any=True): + """Performs a simple, stupid, name-based check against the roles that a user has. + + This must be used after the @requires_auth decorator is applied Args: - role (str): the name of the role to check if the user has + roles (list): a list of names of roles to check + accept_any (boolean): True to accept ANY of the provided roles. False to accept only ALL provided roles. Defaults to True. Returns: - bool: true if the user has the role, false if they dont, and None if there is no currently authenticated user (this must be used after the @requires_auth decorator is applied) + bool: true if the user has any of the roles provided, false if the user has none of them, and None if there is no currently authenticated user """ user_id = get_api_user_id() #TODO: make management API optional and check if it is present @@ -288,9 +291,14 @@ def check_for_role(role:str): if user_id != "": roles_json = management_API.get_roles_for_user(user_id) - role_names = [r["name"].lower() for r in roles_json] - - return role.lower() in role_names + # current_app.logger.info(roles_json) + user_role_names = [r["name"].lower() for r in roles_json] + user_role_names = set(user_role_names) + requested_roles = set([r.lower() for r in roles]) + + required_threshold = 1 if accept_any else len(requested_roles) + + return len(requested_roles & user_role_names) >= required_threshold else: return None @@ -392,7 +400,7 @@ def requires_admin(f): @wraps(f) def decorated(*args, **kwargs): - is_admin = check_for_role("admin") + is_admin = check_for_roles(["admin"]) if is_admin is None: raise Oops("There must be a user signed in to perform this action", 400, title="No User Authorization") From 07012edc0bb4348fc09d03521f21c3e385e14e77 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Wed, 4 Jan 2023 11:36:01 -0800 Subject: [PATCH 166/206] include school admin role in role check --- common/helpers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/helpers.py b/common/helpers.py index 424269d..35f55ba 100644 --- a/common/helpers.py +++ b/common/helpers.py @@ -400,7 +400,7 @@ def requires_admin(f): @wraps(f) def decorated(*args, **kwargs): - is_admin = check_for_roles(["admin"]) + is_admin = check_for_roles(["admin", "school admin"]) if is_admin is None: raise Oops("There must be a user signed in to perform this action", 400, title="No User Authorization") From 229687729e40567faa58a38225eacd1733572b24 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Mon, 6 Feb 2023 16:26:32 -0500 Subject: [PATCH 167/206] add a mechanism for refreshing the auth0 management API token when it expires --- common/services/auth0management.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/common/services/auth0management.py b/common/services/auth0management.py index f332c3e..df47b38 100644 --- a/common/services/auth0management.py +++ b/common/services/auth0management.py @@ -30,6 +30,9 @@ def get_roles_for_user(self, user_id): {"Authorization": "Bearer " + self.access_token}} resp = requests.get(url, headers=heads) data = resp.json() + if (data.get("statusCode") == 401 and "xpired token" in data.get("message")): + self.access_token = self.get_token() + return self.get_roles_for_user(user_id) return data From 2039c2b0f8a4b2926f60f07e242418c58682a25d Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Mon, 6 Feb 2023 16:28:12 -0500 Subject: [PATCH 168/206] update access denied error message for those who arent school owners --- common/helpers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/helpers.py b/common/helpers.py index 35f55ba..31e6fc4 100644 --- a/common/helpers.py +++ b/common/helpers.py @@ -304,7 +304,7 @@ def check_for_roles(roles:list, accept_any=True): def check_ownership(school): if get_api_user_id() not in school.owner_id: - raise Oops("Authorizing user is not the owner of this school", 401) + raise Oops("Authorizing user does not have permission to access the requested school", 401) def list_owned_school_ids(cursor, school_id): From 2d961101dc6a7678b2ff2b48a30c23abf72a1742 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Mon, 6 Feb 2023 16:39:26 -0500 Subject: [PATCH 169/206] make sure it still works for list data --- common/services/auth0management.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/common/services/auth0management.py b/common/services/auth0management.py index df47b38..22adce6 100644 --- a/common/services/auth0management.py +++ b/common/services/auth0management.py @@ -30,10 +30,15 @@ def get_roles_for_user(self, user_id): {"Authorization": "Bearer " + self.access_token}} resp = requests.get(url, headers=heads) data = resp.json() - if (data.get("statusCode") == 401 and "xpired token" in data.get("message")): + if isinstance(data, list): + return data + elif (data.get("statusCode") == 401 and "xpired token" in data.get("message")): self.access_token = self.get_token() return self.get_roles_for_user(user_id) - return data + else: + logging.error("encountered unexpected auth0 management API response") + logging.error(data) + return [] def get_token(self): From db7900e898ba7233ed34a71ccb45305504691c67 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Mon, 6 Feb 2023 16:47:30 -0500 Subject: [PATCH 170/206] version bump --- CHANGELOG.md | 3 +++ docs.py | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4f186c4..e6534ab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +## 0.3.2 +- Improvements to the admin role checks +- Fix an issue where the token for the auth0management endpoint for checking user roles would expire and cause requests to return less data than they should ## 0.3.1 - Improvements to logging diff --git a/docs.py b/docs.py index 9cb0ba0..03d39dd 100644 --- a/docs.py +++ b/docs.py @@ -16,7 +16,7 @@ def create_docs(app): # info: { spec = APISpec( title="ClassClock API", - version="0.3.1", + version="0.3.2", openapi_version='2.0', plugins=[ From d6753bb58ad98227c4777725abde4df8c54c6233 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Tue, 7 Feb 2023 08:33:13 -0500 Subject: [PATCH 171/206] add docker badge --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 0928517..b3b1de3 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # ClassClockAPI +![Docker Pulls](https://img.shields.io/docker/pulls/moralcode/classclockapi) + This is the backend that provides access to the ClassClock database. ## Environment Variables From 0484c500e36157741ab33aa8dd13873996f02ef4 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Fri, 17 Feb 2023 09:59:51 -0500 Subject: [PATCH 172/206] add sentry monitoring if environment variable is present --- Pipfile | 1 + Pipfile.lock | 615 ++++++++++++++++++++++++++++++--------------------- README.md | 1 + api.py | 11 + 4 files changed, 381 insertions(+), 247 deletions(-) diff --git a/Pipfile b/Pipfile index e4af36f..225e148 100644 --- a/Pipfile +++ b/Pipfile @@ -24,6 +24,7 @@ python-jose = "*" python-dotenv = "*" flask-migrate = "*" requests = "*" +sentry-sdk = "*" [requires] python_version = "3.8" diff --git a/Pipfile.lock b/Pipfile.lock index 9338808..43f309b 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "88c63e5d755751699383a605685e354d0438f8ba0ec375aa98b51bc4124452ab" + "sha256": "674fb0252cffe8e0fd961659d356f336ff6297696a3ab35ee6e8d3ee42b9b761" }, "pipfile-spec": 6, "requires": { @@ -18,11 +18,11 @@ "default": { "alembic": { "hashes": [ - "sha256:0a024d7f2de88d738d7395ff866997314c837be6104e90c5724350313dee4da4", - "sha256:cd0b5e45b14b706426b833f06369b9a6d5ee03f826ec3238723ce8caaf6e5ffa" + "sha256:4d3bd32ecdbb7bbfb48a9fe9e6d6fd6a831a1b59d03e26e292210237373e7db5", + "sha256:6f1c2207369bf4f49f952057a33bb017fbe5c148c2a773b46906b806ea6e825f" ], "markers": "python_version >= '3.7'", - "version": "==1.8.1" + "version": "==1.9.4" }, "apispec": { "hashes": [ @@ -42,27 +42,113 @@ }, "attrs": { "hashes": [ - "sha256:29adc2665447e5191d0e7c568fde78b21f9672d344281d0c6e1ab085429b22b6", - "sha256:86efa402f67bf2df34f51a335487cf46b1ec130d02b8d39fd248abfd30da551c" + "sha256:29e95c7f6778868dbd49170f98f8818f78f3dc5e0e37c0b1f474e3561b240836", + "sha256:c9227bfc2f01993c03f68db37d1d15c9690188323c067c641f1a35ca58185f99" ], - "markers": "python_version >= '3.5'", - "version": "==22.1.0" + "markers": "python_version >= '3.6'", + "version": "==22.2.0" }, "certifi": { "hashes": [ - "sha256:84c85a9078b11105f04f3036a9482ae10e4621616db313fe045dd24743a0820d", - "sha256:fe86415d55e84719d75f8b69414f6438ac3547d2078ab91b67e779ef69378412" + "sha256:35824b4c3a97115964b408844d64aa14db1cc518f6562e8d7261699d1350a9e3", + "sha256:4ad3232f5e926d6718ec31cfc1fcadfde020920e278684144551c91769c7bc18" ], "markers": "python_version >= '3.6'", - "version": "==2022.6.15" + "version": "==2022.12.7" }, "charset-normalizer": { "hashes": [ - "sha256:5a3d016c7c547f69d6f81fb0db9449ce888b418b5b9952cc5e6e66843e9dd845", - "sha256:83e9a75d1911279afd89352c68b45348559d1fc0506b054b346651b5e7fee29f" + "sha256:00d3ffdaafe92a5dc603cb9bd5111aaa36dfa187c8285c543be562e61b755f6b", + "sha256:024e606be3ed92216e2b6952ed859d86b4cfa52cd5bc5f050e7dc28f9b43ec42", + "sha256:0298eafff88c99982a4cf66ba2efa1128e4ddaca0b05eec4c456bbc7db691d8d", + "sha256:02a51034802cbf38db3f89c66fb5d2ec57e6fe7ef2f4a44d070a593c3688667b", + "sha256:083c8d17153ecb403e5e1eb76a7ef4babfc2c48d58899c98fcaa04833e7a2f9a", + "sha256:0a11e971ed097d24c534c037d298ad32c6ce81a45736d31e0ff0ad37ab437d59", + "sha256:0bf2dae5291758b6f84cf923bfaa285632816007db0330002fa1de38bfcb7154", + "sha256:0c0a590235ccd933d9892c627dec5bc7511ce6ad6c1011fdf5b11363022746c1", + "sha256:0f438ae3532723fb6ead77e7c604be7c8374094ef4ee2c5e03a3a17f1fca256c", + "sha256:109487860ef6a328f3eec66f2bf78b0b72400280d8f8ea05f69c51644ba6521a", + "sha256:11b53acf2411c3b09e6af37e4b9005cba376c872503c8f28218c7243582df45d", + "sha256:12db3b2c533c23ab812c2b25934f60383361f8a376ae272665f8e48b88e8e1c6", + "sha256:14e76c0f23218b8f46c4d87018ca2e441535aed3632ca134b10239dfb6dadd6b", + "sha256:16a8663d6e281208d78806dbe14ee9903715361cf81f6d4309944e4d1e59ac5b", + "sha256:292d5e8ba896bbfd6334b096e34bffb56161c81408d6d036a7dfa6929cff8783", + "sha256:2c03cc56021a4bd59be889c2b9257dae13bf55041a3372d3295416f86b295fb5", + "sha256:2e396d70bc4ef5325b72b593a72c8979999aa52fb8bcf03f701c1b03e1166918", + "sha256:2edb64ee7bf1ed524a1da60cdcd2e1f6e2b4f66ef7c077680739f1641f62f555", + "sha256:31a9ddf4718d10ae04d9b18801bd776693487cbb57d74cc3458a7673f6f34639", + "sha256:356541bf4381fa35856dafa6a965916e54bed415ad8a24ee6de6e37deccf2786", + "sha256:358a7c4cb8ba9b46c453b1dd8d9e431452d5249072e4f56cfda3149f6ab1405e", + "sha256:37f8febc8ec50c14f3ec9637505f28e58d4f66752207ea177c1d67df25da5aed", + "sha256:39049da0ffb96c8cbb65cbf5c5f3ca3168990adf3551bd1dee10c48fce8ae820", + "sha256:39cf9ed17fe3b1bc81f33c9ceb6ce67683ee7526e65fde1447c772afc54a1bb8", + "sha256:3ae1de54a77dc0d6d5fcf623290af4266412a7c4be0b1ff7444394f03f5c54e3", + "sha256:3b590df687e3c5ee0deef9fc8c547d81986d9a1b56073d82de008744452d6541", + "sha256:3e45867f1f2ab0711d60c6c71746ac53537f1684baa699f4f668d4c6f6ce8e14", + "sha256:3fc1c4a2ffd64890aebdb3f97e1278b0cc72579a08ca4de8cd2c04799a3a22be", + "sha256:4457ea6774b5611f4bed5eaa5df55f70abde42364d498c5134b7ef4c6958e20e", + "sha256:44ba614de5361b3e5278e1241fda3dc1838deed864b50a10d7ce92983797fa76", + "sha256:4a8fcf28c05c1f6d7e177a9a46a1c52798bfe2ad80681d275b10dcf317deaf0b", + "sha256:4b0d02d7102dd0f997580b51edc4cebcf2ab6397a7edf89f1c73b586c614272c", + "sha256:502218f52498a36d6bf5ea77081844017bf7982cdbe521ad85e64cabee1b608b", + "sha256:503e65837c71b875ecdd733877d852adbc465bd82c768a067badd953bf1bc5a3", + "sha256:5995f0164fa7df59db4746112fec3f49c461dd6b31b841873443bdb077c13cfc", + "sha256:59e5686dd847347e55dffcc191a96622f016bc0ad89105e24c14e0d6305acbc6", + "sha256:601f36512f9e28f029d9481bdaf8e89e5148ac5d89cffd3b05cd533eeb423b59", + "sha256:608862a7bf6957f2333fc54ab4399e405baad0163dc9f8d99cb236816db169d4", + "sha256:62595ab75873d50d57323a91dd03e6966eb79c41fa834b7a1661ed043b2d404d", + "sha256:70990b9c51340e4044cfc394a81f614f3f90d41397104d226f21e66de668730d", + "sha256:71140351489970dfe5e60fc621ada3e0f41104a5eddaca47a7acb3c1b851d6d3", + "sha256:72966d1b297c741541ca8cf1223ff262a6febe52481af742036a0b296e35fa5a", + "sha256:74292fc76c905c0ef095fe11e188a32ebd03bc38f3f3e9bcb85e4e6db177b7ea", + "sha256:761e8904c07ad053d285670f36dd94e1b6ab7f16ce62b9805c475b7aa1cffde6", + "sha256:772b87914ff1152b92a197ef4ea40efe27a378606c39446ded52c8f80f79702e", + "sha256:79909e27e8e4fcc9db4addea88aa63f6423ebb171db091fb4373e3312cb6d603", + "sha256:7e189e2e1d3ed2f4aebabd2d5b0f931e883676e51c7624826e0a4e5fe8a0bf24", + "sha256:7eb33a30d75562222b64f569c642ff3dc6689e09adda43a082208397f016c39a", + "sha256:81d6741ab457d14fdedc215516665050f3822d3e56508921cc7239f8c8e66a58", + "sha256:8499ca8f4502af841f68135133d8258f7b32a53a1d594aa98cc52013fff55678", + "sha256:84c3990934bae40ea69a82034912ffe5a62c60bbf6ec5bc9691419641d7d5c9a", + "sha256:87701167f2a5c930b403e9756fab1d31d4d4da52856143b609e30a1ce7160f3c", + "sha256:88600c72ef7587fe1708fd242b385b6ed4b8904976d5da0893e31df8b3480cb6", + "sha256:8ac7b6a045b814cf0c47f3623d21ebd88b3e8cf216a14790b455ea7ff0135d18", + "sha256:8b8af03d2e37866d023ad0ddea594edefc31e827fee64f8de5611a1dbc373174", + "sha256:8c7fe7afa480e3e82eed58e0ca89f751cd14d767638e2550c77a92a9e749c317", + "sha256:8eade758719add78ec36dc13201483f8e9b5d940329285edcd5f70c0a9edbd7f", + "sha256:911d8a40b2bef5b8bbae2e36a0b103f142ac53557ab421dc16ac4aafee6f53dc", + "sha256:93ad6d87ac18e2a90b0fe89df7c65263b9a99a0eb98f0a3d2e079f12a0735837", + "sha256:95dea361dd73757c6f1c0a1480ac499952c16ac83f7f5f4f84f0658a01b8ef41", + "sha256:9ab77acb98eba3fd2a85cd160851816bfce6871d944d885febf012713f06659c", + "sha256:9cb3032517f1627cc012dbc80a8ec976ae76d93ea2b5feaa9d2a5b8882597579", + "sha256:9cf4e8ad252f7c38dd1f676b46514f92dc0ebeb0db5552f5f403509705e24753", + "sha256:9d9153257a3f70d5f69edf2325357251ed20f772b12e593f3b3377b5f78e7ef8", + "sha256:a152f5f33d64a6be73f1d30c9cc82dfc73cec6477ec268e7c6e4c7d23c2d2291", + "sha256:a16418ecf1329f71df119e8a65f3aa68004a3f9383821edcb20f0702934d8087", + "sha256:a60332922359f920193b1d4826953c507a877b523b2395ad7bc716ddd386d866", + "sha256:a8d0fc946c784ff7f7c3742310cc8a57c5c6dc31631269876a88b809dbeff3d3", + "sha256:ab5de034a886f616a5668aa5d098af2b5385ed70142090e2a31bcbd0af0fdb3d", + "sha256:c22d3fe05ce11d3671297dc8973267daa0f938b93ec716e12e0f6dee81591dc1", + "sha256:c2ac1b08635a8cd4e0cbeaf6f5e922085908d48eb05d44c5ae9eabab148512ca", + "sha256:c512accbd6ff0270939b9ac214b84fb5ada5f0409c44298361b2f5e13f9aed9e", + "sha256:c75ffc45f25324e68ab238cb4b5c0a38cd1c3d7f1fb1f72b5541de469e2247db", + "sha256:c95a03c79bbe30eec3ec2b7f076074f4281526724c8685a42872974ef4d36b72", + "sha256:cadaeaba78750d58d3cc6ac4d1fd867da6fc73c88156b7a3212a3cd4819d679d", + "sha256:cd6056167405314a4dc3c173943f11249fa0f1b204f8b51ed4bde1a9cd1834dc", + "sha256:db72b07027db150f468fbada4d85b3b2729a3db39178abf5c543b784c1254539", + "sha256:df2c707231459e8a4028eabcd3cfc827befd635b3ef72eada84ab13b52e1574d", + "sha256:e62164b50f84e20601c1ff8eb55620d2ad25fb81b59e3cd776a1902527a788af", + "sha256:e696f0dd336161fca9adbb846875d40752e6eba585843c768935ba5c9960722b", + "sha256:eaa379fcd227ca235d04152ca6704c7cb55564116f8bc52545ff357628e10602", + "sha256:ebea339af930f8ca5d7a699b921106c6e29c617fe9606fa7baa043c1cdae326f", + "sha256:f4c39b0e3eac288fedc2b43055cfc2ca7a60362d0e5e87a637beac5d801ef478", + "sha256:f5057856d21e7586765171eac8b9fc3f7d44ef39425f85dbcccb13b3ebea806c", + "sha256:f6f45710b4459401609ebebdbcfb34515da4fc2aa886f95107f556ac69a9147e", + "sha256:f97e83fa6c25693c7a35de154681fcc257c1c41b38beb0304b9c4d2d9e164479", + "sha256:f9d0c5c045a3ca9bedfc35dca8526798eb91a07aa7a2c0fee134c6c6f321cbd7", + "sha256:ff6f3db31555657f3163b15a6b7c6938d08df7adbfc9dd13d9d19edad678f1e8" ], "markers": "python_version >= '3.6'", - "version": "==2.1.1" + "version": "==3.0.1" }, "click": { "hashes": [ @@ -130,11 +216,11 @@ }, "flask-migrate": { "hashes": [ - "sha256:57d6060839e3a7f150eaab6fe4e726d9e3e7cffe2150fb223d73f92421c6d1d9", - "sha256:a6498706241aba6be7a251078de9cf166d74307bca41a4ca3e403c9d39e2f897" + "sha256:73293d40b10ac17736e715b377e7b7bde474cb8105165d77474df4c3619b10b3", + "sha256:77580f27ab39bc68be4906a43c56d7674b45075bc4f883b1d0b985db5164d58f" ], "index": "pypi", - "version": "==3.1.0" + "version": "==4.0.4" }, "flask-sqlalchemy": { "hashes": [ @@ -154,27 +240,27 @@ }, "idna": { "hashes": [ - "sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff", - "sha256:9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d" + "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4", + "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2" ], "markers": "python_version >= '3.5'", - "version": "==3.3" + "version": "==3.4" }, "importlib-metadata": { "hashes": [ - "sha256:637245b8bab2b6502fcbc752cc4b7a6f6243bb02b31c5c26156ad103d3d45670", - "sha256:7401a975809ea1fdc658c3aa4f78cc2195a0e019c5cbc4c06122884e9ae80c23" + "sha256:7efb448ec9a5e313a57655d35aa54cd3e01b7e1fbcf72dce1bf06119420f5bad", + "sha256:e354bedeb60efa6affdcc8ae121b73544a7aa74156d047311948f6d711cd378d" ], "markers": "python_version < '3.9'", - "version": "==4.12.0" + "version": "==6.0.0" }, "importlib-resources": { "hashes": [ - "sha256:5481e97fb45af8dcf2f798952625591c58fe599d0735d86b10f54de086a61681", - "sha256:f78a8df21a79bcc30cfd400bdc38f314333de7c0fb619763f6b9dabab8268bb7" + "sha256:7d543798b0beca10b6a01ac7cafda9f822c54db9e8376a6bf57e0cbd74d486b6", + "sha256:e4a96c8cc0339647ff9a5e0550d9f276fc5a01ffa276012b58ec108cfd7b8484" ], "markers": "python_version < '3.9'", - "version": "==5.9.0" + "version": "==5.10.2" }, "itsdangerous": { "hashes": [ @@ -194,81 +280,91 @@ }, "jsonschema": { "hashes": [ - "sha256:21f4979391bdceb044e502fd8e79e738c0cdfbdc8773f9a49b5769461e82fe1e", - "sha256:2df0fab225abb3b41967bb3a46fd37dc74b1536b5296d0b1c2078cd072adf0f7" + "sha256:0f864437ab8b6076ba6707453ef8f98a6a0d512a80e93f8abdb676f737ecb60d", + "sha256:a870ad254da1a8ca84b6a2905cac29d265f805acc57af304784962a2aa6508f6" ], "markers": "python_version >= '3.7'", - "version": "==4.15.0" + "version": "==4.17.3" }, "limits": { "hashes": [ - "sha256:847a78b24a47e822a8f8713028a1340db44003763ab1cb90e798ccf462880355", - "sha256:cf043c376f14208a8204dc4cd74af1210fcaf24082bf7e3a38028706aa129899" + "sha256:3e12a0d90bc1fb7f3d95fe61c5a76770aaeb21d50f590268187a8884d513c1da", + "sha256:6fe1d261162ca6fd8023311273661a7355bc0f4615832bc9a4d6e45c0df59f5e" ], "markers": "python_version >= '3.7'", - "version": "==2.7.0" + "version": "==3.2.0" }, "mako": { "hashes": [ - "sha256:3724869b363ba630a272a5f89f68c070352137b8fd1757650017b7e06fda163f", - "sha256:8efcb8004681b5f71d09c983ad5a9e6f5c40601a6ec469148753292abc0da534" + "sha256:c97c79c018b9165ac9922ae4f32da095ffd3c4e6872b45eded42926deea46818", + "sha256:d60a3903dc3bb01a18ad6a89cdbe2e4eadc69c0bc8ef1e3773ba53d44c3f7a34" ], "markers": "python_version >= '3.7'", - "version": "==1.2.2" + "version": "==1.2.4" }, "markupsafe": { "hashes": [ - "sha256:0212a68688482dc52b2d45013df70d169f542b7394fc744c02a57374a4207003", - "sha256:089cf3dbf0cd6c100f02945abeb18484bd1ee57a079aefd52cffd17fba910b88", - "sha256:10c1bfff05d95783da83491be968e8fe789263689c02724e0c691933c52994f5", - "sha256:33b74d289bd2f5e527beadcaa3f401e0df0a89927c1559c8566c066fa4248ab7", - "sha256:3799351e2336dc91ea70b034983ee71cf2f9533cdff7c14c90ea126bfd95d65a", - "sha256:3ce11ee3f23f79dbd06fb3d63e2f6af7b12db1d46932fe7bd8afa259a5996603", - "sha256:421be9fbf0ffe9ffd7a378aafebbf6f4602d564d34be190fc19a193232fd12b1", - "sha256:43093fb83d8343aac0b1baa75516da6092f58f41200907ef92448ecab8825135", - "sha256:46d00d6cfecdde84d40e572d63735ef81423ad31184100411e6e3388d405e247", - "sha256:4a33dea2b688b3190ee12bd7cfa29d39c9ed176bda40bfa11099a3ce5d3a7ac6", - "sha256:4b9fe39a2ccc108a4accc2676e77da025ce383c108593d65cc909add5c3bd601", - "sha256:56442863ed2b06d19c37f94d999035e15ee982988920e12a5b4ba29b62ad1f77", - "sha256:671cd1187ed5e62818414afe79ed29da836dde67166a9fac6d435873c44fdd02", - "sha256:694deca8d702d5db21ec83983ce0bb4b26a578e71fbdbd4fdcd387daa90e4d5e", - "sha256:6a074d34ee7a5ce3effbc526b7083ec9731bb3cbf921bbe1d3005d4d2bdb3a63", - "sha256:6d0072fea50feec76a4c418096652f2c3238eaa014b2f94aeb1d56a66b41403f", - "sha256:6fbf47b5d3728c6aea2abb0589b5d30459e369baa772e0f37a0320185e87c980", - "sha256:7f91197cc9e48f989d12e4e6fbc46495c446636dfc81b9ccf50bb0ec74b91d4b", - "sha256:86b1f75c4e7c2ac2ccdaec2b9022845dbb81880ca318bb7a0a01fbf7813e3812", - "sha256:8dc1c72a69aa7e082593c4a203dcf94ddb74bb5c8a731e4e1eb68d031e8498ff", - "sha256:8e3dcf21f367459434c18e71b2a9532d96547aef8a871872a5bd69a715c15f96", - "sha256:8e576a51ad59e4bfaac456023a78f6b5e6e7651dcd383bcc3e18d06f9b55d6d1", - "sha256:96e37a3dc86e80bf81758c152fe66dbf60ed5eca3d26305edf01892257049925", - "sha256:97a68e6ada378df82bc9f16b800ab77cbf4b2fada0081794318520138c088e4a", - "sha256:99a2a507ed3ac881b975a2976d59f38c19386d128e7a9a18b7df6fff1fd4c1d6", - "sha256:a49907dd8420c5685cfa064a1335b6754b74541bbb3706c259c02ed65b644b3e", - "sha256:b09bf97215625a311f669476f44b8b318b075847b49316d3e28c08e41a7a573f", - "sha256:b7bd98b796e2b6553da7225aeb61f447f80a1ca64f41d83612e6139ca5213aa4", - "sha256:b87db4360013327109564f0e591bd2a3b318547bcef31b468a92ee504d07ae4f", - "sha256:bcb3ed405ed3222f9904899563d6fc492ff75cce56cba05e32eff40e6acbeaa3", - "sha256:d4306c36ca495956b6d568d276ac11fdd9c30a36f1b6eb928070dc5360b22e1c", - "sha256:d5ee4f386140395a2c818d149221149c54849dfcfcb9f1debfe07a8b8bd63f9a", - "sha256:dda30ba7e87fbbb7eab1ec9f58678558fd9a6b8b853530e176eabd064da81417", - "sha256:e04e26803c9c3851c931eac40c695602c6295b8d432cbe78609649ad9bd2da8a", - "sha256:e1c0b87e09fa55a220f058d1d49d3fb8df88fbfab58558f1198e08c1e1de842a", - "sha256:e72591e9ecd94d7feb70c1cbd7be7b3ebea3f548870aa91e2732960fa4d57a37", - "sha256:e8c843bbcda3a2f1e3c2ab25913c80a3c5376cd00c6e8c4a86a89a28c8dc5452", - "sha256:efc1913fd2ca4f334418481c7e595c00aad186563bbc1ec76067848c7ca0a933", - "sha256:f121a1420d4e173a5d96e47e9a0c0dcff965afdf1626d28de1460815f7c4ee7a", - "sha256:fc7b548b17d238737688817ab67deebb30e8073c95749d55538ed473130ec0c7" + "sha256:0576fe974b40a400449768941d5d0858cc624e3249dfd1e0c33674e5c7ca7aed", + "sha256:085fd3201e7b12809f9e6e9bc1e5c96a368c8523fad5afb02afe3c051ae4afcc", + "sha256:090376d812fb6ac5f171e5938e82e7f2d7adc2b629101cec0db8b267815c85e2", + "sha256:0b462104ba25f1ac006fdab8b6a01ebbfbce9ed37fd37fd4acd70c67c973e460", + "sha256:137678c63c977754abe9086a3ec011e8fd985ab90631145dfb9294ad09c102a7", + "sha256:1bea30e9bf331f3fef67e0a3877b2288593c98a21ccb2cf29b74c581a4eb3af0", + "sha256:22152d00bf4a9c7c83960521fc558f55a1adbc0631fbb00a9471e097b19d72e1", + "sha256:22731d79ed2eb25059ae3df1dfc9cb1546691cc41f4e3130fe6bfbc3ecbbecfa", + "sha256:2298c859cfc5463f1b64bd55cb3e602528db6fa0f3cfd568d3605c50678f8f03", + "sha256:28057e985dace2f478e042eaa15606c7efccb700797660629da387eb289b9323", + "sha256:2e7821bffe00aa6bd07a23913b7f4e01328c3d5cc0b40b36c0bd81d362faeb65", + "sha256:2ec4f2d48ae59bbb9d1f9d7efb9236ab81429a764dedca114f5fdabbc3788013", + "sha256:340bea174e9761308703ae988e982005aedf427de816d1afe98147668cc03036", + "sha256:40627dcf047dadb22cd25ea7ecfe9cbf3bbbad0482ee5920b582f3809c97654f", + "sha256:40dfd3fefbef579ee058f139733ac336312663c6706d1163b82b3003fb1925c4", + "sha256:4cf06cdc1dda95223e9d2d3c58d3b178aa5dacb35ee7e3bbac10e4e1faacb419", + "sha256:50c42830a633fa0cf9e7d27664637532791bfc31c731a87b202d2d8ac40c3ea2", + "sha256:55f44b440d491028addb3b88f72207d71eeebfb7b5dbf0643f7c023ae1fba619", + "sha256:608e7073dfa9e38a85d38474c082d4281f4ce276ac0010224eaba11e929dd53a", + "sha256:63ba06c9941e46fa389d389644e2d8225e0e3e5ebcc4ff1ea8506dce646f8c8a", + "sha256:65608c35bfb8a76763f37036547f7adfd09270fbdbf96608be2bead319728fcd", + "sha256:665a36ae6f8f20a4676b53224e33d456a6f5a72657d9c83c2aa00765072f31f7", + "sha256:6d6607f98fcf17e534162f0709aaad3ab7a96032723d8ac8750ffe17ae5a0666", + "sha256:7313ce6a199651c4ed9d7e4cfb4aa56fe923b1adf9af3b420ee14e6d9a73df65", + "sha256:7668b52e102d0ed87cb082380a7e2e1e78737ddecdde129acadb0eccc5423859", + "sha256:7df70907e00c970c60b9ef2938d894a9381f38e6b9db73c5be35e59d92e06625", + "sha256:7e007132af78ea9df29495dbf7b5824cb71648d7133cf7848a2a5dd00d36f9ff", + "sha256:835fb5e38fd89328e9c81067fd642b3593c33e1e17e2fdbf77f5676abb14a156", + "sha256:8bca7e26c1dd751236cfb0c6c72d4ad61d986e9a41bbf76cb445f69488b2a2bd", + "sha256:8db032bf0ce9022a8e41a22598eefc802314e81b879ae093f36ce9ddf39ab1ba", + "sha256:99625a92da8229df6d44335e6fcc558a5037dd0a760e11d84be2260e6f37002f", + "sha256:9cad97ab29dfc3f0249b483412c85c8ef4766d96cdf9dcf5a1e3caa3f3661cf1", + "sha256:a4abaec6ca3ad8660690236d11bfe28dfd707778e2442b45addd2f086d6ef094", + "sha256:a6e40afa7f45939ca356f348c8e23048e02cb109ced1eb8420961b2f40fb373a", + "sha256:a6f2fcca746e8d5910e18782f976489939d54a91f9411c32051b4aab2bd7c513", + "sha256:a806db027852538d2ad7555b203300173dd1b77ba116de92da9afbc3a3be3eed", + "sha256:abcabc8c2b26036d62d4c746381a6f7cf60aafcc653198ad678306986b09450d", + "sha256:b8526c6d437855442cdd3d87eede9c425c4445ea011ca38d937db299382e6fa3", + "sha256:bb06feb762bade6bf3c8b844462274db0c76acc95c52abe8dbed28ae3d44a147", + "sha256:c0a33bc9f02c2b17c3ea382f91b4db0e6cde90b63b296422a939886a7a80de1c", + "sha256:c4a549890a45f57f1ebf99c067a4ad0cb423a05544accaf2b065246827ed9603", + "sha256:ca244fa73f50a800cf8c3ebf7fd93149ec37f5cb9596aa8873ae2c1d23498601", + "sha256:cf877ab4ed6e302ec1d04952ca358b381a882fbd9d1b07cccbfd61783561f98a", + "sha256:d9d971ec1e79906046aa3ca266de79eac42f1dbf3612a05dc9368125952bd1a1", + "sha256:da25303d91526aac3672ee6d49a2f3db2d9502a4a60b55519feb1a4c7714e07d", + "sha256:e55e40ff0cc8cc5c07996915ad367fa47da6b3fc091fdadca7f5403239c5fec3", + "sha256:f03a532d7dee1bed20bc4884194a16160a2de9ffc6354b3878ec9682bb623c54", + "sha256:f1cd098434e83e656abf198f103a8207a8187c0fc110306691a2e94a78d0abb2", + "sha256:f2bfb563d0211ce16b63c7cb9395d2c682a23187f54c3d79bfec33e6705473c6", + "sha256:f8ffb705ffcf5ddd0e80b65ddf7bed7ee4f5a441ea7d3419e861a12eaf41af58" ], "markers": "python_version >= '3.7'", - "version": "==2.1.1" + "version": "==2.1.2" }, "marshmallow": { "hashes": [ - "sha256:1172ce82765bf26c24a3f9299ed6dbeeca4d213f638eaa39a37772656d7ce408", - "sha256:48e2d88d4ab431ad5a17c25556d9da529ea6e966876f2a38d274082e270287f0" + "sha256:90032c0fd650ce94b6ec6dc8dfeb0e3ff50c144586462c389b81a07205bedb78", + "sha256:93f0958568da045b0021ec6aeb7ac37c81bfcccbb9a0e7ed8559885070b3a19b" ], "markers": "python_version >= '3.7'", - "version": "==3.17.1" + "version": "==3.19.0" }, "marshmallow-sqlalchemy": { "hashes": [ @@ -280,45 +376,49 @@ }, "mistune": { "hashes": [ - "sha256:182cc5ee6f8ed1b807de6b7bb50155df7b66495412836b9a74c8fbdfc75fe36d", - "sha256:9ee0a66053e2267aba772c71e06891fa8f1af6d4b01d5e84e267b4570d4d9808" + "sha256:0246113cb2492db875c6be56974a7c893333bf26cd92891c85f63151cee09d34", + "sha256:bad7f5d431886fcbaf5f758118ecff70d31f75231b34024a1341120340a65ce8" ], - "version": "==2.0.4" + "version": "==2.0.5" }, "mysql-connector-python": { "hashes": [ - "sha256:1d9d3af14594aceda2c3096564b4c87ffac21e375806a802daeaf7adcd18d36b", - "sha256:234c6b156a1989bebca6eb564dc8f2e9d352f90a51bd228ccd68eb66fcd5fd7a", - "sha256:33c4e567547a9a1868462fda8f2b19ea186a7b1afe498171dca39c0f3aa43a75", - "sha256:36e763f21e62b3c9623a264f2513ee11924ea1c9cc8640c115a279d3087064be", - "sha256:41a04d1900e366bf6c2a645ead89ab9a567806d5ada7d417a3a31f170321dd14", - "sha256:47deb8c3324db7eb2bfb720ec8084d547b1bce457672ea261bc21836024249db", - "sha256:59a8592e154c874c299763bb8aa12c518384c364bcfd0d193e85c869ea81a895", - "sha256:611c6945805216104575f7143ff6497c87396ce82d3257e6da7257b65406f13e", - "sha256:62266d1b18cb4e286a05df0e1c99163a4955c82d41045305bcf0ab2aac107843", - "sha256:712cdfa97f35fec715e8d7aaa15ed9ce04f3cf71b3c177fcca273047040de9f2", - "sha256:7f771bd5cba3ade6d9f7a649e65d7c030f69f0e69980632b5cbbd3d19c39cee5", - "sha256:8876b1d51cae33cdfe7021d68206661e94dcd2666e5e14a743f8321e2b068e84", - "sha256:8b7d50c221320b0e609dce9ca8801ab2f2a748dfee65cd76b1e4c6940757734a", - "sha256:954a1fc2e9a811662c5b17cea24819c020ff9d56b2ff8e583dd0a233fb2399f6", - "sha256:a130c5489861c7ff2990e5b503c37beb2fb7b32211b92f9107ad864ee90654c0", - "sha256:b5dc0f3295e404f93b674bfaff7589a9fbb8b5ae6c1c134112a1d1beb2f664b2", - "sha256:ce23ca9c27e1f7b4707b3299ce515125f312736d86a7e5b2aa778484fa3ffa10", - "sha256:d8f74c9388176635f75c01d47d0abc783a47e58d7f36d04fb6ee40ab6fb35c9b", - "sha256:f1d40cac9c786e292433716c1ade7a8968cbc3ea177026697b86a63188ddba34", - "sha256:f1eb74eb30bb04ff314f5e19af5421d23b504e41d16ddcee2603b4100d18fd68", - "sha256:f5d812245754d4759ebc8c075662fef65397e1e2a438a3c391eac9d545077b8b" + "sha256:145aeb75eefb7425e0a7fb36a4f95ebfe79e06be7c69a4045d34cde95c666dc4", + "sha256:1c0a11f3ffbf850f2ca7b39e6c82021e8de910ddaeffd856e53dca028d21c923", + "sha256:1f399f3c2599d2591854cd0e0a24c7c399dff21ac5accb6e52e06924de29f3f4", + "sha256:232095f0c36266510009b0f1214d2823a649efb8bc511dbab9ce8847f66ab08a", + "sha256:283fe6f647e9d684feb1b7c48fa6a46b1e72c59ecdd6ea2b62392cd80c1a6701", + "sha256:4b2d00c9e2cb9e3d11c57ec411226f43aa627607085fbed661cfea1c4dc57f61", + "sha256:4df11c683924ef34c177a54887dc4844ae735b01c8a29ce6ab92d6d3db7a2757", + "sha256:677b5c6dcaec7e2a4bf95b991a869f4d371114f69a0d9a5bb236e988c8f4c376", + "sha256:6cdba2779bcd16af0ceff0a6e50d33e6664a83f8d17d70524beb6f677a6d1fae", + "sha256:7f7a69db9e0c36764a6c65377f6174aee46e484520e48659e7aa674415b8e192", + "sha256:8c334c41cd1c5bcfa3550340253ef7d9d3b962211f33327c20f69706a0bcce06", + "sha256:8c5bfedc979d7858402f39c20d66a6cf03ca4c960732a98318126c278535ddb2", + "sha256:93b1eb3e07d19a23ccf2605d818aacee0d842b1820bbeef8d0022d8d3d014ab9", + "sha256:992b7a464daa398e86df8c75f7d8cd6044f884ff9087e782120fc8beff96c638", + "sha256:ab13dd6ede0e0e99ba97c73946462c3420625ab6e63fe13b6fc350e30eb3298d", + "sha256:bd52a462759aa324a60054c4b44dc8b32007187a328f72be6b58f193d5e32a91", + "sha256:bdd716b1e162fe4b3887f6617e9ddcfa659ba96a9ddb22feeae208a72f43d22f", + "sha256:be82357cc7e7e1377e2f4f8c18aa89c8aab6c0117155cf9fcf18e3cd0eb6ac8e", + "sha256:c2d20b29fd096a0633f9360c275bd2434d4bcf597281991c4b7f1c820cd07b84", + "sha256:c8bba02501525e1fbbba094a6d8d391d1534e8be41be6396c3e1b9f7d9d13b1c", + "sha256:c990f4c0702d1739076261c4dece1042e1eb18bf34e0d8516d19ec5166a205ce", + "sha256:d6b54656ca131a4f0f17b9d0adddc60f84fd982d64e06360026d5b06e5dbf865", + "sha256:e0299236297b63bf6cbb61d81a9d400bc01cad4743d1abe5296ef349de15ee53", + "sha256:e722b6ffa5b0d7188eebac792b18bc871643db505bf60d0e6bd2859f31e5ed79", + "sha256:fd233c83daaf048c1f9827be984c2721576ae0adf50e139429a06ccd094987d9" ], "index": "pypi", - "version": "==8.0.30" + "version": "==8.0.32" }, "packaging": { "hashes": [ - "sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb", - "sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522" + "sha256:714ac14496c3e68c99c29b00845f7a2b85f3bb6f1078fd9f72fd20f0570002b2", + "sha256:b6ad297f8907de0fa2fe1ccbd26fdaf387f5f47c7275fedf8cce89f99446cf97" ], - "markers": "python_version >= '3.6'", - "version": "==21.3" + "markers": "python_version >= '3.7'", + "version": "==23.0" }, "pkgutil-resolve-name": { "hashes": [ @@ -330,33 +430,31 @@ }, "protobuf": { "hashes": [ - "sha256:06059eb6953ff01e56a25cd02cca1a9649a75a7e65397b5b9b4e929ed71d10cf", - "sha256:097c5d8a9808302fb0da7e20edf0b8d4703274d140fd25c5edabddcde43e081f", - "sha256:284f86a6207c897542d7e956eb243a36bb8f9564c1742b253462386e96c6b78f", - "sha256:32ca378605b41fd180dfe4e14d3226386d8d1b002ab31c969c366549e66a2bb7", - "sha256:3cc797c9d15d7689ed507b165cd05913acb992d78b379f6014e013f9ecb20996", - "sha256:62f1b5c4cd6c5402b4e2d63804ba49a327e0c386c99b1675c8a0fefda23b2067", - "sha256:69ccfdf3657ba59569c64295b7d51325f91af586f8d5793b734260dfe2e94e2c", - "sha256:6f50601512a3d23625d8a85b1638d914a0970f17920ff39cec63aaef80a93fb7", - "sha256:7403941f6d0992d40161aa8bb23e12575637008a5a02283a930addc0508982f9", - "sha256:755f3aee41354ae395e104d62119cb223339a8f3276a0cd009ffabfcdd46bb0c", - "sha256:77053d28427a29987ca9caf7b72ccafee011257561259faba8dd308fda9a8739", - "sha256:7e371f10abe57cee5021797126c93479f59fccc9693dafd6bd5633ab67808a91", - "sha256:9016d01c91e8e625141d24ec1b20fed584703e527d28512aa8c8707f105a683c", - "sha256:9be73ad47579abc26c12024239d3540e6b765182a91dbc88e23658ab71767153", - "sha256:adc31566d027f45efe3f44eeb5b1f329da43891634d61c75a5944e9be6dd42c9", - "sha256:adfc6cf69c7f8c50fd24c793964eef18f0ac321315439d94945820612849c388", - "sha256:af0ebadc74e281a517141daad9d0f2c5d93ab78e9d455113719a45a49da9db4e", - "sha256:cb29edb9eab15742d791e1025dd7b6a8f6fcb53802ad2f6e3adcb102051063ab", - "sha256:cd68be2559e2a3b84f517fb029ee611546f7812b1fdd0aa2ecc9bc6ec0e4fdde", - "sha256:cdee09140e1cd184ba9324ec1df410e7147242b94b5f8b0c64fc89e38a8ba531", - "sha256:db977c4ca738dd9ce508557d4fce0f5aebd105e158c725beec86feb1f6bc20d8", - "sha256:dd5789b2948ca702c17027c84c2accb552fc30f4622a98ab5c51fcfe8c50d3e7", - "sha256:e250a42f15bf9d5b09fe1b293bdba2801cd520a9f5ea2d7fb7536d4441811d20", - "sha256:ff8d8fa42675249bb456f5db06c00de6c2f4c27a065955917b28c4f15978b9c3" + "sha256:03038ac1cfbc41aa21f6afcbcd357281d7521b4157926f30ebecc8d4ea59dcb7", + "sha256:28545383d61f55b57cf4df63eebd9827754fd2dc25f80c5253f9184235db242c", + "sha256:2e3427429c9cffebf259491be0af70189607f365c2f41c7c3764af6f337105f2", + "sha256:398a9e0c3eaceb34ec1aee71894ca3299605fa8e761544934378bbc6c97de23b", + "sha256:44246bab5dd4b7fbd3c0c80b6f16686808fab0e4aca819ade6e8d294a29c7050", + "sha256:447d43819997825d4e71bf5769d869b968ce96848b6479397e29fc24c4a5dfe9", + "sha256:67a3598f0a2dcbc58d02dd1928544e7d88f764b47d4a286202913f0b2801c2e7", + "sha256:74480f79a023f90dc6e18febbf7b8bac7508420f2006fabd512013c0c238f454", + "sha256:819559cafa1a373b7096a482b504ae8a857c89593cf3a25af743ac9ecbd23480", + "sha256:899dc660cd599d7352d6f10d83c95df430a38b410c1b66b407a6b29265d66469", + "sha256:8c0c984a1b8fef4086329ff8dd19ac77576b384079247c770f29cc8ce3afa06c", + "sha256:9aae4406ea63d825636cc11ffb34ad3379335803216ee3a856787bcf5ccc751e", + "sha256:a7ca6d488aa8ff7f329d4c545b2dbad8ac31464f1d8b1c87ad1346717731e4db", + "sha256:b6cc7ba72a8850621bfec987cb72623e703b7fe2b9127a161ce61e61558ad905", + "sha256:bf01b5720be110540be4286e791db73f84a2b721072a3711efff6c324cdf074b", + "sha256:c02ce36ec760252242a33967d51c289fd0e1c0e6e5cc9397e2279177716add86", + "sha256:d9e4432ff660d67d775c66ac42a67cf2453c27cb4d738fc22cb53b5d84c135d4", + "sha256:daa564862dd0d39c00f8086f88700fdbe8bc717e993a21e90711acfed02f2402", + "sha256:de78575669dddf6099a8a0f46a27e82a1783c557ccc38ee620ed8cc96d3be7d7", + "sha256:e64857f395505ebf3d2569935506ae0dfc4a15cb80dc25261176c784662cdcc4", + "sha256:f4bd856d702e5b0d96a00ec6b307b0f51c1982c2bf9c0052cf9019e9a544ba99", + "sha256:f4c42102bc82a51108e449cbb32b19b180022941c727bac0cfd50170341f16ee" ], "markers": "python_version >= '3.7'", - "version": "==3.20.1" + "version": "==3.20.3" }, "pyasn1": { "hashes": [ @@ -376,48 +474,46 @@ ], "version": "==0.4.8" }, - "pyparsing": { - "hashes": [ - "sha256:2b020ecf7d21b687f219b71ecad3631f644a47f01403fa1d1036b0c6416d70fb", - "sha256:5026bae9a10eeaefb61dab2f09052b9f4307d44aee4eda64b309723d8d206bbc" - ], - "markers": "python_full_version >= '3.6.8'", - "version": "==3.0.9" - }, "pyrsistent": { "hashes": [ - "sha256:0e3e1fcc45199df76053026a51cc59ab2ea3fc7c094c6627e93b7b44cdae2c8c", - "sha256:1b34eedd6812bf4d33814fca1b66005805d3640ce53140ab8bbb1e2651b0d9bc", - "sha256:4ed6784ceac462a7d6fcb7e9b663e93b9a6fb373b7f43594f9ff68875788e01e", - "sha256:5d45866ececf4a5fff8742c25722da6d4c9e180daa7b405dc0a2a2790d668c26", - "sha256:636ce2dc235046ccd3d8c56a7ad54e99d5c1cd0ef07d9ae847306c91d11b5fec", - "sha256:6455fc599df93d1f60e1c5c4fe471499f08d190d57eca040c0ea182301321286", - "sha256:6bc66318fb7ee012071b2792024564973ecc80e9522842eb4e17743604b5e045", - "sha256:7bfe2388663fd18bd8ce7db2c91c7400bf3e1a9e8bd7d63bf7e77d39051b85ec", - "sha256:7ec335fc998faa4febe75cc5268a9eac0478b3f681602c1f27befaf2a1abe1d8", - "sha256:914474c9f1d93080338ace89cb2acee74f4f666fb0424896fcfb8d86058bf17c", - "sha256:b568f35ad53a7b07ed9b1b2bae09eb15cdd671a5ba5d2c66caee40dbf91c68ca", - "sha256:cdfd2c361b8a8e5d9499b9082b501c452ade8bbf42aef97ea04854f4a3f43b22", - "sha256:d1b96547410f76078eaf66d282ddca2e4baae8964364abb4f4dcdde855cd123a", - "sha256:d4d61f8b993a7255ba714df3aca52700f8125289f84f704cf80916517c46eb96", - "sha256:d7a096646eab884bf8bed965bad63ea327e0d0c38989fc83c5ea7b8a87037bfc", - "sha256:df46c854f490f81210870e509818b729db4488e1f30f2a1ce1698b2295a878d1", - "sha256:e24a828f57e0c337c8d8bb9f6b12f09dfdf0273da25fda9e314f0b684b415a07", - "sha256:e4f3149fd5eb9b285d6bfb54d2e5173f6a116fe19172686797c056672689daf6", - "sha256:e92a52c166426efbe0d1ec1332ee9119b6d32fc1f0bbfd55d5c1088070e7fc1b", - "sha256:f87cc2863ef33c709e237d4b5f4502a62a00fab450c9e020892e8e2ede5847f5", - "sha256:fd8da6d0124efa2f67d86fa70c851022f87c98e205f0594e1fae044e7119a5a6" + "sha256:016ad1afadf318eb7911baa24b049909f7f3bb2c5b1ed7b6a8f21db21ea3faa8", + "sha256:1a2994773706bbb4995c31a97bc94f1418314923bd1048c6d964837040376440", + "sha256:20460ac0ea439a3e79caa1dbd560344b64ed75e85d8703943e0b66c2a6150e4a", + "sha256:3311cb4237a341aa52ab8448c27e3a9931e2ee09561ad150ba94e4cfd3fc888c", + "sha256:3a8cb235fa6d3fd7aae6a4f1429bbb1fec1577d978098da1252f0489937786f3", + "sha256:3ab2204234c0ecd8b9368dbd6a53e83c3d4f3cab10ecaf6d0e772f456c442393", + "sha256:42ac0b2f44607eb92ae88609eda931a4f0dfa03038c44c772e07f43e738bcac9", + "sha256:49c32f216c17148695ca0e02a5c521e28a4ee6c5089f97e34fe24163113722da", + "sha256:4b774f9288dda8d425adb6544e5903f1fb6c273ab3128a355c6b972b7df39dcf", + "sha256:4c18264cb84b5e68e7085a43723f9e4c1fd1d935ab240ce02c0324a8e01ccb64", + "sha256:5a474fb80f5e0d6c9394d8db0fc19e90fa540b82ee52dba7d246a7791712f74a", + "sha256:64220c429e42a7150f4bfd280f6f4bb2850f95956bde93c6fda1b70507af6ef3", + "sha256:878433581fc23e906d947a6814336eee031a00e6defba224234169ae3d3d6a98", + "sha256:99abb85579e2165bd8522f0c0138864da97847875ecbd45f3e7e2af569bfc6f2", + "sha256:a2471f3f8693101975b1ff85ffd19bb7ca7dd7c38f8a81701f67d6b4f97b87d8", + "sha256:aeda827381f5e5d65cced3024126529ddc4289d944f75e090572c77ceb19adbf", + "sha256:b735e538f74ec31378f5a1e3886a26d2ca6351106b4dfde376a26fc32a044edc", + "sha256:c147257a92374fde8498491f53ffa8f4822cd70c0d85037e09028e478cababb7", + "sha256:c4db1bd596fefd66b296a3d5d943c94f4fac5bcd13e99bffe2ba6a759d959a28", + "sha256:c74bed51f9b41c48366a286395c67f4e894374306b197e62810e0fdaf2364da2", + "sha256:c9bb60a40a0ab9aba40a59f68214eed5a29c6274c83b2cc206a359c4a89fa41b", + "sha256:cc5d149f31706762c1f8bda2e8c4f8fead6e80312e3692619a75301d3dbb819a", + "sha256:ccf0d6bd208f8111179f0c26fdf84ed7c3891982f2edaeae7422575f47e66b64", + "sha256:e42296a09e83028b3476f7073fcb69ffebac0e66dbbfd1bd847d61f74db30f19", + "sha256:e8f2b814a3dc6225964fa03d8582c6e0b6650d68a232df41e3cc1b66a5d2f8d1", + "sha256:f0774bf48631f3a20471dd7c5989657b639fd2d285b861237ea9e82c36a415a9", + "sha256:f0e7c4b2f77593871e918be000b96c8107da48444d57005b6a6bc61fb4331b2c" ], "markers": "python_version >= '3.7'", - "version": "==0.18.1" + "version": "==0.19.3" }, "python-dotenv": { "hashes": [ - "sha256:1684eb44636dd462b66c3ee016599815514527ad99965de77f43e0944634a7e5", - "sha256:b77d08274639e3d34145dfa6c7008e66df0f04b7be7a75fd0d5292c191d79045" + "sha256:1c93de8f636cde3ce377292818d0e440b6e45a82f215c3744979151fa8151c49", + "sha256:41e12e0318bebc859fcc4d97d4db8d20ad21721a6aa5047dd59f090391cb549a" ], "index": "pypi", - "version": "==0.21.0" + "version": "==0.21.1" }, "python-jose": { "hashes": [ @@ -429,6 +525,7 @@ }, "pyyaml": { "hashes": [ + "sha256:01b45c0191e6d66c470b6cf1b9531a771a83c1c4208272ead47a3ae4f2f603bf", "sha256:0283c35a6a9fbf047493e3a0ce8d79ef5030852c51e9d911a27badfde0605293", "sha256:055d937d65826939cb044fc8c9b08889e8c743fdc6a32b33e2390f66013e449b", "sha256:07751360502caac1c067a8132d150cf3d61339af5691fe9e87803040dbc5db57", @@ -440,26 +537,32 @@ "sha256:277a0ef2981ca40581a47093e9e2d13b3f1fbbeffae064c1d21bfceba2030287", "sha256:2cd5df3de48857ed0544b34e2d40e9fac445930039f3cfe4bcc592a1f836d513", "sha256:40527857252b61eacd1d9af500c3337ba8deb8fc298940291486c465c8b46ec0", + "sha256:432557aa2c09802be39460360ddffd48156e30721f5e8d917f01d31694216782", "sha256:473f9edb243cb1935ab5a084eb238d842fb8f404ed2193a915d1784b5a6b5fc0", "sha256:48c346915c114f5fdb3ead70312bd042a953a8ce5c7106d5bfb1a5254e47da92", "sha256:50602afada6d6cbfad699b0c7bb50d5ccffa7e46a3d738092afddc1f9758427f", "sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2", "sha256:77f396e6ef4c73fdc33a9157446466f1cff553d979bd00ecb64385760c6babdc", + "sha256:81957921f441d50af23654aa6c5e5eaf9b06aba7f0a19c18a538dc7ef291c5a1", "sha256:819b3830a1543db06c4d4b865e70ded25be52a2e0631ccd2f6a47a2822f2fd7c", "sha256:897b80890765f037df3403d22bab41627ca8811ae55e9a722fd0392850ec4d86", "sha256:98c4d36e99714e55cfbaaee6dd5badbc9a1ec339ebfc3b1f52e293aee6bb71a4", "sha256:9df7ed3b3d2e0ecfe09e14741b857df43adb5a3ddadc919a2d94fbdf78fea53c", "sha256:9fa600030013c4de8165339db93d182b9431076eb98eb40ee068700c9c813e34", "sha256:a80a78046a72361de73f8f395f1f1e49f956c6be882eed58505a15f3e430962b", + "sha256:afa17f5bc4d1b10afd4466fd3a44dc0e245382deca5b3c353d8b757f9e3ecb8d", "sha256:b3d267842bf12586ba6c734f89d1f5b871df0273157918b0ccefa29deb05c21c", "sha256:b5b9eccad747aabaaffbc6064800670f0c297e52c12754eb1d976c57e4f74dcb", + "sha256:bfaef573a63ba8923503d27530362590ff4f576c626d86a9fed95822a8255fd7", "sha256:c5687b8d43cf58545ade1fe3e055f70eac7a5a1a0bf42824308d868289a95737", "sha256:cba8c411ef271aa037d7357a2bc8f9ee8b58b9965831d9e51baf703280dc73d3", "sha256:d15a181d1ecd0d4270dc32edb46f7cb7733c7c508857278d3d378d14d606db2d", + "sha256:d4b0ba9512519522b118090257be113b9468d804b19d63c71dbcf4a48fa32358", "sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53", "sha256:d4eccecf9adf6fbcc6861a38015c2a64f38b9d94838ac1810a9023a0609e1b78", "sha256:d67d839ede4ed1b28a4e8909735fc992a923cdb84e618544973d7dfc71540803", "sha256:daf496c58a8c52083df09b80c860005194014c3698698d1a57cbcfa182142a3a", + "sha256:dbad0e9d368bb989f4515da330b88a057617d16b6a8245084f1b05400f24609f", "sha256:e61ceaab6f49fb8bdfaa0f92c4b57bcfbea54c09277b1b4f7ac376bfb7a7c174", "sha256:f84fbc98b019fef2ee9a1cb3ce93e3187a6df0b2538a651bfb890254ba9f90b5" ], @@ -468,11 +571,11 @@ }, "requests": { "hashes": [ - "sha256:7c5599b102feddaa661c826c56ab4fee28bfd17f5abca1ebbe3e7f19d7c97983", - "sha256:8fefa2a1a1365bf5520aac41836fbee479da67864514bdb821f31ce07ce65349" + "sha256:64299f4909223da747622c030b781c0d7811e359c37124b4bd368fb8c6518baa", + "sha256:98b1b2782e3c6c4904938b84c0eb932721069dfdb9134313beff7c83c2df24bf" ], "index": "pypi", - "version": "==2.28.1" + "version": "==2.28.2" }, "rsa": { "hashes": [ @@ -482,13 +585,21 @@ "markers": "python_version >= '3.6' and python_version < '4'", "version": "==4.9" }, + "sentry-sdk": { + "hashes": [ + "sha256:69ecbb2e1ff4db02a06c4f20f6f69cb5dfe3ebfbc06d023e40d77cf78e9c37e7", + "sha256:7ad4d37dd093f4a7cb5ad804c6efe9e8fab8873f7ffc06042dc3f3fd700a93ec" + ], + "index": "pypi", + "version": "==1.15.0" + }, "setuptools": { "hashes": [ - "sha256:2e24e0bec025f035a2e72cdd1961119f557d78ad331bb00ff82efb2ab8da8e82", - "sha256:7732871f4f7fa58fb6bdcaeadb0161b2bd046c85905dbaa066bdcbcc81953b57" + "sha256:95f00380ef2ffa41d9bba85d95b27689d923c93dfbafed4aecd7cf988a25e012", + "sha256:bb6d8e508de562768f2027902929f8523932fcd1fb784e6d573d2cafac995a48" ], "markers": "python_version >= '3.7'", - "version": "==65.3.0" + "version": "==67.3.2" }, "six": { "hashes": [ @@ -540,27 +651,27 @@ }, "typing-extensions": { "hashes": [ - "sha256:25642c956049920a5aa49edcdd6ab1e06d7e5d467fc00e0506c44ac86fbfca02", - "sha256:e6d2677a32f47fc7eb2795db1dd15c1f34eff616bcaf2cfb5e997f854fa1c4a6" + "sha256:5cb5f4a79139d699607b3ef622a1dedafa84e115ab0024e0d9c044a9479ca7cb", + "sha256:fb33085c39dd998ac16d1431ebc293a8b3eedd00fd4a32de0ff79002c19511b4" ], "markers": "python_version >= '3.7'", - "version": "==4.3.0" + "version": "==4.5.0" }, "urllib3": { "hashes": [ - "sha256:3fa96cf423e6987997fc326ae8df396db2a8b7c667747d47ddd8ecba91f4a74e", - "sha256:b930dd878d5a8afb066a637fbb35144fe7901e3b209d1cd4f524bd0e9deee997" + "sha256:076907bf8fd355cde77728471316625a4d2f7e713c125f51953bb5b3eecf4f72", + "sha256:75edcdc2f7d85b137124a6c3c9fc3933cdeaa12ecb9a6a959f22797a0feca7e1" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5' and python_version < '4'", - "version": "==1.26.12" + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'", + "version": "==1.26.14" }, "werkzeug": { "hashes": [ - "sha256:7ea2d48322cc7c0f8b3a215ed73eabd7b5d75d0b50e31ab006286ccff9e00b8f", - "sha256:f979ab81f58d7318e064e99c4506445d60135ac5cd2e177a2de0089bfd4c9bd5" + "sha256:2e1ccc9417d4da358b9de6f174e3ac094391ea1d4fbef2d667865d819dfd0afe", + "sha256:56433961bc1f12533306c624f3be5e744389ac61d722175d543e1751285da612" ], "markers": "python_version >= '3.7'", - "version": "==2.2.2" + "version": "==2.2.3" }, "wrapt": { "hashes": [ @@ -634,21 +745,21 @@ }, "zipp": { "hashes": [ - "sha256:05b45f1ee8f807d0cc928485ca40a07cb491cf092ff587c0df9cb1fd154848d2", - "sha256:47c40d7fe183a6f21403a199b3e4192cca5774656965b0a4988ad2f8feb5f009" + "sha256:23f70e964bc11a34cef175bc90ba2914e1e4545ea1e3e2f67c079671883f9cb6", + "sha256:e8b2a36ea17df80ffe9e2c4fda3f693c3dad6df1697d3cd3af232db680950b0b" ], "markers": "python_version < '3.10'", - "version": "==3.8.1" + "version": "==3.13.0" } }, "develop": { "alembic": { "hashes": [ - "sha256:0a024d7f2de88d738d7395ff866997314c837be6104e90c5724350313dee4da4", - "sha256:cd0b5e45b14b706426b833f06369b9a6d5ee03f826ec3238723ce8caaf6e5ffa" + "sha256:4d3bd32ecdbb7bbfb48a9fe9e6d6fd6a831a1b59d03e26e292210237373e7db5", + "sha256:6f1c2207369bf4f49f952057a33bb017fbe5c148c2a773b46906b806ea6e825f" ], "markers": "python_version >= '3.7'", - "version": "==1.8.1" + "version": "==1.9.4" }, "click": { "hashes": [ @@ -668,11 +779,11 @@ }, "flask-migrate": { "hashes": [ - "sha256:57d6060839e3a7f150eaab6fe4e726d9e3e7cffe2150fb223d73f92421c6d1d9", - "sha256:a6498706241aba6be7a251078de9cf166d74307bca41a4ca3e403c9d39e2f897" + "sha256:73293d40b10ac17736e715b377e7b7bde474cb8105165d77474df4c3619b10b3", + "sha256:77580f27ab39bc68be4906a43c56d7674b45075bc4f883b1d0b985db5164d58f" ], "index": "pypi", - "version": "==3.1.0" + "version": "==4.0.4" }, "flask-sqlalchemy": { "hashes": [ @@ -684,19 +795,19 @@ }, "importlib-metadata": { "hashes": [ - "sha256:637245b8bab2b6502fcbc752cc4b7a6f6243bb02b31c5c26156ad103d3d45670", - "sha256:7401a975809ea1fdc658c3aa4f78cc2195a0e019c5cbc4c06122884e9ae80c23" + "sha256:7efb448ec9a5e313a57655d35aa54cd3e01b7e1fbcf72dce1bf06119420f5bad", + "sha256:e354bedeb60efa6affdcc8ae121b73544a7aa74156d047311948f6d711cd378d" ], "markers": "python_version < '3.9'", - "version": "==4.12.0" + "version": "==6.0.0" }, "importlib-resources": { "hashes": [ - "sha256:5481e97fb45af8dcf2f798952625591c58fe599d0735d86b10f54de086a61681", - "sha256:f78a8df21a79bcc30cfd400bdc38f314333de7c0fb619763f6b9dabab8268bb7" + "sha256:7d543798b0beca10b6a01ac7cafda9f822c54db9e8376a6bf57e0cbd74d486b6", + "sha256:e4a96c8cc0339647ff9a5e0550d9f276fc5a01ffa276012b58ec108cfd7b8484" ], "markers": "python_version < '3.9'", - "version": "==5.9.0" + "version": "==5.10.2" }, "itsdangerous": { "hashes": [ @@ -716,57 +827,67 @@ }, "mako": { "hashes": [ - "sha256:3724869b363ba630a272a5f89f68c070352137b8fd1757650017b7e06fda163f", - "sha256:8efcb8004681b5f71d09c983ad5a9e6f5c40601a6ec469148753292abc0da534" + "sha256:c97c79c018b9165ac9922ae4f32da095ffd3c4e6872b45eded42926deea46818", + "sha256:d60a3903dc3bb01a18ad6a89cdbe2e4eadc69c0bc8ef1e3773ba53d44c3f7a34" ], "markers": "python_version >= '3.7'", - "version": "==1.2.2" + "version": "==1.2.4" }, "markupsafe": { "hashes": [ - "sha256:0212a68688482dc52b2d45013df70d169f542b7394fc744c02a57374a4207003", - "sha256:089cf3dbf0cd6c100f02945abeb18484bd1ee57a079aefd52cffd17fba910b88", - "sha256:10c1bfff05d95783da83491be968e8fe789263689c02724e0c691933c52994f5", - "sha256:33b74d289bd2f5e527beadcaa3f401e0df0a89927c1559c8566c066fa4248ab7", - "sha256:3799351e2336dc91ea70b034983ee71cf2f9533cdff7c14c90ea126bfd95d65a", - "sha256:3ce11ee3f23f79dbd06fb3d63e2f6af7b12db1d46932fe7bd8afa259a5996603", - "sha256:421be9fbf0ffe9ffd7a378aafebbf6f4602d564d34be190fc19a193232fd12b1", - "sha256:43093fb83d8343aac0b1baa75516da6092f58f41200907ef92448ecab8825135", - "sha256:46d00d6cfecdde84d40e572d63735ef81423ad31184100411e6e3388d405e247", - "sha256:4a33dea2b688b3190ee12bd7cfa29d39c9ed176bda40bfa11099a3ce5d3a7ac6", - "sha256:4b9fe39a2ccc108a4accc2676e77da025ce383c108593d65cc909add5c3bd601", - "sha256:56442863ed2b06d19c37f94d999035e15ee982988920e12a5b4ba29b62ad1f77", - "sha256:671cd1187ed5e62818414afe79ed29da836dde67166a9fac6d435873c44fdd02", - "sha256:694deca8d702d5db21ec83983ce0bb4b26a578e71fbdbd4fdcd387daa90e4d5e", - "sha256:6a074d34ee7a5ce3effbc526b7083ec9731bb3cbf921bbe1d3005d4d2bdb3a63", - "sha256:6d0072fea50feec76a4c418096652f2c3238eaa014b2f94aeb1d56a66b41403f", - "sha256:6fbf47b5d3728c6aea2abb0589b5d30459e369baa772e0f37a0320185e87c980", - "sha256:7f91197cc9e48f989d12e4e6fbc46495c446636dfc81b9ccf50bb0ec74b91d4b", - "sha256:86b1f75c4e7c2ac2ccdaec2b9022845dbb81880ca318bb7a0a01fbf7813e3812", - "sha256:8dc1c72a69aa7e082593c4a203dcf94ddb74bb5c8a731e4e1eb68d031e8498ff", - "sha256:8e3dcf21f367459434c18e71b2a9532d96547aef8a871872a5bd69a715c15f96", - "sha256:8e576a51ad59e4bfaac456023a78f6b5e6e7651dcd383bcc3e18d06f9b55d6d1", - "sha256:96e37a3dc86e80bf81758c152fe66dbf60ed5eca3d26305edf01892257049925", - "sha256:97a68e6ada378df82bc9f16b800ab77cbf4b2fada0081794318520138c088e4a", - "sha256:99a2a507ed3ac881b975a2976d59f38c19386d128e7a9a18b7df6fff1fd4c1d6", - "sha256:a49907dd8420c5685cfa064a1335b6754b74541bbb3706c259c02ed65b644b3e", - "sha256:b09bf97215625a311f669476f44b8b318b075847b49316d3e28c08e41a7a573f", - "sha256:b7bd98b796e2b6553da7225aeb61f447f80a1ca64f41d83612e6139ca5213aa4", - "sha256:b87db4360013327109564f0e591bd2a3b318547bcef31b468a92ee504d07ae4f", - "sha256:bcb3ed405ed3222f9904899563d6fc492ff75cce56cba05e32eff40e6acbeaa3", - "sha256:d4306c36ca495956b6d568d276ac11fdd9c30a36f1b6eb928070dc5360b22e1c", - "sha256:d5ee4f386140395a2c818d149221149c54849dfcfcb9f1debfe07a8b8bd63f9a", - "sha256:dda30ba7e87fbbb7eab1ec9f58678558fd9a6b8b853530e176eabd064da81417", - "sha256:e04e26803c9c3851c931eac40c695602c6295b8d432cbe78609649ad9bd2da8a", - "sha256:e1c0b87e09fa55a220f058d1d49d3fb8df88fbfab58558f1198e08c1e1de842a", - "sha256:e72591e9ecd94d7feb70c1cbd7be7b3ebea3f548870aa91e2732960fa4d57a37", - "sha256:e8c843bbcda3a2f1e3c2ab25913c80a3c5376cd00c6e8c4a86a89a28c8dc5452", - "sha256:efc1913fd2ca4f334418481c7e595c00aad186563bbc1ec76067848c7ca0a933", - "sha256:f121a1420d4e173a5d96e47e9a0c0dcff965afdf1626d28de1460815f7c4ee7a", - "sha256:fc7b548b17d238737688817ab67deebb30e8073c95749d55538ed473130ec0c7" + "sha256:0576fe974b40a400449768941d5d0858cc624e3249dfd1e0c33674e5c7ca7aed", + "sha256:085fd3201e7b12809f9e6e9bc1e5c96a368c8523fad5afb02afe3c051ae4afcc", + "sha256:090376d812fb6ac5f171e5938e82e7f2d7adc2b629101cec0db8b267815c85e2", + "sha256:0b462104ba25f1ac006fdab8b6a01ebbfbce9ed37fd37fd4acd70c67c973e460", + "sha256:137678c63c977754abe9086a3ec011e8fd985ab90631145dfb9294ad09c102a7", + "sha256:1bea30e9bf331f3fef67e0a3877b2288593c98a21ccb2cf29b74c581a4eb3af0", + "sha256:22152d00bf4a9c7c83960521fc558f55a1adbc0631fbb00a9471e097b19d72e1", + "sha256:22731d79ed2eb25059ae3df1dfc9cb1546691cc41f4e3130fe6bfbc3ecbbecfa", + "sha256:2298c859cfc5463f1b64bd55cb3e602528db6fa0f3cfd568d3605c50678f8f03", + "sha256:28057e985dace2f478e042eaa15606c7efccb700797660629da387eb289b9323", + "sha256:2e7821bffe00aa6bd07a23913b7f4e01328c3d5cc0b40b36c0bd81d362faeb65", + "sha256:2ec4f2d48ae59bbb9d1f9d7efb9236ab81429a764dedca114f5fdabbc3788013", + "sha256:340bea174e9761308703ae988e982005aedf427de816d1afe98147668cc03036", + "sha256:40627dcf047dadb22cd25ea7ecfe9cbf3bbbad0482ee5920b582f3809c97654f", + "sha256:40dfd3fefbef579ee058f139733ac336312663c6706d1163b82b3003fb1925c4", + "sha256:4cf06cdc1dda95223e9d2d3c58d3b178aa5dacb35ee7e3bbac10e4e1faacb419", + "sha256:50c42830a633fa0cf9e7d27664637532791bfc31c731a87b202d2d8ac40c3ea2", + "sha256:55f44b440d491028addb3b88f72207d71eeebfb7b5dbf0643f7c023ae1fba619", + "sha256:608e7073dfa9e38a85d38474c082d4281f4ce276ac0010224eaba11e929dd53a", + "sha256:63ba06c9941e46fa389d389644e2d8225e0e3e5ebcc4ff1ea8506dce646f8c8a", + "sha256:65608c35bfb8a76763f37036547f7adfd09270fbdbf96608be2bead319728fcd", + "sha256:665a36ae6f8f20a4676b53224e33d456a6f5a72657d9c83c2aa00765072f31f7", + "sha256:6d6607f98fcf17e534162f0709aaad3ab7a96032723d8ac8750ffe17ae5a0666", + "sha256:7313ce6a199651c4ed9d7e4cfb4aa56fe923b1adf9af3b420ee14e6d9a73df65", + "sha256:7668b52e102d0ed87cb082380a7e2e1e78737ddecdde129acadb0eccc5423859", + "sha256:7df70907e00c970c60b9ef2938d894a9381f38e6b9db73c5be35e59d92e06625", + "sha256:7e007132af78ea9df29495dbf7b5824cb71648d7133cf7848a2a5dd00d36f9ff", + "sha256:835fb5e38fd89328e9c81067fd642b3593c33e1e17e2fdbf77f5676abb14a156", + "sha256:8bca7e26c1dd751236cfb0c6c72d4ad61d986e9a41bbf76cb445f69488b2a2bd", + "sha256:8db032bf0ce9022a8e41a22598eefc802314e81b879ae093f36ce9ddf39ab1ba", + "sha256:99625a92da8229df6d44335e6fcc558a5037dd0a760e11d84be2260e6f37002f", + "sha256:9cad97ab29dfc3f0249b483412c85c8ef4766d96cdf9dcf5a1e3caa3f3661cf1", + "sha256:a4abaec6ca3ad8660690236d11bfe28dfd707778e2442b45addd2f086d6ef094", + "sha256:a6e40afa7f45939ca356f348c8e23048e02cb109ced1eb8420961b2f40fb373a", + "sha256:a6f2fcca746e8d5910e18782f976489939d54a91f9411c32051b4aab2bd7c513", + "sha256:a806db027852538d2ad7555b203300173dd1b77ba116de92da9afbc3a3be3eed", + "sha256:abcabc8c2b26036d62d4c746381a6f7cf60aafcc653198ad678306986b09450d", + "sha256:b8526c6d437855442cdd3d87eede9c425c4445ea011ca38d937db299382e6fa3", + "sha256:bb06feb762bade6bf3c8b844462274db0c76acc95c52abe8dbed28ae3d44a147", + "sha256:c0a33bc9f02c2b17c3ea382f91b4db0e6cde90b63b296422a939886a7a80de1c", + "sha256:c4a549890a45f57f1ebf99c067a4ad0cb423a05544accaf2b065246827ed9603", + "sha256:ca244fa73f50a800cf8c3ebf7fd93149ec37f5cb9596aa8873ae2c1d23498601", + "sha256:cf877ab4ed6e302ec1d04952ca358b381a882fbd9d1b07cccbfd61783561f98a", + "sha256:d9d971ec1e79906046aa3ca266de79eac42f1dbf3612a05dc9368125952bd1a1", + "sha256:da25303d91526aac3672ee6d49a2f3db2d9502a4a60b55519feb1a4c7714e07d", + "sha256:e55e40ff0cc8cc5c07996915ad367fa47da6b3fc091fdadca7f5403239c5fec3", + "sha256:f03a532d7dee1bed20bc4884194a16160a2de9ffc6354b3878ec9682bb623c54", + "sha256:f1cd098434e83e656abf198f103a8207a8187c0fc110306691a2e94a78d0abb2", + "sha256:f2bfb563d0211ce16b63c7cb9395d2c682a23187f54c3d79bfec33e6705473c6", + "sha256:f8ffb705ffcf5ddd0e80b65ddf7bed7ee4f5a441ea7d3419e861a12eaf41af58" ], "markers": "python_version >= '3.7'", - "version": "==2.1.1" + "version": "==2.1.2" }, "sqlalchemy": { "hashes": [ @@ -810,19 +931,19 @@ }, "werkzeug": { "hashes": [ - "sha256:7ea2d48322cc7c0f8b3a215ed73eabd7b5d75d0b50e31ab006286ccff9e00b8f", - "sha256:f979ab81f58d7318e064e99c4506445d60135ac5cd2e177a2de0089bfd4c9bd5" + "sha256:2e1ccc9417d4da358b9de6f174e3ac094391ea1d4fbef2d667865d819dfd0afe", + "sha256:56433961bc1f12533306c624f3be5e744389ac61d722175d543e1751285da612" ], "markers": "python_version >= '3.7'", - "version": "==2.2.2" + "version": "==2.2.3" }, "zipp": { "hashes": [ - "sha256:05b45f1ee8f807d0cc928485ca40a07cb491cf092ff587c0df9cb1fd154848d2", - "sha256:47c40d7fe183a6f21403a199b3e4192cca5774656965b0a4988ad2f8feb5f009" + "sha256:23f70e964bc11a34cef175bc90ba2914e1e4545ea1e3e2f67c079671883f9cb6", + "sha256:e8b2a36ea17df80ffe9e2c4fda3f693c3dad6df1697d3cd3af232db680950b0b" ], "markers": "python_version < '3.10'", - "version": "==3.8.1" + "version": "==3.13.0" } } } diff --git a/README.md b/README.md index b3b1de3..75d1007 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,7 @@ This is the backend that provides access to the ClassClock database. | API_IDENTIFIER | no default | Your Auth0 api identifier. This may be your API domain name. i.e. `https://api.yourdomain.com` | | AUTH0_CLIENT_ID | no default | Your Auth0 Client ID | | AUTH0_CLIENT_SECRET | no default | Your Auth0 Client Secret | +| SENTRY_DSN | no default | The dsn URL from the sentry.io setup in case you wish to set up error monitoring | diff --git a/api.py b/api.py index df9e10e..bc7bc72 100644 --- a/api.py +++ b/api.py @@ -8,6 +8,17 @@ from common.schemas import * from auth import db_connection_string from flask_migrate import Migrate +from os import environ as env + +if env.get("SENTRY_DSN"): + import sentry_sdk + sentry_sdk.init( + dsn=env.get("SENTRY_DSN"), + # Set traces_sample_rate to 1.0 to capture 100% + # of transactions for performance monitoring. + # We recommend adjusting this value in production. + traces_sample_rate=1.0 + ) def create_app(config_filename=None): app = Flask(__name__) From f0f96e3cb565c66526676370604aced4d86a38f4 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Fri, 17 Feb 2023 10:00:02 -0500 Subject: [PATCH 173/206] make logging less needlessly noisy --- blueprints/v0.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/blueprints/v0.py b/blueprints/v0.py index 8c2d148..634d703 100644 --- a/blueprints/v0.py +++ b/blueprints/v0.py @@ -541,13 +541,17 @@ def delete_bellschedule(bell_schedule_id): @blueprint.before_request def before(): - current_app.logger.info( "Received request " + request.method + " " + request.path + " for API client '" + get_api_client_id() + "' user '" + get_api_user_id() + "'" ) + current_app.logger.info(request.method + " " + request.path) @blueprint.after_request def after_request(response): response.headers['Content-Type'] = 'application/json' - current_app.logger.info( "Handled request with HTTP status: " + str(response.status_code)) + if response.status_code != 200: + current_app.logger.info( "Handled request with HTTP status: " + str(response.status_code)) + + if response.status_code > 399: + current_app.logger.info(str(response.get_data())) return response # From 480a718f16a835af836157709e351d43afee4cbb Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Fri, 17 Feb 2023 17:20:25 -0500 Subject: [PATCH 174/206] update flask_limiter --- Pipfile | 2 +- Pipfile.lock | 60 +++++++++++++++++++++++++++++++++++++++-------- api.py | 7 +++--- common/helpers.py | 4 ---- 4 files changed, 55 insertions(+), 18 deletions(-) diff --git a/Pipfile b/Pipfile index 225e148..496608c 100644 --- a/Pipfile +++ b/Pipfile @@ -12,7 +12,7 @@ flasgger = "~=0.9.3" flask-marshmallow = "~=0.10.1" Flask = "~=2.0.0" Flask-Cors = "~=3.0.8" -Flask-Limiter = "~=1.0.1" +Flask-Limiter = "~=3.2.0" gunicorn = "~=19.9.0" sqlalchemy = "~=1.3.13" flask-sqlalchemy = "~=2.5.0" diff --git a/Pipfile.lock b/Pipfile.lock index 43f309b..aeccc0a 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "674fb0252cffe8e0fd961659d356f336ff6297696a3ab35ee6e8d3ee42b9b761" + "sha256": "b1849b334bc581a3fe5029df9c343865fc0b6c322e3da71f83b432de53f90515" }, "pipfile-spec": 6, "requires": { @@ -200,11 +200,11 @@ }, "flask-limiter": { "hashes": [ - "sha256:473aa5bc97310406aa8c12ab3dc080697bcfa8cd21a6d0aba30916911bbc673c", - "sha256:8cce98dcf25bf2ddbb824c2b503b4fc8e1a139154240fd2c60d9306bad8a0db8" + "sha256:919b4af05b7d4162a699bfdc24357feeec876b70b1916150c3b4337ad711a995", + "sha256:e56140f2d48a3ee7d9d6e49bb81015e30cd1e99dc9e44adebb0c1127b89b3dc8" ], "index": "pypi", - "version": "==1.0.1" + "version": "==3.2.0" }, "flask-marshmallow": { "hashes": [ @@ -256,11 +256,11 @@ }, "importlib-resources": { "hashes": [ - "sha256:7d543798b0beca10b6a01ac7cafda9f822c54db9e8376a6bf57e0cbd74d486b6", - "sha256:e4a96c8cc0339647ff9a5e0550d9f276fc5a01ffa276012b58ec108cfd7b8484" + "sha256:1e534a02295f3eeee0785e21b26c726557909cbaf1b871cf9adcbc0df44c1308", + "sha256:c0a55f37559b5e9ca1d3fce02d60243846245ad8f8d806a4484093806d4d0ae5" ], "markers": "python_version < '3.9'", - "version": "==5.10.2" + "version": "==5.11.0" }, "itsdangerous": { "hashes": [ @@ -302,6 +302,14 @@ "markers": "python_version >= '3.7'", "version": "==1.2.4" }, + "markdown-it-py": { + "hashes": [ + "sha256:93de681e5c021a432c63147656fe21790bc01231e0cd2da73626f1aa3ac0fe27", + "sha256:cf7e59fed14b5ae17c0006eff14a2d9a00ed5f3a846148153899a0224e2c07da" + ], + "markers": "python_version >= '3.7'", + "version": "==2.1.0" + }, "markupsafe": { "hashes": [ "sha256:0576fe974b40a400449768941d5d0858cc624e3249dfd1e0c33674e5c7ca7aed", @@ -374,6 +382,14 @@ "index": "pypi", "version": "==0.28.1" }, + "mdurl": { + "hashes": [ + "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", + "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba" + ], + "markers": "python_version >= '3.7'", + "version": "==0.1.2" + }, "mistune": { "hashes": [ "sha256:0246113cb2492db875c6be56974a7c893333bf26cd92891c85f63151cee09d34", @@ -412,6 +428,14 @@ "index": "pypi", "version": "==8.0.32" }, + "ordered-set": { + "hashes": [ + "sha256:046e1132c71fcf3330438a539928932caf51ddbc582496833e23de611de14562", + "sha256:694a8e44c87657c59292ede72891eb91d34131f6531463aab3009191c77364a8" + ], + "markers": "python_version >= '3.7'", + "version": "==4.1.0" + }, "packaging": { "hashes": [ "sha256:714ac14496c3e68c99c29b00845f7a2b85f3bb6f1078fd9f72fd20f0570002b2", @@ -474,6 +498,14 @@ ], "version": "==0.4.8" }, + "pygments": { + "hashes": [ + "sha256:b3ed06a9e8ac9a9aae5a6f5dbe78a8a58655d17b43b93c078f094ddc476ae297", + "sha256:fa7bd7bd2771287c0de303af8bfdfc731f51bd2c6a47ab69d117138893b82717" + ], + "markers": "python_version >= '3.6'", + "version": "==2.14.0" + }, "pyrsistent": { "hashes": [ "sha256:016ad1afadf318eb7911baa24b049909f7f3bb2c5b1ed7b6a8f21db21ea3faa8", @@ -577,6 +609,14 @@ "index": "pypi", "version": "==2.28.2" }, + "rich": { + "hashes": [ + "sha256:125d96d20c92b946b983d0d392b84ff945461e5a06d3867e9f9e575f8697b67f", + "sha256:8aa57747f3fc3e977684f0176a88e789be314a99f99b43b75d1e9cb5dc6db9e9" + ], + "markers": "python_version >= '3.7'", + "version": "==13.3.1" + }, "rsa": { "hashes": [ "sha256:90260d9058e514786967344d0ef75fa8727eed8a7d2e43ce9f4bcf1b536174f7", @@ -803,11 +843,11 @@ }, "importlib-resources": { "hashes": [ - "sha256:7d543798b0beca10b6a01ac7cafda9f822c54db9e8376a6bf57e0cbd74d486b6", - "sha256:e4a96c8cc0339647ff9a5e0550d9f276fc5a01ffa276012b58ec108cfd7b8484" + "sha256:1e534a02295f3eeee0785e21b26c726557909cbaf1b871cf9adcbc0df44c1308", + "sha256:c0a55f37559b5e9ca1d3fce02d60243846245ad8f8d806a4484093806d4d0ae5" ], "markers": "python_version < '3.9'", - "version": "==5.10.2" + "version": "==5.11.0" }, "itsdangerous": { "hashes": [ diff --git a/api.py b/api.py index bc7bc72..05f9020 100644 --- a/api.py +++ b/api.py @@ -3,7 +3,8 @@ from blueprints import v0, main from docs import create_docs from flask_limiter import Limiter -from common.helpers import get_request_origin_identifier, make_error_object, respond +from flask_limiter.util import get_remote_address +from common.helpers import make_error_object, respond from common.db_schema import db from common.schemas import * from auth import db_connection_string @@ -25,8 +26,8 @@ def create_app(config_filename=None): if config_filename: app.config.from_pyfile(config_filename) - limiter = Limiter(app, default_limits=[ - "25/hour", "5/minute"], key_func=get_request_origin_identifier, headers_enabled=True) + limiter = Limiter(get_remote_address, app=app, default_limits=[ + "25/hour", "5/minute"], headers_enabled=True) app.register_blueprint(v0.blueprint, url_prefix='/v0') app.register_blueprint(main.main_pages) diff --git a/common/helpers.py b/common/helpers.py index 31e6fc4..100ac44 100644 --- a/common/helpers.py +++ b/common/helpers.py @@ -195,10 +195,6 @@ def get_request_body(request): """ return request.get_json() -def get_request_origin_identifier(): - user_id_parts = get_api_user_id().split("|") - return flask_limiter.util.get_remote_address() + get_api_client_id() + user_id_parts[1] if len(user_id_parts) > 2 else "" - def get_api_client_id(): """Returns a string to group API calls together for the purposes of ratelimiting From 3363d5af26def960af52e1f2b9f55d49c52be0c7 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Fri, 17 Feb 2023 17:20:53 -0500 Subject: [PATCH 175/206] add an env var to handle getting IP from behind a proxy and fixing rate limiting --- README.md | 2 +- api.py | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 75d1007..def9d7a 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ This is the backend that provides access to the ClassClock database. | AUTH0_CLIENT_ID | no default | Your Auth0 Client ID | | AUTH0_CLIENT_SECRET | no default | Your Auth0 Client Secret | | SENTRY_DSN | no default | The dsn URL from the sentry.io setup in case you wish to set up error monitoring | - +| TRUSTED_PROXY_COUNT | no default | The number of proxies that are in between users and the app itself. Setting this too high can create security problems. Setting too low can cause rate limiting to not work | ## First time Setup diff --git a/api.py b/api.py index 05f9020..ec22b00 100644 --- a/api.py +++ b/api.py @@ -9,6 +9,8 @@ from common.schemas import * from auth import db_connection_string from flask_migrate import Migrate +from werkzeug.middleware.proxy_fix import ProxyFix + from os import environ as env if env.get("SENTRY_DSN"): @@ -23,6 +25,11 @@ def create_app(config_filename=None): app = Flask(__name__) + if env.get("TRUSTED_PROXY_COUNT"): + # for example if the request goes through one proxy + # before hitting your application server + app.wsgi_app = ProxyFix(app.wsgi_app, x_for=env.get("TRUSTED_PROXY_COUNT")) + if config_filename: app.config.from_pyfile(config_filename) From 47d16061e238866a69d2a28ba0a69618fb645a15 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Fri, 17 Feb 2023 17:53:38 -0500 Subject: [PATCH 176/206] convert provided trusted proxy count into an integer --- api.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api.py b/api.py index ec22b00..7393a49 100644 --- a/api.py +++ b/api.py @@ -28,7 +28,7 @@ def create_app(config_filename=None): if env.get("TRUSTED_PROXY_COUNT"): # for example if the request goes through one proxy # before hitting your application server - app.wsgi_app = ProxyFix(app.wsgi_app, x_for=env.get("TRUSTED_PROXY_COUNT")) + app.wsgi_app = ProxyFix(app.wsgi_app, x_for=int(env.get("TRUSTED_PROXY_COUNT") or 0)) if config_filename: app.config.from_pyfile(config_filename) From fbb0d906ed3707d0ecf60a1d9885045502e79dc4 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Fri, 17 Feb 2023 18:09:53 -0500 Subject: [PATCH 177/206] add logging to indicate when stuff is successfully setup --- api.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/api.py b/api.py index 7393a49..0f9564c 100644 --- a/api.py +++ b/api.py @@ -14,6 +14,8 @@ from os import environ as env if env.get("SENTRY_DSN"): + app.logger.info("Detected Sentry DSN, setting up sentry...") + import sentry_sdk sentry_sdk.init( dsn=env.get("SENTRY_DSN"), @@ -26,6 +28,8 @@ def create_app(config_filename=None): app = Flask(__name__) if env.get("TRUSTED_PROXY_COUNT"): + app.logger.info("Detected value for TRUSTED_PROXY_COUNT, setting up ProxyFix..." + env.get("TRUSTED_PROXY_COUNT")) + # for example if the request goes through one proxy # before hitting your application server app.wsgi_app = ProxyFix(app.wsgi_app, x_for=int(env.get("TRUSTED_PROXY_COUNT") or 0)) From 9a589f56dd0b7def1c0b84fc6f0bcd15fb82125c Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Fri, 17 Feb 2023 18:14:12 -0500 Subject: [PATCH 178/206] nope, that is crashing --- api.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api.py b/api.py index 0f9564c..a054699 100644 --- a/api.py +++ b/api.py @@ -14,7 +14,7 @@ from os import environ as env if env.get("SENTRY_DSN"): - app.logger.info("Detected Sentry DSN, setting up sentry...") + # app.logger.info("Detected Sentry DSN, setting up sentry...") import sentry_sdk sentry_sdk.init( From 140439a4952888f37e7d7d56d498122ea4b35e11 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Fri, 17 Feb 2023 18:45:09 -0500 Subject: [PATCH 179/206] bump rate limit a bit --- api.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api.py b/api.py index a054699..dc2537e 100644 --- a/api.py +++ b/api.py @@ -38,7 +38,7 @@ def create_app(config_filename=None): app.config.from_pyfile(config_filename) limiter = Limiter(get_remote_address, app=app, default_limits=[ - "25/hour", "5/minute"], headers_enabled=True) + "100/hour", "5/minute"], headers_enabled=True) app.register_blueprint(v0.blueprint, url_prefix='/v0') app.register_blueprint(main.main_pages) From 845de760310b1c3b27299ee36a2d546785d41bf8 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Fri, 17 Feb 2023 18:45:32 -0500 Subject: [PATCH 180/206] import respond so 429 errors can be properly handled --- blueprints/v0.py | 1 + 1 file changed, 1 insertion(+) diff --git a/blueprints/v0.py b/blueprints/v0.py index 634d703..397c015 100644 --- a/blueprints/v0.py +++ b/blueprints/v0.py @@ -4,6 +4,7 @@ from flask import current_app, json from os import environ as env +from helpers import respond from flask import Blueprint, abort, jsonify, request from werkzeug.exceptions import HTTPException from flask_cors import CORS From ef147d556204483126f8297b5074a8321a949d1f Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Fri, 17 Feb 2023 18:45:58 -0500 Subject: [PATCH 181/206] improve logging for rate limit exceeded messages --- blueprints/v0.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/blueprints/v0.py b/blueprints/v0.py index 397c015..04841b3 100644 --- a/blueprints/v0.py +++ b/blueprints/v0.py @@ -4,6 +4,7 @@ from flask import current_app, json from os import environ as env +from flask_limiter.util import get_remote_address from helpers import respond from flask import Blueprint, abort, jsonify, request from werkzeug.exceptions import HTTPException @@ -565,7 +566,8 @@ def after_request(response): # https://flask-limiter.readthedocs.io/en/stable/#custom-rate-limit-exceeded-responses @blueprint.errorhandler(429) def ratelimit_handler(e): - print(e) + current_app.logger.warning(e) + current_app.logger.warning("User at address " + get_remote_address() + "exceeded rate limit of " + e.description) return respond( make_error_object(429, title="Ratelimit Exceeded", message="ratelimit of " + e.description + " exceeded"), From 06108fe63be3c0cebee22b08f2208d83348c84cd Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Fri, 17 Feb 2023 19:24:12 -0500 Subject: [PATCH 182/206] fix import --- blueprints/v0.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/blueprints/v0.py b/blueprints/v0.py index 04841b3..ef84b58 100644 --- a/blueprints/v0.py +++ b/blueprints/v0.py @@ -5,7 +5,7 @@ from os import environ as env from flask_limiter.util import get_remote_address -from helpers import respond +from common.helpers import respond from flask import Blueprint, abort, jsonify, request from werkzeug.exceptions import HTTPException from flask_cors import CORS From 352108ab37e2e07eb40ecfe83476872680a5ddd8 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Mon, 17 Apr 2023 06:31:18 -0400 Subject: [PATCH 183/206] further update rate limits --- api.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api.py b/api.py index dc2537e..d325136 100644 --- a/api.py +++ b/api.py @@ -38,7 +38,7 @@ def create_app(config_filename=None): app.config.from_pyfile(config_filename) limiter = Limiter(get_remote_address, app=app, default_limits=[ - "100/hour", "5/minute"], headers_enabled=True) + "500/hour", "100/minute"], headers_enabled=True) app.register_blueprint(v0.blueprint, url_prefix='/v0') app.register_blueprint(main.main_pages) From 865684cb4088c2e476e5e7874ae38015840ec5df Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Mon, 17 Apr 2023 06:32:59 -0400 Subject: [PATCH 184/206] add source for TRUSTED_PROXY_COUNT docs claim that it can cause problems if set too high --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index def9d7a..20fd999 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ This is the backend that provides access to the ClassClock database. | AUTH0_CLIENT_ID | no default | Your Auth0 Client ID | | AUTH0_CLIENT_SECRET | no default | Your Auth0 Client Secret | | SENTRY_DSN | no default | The dsn URL from the sentry.io setup in case you wish to set up error monitoring | -| TRUSTED_PROXY_COUNT | no default | The number of proxies that are in between users and the app itself. Setting this too high can create security problems. Setting too low can cause rate limiting to not work | +| TRUSTED_PROXY_COUNT | no default | The number of proxies that are in between users and the app itself. Setting this too high can create security problems. Setting too low can cause rate limiting to not work. see [here](https://flask-limiter.readthedocs.io/en/stable/recipes.html#deploying-an-application-behind-a-proxy) for what this is used for | ## First time Setup From eecc8eaa63ad5b938abf7e4c8a06a685cd16e063 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Mon, 17 Apr 2023 06:35:58 -0400 Subject: [PATCH 185/206] changelog update and version bump --- CHANGELOG.md | 6 ++++++ docs.py | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e6534ab..12e80af 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## 0.3.3 +- add optional sentry monitoring +- add TRUSTED_PROXY_COUNT environment variable to allow the app to run behind a proxy +- increase rate limits +- improve handling of 429 errors + ## 0.3.2 - Improvements to the admin role checks - Fix an issue where the token for the auth0management endpoint for checking user roles would expire and cause requests to return less data than they should diff --git a/docs.py b/docs.py index 03d39dd..39314be 100644 --- a/docs.py +++ b/docs.py @@ -16,7 +16,7 @@ def create_docs(app): # info: { spec = APISpec( title="ClassClock API", - version="0.3.2", + version="0.3.3", openapi_version='2.0', plugins=[ From 00866565f5b3a2f2903321119485e192b4aa2116 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Tue, 25 Apr 2023 11:33:18 -0400 Subject: [PATCH 186/206] switch to localhost --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 0229ded..4e93ac3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -11,4 +11,4 @@ RUN pipenv install COPY . /classclock-api/ -ENTRYPOINT pipenv run gunicorn --workers 2 --bind 0.0.0.0 api:app +ENTRYPOINT pipenv run gunicorn --workers 2 --bind 127.0.0.1 api:app From 4652ee112993e163844e815167a372cf3840d904 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Tue, 25 Apr 2023 11:37:13 -0400 Subject: [PATCH 187/206] fly config --- fly.toml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 fly.toml diff --git a/fly.toml b/fly.toml new file mode 100644 index 0000000..eb6414c --- /dev/null +++ b/fly.toml @@ -0,0 +1,20 @@ +# fly.toml app configuration file generated for classclockapi on 2023-04-25T11:26:13-04:00 +# +# See https://fly.io/docs/reference/configuration/ for information about how to use this file. +# + +app = "classclockapi" +primary_region = "den" + +[http_service] + internal_port = 8080 + force_https = true + auto_stop_machines = true + auto_start_machines = true + +[checks] + [checks.alive] + type = "tcp" + interval = "15s" + timeout = "2s" + grace_period = "5s" From 913d117446e87aaf166b04e4512ca9b356fbf1fa Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Tue, 25 Apr 2023 11:37:24 -0400 Subject: [PATCH 188/206] update fly internal port number --- fly.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fly.toml b/fly.toml index eb6414c..973e4b2 100644 --- a/fly.toml +++ b/fly.toml @@ -7,7 +7,7 @@ app = "classclockapi" primary_region = "den" [http_service] - internal_port = 8080 + internal_port = 5000 force_https = true auto_stop_machines = true auto_start_machines = true From bfcaa8ff971b6cfecded61a727490a67fefa2065 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Tue, 25 Apr 2023 11:49:06 -0400 Subject: [PATCH 189/206] update port number --- fly.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fly.toml b/fly.toml index 973e4b2..0479895 100644 --- a/fly.toml +++ b/fly.toml @@ -1,4 +1,4 @@ -# fly.toml app configuration file generated for classclockapi on 2023-04-25T11:26:13-04:00 +# fly.toml app configuration file generated for classclockapi on 2023-04-25T11:44:51-04:00 # # See https://fly.io/docs/reference/configuration/ for information about how to use this file. # @@ -7,7 +7,7 @@ app = "classclockapi" primary_region = "den" [http_service] - internal_port = 5000 + internal_port = 8000 force_https = true auto_stop_machines = true auto_start_machines = true From dc711807b228ce5ff6195d2658a0edde10536b94 Mon Sep 17 00:00:00 2001 From: Adrian Edwards <17362949+MoralCode@users.noreply.github.com> Date: Tue, 25 Apr 2023 12:17:03 -0400 Subject: [PATCH 190/206] Revert "switch to localhost" This reverts commit 00866565f5b3a2f2903321119485e192b4aa2116. --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 4e93ac3..0229ded 100644 --- a/Dockerfile +++ b/Dockerfile @@ -11,4 +11,4 @@ RUN pipenv install COPY . /classclock-api/ -ENTRYPOINT pipenv run gunicorn --workers 2 --bind 127.0.0.1 api:app +ENTRYPOINT pipenv run gunicorn --workers 2 --bind 0.0.0.0 api:app From 24f4f63c579024bbf08a2f80646e65839f7cd43d Mon Sep 17 00:00:00 2001 From: Adrian Edwards Date: Sun, 13 Aug 2023 12:03:21 -0400 Subject: [PATCH 191/206] refactor auth file to also allow the DATABASE_URL variable --- auth.py | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/auth.py b/auth.py index e515c56..38436ed 100644 --- a/auth.py +++ b/auth.py @@ -9,16 +9,11 @@ db_host = os.getenv("DB_HOST", "localhost") db_name = os.getenv("DB_NAME", "classclock") +connection_url = f'mysql+mysqlconnector://{db_username}:{db_password}@{db_host}/{db_name}?charset=utf8mb4&collation=utf8mb4_general_ci' +db_connection_string = os.getenv("DB_CONNECTION_URL", connection_url) +db_connection_string = os.getenv("DATABASE_URL", connection_url) -db_connection_string=os.getenv("DB_CONNECTION_URL", - 'mysql+mysqlconnector://{user}:{pw}@{url}/{db}?charset=utf8mb4&collation=utf8mb4_general_ci'.format( - user=db_username, - pw=db_password, - url=db_host, - db=db_name - ) -) # elif sys.argv[1] == "demo": # # https://stackoverflow.com/a/46541219 # with app.app_context(): From 4c399ae43b6a2860eae9ee40d9375978ae40c05f Mon Sep 17 00:00:00 2001 From: Adrian Edwards Date: Sun, 13 Aug 2023 12:07:40 -0400 Subject: [PATCH 192/206] install psycopg2 for postgress support (and apparrently also install updates) --- Pipfile | 1 + Pipfile.lock | 1079 +++++++++++++++++++++++++++----------------------- 2 files changed, 584 insertions(+), 496 deletions(-) diff --git a/Pipfile b/Pipfile index 496608c..9c281af 100644 --- a/Pipfile +++ b/Pipfile @@ -25,6 +25,7 @@ python-dotenv = "*" flask-migrate = "*" requests = "*" sentry-sdk = "*" +psycopg2 = "*" [requires] python_version = "3.8" diff --git a/Pipfile.lock b/Pipfile.lock index aeccc0a..46ba4bc 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "b1849b334bc581a3fe5029df9c343865fc0b6c322e3da71f83b432de53f90515" + "sha256": "f02915067d6d041c70717935c631888f845939aebacec22e284d5897cdba7876" }, "pipfile-spec": 6, "requires": { @@ -18,11 +18,11 @@ "default": { "alembic": { "hashes": [ - "sha256:4d3bd32ecdbb7bbfb48a9fe9e6d6fd6a831a1b59d03e26e292210237373e7db5", - "sha256:6f1c2207369bf4f49f952057a33bb017fbe5c148c2a773b46906b806ea6e825f" + "sha256:678f662130dc540dac12de0ea73de9f89caea9dbea138f60ef6263149bf84657", + "sha256:7981ab0c4fad4fe1be0cf183aae17689fe394ff874fd2464adb774396faf0796" ], "markers": "python_version >= '3.7'", - "version": "==1.9.4" + "version": "==1.11.2" }, "apispec": { "hashes": [ @@ -42,129 +42,116 @@ }, "attrs": { "hashes": [ - "sha256:29e95c7f6778868dbd49170f98f8818f78f3dc5e0e37c0b1f474e3561b240836", - "sha256:c9227bfc2f01993c03f68db37d1d15c9690188323c067c641f1a35ca58185f99" + "sha256:1f28b4522cdc2fb4256ac1a020c78acf9cba2c6b461ccd2c126f3aa8e8335d04", + "sha256:6279836d581513a26f1bf235f9acd333bc9115683f14f7e8fae46c98fc50e015" ], - "markers": "python_version >= '3.6'", - "version": "==22.2.0" + "markers": "python_version >= '3.7'", + "version": "==23.1.0" }, "certifi": { "hashes": [ - "sha256:35824b4c3a97115964b408844d64aa14db1cc518f6562e8d7261699d1350a9e3", - "sha256:4ad3232f5e926d6718ec31cfc1fcadfde020920e278684144551c91769c7bc18" + "sha256:539cc1d13202e33ca466e88b2807e29f4c13049d6d87031a3c110744495cb082", + "sha256:92d6037539857d8206b8f6ae472e8b77db8058fec5937a1ef3f54304089edbb9" ], "markers": "python_version >= '3.6'", - "version": "==2022.12.7" + "version": "==2023.7.22" }, "charset-normalizer": { "hashes": [ - "sha256:00d3ffdaafe92a5dc603cb9bd5111aaa36dfa187c8285c543be562e61b755f6b", - "sha256:024e606be3ed92216e2b6952ed859d86b4cfa52cd5bc5f050e7dc28f9b43ec42", - "sha256:0298eafff88c99982a4cf66ba2efa1128e4ddaca0b05eec4c456bbc7db691d8d", - "sha256:02a51034802cbf38db3f89c66fb5d2ec57e6fe7ef2f4a44d070a593c3688667b", - "sha256:083c8d17153ecb403e5e1eb76a7ef4babfc2c48d58899c98fcaa04833e7a2f9a", - "sha256:0a11e971ed097d24c534c037d298ad32c6ce81a45736d31e0ff0ad37ab437d59", - "sha256:0bf2dae5291758b6f84cf923bfaa285632816007db0330002fa1de38bfcb7154", - "sha256:0c0a590235ccd933d9892c627dec5bc7511ce6ad6c1011fdf5b11363022746c1", - "sha256:0f438ae3532723fb6ead77e7c604be7c8374094ef4ee2c5e03a3a17f1fca256c", - "sha256:109487860ef6a328f3eec66f2bf78b0b72400280d8f8ea05f69c51644ba6521a", - "sha256:11b53acf2411c3b09e6af37e4b9005cba376c872503c8f28218c7243582df45d", - "sha256:12db3b2c533c23ab812c2b25934f60383361f8a376ae272665f8e48b88e8e1c6", - "sha256:14e76c0f23218b8f46c4d87018ca2e441535aed3632ca134b10239dfb6dadd6b", - "sha256:16a8663d6e281208d78806dbe14ee9903715361cf81f6d4309944e4d1e59ac5b", - "sha256:292d5e8ba896bbfd6334b096e34bffb56161c81408d6d036a7dfa6929cff8783", - "sha256:2c03cc56021a4bd59be889c2b9257dae13bf55041a3372d3295416f86b295fb5", - "sha256:2e396d70bc4ef5325b72b593a72c8979999aa52fb8bcf03f701c1b03e1166918", - "sha256:2edb64ee7bf1ed524a1da60cdcd2e1f6e2b4f66ef7c077680739f1641f62f555", - "sha256:31a9ddf4718d10ae04d9b18801bd776693487cbb57d74cc3458a7673f6f34639", - "sha256:356541bf4381fa35856dafa6a965916e54bed415ad8a24ee6de6e37deccf2786", - "sha256:358a7c4cb8ba9b46c453b1dd8d9e431452d5249072e4f56cfda3149f6ab1405e", - "sha256:37f8febc8ec50c14f3ec9637505f28e58d4f66752207ea177c1d67df25da5aed", - "sha256:39049da0ffb96c8cbb65cbf5c5f3ca3168990adf3551bd1dee10c48fce8ae820", - "sha256:39cf9ed17fe3b1bc81f33c9ceb6ce67683ee7526e65fde1447c772afc54a1bb8", - "sha256:3ae1de54a77dc0d6d5fcf623290af4266412a7c4be0b1ff7444394f03f5c54e3", - "sha256:3b590df687e3c5ee0deef9fc8c547d81986d9a1b56073d82de008744452d6541", - "sha256:3e45867f1f2ab0711d60c6c71746ac53537f1684baa699f4f668d4c6f6ce8e14", - "sha256:3fc1c4a2ffd64890aebdb3f97e1278b0cc72579a08ca4de8cd2c04799a3a22be", - "sha256:4457ea6774b5611f4bed5eaa5df55f70abde42364d498c5134b7ef4c6958e20e", - "sha256:44ba614de5361b3e5278e1241fda3dc1838deed864b50a10d7ce92983797fa76", - "sha256:4a8fcf28c05c1f6d7e177a9a46a1c52798bfe2ad80681d275b10dcf317deaf0b", - "sha256:4b0d02d7102dd0f997580b51edc4cebcf2ab6397a7edf89f1c73b586c614272c", - "sha256:502218f52498a36d6bf5ea77081844017bf7982cdbe521ad85e64cabee1b608b", - "sha256:503e65837c71b875ecdd733877d852adbc465bd82c768a067badd953bf1bc5a3", - "sha256:5995f0164fa7df59db4746112fec3f49c461dd6b31b841873443bdb077c13cfc", - "sha256:59e5686dd847347e55dffcc191a96622f016bc0ad89105e24c14e0d6305acbc6", - "sha256:601f36512f9e28f029d9481bdaf8e89e5148ac5d89cffd3b05cd533eeb423b59", - "sha256:608862a7bf6957f2333fc54ab4399e405baad0163dc9f8d99cb236816db169d4", - "sha256:62595ab75873d50d57323a91dd03e6966eb79c41fa834b7a1661ed043b2d404d", - "sha256:70990b9c51340e4044cfc394a81f614f3f90d41397104d226f21e66de668730d", - "sha256:71140351489970dfe5e60fc621ada3e0f41104a5eddaca47a7acb3c1b851d6d3", - "sha256:72966d1b297c741541ca8cf1223ff262a6febe52481af742036a0b296e35fa5a", - "sha256:74292fc76c905c0ef095fe11e188a32ebd03bc38f3f3e9bcb85e4e6db177b7ea", - "sha256:761e8904c07ad053d285670f36dd94e1b6ab7f16ce62b9805c475b7aa1cffde6", - "sha256:772b87914ff1152b92a197ef4ea40efe27a378606c39446ded52c8f80f79702e", - "sha256:79909e27e8e4fcc9db4addea88aa63f6423ebb171db091fb4373e3312cb6d603", - "sha256:7e189e2e1d3ed2f4aebabd2d5b0f931e883676e51c7624826e0a4e5fe8a0bf24", - "sha256:7eb33a30d75562222b64f569c642ff3dc6689e09adda43a082208397f016c39a", - "sha256:81d6741ab457d14fdedc215516665050f3822d3e56508921cc7239f8c8e66a58", - "sha256:8499ca8f4502af841f68135133d8258f7b32a53a1d594aa98cc52013fff55678", - "sha256:84c3990934bae40ea69a82034912ffe5a62c60bbf6ec5bc9691419641d7d5c9a", - "sha256:87701167f2a5c930b403e9756fab1d31d4d4da52856143b609e30a1ce7160f3c", - "sha256:88600c72ef7587fe1708fd242b385b6ed4b8904976d5da0893e31df8b3480cb6", - "sha256:8ac7b6a045b814cf0c47f3623d21ebd88b3e8cf216a14790b455ea7ff0135d18", - "sha256:8b8af03d2e37866d023ad0ddea594edefc31e827fee64f8de5611a1dbc373174", - "sha256:8c7fe7afa480e3e82eed58e0ca89f751cd14d767638e2550c77a92a9e749c317", - "sha256:8eade758719add78ec36dc13201483f8e9b5d940329285edcd5f70c0a9edbd7f", - "sha256:911d8a40b2bef5b8bbae2e36a0b103f142ac53557ab421dc16ac4aafee6f53dc", - "sha256:93ad6d87ac18e2a90b0fe89df7c65263b9a99a0eb98f0a3d2e079f12a0735837", - "sha256:95dea361dd73757c6f1c0a1480ac499952c16ac83f7f5f4f84f0658a01b8ef41", - "sha256:9ab77acb98eba3fd2a85cd160851816bfce6871d944d885febf012713f06659c", - "sha256:9cb3032517f1627cc012dbc80a8ec976ae76d93ea2b5feaa9d2a5b8882597579", - "sha256:9cf4e8ad252f7c38dd1f676b46514f92dc0ebeb0db5552f5f403509705e24753", - "sha256:9d9153257a3f70d5f69edf2325357251ed20f772b12e593f3b3377b5f78e7ef8", - "sha256:a152f5f33d64a6be73f1d30c9cc82dfc73cec6477ec268e7c6e4c7d23c2d2291", - "sha256:a16418ecf1329f71df119e8a65f3aa68004a3f9383821edcb20f0702934d8087", - "sha256:a60332922359f920193b1d4826953c507a877b523b2395ad7bc716ddd386d866", - "sha256:a8d0fc946c784ff7f7c3742310cc8a57c5c6dc31631269876a88b809dbeff3d3", - "sha256:ab5de034a886f616a5668aa5d098af2b5385ed70142090e2a31bcbd0af0fdb3d", - "sha256:c22d3fe05ce11d3671297dc8973267daa0f938b93ec716e12e0f6dee81591dc1", - "sha256:c2ac1b08635a8cd4e0cbeaf6f5e922085908d48eb05d44c5ae9eabab148512ca", - "sha256:c512accbd6ff0270939b9ac214b84fb5ada5f0409c44298361b2f5e13f9aed9e", - "sha256:c75ffc45f25324e68ab238cb4b5c0a38cd1c3d7f1fb1f72b5541de469e2247db", - "sha256:c95a03c79bbe30eec3ec2b7f076074f4281526724c8685a42872974ef4d36b72", - "sha256:cadaeaba78750d58d3cc6ac4d1fd867da6fc73c88156b7a3212a3cd4819d679d", - "sha256:cd6056167405314a4dc3c173943f11249fa0f1b204f8b51ed4bde1a9cd1834dc", - "sha256:db72b07027db150f468fbada4d85b3b2729a3db39178abf5c543b784c1254539", - "sha256:df2c707231459e8a4028eabcd3cfc827befd635b3ef72eada84ab13b52e1574d", - "sha256:e62164b50f84e20601c1ff8eb55620d2ad25fb81b59e3cd776a1902527a788af", - "sha256:e696f0dd336161fca9adbb846875d40752e6eba585843c768935ba5c9960722b", - "sha256:eaa379fcd227ca235d04152ca6704c7cb55564116f8bc52545ff357628e10602", - "sha256:ebea339af930f8ca5d7a699b921106c6e29c617fe9606fa7baa043c1cdae326f", - "sha256:f4c39b0e3eac288fedc2b43055cfc2ca7a60362d0e5e87a637beac5d801ef478", - "sha256:f5057856d21e7586765171eac8b9fc3f7d44ef39425f85dbcccb13b3ebea806c", - "sha256:f6f45710b4459401609ebebdbcfb34515da4fc2aa886f95107f556ac69a9147e", - "sha256:f97e83fa6c25693c7a35de154681fcc257c1c41b38beb0304b9c4d2d9e164479", - "sha256:f9d0c5c045a3ca9bedfc35dca8526798eb91a07aa7a2c0fee134c6c6f321cbd7", - "sha256:ff6f3db31555657f3163b15a6b7c6938d08df7adbfc9dd13d9d19edad678f1e8" + "sha256:04e57ab9fbf9607b77f7d057974694b4f6b142da9ed4a199859d9d4d5c63fe96", + "sha256:09393e1b2a9461950b1c9a45d5fd251dc7c6f228acab64da1c9c0165d9c7765c", + "sha256:0b87549028f680ca955556e3bd57013ab47474c3124dc069faa0b6545b6c9710", + "sha256:1000fba1057b92a65daec275aec30586c3de2401ccdcd41f8a5c1e2c87078706", + "sha256:1249cbbf3d3b04902ff081ffbb33ce3377fa6e4c7356f759f3cd076cc138d020", + "sha256:1920d4ff15ce893210c1f0c0e9d19bfbecb7983c76b33f046c13a8ffbd570252", + "sha256:193cbc708ea3aca45e7221ae58f0fd63f933753a9bfb498a3b474878f12caaad", + "sha256:1a100c6d595a7f316f1b6f01d20815d916e75ff98c27a01ae817439ea7726329", + "sha256:1f30b48dd7fa1474554b0b0f3fdfdd4c13b5c737a3c6284d3cdc424ec0ffff3a", + "sha256:203f0c8871d5a7987be20c72442488a0b8cfd0f43b7973771640fc593f56321f", + "sha256:246de67b99b6851627d945db38147d1b209a899311b1305dd84916f2b88526c6", + "sha256:2dee8e57f052ef5353cf608e0b4c871aee320dd1b87d351c28764fc0ca55f9f4", + "sha256:2efb1bd13885392adfda4614c33d3b68dee4921fd0ac1d3988f8cbb7d589e72a", + "sha256:2f4ac36d8e2b4cc1aa71df3dd84ff8efbe3bfb97ac41242fbcfc053c67434f46", + "sha256:3170c9399da12c9dc66366e9d14da8bf7147e1e9d9ea566067bbce7bb74bd9c2", + "sha256:3b1613dd5aee995ec6d4c69f00378bbd07614702a315a2cf6c1d21461fe17c23", + "sha256:3bb3d25a8e6c0aedd251753a79ae98a093c7e7b471faa3aa9a93a81431987ace", + "sha256:3bb7fda7260735efe66d5107fb7e6af6a7c04c7fce9b2514e04b7a74b06bf5dd", + "sha256:41b25eaa7d15909cf3ac4c96088c1f266a9a93ec44f87f1d13d4a0e86c81b982", + "sha256:45de3f87179c1823e6d9e32156fb14c1927fcc9aba21433f088fdfb555b77c10", + "sha256:46fb8c61d794b78ec7134a715a3e564aafc8f6b5e338417cb19fe9f57a5a9bf2", + "sha256:48021783bdf96e3d6de03a6e39a1171ed5bd7e8bb93fc84cc649d11490f87cea", + "sha256:4957669ef390f0e6719db3613ab3a7631e68424604a7b448f079bee145da6e09", + "sha256:5e86d77b090dbddbe78867a0275cb4df08ea195e660f1f7f13435a4649e954e5", + "sha256:6339d047dab2780cc6220f46306628e04d9750f02f983ddb37439ca47ced7149", + "sha256:681eb3d7e02e3c3655d1b16059fbfb605ac464c834a0c629048a30fad2b27489", + "sha256:6c409c0deba34f147f77efaa67b8e4bb83d2f11c8806405f76397ae5b8c0d1c9", + "sha256:7095f6fbfaa55defb6b733cfeb14efaae7a29f0b59d8cf213be4e7ca0b857b80", + "sha256:70c610f6cbe4b9fce272c407dd9d07e33e6bf7b4aa1b7ffb6f6ded8e634e3592", + "sha256:72814c01533f51d68702802d74f77ea026b5ec52793c791e2da806a3844a46c3", + "sha256:7a4826ad2bd6b07ca615c74ab91f32f6c96d08f6fcc3902ceeedaec8cdc3bcd6", + "sha256:7c70087bfee18a42b4040bb9ec1ca15a08242cf5867c58726530bdf3945672ed", + "sha256:855eafa5d5a2034b4621c74925d89c5efef61418570e5ef9b37717d9c796419c", + "sha256:8700f06d0ce6f128de3ccdbc1acaea1ee264d2caa9ca05daaf492fde7c2a7200", + "sha256:89f1b185a01fe560bc8ae5f619e924407efca2191b56ce749ec84982fc59a32a", + "sha256:8b2c760cfc7042b27ebdb4a43a4453bd829a5742503599144d54a032c5dc7e9e", + "sha256:8c2f5e83493748286002f9369f3e6607c565a6a90425a3a1fef5ae32a36d749d", + "sha256:8e098148dd37b4ce3baca71fb394c81dc5d9c7728c95df695d2dca218edf40e6", + "sha256:94aea8eff76ee6d1cdacb07dd2123a68283cb5569e0250feab1240058f53b623", + "sha256:95eb302ff792e12aba9a8b8f8474ab229a83c103d74a750ec0bd1c1eea32e669", + "sha256:9bd9b3b31adcb054116447ea22caa61a285d92e94d710aa5ec97992ff5eb7cf3", + "sha256:9e608aafdb55eb9f255034709e20d5a83b6d60c054df0802fa9c9883d0a937aa", + "sha256:a103b3a7069b62f5d4890ae1b8f0597618f628b286b03d4bc9195230b154bfa9", + "sha256:a386ebe437176aab38c041de1260cd3ea459c6ce5263594399880bbc398225b2", + "sha256:a38856a971c602f98472050165cea2cdc97709240373041b69030be15047691f", + "sha256:a401b4598e5d3f4a9a811f3daf42ee2291790c7f9d74b18d75d6e21dda98a1a1", + "sha256:a7647ebdfb9682b7bb97e2a5e7cb6ae735b1c25008a70b906aecca294ee96cf4", + "sha256:aaf63899c94de41fe3cf934601b0f7ccb6b428c6e4eeb80da72c58eab077b19a", + "sha256:b0dac0ff919ba34d4df1b6131f59ce95b08b9065233446be7e459f95554c0dc8", + "sha256:baacc6aee0b2ef6f3d308e197b5d7a81c0e70b06beae1f1fcacffdbd124fe0e3", + "sha256:bf420121d4c8dce6b889f0e8e4ec0ca34b7f40186203f06a946fa0276ba54029", + "sha256:c04a46716adde8d927adb9457bbe39cf473e1e2c2f5d0a16ceb837e5d841ad4f", + "sha256:c0b21078a4b56965e2b12f247467b234734491897e99c1d51cee628da9786959", + "sha256:c1c76a1743432b4b60ab3358c937a3fe1341c828ae6194108a94c69028247f22", + "sha256:c4983bf937209c57240cff65906b18bb35e64ae872da6a0db937d7b4af845dd7", + "sha256:c4fb39a81950ec280984b3a44f5bd12819953dc5fa3a7e6fa7a80db5ee853952", + "sha256:c57921cda3a80d0f2b8aec7e25c8aa14479ea92b5b51b6876d975d925a2ea346", + "sha256:c8063cf17b19661471ecbdb3df1c84f24ad2e389e326ccaf89e3fb2484d8dd7e", + "sha256:ccd16eb18a849fd8dcb23e23380e2f0a354e8daa0c984b8a732d9cfaba3a776d", + "sha256:cd6dbe0238f7743d0efe563ab46294f54f9bc8f4b9bcf57c3c666cc5bc9d1299", + "sha256:d62e51710986674142526ab9f78663ca2b0726066ae26b78b22e0f5e571238dd", + "sha256:db901e2ac34c931d73054d9797383d0f8009991e723dab15109740a63e7f902a", + "sha256:e03b8895a6990c9ab2cdcd0f2fe44088ca1c65ae592b8f795c3294af00a461c3", + "sha256:e1c8a2f4c69e08e89632defbfabec2feb8a8d99edc9f89ce33c4b9e36ab63037", + "sha256:e4b749b9cc6ee664a3300bb3a273c1ca8068c46be705b6c31cf5d276f8628a94", + "sha256:e6a5bf2cba5ae1bb80b154ed68a3cfa2fa00fde979a7f50d6598d3e17d9ac20c", + "sha256:e857a2232ba53ae940d3456f7533ce6ca98b81917d47adc3c7fd55dad8fab858", + "sha256:ee4006268ed33370957f55bf2e6f4d263eaf4dc3cfc473d1d90baff6ed36ce4a", + "sha256:eef9df1eefada2c09a5e7a40991b9fc6ac6ef20b1372abd48d2794a316dc0449", + "sha256:f058f6963fd82eb143c692cecdc89e075fa0828db2e5b291070485390b2f1c9c", + "sha256:f25c229a6ba38a35ae6e25ca1264621cc25d4d38dca2942a7fce0b67a4efe918", + "sha256:f2a1d0fd4242bd8643ce6f98927cf9c04540af6efa92323e9d3124f57727bfc1", + "sha256:f7560358a6811e52e9c4d142d497f1a6e10103d3a6881f18d04dbce3729c0e2c", + "sha256:f779d3ad205f108d14e99bb3859aa7dd8e9c68874617c72354d7ecaec2a054ac", + "sha256:f87f746ee241d30d6ed93969de31e5ffd09a2961a051e60ae6bddde9ec3583aa" ], - "markers": "python_version >= '3.6'", - "version": "==3.0.1" + "markers": "python_version >= '3.7'", + "version": "==3.2.0" }, "click": { "hashes": [ - "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e", - "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48" + "sha256:48ee849951919527a045bfe3bf7baa8a959c423134e1a5b98c05c20ba75a1cbd", + "sha256:fa244bb30b3b5ee2cae3da8f55c9e5e0c0e86093306301fb418eb9dc40fbded5" ], "markers": "python_version >= '3.7'", - "version": "==8.1.3" + "version": "==8.1.6" }, "deprecated": { "hashes": [ - "sha256:43ac5335da90c31c24ba028af536a91d41d53f9e6901ddb021bcc572ce44e38d", - "sha256:64756e3e14c8c5eea9795d93c524551432a0be75629f8f29e67ab8caf076c76d" + "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c", + "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3" ], "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==1.2.13" + "version": "==1.2.14" }, "ecdsa": { "hashes": [ @@ -176,11 +163,10 @@ }, "flasgger": { "hashes": [ - "sha256:0603941cf4003626b4ee551ca87331f1d17b8eecce500ccf1a1f1d3a332fc94a", - "sha256:6ebea406b5beecd77e8da42550f380d4d05a6107bc90b69ce9e77aee7612e2d0" + "sha256:ca098e10bfbb12f047acc6299cc70a33851943a746e550d86e65e60d4df245fb" ], "index": "pypi", - "version": "==0.9.5" + "version": "==0.9.7.1" }, "flask": { "hashes": [ @@ -248,19 +234,19 @@ }, "importlib-metadata": { "hashes": [ - "sha256:7efb448ec9a5e313a57655d35aa54cd3e01b7e1fbcf72dce1bf06119420f5bad", - "sha256:e354bedeb60efa6affdcc8ae121b73544a7aa74156d047311948f6d711cd378d" + "sha256:3ebb78df84a805d7698245025b975d9d67053cd94c79245ba4b3eb694abe68bb", + "sha256:dbace7892d8c0c4ac1ad096662232f831d4e64f4c4545bd53016a3e9d4654743" ], "markers": "python_version < '3.9'", - "version": "==6.0.0" + "version": "==6.8.0" }, "importlib-resources": { "hashes": [ - "sha256:1e534a02295f3eeee0785e21b26c726557909cbaf1b871cf9adcbc0df44c1308", - "sha256:c0a55f37559b5e9ca1d3fce02d60243846245ad8f8d806a4484093806d4d0ae5" + "sha256:134832a506243891221b88b4ae1213327eea96ceb4e407a00d790bb0626f45cf", + "sha256:4359457e42708462b9626a04657c6208ad799ceb41e5c58c57ffa0e6a098a5d4" ], "markers": "python_version < '3.9'", - "version": "==5.11.0" + "version": "==6.0.1" }, "itsdangerous": { "hashes": [ @@ -280,19 +266,27 @@ }, "jsonschema": { "hashes": [ - "sha256:0f864437ab8b6076ba6707453ef8f98a6a0d512a80e93f8abdb676f737ecb60d", - "sha256:a870ad254da1a8ca84b6a2905cac29d265f805acc57af304784962a2aa6508f6" + "sha256:043dc26a3845ff09d20e4420d6012a9c91c9aa8999fa184e7efcfeccb41e32cb", + "sha256:6e1e7569ac13be8139b2dd2c21a55d350066ee3f80df06c608b398cdc6f30e8f" ], - "markers": "python_version >= '3.7'", - "version": "==4.17.3" + "markers": "python_version >= '3.8'", + "version": "==4.19.0" + }, + "jsonschema-specifications": { + "hashes": [ + "sha256:05adf340b659828a004220a9613be00fa3f223f2b82002e273dee62fd50524b1", + "sha256:c91a50404e88a1f6ba40636778e2ee08f6e24c5613fe4c53ac24578a5a7f72bb" + ], + "markers": "python_version >= '3.8'", + "version": "==2023.7.1" }, "limits": { "hashes": [ - "sha256:3e12a0d90bc1fb7f3d95fe61c5a76770aaeb21d50f590268187a8884d513c1da", - "sha256:6fe1d261162ca6fd8023311273661a7355bc0f4615832bc9a4d6e45c0df59f5e" + "sha256:3ad525faeb7e1c63859ca1cae34c9ed22a8f22c9ea9d96e2f412869f6b36beb9", + "sha256:b728c9ab3c6163997b1d11a51d252d951efd13f0d248ea2403383952498f8a22" ], "markers": "python_version >= '3.7'", - "version": "==3.2.0" + "version": "==3.5.0" }, "mako": { "hashes": [ @@ -304,83 +298,83 @@ }, "markdown-it-py": { "hashes": [ - "sha256:93de681e5c021a432c63147656fe21790bc01231e0cd2da73626f1aa3ac0fe27", - "sha256:cf7e59fed14b5ae17c0006eff14a2d9a00ed5f3a846148153899a0224e2c07da" + "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1", + "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb" ], - "markers": "python_version >= '3.7'", - "version": "==2.1.0" + "markers": "python_version >= '3.8'", + "version": "==3.0.0" }, "markupsafe": { "hashes": [ - "sha256:0576fe974b40a400449768941d5d0858cc624e3249dfd1e0c33674e5c7ca7aed", - "sha256:085fd3201e7b12809f9e6e9bc1e5c96a368c8523fad5afb02afe3c051ae4afcc", - "sha256:090376d812fb6ac5f171e5938e82e7f2d7adc2b629101cec0db8b267815c85e2", - "sha256:0b462104ba25f1ac006fdab8b6a01ebbfbce9ed37fd37fd4acd70c67c973e460", - "sha256:137678c63c977754abe9086a3ec011e8fd985ab90631145dfb9294ad09c102a7", - "sha256:1bea30e9bf331f3fef67e0a3877b2288593c98a21ccb2cf29b74c581a4eb3af0", - "sha256:22152d00bf4a9c7c83960521fc558f55a1adbc0631fbb00a9471e097b19d72e1", - "sha256:22731d79ed2eb25059ae3df1dfc9cb1546691cc41f4e3130fe6bfbc3ecbbecfa", - "sha256:2298c859cfc5463f1b64bd55cb3e602528db6fa0f3cfd568d3605c50678f8f03", - "sha256:28057e985dace2f478e042eaa15606c7efccb700797660629da387eb289b9323", - "sha256:2e7821bffe00aa6bd07a23913b7f4e01328c3d5cc0b40b36c0bd81d362faeb65", - "sha256:2ec4f2d48ae59bbb9d1f9d7efb9236ab81429a764dedca114f5fdabbc3788013", - "sha256:340bea174e9761308703ae988e982005aedf427de816d1afe98147668cc03036", - "sha256:40627dcf047dadb22cd25ea7ecfe9cbf3bbbad0482ee5920b582f3809c97654f", - "sha256:40dfd3fefbef579ee058f139733ac336312663c6706d1163b82b3003fb1925c4", - "sha256:4cf06cdc1dda95223e9d2d3c58d3b178aa5dacb35ee7e3bbac10e4e1faacb419", - "sha256:50c42830a633fa0cf9e7d27664637532791bfc31c731a87b202d2d8ac40c3ea2", - "sha256:55f44b440d491028addb3b88f72207d71eeebfb7b5dbf0643f7c023ae1fba619", - "sha256:608e7073dfa9e38a85d38474c082d4281f4ce276ac0010224eaba11e929dd53a", - "sha256:63ba06c9941e46fa389d389644e2d8225e0e3e5ebcc4ff1ea8506dce646f8c8a", - "sha256:65608c35bfb8a76763f37036547f7adfd09270fbdbf96608be2bead319728fcd", - "sha256:665a36ae6f8f20a4676b53224e33d456a6f5a72657d9c83c2aa00765072f31f7", - "sha256:6d6607f98fcf17e534162f0709aaad3ab7a96032723d8ac8750ffe17ae5a0666", - "sha256:7313ce6a199651c4ed9d7e4cfb4aa56fe923b1adf9af3b420ee14e6d9a73df65", - "sha256:7668b52e102d0ed87cb082380a7e2e1e78737ddecdde129acadb0eccc5423859", - "sha256:7df70907e00c970c60b9ef2938d894a9381f38e6b9db73c5be35e59d92e06625", - "sha256:7e007132af78ea9df29495dbf7b5824cb71648d7133cf7848a2a5dd00d36f9ff", - "sha256:835fb5e38fd89328e9c81067fd642b3593c33e1e17e2fdbf77f5676abb14a156", - "sha256:8bca7e26c1dd751236cfb0c6c72d4ad61d986e9a41bbf76cb445f69488b2a2bd", - "sha256:8db032bf0ce9022a8e41a22598eefc802314e81b879ae093f36ce9ddf39ab1ba", - "sha256:99625a92da8229df6d44335e6fcc558a5037dd0a760e11d84be2260e6f37002f", - "sha256:9cad97ab29dfc3f0249b483412c85c8ef4766d96cdf9dcf5a1e3caa3f3661cf1", - "sha256:a4abaec6ca3ad8660690236d11bfe28dfd707778e2442b45addd2f086d6ef094", - "sha256:a6e40afa7f45939ca356f348c8e23048e02cb109ced1eb8420961b2f40fb373a", - "sha256:a6f2fcca746e8d5910e18782f976489939d54a91f9411c32051b4aab2bd7c513", - "sha256:a806db027852538d2ad7555b203300173dd1b77ba116de92da9afbc3a3be3eed", - "sha256:abcabc8c2b26036d62d4c746381a6f7cf60aafcc653198ad678306986b09450d", - "sha256:b8526c6d437855442cdd3d87eede9c425c4445ea011ca38d937db299382e6fa3", - "sha256:bb06feb762bade6bf3c8b844462274db0c76acc95c52abe8dbed28ae3d44a147", - "sha256:c0a33bc9f02c2b17c3ea382f91b4db0e6cde90b63b296422a939886a7a80de1c", - "sha256:c4a549890a45f57f1ebf99c067a4ad0cb423a05544accaf2b065246827ed9603", - "sha256:ca244fa73f50a800cf8c3ebf7fd93149ec37f5cb9596aa8873ae2c1d23498601", - "sha256:cf877ab4ed6e302ec1d04952ca358b381a882fbd9d1b07cccbfd61783561f98a", - "sha256:d9d971ec1e79906046aa3ca266de79eac42f1dbf3612a05dc9368125952bd1a1", - "sha256:da25303d91526aac3672ee6d49a2f3db2d9502a4a60b55519feb1a4c7714e07d", - "sha256:e55e40ff0cc8cc5c07996915ad367fa47da6b3fc091fdadca7f5403239c5fec3", - "sha256:f03a532d7dee1bed20bc4884194a16160a2de9ffc6354b3878ec9682bb623c54", - "sha256:f1cd098434e83e656abf198f103a8207a8187c0fc110306691a2e94a78d0abb2", - "sha256:f2bfb563d0211ce16b63c7cb9395d2c682a23187f54c3d79bfec33e6705473c6", - "sha256:f8ffb705ffcf5ddd0e80b65ddf7bed7ee4f5a441ea7d3419e861a12eaf41af58" + "sha256:05fb21170423db021895e1ea1e1f3ab3adb85d1c2333cbc2310f2a26bc77272e", + "sha256:0a4e4a1aff6c7ac4cd55792abf96c915634c2b97e3cc1c7129578aa68ebd754e", + "sha256:10bbfe99883db80bdbaff2dcf681dfc6533a614f700da1287707e8a5d78a8431", + "sha256:134da1eca9ec0ae528110ccc9e48041e0828d79f24121a1a146161103c76e686", + "sha256:1577735524cdad32f9f694208aa75e422adba74f1baee7551620e43a3141f559", + "sha256:1b40069d487e7edb2676d3fbdb2b0829ffa2cd63a2ec26c4938b2d34391b4ecc", + "sha256:282c2cb35b5b673bbcadb33a585408104df04f14b2d9b01d4c345a3b92861c2c", + "sha256:2c1b19b3aaacc6e57b7e25710ff571c24d6c3613a45e905b1fde04d691b98ee0", + "sha256:2ef12179d3a291be237280175b542c07a36e7f60718296278d8593d21ca937d4", + "sha256:338ae27d6b8745585f87218a3f23f1512dbf52c26c28e322dbe54bcede54ccb9", + "sha256:3c0fae6c3be832a0a0473ac912810b2877c8cb9d76ca48de1ed31e1c68386575", + "sha256:3fd4abcb888d15a94f32b75d8fd18ee162ca0c064f35b11134be77050296d6ba", + "sha256:42de32b22b6b804f42c5d98be4f7e5e977ecdd9ee9b660fda1a3edf03b11792d", + "sha256:504b320cd4b7eff6f968eddf81127112db685e81f7e36e75f9f84f0df46041c3", + "sha256:525808b8019e36eb524b8c68acdd63a37e75714eac50e988180b169d64480a00", + "sha256:56d9f2ecac662ca1611d183feb03a3fa4406469dafe241673d521dd5ae92a155", + "sha256:5bbe06f8eeafd38e5d0a4894ffec89378b6c6a625ff57e3028921f8ff59318ac", + "sha256:65c1a9bcdadc6c28eecee2c119465aebff8f7a584dd719facdd9e825ec61ab52", + "sha256:68e78619a61ecf91e76aa3e6e8e33fc4894a2bebe93410754bd28fce0a8a4f9f", + "sha256:69c0f17e9f5a7afdf2cc9fb2d1ce6aabdb3bafb7f38017c0b77862bcec2bbad8", + "sha256:6b2b56950d93e41f33b4223ead100ea0fe11f8e6ee5f641eb753ce4b77a7042b", + "sha256:787003c0ddb00500e49a10f2844fac87aa6ce977b90b0feaaf9de23c22508b24", + "sha256:7ef3cb2ebbf91e330e3bb937efada0edd9003683db6b57bb108c4001f37a02ea", + "sha256:8023faf4e01efadfa183e863fefde0046de576c6f14659e8782065bcece22198", + "sha256:8758846a7e80910096950b67071243da3e5a20ed2546e6392603c096778d48e0", + "sha256:8afafd99945ead6e075b973fefa56379c5b5c53fd8937dad92c662da5d8fd5ee", + "sha256:8c41976a29d078bb235fea9b2ecd3da465df42a562910f9022f1a03107bd02be", + "sha256:8e254ae696c88d98da6555f5ace2279cf7cd5b3f52be2b5cf97feafe883b58d2", + "sha256:9402b03f1a1b4dc4c19845e5c749e3ab82d5078d16a2a4c2cd2df62d57bb0707", + "sha256:962f82a3086483f5e5f64dbad880d31038b698494799b097bc59c2edf392fce6", + "sha256:9dcdfd0eaf283af041973bff14a2e143b8bd64e069f4c383416ecd79a81aab58", + "sha256:aa7bd130efab1c280bed0f45501b7c8795f9fdbeb02e965371bbef3523627779", + "sha256:ab4a0df41e7c16a1392727727e7998a467472d0ad65f3ad5e6e765015df08636", + "sha256:ad9e82fb8f09ade1c3e1b996a6337afac2b8b9e365f926f5a61aacc71adc5b3c", + "sha256:af598ed32d6ae86f1b747b82783958b1a4ab8f617b06fe68795c7f026abbdcad", + "sha256:b076b6226fb84157e3f7c971a47ff3a679d837cf338547532ab866c57930dbee", + "sha256:b7ff0f54cb4ff66dd38bebd335a38e2c22c41a8ee45aa608efc890ac3e3931bc", + "sha256:bfce63a9e7834b12b87c64d6b155fdd9b3b96191b6bd334bf37db7ff1fe457f2", + "sha256:c011a4149cfbcf9f03994ec2edffcb8b1dc2d2aede7ca243746df97a5d41ce48", + "sha256:c9c804664ebe8f83a211cace637506669e7890fec1b4195b505c214e50dd4eb7", + "sha256:ca379055a47383d02a5400cb0d110cef0a776fc644cda797db0c5696cfd7e18e", + "sha256:cb0932dc158471523c9637e807d9bfb93e06a95cbf010f1a38b98623b929ef2b", + "sha256:cd0f502fe016460680cd20aaa5a76d241d6f35a1c3350c474bac1273803893fa", + "sha256:ceb01949af7121f9fc39f7d27f91be8546f3fb112c608bc4029aef0bab86a2a5", + "sha256:d080e0a5eb2529460b30190fcfcc4199bd7f827663f858a226a81bc27beaa97e", + "sha256:dd15ff04ffd7e05ffcb7fe79f1b98041b8ea30ae9234aed2a9168b5797c3effb", + "sha256:df0be2b576a7abbf737b1575f048c23fb1d769f267ec4358296f31c2479db8f9", + "sha256:e09031c87a1e51556fdcb46e5bd4f59dfb743061cf93c4d6831bf894f125eb57", + "sha256:e4dd52d80b8c83fdce44e12478ad2e85c64ea965e75d66dbeafb0a3e77308fcc", + "sha256:fec21693218efe39aa7f8599346e90c705afa52c5b31ae019b2e57e8f6542bb2" ], "markers": "python_version >= '3.7'", - "version": "==2.1.2" + "version": "==2.1.3" }, "marshmallow": { "hashes": [ - "sha256:90032c0fd650ce94b6ec6dc8dfeb0e3ff50c144586462c389b81a07205bedb78", - "sha256:93f0958568da045b0021ec6aeb7ac37c81bfcccbb9a0e7ed8559885070b3a19b" + "sha256:5d2371bbe42000f2b3fb5eaa065224df7d8f8597bc19a1bbfa5bfe7fba8da889", + "sha256:684939db93e80ad3561392f47be0230743131560a41c5110684c16e21ade0a5c" ], - "markers": "python_version >= '3.7'", - "version": "==3.19.0" + "markers": "python_version >= '3.8'", + "version": "==3.20.1" }, "marshmallow-sqlalchemy": { "hashes": [ - "sha256:aa376747296780a56355e3067b9c8bf43a2a1c44ff985de82b3a5d9e161ca2b8", - "sha256:dbb061c19375eca3a7d18358d2ca8bbaee825fc3000a3f114e2698282362b536" + "sha256:2ab0f1280c793e5aec81deab3e63ec23688ddfe05e5f38ac960368a1079520a1", + "sha256:c31b3bdf794de1d78c53e1c495502cbb3eeb06ed216869980c71d6159e7e9e66" ], "index": "pypi", - "version": "==0.28.1" + "version": "==0.28.2" }, "mdurl": { "hashes": [ @@ -392,41 +386,38 @@ }, "mistune": { "hashes": [ - "sha256:0246113cb2492db875c6be56974a7c893333bf26cd92891c85f63151cee09d34", - "sha256:bad7f5d431886fcbaf5f758118ecff70d31f75231b34024a1341120340a65ce8" + "sha256:b9b3e438efbb57c62b5beb5e134dab664800bdf1284a7ee09e8b12b13eb1aac6", + "sha256:e912116c13aa0944f9dc530db38eb88f6a77087ab128f49f84a48f4c05ea163c" ], - "version": "==2.0.5" + "markers": "python_version >= '3.7'", + "version": "==3.0.1" }, "mysql-connector-python": { "hashes": [ - "sha256:145aeb75eefb7425e0a7fb36a4f95ebfe79e06be7c69a4045d34cde95c666dc4", - "sha256:1c0a11f3ffbf850f2ca7b39e6c82021e8de910ddaeffd856e53dca028d21c923", - "sha256:1f399f3c2599d2591854cd0e0a24c7c399dff21ac5accb6e52e06924de29f3f4", - "sha256:232095f0c36266510009b0f1214d2823a649efb8bc511dbab9ce8847f66ab08a", - "sha256:283fe6f647e9d684feb1b7c48fa6a46b1e72c59ecdd6ea2b62392cd80c1a6701", - "sha256:4b2d00c9e2cb9e3d11c57ec411226f43aa627607085fbed661cfea1c4dc57f61", - "sha256:4df11c683924ef34c177a54887dc4844ae735b01c8a29ce6ab92d6d3db7a2757", - "sha256:677b5c6dcaec7e2a4bf95b991a869f4d371114f69a0d9a5bb236e988c8f4c376", - "sha256:6cdba2779bcd16af0ceff0a6e50d33e6664a83f8d17d70524beb6f677a6d1fae", - "sha256:7f7a69db9e0c36764a6c65377f6174aee46e484520e48659e7aa674415b8e192", - "sha256:8c334c41cd1c5bcfa3550340253ef7d9d3b962211f33327c20f69706a0bcce06", - "sha256:8c5bfedc979d7858402f39c20d66a6cf03ca4c960732a98318126c278535ddb2", - "sha256:93b1eb3e07d19a23ccf2605d818aacee0d842b1820bbeef8d0022d8d3d014ab9", - "sha256:992b7a464daa398e86df8c75f7d8cd6044f884ff9087e782120fc8beff96c638", - "sha256:ab13dd6ede0e0e99ba97c73946462c3420625ab6e63fe13b6fc350e30eb3298d", - "sha256:bd52a462759aa324a60054c4b44dc8b32007187a328f72be6b58f193d5e32a91", - "sha256:bdd716b1e162fe4b3887f6617e9ddcfa659ba96a9ddb22feeae208a72f43d22f", - "sha256:be82357cc7e7e1377e2f4f8c18aa89c8aab6c0117155cf9fcf18e3cd0eb6ac8e", - "sha256:c2d20b29fd096a0633f9360c275bd2434d4bcf597281991c4b7f1c820cd07b84", - "sha256:c8bba02501525e1fbbba094a6d8d391d1534e8be41be6396c3e1b9f7d9d13b1c", - "sha256:c990f4c0702d1739076261c4dece1042e1eb18bf34e0d8516d19ec5166a205ce", - "sha256:d6b54656ca131a4f0f17b9d0adddc60f84fd982d64e06360026d5b06e5dbf865", - "sha256:e0299236297b63bf6cbb61d81a9d400bc01cad4743d1abe5296ef349de15ee53", - "sha256:e722b6ffa5b0d7188eebac792b18bc871643db505bf60d0e6bd2859f31e5ed79", - "sha256:fd233c83daaf048c1f9827be984c2721576ae0adf50e139429a06ccd094987d9" + "sha256:1d292d8ee08a3e0103f3e9aba81f292c12c244c1d5345168375bf6842b2b3e9b", + "sha256:22259479bdba53e0eb64325d5d97d7ecae35e729a8b39822c16729476ba2cd92", + "sha256:40e3b5d60dbc5446ccd1901eb3db4c9b1ad07a490f4e0fc96e7ac53a6fe9b7bc", + "sha256:4f58e1d41b3ba04281099884421c3a63589204b2cf40e473c5dbebbc26971017", + "sha256:556f83cfc3e1f3e3db0080bb19ca50650815551ef7e10518053fe2ba76d2e59e", + "sha256:5f1cdf9d3ed2f3c70a91c4b94d3ab3b2890c477a61b4085bb89d2275c50e1e3d", + "sha256:64f4d7f7c60e2fe5a01d9e7915634d05a350bd866332ea4eab281b29db190e2b", + "sha256:76432810ee58abda81e0a34666f86aba69a7ded58f164a1d19835dba70b1451b", + "sha256:78a43eeb2b845986dc769ab611e3c480991c8037c94aee67ee6842d1f7e961a9", + "sha256:7abe27b88ae1354433713fc289ed663cc04f7b75ea818a2b18067c3a736b0975", + "sha256:7f1cbc06411115c318af775291386ed1494302e05b5c45da73f01593c0827bc1", + "sha256:8062c11619bc48baf9ada3f85d85832aec5e57359eb11ed9e7d75ddcce81721a", + "sha256:816b46c9dc250a0e59d11a902e187be190dae992a2b802512b888930db380487", + "sha256:89151683654748f4de59cd4cf04102b6180976923f1db9921b87cff2c2da7b1d", + "sha256:90adf52cdb25a7adc18da0cc6c5454709598af0e87343e39ab2c11d7dc5aaf34", + "sha256:9cc256eaf55a7dd706ae514bebb863d3e426bd12686b88e284bdad6c37bf6dde", + "sha256:dd0005e9b7e54c700745416ecf26435c69687d5234eef9ff11cf85a7d76945e2", + "sha256:e3a2c2b398af1c5f0cbc1b1935f98bb5a7da4f178b2e73f0851872fbb37e66cc", + "sha256:f2ac6d43fc5a01e574fcc2a6b732cc2374e6ce576ee039cc2051f18d2daafd6d", + "sha256:f36a1a308d0d0d6202fea2e51741b5265f60206be331cfbb32f2f5bf62a20359", + "sha256:f8160777788c7e561f9d7f93eff45776031c83aa2f02a0d8c138d8f9c9bd088e" ], "index": "pypi", - "version": "==8.0.32" + "version": "==8.1.0" }, "ordered-set": { "hashes": [ @@ -438,11 +429,11 @@ }, "packaging": { "hashes": [ - "sha256:714ac14496c3e68c99c29b00845f7a2b85f3bb6f1078fd9f72fd20f0570002b2", - "sha256:b6ad297f8907de0fa2fe1ccbd26fdaf387f5f47c7275fedf8cce89f99446cf97" + "sha256:994793af429502c4ea2ebf6bf664629d07c1a9fe974af92966e4b8d2df7edc61", + "sha256:a392980d2b6cffa644431898be54b0045151319d1e7ec34f0cfed48767dd334f" ], "markers": "python_version >= '3.7'", - "version": "==23.0" + "version": "==23.1" }, "pkgutil-resolve-name": { "hashes": [ @@ -454,98 +445,64 @@ }, "protobuf": { "hashes": [ - "sha256:03038ac1cfbc41aa21f6afcbcd357281d7521b4157926f30ebecc8d4ea59dcb7", - "sha256:28545383d61f55b57cf4df63eebd9827754fd2dc25f80c5253f9184235db242c", - "sha256:2e3427429c9cffebf259491be0af70189607f365c2f41c7c3764af6f337105f2", - "sha256:398a9e0c3eaceb34ec1aee71894ca3299605fa8e761544934378bbc6c97de23b", - "sha256:44246bab5dd4b7fbd3c0c80b6f16686808fab0e4aca819ade6e8d294a29c7050", - "sha256:447d43819997825d4e71bf5769d869b968ce96848b6479397e29fc24c4a5dfe9", - "sha256:67a3598f0a2dcbc58d02dd1928544e7d88f764b47d4a286202913f0b2801c2e7", - "sha256:74480f79a023f90dc6e18febbf7b8bac7508420f2006fabd512013c0c238f454", - "sha256:819559cafa1a373b7096a482b504ae8a857c89593cf3a25af743ac9ecbd23480", - "sha256:899dc660cd599d7352d6f10d83c95df430a38b410c1b66b407a6b29265d66469", - "sha256:8c0c984a1b8fef4086329ff8dd19ac77576b384079247c770f29cc8ce3afa06c", - "sha256:9aae4406ea63d825636cc11ffb34ad3379335803216ee3a856787bcf5ccc751e", - "sha256:a7ca6d488aa8ff7f329d4c545b2dbad8ac31464f1d8b1c87ad1346717731e4db", - "sha256:b6cc7ba72a8850621bfec987cb72623e703b7fe2b9127a161ce61e61558ad905", - "sha256:bf01b5720be110540be4286e791db73f84a2b721072a3711efff6c324cdf074b", - "sha256:c02ce36ec760252242a33967d51c289fd0e1c0e6e5cc9397e2279177716add86", - "sha256:d9e4432ff660d67d775c66ac42a67cf2453c27cb4d738fc22cb53b5d84c135d4", - "sha256:daa564862dd0d39c00f8086f88700fdbe8bc717e993a21e90711acfed02f2402", - "sha256:de78575669dddf6099a8a0f46a27e82a1783c557ccc38ee620ed8cc96d3be7d7", - "sha256:e64857f395505ebf3d2569935506ae0dfc4a15cb80dc25261176c784662cdcc4", - "sha256:f4bd856d702e5b0d96a00ec6b307b0f51c1982c2bf9c0052cf9019e9a544ba99", - "sha256:f4c42102bc82a51108e449cbb32b19b180022941c727bac0cfd50170341f16ee" + "sha256:1f22ac0ca65bb70a876060d96d914dae09ac98d114294f77584b0d2644fa9c30", + "sha256:237216c3326d46808a9f7c26fd1bd4b20015fb6867dc5d263a493ef9a539293b", + "sha256:27f4d15021da6d2b706ddc3860fac0a5ddaba34ab679dc182b60a8bb4e1121cc", + "sha256:299ea899484ee6f44604deb71f424234f654606b983cb496ea2a53e3c63ab791", + "sha256:3d164928ff0727d97022957c2b849250ca0e64777ee31efd7d6de2e07c494717", + "sha256:6ab80df09e3208f742c98443b6166bcb70d65f52cfeb67357d52032ea1ae9bec", + "sha256:78a28c9fa223998472886c77042e9b9afb6fe4242bd2a2a5aced88e3f4422aa7", + "sha256:7cd532c4566d0e6feafecc1059d04c7915aec8e182d1cf7adee8b24ef1e2e6ab", + "sha256:89f9149e4a0169cddfc44c74f230d7743002e3aa0b9472d8c28f0388102fc4c2", + "sha256:a53fd3f03e578553623272dc46ac2f189de23862e68565e83dde203d41b76fc5", + "sha256:b135410244ebe777db80298297a97fbb4c862c881b4403b71bac9d4107d61fd1", + "sha256:b98d0148f84e3a3c569e19f52103ca1feacdac0d2df8d6533cf983d1fda28462", + "sha256:d1736130bce8cf131ac7957fa26880ca19227d4ad68b4888b3be0dea1f95df97", + "sha256:f45460f9ee70a0ec1b6694c6e4e348ad2019275680bd68a1d9314b8c7e01e574" ], "markers": "python_version >= '3.7'", - "version": "==3.20.3" + "version": "==4.21.12" + }, + "psycopg2": { + "hashes": [ + "sha256:1a6a2d609bce44f78af4556bea0c62a5e7f05c23e5ea9c599e07678995609084", + "sha256:44d93a0109dfdf22fe399b419bcd7fa589d86895d3931b01fb321d74dadc68f1", + "sha256:8275abf628c6dc7ec834ea63f6f3846bf33518907a2b9b693d41fd063767a866", + "sha256:91e81a8333a0037babfc9fe6d11e997a9d4dac0f38c43074886b0d9dead94fe9", + "sha256:b22ed9c66da2589a664e0f1ca2465c29b75aaab36fa209d4fb916025fb9119e5", + "sha256:b6bd7d9d3a7a63faae6edf365f0ed0e9b0a1aaf1da3ca146e6b043fb3eb5d723", + "sha256:c7949770cafbd2f12cecc97dea410c514368908a103acf519f2a346134caa4d5", + "sha256:d1210fcf99aae6f728812d1d2240afc1dc44b9e6cba526a06fb8134f969957c2", + "sha256:d5c5297e2fbc8068d4255f1e606bfc9291f06f91ec31b2a0d4c536210ac5c0a2", + "sha256:e9b04cbef584310a1ac0f0d55bb623ca3244c87c51187645432e342de9ae81a8", + "sha256:f00cc35bd7119f1fed17b85bd1007855194dde2cbd8de01ab8ebb17487440ad8" + ], + "index": "pypi", + "version": "==2.9.7" }, "pyasn1": { "hashes": [ - "sha256:014c0e9976956a08139dc0712ae195324a75e142284d5f87f1a87ee1b068a359", - "sha256:03840c999ba71680a131cfaee6fab142e1ed9bbd9c693e285cc6aca0d555e576", - "sha256:0458773cfe65b153891ac249bcf1b5f8f320b7c2ce462151f8fa74de8934becf", - "sha256:08c3c53b75eaa48d71cf8c710312316392ed40899cb34710d092e96745a358b7", - "sha256:39c7e2ec30515947ff4e87fb6f456dfc6e84857d34be479c9d4a4ba4bf46aa5d", - "sha256:5c9414dcfede6e441f7e8f81b43b34e834731003427e5b09e4e00e3172a10f00", - "sha256:6e7545f1a61025a4e58bb336952c5061697da694db1cae97b116e9c46abcf7c8", - "sha256:78fa6da68ed2727915c4767bb386ab32cdba863caa7dbe473eaae45f9959da86", - "sha256:7ab8a544af125fb704feadb008c99a88805126fb525280b2270bb25cc1d78a12", - "sha256:99fcc3c8d804d1bc6d9a099921e39d827026409a58f2a720dcdb89374ea0c776", - "sha256:aef77c9fb94a3ac588e87841208bdec464471d9871bd5050a287cc9a475cd0ba", - "sha256:e89bf84b5437b532b0803ba5c9a5e054d21fec423a89952a74f87fa2c9b7bce2", - "sha256:fec3e9d8e36808a28efb59b489e4528c10ad0f480e57dcc32b4de5c9d8c9fdf3" - ], - "version": "==0.4.8" + "sha256:87a2121042a1ac9358cabcaf1d07680ff97ee6404333bacca15f76aa8ad01a57", + "sha256:97b7290ca68e62a832558ec3976f15cbf911bf5d7c7039d8b861c2a0ece69fde" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'", + "version": "==0.5.0" }, "pygments": { "hashes": [ - "sha256:b3ed06a9e8ac9a9aae5a6f5dbe78a8a58655d17b43b93c078f094ddc476ae297", - "sha256:fa7bd7bd2771287c0de303af8bfdfc731f51bd2c6a47ab69d117138893b82717" - ], - "markers": "python_version >= '3.6'", - "version": "==2.14.0" - }, - "pyrsistent": { - "hashes": [ - "sha256:016ad1afadf318eb7911baa24b049909f7f3bb2c5b1ed7b6a8f21db21ea3faa8", - "sha256:1a2994773706bbb4995c31a97bc94f1418314923bd1048c6d964837040376440", - "sha256:20460ac0ea439a3e79caa1dbd560344b64ed75e85d8703943e0b66c2a6150e4a", - "sha256:3311cb4237a341aa52ab8448c27e3a9931e2ee09561ad150ba94e4cfd3fc888c", - "sha256:3a8cb235fa6d3fd7aae6a4f1429bbb1fec1577d978098da1252f0489937786f3", - "sha256:3ab2204234c0ecd8b9368dbd6a53e83c3d4f3cab10ecaf6d0e772f456c442393", - "sha256:42ac0b2f44607eb92ae88609eda931a4f0dfa03038c44c772e07f43e738bcac9", - "sha256:49c32f216c17148695ca0e02a5c521e28a4ee6c5089f97e34fe24163113722da", - "sha256:4b774f9288dda8d425adb6544e5903f1fb6c273ab3128a355c6b972b7df39dcf", - "sha256:4c18264cb84b5e68e7085a43723f9e4c1fd1d935ab240ce02c0324a8e01ccb64", - "sha256:5a474fb80f5e0d6c9394d8db0fc19e90fa540b82ee52dba7d246a7791712f74a", - "sha256:64220c429e42a7150f4bfd280f6f4bb2850f95956bde93c6fda1b70507af6ef3", - "sha256:878433581fc23e906d947a6814336eee031a00e6defba224234169ae3d3d6a98", - "sha256:99abb85579e2165bd8522f0c0138864da97847875ecbd45f3e7e2af569bfc6f2", - "sha256:a2471f3f8693101975b1ff85ffd19bb7ca7dd7c38f8a81701f67d6b4f97b87d8", - "sha256:aeda827381f5e5d65cced3024126529ddc4289d944f75e090572c77ceb19adbf", - "sha256:b735e538f74ec31378f5a1e3886a26d2ca6351106b4dfde376a26fc32a044edc", - "sha256:c147257a92374fde8498491f53ffa8f4822cd70c0d85037e09028e478cababb7", - "sha256:c4db1bd596fefd66b296a3d5d943c94f4fac5bcd13e99bffe2ba6a759d959a28", - "sha256:c74bed51f9b41c48366a286395c67f4e894374306b197e62810e0fdaf2364da2", - "sha256:c9bb60a40a0ab9aba40a59f68214eed5a29c6274c83b2cc206a359c4a89fa41b", - "sha256:cc5d149f31706762c1f8bda2e8c4f8fead6e80312e3692619a75301d3dbb819a", - "sha256:ccf0d6bd208f8111179f0c26fdf84ed7c3891982f2edaeae7422575f47e66b64", - "sha256:e42296a09e83028b3476f7073fcb69ffebac0e66dbbfd1bd847d61f74db30f19", - "sha256:e8f2b814a3dc6225964fa03d8582c6e0b6650d68a232df41e3cc1b66a5d2f8d1", - "sha256:f0774bf48631f3a20471dd7c5989657b639fd2d285b861237ea9e82c36a415a9", - "sha256:f0e7c4b2f77593871e918be000b96c8107da48444d57005b6a6bc61fb4331b2c" + "sha256:13fc09fa63bc8d8671a6d247e1eb303c4b343eaee81d861f3404db2935653692", + "sha256:1daff0494820c69bc8941e407aa20f577374ee88364ee10a98fdbe0aece96e29" ], "markers": "python_version >= '3.7'", - "version": "==0.19.3" + "version": "==2.16.1" }, "python-dotenv": { "hashes": [ - "sha256:1c93de8f636cde3ce377292818d0e440b6e45a82f215c3744979151fa8151c49", - "sha256:41e12e0318bebc859fcc4d97d4db8d20ad21721a6aa5047dd59f090391cb549a" + "sha256:a8df96034aae6d2d50a4ebe8216326c61c3eb64836776504fcca410e5937a3ba", + "sha256:f5971a9226b701070a4bf2c38c89e5a3f0d64de8debda981d1db98583009122a" ], "index": "pypi", - "version": "==0.21.1" + "version": "==1.0.0" }, "python-jose": { "hashes": [ @@ -557,65 +514,176 @@ }, "pyyaml": { "hashes": [ - "sha256:01b45c0191e6d66c470b6cf1b9531a771a83c1c4208272ead47a3ae4f2f603bf", - "sha256:0283c35a6a9fbf047493e3a0ce8d79ef5030852c51e9d911a27badfde0605293", - "sha256:055d937d65826939cb044fc8c9b08889e8c743fdc6a32b33e2390f66013e449b", - "sha256:07751360502caac1c067a8132d150cf3d61339af5691fe9e87803040dbc5db57", - "sha256:0b4624f379dab24d3725ffde76559cff63d9ec94e1736b556dacdfebe5ab6d4b", - "sha256:0ce82d761c532fe4ec3f87fc45688bdd3a4c1dc5e0b4a19814b9009a29baefd4", - "sha256:1e4747bc279b4f613a09eb64bba2ba602d8a6664c6ce6396a4d0cd413a50ce07", - "sha256:213c60cd50106436cc818accf5baa1aba61c0189ff610f64f4a3e8c6726218ba", - "sha256:231710d57adfd809ef5d34183b8ed1eeae3f76459c18fb4a0b373ad56bedcdd9", - "sha256:277a0ef2981ca40581a47093e9e2d13b3f1fbbeffae064c1d21bfceba2030287", - "sha256:2cd5df3de48857ed0544b34e2d40e9fac445930039f3cfe4bcc592a1f836d513", - "sha256:40527857252b61eacd1d9af500c3337ba8deb8fc298940291486c465c8b46ec0", - "sha256:432557aa2c09802be39460360ddffd48156e30721f5e8d917f01d31694216782", - "sha256:473f9edb243cb1935ab5a084eb238d842fb8f404ed2193a915d1784b5a6b5fc0", - "sha256:48c346915c114f5fdb3ead70312bd042a953a8ce5c7106d5bfb1a5254e47da92", - "sha256:50602afada6d6cbfad699b0c7bb50d5ccffa7e46a3d738092afddc1f9758427f", - "sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2", - "sha256:77f396e6ef4c73fdc33a9157446466f1cff553d979bd00ecb64385760c6babdc", - "sha256:81957921f441d50af23654aa6c5e5eaf9b06aba7f0a19c18a538dc7ef291c5a1", - "sha256:819b3830a1543db06c4d4b865e70ded25be52a2e0631ccd2f6a47a2822f2fd7c", - "sha256:897b80890765f037df3403d22bab41627ca8811ae55e9a722fd0392850ec4d86", - "sha256:98c4d36e99714e55cfbaaee6dd5badbc9a1ec339ebfc3b1f52e293aee6bb71a4", - "sha256:9df7ed3b3d2e0ecfe09e14741b857df43adb5a3ddadc919a2d94fbdf78fea53c", - "sha256:9fa600030013c4de8165339db93d182b9431076eb98eb40ee068700c9c813e34", - "sha256:a80a78046a72361de73f8f395f1f1e49f956c6be882eed58505a15f3e430962b", - "sha256:afa17f5bc4d1b10afd4466fd3a44dc0e245382deca5b3c353d8b757f9e3ecb8d", - "sha256:b3d267842bf12586ba6c734f89d1f5b871df0273157918b0ccefa29deb05c21c", - "sha256:b5b9eccad747aabaaffbc6064800670f0c297e52c12754eb1d976c57e4f74dcb", - "sha256:bfaef573a63ba8923503d27530362590ff4f576c626d86a9fed95822a8255fd7", - "sha256:c5687b8d43cf58545ade1fe3e055f70eac7a5a1a0bf42824308d868289a95737", - "sha256:cba8c411ef271aa037d7357a2bc8f9ee8b58b9965831d9e51baf703280dc73d3", - "sha256:d15a181d1ecd0d4270dc32edb46f7cb7733c7c508857278d3d378d14d606db2d", - "sha256:d4b0ba9512519522b118090257be113b9468d804b19d63c71dbcf4a48fa32358", - "sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53", - "sha256:d4eccecf9adf6fbcc6861a38015c2a64f38b9d94838ac1810a9023a0609e1b78", - "sha256:d67d839ede4ed1b28a4e8909735fc992a923cdb84e618544973d7dfc71540803", - "sha256:daf496c58a8c52083df09b80c860005194014c3698698d1a57cbcfa182142a3a", - "sha256:dbad0e9d368bb989f4515da330b88a057617d16b6a8245084f1b05400f24609f", - "sha256:e61ceaab6f49fb8bdfaa0f92c4b57bcfbea54c09277b1b4f7ac376bfb7a7c174", - "sha256:f84fbc98b019fef2ee9a1cb3ce93e3187a6df0b2538a651bfb890254ba9f90b5" + "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc", + "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741", + "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206", + "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27", + "sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595", + "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62", + "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98", + "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696", + "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d", + "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867", + "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47", + "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486", + "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6", + "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3", + "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007", + "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938", + "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c", + "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735", + "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d", + "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba", + "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8", + "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5", + "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd", + "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3", + "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0", + "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515", + "sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c", + "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c", + "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924", + "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34", + "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43", + "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859", + "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673", + "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a", + "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab", + "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa", + "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c", + "sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585", + "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d", + "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f" ], "markers": "python_version >= '3.6'", - "version": "==6.0" + "version": "==6.0.1" + }, + "referencing": { + "hashes": [ + "sha256:449b6669b6121a9e96a7f9e410b245d471e8d48964c67113ce9afe50c8dd7bdf", + "sha256:794ad8003c65938edcdbc027f1933215e0d0ccc0291e3ce20a4d87432b59efc0" + ], + "markers": "python_version >= '3.8'", + "version": "==0.30.2" }, "requests": { "hashes": [ - "sha256:64299f4909223da747622c030b781c0d7811e359c37124b4bd368fb8c6518baa", - "sha256:98b1b2782e3c6c4904938b84c0eb932721069dfdb9134313beff7c83c2df24bf" + "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f", + "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1" ], "index": "pypi", - "version": "==2.28.2" + "version": "==2.31.0" }, "rich": { "hashes": [ - "sha256:125d96d20c92b946b983d0d392b84ff945461e5a06d3867e9f9e575f8697b67f", - "sha256:8aa57747f3fc3e977684f0176a88e789be314a99f99b43b75d1e9cb5dc6db9e9" + "sha256:146a90b3b6b47cac4a73c12866a499e9817426423f57c5a66949c086191a8808", + "sha256:fb9d6c0a0f643c99eed3875b5377a184132ba9be4d61516a55273d3554d75a39" ], "markers": "python_version >= '3.7'", - "version": "==13.3.1" + "version": "==13.5.2" + }, + "rpds-py": { + "hashes": [ + "sha256:0173c0444bec0a3d7d848eaeca2d8bd32a1b43f3d3fde6617aac3731fa4be05f", + "sha256:01899794b654e616c8625b194ddd1e5b51ef5b60ed61baa7a2d9c2ad7b2a4238", + "sha256:02938432352359805b6da099c9c95c8a0547fe4b274ce8f1a91677401bb9a45f", + "sha256:03421628f0dc10a4119d714a17f646e2837126a25ac7a256bdf7c3943400f67f", + "sha256:03975db5f103997904c37e804e5f340c8fdabbb5883f26ee50a255d664eed58c", + "sha256:0766babfcf941db8607bdaf82569ec38107dbb03c7f0b72604a0b346b6eb3298", + "sha256:07e2c54bef6838fa44c48dfbc8234e8e2466d851124b551fc4e07a1cfeb37260", + "sha256:0836d71ca19071090d524739420a61580f3f894618d10b666cf3d9a1688355b1", + "sha256:095b460e117685867d45548fbd8598a8d9999227e9061ee7f012d9d264e6048d", + "sha256:0e7521f5af0233e89939ad626b15278c71b69dc1dfccaa7b97bd4cdf96536bb7", + "sha256:0f2996fbac8e0b77fd67102becb9229986396e051f33dbceada3debaacc7033f", + "sha256:1054a08e818f8e18910f1bee731583fe8f899b0a0a5044c6e680ceea34f93876", + "sha256:13b602dc3e8dff3063734f02dcf05111e887f301fdda74151a93dbbc249930fe", + "sha256:141acb9d4ccc04e704e5992d35472f78c35af047fa0cfae2923835d153f091be", + "sha256:14c408e9d1a80dcb45c05a5149e5961aadb912fff42ca1dd9b68c0044904eb32", + "sha256:159fba751a1e6b1c69244e23ba6c28f879a8758a3e992ed056d86d74a194a0f3", + "sha256:190ca6f55042ea4649ed19c9093a9be9d63cd8a97880106747d7147f88a49d18", + "sha256:196cb208825a8b9c8fc360dc0f87993b8b260038615230242bf18ec84447c08d", + "sha256:1fcdee18fea97238ed17ab6478c66b2095e4ae7177e35fb71fbe561a27adf620", + "sha256:207f57c402d1f8712618f737356e4b6f35253b6d20a324d9a47cb9f38ee43a6b", + "sha256:24a81c177379300220e907e9b864107614b144f6c2a15ed5c3450e19cf536fae", + "sha256:29cd8bfb2d716366a035913ced99188a79b623a3512292963d84d3e06e63b496", + "sha256:2d8b3b3a2ce0eaa00c5bbbb60b6713e94e7e0becab7b3db6c5c77f979e8ed1f1", + "sha256:35da5cc5cb37c04c4ee03128ad59b8c3941a1e5cd398d78c37f716f32a9b7f67", + "sha256:44659b1f326214950a8204a248ca6199535e73a694be8d3e0e869f820767f12f", + "sha256:47c5f58a8e0c2c920cc7783113df2fc4ff12bf3a411d985012f145e9242a2764", + "sha256:4bd4dc3602370679c2dfb818d9c97b1137d4dd412230cfecd3c66a1bf388a196", + "sha256:4ea6b73c22d8182dff91155af018b11aac9ff7eca085750455c5990cb1cfae6e", + "sha256:50025635ba8b629a86d9d5474e650da304cb46bbb4d18690532dd79341467846", + "sha256:517cbf6e67ae3623c5127206489d69eb2bdb27239a3c3cc559350ef52a3bbf0b", + "sha256:5855c85eb8b8a968a74dc7fb014c9166a05e7e7a8377fb91d78512900aadd13d", + "sha256:5a46859d7f947061b4010e554ccd1791467d1b1759f2dc2ec9055fa239f1bc26", + "sha256:65a0583c43d9f22cb2130c7b110e695fff834fd5e832a776a107197e59a1898e", + "sha256:674c704605092e3ebbbd13687b09c9f78c362a4bc710343efe37a91457123044", + "sha256:682726178138ea45a0766907957b60f3a1bf3acdf212436be9733f28b6c5af3c", + "sha256:686ba516e02db6d6f8c279d1641f7067ebb5dc58b1d0536c4aaebb7bf01cdc5d", + "sha256:6a5d3fbd02efd9cf6a8ffc2f17b53a33542f6b154e88dd7b42ef4a4c0700fdad", + "sha256:6aa8326a4a608e1c28da191edd7c924dff445251b94653988efb059b16577a4d", + "sha256:700375326ed641f3d9d32060a91513ad668bcb7e2cffb18415c399acb25de2ab", + "sha256:71f2f7715935a61fa3e4ae91d91b67e571aeb5cb5d10331ab681256bda2ad920", + "sha256:745f5a43fdd7d6d25a53ab1a99979e7f8ea419dfefebcab0a5a1e9095490ee5e", + "sha256:79f594919d2c1a0cc17d1988a6adaf9a2f000d2e1048f71f298b056b1018e872", + "sha256:7d68dc8acded354c972116f59b5eb2e5864432948e098c19fe6994926d8e15c3", + "sha256:7f67da97f5b9eac838b6980fc6da268622e91f8960e083a34533ca710bec8611", + "sha256:83b32f0940adec65099f3b1c215ef7f1d025d13ff947975a055989cb7fd019a4", + "sha256:876bf9ed62323bc7dcfc261dbc5572c996ef26fe6406b0ff985cbcf460fc8a4c", + "sha256:890ba852c16ace6ed9f90e8670f2c1c178d96510a21b06d2fa12d8783a905193", + "sha256:8b08605d248b974eb02f40bdcd1a35d3924c83a2a5e8f5d0fa5af852c4d960af", + "sha256:8b2eb034c94b0b96d5eddb290b7b5198460e2d5d0c421751713953a9c4e47d10", + "sha256:8b9ec12ad5f0a4625db34db7e0005be2632c1013b253a4a60e8302ad4d462afd", + "sha256:8c8d7594e38cf98d8a7df25b440f684b510cf4627fe038c297a87496d10a174f", + "sha256:8d3335c03100a073883857e91db9f2e0ef8a1cf42dc0369cbb9151c149dbbc1b", + "sha256:8d70e8f14900f2657c249ea4def963bed86a29b81f81f5b76b5a9215680de945", + "sha256:9039a11bca3c41be5a58282ed81ae422fa680409022b996032a43badef2a3752", + "sha256:91378d9f4151adc223d584489591dbb79f78814c0734a7c3bfa9c9e09978121c", + "sha256:9251eb8aa82e6cf88510530b29eef4fac825a2b709baf5b94a6094894f252387", + "sha256:933a7d5cd4b84f959aedeb84f2030f0a01d63ae6cf256629af3081cf3e3426e8", + "sha256:978fa96dbb005d599ec4fd9ed301b1cc45f1a8f7982d4793faf20b404b56677d", + "sha256:987b06d1cdb28f88a42e4fb8a87f094e43f3c435ed8e486533aea0bf2e53d931", + "sha256:99b1c16f732b3a9971406fbfe18468592c5a3529585a45a35adbc1389a529a03", + "sha256:99e7c4bb27ff1aab90dcc3e9d37ee5af0231ed98d99cb6f5250de28889a3d502", + "sha256:9c439fd54b2b9053717cca3de9583be6584b384d88d045f97d409f0ca867d80f", + "sha256:9ea4d00850ef1e917815e59b078ecb338f6a8efda23369677c54a5825dbebb55", + "sha256:9f30d205755566a25f2ae0382944fcae2f350500ae4df4e795efa9e850821d82", + "sha256:a06418fe1155e72e16dddc68bb3780ae44cebb2912fbd8bb6ff9161de56e1798", + "sha256:a0805911caedfe2736935250be5008b261f10a729a303f676d3d5fea6900c96a", + "sha256:a1f044792e1adcea82468a72310c66a7f08728d72a244730d14880cd1dabe36b", + "sha256:a216b26e5af0a8e265d4efd65d3bcec5fba6b26909014effe20cd302fd1138fa", + "sha256:a987578ac5214f18b99d1f2a3851cba5b09f4a689818a106c23dbad0dfeb760f", + "sha256:aad51239bee6bff6823bbbdc8ad85136c6125542bbc609e035ab98ca1e32a192", + "sha256:ab2299e3f92aa5417d5e16bb45bb4586171c1327568f638e8453c9f8d9e0f020", + "sha256:ab6919a09c055c9b092798ce18c6c4adf49d24d4d9e43a92b257e3f2548231e7", + "sha256:b0c43f8ae8f6be1d605b0465671124aa8d6a0e40f1fb81dcea28b7e3d87ca1e1", + "sha256:b1440c291db3f98a914e1afd9d6541e8fc60b4c3aab1a9008d03da4651e67386", + "sha256:b52e7c5ae35b00566d244ffefba0f46bb6bec749a50412acf42b1c3f402e2c90", + "sha256:bf4151acb541b6e895354f6ff9ac06995ad9e4175cbc6d30aaed08856558201f", + "sha256:c27ee01a6c3223025f4badd533bea5e87c988cb0ba2811b690395dfe16088cfe", + "sha256:c545d9d14d47be716495076b659db179206e3fd997769bc01e2d550eeb685596", + "sha256:c5934e2833afeaf36bd1eadb57256239785f5af0220ed8d21c2896ec4d3a765f", + "sha256:c7671d45530fcb6d5e22fd40c97e1e1e01965fc298cbda523bb640f3d923b387", + "sha256:c861a7e4aef15ff91233751619ce3a3d2b9e5877e0fcd76f9ea4f6847183aa16", + "sha256:d25b1c1096ef0447355f7293fbe9ad740f7c47ae032c2884113f8e87660d8f6e", + "sha256:d55777a80f78dd09410bd84ff8c95ee05519f41113b2df90a69622f5540c4f8b", + "sha256:d576c3ef8c7b2d560e301eb33891d1944d965a4d7a2eacb6332eee8a71827db6", + "sha256:dd9da77c6ec1f258387957b754f0df60766ac23ed698b61941ba9acccd3284d1", + "sha256:de0b6eceb46141984671802d412568d22c6bacc9b230174f9e55fc72ef4f57de", + "sha256:e07e5dbf8a83c66783a9fe2d4566968ea8c161199680e8ad38d53e075df5f0d0", + "sha256:e564d2238512c5ef5e9d79338ab77f1cbbda6c2d541ad41b2af445fb200385e3", + "sha256:ed89861ee8c8c47d6beb742a602f912b1bb64f598b1e2f3d758948721d44d468", + "sha256:ef1f08f2a924837e112cba2953e15aacfccbbfcd773b4b9b4723f8f2ddded08e", + "sha256:f411330a6376fb50e5b7a3e66894e4a39e60ca2e17dce258d53768fea06a37bd", + "sha256:f68996a3b3dc9335037f82754f9cdbe3a95db42bde571d8c3be26cc6245f2324", + "sha256:f7fdf55283ad38c33e35e2855565361f4bf0abd02470b8ab28d499c663bc5d7c", + "sha256:f963c6b1218b96db85fc37a9f0851eaf8b9040aa46dec112611697a7023da535", + "sha256:fa2818759aba55df50592ecbc95ebcdc99917fa7b55cc6796235b04193eb3c55", + "sha256:fae5cb554b604b3f9e2c608241b5d8d303e410d7dfb6d397c335f983495ce7f6", + "sha256:fb39aca7a64ad0c9490adfa719dbeeb87d13be137ca189d2564e596f8ba32c07" + ], + "markers": "python_version >= '3.8'", + "version": "==0.9.2" }, "rsa": { "hashes": [ @@ -627,19 +695,19 @@ }, "sentry-sdk": { "hashes": [ - "sha256:69ecbb2e1ff4db02a06c4f20f6f69cb5dfe3ebfbc06d023e40d77cf78e9c37e7", - "sha256:7ad4d37dd093f4a7cb5ad804c6efe9e8fab8873f7ffc06042dc3f3fd700a93ec" + "sha256:3e17215d8006612e2df02b0e73115eb8376c37e3f586d8436fa41644e605074d", + "sha256:a99ee105384788c3f228726a88baf515fe7b5f1d2d0f215a03d194369f158df7" ], "index": "pypi", - "version": "==1.15.0" + "version": "==1.29.2" }, "setuptools": { "hashes": [ - "sha256:95f00380ef2ffa41d9bba85d95b27689d923c93dfbafed4aecd7cf988a25e012", - "sha256:bb6d8e508de562768f2027902929f8523932fcd1fb784e6d573d2cafac995a48" + "sha256:11e52c67415a381d10d6b462ced9cfb97066179f0e871399e006c4ab101fc85f", + "sha256:baf1fdb41c6da4cd2eae722e135500da913332ab3f2f5c7d33af9b492acb5235" ], "markers": "python_version >= '3.7'", - "version": "==67.3.2" + "version": "==68.0.0" }, "six": { "hashes": [ @@ -691,123 +759,134 @@ }, "typing-extensions": { "hashes": [ - "sha256:5cb5f4a79139d699607b3ef622a1dedafa84e115ab0024e0d9c044a9479ca7cb", - "sha256:fb33085c39dd998ac16d1431ebc293a8b3eedd00fd4a32de0ff79002c19511b4" + "sha256:440d5dd3af93b060174bf433bccd69b0babc3b15b1a8dca43789fd7f61514b36", + "sha256:b75ddc264f0ba5615db7ba217daeb99701ad295353c45f9e95963337ceeeffb2" ], "markers": "python_version >= '3.7'", - "version": "==4.5.0" + "version": "==4.7.1" }, "urllib3": { "hashes": [ - "sha256:076907bf8fd355cde77728471316625a4d2f7e713c125f51953bb5b3eecf4f72", - "sha256:75edcdc2f7d85b137124a6c3c9fc3933cdeaa12ecb9a6a959f22797a0feca7e1" + "sha256:8d22f86aae8ef5e410d4f539fde9ce6b2113a001bb4d189e0aed70642d602b11", + "sha256:de7df1803967d2c2a98e4b11bb7d6bd9210474c46e8a0401514e3a42a75ebde4" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'", - "version": "==1.26.14" + "markers": "python_version >= '3.7'", + "version": "==2.0.4" }, "werkzeug": { "hashes": [ - "sha256:2e1ccc9417d4da358b9de6f174e3ac094391ea1d4fbef2d667865d819dfd0afe", - "sha256:56433961bc1f12533306c624f3be5e744389ac61d722175d543e1751285da612" + "sha256:935539fa1413afbb9195b24880778422ed620c0fc09670945185cce4d91a8890", + "sha256:98c774df2f91b05550078891dee5f0eb0cb797a522c757a2452b9cee5b202330" ], - "markers": "python_version >= '3.7'", - "version": "==2.2.3" + "markers": "python_version >= '3.8'", + "version": "==2.3.6" }, "wrapt": { "hashes": [ - "sha256:00b6d4ea20a906c0ca56d84f93065b398ab74b927a7a3dbd470f6fc503f95dc3", - "sha256:01c205616a89d09827986bc4e859bcabd64f5a0662a7fe95e0d359424e0e071b", - "sha256:02b41b633c6261feff8ddd8d11c711df6842aba629fdd3da10249a53211a72c4", - "sha256:07f7a7d0f388028b2df1d916e94bbb40624c59b48ecc6cbc232546706fac74c2", - "sha256:11871514607b15cfeb87c547a49bca19fde402f32e2b1c24a632506c0a756656", - "sha256:1b376b3f4896e7930f1f772ac4b064ac12598d1c38d04907e696cc4d794b43d3", - "sha256:21ac0156c4b089b330b7666db40feee30a5d52634cc4560e1905d6529a3897ff", - "sha256:257fd78c513e0fb5cdbe058c27a0624c9884e735bbd131935fd49e9fe719d310", - "sha256:2b39d38039a1fdad98c87279b48bc5dce2c0ca0d73483b12cb72aa9609278e8a", - "sha256:2cf71233a0ed05ccdabe209c606fe0bac7379fdcf687f39b944420d2a09fdb57", - "sha256:2fe803deacd09a233e4762a1adcea5db5d31e6be577a43352936179d14d90069", - "sha256:3232822c7d98d23895ccc443bbdf57c7412c5a65996c30442ebe6ed3df335383", - "sha256:34aa51c45f28ba7f12accd624225e2b1e5a3a45206aa191f6f9aac931d9d56fe", - "sha256:36f582d0c6bc99d5f39cd3ac2a9062e57f3cf606ade29a0a0d6b323462f4dd87", - "sha256:380a85cf89e0e69b7cfbe2ea9f765f004ff419f34194018a6827ac0e3edfed4d", - "sha256:40e7bc81c9e2b2734ea4bc1aceb8a8f0ceaac7c5299bc5d69e37c44d9081d43b", - "sha256:43ca3bbbe97af00f49efb06e352eae40434ca9d915906f77def219b88e85d907", - "sha256:4fcc4649dc762cddacd193e6b55bc02edca674067f5f98166d7713b193932b7f", - "sha256:5a0f54ce2c092aaf439813735584b9537cad479575a09892b8352fea5e988dc0", - "sha256:5a9a0d155deafd9448baff28c08e150d9b24ff010e899311ddd63c45c2445e28", - "sha256:5b02d65b9ccf0ef6c34cba6cf5bf2aab1bb2f49c6090bafeecc9cd81ad4ea1c1", - "sha256:60db23fa423575eeb65ea430cee741acb7c26a1365d103f7b0f6ec412b893853", - "sha256:642c2e7a804fcf18c222e1060df25fc210b9c58db7c91416fb055897fc27e8cc", - "sha256:6a9a25751acb379b466ff6be78a315e2b439d4c94c1e99cb7266d40a537995d3", - "sha256:6b1a564e6cb69922c7fe3a678b9f9a3c54e72b469875aa8018f18b4d1dd1adf3", - "sha256:6d323e1554b3d22cfc03cd3243b5bb815a51f5249fdcbb86fda4bf62bab9e164", - "sha256:6e743de5e9c3d1b7185870f480587b75b1cb604832e380d64f9504a0535912d1", - "sha256:709fe01086a55cf79d20f741f39325018f4df051ef39fe921b1ebe780a66184c", - "sha256:7b7c050ae976e286906dd3f26009e117eb000fb2cf3533398c5ad9ccc86867b1", - "sha256:7d2872609603cb35ca513d7404a94d6d608fc13211563571117046c9d2bcc3d7", - "sha256:7ef58fb89674095bfc57c4069e95d7a31cfdc0939e2a579882ac7d55aadfd2a1", - "sha256:80bb5c256f1415f747011dc3604b59bc1f91c6e7150bd7db03b19170ee06b320", - "sha256:81b19725065dcb43df02b37e03278c011a09e49757287dca60c5aecdd5a0b8ed", - "sha256:833b58d5d0b7e5b9832869f039203389ac7cbf01765639c7309fd50ef619e0b1", - "sha256:88bd7b6bd70a5b6803c1abf6bca012f7ed963e58c68d76ee20b9d751c74a3248", - "sha256:8ad85f7f4e20964db4daadcab70b47ab05c7c1cf2a7c1e51087bfaa83831854c", - "sha256:8c0ce1e99116d5ab21355d8ebe53d9460366704ea38ae4d9f6933188f327b456", - "sha256:8d649d616e5c6a678b26d15ece345354f7c2286acd6db868e65fcc5ff7c24a77", - "sha256:903500616422a40a98a5a3c4ff4ed9d0066f3b4c951fa286018ecdf0750194ef", - "sha256:9736af4641846491aedb3c3f56b9bc5568d92b0692303b5a305301a95dfd38b1", - "sha256:988635d122aaf2bdcef9e795435662bcd65b02f4f4c1ae37fbee7401c440b3a7", - "sha256:9cca3c2cdadb362116235fdbd411735de4328c61425b0aa9f872fd76d02c4e86", - "sha256:9e0fd32e0148dd5dea6af5fee42beb949098564cc23211a88d799e434255a1f4", - "sha256:9f3e6f9e05148ff90002b884fbc2a86bd303ae847e472f44ecc06c2cd2fcdb2d", - "sha256:a85d2b46be66a71bedde836d9e41859879cc54a2a04fad1191eb50c2066f6e9d", - "sha256:a9a52172be0b5aae932bef82a79ec0a0ce87288c7d132946d645eba03f0ad8a8", - "sha256:aa31fdcc33fef9eb2552cbcbfee7773d5a6792c137b359e82879c101e98584c5", - "sha256:b014c23646a467558be7da3d6b9fa409b2c567d2110599b7cf9a0c5992b3b471", - "sha256:b21bb4c09ffabfa0e85e3a6b623e19b80e7acd709b9f91452b8297ace2a8ab00", - "sha256:b5901a312f4d14c59918c221323068fad0540e34324925c8475263841dbdfe68", - "sha256:b9b7a708dd92306328117d8c4b62e2194d00c365f18eff11a9b53c6f923b01e3", - "sha256:d1967f46ea8f2db647c786e78d8cc7e4313dbd1b0aca360592d8027b8508e24d", - "sha256:d52a25136894c63de15a35bc0bdc5adb4b0e173b9c0d07a2be9d3ca64a332735", - "sha256:d77c85fedff92cf788face9bfa3ebaa364448ebb1d765302e9af11bf449ca36d", - "sha256:d79d7d5dc8a32b7093e81e97dad755127ff77bcc899e845f41bf71747af0c569", - "sha256:dbcda74c67263139358f4d188ae5faae95c30929281bc6866d00573783c422b7", - "sha256:ddaea91abf8b0d13443f6dac52e89051a5063c7d014710dcb4d4abb2ff811a59", - "sha256:dee0ce50c6a2dd9056c20db781e9c1cfd33e77d2d569f5d1d9321c641bb903d5", - "sha256:dee60e1de1898bde3b238f18340eec6148986da0455d8ba7848d50470a7a32fb", - "sha256:e2f83e18fe2f4c9e7db597e988f72712c0c3676d337d8b101f6758107c42425b", - "sha256:e3fb1677c720409d5f671e39bac6c9e0e422584e5f518bfd50aa4cbbea02433f", - "sha256:ee2b1b1769f6707a8a445162ea16dddf74285c3964f605877a20e38545c3c462", - "sha256:ee6acae74a2b91865910eef5e7de37dc6895ad96fa23603d1d27ea69df545015", - "sha256:ef3f72c9666bba2bab70d2a8b79f2c6d2c1a42a7f7e2b0ec83bb2f9e383950af" + "sha256:02fce1852f755f44f95af51f69d22e45080102e9d00258053b79367d07af39c0", + "sha256:077ff0d1f9d9e4ce6476c1a924a3332452c1406e59d90a2cf24aeb29eeac9420", + "sha256:078e2a1a86544e644a68422f881c48b84fef6d18f8c7a957ffd3f2e0a74a0d4a", + "sha256:0970ddb69bba00670e58955f8019bec4a42d1785db3faa043c33d81de2bf843c", + "sha256:1286eb30261894e4c70d124d44b7fd07825340869945c79d05bda53a40caa079", + "sha256:21f6d9a0d5b3a207cdf7acf8e58d7d13d463e639f0c7e01d82cdb671e6cb7923", + "sha256:230ae493696a371f1dbffaad3dafbb742a4d27a0afd2b1aecebe52b740167e7f", + "sha256:26458da5653aa5b3d8dc8b24192f574a58984c749401f98fff994d41d3f08da1", + "sha256:2cf56d0e237280baed46f0b5316661da892565ff58309d4d2ed7dba763d984b8", + "sha256:2e51de54d4fb8fb50d6ee8327f9828306a959ae394d3e01a1ba8b2f937747d86", + "sha256:2fbfbca668dd15b744418265a9607baa970c347eefd0db6a518aaf0cfbd153c0", + "sha256:38adf7198f8f154502883242f9fe7333ab05a5b02de7d83aa2d88ea621f13364", + "sha256:3a8564f283394634a7a7054b7983e47dbf39c07712d7b177b37e03f2467a024e", + "sha256:3abbe948c3cbde2689370a262a8d04e32ec2dd4f27103669a45c6929bcdbfe7c", + "sha256:3bbe623731d03b186b3d6b0d6f51865bf598587c38d6f7b0be2e27414f7f214e", + "sha256:40737a081d7497efea35ab9304b829b857f21558acfc7b3272f908d33b0d9d4c", + "sha256:41d07d029dd4157ae27beab04d22b8e261eddfc6ecd64ff7000b10dc8b3a5727", + "sha256:46ed616d5fb42f98630ed70c3529541408166c22cdfd4540b88d5f21006b0eff", + "sha256:493d389a2b63c88ad56cdc35d0fa5752daac56ca755805b1b0c530f785767d5e", + "sha256:4ff0d20f2e670800d3ed2b220d40984162089a6e2c9646fdb09b85e6f9a8fc29", + "sha256:54accd4b8bc202966bafafd16e69da9d5640ff92389d33d28555c5fd4f25ccb7", + "sha256:56374914b132c702aa9aa9959c550004b8847148f95e1b824772d453ac204a72", + "sha256:578383d740457fa790fdf85e6d346fda1416a40549fe8db08e5e9bd281c6a475", + "sha256:58d7a75d731e8c63614222bcb21dd992b4ab01a399f1f09dd82af17bbfc2368a", + "sha256:5c5aa28df055697d7c37d2099a7bc09f559d5053c3349b1ad0c39000e611d317", + "sha256:5fc8e02f5984a55d2c653f5fea93531e9836abbd84342c1d1e17abc4a15084c2", + "sha256:63424c681923b9f3bfbc5e3205aafe790904053d42ddcc08542181a30a7a51bd", + "sha256:64b1df0f83706b4ef4cfb4fb0e4c2669100fd7ecacfb59e091fad300d4e04640", + "sha256:74934ebd71950e3db69960a7da29204f89624dde411afbfb3b4858c1409b1e98", + "sha256:75669d77bb2c071333417617a235324a1618dba66f82a750362eccbe5b61d248", + "sha256:75760a47c06b5974aa5e01949bf7e66d2af4d08cb8c1d6516af5e39595397f5e", + "sha256:76407ab327158c510f44ded207e2f76b657303e17cb7a572ffe2f5a8a48aa04d", + "sha256:76e9c727a874b4856d11a32fb0b389afc61ce8aaf281ada613713ddeadd1cfec", + "sha256:77d4c1b881076c3ba173484dfa53d3582c1c8ff1f914c6461ab70c8428b796c1", + "sha256:780c82a41dc493b62fc5884fb1d3a3b81106642c5c5c78d6a0d4cbe96d62ba7e", + "sha256:7dc0713bf81287a00516ef43137273b23ee414fe41a3c14be10dd95ed98a2df9", + "sha256:7eebcdbe3677e58dd4c0e03b4f2cfa346ed4049687d839adad68cc38bb559c92", + "sha256:896689fddba4f23ef7c718279e42f8834041a21342d95e56922e1c10c0cc7afb", + "sha256:96177eb5645b1c6985f5c11d03fc2dbda9ad24ec0f3a46dcce91445747e15094", + "sha256:96e25c8603a155559231c19c0349245eeb4ac0096fe3c1d0be5c47e075bd4f46", + "sha256:9d37ac69edc5614b90516807de32d08cb8e7b12260a285ee330955604ed9dd29", + "sha256:9ed6aa0726b9b60911f4aed8ec5b8dd7bf3491476015819f56473ffaef8959bd", + "sha256:a487f72a25904e2b4bbc0817ce7a8de94363bd7e79890510174da9d901c38705", + "sha256:a4cbb9ff5795cd66f0066bdf5947f170f5d63a9274f99bdbca02fd973adcf2a8", + "sha256:a74d56552ddbde46c246b5b89199cb3fd182f9c346c784e1a93e4dc3f5ec9975", + "sha256:a89ce3fd220ff144bd9d54da333ec0de0399b52c9ac3d2ce34b569cf1a5748fb", + "sha256:abd52a09d03adf9c763d706df707c343293d5d106aea53483e0ec8d9e310ad5e", + "sha256:abd8f36c99512755b8456047b7be10372fca271bf1467a1caa88db991e7c421b", + "sha256:af5bd9ccb188f6a5fdda9f1f09d9f4c86cc8a539bd48a0bfdc97723970348418", + "sha256:b02f21c1e2074943312d03d243ac4388319f2456576b2c6023041c4d57cd7019", + "sha256:b06fa97478a5f478fb05e1980980a7cdf2712015493b44d0c87606c1513ed5b1", + "sha256:b0724f05c396b0a4c36a3226c31648385deb6a65d8992644c12a4963c70326ba", + "sha256:b130fe77361d6771ecf5a219d8e0817d61b236b7d8b37cc045172e574ed219e6", + "sha256:b56d5519e470d3f2fe4aa7585f0632b060d532d0696c5bdfb5e8319e1d0f69a2", + "sha256:b67b819628e3b748fd3c2192c15fb951f549d0f47c0449af0764d7647302fda3", + "sha256:ba1711cda2d30634a7e452fc79eabcadaffedf241ff206db2ee93dd2c89a60e7", + "sha256:bbeccb1aa40ab88cd29e6c7d8585582c99548f55f9b2581dfc5ba68c59a85752", + "sha256:bd84395aab8e4d36263cd1b9308cd504f6cf713b7d6d3ce25ea55670baec5416", + "sha256:c99f4309f5145b93eca6e35ac1a988f0dc0a7ccf9ccdcd78d3c0adf57224e62f", + "sha256:ca1cccf838cd28d5a0883b342474c630ac48cac5df0ee6eacc9c7290f76b11c1", + "sha256:cd525e0e52a5ff16653a3fc9e3dd827981917d34996600bbc34c05d048ca35cc", + "sha256:cdb4f085756c96a3af04e6eca7f08b1345e94b53af8921b25c72f096e704e145", + "sha256:ce42618f67741d4697684e501ef02f29e758a123aa2d669e2d964ff734ee00ee", + "sha256:d06730c6aed78cee4126234cf2d071e01b44b915e725a6cb439a879ec9754a3a", + "sha256:d5fe3e099cf07d0fb5a1e23d399e5d4d1ca3e6dfcbe5c8570ccff3e9208274f7", + "sha256:d6bcbfc99f55655c3d93feb7ef3800bd5bbe963a755687cbf1f490a71fb7794b", + "sha256:d787272ed958a05b2c86311d3a4135d3c2aeea4fc655705f074130aa57d71653", + "sha256:e169e957c33576f47e21864cf3fc9ff47c223a4ebca8960079b8bd36cb014fd0", + "sha256:e20076a211cd6f9b44a6be58f7eeafa7ab5720eb796975d0c03f05b47d89eb90", + "sha256:e826aadda3cae59295b95343db8f3d965fb31059da7de01ee8d1c40a60398b29", + "sha256:eef4d64c650f33347c1f9266fa5ae001440b232ad9b98f1f43dfe7a79435c0a6", + "sha256:f2e69b3ed24544b0d3dbe2c5c0ba5153ce50dcebb576fdc4696d52aa22db6034", + "sha256:f87ec75864c37c4c6cb908d282e1969e79763e0d9becdfe9fe5473b7bb1e5f09", + "sha256:fbec11614dba0424ca72f4e8ba3c420dba07b4a7c206c8c8e4e73f2e98f4c559", + "sha256:fd69666217b62fa5d7c6aa88e507493a34dec4fa20c5bd925e4bc12fce586639" ], "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==1.14.1" + "version": "==1.15.0" }, "zipp": { "hashes": [ - "sha256:23f70e964bc11a34cef175bc90ba2914e1e4545ea1e3e2f67c079671883f9cb6", - "sha256:e8b2a36ea17df80ffe9e2c4fda3f693c3dad6df1697d3cd3af232db680950b0b" + "sha256:679e51dd4403591b2d6838a48de3d283f3d188412a9782faadf845f298736ba0", + "sha256:ebc15946aa78bd63458992fc81ec3b6f7b1e92d51c35e6de1c3804e73b799147" ], "markers": "python_version < '3.10'", - "version": "==3.13.0" + "version": "==3.16.2" } }, "develop": { "alembic": { "hashes": [ - "sha256:4d3bd32ecdbb7bbfb48a9fe9e6d6fd6a831a1b59d03e26e292210237373e7db5", - "sha256:6f1c2207369bf4f49f952057a33bb017fbe5c148c2a773b46906b806ea6e825f" + "sha256:678f662130dc540dac12de0ea73de9f89caea9dbea138f60ef6263149bf84657", + "sha256:7981ab0c4fad4fe1be0cf183aae17689fe394ff874fd2464adb774396faf0796" ], "markers": "python_version >= '3.7'", - "version": "==1.9.4" + "version": "==1.11.2" }, "click": { "hashes": [ - "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e", - "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48" + "sha256:48ee849951919527a045bfe3bf7baa8a959c423134e1a5b98c05c20ba75a1cbd", + "sha256:fa244bb30b3b5ee2cae3da8f55c9e5e0c0e86093306301fb418eb9dc40fbded5" ], "markers": "python_version >= '3.7'", - "version": "==8.1.3" + "version": "==8.1.6" }, "flask": { "hashes": [ @@ -835,19 +914,19 @@ }, "importlib-metadata": { "hashes": [ - "sha256:7efb448ec9a5e313a57655d35aa54cd3e01b7e1fbcf72dce1bf06119420f5bad", - "sha256:e354bedeb60efa6affdcc8ae121b73544a7aa74156d047311948f6d711cd378d" + "sha256:3ebb78df84a805d7698245025b975d9d67053cd94c79245ba4b3eb694abe68bb", + "sha256:dbace7892d8c0c4ac1ad096662232f831d4e64f4c4545bd53016a3e9d4654743" ], "markers": "python_version < '3.9'", - "version": "==6.0.0" + "version": "==6.8.0" }, "importlib-resources": { "hashes": [ - "sha256:1e534a02295f3eeee0785e21b26c726557909cbaf1b871cf9adcbc0df44c1308", - "sha256:c0a55f37559b5e9ca1d3fce02d60243846245ad8f8d806a4484093806d4d0ae5" + "sha256:134832a506243891221b88b4ae1213327eea96ceb4e407a00d790bb0626f45cf", + "sha256:4359457e42708462b9626a04657c6208ad799ceb41e5c58c57ffa0e6a098a5d4" ], "markers": "python_version < '3.9'", - "version": "==5.11.0" + "version": "==6.0.1" }, "itsdangerous": { "hashes": [ @@ -875,59 +954,59 @@ }, "markupsafe": { "hashes": [ - "sha256:0576fe974b40a400449768941d5d0858cc624e3249dfd1e0c33674e5c7ca7aed", - "sha256:085fd3201e7b12809f9e6e9bc1e5c96a368c8523fad5afb02afe3c051ae4afcc", - "sha256:090376d812fb6ac5f171e5938e82e7f2d7adc2b629101cec0db8b267815c85e2", - "sha256:0b462104ba25f1ac006fdab8b6a01ebbfbce9ed37fd37fd4acd70c67c973e460", - "sha256:137678c63c977754abe9086a3ec011e8fd985ab90631145dfb9294ad09c102a7", - "sha256:1bea30e9bf331f3fef67e0a3877b2288593c98a21ccb2cf29b74c581a4eb3af0", - "sha256:22152d00bf4a9c7c83960521fc558f55a1adbc0631fbb00a9471e097b19d72e1", - "sha256:22731d79ed2eb25059ae3df1dfc9cb1546691cc41f4e3130fe6bfbc3ecbbecfa", - "sha256:2298c859cfc5463f1b64bd55cb3e602528db6fa0f3cfd568d3605c50678f8f03", - "sha256:28057e985dace2f478e042eaa15606c7efccb700797660629da387eb289b9323", - "sha256:2e7821bffe00aa6bd07a23913b7f4e01328c3d5cc0b40b36c0bd81d362faeb65", - "sha256:2ec4f2d48ae59bbb9d1f9d7efb9236ab81429a764dedca114f5fdabbc3788013", - "sha256:340bea174e9761308703ae988e982005aedf427de816d1afe98147668cc03036", - "sha256:40627dcf047dadb22cd25ea7ecfe9cbf3bbbad0482ee5920b582f3809c97654f", - "sha256:40dfd3fefbef579ee058f139733ac336312663c6706d1163b82b3003fb1925c4", - "sha256:4cf06cdc1dda95223e9d2d3c58d3b178aa5dacb35ee7e3bbac10e4e1faacb419", - "sha256:50c42830a633fa0cf9e7d27664637532791bfc31c731a87b202d2d8ac40c3ea2", - "sha256:55f44b440d491028addb3b88f72207d71eeebfb7b5dbf0643f7c023ae1fba619", - "sha256:608e7073dfa9e38a85d38474c082d4281f4ce276ac0010224eaba11e929dd53a", - "sha256:63ba06c9941e46fa389d389644e2d8225e0e3e5ebcc4ff1ea8506dce646f8c8a", - "sha256:65608c35bfb8a76763f37036547f7adfd09270fbdbf96608be2bead319728fcd", - "sha256:665a36ae6f8f20a4676b53224e33d456a6f5a72657d9c83c2aa00765072f31f7", - "sha256:6d6607f98fcf17e534162f0709aaad3ab7a96032723d8ac8750ffe17ae5a0666", - "sha256:7313ce6a199651c4ed9d7e4cfb4aa56fe923b1adf9af3b420ee14e6d9a73df65", - "sha256:7668b52e102d0ed87cb082380a7e2e1e78737ddecdde129acadb0eccc5423859", - "sha256:7df70907e00c970c60b9ef2938d894a9381f38e6b9db73c5be35e59d92e06625", - "sha256:7e007132af78ea9df29495dbf7b5824cb71648d7133cf7848a2a5dd00d36f9ff", - "sha256:835fb5e38fd89328e9c81067fd642b3593c33e1e17e2fdbf77f5676abb14a156", - "sha256:8bca7e26c1dd751236cfb0c6c72d4ad61d986e9a41bbf76cb445f69488b2a2bd", - "sha256:8db032bf0ce9022a8e41a22598eefc802314e81b879ae093f36ce9ddf39ab1ba", - "sha256:99625a92da8229df6d44335e6fcc558a5037dd0a760e11d84be2260e6f37002f", - "sha256:9cad97ab29dfc3f0249b483412c85c8ef4766d96cdf9dcf5a1e3caa3f3661cf1", - "sha256:a4abaec6ca3ad8660690236d11bfe28dfd707778e2442b45addd2f086d6ef094", - "sha256:a6e40afa7f45939ca356f348c8e23048e02cb109ced1eb8420961b2f40fb373a", - "sha256:a6f2fcca746e8d5910e18782f976489939d54a91f9411c32051b4aab2bd7c513", - "sha256:a806db027852538d2ad7555b203300173dd1b77ba116de92da9afbc3a3be3eed", - "sha256:abcabc8c2b26036d62d4c746381a6f7cf60aafcc653198ad678306986b09450d", - "sha256:b8526c6d437855442cdd3d87eede9c425c4445ea011ca38d937db299382e6fa3", - "sha256:bb06feb762bade6bf3c8b844462274db0c76acc95c52abe8dbed28ae3d44a147", - "sha256:c0a33bc9f02c2b17c3ea382f91b4db0e6cde90b63b296422a939886a7a80de1c", - "sha256:c4a549890a45f57f1ebf99c067a4ad0cb423a05544accaf2b065246827ed9603", - "sha256:ca244fa73f50a800cf8c3ebf7fd93149ec37f5cb9596aa8873ae2c1d23498601", - "sha256:cf877ab4ed6e302ec1d04952ca358b381a882fbd9d1b07cccbfd61783561f98a", - "sha256:d9d971ec1e79906046aa3ca266de79eac42f1dbf3612a05dc9368125952bd1a1", - "sha256:da25303d91526aac3672ee6d49a2f3db2d9502a4a60b55519feb1a4c7714e07d", - "sha256:e55e40ff0cc8cc5c07996915ad367fa47da6b3fc091fdadca7f5403239c5fec3", - "sha256:f03a532d7dee1bed20bc4884194a16160a2de9ffc6354b3878ec9682bb623c54", - "sha256:f1cd098434e83e656abf198f103a8207a8187c0fc110306691a2e94a78d0abb2", - "sha256:f2bfb563d0211ce16b63c7cb9395d2c682a23187f54c3d79bfec33e6705473c6", - "sha256:f8ffb705ffcf5ddd0e80b65ddf7bed7ee4f5a441ea7d3419e861a12eaf41af58" + "sha256:05fb21170423db021895e1ea1e1f3ab3adb85d1c2333cbc2310f2a26bc77272e", + "sha256:0a4e4a1aff6c7ac4cd55792abf96c915634c2b97e3cc1c7129578aa68ebd754e", + "sha256:10bbfe99883db80bdbaff2dcf681dfc6533a614f700da1287707e8a5d78a8431", + "sha256:134da1eca9ec0ae528110ccc9e48041e0828d79f24121a1a146161103c76e686", + "sha256:1577735524cdad32f9f694208aa75e422adba74f1baee7551620e43a3141f559", + "sha256:1b40069d487e7edb2676d3fbdb2b0829ffa2cd63a2ec26c4938b2d34391b4ecc", + "sha256:282c2cb35b5b673bbcadb33a585408104df04f14b2d9b01d4c345a3b92861c2c", + "sha256:2c1b19b3aaacc6e57b7e25710ff571c24d6c3613a45e905b1fde04d691b98ee0", + "sha256:2ef12179d3a291be237280175b542c07a36e7f60718296278d8593d21ca937d4", + "sha256:338ae27d6b8745585f87218a3f23f1512dbf52c26c28e322dbe54bcede54ccb9", + "sha256:3c0fae6c3be832a0a0473ac912810b2877c8cb9d76ca48de1ed31e1c68386575", + "sha256:3fd4abcb888d15a94f32b75d8fd18ee162ca0c064f35b11134be77050296d6ba", + "sha256:42de32b22b6b804f42c5d98be4f7e5e977ecdd9ee9b660fda1a3edf03b11792d", + "sha256:504b320cd4b7eff6f968eddf81127112db685e81f7e36e75f9f84f0df46041c3", + "sha256:525808b8019e36eb524b8c68acdd63a37e75714eac50e988180b169d64480a00", + "sha256:56d9f2ecac662ca1611d183feb03a3fa4406469dafe241673d521dd5ae92a155", + "sha256:5bbe06f8eeafd38e5d0a4894ffec89378b6c6a625ff57e3028921f8ff59318ac", + "sha256:65c1a9bcdadc6c28eecee2c119465aebff8f7a584dd719facdd9e825ec61ab52", + "sha256:68e78619a61ecf91e76aa3e6e8e33fc4894a2bebe93410754bd28fce0a8a4f9f", + "sha256:69c0f17e9f5a7afdf2cc9fb2d1ce6aabdb3bafb7f38017c0b77862bcec2bbad8", + "sha256:6b2b56950d93e41f33b4223ead100ea0fe11f8e6ee5f641eb753ce4b77a7042b", + "sha256:787003c0ddb00500e49a10f2844fac87aa6ce977b90b0feaaf9de23c22508b24", + "sha256:7ef3cb2ebbf91e330e3bb937efada0edd9003683db6b57bb108c4001f37a02ea", + "sha256:8023faf4e01efadfa183e863fefde0046de576c6f14659e8782065bcece22198", + "sha256:8758846a7e80910096950b67071243da3e5a20ed2546e6392603c096778d48e0", + "sha256:8afafd99945ead6e075b973fefa56379c5b5c53fd8937dad92c662da5d8fd5ee", + "sha256:8c41976a29d078bb235fea9b2ecd3da465df42a562910f9022f1a03107bd02be", + "sha256:8e254ae696c88d98da6555f5ace2279cf7cd5b3f52be2b5cf97feafe883b58d2", + "sha256:9402b03f1a1b4dc4c19845e5c749e3ab82d5078d16a2a4c2cd2df62d57bb0707", + "sha256:962f82a3086483f5e5f64dbad880d31038b698494799b097bc59c2edf392fce6", + "sha256:9dcdfd0eaf283af041973bff14a2e143b8bd64e069f4c383416ecd79a81aab58", + "sha256:aa7bd130efab1c280bed0f45501b7c8795f9fdbeb02e965371bbef3523627779", + "sha256:ab4a0df41e7c16a1392727727e7998a467472d0ad65f3ad5e6e765015df08636", + "sha256:ad9e82fb8f09ade1c3e1b996a6337afac2b8b9e365f926f5a61aacc71adc5b3c", + "sha256:af598ed32d6ae86f1b747b82783958b1a4ab8f617b06fe68795c7f026abbdcad", + "sha256:b076b6226fb84157e3f7c971a47ff3a679d837cf338547532ab866c57930dbee", + "sha256:b7ff0f54cb4ff66dd38bebd335a38e2c22c41a8ee45aa608efc890ac3e3931bc", + "sha256:bfce63a9e7834b12b87c64d6b155fdd9b3b96191b6bd334bf37db7ff1fe457f2", + "sha256:c011a4149cfbcf9f03994ec2edffcb8b1dc2d2aede7ca243746df97a5d41ce48", + "sha256:c9c804664ebe8f83a211cace637506669e7890fec1b4195b505c214e50dd4eb7", + "sha256:ca379055a47383d02a5400cb0d110cef0a776fc644cda797db0c5696cfd7e18e", + "sha256:cb0932dc158471523c9637e807d9bfb93e06a95cbf010f1a38b98623b929ef2b", + "sha256:cd0f502fe016460680cd20aaa5a76d241d6f35a1c3350c474bac1273803893fa", + "sha256:ceb01949af7121f9fc39f7d27f91be8546f3fb112c608bc4029aef0bab86a2a5", + "sha256:d080e0a5eb2529460b30190fcfcc4199bd7f827663f858a226a81bc27beaa97e", + "sha256:dd15ff04ffd7e05ffcb7fe79f1b98041b8ea30ae9234aed2a9168b5797c3effb", + "sha256:df0be2b576a7abbf737b1575f048c23fb1d769f267ec4358296f31c2479db8f9", + "sha256:e09031c87a1e51556fdcb46e5bd4f59dfb743061cf93c4d6831bf894f125eb57", + "sha256:e4dd52d80b8c83fdce44e12478ad2e85c64ea965e75d66dbeafb0a3e77308fcc", + "sha256:fec21693218efe39aa7f8599346e90c705afa52c5b31ae019b2e57e8f6542bb2" ], "markers": "python_version >= '3.7'", - "version": "==2.1.2" + "version": "==2.1.3" }, "sqlalchemy": { "hashes": [ @@ -969,21 +1048,29 @@ "index": "pypi", "version": "==1.3.24" }, - "werkzeug": { + "typing-extensions": { "hashes": [ - "sha256:2e1ccc9417d4da358b9de6f174e3ac094391ea1d4fbef2d667865d819dfd0afe", - "sha256:56433961bc1f12533306c624f3be5e744389ac61d722175d543e1751285da612" + "sha256:440d5dd3af93b060174bf433bccd69b0babc3b15b1a8dca43789fd7f61514b36", + "sha256:b75ddc264f0ba5615db7ba217daeb99701ad295353c45f9e95963337ceeeffb2" ], "markers": "python_version >= '3.7'", - "version": "==2.2.3" + "version": "==4.7.1" + }, + "werkzeug": { + "hashes": [ + "sha256:935539fa1413afbb9195b24880778422ed620c0fc09670945185cce4d91a8890", + "sha256:98c774df2f91b05550078891dee5f0eb0cb797a522c757a2452b9cee5b202330" + ], + "markers": "python_version >= '3.8'", + "version": "==2.3.6" }, "zipp": { "hashes": [ - "sha256:23f70e964bc11a34cef175bc90ba2914e1e4545ea1e3e2f67c079671883f9cb6", - "sha256:e8b2a36ea17df80ffe9e2c4fda3f693c3dad6df1697d3cd3af232db680950b0b" + "sha256:679e51dd4403591b2d6838a48de3d283f3d188412a9782faadf845f298736ba0", + "sha256:ebc15946aa78bd63458992fc81ec3b6f7b1e92d51c35e6de1c3804e73b799147" ], "markers": "python_version < '3.10'", - "version": "==3.13.0" + "version": "==3.16.2" } } } From 8c350ca18fd917153d4f5a67ccc566d8c6cc64c0 Mon Sep 17 00:00:00 2001 From: Adrian Edwards Date: Sun, 13 Aug 2023 12:14:39 -0400 Subject: [PATCH 193/206] switch to psycopg2-binary to avoid compilation dependency messiness --- Pipfile | 2 +- Pipfile.lock | 77 ++++++++++++++++++++++++++++++++++++++++++---------- 2 files changed, 64 insertions(+), 15 deletions(-) diff --git a/Pipfile b/Pipfile index 9c281af..b13d05c 100644 --- a/Pipfile +++ b/Pipfile @@ -25,7 +25,7 @@ python-dotenv = "*" flask-migrate = "*" requests = "*" sentry-sdk = "*" -psycopg2 = "*" +psycopg2-binary = "*" [requires] python_version = "3.8" diff --git a/Pipfile.lock b/Pipfile.lock index 46ba4bc..7d28669 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "f02915067d6d041c70717935c631888f845939aebacec22e284d5897cdba7876" + "sha256": "0015aecf8305c4ed6e2b488d20317db74e4adc376211b99efbc7d6948e0b5cea" }, "pipfile-spec": 6, "requires": { @@ -463,19 +463,68 @@ "markers": "python_version >= '3.7'", "version": "==4.21.12" }, - "psycopg2": { - "hashes": [ - "sha256:1a6a2d609bce44f78af4556bea0c62a5e7f05c23e5ea9c599e07678995609084", - "sha256:44d93a0109dfdf22fe399b419bcd7fa589d86895d3931b01fb321d74dadc68f1", - "sha256:8275abf628c6dc7ec834ea63f6f3846bf33518907a2b9b693d41fd063767a866", - "sha256:91e81a8333a0037babfc9fe6d11e997a9d4dac0f38c43074886b0d9dead94fe9", - "sha256:b22ed9c66da2589a664e0f1ca2465c29b75aaab36fa209d4fb916025fb9119e5", - "sha256:b6bd7d9d3a7a63faae6edf365f0ed0e9b0a1aaf1da3ca146e6b043fb3eb5d723", - "sha256:c7949770cafbd2f12cecc97dea410c514368908a103acf519f2a346134caa4d5", - "sha256:d1210fcf99aae6f728812d1d2240afc1dc44b9e6cba526a06fb8134f969957c2", - "sha256:d5c5297e2fbc8068d4255f1e606bfc9291f06f91ec31b2a0d4c536210ac5c0a2", - "sha256:e9b04cbef584310a1ac0f0d55bb623ca3244c87c51187645432e342de9ae81a8", - "sha256:f00cc35bd7119f1fed17b85bd1007855194dde2cbd8de01ab8ebb17487440ad8" + "psycopg2-binary": { + "hashes": [ + "sha256:00d8db270afb76f48a499f7bb8fa70297e66da67288471ca873db88382850bf4", + "sha256:024eaeb2a08c9a65cd5f94b31ace1ee3bb3f978cd4d079406aef85169ba01f08", + "sha256:094af2e77a1976efd4956a031028774b827029729725e136514aae3cdf49b87b", + "sha256:1011eeb0c51e5b9ea1016f0f45fa23aca63966a4c0afcf0340ccabe85a9f65bd", + "sha256:11abdbfc6f7f7dea4a524b5f4117369b0d757725798f1593796be6ece20266cb", + "sha256:122641b7fab18ef76b18860dd0c772290566b6fb30cc08e923ad73d17461dc63", + "sha256:17cc17a70dfb295a240db7f65b6d8153c3d81efb145d76da1e4a096e9c5c0e63", + "sha256:18f12632ab516c47c1ac4841a78fddea6508a8284c7cf0f292cb1a523f2e2379", + "sha256:1b918f64a51ffe19cd2e230b3240ba481330ce1d4b7875ae67305bd1d37b041c", + "sha256:1c31c2606ac500dbd26381145684d87730a2fac9a62ebcfbaa2b119f8d6c19f4", + "sha256:26484e913d472ecb6b45937ea55ce29c57c662066d222fb0fbdc1fab457f18c5", + "sha256:2993ccb2b7e80844d534e55e0f12534c2871952f78e0da33c35e648bf002bbff", + "sha256:2b04da24cbde33292ad34a40db9832a80ad12de26486ffeda883413c9e1b1d5e", + "sha256:2dec5a75a3a5d42b120e88e6ed3e3b37b46459202bb8e36cd67591b6e5feebc1", + "sha256:2df562bb2e4e00ee064779902d721223cfa9f8f58e7e52318c97d139cf7f012d", + "sha256:3fbb1184c7e9d28d67671992970718c05af5f77fc88e26fd7136613c4ece1f89", + "sha256:42a62ef0e5abb55bf6ffb050eb2b0fcd767261fa3faf943a4267539168807522", + "sha256:4ecc15666f16f97709106d87284c136cdc82647e1c3f8392a672616aed3c7151", + "sha256:4eec5d36dbcfc076caab61a2114c12094c0b7027d57e9e4387b634e8ab36fd44", + "sha256:4fe13712357d802080cfccbf8c6266a3121dc0e27e2144819029095ccf708372", + "sha256:51d1b42d44f4ffb93188f9b39e6d1c82aa758fdb8d9de65e1ddfe7a7d250d7ad", + "sha256:59f7e9109a59dfa31efa022e94a244736ae401526682de504e87bd11ce870c22", + "sha256:62cb6de84d7767164a87ca97e22e5e0a134856ebcb08f21b621c6125baf61f16", + "sha256:642df77484b2dcaf87d4237792246d8068653f9e0f5c025e2c692fc56b0dda70", + "sha256:6822c9c63308d650db201ba22fe6648bd6786ca6d14fdaf273b17e15608d0852", + "sha256:692df8763b71d42eb8343f54091368f6f6c9cfc56dc391858cdb3c3ef1e3e584", + "sha256:6d92e139ca388ccfe8c04aacc163756e55ba4c623c6ba13d5d1595ed97523e4b", + "sha256:7952807f95c8eba6a8ccb14e00bf170bb700cafcec3924d565235dffc7dc4ae8", + "sha256:7db7b9b701974c96a88997d458b38ccb110eba8f805d4b4f74944aac48639b42", + "sha256:81d5dd2dd9ab78d31a451e357315f201d976c131ca7d43870a0e8063b6b7a1ec", + "sha256:8a136c8aaf6615653450817a7abe0fc01e4ea720ae41dfb2823eccae4b9062a3", + "sha256:8a7968fd20bd550431837656872c19575b687f3f6f98120046228e451e4064df", + "sha256:8c721ee464e45ecf609ff8c0a555018764974114f671815a0a7152aedb9f3343", + "sha256:8f309b77a7c716e6ed9891b9b42953c3ff7d533dc548c1e33fddc73d2f5e21f9", + "sha256:8f94cb12150d57ea433e3e02aabd072205648e86f1d5a0a692d60242f7809b15", + "sha256:95a7a747bdc3b010bb6a980f053233e7610276d55f3ca506afff4ad7749ab58a", + "sha256:9b0c2b466b2f4d89ccc33784c4ebb1627989bd84a39b79092e560e937a11d4ac", + "sha256:9dcfd5d37e027ec393a303cc0a216be564b96c80ba532f3d1e0d2b5e5e4b1e6e", + "sha256:a5ee89587696d808c9a00876065d725d4ae606f5f7853b961cdbc348b0f7c9a1", + "sha256:a6a8b575ac45af1eaccbbcdcf710ab984fd50af048fe130672377f78aaff6fc1", + "sha256:ac83ab05e25354dad798401babaa6daa9577462136ba215694865394840e31f8", + "sha256:ad26d4eeaa0d722b25814cce97335ecf1b707630258f14ac4d2ed3d1d8415265", + "sha256:ad5ec10b53cbb57e9a2e77b67e4e4368df56b54d6b00cc86398578f1c635f329", + "sha256:c82986635a16fb1fa15cd5436035c88bc65c3d5ced1cfaac7f357ee9e9deddd4", + "sha256:ced63c054bdaf0298f62681d5dcae3afe60cbae332390bfb1acf0e23dcd25fc8", + "sha256:d0b16e5bb0ab78583f0ed7ab16378a0f8a89a27256bb5560402749dbe8a164d7", + "sha256:dbbc3c5d15ed76b0d9db7753c0db40899136ecfe97d50cbde918f630c5eb857a", + "sha256:ded8e15f7550db9e75c60b3d9fcbc7737fea258a0f10032cdb7edc26c2a671fd", + "sha256:e02bc4f2966475a7393bd0f098e1165d470d3fa816264054359ed4f10f6914ea", + "sha256:e5666632ba2b0d9757b38fc17337d84bdf932d38563c5234f5f8c54fd01349c9", + "sha256:ea5f8ee87f1eddc818fc04649d952c526db4426d26bab16efbe5a0c52b27d6ab", + "sha256:eb1c0e682138f9067a58fc3c9a9bf1c83d8e08cfbee380d858e63196466d5c86", + "sha256:eb3b8d55924a6058a26db69fb1d3e7e32695ff8b491835ba9f479537e14dcf9f", + "sha256:ee919b676da28f78f91b464fb3e12238bd7474483352a59c8a16c39dfc59f0c5", + "sha256:f02f4a72cc3ab2565c6d9720f0343cb840fb2dc01a2e9ecb8bc58ccf95dc5c06", + "sha256:f4f37bbc6588d402980ffbd1f3338c871368fb4b1cfa091debe13c68bb3852b3", + "sha256:f8651cf1f144f9ee0fa7d1a1df61a9184ab72962531ca99f077bbdcba3947c58", + "sha256:f955aa50d7d5220fcb6e38f69ea126eafecd812d96aeed5d5f3597f33fad43bb", + "sha256:fc10da7e7df3380426521e8c1ed975d22df678639da2ed0ec3244c3dc2ab54c8", + "sha256:fdca0511458d26cf39b827a663d7d87db6f32b93efc22442a742035728603d5f" ], "index": "pypi", "version": "==2.9.7" From d47ba273353af74121f1e5f7fcc81bb4f2eadeae Mon Sep 17 00:00:00 2001 From: Adrian Edwards Date: Sun, 13 Aug 2023 12:27:12 -0400 Subject: [PATCH 194/206] attempt to fix uuid not found --- common/guid.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/guid.py b/common/guid.py index ed95e8b..c67467d 100644 --- a/common/guid.py +++ b/common/guid.py @@ -8,7 +8,7 @@ class HashColumn(types.TypeDecorator): def load_dialect_impl(self, dialect): if dialect.name == 'postgresql': - return dialect.type_descriptor(UUID()) + return dialect.type_descriptor(uuid.UUID()) else: return dialect.type_descriptor(types.BINARY(16)) From 9a7318899f0d76172118c9f0a86ad9b15d6143f2 Mon Sep 17 00:00:00 2001 From: Adrian Edwards Date: Sun, 13 Aug 2023 12:31:56 -0400 Subject: [PATCH 195/206] more attempts --- common/guid.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/common/guid.py b/common/guid.py index c67467d..5054c87 100644 --- a/common/guid.py +++ b/common/guid.py @@ -1,5 +1,6 @@ from __future__ import absolute_import import uuid +from sqlalchemy.dialects.postgresql import UUID from sqlalchemy import types, func #https://docs.sqlalchemy.org/en/13/core/custom_types.html#backend-agnostic-guid-type @@ -8,7 +9,7 @@ class HashColumn(types.TypeDecorator): def load_dialect_impl(self, dialect): if dialect.name == 'postgresql': - return dialect.type_descriptor(uuid.UUID()) + return dialect.type_descriptor(UUID()) else: return dialect.type_descriptor(types.BINARY(16)) @@ -16,8 +17,14 @@ def load_dialect_impl(self, dialect): def process_bind_param(self, value, dialect): if value is None: return value + elif dialect.name == 'postgresql': + return uuid.UUID(value) else: - return uuid.UUID(hex=value).bytes + if not isinstance(value, uuid.UUID): + return uuid.UUID(value).bytes + else: + # bytes + return value.bytes def process_result_value(self, value, dialect): if value is None: From bb9ae11de968b0bdbf485e7b880390d72a3ee676 Mon Sep 17 00:00:00 2001 From: Adrian Edwards Date: Sun, 13 Aug 2023 15:30:43 -0400 Subject: [PATCH 196/206] atempt to fix 'UUID' object has no attribute 'replace' --- common/guid.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/guid.py b/common/guid.py index 5054c87..65736c2 100644 --- a/common/guid.py +++ b/common/guid.py @@ -18,7 +18,7 @@ def process_bind_param(self, value, dialect): if value is None: return value elif dialect.name == 'postgresql': - return uuid.UUID(value) + return uuid.UUID(value).bytes else: if not isinstance(value, uuid.UUID): return uuid.UUID(value).bytes From adeed565d75c814c8dba6de024425137f579bcb3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 17 Apr 2024 17:18:15 +0000 Subject: [PATCH 197/206] Bump gunicorn from 19.9.0 to 22.0.0 Bumps [gunicorn](https://github.com/benoitc/gunicorn) from 19.9.0 to 22.0.0. - [Release notes](https://github.com/benoitc/gunicorn/releases) - [Commits](https://github.com/benoitc/gunicorn/compare/19.9.0...22.0.0) --- updated-dependencies: - dependency-name: gunicorn dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- Pipfile | 2 +- Pipfile.lock | 15 ++++++++------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/Pipfile b/Pipfile index 496608c..8404daa 100644 --- a/Pipfile +++ b/Pipfile @@ -13,7 +13,7 @@ flask-marshmallow = "~=0.10.1" Flask = "~=2.0.0" Flask-Cors = "~=3.0.8" Flask-Limiter = "~=3.2.0" -gunicorn = "~=19.9.0" +gunicorn = "~=22.0.0" sqlalchemy = "~=1.3.13" flask-sqlalchemy = "~=2.5.0" marshmallow-sqlalchemy = "~=0.23" diff --git a/Pipfile.lock b/Pipfile.lock index aeccc0a..ba1cb93 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "b1849b334bc581a3fe5029df9c343865fc0b6c322e3da71f83b432de53f90515" + "sha256": "80869db229f6dc524dd905ca300ea58395a164495d77140b4ee4bb160f21ebfd" }, "pipfile-spec": 6, "requires": { @@ -232,11 +232,12 @@ }, "gunicorn": { "hashes": [ - "sha256:aa8e0b40b4157b36a5df5e599f45c9c76d6af43845ba3b3b0efe2c70473c2471", - "sha256:fa2662097c66f920f53f70621c6c58ca4a3c4d3434205e608e121b5b3b71f4f3" + "sha256:350679f91b24062c86e386e198a15438d53a7a8207235a78ba1b53df4c4378d9", + "sha256:4a0b436239ff76fb33f11c07a16482c521a7e09c1ce3cc293c2330afe01bec63" ], "index": "pypi", - "version": "==19.9.0" + "markers": "python_version >= '3.7'", + "version": "==22.0.0" }, "idna": { "hashes": [ @@ -438,11 +439,11 @@ }, "packaging": { "hashes": [ - "sha256:714ac14496c3e68c99c29b00845f7a2b85f3bb6f1078fd9f72fd20f0570002b2", - "sha256:b6ad297f8907de0fa2fe1ccbd26fdaf387f5f47c7275fedf8cce89f99446cf97" + "sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5", + "sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9" ], "markers": "python_version >= '3.7'", - "version": "==23.0" + "version": "==24.0" }, "pkgutil-resolve-name": { "hashes": [ From e213d5a10f717b62837b370316f11fa0db84ee4c Mon Sep 17 00:00:00 2001 From: Adrian Edwards Date: Tue, 8 Oct 2024 20:13:13 -0400 Subject: [PATCH 198/206] install ordered_set (causing crash) and lock werkzeug to not go to 3.0 (requires larger changes) --- Pipfile | 2 + Pipfile.lock | 1207 +++++++++++++++++++++++++++----------------------- 2 files changed, 653 insertions(+), 556 deletions(-) diff --git a/Pipfile b/Pipfile index 8404daa..03a86f0 100644 --- a/Pipfile +++ b/Pipfile @@ -14,6 +14,7 @@ Flask = "~=2.0.0" Flask-Cors = "~=3.0.8" Flask-Limiter = "~=3.2.0" gunicorn = "~=22.0.0" +werkzeug = "~=2.0.0" sqlalchemy = "~=1.3.13" flask-sqlalchemy = "~=2.5.0" marshmallow-sqlalchemy = "~=0.23" @@ -25,6 +26,7 @@ python-dotenv = "*" flask-migrate = "*" requests = "*" sentry-sdk = "*" +ordered-set = "*" [requires] python_version = "3.8" diff --git a/Pipfile.lock b/Pipfile.lock index ba1cb93..969f808 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "80869db229f6dc524dd905ca300ea58395a164495d77140b4ee4bb160f21ebfd" + "sha256": "8456fae80b7723a416a0f2bb483ab90e665c9ab2ffa8d1368dfee2bbadf16180" }, "pipfile-spec": 6, "requires": { @@ -18,11 +18,11 @@ "default": { "alembic": { "hashes": [ - "sha256:4d3bd32ecdbb7bbfb48a9fe9e6d6fd6a831a1b59d03e26e292210237373e7db5", - "sha256:6f1c2207369bf4f49f952057a33bb017fbe5c148c2a773b46906b806ea6e825f" + "sha256:203503117415561e203aa14541740643a611f641517f0209fcae63e9fa09f1a2", + "sha256:908e905976d15235fae59c9ac42c4c5b75cfcefe3d27c0fbf7ae15a37715d80e" ], - "markers": "python_version >= '3.7'", - "version": "==1.9.4" + "markers": "python_version >= '3.8'", + "version": "==1.13.3" }, "apispec": { "hashes": [ @@ -42,145 +42,146 @@ }, "attrs": { "hashes": [ - "sha256:29e95c7f6778868dbd49170f98f8818f78f3dc5e0e37c0b1f474e3561b240836", - "sha256:c9227bfc2f01993c03f68db37d1d15c9690188323c067c641f1a35ca58185f99" + "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346", + "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2" ], - "markers": "python_version >= '3.6'", - "version": "==22.2.0" + "markers": "python_version >= '3.7'", + "version": "==24.2.0" }, "certifi": { "hashes": [ - "sha256:35824b4c3a97115964b408844d64aa14db1cc518f6562e8d7261699d1350a9e3", - "sha256:4ad3232f5e926d6718ec31cfc1fcadfde020920e278684144551c91769c7bc18" + "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8", + "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9" ], "markers": "python_version >= '3.6'", - "version": "==2022.12.7" + "version": "==2024.8.30" }, "charset-normalizer": { "hashes": [ - "sha256:00d3ffdaafe92a5dc603cb9bd5111aaa36dfa187c8285c543be562e61b755f6b", - "sha256:024e606be3ed92216e2b6952ed859d86b4cfa52cd5bc5f050e7dc28f9b43ec42", - "sha256:0298eafff88c99982a4cf66ba2efa1128e4ddaca0b05eec4c456bbc7db691d8d", - "sha256:02a51034802cbf38db3f89c66fb5d2ec57e6fe7ef2f4a44d070a593c3688667b", - "sha256:083c8d17153ecb403e5e1eb76a7ef4babfc2c48d58899c98fcaa04833e7a2f9a", - "sha256:0a11e971ed097d24c534c037d298ad32c6ce81a45736d31e0ff0ad37ab437d59", - "sha256:0bf2dae5291758b6f84cf923bfaa285632816007db0330002fa1de38bfcb7154", - "sha256:0c0a590235ccd933d9892c627dec5bc7511ce6ad6c1011fdf5b11363022746c1", - "sha256:0f438ae3532723fb6ead77e7c604be7c8374094ef4ee2c5e03a3a17f1fca256c", - "sha256:109487860ef6a328f3eec66f2bf78b0b72400280d8f8ea05f69c51644ba6521a", - "sha256:11b53acf2411c3b09e6af37e4b9005cba376c872503c8f28218c7243582df45d", - "sha256:12db3b2c533c23ab812c2b25934f60383361f8a376ae272665f8e48b88e8e1c6", - "sha256:14e76c0f23218b8f46c4d87018ca2e441535aed3632ca134b10239dfb6dadd6b", - "sha256:16a8663d6e281208d78806dbe14ee9903715361cf81f6d4309944e4d1e59ac5b", - "sha256:292d5e8ba896bbfd6334b096e34bffb56161c81408d6d036a7dfa6929cff8783", - "sha256:2c03cc56021a4bd59be889c2b9257dae13bf55041a3372d3295416f86b295fb5", - "sha256:2e396d70bc4ef5325b72b593a72c8979999aa52fb8bcf03f701c1b03e1166918", - "sha256:2edb64ee7bf1ed524a1da60cdcd2e1f6e2b4f66ef7c077680739f1641f62f555", - "sha256:31a9ddf4718d10ae04d9b18801bd776693487cbb57d74cc3458a7673f6f34639", - "sha256:356541bf4381fa35856dafa6a965916e54bed415ad8a24ee6de6e37deccf2786", - "sha256:358a7c4cb8ba9b46c453b1dd8d9e431452d5249072e4f56cfda3149f6ab1405e", - "sha256:37f8febc8ec50c14f3ec9637505f28e58d4f66752207ea177c1d67df25da5aed", - "sha256:39049da0ffb96c8cbb65cbf5c5f3ca3168990adf3551bd1dee10c48fce8ae820", - "sha256:39cf9ed17fe3b1bc81f33c9ceb6ce67683ee7526e65fde1447c772afc54a1bb8", - "sha256:3ae1de54a77dc0d6d5fcf623290af4266412a7c4be0b1ff7444394f03f5c54e3", - "sha256:3b590df687e3c5ee0deef9fc8c547d81986d9a1b56073d82de008744452d6541", - "sha256:3e45867f1f2ab0711d60c6c71746ac53537f1684baa699f4f668d4c6f6ce8e14", - "sha256:3fc1c4a2ffd64890aebdb3f97e1278b0cc72579a08ca4de8cd2c04799a3a22be", - "sha256:4457ea6774b5611f4bed5eaa5df55f70abde42364d498c5134b7ef4c6958e20e", - "sha256:44ba614de5361b3e5278e1241fda3dc1838deed864b50a10d7ce92983797fa76", - "sha256:4a8fcf28c05c1f6d7e177a9a46a1c52798bfe2ad80681d275b10dcf317deaf0b", - "sha256:4b0d02d7102dd0f997580b51edc4cebcf2ab6397a7edf89f1c73b586c614272c", - "sha256:502218f52498a36d6bf5ea77081844017bf7982cdbe521ad85e64cabee1b608b", - "sha256:503e65837c71b875ecdd733877d852adbc465bd82c768a067badd953bf1bc5a3", - "sha256:5995f0164fa7df59db4746112fec3f49c461dd6b31b841873443bdb077c13cfc", - "sha256:59e5686dd847347e55dffcc191a96622f016bc0ad89105e24c14e0d6305acbc6", - "sha256:601f36512f9e28f029d9481bdaf8e89e5148ac5d89cffd3b05cd533eeb423b59", - "sha256:608862a7bf6957f2333fc54ab4399e405baad0163dc9f8d99cb236816db169d4", - "sha256:62595ab75873d50d57323a91dd03e6966eb79c41fa834b7a1661ed043b2d404d", - "sha256:70990b9c51340e4044cfc394a81f614f3f90d41397104d226f21e66de668730d", - "sha256:71140351489970dfe5e60fc621ada3e0f41104a5eddaca47a7acb3c1b851d6d3", - "sha256:72966d1b297c741541ca8cf1223ff262a6febe52481af742036a0b296e35fa5a", - "sha256:74292fc76c905c0ef095fe11e188a32ebd03bc38f3f3e9bcb85e4e6db177b7ea", - "sha256:761e8904c07ad053d285670f36dd94e1b6ab7f16ce62b9805c475b7aa1cffde6", - "sha256:772b87914ff1152b92a197ef4ea40efe27a378606c39446ded52c8f80f79702e", - "sha256:79909e27e8e4fcc9db4addea88aa63f6423ebb171db091fb4373e3312cb6d603", - "sha256:7e189e2e1d3ed2f4aebabd2d5b0f931e883676e51c7624826e0a4e5fe8a0bf24", - "sha256:7eb33a30d75562222b64f569c642ff3dc6689e09adda43a082208397f016c39a", - "sha256:81d6741ab457d14fdedc215516665050f3822d3e56508921cc7239f8c8e66a58", - "sha256:8499ca8f4502af841f68135133d8258f7b32a53a1d594aa98cc52013fff55678", - "sha256:84c3990934bae40ea69a82034912ffe5a62c60bbf6ec5bc9691419641d7d5c9a", - "sha256:87701167f2a5c930b403e9756fab1d31d4d4da52856143b609e30a1ce7160f3c", - "sha256:88600c72ef7587fe1708fd242b385b6ed4b8904976d5da0893e31df8b3480cb6", - "sha256:8ac7b6a045b814cf0c47f3623d21ebd88b3e8cf216a14790b455ea7ff0135d18", - "sha256:8b8af03d2e37866d023ad0ddea594edefc31e827fee64f8de5611a1dbc373174", - "sha256:8c7fe7afa480e3e82eed58e0ca89f751cd14d767638e2550c77a92a9e749c317", - "sha256:8eade758719add78ec36dc13201483f8e9b5d940329285edcd5f70c0a9edbd7f", - "sha256:911d8a40b2bef5b8bbae2e36a0b103f142ac53557ab421dc16ac4aafee6f53dc", - "sha256:93ad6d87ac18e2a90b0fe89df7c65263b9a99a0eb98f0a3d2e079f12a0735837", - "sha256:95dea361dd73757c6f1c0a1480ac499952c16ac83f7f5f4f84f0658a01b8ef41", - "sha256:9ab77acb98eba3fd2a85cd160851816bfce6871d944d885febf012713f06659c", - "sha256:9cb3032517f1627cc012dbc80a8ec976ae76d93ea2b5feaa9d2a5b8882597579", - "sha256:9cf4e8ad252f7c38dd1f676b46514f92dc0ebeb0db5552f5f403509705e24753", - "sha256:9d9153257a3f70d5f69edf2325357251ed20f772b12e593f3b3377b5f78e7ef8", - "sha256:a152f5f33d64a6be73f1d30c9cc82dfc73cec6477ec268e7c6e4c7d23c2d2291", - "sha256:a16418ecf1329f71df119e8a65f3aa68004a3f9383821edcb20f0702934d8087", - "sha256:a60332922359f920193b1d4826953c507a877b523b2395ad7bc716ddd386d866", - "sha256:a8d0fc946c784ff7f7c3742310cc8a57c5c6dc31631269876a88b809dbeff3d3", - "sha256:ab5de034a886f616a5668aa5d098af2b5385ed70142090e2a31bcbd0af0fdb3d", - "sha256:c22d3fe05ce11d3671297dc8973267daa0f938b93ec716e12e0f6dee81591dc1", - "sha256:c2ac1b08635a8cd4e0cbeaf6f5e922085908d48eb05d44c5ae9eabab148512ca", - "sha256:c512accbd6ff0270939b9ac214b84fb5ada5f0409c44298361b2f5e13f9aed9e", - "sha256:c75ffc45f25324e68ab238cb4b5c0a38cd1c3d7f1fb1f72b5541de469e2247db", - "sha256:c95a03c79bbe30eec3ec2b7f076074f4281526724c8685a42872974ef4d36b72", - "sha256:cadaeaba78750d58d3cc6ac4d1fd867da6fc73c88156b7a3212a3cd4819d679d", - "sha256:cd6056167405314a4dc3c173943f11249fa0f1b204f8b51ed4bde1a9cd1834dc", - "sha256:db72b07027db150f468fbada4d85b3b2729a3db39178abf5c543b784c1254539", - "sha256:df2c707231459e8a4028eabcd3cfc827befd635b3ef72eada84ab13b52e1574d", - "sha256:e62164b50f84e20601c1ff8eb55620d2ad25fb81b59e3cd776a1902527a788af", - "sha256:e696f0dd336161fca9adbb846875d40752e6eba585843c768935ba5c9960722b", - "sha256:eaa379fcd227ca235d04152ca6704c7cb55564116f8bc52545ff357628e10602", - "sha256:ebea339af930f8ca5d7a699b921106c6e29c617fe9606fa7baa043c1cdae326f", - "sha256:f4c39b0e3eac288fedc2b43055cfc2ca7a60362d0e5e87a637beac5d801ef478", - "sha256:f5057856d21e7586765171eac8b9fc3f7d44ef39425f85dbcccb13b3ebea806c", - "sha256:f6f45710b4459401609ebebdbcfb34515da4fc2aa886f95107f556ac69a9147e", - "sha256:f97e83fa6c25693c7a35de154681fcc257c1c41b38beb0304b9c4d2d9e164479", - "sha256:f9d0c5c045a3ca9bedfc35dca8526798eb91a07aa7a2c0fee134c6c6f321cbd7", - "sha256:ff6f3db31555657f3163b15a6b7c6938d08df7adbfc9dd13d9d19edad678f1e8" + "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027", + "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087", + "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786", + "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8", + "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09", + "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185", + "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574", + "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e", + "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519", + "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898", + "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269", + "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3", + "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f", + "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6", + "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8", + "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a", + "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73", + "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc", + "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714", + "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2", + "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc", + "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce", + "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d", + "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e", + "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6", + "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269", + "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96", + "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d", + "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a", + "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4", + "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77", + "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d", + "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0", + "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed", + "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068", + "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac", + "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25", + "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8", + "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab", + "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26", + "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2", + "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db", + "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f", + "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5", + "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99", + "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c", + "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d", + "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811", + "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa", + "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a", + "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03", + "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b", + "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04", + "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c", + "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001", + "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458", + "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389", + "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99", + "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985", + "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537", + "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238", + "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f", + "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d", + "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796", + "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a", + "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143", + "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8", + "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c", + "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5", + "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5", + "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711", + "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4", + "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6", + "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c", + "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7", + "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4", + "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b", + "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae", + "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12", + "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c", + "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae", + "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8", + "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887", + "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b", + "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4", + "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f", + "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5", + "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33", + "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519", + "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561" ], - "markers": "python_version >= '3.6'", - "version": "==3.0.1" + "markers": "python_version >= '3.7'", + "version": "==3.3.2" }, "click": { "hashes": [ - "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e", - "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48" + "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28", + "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de" ], "markers": "python_version >= '3.7'", - "version": "==8.1.3" + "version": "==8.1.7" }, "deprecated": { "hashes": [ - "sha256:43ac5335da90c31c24ba028af536a91d41d53f9e6901ddb021bcc572ce44e38d", - "sha256:64756e3e14c8c5eea9795d93c524551432a0be75629f8f29e67ab8caf076c76d" + "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c", + "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3" ], "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==1.2.13" + "version": "==1.2.14" }, "ecdsa": { "hashes": [ - "sha256:190348041559e21b22a1d65cee485282ca11a6f81d503fddb84d5017e9ed1e49", - "sha256:80600258e7ed2f16b9aa1d7c295bd70194109ad5a30fdee0eaeefef1d4c559dd" + "sha256:2cea9b88407fdac7bbeca0833b189e4c9c53f2ef1e1eaa29f6224dbc809b707a", + "sha256:60eaad1199659900dd0af521ed462b793bbdf867432b3948e87416ae4caf6bf8" ], - "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==0.18.0" + "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", + "version": "==0.19.0" }, "flasgger": { "hashes": [ - "sha256:0603941cf4003626b4ee551ca87331f1d17b8eecce500ccf1a1f1d3a332fc94a", - "sha256:6ebea406b5beecd77e8da42550f380d4d05a6107bc90b69ce9e77aee7612e2d0" + "sha256:ca098e10bfbb12f047acc6299cc70a33851943a746e550d86e65e60d4df245fb" ], "index": "pypi", - "version": "==0.9.5" + "version": "==0.9.7.1" }, "flask": { "hashes": [ @@ -216,11 +217,11 @@ }, "flask-migrate": { "hashes": [ - "sha256:73293d40b10ac17736e715b377e7b7bde474cb8105165d77474df4c3619b10b3", - "sha256:77580f27ab39bc68be4906a43c56d7674b45075bc4f883b1d0b985db5164d58f" + "sha256:5c532be17e7b43a223b7500d620edae33795df27c75811ddf32560f7d48ec617", + "sha256:dff7dd25113c210b069af280ea713b883f3840c1e3455274745d7355778c8622" ], "index": "pypi", - "version": "==4.0.4" + "version": "==4.0.7" }, "flask-sqlalchemy": { "hashes": [ @@ -236,152 +237,169 @@ "sha256:4a0b436239ff76fb33f11c07a16482c521a7e09c1ce3cc293c2330afe01bec63" ], "index": "pypi", - "markers": "python_version >= '3.7'", "version": "==22.0.0" }, "idna": { "hashes": [ - "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4", - "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2" + "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9", + "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3" ], - "markers": "python_version >= '3.5'", - "version": "==3.4" + "markers": "python_version >= '3.6'", + "version": "==3.10" }, "importlib-metadata": { "hashes": [ - "sha256:7efb448ec9a5e313a57655d35aa54cd3e01b7e1fbcf72dce1bf06119420f5bad", - "sha256:e354bedeb60efa6affdcc8ae121b73544a7aa74156d047311948f6d711cd378d" + "sha256:45e54197d28b7a7f1559e60b95e7c567032b602131fbd588f1497f47880aa68b", + "sha256:71522656f0abace1d072b9e5481a48f07c138e00f079c38c8f883823f9c26bd7" ], "markers": "python_version < '3.9'", - "version": "==6.0.0" + "version": "==8.5.0" }, "importlib-resources": { "hashes": [ - "sha256:1e534a02295f3eeee0785e21b26c726557909cbaf1b871cf9adcbc0df44c1308", - "sha256:c0a55f37559b5e9ca1d3fce02d60243846245ad8f8d806a4484093806d4d0ae5" + "sha256:980862a1d16c9e147a59603677fa2aa5fd82b87f223b6cb870695bcfce830065", + "sha256:ac29d5f956f01d5e4bb63102a5a19957f1b9175e45649977264a1416783bb717" ], "markers": "python_version < '3.9'", - "version": "==5.11.0" + "version": "==6.4.5" }, "itsdangerous": { "hashes": [ - "sha256:2c2349112351b88699d8d4b6b075022c0808887cb7ad10069318a8b0bc88db44", - "sha256:5dbbc68b317e5e42f327f9021763545dc3fc3bfe22e6deb96aaf1fc38874156a" + "sha256:c6242fc49e35958c8b15141343aa660db5fc54d4f13a1db01a3f5891b98700ef", + "sha256:e0050c0b7da1eea53ffaf149c0cfbb5c6e2e2b69c4bef22c81fa6eb73e5f6173" ], - "markers": "python_version >= '3.7'", - "version": "==2.1.2" + "markers": "python_version >= '3.8'", + "version": "==2.2.0" }, "jinja2": { "hashes": [ - "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852", - "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61" + "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369", + "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d" ], "markers": "python_version >= '3.7'", - "version": "==3.1.2" + "version": "==3.1.4" }, "jsonschema": { "hashes": [ - "sha256:0f864437ab8b6076ba6707453ef8f98a6a0d512a80e93f8abdb676f737ecb60d", - "sha256:a870ad254da1a8ca84b6a2905cac29d265f805acc57af304784962a2aa6508f6" + "sha256:d71497fef26351a33265337fa77ffeb82423f3ea21283cd9467bb03999266bc4", + "sha256:fbadb6f8b144a8f8cf9f0b89ba94501d143e50411a1278633f56a7acf7fd5566" ], - "markers": "python_version >= '3.7'", - "version": "==4.17.3" + "markers": "python_version >= '3.8'", + "version": "==4.23.0" + }, + "jsonschema-specifications": { + "hashes": [ + "sha256:48a76787b3e70f5ed53f1160d2b81f586e4ca6d1548c5de7085d1682674764cc", + "sha256:87e4fdf3a94858b8a2ba2778d9ba57d8a9cafca7c7489c46ba0d30a8bc6a9c3c" + ], + "markers": "python_version >= '3.8'", + "version": "==2023.12.1" }, "limits": { "hashes": [ - "sha256:3e12a0d90bc1fb7f3d95fe61c5a76770aaeb21d50f590268187a8884d513c1da", - "sha256:6fe1d261162ca6fd8023311273661a7355bc0f4615832bc9a4d6e45c0df59f5e" + "sha256:6571b0c567bfa175a35fed9f8a954c0c92f1c3200804282f1b8f1de4ad98a953", + "sha256:9767f7233da4255e9904b79908a728e8ec0984c0b086058b4cbbd309aea553f6" ], - "markers": "python_version >= '3.7'", - "version": "==3.2.0" + "markers": "python_version >= '3.8'", + "version": "==3.13.0" }, "mako": { "hashes": [ - "sha256:c97c79c018b9165ac9922ae4f32da095ffd3c4e6872b45eded42926deea46818", - "sha256:d60a3903dc3bb01a18ad6a89cdbe2e4eadc69c0bc8ef1e3773ba53d44c3f7a34" + "sha256:260f1dbc3a519453a9c856dedfe4beb4e50bd5a26d96386cb6c80856556bb91a", + "sha256:48dbc20568c1d276a2698b36d968fa76161bf127194907ea6fc594fa81f943bc" ], - "markers": "python_version >= '3.7'", - "version": "==1.2.4" + "markers": "python_version >= '3.8'", + "version": "==1.3.5" }, "markdown-it-py": { "hashes": [ - "sha256:93de681e5c021a432c63147656fe21790bc01231e0cd2da73626f1aa3ac0fe27", - "sha256:cf7e59fed14b5ae17c0006eff14a2d9a00ed5f3a846148153899a0224e2c07da" + "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1", + "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb" ], - "markers": "python_version >= '3.7'", - "version": "==2.1.0" + "markers": "python_version >= '3.8'", + "version": "==3.0.0" }, "markupsafe": { "hashes": [ - "sha256:0576fe974b40a400449768941d5d0858cc624e3249dfd1e0c33674e5c7ca7aed", - "sha256:085fd3201e7b12809f9e6e9bc1e5c96a368c8523fad5afb02afe3c051ae4afcc", - "sha256:090376d812fb6ac5f171e5938e82e7f2d7adc2b629101cec0db8b267815c85e2", - "sha256:0b462104ba25f1ac006fdab8b6a01ebbfbce9ed37fd37fd4acd70c67c973e460", - "sha256:137678c63c977754abe9086a3ec011e8fd985ab90631145dfb9294ad09c102a7", - "sha256:1bea30e9bf331f3fef67e0a3877b2288593c98a21ccb2cf29b74c581a4eb3af0", - "sha256:22152d00bf4a9c7c83960521fc558f55a1adbc0631fbb00a9471e097b19d72e1", - "sha256:22731d79ed2eb25059ae3df1dfc9cb1546691cc41f4e3130fe6bfbc3ecbbecfa", - "sha256:2298c859cfc5463f1b64bd55cb3e602528db6fa0f3cfd568d3605c50678f8f03", - "sha256:28057e985dace2f478e042eaa15606c7efccb700797660629da387eb289b9323", - "sha256:2e7821bffe00aa6bd07a23913b7f4e01328c3d5cc0b40b36c0bd81d362faeb65", - "sha256:2ec4f2d48ae59bbb9d1f9d7efb9236ab81429a764dedca114f5fdabbc3788013", - "sha256:340bea174e9761308703ae988e982005aedf427de816d1afe98147668cc03036", - "sha256:40627dcf047dadb22cd25ea7ecfe9cbf3bbbad0482ee5920b582f3809c97654f", - "sha256:40dfd3fefbef579ee058f139733ac336312663c6706d1163b82b3003fb1925c4", - "sha256:4cf06cdc1dda95223e9d2d3c58d3b178aa5dacb35ee7e3bbac10e4e1faacb419", - "sha256:50c42830a633fa0cf9e7d27664637532791bfc31c731a87b202d2d8ac40c3ea2", - "sha256:55f44b440d491028addb3b88f72207d71eeebfb7b5dbf0643f7c023ae1fba619", - "sha256:608e7073dfa9e38a85d38474c082d4281f4ce276ac0010224eaba11e929dd53a", - "sha256:63ba06c9941e46fa389d389644e2d8225e0e3e5ebcc4ff1ea8506dce646f8c8a", - "sha256:65608c35bfb8a76763f37036547f7adfd09270fbdbf96608be2bead319728fcd", - "sha256:665a36ae6f8f20a4676b53224e33d456a6f5a72657d9c83c2aa00765072f31f7", - "sha256:6d6607f98fcf17e534162f0709aaad3ab7a96032723d8ac8750ffe17ae5a0666", - "sha256:7313ce6a199651c4ed9d7e4cfb4aa56fe923b1adf9af3b420ee14e6d9a73df65", - "sha256:7668b52e102d0ed87cb082380a7e2e1e78737ddecdde129acadb0eccc5423859", - "sha256:7df70907e00c970c60b9ef2938d894a9381f38e6b9db73c5be35e59d92e06625", - "sha256:7e007132af78ea9df29495dbf7b5824cb71648d7133cf7848a2a5dd00d36f9ff", - "sha256:835fb5e38fd89328e9c81067fd642b3593c33e1e17e2fdbf77f5676abb14a156", - "sha256:8bca7e26c1dd751236cfb0c6c72d4ad61d986e9a41bbf76cb445f69488b2a2bd", - "sha256:8db032bf0ce9022a8e41a22598eefc802314e81b879ae093f36ce9ddf39ab1ba", - "sha256:99625a92da8229df6d44335e6fcc558a5037dd0a760e11d84be2260e6f37002f", - "sha256:9cad97ab29dfc3f0249b483412c85c8ef4766d96cdf9dcf5a1e3caa3f3661cf1", - "sha256:a4abaec6ca3ad8660690236d11bfe28dfd707778e2442b45addd2f086d6ef094", - "sha256:a6e40afa7f45939ca356f348c8e23048e02cb109ced1eb8420961b2f40fb373a", - "sha256:a6f2fcca746e8d5910e18782f976489939d54a91f9411c32051b4aab2bd7c513", - "sha256:a806db027852538d2ad7555b203300173dd1b77ba116de92da9afbc3a3be3eed", - "sha256:abcabc8c2b26036d62d4c746381a6f7cf60aafcc653198ad678306986b09450d", - "sha256:b8526c6d437855442cdd3d87eede9c425c4445ea011ca38d937db299382e6fa3", - "sha256:bb06feb762bade6bf3c8b844462274db0c76acc95c52abe8dbed28ae3d44a147", - "sha256:c0a33bc9f02c2b17c3ea382f91b4db0e6cde90b63b296422a939886a7a80de1c", - "sha256:c4a549890a45f57f1ebf99c067a4ad0cb423a05544accaf2b065246827ed9603", - "sha256:ca244fa73f50a800cf8c3ebf7fd93149ec37f5cb9596aa8873ae2c1d23498601", - "sha256:cf877ab4ed6e302ec1d04952ca358b381a882fbd9d1b07cccbfd61783561f98a", - "sha256:d9d971ec1e79906046aa3ca266de79eac42f1dbf3612a05dc9368125952bd1a1", - "sha256:da25303d91526aac3672ee6d49a2f3db2d9502a4a60b55519feb1a4c7714e07d", - "sha256:e55e40ff0cc8cc5c07996915ad367fa47da6b3fc091fdadca7f5403239c5fec3", - "sha256:f03a532d7dee1bed20bc4884194a16160a2de9ffc6354b3878ec9682bb623c54", - "sha256:f1cd098434e83e656abf198f103a8207a8187c0fc110306691a2e94a78d0abb2", - "sha256:f2bfb563d0211ce16b63c7cb9395d2c682a23187f54c3d79bfec33e6705473c6", - "sha256:f8ffb705ffcf5ddd0e80b65ddf7bed7ee4f5a441ea7d3419e861a12eaf41af58" + "sha256:00e046b6dd71aa03a41079792f8473dc494d564611a8f89bbbd7cb93295ebdcf", + "sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff", + "sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f", + "sha256:17b950fccb810b3293638215058e432159d2b71005c74371d784862b7e4683f3", + "sha256:1f3fbcb7ef1f16e48246f704ab79d79da8a46891e2da03f8783a5b6fa41a9532", + "sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f", + "sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617", + "sha256:2d2d793e36e230fd32babe143b04cec8a8b3eb8a3122d2aceb4a371e6b09b8df", + "sha256:30b600cf0a7ac9234b2638fbc0fb6158ba5bdcdf46aeb631ead21248b9affbc4", + "sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906", + "sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f", + "sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4", + "sha256:3e53af139f8579a6d5f7b76549125f0d94d7e630761a2111bc431fd820e163b8", + "sha256:4096e9de5c6fdf43fb4f04c26fb114f61ef0bf2e5604b6ee3019d51b69e8c371", + "sha256:4275d846e41ecefa46e2015117a9f491e57a71ddd59bbead77e904dc02b1bed2", + "sha256:4c31f53cdae6ecfa91a77820e8b151dba54ab528ba65dfd235c80b086d68a465", + "sha256:4f11aa001c540f62c6166c7726f71f7573b52c68c31f014c25cc7901deea0b52", + "sha256:5049256f536511ee3f7e1b3f87d1d1209d327e818e6ae1365e8653d7e3abb6a6", + "sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169", + "sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad", + "sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2", + "sha256:5dedb4db619ba5a2787a94d877bc8ffc0566f92a01c0ef214865e54ecc9ee5e0", + "sha256:619bc166c4f2de5caa5a633b8b7326fbe98e0ccbfacabd87268a2b15ff73a029", + "sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f", + "sha256:656f7526c69fac7f600bd1f400991cc282b417d17539a1b228617081106feb4a", + "sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced", + "sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5", + "sha256:7502934a33b54030eaf1194c21c692a534196063db72176b0c4028e140f8f32c", + "sha256:7a68b554d356a91cce1236aa7682dc01df0edba8d043fd1ce607c49dd3c1edcf", + "sha256:7b2e5a267c855eea6b4283940daa6e88a285f5f2a67f2220203786dfa59b37e9", + "sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb", + "sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad", + "sha256:8dd717634f5a044f860435c1d8c16a270ddf0ef8588d4887037c5028b859b0c3", + "sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1", + "sha256:97cafb1f3cbcd3fd2b6fbfb99ae11cdb14deea0736fc2b0952ee177f2b813a46", + "sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc", + "sha256:a549b9c31bec33820e885335b451286e2969a2d9e24879f83fe904a5ce59d70a", + "sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee", + "sha256:ae2ad8ae6ebee9d2d94b17fb62763125f3f374c25618198f40cbb8b525411900", + "sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5", + "sha256:bc1667f8b83f48511b94671e0e441401371dfd0f0a795c7daa4a3cd1dde55bea", + "sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f", + "sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5", + "sha256:bff1b4290a66b490a2f4719358c0cdcd9bafb6b8f061e45c7a2460866bf50c2e", + "sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a", + "sha256:c8b29db45f8fe46ad280a7294f5c3ec36dbac9491f2d1c17345be8e69cc5928f", + "sha256:ce409136744f6521e39fd8e2a24c53fa18ad67aa5bc7c2cf83645cce5b5c4e50", + "sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a", + "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b", + "sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4", + "sha256:daa4ee5a243f0f20d528d939d06670a298dd39b1ad5f8a72a4275124a7819eff", + "sha256:db0b55e0f3cc0be60c1f19efdde9a637c32740486004f20d1cff53c3c0ece4d2", + "sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46", + "sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b", + "sha256:ec6a563cff360b50eed26f13adc43e61bc0c04d94b8be985e6fb24b81f6dcfdf", + "sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5", + "sha256:fa173ec60341d6bb97a89f5ea19c85c5643c1e7dedebc22f5181eb73573142c5", + "sha256:fa9db3f79de01457b03d4f01b34cf91bc0048eb2c3846ff26f66687c2f6d16ab", + "sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd", + "sha256:ffee1f21e5ef0d712f9033568f8344d5da8cc2869dbd08d87c84656e6a2d2f68" ], "markers": "python_version >= '3.7'", - "version": "==2.1.2" + "version": "==2.1.5" }, "marshmallow": { "hashes": [ - "sha256:90032c0fd650ce94b6ec6dc8dfeb0e3ff50c144586462c389b81a07205bedb78", - "sha256:93f0958568da045b0021ec6aeb7ac37c81bfcccbb9a0e7ed8559885070b3a19b" + "sha256:4972f529104a220bb8637d595aa4c9762afbe7f7a77d82dc58c1615d70c5823e", + "sha256:71a2dce49ef901c3f97ed296ae5051135fd3febd2bf43afe0ae9a82143a494d9" ], - "markers": "python_version >= '3.7'", - "version": "==3.19.0" + "markers": "python_version >= '3.8'", + "version": "==3.22.0" }, "marshmallow-sqlalchemy": { "hashes": [ - "sha256:aa376747296780a56355e3067b9c8bf43a2a1c44ff985de82b3a5d9e161ca2b8", - "sha256:dbb061c19375eca3a7d18358d2ca8bbaee825fc3000a3f114e2698282362b536" + "sha256:2ab0f1280c793e5aec81deab3e63ec23688ddfe05e5f38ac960368a1079520a1", + "sha256:c31b3bdf794de1d78c53e1c495502cbb3eeb06ed216869980c71d6159e7e9e66" ], "index": "pypi", - "version": "==0.28.1" + "version": "==0.28.2" }, "mdurl": { "hashes": [ @@ -393,57 +411,59 @@ }, "mistune": { "hashes": [ - "sha256:0246113cb2492db875c6be56974a7c893333bf26cd92891c85f63151cee09d34", - "sha256:bad7f5d431886fcbaf5f758118ecff70d31f75231b34024a1341120340a65ce8" + "sha256:71481854c30fdbc938963d3605b72501f5c10a9320ecd412c121c163a1c7d205", + "sha256:fc7f93ded930c92394ef2cb6f04a8aabab4117a91449e72dcc8dfa646a508be8" ], - "version": "==2.0.5" + "markers": "python_version >= '3.7'", + "version": "==3.0.2" }, "mysql-connector-python": { "hashes": [ - "sha256:145aeb75eefb7425e0a7fb36a4f95ebfe79e06be7c69a4045d34cde95c666dc4", - "sha256:1c0a11f3ffbf850f2ca7b39e6c82021e8de910ddaeffd856e53dca028d21c923", - "sha256:1f399f3c2599d2591854cd0e0a24c7c399dff21ac5accb6e52e06924de29f3f4", - "sha256:232095f0c36266510009b0f1214d2823a649efb8bc511dbab9ce8847f66ab08a", - "sha256:283fe6f647e9d684feb1b7c48fa6a46b1e72c59ecdd6ea2b62392cd80c1a6701", - "sha256:4b2d00c9e2cb9e3d11c57ec411226f43aa627607085fbed661cfea1c4dc57f61", - "sha256:4df11c683924ef34c177a54887dc4844ae735b01c8a29ce6ab92d6d3db7a2757", - "sha256:677b5c6dcaec7e2a4bf95b991a869f4d371114f69a0d9a5bb236e988c8f4c376", - "sha256:6cdba2779bcd16af0ceff0a6e50d33e6664a83f8d17d70524beb6f677a6d1fae", - "sha256:7f7a69db9e0c36764a6c65377f6174aee46e484520e48659e7aa674415b8e192", - "sha256:8c334c41cd1c5bcfa3550340253ef7d9d3b962211f33327c20f69706a0bcce06", - "sha256:8c5bfedc979d7858402f39c20d66a6cf03ca4c960732a98318126c278535ddb2", - "sha256:93b1eb3e07d19a23ccf2605d818aacee0d842b1820bbeef8d0022d8d3d014ab9", - "sha256:992b7a464daa398e86df8c75f7d8cd6044f884ff9087e782120fc8beff96c638", - "sha256:ab13dd6ede0e0e99ba97c73946462c3420625ab6e63fe13b6fc350e30eb3298d", - "sha256:bd52a462759aa324a60054c4b44dc8b32007187a328f72be6b58f193d5e32a91", - "sha256:bdd716b1e162fe4b3887f6617e9ddcfa659ba96a9ddb22feeae208a72f43d22f", - "sha256:be82357cc7e7e1377e2f4f8c18aa89c8aab6c0117155cf9fcf18e3cd0eb6ac8e", - "sha256:c2d20b29fd096a0633f9360c275bd2434d4bcf597281991c4b7f1c820cd07b84", - "sha256:c8bba02501525e1fbbba094a6d8d391d1534e8be41be6396c3e1b9f7d9d13b1c", - "sha256:c990f4c0702d1739076261c4dece1042e1eb18bf34e0d8516d19ec5166a205ce", - "sha256:d6b54656ca131a4f0f17b9d0adddc60f84fd982d64e06360026d5b06e5dbf865", - "sha256:e0299236297b63bf6cbb61d81a9d400bc01cad4743d1abe5296ef349de15ee53", - "sha256:e722b6ffa5b0d7188eebac792b18bc871643db505bf60d0e6bd2859f31e5ed79", - "sha256:fd233c83daaf048c1f9827be984c2721576ae0adf50e139429a06ccd094987d9" + "sha256:016d81bb1499dee8b77c82464244e98f10d3671ceefb4023adc559267d1fad50", + "sha256:052058cf3dc0bf183ab522132f3b18a614a26f3e392ae886efcdab38d4f4fc42", + "sha256:134b71e439e2eafaee4c550365221ae2890dd54fb76227c64a87a94a07fe79b4", + "sha256:2a8f451c4d700802fdfe515890c14974766c322213df2ceed3b27752929dc70f", + "sha256:2dcf05355315e5c7c81e9eca34395d78f29c4da3662e869e42dd7b16380f92ce", + "sha256:38c229d76cd1dea8465357855f2b2842b7a9b201f17dea13b0eab7d3b9d6ad74", + "sha256:67fc2b2e67a63963c633fc884f285a8de5a626967a3cc5f5d48ac3e8d15b122d", + "sha256:6d92c58f71c691f86ad35bb2f3e13d7a9cc1c84ce0b04c146e5980e450faeff1", + "sha256:72bfd0213364c2bea0244f6432ababb2f204cff43f4f886c65dca2be11f536ee", + "sha256:7af7f68198f2aca3a520e1201fe2b329331e0ca19a481f3b3451cb0746f56c01", + "sha256:823190e7f2a9b4bcc574ab6bb72a33802933e1a8c171594faad90162d2d27758", + "sha256:853c5916d188ef2c357a474e15ac81cafae6085e599ceb9b2b0bcb9104118e63", + "sha256:8a404db37864acca43fd76222d1fbc7ff8d17d4ce02d803289c2141c2693ce9e", + "sha256:9199d6ecc81576602990178f0c2fb71737c53a598c8a2f51e1097a53fcfaee40", + "sha256:933c3e39d30cc6f9ff636d27d18aa3f1341b23d803ade4b57a76f91c26d14066", + "sha256:a48534b881c176557ddc78527c8c75b4c9402511e972670ad33c5e49d31eddfe", + "sha256:a688ea65b2ea771b9b69dc409377240a7cab7c1aafef46cd75219d5a94ba49e0", + "sha256:ac92b2f2a9307ac0c4aafdfcf7ecf01ec92dfebd9140f8c95353adfbf5822cd4", + "sha256:b267a6c000b7f98e6436a9acefa5582a9662e503b0632a2562e3093a677f6845", + "sha256:b8639d8aa381a7d19b92ca1a32448f09baaf80787e50187d1f7d072191430768", + "sha256:c01aad36f0c34ca3f642018be37fd0d55c546f088837cba88f1a1aff408c63dd", + "sha256:ca8349fe56ce39498d9b5ca8eabba744774e94d85775259f26a43a03e8825429", + "sha256:ced1fa55e653d28f66c4f3569ed524d4d92098119dcd80c2fa026872a30eba55", + "sha256:e90a7b96ce2c6a60f6e2609b0c83f45bd55e144cc7c2a9714e344938827da363", + "sha256:eacc353dcf6f39665d4ca3311ded5ddae0f5a117f03107991d4185ffa59fd890", + "sha256:f41cb8da8bb487ed60329ac31789c50621f0e6d2c26abc7d4ae2383838fb1b93" ], "index": "pypi", - "version": "==8.0.32" + "version": "==9.0.0" }, "ordered-set": { "hashes": [ "sha256:046e1132c71fcf3330438a539928932caf51ddbc582496833e23de611de14562", "sha256:694a8e44c87657c59292ede72891eb91d34131f6531463aab3009191c77364a8" ], - "markers": "python_version >= '3.7'", + "index": "pypi", "version": "==4.1.0" }, "packaging": { "hashes": [ - "sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5", - "sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9" + "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002", + "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124" ], - "markers": "python_version >= '3.7'", - "version": "==24.0" + "markers": "python_version >= '3.8'", + "version": "==24.1" }, "pkgutil-resolve-name": { "hashes": [ @@ -453,100 +473,29 @@ "markers": "python_version < '3.9'", "version": "==1.3.10" }, - "protobuf": { - "hashes": [ - "sha256:03038ac1cfbc41aa21f6afcbcd357281d7521b4157926f30ebecc8d4ea59dcb7", - "sha256:28545383d61f55b57cf4df63eebd9827754fd2dc25f80c5253f9184235db242c", - "sha256:2e3427429c9cffebf259491be0af70189607f365c2f41c7c3764af6f337105f2", - "sha256:398a9e0c3eaceb34ec1aee71894ca3299605fa8e761544934378bbc6c97de23b", - "sha256:44246bab5dd4b7fbd3c0c80b6f16686808fab0e4aca819ade6e8d294a29c7050", - "sha256:447d43819997825d4e71bf5769d869b968ce96848b6479397e29fc24c4a5dfe9", - "sha256:67a3598f0a2dcbc58d02dd1928544e7d88f764b47d4a286202913f0b2801c2e7", - "sha256:74480f79a023f90dc6e18febbf7b8bac7508420f2006fabd512013c0c238f454", - "sha256:819559cafa1a373b7096a482b504ae8a857c89593cf3a25af743ac9ecbd23480", - "sha256:899dc660cd599d7352d6f10d83c95df430a38b410c1b66b407a6b29265d66469", - "sha256:8c0c984a1b8fef4086329ff8dd19ac77576b384079247c770f29cc8ce3afa06c", - "sha256:9aae4406ea63d825636cc11ffb34ad3379335803216ee3a856787bcf5ccc751e", - "sha256:a7ca6d488aa8ff7f329d4c545b2dbad8ac31464f1d8b1c87ad1346717731e4db", - "sha256:b6cc7ba72a8850621bfec987cb72623e703b7fe2b9127a161ce61e61558ad905", - "sha256:bf01b5720be110540be4286e791db73f84a2b721072a3711efff6c324cdf074b", - "sha256:c02ce36ec760252242a33967d51c289fd0e1c0e6e5cc9397e2279177716add86", - "sha256:d9e4432ff660d67d775c66ac42a67cf2453c27cb4d738fc22cb53b5d84c135d4", - "sha256:daa564862dd0d39c00f8086f88700fdbe8bc717e993a21e90711acfed02f2402", - "sha256:de78575669dddf6099a8a0f46a27e82a1783c557ccc38ee620ed8cc96d3be7d7", - "sha256:e64857f395505ebf3d2569935506ae0dfc4a15cb80dc25261176c784662cdcc4", - "sha256:f4bd856d702e5b0d96a00ec6b307b0f51c1982c2bf9c0052cf9019e9a544ba99", - "sha256:f4c42102bc82a51108e449cbb32b19b180022941c727bac0cfd50170341f16ee" - ], - "markers": "python_version >= '3.7'", - "version": "==3.20.3" - }, "pyasn1": { "hashes": [ - "sha256:014c0e9976956a08139dc0712ae195324a75e142284d5f87f1a87ee1b068a359", - "sha256:03840c999ba71680a131cfaee6fab142e1ed9bbd9c693e285cc6aca0d555e576", - "sha256:0458773cfe65b153891ac249bcf1b5f8f320b7c2ce462151f8fa74de8934becf", - "sha256:08c3c53b75eaa48d71cf8c710312316392ed40899cb34710d092e96745a358b7", - "sha256:39c7e2ec30515947ff4e87fb6f456dfc6e84857d34be479c9d4a4ba4bf46aa5d", - "sha256:5c9414dcfede6e441f7e8f81b43b34e834731003427e5b09e4e00e3172a10f00", - "sha256:6e7545f1a61025a4e58bb336952c5061697da694db1cae97b116e9c46abcf7c8", - "sha256:78fa6da68ed2727915c4767bb386ab32cdba863caa7dbe473eaae45f9959da86", - "sha256:7ab8a544af125fb704feadb008c99a88805126fb525280b2270bb25cc1d78a12", - "sha256:99fcc3c8d804d1bc6d9a099921e39d827026409a58f2a720dcdb89374ea0c776", - "sha256:aef77c9fb94a3ac588e87841208bdec464471d9871bd5050a287cc9a475cd0ba", - "sha256:e89bf84b5437b532b0803ba5c9a5e054d21fec423a89952a74f87fa2c9b7bce2", - "sha256:fec3e9d8e36808a28efb59b489e4528c10ad0f480e57dcc32b4de5c9d8c9fdf3" - ], - "version": "==0.4.8" + "sha256:0d632f46f2ba09143da3a8afe9e33fb6f92fa2320ab7e886e2d0f7672af84629", + "sha256:6f580d2bdd84365380830acf45550f2511469f673cb4a5ae3857a3170128b034" + ], + "markers": "python_version >= '3.8'", + "version": "==0.6.1" }, "pygments": { "hashes": [ - "sha256:b3ed06a9e8ac9a9aae5a6f5dbe78a8a58655d17b43b93c078f094ddc476ae297", - "sha256:fa7bd7bd2771287c0de303af8bfdfc731f51bd2c6a47ab69d117138893b82717" + "sha256:786ff802f32e91311bff3889f6e9a86e81505fe99f2735bb6d60ae0c5004f199", + "sha256:b8e6aca0523f3ab76fee51799c488e38782ac06eafcf95e7ba832985c8e7b13a" ], - "markers": "python_version >= '3.6'", - "version": "==2.14.0" - }, - "pyrsistent": { - "hashes": [ - "sha256:016ad1afadf318eb7911baa24b049909f7f3bb2c5b1ed7b6a8f21db21ea3faa8", - "sha256:1a2994773706bbb4995c31a97bc94f1418314923bd1048c6d964837040376440", - "sha256:20460ac0ea439a3e79caa1dbd560344b64ed75e85d8703943e0b66c2a6150e4a", - "sha256:3311cb4237a341aa52ab8448c27e3a9931e2ee09561ad150ba94e4cfd3fc888c", - "sha256:3a8cb235fa6d3fd7aae6a4f1429bbb1fec1577d978098da1252f0489937786f3", - "sha256:3ab2204234c0ecd8b9368dbd6a53e83c3d4f3cab10ecaf6d0e772f456c442393", - "sha256:42ac0b2f44607eb92ae88609eda931a4f0dfa03038c44c772e07f43e738bcac9", - "sha256:49c32f216c17148695ca0e02a5c521e28a4ee6c5089f97e34fe24163113722da", - "sha256:4b774f9288dda8d425adb6544e5903f1fb6c273ab3128a355c6b972b7df39dcf", - "sha256:4c18264cb84b5e68e7085a43723f9e4c1fd1d935ab240ce02c0324a8e01ccb64", - "sha256:5a474fb80f5e0d6c9394d8db0fc19e90fa540b82ee52dba7d246a7791712f74a", - "sha256:64220c429e42a7150f4bfd280f6f4bb2850f95956bde93c6fda1b70507af6ef3", - "sha256:878433581fc23e906d947a6814336eee031a00e6defba224234169ae3d3d6a98", - "sha256:99abb85579e2165bd8522f0c0138864da97847875ecbd45f3e7e2af569bfc6f2", - "sha256:a2471f3f8693101975b1ff85ffd19bb7ca7dd7c38f8a81701f67d6b4f97b87d8", - "sha256:aeda827381f5e5d65cced3024126529ddc4289d944f75e090572c77ceb19adbf", - "sha256:b735e538f74ec31378f5a1e3886a26d2ca6351106b4dfde376a26fc32a044edc", - "sha256:c147257a92374fde8498491f53ffa8f4822cd70c0d85037e09028e478cababb7", - "sha256:c4db1bd596fefd66b296a3d5d943c94f4fac5bcd13e99bffe2ba6a759d959a28", - "sha256:c74bed51f9b41c48366a286395c67f4e894374306b197e62810e0fdaf2364da2", - "sha256:c9bb60a40a0ab9aba40a59f68214eed5a29c6274c83b2cc206a359c4a89fa41b", - "sha256:cc5d149f31706762c1f8bda2e8c4f8fead6e80312e3692619a75301d3dbb819a", - "sha256:ccf0d6bd208f8111179f0c26fdf84ed7c3891982f2edaeae7422575f47e66b64", - "sha256:e42296a09e83028b3476f7073fcb69ffebac0e66dbbfd1bd847d61f74db30f19", - "sha256:e8f2b814a3dc6225964fa03d8582c6e0b6650d68a232df41e3cc1b66a5d2f8d1", - "sha256:f0774bf48631f3a20471dd7c5989657b639fd2d285b861237ea9e82c36a415a9", - "sha256:f0e7c4b2f77593871e918be000b96c8107da48444d57005b6a6bc61fb4331b2c" - ], - "markers": "python_version >= '3.7'", - "version": "==0.19.3" + "markers": "python_version >= '3.8'", + "version": "==2.18.0" }, "python-dotenv": { "hashes": [ - "sha256:1c93de8f636cde3ce377292818d0e440b6e45a82f215c3744979151fa8151c49", - "sha256:41e12e0318bebc859fcc4d97d4db8d20ad21721a6aa5047dd59f090391cb549a" + "sha256:e324ee90a023d808f1959c46bcbc04446a10ced277783dc6ee09987c37ec10ca", + "sha256:f7b63ef50f1b690dddf550d03497b66d609393b40b564ed0d674909a68ebf16a" ], "index": "pypi", - "version": "==0.21.1" + "version": "==1.0.1" }, "python-jose": { "hashes": [ @@ -558,65 +507,195 @@ }, "pyyaml": { "hashes": [ - "sha256:01b45c0191e6d66c470b6cf1b9531a771a83c1c4208272ead47a3ae4f2f603bf", - "sha256:0283c35a6a9fbf047493e3a0ce8d79ef5030852c51e9d911a27badfde0605293", - "sha256:055d937d65826939cb044fc8c9b08889e8c743fdc6a32b33e2390f66013e449b", - "sha256:07751360502caac1c067a8132d150cf3d61339af5691fe9e87803040dbc5db57", - "sha256:0b4624f379dab24d3725ffde76559cff63d9ec94e1736b556dacdfebe5ab6d4b", - "sha256:0ce82d761c532fe4ec3f87fc45688bdd3a4c1dc5e0b4a19814b9009a29baefd4", - "sha256:1e4747bc279b4f613a09eb64bba2ba602d8a6664c6ce6396a4d0cd413a50ce07", - "sha256:213c60cd50106436cc818accf5baa1aba61c0189ff610f64f4a3e8c6726218ba", - "sha256:231710d57adfd809ef5d34183b8ed1eeae3f76459c18fb4a0b373ad56bedcdd9", - "sha256:277a0ef2981ca40581a47093e9e2d13b3f1fbbeffae064c1d21bfceba2030287", - "sha256:2cd5df3de48857ed0544b34e2d40e9fac445930039f3cfe4bcc592a1f836d513", - "sha256:40527857252b61eacd1d9af500c3337ba8deb8fc298940291486c465c8b46ec0", - "sha256:432557aa2c09802be39460360ddffd48156e30721f5e8d917f01d31694216782", - "sha256:473f9edb243cb1935ab5a084eb238d842fb8f404ed2193a915d1784b5a6b5fc0", - "sha256:48c346915c114f5fdb3ead70312bd042a953a8ce5c7106d5bfb1a5254e47da92", - "sha256:50602afada6d6cbfad699b0c7bb50d5ccffa7e46a3d738092afddc1f9758427f", - "sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2", - "sha256:77f396e6ef4c73fdc33a9157446466f1cff553d979bd00ecb64385760c6babdc", - "sha256:81957921f441d50af23654aa6c5e5eaf9b06aba7f0a19c18a538dc7ef291c5a1", - "sha256:819b3830a1543db06c4d4b865e70ded25be52a2e0631ccd2f6a47a2822f2fd7c", - "sha256:897b80890765f037df3403d22bab41627ca8811ae55e9a722fd0392850ec4d86", - "sha256:98c4d36e99714e55cfbaaee6dd5badbc9a1ec339ebfc3b1f52e293aee6bb71a4", - "sha256:9df7ed3b3d2e0ecfe09e14741b857df43adb5a3ddadc919a2d94fbdf78fea53c", - "sha256:9fa600030013c4de8165339db93d182b9431076eb98eb40ee068700c9c813e34", - "sha256:a80a78046a72361de73f8f395f1f1e49f956c6be882eed58505a15f3e430962b", - "sha256:afa17f5bc4d1b10afd4466fd3a44dc0e245382deca5b3c353d8b757f9e3ecb8d", - "sha256:b3d267842bf12586ba6c734f89d1f5b871df0273157918b0ccefa29deb05c21c", - "sha256:b5b9eccad747aabaaffbc6064800670f0c297e52c12754eb1d976c57e4f74dcb", - "sha256:bfaef573a63ba8923503d27530362590ff4f576c626d86a9fed95822a8255fd7", - "sha256:c5687b8d43cf58545ade1fe3e055f70eac7a5a1a0bf42824308d868289a95737", - "sha256:cba8c411ef271aa037d7357a2bc8f9ee8b58b9965831d9e51baf703280dc73d3", - "sha256:d15a181d1ecd0d4270dc32edb46f7cb7733c7c508857278d3d378d14d606db2d", - "sha256:d4b0ba9512519522b118090257be113b9468d804b19d63c71dbcf4a48fa32358", - "sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53", - "sha256:d4eccecf9adf6fbcc6861a38015c2a64f38b9d94838ac1810a9023a0609e1b78", - "sha256:d67d839ede4ed1b28a4e8909735fc992a923cdb84e618544973d7dfc71540803", - "sha256:daf496c58a8c52083df09b80c860005194014c3698698d1a57cbcfa182142a3a", - "sha256:dbad0e9d368bb989f4515da330b88a057617d16b6a8245084f1b05400f24609f", - "sha256:e61ceaab6f49fb8bdfaa0f92c4b57bcfbea54c09277b1b4f7ac376bfb7a7c174", - "sha256:f84fbc98b019fef2ee9a1cb3ce93e3187a6df0b2538a651bfb890254ba9f90b5" - ], - "markers": "python_version >= '3.6'", - "version": "==6.0" + "sha256:01179a4a8559ab5de078078f37e5c1a30d76bb88519906844fd7bdea1b7729ff", + "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48", + "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086", + "sha256:0b69e4ce7a131fe56b7e4d770c67429700908fc0752af059838b1cfb41960e4e", + "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133", + "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5", + "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484", + "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee", + "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5", + "sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68", + "sha256:24471b829b3bf607e04e88d79542a9d48bb037c2267d7927a874e6c205ca7e9a", + "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf", + "sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99", + "sha256:39693e1f8320ae4f43943590b49779ffb98acb81f788220ea932a6b6c51004d8", + "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85", + "sha256:3b1fdb9dc17f5a7677423d508ab4f243a726dea51fa5e70992e59a7411c89d19", + "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc", + "sha256:43fa96a3ca0d6b1812e01ced1044a003533c47f6ee8aca31724f78e93ccc089a", + "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1", + "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317", + "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c", + "sha256:6395c297d42274772abc367baaa79683958044e5d3835486c16da75d2a694631", + "sha256:688ba32a1cffef67fd2e9398a2efebaea461578b0923624778664cc1c914db5d", + "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652", + "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5", + "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e", + "sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b", + "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8", + "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476", + "sha256:82d09873e40955485746739bcb8b4586983670466c23382c19cffecbf1fd8706", + "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563", + "sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237", + "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b", + "sha256:9056c1ecd25795207ad294bcf39f2db3d845767be0ea6e6a34d856f006006083", + "sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180", + "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425", + "sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e", + "sha256:a8786accb172bd8afb8be14490a16625cbc387036876ab6ba70912730faf8e1f", + "sha256:a9f8c2e67970f13b16084e04f134610fd1d374bf477b17ec1599185cf611d725", + "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183", + "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab", + "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774", + "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725", + "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e", + "sha256:d7fded462629cfa4b685c5416b949ebad6cec74af5e2d42905d41e257e0869f5", + "sha256:d84a1718ee396f54f3a086ea0a66d8e552b2ab2017ef8b420e92edbc841c352d", + "sha256:d8e03406cac8513435335dbab54c0d385e4a49e4945d2909a581c83647ca0290", + "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44", + "sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed", + "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4", + "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba", + "sha256:f753120cb8181e736c57ef7636e83f31b9c0d1722c516f7e86cf15b7aa57ff12", + "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4" + ], + "markers": "python_version >= '3.8'", + "version": "==6.0.2" + }, + "referencing": { + "hashes": [ + "sha256:25b42124a6c8b632a425174f24087783efb348a6f1e0008e63cd4466fedf703c", + "sha256:eda6d3234d62814d1c64e305c1331c9a3a6132da475ab6382eaa997b21ee75de" + ], + "markers": "python_version >= '3.8'", + "version": "==0.35.1" }, "requests": { "hashes": [ - "sha256:64299f4909223da747622c030b781c0d7811e359c37124b4bd368fb8c6518baa", - "sha256:98b1b2782e3c6c4904938b84c0eb932721069dfdb9134313beff7c83c2df24bf" + "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760", + "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6" ], "index": "pypi", - "version": "==2.28.2" + "version": "==2.32.3" }, "rich": { "hashes": [ - "sha256:125d96d20c92b946b983d0d392b84ff945461e5a06d3867e9f9e575f8697b67f", - "sha256:8aa57747f3fc3e977684f0176a88e789be314a99f99b43b75d1e9cb5dc6db9e9" - ], - "markers": "python_version >= '3.7'", - "version": "==13.3.1" + "sha256:51a2c62057461aaf7152b4d611168f93a9fc73068f8ded2790f29fe2b5366d0c", + "sha256:8c82a3d3f8dcfe9e734771313e606b39d8247bb6b826e196f4914b333b743cf1" + ], + "markers": "python_version >= '3.8'", + "version": "==13.9.2" + }, + "rpds-py": { + "hashes": [ + "sha256:06db23d43f26478303e954c34c75182356ca9aa7797d22c5345b16871ab9c45c", + "sha256:0e13e6952ef264c40587d510ad676a988df19adea20444c2b295e536457bc585", + "sha256:11ef6ce74616342888b69878d45e9f779b95d4bd48b382a229fe624a409b72c5", + "sha256:1259c7b3705ac0a0bd38197565a5d603218591d3f6cee6e614e380b6ba61c6f6", + "sha256:18d7585c463087bddcfa74c2ba267339f14f2515158ac4db30b1f9cbdb62c8ef", + "sha256:1e0f80b739e5a8f54837be5d5c924483996b603d5502bfff79bf33da06164ee2", + "sha256:1e5f3cd7397c8f86c8cc72d5a791071431c108edd79872cdd96e00abd8497d29", + "sha256:220002c1b846db9afd83371d08d239fdc865e8f8c5795bbaec20916a76db3318", + "sha256:22e6c9976e38f4d8c4a63bd8a8edac5307dffd3ee7e6026d97f3cc3a2dc02a0b", + "sha256:238a2d5b1cad28cdc6ed15faf93a998336eb041c4e440dd7f902528b8891b399", + "sha256:2580b0c34583b85efec8c5c5ec9edf2dfe817330cc882ee972ae650e7b5ef739", + "sha256:28527c685f237c05445efec62426d285e47a58fb05ba0090a4340b73ecda6dee", + "sha256:2cf126d33a91ee6eedc7f3197b53e87a2acdac63602c0f03a02dd69e4b138174", + "sha256:338ca4539aad4ce70a656e5187a3a31c5204f261aef9f6ab50e50bcdffaf050a", + "sha256:39ed0d010457a78f54090fafb5d108501b5aa5604cc22408fc1c0c77eac14344", + "sha256:3ad0fda1635f8439cde85c700f964b23ed5fc2d28016b32b9ee5fe30da5c84e2", + "sha256:3d2b1ad682a3dfda2a4e8ad8572f3100f95fad98cb99faf37ff0ddfe9cbf9d03", + "sha256:3d61339e9f84a3f0767b1995adfb171a0d00a1185192718a17af6e124728e0f5", + "sha256:3fde368e9140312b6e8b6c09fb9f8c8c2f00999d1823403ae90cc00480221b22", + "sha256:40ce74fc86ee4645d0a225498d091d8bc61f39b709ebef8204cb8b5a464d3c0e", + "sha256:49a8063ea4296b3a7e81a5dfb8f7b2d73f0b1c20c2af401fb0cdf22e14711a96", + "sha256:4a1f1d51eccb7e6c32ae89243cb352389228ea62f89cd80823ea7dd1b98e0b91", + "sha256:4b16aa0107ecb512b568244ef461f27697164d9a68d8b35090e9b0c1c8b27752", + "sha256:4f1ed4749a08379555cebf4650453f14452eaa9c43d0a95c49db50c18b7da075", + "sha256:4fe84294c7019456e56d93e8ababdad5a329cd25975be749c3f5f558abb48253", + "sha256:50eccbf054e62a7b2209b28dc7a22d6254860209d6753e6b78cfaeb0075d7bee", + "sha256:514b3293b64187172bc77c8fb0cdae26981618021053b30d8371c3a902d4d5ad", + "sha256:54b43a2b07db18314669092bb2de584524d1ef414588780261e31e85846c26a5", + "sha256:55fea87029cded5df854ca7e192ec7bdb7ecd1d9a3f63d5c4eb09148acf4a7ce", + "sha256:569b3ea770c2717b730b61998b6c54996adee3cef69fc28d444f3e7920313cf7", + "sha256:56e27147a5a4c2c21633ff8475d185734c0e4befd1c989b5b95a5d0db699b21b", + "sha256:57eb94a8c16ab08fef6404301c38318e2c5a32216bf5de453e2714c964c125c8", + "sha256:5a35df9f5548fd79cb2f52d27182108c3e6641a4feb0f39067911bf2adaa3e57", + "sha256:5a8c94dad2e45324fc74dce25e1645d4d14df9a4e54a30fa0ae8bad9a63928e3", + "sha256:5b4f105deeffa28bbcdff6c49b34e74903139afa690e35d2d9e3c2c2fba18cec", + "sha256:5c1dc0f53856b9cc9a0ccca0a7cc61d3d20a7088201c0937f3f4048c1718a209", + "sha256:614fdafe9f5f19c63ea02817fa4861c606a59a604a77c8cdef5aa01d28b97921", + "sha256:617c7357272c67696fd052811e352ac54ed1d9b49ab370261a80d3b6ce385045", + "sha256:65794e4048ee837494aea3c21a28ad5fc080994dfba5b036cf84de37f7ad5074", + "sha256:6632f2d04f15d1bd6fe0eedd3b86d9061b836ddca4c03d5cf5c7e9e6b7c14580", + "sha256:6c8ef2ebf76df43f5750b46851ed1cdf8f109d7787ca40035fe19fbdc1acc5a7", + "sha256:758406267907b3781beee0f0edfe4a179fbd97c0be2e9b1154d7f0a1279cf8e5", + "sha256:7e60cb630f674a31f0368ed32b2a6b4331b8350d67de53c0359992444b116dd3", + "sha256:89c19a494bf3ad08c1da49445cc5d13d8fefc265f48ee7e7556839acdacf69d0", + "sha256:8a86a9b96070674fc88b6f9f71a97d2c1d3e5165574615d1f9168ecba4cecb24", + "sha256:8bc7690f7caee50b04a79bf017a8d020c1f48c2a1077ffe172abec59870f1139", + "sha256:8d7919548df3f25374a1f5d01fbcd38dacab338ef5f33e044744b5c36729c8db", + "sha256:9426133526f69fcaba6e42146b4e12d6bc6c839b8b555097020e2b78ce908dcc", + "sha256:9824fb430c9cf9af743cf7aaf6707bf14323fb51ee74425c380f4c846ea70789", + "sha256:9bb4a0d90fdb03437c109a17eade42dfbf6190408f29b2744114d11586611d6f", + "sha256:9bc2d153989e3216b0559251b0c260cfd168ec78b1fac33dd485750a228db5a2", + "sha256:9d35cef91e59ebbeaa45214861874bc6f19eb35de96db73e467a8358d701a96c", + "sha256:a1862d2d7ce1674cffa6d186d53ca95c6e17ed2b06b3f4c476173565c862d232", + "sha256:a84ab91cbe7aab97f7446652d0ed37d35b68a465aeef8fc41932a9d7eee2c1a6", + "sha256:aa7f429242aae2947246587d2964fad750b79e8c233a2367f71b554e9447949c", + "sha256:aa9a0521aeca7d4941499a73ad7d4f8ffa3d1affc50b9ea11d992cd7eff18a29", + "sha256:ac2f4f7a98934c2ed6505aead07b979e6f999389f16b714448fb39bbaa86a489", + "sha256:ae94bd0b2f02c28e199e9bc51485d0c5601f58780636185660f86bf80c89af94", + "sha256:af0fc424a5842a11e28956e69395fbbeab2c97c42253169d87e90aac2886d751", + "sha256:b2a5db5397d82fa847e4c624b0c98fe59d2d9b7cf0ce6de09e4d2e80f8f5b3f2", + "sha256:b4c29cbbba378759ac5786730d1c3cb4ec6f8ababf5c42a9ce303dc4b3d08cda", + "sha256:b74b25f024b421d5859d156750ea9a65651793d51b76a2e9238c05c9d5f203a9", + "sha256:b7f19250ceef892adf27f0399b9e5afad019288e9be756d6919cb58892129f51", + "sha256:b80d4a7900cf6b66bb9cee5c352b2d708e29e5a37fe9bf784fa97fc11504bf6c", + "sha256:b8c00a3b1e70c1d3891f0db1b05292747f0dbcfb49c43f9244d04c70fbc40eb8", + "sha256:bb273176be34a746bdac0b0d7e4e2c467323d13640b736c4c477881a3220a989", + "sha256:c3c20f0ddeb6e29126d45f89206b8291352b8c5b44384e78a6499d68b52ae511", + "sha256:c3e130fd0ec56cb76eb49ef52faead8ff09d13f4527e9b0c400307ff72b408e1", + "sha256:c52d3f2f82b763a24ef52f5d24358553e8403ce05f893b5347098014f2d9eff2", + "sha256:c6377e647bbfd0a0b159fe557f2c6c602c159fc752fa316572f012fc0bf67150", + "sha256:c638144ce971df84650d3ed0096e2ae7af8e62ecbbb7b201c8935c370df00a2c", + "sha256:ce9845054c13696f7af7f2b353e6b4f676dab1b4b215d7fe5e05c6f8bb06f965", + "sha256:cf258ede5bc22a45c8e726b29835b9303c285ab46fc7c3a4cc770736b5304c9f", + "sha256:d0a26ffe9d4dd35e4dfdd1e71f46401cff0181c75ac174711ccff0459135fa58", + "sha256:d0b67d87bb45ed1cd020e8fbf2307d449b68abc45402fe1a4ac9e46c3c8b192b", + "sha256:d20277fd62e1b992a50c43f13fbe13277a31f8c9f70d59759c88f644d66c619f", + "sha256:d454b8749b4bd70dd0a79f428731ee263fa6995f83ccb8bada706e8d1d3ff89d", + "sha256:d4c7d1a051eeb39f5c9547e82ea27cbcc28338482242e3e0b7768033cb083821", + "sha256:d72278a30111e5b5525c1dd96120d9e958464316f55adb030433ea905866f4de", + "sha256:d72a210824facfdaf8768cf2d7ca25a042c30320b3020de2fa04640920d4e121", + "sha256:d807dc2051abe041b6649681dce568f8e10668e3c1c6543ebae58f2d7e617855", + "sha256:dbe982f38565bb50cb7fb061ebf762c2f254ca3d8c20d4006878766e84266272", + "sha256:dcedf0b42bcb4cfff4101d7771a10532415a6106062f005ab97d1d0ab5681c60", + "sha256:deb62214c42a261cb3eb04d474f7155279c1a8a8c30ac89b7dcb1721d92c3c02", + "sha256:def7400461c3a3f26e49078302e1c1b38f6752342c77e3cf72ce91ca69fb1bc1", + "sha256:df3de6b7726b52966edf29663e57306b23ef775faf0ac01a3e9f4012a24a4140", + "sha256:e1940dae14e715e2e02dfd5b0f64a52e8374a517a1e531ad9412319dc3ac7879", + "sha256:e4df1e3b3bec320790f699890d41c59d250f6beda159ea3c44c3f5bac1976940", + "sha256:e6900ecdd50ce0facf703f7a00df12374b74bbc8ad9fe0f6559947fb20f82364", + "sha256:ea438162a9fcbee3ecf36c23e6c68237479f89f962f82dae83dc15feeceb37e4", + "sha256:eb851b7df9dda52dc1415ebee12362047ce771fc36914586b2e9fcbd7d293b3e", + "sha256:ec31a99ca63bf3cd7f1a5ac9fe95c5e2d060d3c768a09bc1d16e235840861420", + "sha256:f0475242f447cc6cb8a9dd486d68b2ef7fbee84427124c232bff5f63b1fe11e5", + "sha256:f2fbf7db2012d4876fb0d66b5b9ba6591197b0f165db8d99371d976546472a24", + "sha256:f60012a73aa396be721558caa3a6fd49b3dd0033d1675c6d59c4502e870fcf0c", + "sha256:f8e604fe73ba048c06085beaf51147eaec7df856824bfe7b98657cf436623daf", + "sha256:f90a4cd061914a60bd51c68bcb4357086991bd0bb93d8aa66a6da7701370708f", + "sha256:f918a1a130a6dfe1d7fe0f105064141342e7dd1611f2e6a21cd2f5c8cb1cfb3e", + "sha256:fa518bcd7600c584bf42e6617ee8132869e877db2f76bcdc281ec6a4113a53ab", + "sha256:faefcc78f53a88f3076b7f8be0a8f8d35133a3ecf7f3770895c25f8813460f08", + "sha256:fcaeb7b57f1a1e071ebd748984359fef83ecb026325b9d4ca847c95bc7311c92", + "sha256:fd2d84f40633bc475ef2d5490b9c19543fbf18596dcb1b291e3a12ea5d722f7a", + "sha256:fdfc3a892927458d98f3d55428ae46b921d1f7543b89382fdb483f5640daaec8" + ], + "markers": "python_version >= '3.8'", + "version": "==0.20.0" }, "rsa": { "hashes": [ @@ -628,19 +707,11 @@ }, "sentry-sdk": { "hashes": [ - "sha256:69ecbb2e1ff4db02a06c4f20f6f69cb5dfe3ebfbc06d023e40d77cf78e9c37e7", - "sha256:7ad4d37dd093f4a7cb5ad804c6efe9e8fab8873f7ffc06042dc3f3fd700a93ec" + "sha256:49139c31ebcd398f4f6396b18910610a0c1602f6e67083240c33019d1f6aa30c", + "sha256:90f733b32e15dfc1999e6b7aca67a38688a567329de4d6e184154a73f96c6892" ], "index": "pypi", - "version": "==1.15.0" - }, - "setuptools": { - "hashes": [ - "sha256:95f00380ef2ffa41d9bba85d95b27689d923c93dfbafed4aecd7cf988a25e012", - "sha256:bb6d8e508de562768f2027902929f8523932fcd1fb784e6d573d2cafac995a48" - ], - "markers": "python_version >= '3.7'", - "version": "==67.3.2" + "version": "==2.16.0" }, "six": { "hashes": [ @@ -692,123 +763,129 @@ }, "typing-extensions": { "hashes": [ - "sha256:5cb5f4a79139d699607b3ef622a1dedafa84e115ab0024e0d9c044a9479ca7cb", - "sha256:fb33085c39dd998ac16d1431ebc293a8b3eedd00fd4a32de0ff79002c19511b4" + "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d", + "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8" ], - "markers": "python_version >= '3.7'", - "version": "==4.5.0" + "markers": "python_version >= '3.8'", + "version": "==4.12.2" }, "urllib3": { "hashes": [ - "sha256:076907bf8fd355cde77728471316625a4d2f7e713c125f51953bb5b3eecf4f72", - "sha256:75edcdc2f7d85b137124a6c3c9fc3933cdeaa12ecb9a6a959f22797a0feca7e1" + "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac", + "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'", - "version": "==1.26.14" + "markers": "python_version >= '3.8'", + "version": "==2.2.3" }, "werkzeug": { "hashes": [ - "sha256:2e1ccc9417d4da358b9de6f174e3ac094391ea1d4fbef2d667865d819dfd0afe", - "sha256:56433961bc1f12533306c624f3be5e744389ac61d722175d543e1751285da612" + "sha256:1421ebfc7648a39a5c58c601b154165d05cf47a3cd0ccb70857cbdacf6c8f2b8", + "sha256:b863f8ff057c522164b6067c9e28b041161b4be5ba4d0daceeaa50a163822d3c" ], - "markers": "python_version >= '3.7'", - "version": "==2.2.3" + "index": "pypi", + "version": "==2.0.3" }, "wrapt": { "hashes": [ - "sha256:00b6d4ea20a906c0ca56d84f93065b398ab74b927a7a3dbd470f6fc503f95dc3", - "sha256:01c205616a89d09827986bc4e859bcabd64f5a0662a7fe95e0d359424e0e071b", - "sha256:02b41b633c6261feff8ddd8d11c711df6842aba629fdd3da10249a53211a72c4", - "sha256:07f7a7d0f388028b2df1d916e94bbb40624c59b48ecc6cbc232546706fac74c2", - "sha256:11871514607b15cfeb87c547a49bca19fde402f32e2b1c24a632506c0a756656", - "sha256:1b376b3f4896e7930f1f772ac4b064ac12598d1c38d04907e696cc4d794b43d3", - "sha256:21ac0156c4b089b330b7666db40feee30a5d52634cc4560e1905d6529a3897ff", - "sha256:257fd78c513e0fb5cdbe058c27a0624c9884e735bbd131935fd49e9fe719d310", - "sha256:2b39d38039a1fdad98c87279b48bc5dce2c0ca0d73483b12cb72aa9609278e8a", - "sha256:2cf71233a0ed05ccdabe209c606fe0bac7379fdcf687f39b944420d2a09fdb57", - "sha256:2fe803deacd09a233e4762a1adcea5db5d31e6be577a43352936179d14d90069", - "sha256:3232822c7d98d23895ccc443bbdf57c7412c5a65996c30442ebe6ed3df335383", - "sha256:34aa51c45f28ba7f12accd624225e2b1e5a3a45206aa191f6f9aac931d9d56fe", - "sha256:36f582d0c6bc99d5f39cd3ac2a9062e57f3cf606ade29a0a0d6b323462f4dd87", - "sha256:380a85cf89e0e69b7cfbe2ea9f765f004ff419f34194018a6827ac0e3edfed4d", - "sha256:40e7bc81c9e2b2734ea4bc1aceb8a8f0ceaac7c5299bc5d69e37c44d9081d43b", - "sha256:43ca3bbbe97af00f49efb06e352eae40434ca9d915906f77def219b88e85d907", - "sha256:4fcc4649dc762cddacd193e6b55bc02edca674067f5f98166d7713b193932b7f", - "sha256:5a0f54ce2c092aaf439813735584b9537cad479575a09892b8352fea5e988dc0", - "sha256:5a9a0d155deafd9448baff28c08e150d9b24ff010e899311ddd63c45c2445e28", - "sha256:5b02d65b9ccf0ef6c34cba6cf5bf2aab1bb2f49c6090bafeecc9cd81ad4ea1c1", - "sha256:60db23fa423575eeb65ea430cee741acb7c26a1365d103f7b0f6ec412b893853", - "sha256:642c2e7a804fcf18c222e1060df25fc210b9c58db7c91416fb055897fc27e8cc", - "sha256:6a9a25751acb379b466ff6be78a315e2b439d4c94c1e99cb7266d40a537995d3", - "sha256:6b1a564e6cb69922c7fe3a678b9f9a3c54e72b469875aa8018f18b4d1dd1adf3", - "sha256:6d323e1554b3d22cfc03cd3243b5bb815a51f5249fdcbb86fda4bf62bab9e164", - "sha256:6e743de5e9c3d1b7185870f480587b75b1cb604832e380d64f9504a0535912d1", - "sha256:709fe01086a55cf79d20f741f39325018f4df051ef39fe921b1ebe780a66184c", - "sha256:7b7c050ae976e286906dd3f26009e117eb000fb2cf3533398c5ad9ccc86867b1", - "sha256:7d2872609603cb35ca513d7404a94d6d608fc13211563571117046c9d2bcc3d7", - "sha256:7ef58fb89674095bfc57c4069e95d7a31cfdc0939e2a579882ac7d55aadfd2a1", - "sha256:80bb5c256f1415f747011dc3604b59bc1f91c6e7150bd7db03b19170ee06b320", - "sha256:81b19725065dcb43df02b37e03278c011a09e49757287dca60c5aecdd5a0b8ed", - "sha256:833b58d5d0b7e5b9832869f039203389ac7cbf01765639c7309fd50ef619e0b1", - "sha256:88bd7b6bd70a5b6803c1abf6bca012f7ed963e58c68d76ee20b9d751c74a3248", - "sha256:8ad85f7f4e20964db4daadcab70b47ab05c7c1cf2a7c1e51087bfaa83831854c", - "sha256:8c0ce1e99116d5ab21355d8ebe53d9460366704ea38ae4d9f6933188f327b456", - "sha256:8d649d616e5c6a678b26d15ece345354f7c2286acd6db868e65fcc5ff7c24a77", - "sha256:903500616422a40a98a5a3c4ff4ed9d0066f3b4c951fa286018ecdf0750194ef", - "sha256:9736af4641846491aedb3c3f56b9bc5568d92b0692303b5a305301a95dfd38b1", - "sha256:988635d122aaf2bdcef9e795435662bcd65b02f4f4c1ae37fbee7401c440b3a7", - "sha256:9cca3c2cdadb362116235fdbd411735de4328c61425b0aa9f872fd76d02c4e86", - "sha256:9e0fd32e0148dd5dea6af5fee42beb949098564cc23211a88d799e434255a1f4", - "sha256:9f3e6f9e05148ff90002b884fbc2a86bd303ae847e472f44ecc06c2cd2fcdb2d", - "sha256:a85d2b46be66a71bedde836d9e41859879cc54a2a04fad1191eb50c2066f6e9d", - "sha256:a9a52172be0b5aae932bef82a79ec0a0ce87288c7d132946d645eba03f0ad8a8", - "sha256:aa31fdcc33fef9eb2552cbcbfee7773d5a6792c137b359e82879c101e98584c5", - "sha256:b014c23646a467558be7da3d6b9fa409b2c567d2110599b7cf9a0c5992b3b471", - "sha256:b21bb4c09ffabfa0e85e3a6b623e19b80e7acd709b9f91452b8297ace2a8ab00", - "sha256:b5901a312f4d14c59918c221323068fad0540e34324925c8475263841dbdfe68", - "sha256:b9b7a708dd92306328117d8c4b62e2194d00c365f18eff11a9b53c6f923b01e3", - "sha256:d1967f46ea8f2db647c786e78d8cc7e4313dbd1b0aca360592d8027b8508e24d", - "sha256:d52a25136894c63de15a35bc0bdc5adb4b0e173b9c0d07a2be9d3ca64a332735", - "sha256:d77c85fedff92cf788face9bfa3ebaa364448ebb1d765302e9af11bf449ca36d", - "sha256:d79d7d5dc8a32b7093e81e97dad755127ff77bcc899e845f41bf71747af0c569", - "sha256:dbcda74c67263139358f4d188ae5faae95c30929281bc6866d00573783c422b7", - "sha256:ddaea91abf8b0d13443f6dac52e89051a5063c7d014710dcb4d4abb2ff811a59", - "sha256:dee0ce50c6a2dd9056c20db781e9c1cfd33e77d2d569f5d1d9321c641bb903d5", - "sha256:dee60e1de1898bde3b238f18340eec6148986da0455d8ba7848d50470a7a32fb", - "sha256:e2f83e18fe2f4c9e7db597e988f72712c0c3676d337d8b101f6758107c42425b", - "sha256:e3fb1677c720409d5f671e39bac6c9e0e422584e5f518bfd50aa4cbbea02433f", - "sha256:ee2b1b1769f6707a8a445162ea16dddf74285c3964f605877a20e38545c3c462", - "sha256:ee6acae74a2b91865910eef5e7de37dc6895ad96fa23603d1d27ea69df545015", - "sha256:ef3f72c9666bba2bab70d2a8b79f2c6d2c1a42a7f7e2b0ec83bb2f9e383950af" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==1.14.1" + "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc", + "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81", + "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09", + "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e", + "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca", + "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0", + "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb", + "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487", + "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40", + "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c", + "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060", + "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202", + "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41", + "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9", + "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b", + "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664", + "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d", + "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362", + "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00", + "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc", + "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1", + "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267", + "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956", + "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966", + "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1", + "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228", + "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72", + "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d", + "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292", + "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0", + "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0", + "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36", + "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c", + "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5", + "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f", + "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73", + "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b", + "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2", + "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593", + "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39", + "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389", + "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf", + "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf", + "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89", + "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c", + "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c", + "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f", + "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440", + "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465", + "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136", + "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b", + "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8", + "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3", + "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8", + "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6", + "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e", + "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f", + "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c", + "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e", + "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8", + "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2", + "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020", + "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35", + "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d", + "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3", + "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537", + "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809", + "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d", + "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a", + "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4" + ], + "markers": "python_version >= '3.6'", + "version": "==1.16.0" }, "zipp": { "hashes": [ - "sha256:23f70e964bc11a34cef175bc90ba2914e1e4545ea1e3e2f67c079671883f9cb6", - "sha256:e8b2a36ea17df80ffe9e2c4fda3f693c3dad6df1697d3cd3af232db680950b0b" + "sha256:a817ac80d6cf4b23bf7f2828b7cabf326f15a001bea8b1f9b49631780ba28350", + "sha256:bc9eb26f4506fda01b81bcde0ca78103b6e62f991b381fec825435c836edbc29" ], "markers": "python_version < '3.10'", - "version": "==3.13.0" + "version": "==3.20.2" } }, "develop": { "alembic": { "hashes": [ - "sha256:4d3bd32ecdbb7bbfb48a9fe9e6d6fd6a831a1b59d03e26e292210237373e7db5", - "sha256:6f1c2207369bf4f49f952057a33bb017fbe5c148c2a773b46906b806ea6e825f" + "sha256:203503117415561e203aa14541740643a611f641517f0209fcae63e9fa09f1a2", + "sha256:908e905976d15235fae59c9ac42c4c5b75cfcefe3d27c0fbf7ae15a37715d80e" ], - "markers": "python_version >= '3.7'", - "version": "==1.9.4" + "markers": "python_version >= '3.8'", + "version": "==1.13.3" }, "click": { "hashes": [ - "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e", - "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48" + "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28", + "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de" ], "markers": "python_version >= '3.7'", - "version": "==8.1.3" + "version": "==8.1.7" }, "flask": { "hashes": [ @@ -820,11 +897,11 @@ }, "flask-migrate": { "hashes": [ - "sha256:73293d40b10ac17736e715b377e7b7bde474cb8105165d77474df4c3619b10b3", - "sha256:77580f27ab39bc68be4906a43c56d7674b45075bc4f883b1d0b985db5164d58f" + "sha256:5c532be17e7b43a223b7500d620edae33795df27c75811ddf32560f7d48ec617", + "sha256:dff7dd25113c210b069af280ea713b883f3840c1e3455274745d7355778c8622" ], "index": "pypi", - "version": "==4.0.4" + "version": "==4.0.7" }, "flask-sqlalchemy": { "hashes": [ @@ -836,99 +913,109 @@ }, "importlib-metadata": { "hashes": [ - "sha256:7efb448ec9a5e313a57655d35aa54cd3e01b7e1fbcf72dce1bf06119420f5bad", - "sha256:e354bedeb60efa6affdcc8ae121b73544a7aa74156d047311948f6d711cd378d" + "sha256:45e54197d28b7a7f1559e60b95e7c567032b602131fbd588f1497f47880aa68b", + "sha256:71522656f0abace1d072b9e5481a48f07c138e00f079c38c8f883823f9c26bd7" ], "markers": "python_version < '3.9'", - "version": "==6.0.0" + "version": "==8.5.0" }, "importlib-resources": { "hashes": [ - "sha256:1e534a02295f3eeee0785e21b26c726557909cbaf1b871cf9adcbc0df44c1308", - "sha256:c0a55f37559b5e9ca1d3fce02d60243846245ad8f8d806a4484093806d4d0ae5" + "sha256:980862a1d16c9e147a59603677fa2aa5fd82b87f223b6cb870695bcfce830065", + "sha256:ac29d5f956f01d5e4bb63102a5a19957f1b9175e45649977264a1416783bb717" ], "markers": "python_version < '3.9'", - "version": "==5.11.0" + "version": "==6.4.5" }, "itsdangerous": { "hashes": [ - "sha256:2c2349112351b88699d8d4b6b075022c0808887cb7ad10069318a8b0bc88db44", - "sha256:5dbbc68b317e5e42f327f9021763545dc3fc3bfe22e6deb96aaf1fc38874156a" + "sha256:c6242fc49e35958c8b15141343aa660db5fc54d4f13a1db01a3f5891b98700ef", + "sha256:e0050c0b7da1eea53ffaf149c0cfbb5c6e2e2b69c4bef22c81fa6eb73e5f6173" ], - "markers": "python_version >= '3.7'", - "version": "==2.1.2" + "markers": "python_version >= '3.8'", + "version": "==2.2.0" }, "jinja2": { "hashes": [ - "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852", - "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61" + "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369", + "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d" ], "markers": "python_version >= '3.7'", - "version": "==3.1.2" + "version": "==3.1.4" }, "mako": { "hashes": [ - "sha256:c97c79c018b9165ac9922ae4f32da095ffd3c4e6872b45eded42926deea46818", - "sha256:d60a3903dc3bb01a18ad6a89cdbe2e4eadc69c0bc8ef1e3773ba53d44c3f7a34" + "sha256:260f1dbc3a519453a9c856dedfe4beb4e50bd5a26d96386cb6c80856556bb91a", + "sha256:48dbc20568c1d276a2698b36d968fa76161bf127194907ea6fc594fa81f943bc" ], - "markers": "python_version >= '3.7'", - "version": "==1.2.4" + "markers": "python_version >= '3.8'", + "version": "==1.3.5" }, "markupsafe": { "hashes": [ - "sha256:0576fe974b40a400449768941d5d0858cc624e3249dfd1e0c33674e5c7ca7aed", - "sha256:085fd3201e7b12809f9e6e9bc1e5c96a368c8523fad5afb02afe3c051ae4afcc", - "sha256:090376d812fb6ac5f171e5938e82e7f2d7adc2b629101cec0db8b267815c85e2", - "sha256:0b462104ba25f1ac006fdab8b6a01ebbfbce9ed37fd37fd4acd70c67c973e460", - "sha256:137678c63c977754abe9086a3ec011e8fd985ab90631145dfb9294ad09c102a7", - "sha256:1bea30e9bf331f3fef67e0a3877b2288593c98a21ccb2cf29b74c581a4eb3af0", - "sha256:22152d00bf4a9c7c83960521fc558f55a1adbc0631fbb00a9471e097b19d72e1", - "sha256:22731d79ed2eb25059ae3df1dfc9cb1546691cc41f4e3130fe6bfbc3ecbbecfa", - "sha256:2298c859cfc5463f1b64bd55cb3e602528db6fa0f3cfd568d3605c50678f8f03", - "sha256:28057e985dace2f478e042eaa15606c7efccb700797660629da387eb289b9323", - "sha256:2e7821bffe00aa6bd07a23913b7f4e01328c3d5cc0b40b36c0bd81d362faeb65", - "sha256:2ec4f2d48ae59bbb9d1f9d7efb9236ab81429a764dedca114f5fdabbc3788013", - "sha256:340bea174e9761308703ae988e982005aedf427de816d1afe98147668cc03036", - "sha256:40627dcf047dadb22cd25ea7ecfe9cbf3bbbad0482ee5920b582f3809c97654f", - "sha256:40dfd3fefbef579ee058f139733ac336312663c6706d1163b82b3003fb1925c4", - "sha256:4cf06cdc1dda95223e9d2d3c58d3b178aa5dacb35ee7e3bbac10e4e1faacb419", - "sha256:50c42830a633fa0cf9e7d27664637532791bfc31c731a87b202d2d8ac40c3ea2", - "sha256:55f44b440d491028addb3b88f72207d71eeebfb7b5dbf0643f7c023ae1fba619", - "sha256:608e7073dfa9e38a85d38474c082d4281f4ce276ac0010224eaba11e929dd53a", - "sha256:63ba06c9941e46fa389d389644e2d8225e0e3e5ebcc4ff1ea8506dce646f8c8a", - "sha256:65608c35bfb8a76763f37036547f7adfd09270fbdbf96608be2bead319728fcd", - "sha256:665a36ae6f8f20a4676b53224e33d456a6f5a72657d9c83c2aa00765072f31f7", - "sha256:6d6607f98fcf17e534162f0709aaad3ab7a96032723d8ac8750ffe17ae5a0666", - "sha256:7313ce6a199651c4ed9d7e4cfb4aa56fe923b1adf9af3b420ee14e6d9a73df65", - "sha256:7668b52e102d0ed87cb082380a7e2e1e78737ddecdde129acadb0eccc5423859", - "sha256:7df70907e00c970c60b9ef2938d894a9381f38e6b9db73c5be35e59d92e06625", - "sha256:7e007132af78ea9df29495dbf7b5824cb71648d7133cf7848a2a5dd00d36f9ff", - "sha256:835fb5e38fd89328e9c81067fd642b3593c33e1e17e2fdbf77f5676abb14a156", - "sha256:8bca7e26c1dd751236cfb0c6c72d4ad61d986e9a41bbf76cb445f69488b2a2bd", - "sha256:8db032bf0ce9022a8e41a22598eefc802314e81b879ae093f36ce9ddf39ab1ba", - "sha256:99625a92da8229df6d44335e6fcc558a5037dd0a760e11d84be2260e6f37002f", - "sha256:9cad97ab29dfc3f0249b483412c85c8ef4766d96cdf9dcf5a1e3caa3f3661cf1", - "sha256:a4abaec6ca3ad8660690236d11bfe28dfd707778e2442b45addd2f086d6ef094", - "sha256:a6e40afa7f45939ca356f348c8e23048e02cb109ced1eb8420961b2f40fb373a", - "sha256:a6f2fcca746e8d5910e18782f976489939d54a91f9411c32051b4aab2bd7c513", - "sha256:a806db027852538d2ad7555b203300173dd1b77ba116de92da9afbc3a3be3eed", - "sha256:abcabc8c2b26036d62d4c746381a6f7cf60aafcc653198ad678306986b09450d", - "sha256:b8526c6d437855442cdd3d87eede9c425c4445ea011ca38d937db299382e6fa3", - "sha256:bb06feb762bade6bf3c8b844462274db0c76acc95c52abe8dbed28ae3d44a147", - "sha256:c0a33bc9f02c2b17c3ea382f91b4db0e6cde90b63b296422a939886a7a80de1c", - "sha256:c4a549890a45f57f1ebf99c067a4ad0cb423a05544accaf2b065246827ed9603", - "sha256:ca244fa73f50a800cf8c3ebf7fd93149ec37f5cb9596aa8873ae2c1d23498601", - "sha256:cf877ab4ed6e302ec1d04952ca358b381a882fbd9d1b07cccbfd61783561f98a", - "sha256:d9d971ec1e79906046aa3ca266de79eac42f1dbf3612a05dc9368125952bd1a1", - "sha256:da25303d91526aac3672ee6d49a2f3db2d9502a4a60b55519feb1a4c7714e07d", - "sha256:e55e40ff0cc8cc5c07996915ad367fa47da6b3fc091fdadca7f5403239c5fec3", - "sha256:f03a532d7dee1bed20bc4884194a16160a2de9ffc6354b3878ec9682bb623c54", - "sha256:f1cd098434e83e656abf198f103a8207a8187c0fc110306691a2e94a78d0abb2", - "sha256:f2bfb563d0211ce16b63c7cb9395d2c682a23187f54c3d79bfec33e6705473c6", - "sha256:f8ffb705ffcf5ddd0e80b65ddf7bed7ee4f5a441ea7d3419e861a12eaf41af58" + "sha256:00e046b6dd71aa03a41079792f8473dc494d564611a8f89bbbd7cb93295ebdcf", + "sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff", + "sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f", + "sha256:17b950fccb810b3293638215058e432159d2b71005c74371d784862b7e4683f3", + "sha256:1f3fbcb7ef1f16e48246f704ab79d79da8a46891e2da03f8783a5b6fa41a9532", + "sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f", + "sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617", + "sha256:2d2d793e36e230fd32babe143b04cec8a8b3eb8a3122d2aceb4a371e6b09b8df", + "sha256:30b600cf0a7ac9234b2638fbc0fb6158ba5bdcdf46aeb631ead21248b9affbc4", + "sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906", + "sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f", + "sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4", + "sha256:3e53af139f8579a6d5f7b76549125f0d94d7e630761a2111bc431fd820e163b8", + "sha256:4096e9de5c6fdf43fb4f04c26fb114f61ef0bf2e5604b6ee3019d51b69e8c371", + "sha256:4275d846e41ecefa46e2015117a9f491e57a71ddd59bbead77e904dc02b1bed2", + "sha256:4c31f53cdae6ecfa91a77820e8b151dba54ab528ba65dfd235c80b086d68a465", + "sha256:4f11aa001c540f62c6166c7726f71f7573b52c68c31f014c25cc7901deea0b52", + "sha256:5049256f536511ee3f7e1b3f87d1d1209d327e818e6ae1365e8653d7e3abb6a6", + "sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169", + "sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad", + "sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2", + "sha256:5dedb4db619ba5a2787a94d877bc8ffc0566f92a01c0ef214865e54ecc9ee5e0", + "sha256:619bc166c4f2de5caa5a633b8b7326fbe98e0ccbfacabd87268a2b15ff73a029", + "sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f", + "sha256:656f7526c69fac7f600bd1f400991cc282b417d17539a1b228617081106feb4a", + "sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced", + "sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5", + "sha256:7502934a33b54030eaf1194c21c692a534196063db72176b0c4028e140f8f32c", + "sha256:7a68b554d356a91cce1236aa7682dc01df0edba8d043fd1ce607c49dd3c1edcf", + "sha256:7b2e5a267c855eea6b4283940daa6e88a285f5f2a67f2220203786dfa59b37e9", + "sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb", + "sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad", + "sha256:8dd717634f5a044f860435c1d8c16a270ddf0ef8588d4887037c5028b859b0c3", + "sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1", + "sha256:97cafb1f3cbcd3fd2b6fbfb99ae11cdb14deea0736fc2b0952ee177f2b813a46", + "sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc", + "sha256:a549b9c31bec33820e885335b451286e2969a2d9e24879f83fe904a5ce59d70a", + "sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee", + "sha256:ae2ad8ae6ebee9d2d94b17fb62763125f3f374c25618198f40cbb8b525411900", + "sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5", + "sha256:bc1667f8b83f48511b94671e0e441401371dfd0f0a795c7daa4a3cd1dde55bea", + "sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f", + "sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5", + "sha256:bff1b4290a66b490a2f4719358c0cdcd9bafb6b8f061e45c7a2460866bf50c2e", + "sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a", + "sha256:c8b29db45f8fe46ad280a7294f5c3ec36dbac9491f2d1c17345be8e69cc5928f", + "sha256:ce409136744f6521e39fd8e2a24c53fa18ad67aa5bc7c2cf83645cce5b5c4e50", + "sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a", + "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b", + "sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4", + "sha256:daa4ee5a243f0f20d528d939d06670a298dd39b1ad5f8a72a4275124a7819eff", + "sha256:db0b55e0f3cc0be60c1f19efdde9a637c32740486004f20d1cff53c3c0ece4d2", + "sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46", + "sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b", + "sha256:ec6a563cff360b50eed26f13adc43e61bc0c04d94b8be985e6fb24b81f6dcfdf", + "sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5", + "sha256:fa173ec60341d6bb97a89f5ea19c85c5643c1e7dedebc22f5181eb73573142c5", + "sha256:fa9db3f79de01457b03d4f01b34cf91bc0048eb2c3846ff26f66687c2f6d16ab", + "sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd", + "sha256:ffee1f21e5ef0d712f9033568f8344d5da8cc2869dbd08d87c84656e6a2d2f68" ], "markers": "python_version >= '3.7'", - "version": "==2.1.2" + "version": "==2.1.5" }, "sqlalchemy": { "hashes": [ @@ -970,21 +1057,29 @@ "index": "pypi", "version": "==1.3.24" }, + "typing-extensions": { + "hashes": [ + "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d", + "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8" + ], + "markers": "python_version >= '3.8'", + "version": "==4.12.2" + }, "werkzeug": { "hashes": [ - "sha256:2e1ccc9417d4da358b9de6f174e3ac094391ea1d4fbef2d667865d819dfd0afe", - "sha256:56433961bc1f12533306c624f3be5e744389ac61d722175d543e1751285da612" + "sha256:1421ebfc7648a39a5c58c601b154165d05cf47a3cd0ccb70857cbdacf6c8f2b8", + "sha256:b863f8ff057c522164b6067c9e28b041161b4be5ba4d0daceeaa50a163822d3c" ], - "markers": "python_version >= '3.7'", - "version": "==2.2.3" + "index": "pypi", + "version": "==2.0.3" }, "zipp": { "hashes": [ - "sha256:23f70e964bc11a34cef175bc90ba2914e1e4545ea1e3e2f67c079671883f9cb6", - "sha256:e8b2a36ea17df80ffe9e2c4fda3f693c3dad6df1697d3cd3af232db680950b0b" + "sha256:a817ac80d6cf4b23bf7f2828b7cabf326f15a001bea8b1f9b49631780ba28350", + "sha256:bc9eb26f4506fda01b81bcde0ca78103b6e62f991b381fec825435c836edbc29" ], "markers": "python_version < '3.10'", - "version": "==3.13.0" + "version": "==3.20.2" } } } From e3936ede9c6eab0e6da864692607be27dd9f1d8d Mon Sep 17 00:00:00 2001 From: Adrian Edwards Date: Mon, 28 Apr 2025 14:54:14 -0400 Subject: [PATCH 199/206] pipenv update --- Pipfile.lock | 706 ++++++++++++++++++++++++++------------------------- 1 file changed, 364 insertions(+), 342 deletions(-) diff --git a/Pipfile.lock b/Pipfile.lock index 969f808..8b9472a 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -18,11 +18,11 @@ "default": { "alembic": { "hashes": [ - "sha256:203503117415561e203aa14541740643a611f641517f0209fcae63e9fa09f1a2", - "sha256:908e905976d15235fae59c9ac42c4c5b75cfcefe3d27c0fbf7ae15a37715d80e" + "sha256:1acdd7a3a478e208b0503cd73614d5e4c6efafa4e73518bb60e4f2846a37b1c5", + "sha256:496e888245a53adf1498fcab31713a469c65836f8de76e01399aa1c3e90dd213" ], "markers": "python_version >= '3.8'", - "version": "==1.13.3" + "version": "==1.14.1" }, "apispec": { "hashes": [ @@ -42,139 +42,141 @@ }, "attrs": { "hashes": [ - "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346", - "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2" + "sha256:427318ce031701fea540783410126f03899a97ffc6f61596ad581ac2e40e3bc3", + "sha256:75d7cefc7fb576747b2c81b4442d4d4a1ce0900973527c011d1030fd3bf4af1b" ], - "markers": "python_version >= '3.7'", - "version": "==24.2.0" + "markers": "python_version >= '3.8'", + "version": "==25.3.0" }, "certifi": { "hashes": [ - "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8", - "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9" + "sha256:0a816057ea3cdefcef70270d2c515e4506bbc954f417fa5ade2021213bb8f0c6", + "sha256:30350364dfe371162649852c63336a15c70c6510c2ad5015b21c2345311805f3" ], "markers": "python_version >= '3.6'", - "version": "==2024.8.30" + "version": "==2025.4.26" }, "charset-normalizer": { "hashes": [ - "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027", - "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087", - "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786", - "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8", - "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09", - "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185", - "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574", - "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e", - "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519", - "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898", - "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269", - "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3", - "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f", - "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6", - "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8", - "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a", - "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73", - "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc", - "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714", - "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2", - "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc", - "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce", - "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d", - "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e", - "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6", - "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269", - "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96", - "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d", - "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a", - "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4", - "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77", - "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d", - "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0", - "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed", - "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068", - "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac", - "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25", - "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8", - "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab", - "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26", - "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2", - "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db", - "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f", - "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5", - "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99", - "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c", - "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d", - "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811", - "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa", - "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a", - "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03", - "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b", - "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04", - "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c", - "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001", - "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458", - "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389", - "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99", - "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985", - "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537", - "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238", - "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f", - "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d", - "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796", - "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a", - "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143", - "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8", - "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c", - "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5", - "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5", - "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711", - "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4", - "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6", - "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c", - "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7", - "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4", - "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b", - "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae", - "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12", - "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c", - "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae", - "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8", - "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887", - "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b", - "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4", - "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f", - "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5", - "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33", - "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519", - "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561" + "sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537", + "sha256:01732659ba9b5b873fc117534143e4feefecf3b2078b0a6a2e925271bb6f4cfa", + "sha256:01ad647cdd609225c5350561d084b42ddf732f4eeefe6e678765636791e78b9a", + "sha256:04432ad9479fa40ec0f387795ddad4437a2b50417c69fa275e212933519ff294", + "sha256:0907f11d019260cdc3f94fbdb23ff9125f6b5d1039b76003b5b0ac9d6a6c9d5b", + "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd", + "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601", + "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd", + "sha256:0af291f4fe114be0280cdd29d533696a77b5b49cfde5467176ecab32353395c4", + "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d", + "sha256:1a2bc9f351a75ef49d664206d51f8e5ede9da246602dc2d2726837620ea034b2", + "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313", + "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd", + "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa", + "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8", + "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1", + "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2", + "sha256:2a75d49014d118e4198bcee5ee0a6f25856b29b12dbf7cd012791f8a6cc5c496", + "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d", + "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b", + "sha256:2fb9bd477fdea8684f78791a6de97a953c51831ee2981f8e4f583ff3b9d9687e", + "sha256:311f30128d7d333eebd7896965bfcfbd0065f1716ec92bd5638d7748eb6f936a", + "sha256:329ce159e82018d646c7ac45b01a430369d526569ec08516081727a20e9e4af4", + "sha256:345b0426edd4e18138d6528aed636de7a9ed169b4aaf9d61a8c19e39d26838ca", + "sha256:363e2f92b0f0174b2f8238240a1a30142e3db7b957a5dd5689b0e75fb717cc78", + "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408", + "sha256:3bed14e9c89dcb10e8f3a29f9ccac4955aebe93c71ae803af79265c9ca5644c5", + "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3", + "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f", + "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a", + "sha256:49402233c892a461407c512a19435d1ce275543138294f7ef013f0b63d5d3765", + "sha256:4c0907b1928a36d5a998d72d64d8eaa7244989f7aaaf947500d3a800c83a3fd6", + "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146", + "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6", + "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9", + "sha256:619a609aa74ae43d90ed2e89bdd784765de0a25ca761b93e196d938b8fd1dbbd", + "sha256:6e27f48bcd0957c6d4cb9d6fa6b61d192d0b13d5ef563e5f2ae35feafc0d179c", + "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f", + "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545", + "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176", + "sha256:75832c08354f595c760a804588b9357d34ec00ba1c940c15e31e96d902093770", + "sha256:7709f51f5f7c853f0fb938bcd3bc59cdfdc5203635ffd18bf354f6967ea0f824", + "sha256:78baa6d91634dfb69ec52a463534bc0df05dbd546209b79a3880a34487f4b84f", + "sha256:7974a0b5ecd505609e3b19742b60cee7aa2aa2fb3151bc917e6e2646d7667dcf", + "sha256:7a4f97a081603d2050bfaffdefa5b02a9ec823f8348a572e39032caa8404a487", + "sha256:7b1bef6280950ee6c177b326508f86cad7ad4dff12454483b51d8b7d673a2c5d", + "sha256:7d053096f67cd1241601111b698f5cad775f97ab25d81567d3f59219b5f1adbd", + "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b", + "sha256:807f52c1f798eef6cf26beb819eeb8819b1622ddfeef9d0977a8502d4db6d534", + "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f", + "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b", + "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9", + "sha256:89149166622f4db9b4b6a449256291dc87a99ee53151c74cbd82a53c8c2f6ccd", + "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125", + "sha256:8c60ca7339acd497a55b0ea5d506b2a2612afb2826560416f6894e8b5770d4a9", + "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de", + "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11", + "sha256:97f68b8d6831127e4787ad15e6757232e14e12060bec17091b85eb1486b91d8d", + "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35", + "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f", + "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda", + "sha256:ab36c8eb7e454e34e60eb55ca5d241a5d18b2c6244f6827a30e451c42410b5f7", + "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a", + "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971", + "sha256:b7b2d86dd06bfc2ade3312a83a5c364c7ec2e3498f8734282c6c3d4b07b346b8", + "sha256:b97e690a2118911e39b4042088092771b4ae3fc3aa86518f84b8cf6888dbdb41", + "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d", + "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f", + "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757", + "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a", + "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886", + "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77", + "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76", + "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247", + "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85", + "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb", + "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7", + "sha256:dccbe65bd2f7f7ec22c4ff99ed56faa1e9f785482b9bbd7c717e26fd723a1d1e", + "sha256:dd78cfcda14a1ef52584dbb008f7ac81c1328c0f58184bf9a84c49c605002da6", + "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037", + "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1", + "sha256:ea0d8d539afa5eb2728aa1932a988a9a7af94f18582ffae4bc10b3fbdad0626e", + "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807", + "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407", + "sha256:ecddf25bee22fe4fe3737a399d0d177d72bc22be6913acfab364b40bce1ba83c", + "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12", + "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3", + "sha256:f30bf9fd9be89ecb2360c7d94a711f00c09b976258846efe40db3d05828e8089", + "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd", + "sha256:fc54db6c8593ef7d4b2a331b58653356cf04f67c960f584edb7c3d8c97e8f39e", + "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00", + "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616" ], "markers": "python_version >= '3.7'", - "version": "==3.3.2" + "version": "==3.4.1" }, "click": { "hashes": [ - "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28", - "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de" + "sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2", + "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a" ], "markers": "python_version >= '3.7'", - "version": "==8.1.7" + "version": "==8.1.8" }, "deprecated": { "hashes": [ - "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c", - "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3" + "sha256:422b6f6d859da6f2ef57857761bfb392480502a64c3028ca9bbe86085d72115d", + "sha256:bd5011788200372a32418f888e326a09ff80d0214bd961147cfed01b5c018eec" ], "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==1.2.14" + "version": "==1.2.18" }, "ecdsa": { "hashes": [ - "sha256:2cea9b88407fdac7bbeca0833b189e4c9c53f2ef1e1eaa29f6224dbc809b707a", - "sha256:60eaad1199659900dd0af521ed462b793bbdf867432b3948e87416ae4caf6bf8" + "sha256:30638e27cf77b7e15c4c4cc1973720149e1033827cfd00661ca5c8cc0cdb24c3", + "sha256:478cba7b62555866fcb3bb3fe985e06decbdb68ef55713c4e5ab98c57d508e61" ], - "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==0.19.0" + "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'", + "version": "==0.19.1" }, "flasgger": { "hashes": [ @@ -217,11 +219,11 @@ }, "flask-migrate": { "hashes": [ - "sha256:5c532be17e7b43a223b7500d620edae33795df27c75811ddf32560f7d48ec617", - "sha256:dff7dd25113c210b069af280ea713b883f3840c1e3455274745d7355778c8622" + "sha256:1a336b06eb2c3ace005f5f2ded8641d534c18798d64061f6ff11f79e1434126d", + "sha256:24d8051af161782e0743af1b04a152d007bad9772b2bca67b7ec1e8ceeb3910d" ], "index": "pypi", - "version": "==4.0.7" + "version": "==4.1.0" }, "flask-sqlalchemy": { "hashes": [ @@ -273,11 +275,11 @@ }, "jinja2": { "hashes": [ - "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369", - "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d" + "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d", + "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67" ], "markers": "python_version >= '3.7'", - "version": "==3.1.4" + "version": "==3.1.6" }, "jsonschema": { "hashes": [ @@ -305,11 +307,11 @@ }, "mako": { "hashes": [ - "sha256:260f1dbc3a519453a9c856dedfe4beb4e50bd5a26d96386cb6c80856556bb91a", - "sha256:48dbc20568c1d276a2698b36d968fa76161bf127194907ea6fc594fa81f943bc" + "sha256:99579a6f39583fa7e5630a28c3c1f440e4e97a414b80372649c0ce338da2ea28", + "sha256:baef24a52fc4fc514a0887ac600f9f1cff3d82c61d4d700a1fa84d597b88db59" ], "markers": "python_version >= '3.8'", - "version": "==1.3.5" + "version": "==1.3.10" }, "markdown-it-py": { "hashes": [ @@ -411,11 +413,11 @@ }, "mistune": { "hashes": [ - "sha256:71481854c30fdbc938963d3605b72501f5c10a9320ecd412c121c163a1c7d205", - "sha256:fc7f93ded930c92394ef2cb6f04a8aabab4117a91449e72dcc8dfa646a508be8" + "sha256:1a32314113cff28aa6432e99e522677c8587fd83e3d51c29b82a52409c842bd9", + "sha256:a7035c21782b2becb6be62f8f25d3df81ccb4d6fa477a6525b15af06539f02a0" ], - "markers": "python_version >= '3.7'", - "version": "==3.0.2" + "markers": "python_version >= '3.8'", + "version": "==3.1.3" }, "mysql-connector-python": { "hashes": [ @@ -459,11 +461,11 @@ }, "packaging": { "hashes": [ - "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002", - "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124" + "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759", + "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f" ], "markers": "python_version >= '3.8'", - "version": "==24.1" + "version": "==24.2" }, "pkgutil-resolve-name": { "hashes": [ @@ -475,19 +477,30 @@ }, "pyasn1": { "hashes": [ - "sha256:0d632f46f2ba09143da3a8afe9e33fb6f92fa2320ab7e886e2d0f7672af84629", - "sha256:6f580d2bdd84365380830acf45550f2511469f673cb4a5ae3857a3170128b034" + "sha256:014c0e9976956a08139dc0712ae195324a75e142284d5f87f1a87ee1b068a359", + "sha256:03840c999ba71680a131cfaee6fab142e1ed9bbd9c693e285cc6aca0d555e576", + "sha256:0458773cfe65b153891ac249bcf1b5f8f320b7c2ce462151f8fa74de8934becf", + "sha256:08c3c53b75eaa48d71cf8c710312316392ed40899cb34710d092e96745a358b7", + "sha256:39c7e2ec30515947ff4e87fb6f456dfc6e84857d34be479c9d4a4ba4bf46aa5d", + "sha256:5c9414dcfede6e441f7e8f81b43b34e834731003427e5b09e4e00e3172a10f00", + "sha256:6e7545f1a61025a4e58bb336952c5061697da694db1cae97b116e9c46abcf7c8", + "sha256:78fa6da68ed2727915c4767bb386ab32cdba863caa7dbe473eaae45f9959da86", + "sha256:7ab8a544af125fb704feadb008c99a88805126fb525280b2270bb25cc1d78a12", + "sha256:99fcc3c8d804d1bc6d9a099921e39d827026409a58f2a720dcdb89374ea0c776", + "sha256:aef77c9fb94a3ac588e87841208bdec464471d9871bd5050a287cc9a475cd0ba", + "sha256:e89bf84b5437b532b0803ba5c9a5e054d21fec423a89952a74f87fa2c9b7bce2", + "sha256:fec3e9d8e36808a28efb59b489e4528c10ad0f480e57dcc32b4de5c9d8c9fdf3" ], "markers": "python_version >= '3.8'", - "version": "==0.6.1" + "version": "==0.4.8" }, "pygments": { "hashes": [ - "sha256:786ff802f32e91311bff3889f6e9a86e81505fe99f2735bb6d60ae0c5004f199", - "sha256:b8e6aca0523f3ab76fee51799c488e38782ac06eafcf95e7ba832985c8e7b13a" + "sha256:61c16d2a8576dc0649d9f39e089b5f02bcd27fba10d8fb4dcc28173f7a45151f", + "sha256:9ea1544ad55cecf4b8242fab6dd35a93bbce657034b0611ee383099054ab6d8c" ], "markers": "python_version >= '3.8'", - "version": "==2.18.0" + "version": "==2.19.1" }, "python-dotenv": { "hashes": [ @@ -499,11 +512,11 @@ }, "python-jose": { "hashes": [ - "sha256:55779b5e6ad599c6336191246e95eb2293a9ddebd555f796a65f838f07e5d78a", - "sha256:9b1376b023f8b298536eedd47ae1089bcdb848f1535ab30555cd92002d78923a" + "sha256:9a9a40f418ced8ecaf7e3b28d69887ceaa76adad3bcaa6dae0d9e596fec1d680", + "sha256:9c9f616819652d109bd889ecd1e15e9a162b9b94d682534c9c2146092945b78f" ], "index": "pypi", - "version": "==3.3.0" + "version": "==3.4.0" }, "pyyaml": { "hashes": [ @@ -582,136 +595,136 @@ }, "rich": { "hashes": [ - "sha256:51a2c62057461aaf7152b4d611168f93a9fc73068f8ded2790f29fe2b5366d0c", - "sha256:8c82a3d3f8dcfe9e734771313e606b39d8247bb6b826e196f4914b333b743cf1" + "sha256:439594978a49a09530cff7ebc4b5c7103ef57baf48d5ea3184f21d9a2befa098", + "sha256:6049d5e6ec054bf2779ab3358186963bac2ea89175919d699e378b99738c2a90" ], "markers": "python_version >= '3.8'", - "version": "==13.9.2" + "version": "==13.9.4" }, "rpds-py": { "hashes": [ - "sha256:06db23d43f26478303e954c34c75182356ca9aa7797d22c5345b16871ab9c45c", - "sha256:0e13e6952ef264c40587d510ad676a988df19adea20444c2b295e536457bc585", - "sha256:11ef6ce74616342888b69878d45e9f779b95d4bd48b382a229fe624a409b72c5", - "sha256:1259c7b3705ac0a0bd38197565a5d603218591d3f6cee6e614e380b6ba61c6f6", - "sha256:18d7585c463087bddcfa74c2ba267339f14f2515158ac4db30b1f9cbdb62c8ef", - "sha256:1e0f80b739e5a8f54837be5d5c924483996b603d5502bfff79bf33da06164ee2", - "sha256:1e5f3cd7397c8f86c8cc72d5a791071431c108edd79872cdd96e00abd8497d29", - "sha256:220002c1b846db9afd83371d08d239fdc865e8f8c5795bbaec20916a76db3318", - "sha256:22e6c9976e38f4d8c4a63bd8a8edac5307dffd3ee7e6026d97f3cc3a2dc02a0b", - "sha256:238a2d5b1cad28cdc6ed15faf93a998336eb041c4e440dd7f902528b8891b399", - "sha256:2580b0c34583b85efec8c5c5ec9edf2dfe817330cc882ee972ae650e7b5ef739", - "sha256:28527c685f237c05445efec62426d285e47a58fb05ba0090a4340b73ecda6dee", - "sha256:2cf126d33a91ee6eedc7f3197b53e87a2acdac63602c0f03a02dd69e4b138174", - "sha256:338ca4539aad4ce70a656e5187a3a31c5204f261aef9f6ab50e50bcdffaf050a", - "sha256:39ed0d010457a78f54090fafb5d108501b5aa5604cc22408fc1c0c77eac14344", - "sha256:3ad0fda1635f8439cde85c700f964b23ed5fc2d28016b32b9ee5fe30da5c84e2", - "sha256:3d2b1ad682a3dfda2a4e8ad8572f3100f95fad98cb99faf37ff0ddfe9cbf9d03", - "sha256:3d61339e9f84a3f0767b1995adfb171a0d00a1185192718a17af6e124728e0f5", - "sha256:3fde368e9140312b6e8b6c09fb9f8c8c2f00999d1823403ae90cc00480221b22", - "sha256:40ce74fc86ee4645d0a225498d091d8bc61f39b709ebef8204cb8b5a464d3c0e", - "sha256:49a8063ea4296b3a7e81a5dfb8f7b2d73f0b1c20c2af401fb0cdf22e14711a96", - "sha256:4a1f1d51eccb7e6c32ae89243cb352389228ea62f89cd80823ea7dd1b98e0b91", - "sha256:4b16aa0107ecb512b568244ef461f27697164d9a68d8b35090e9b0c1c8b27752", - "sha256:4f1ed4749a08379555cebf4650453f14452eaa9c43d0a95c49db50c18b7da075", - "sha256:4fe84294c7019456e56d93e8ababdad5a329cd25975be749c3f5f558abb48253", - "sha256:50eccbf054e62a7b2209b28dc7a22d6254860209d6753e6b78cfaeb0075d7bee", - "sha256:514b3293b64187172bc77c8fb0cdae26981618021053b30d8371c3a902d4d5ad", - "sha256:54b43a2b07db18314669092bb2de584524d1ef414588780261e31e85846c26a5", - "sha256:55fea87029cded5df854ca7e192ec7bdb7ecd1d9a3f63d5c4eb09148acf4a7ce", - "sha256:569b3ea770c2717b730b61998b6c54996adee3cef69fc28d444f3e7920313cf7", - "sha256:56e27147a5a4c2c21633ff8475d185734c0e4befd1c989b5b95a5d0db699b21b", - "sha256:57eb94a8c16ab08fef6404301c38318e2c5a32216bf5de453e2714c964c125c8", - "sha256:5a35df9f5548fd79cb2f52d27182108c3e6641a4feb0f39067911bf2adaa3e57", - "sha256:5a8c94dad2e45324fc74dce25e1645d4d14df9a4e54a30fa0ae8bad9a63928e3", - "sha256:5b4f105deeffa28bbcdff6c49b34e74903139afa690e35d2d9e3c2c2fba18cec", - "sha256:5c1dc0f53856b9cc9a0ccca0a7cc61d3d20a7088201c0937f3f4048c1718a209", - "sha256:614fdafe9f5f19c63ea02817fa4861c606a59a604a77c8cdef5aa01d28b97921", - "sha256:617c7357272c67696fd052811e352ac54ed1d9b49ab370261a80d3b6ce385045", - "sha256:65794e4048ee837494aea3c21a28ad5fc080994dfba5b036cf84de37f7ad5074", - "sha256:6632f2d04f15d1bd6fe0eedd3b86d9061b836ddca4c03d5cf5c7e9e6b7c14580", - "sha256:6c8ef2ebf76df43f5750b46851ed1cdf8f109d7787ca40035fe19fbdc1acc5a7", - "sha256:758406267907b3781beee0f0edfe4a179fbd97c0be2e9b1154d7f0a1279cf8e5", - "sha256:7e60cb630f674a31f0368ed32b2a6b4331b8350d67de53c0359992444b116dd3", - "sha256:89c19a494bf3ad08c1da49445cc5d13d8fefc265f48ee7e7556839acdacf69d0", - "sha256:8a86a9b96070674fc88b6f9f71a97d2c1d3e5165574615d1f9168ecba4cecb24", - "sha256:8bc7690f7caee50b04a79bf017a8d020c1f48c2a1077ffe172abec59870f1139", - "sha256:8d7919548df3f25374a1f5d01fbcd38dacab338ef5f33e044744b5c36729c8db", - "sha256:9426133526f69fcaba6e42146b4e12d6bc6c839b8b555097020e2b78ce908dcc", - "sha256:9824fb430c9cf9af743cf7aaf6707bf14323fb51ee74425c380f4c846ea70789", - "sha256:9bb4a0d90fdb03437c109a17eade42dfbf6190408f29b2744114d11586611d6f", - "sha256:9bc2d153989e3216b0559251b0c260cfd168ec78b1fac33dd485750a228db5a2", - "sha256:9d35cef91e59ebbeaa45214861874bc6f19eb35de96db73e467a8358d701a96c", - "sha256:a1862d2d7ce1674cffa6d186d53ca95c6e17ed2b06b3f4c476173565c862d232", - "sha256:a84ab91cbe7aab97f7446652d0ed37d35b68a465aeef8fc41932a9d7eee2c1a6", - "sha256:aa7f429242aae2947246587d2964fad750b79e8c233a2367f71b554e9447949c", - "sha256:aa9a0521aeca7d4941499a73ad7d4f8ffa3d1affc50b9ea11d992cd7eff18a29", - "sha256:ac2f4f7a98934c2ed6505aead07b979e6f999389f16b714448fb39bbaa86a489", - "sha256:ae94bd0b2f02c28e199e9bc51485d0c5601f58780636185660f86bf80c89af94", - "sha256:af0fc424a5842a11e28956e69395fbbeab2c97c42253169d87e90aac2886d751", - "sha256:b2a5db5397d82fa847e4c624b0c98fe59d2d9b7cf0ce6de09e4d2e80f8f5b3f2", - "sha256:b4c29cbbba378759ac5786730d1c3cb4ec6f8ababf5c42a9ce303dc4b3d08cda", - "sha256:b74b25f024b421d5859d156750ea9a65651793d51b76a2e9238c05c9d5f203a9", - "sha256:b7f19250ceef892adf27f0399b9e5afad019288e9be756d6919cb58892129f51", - "sha256:b80d4a7900cf6b66bb9cee5c352b2d708e29e5a37fe9bf784fa97fc11504bf6c", - "sha256:b8c00a3b1e70c1d3891f0db1b05292747f0dbcfb49c43f9244d04c70fbc40eb8", - "sha256:bb273176be34a746bdac0b0d7e4e2c467323d13640b736c4c477881a3220a989", - "sha256:c3c20f0ddeb6e29126d45f89206b8291352b8c5b44384e78a6499d68b52ae511", - "sha256:c3e130fd0ec56cb76eb49ef52faead8ff09d13f4527e9b0c400307ff72b408e1", - "sha256:c52d3f2f82b763a24ef52f5d24358553e8403ce05f893b5347098014f2d9eff2", - "sha256:c6377e647bbfd0a0b159fe557f2c6c602c159fc752fa316572f012fc0bf67150", - "sha256:c638144ce971df84650d3ed0096e2ae7af8e62ecbbb7b201c8935c370df00a2c", - "sha256:ce9845054c13696f7af7f2b353e6b4f676dab1b4b215d7fe5e05c6f8bb06f965", - "sha256:cf258ede5bc22a45c8e726b29835b9303c285ab46fc7c3a4cc770736b5304c9f", - "sha256:d0a26ffe9d4dd35e4dfdd1e71f46401cff0181c75ac174711ccff0459135fa58", - "sha256:d0b67d87bb45ed1cd020e8fbf2307d449b68abc45402fe1a4ac9e46c3c8b192b", - "sha256:d20277fd62e1b992a50c43f13fbe13277a31f8c9f70d59759c88f644d66c619f", - "sha256:d454b8749b4bd70dd0a79f428731ee263fa6995f83ccb8bada706e8d1d3ff89d", - "sha256:d4c7d1a051eeb39f5c9547e82ea27cbcc28338482242e3e0b7768033cb083821", - "sha256:d72278a30111e5b5525c1dd96120d9e958464316f55adb030433ea905866f4de", - "sha256:d72a210824facfdaf8768cf2d7ca25a042c30320b3020de2fa04640920d4e121", - "sha256:d807dc2051abe041b6649681dce568f8e10668e3c1c6543ebae58f2d7e617855", - "sha256:dbe982f38565bb50cb7fb061ebf762c2f254ca3d8c20d4006878766e84266272", - "sha256:dcedf0b42bcb4cfff4101d7771a10532415a6106062f005ab97d1d0ab5681c60", - "sha256:deb62214c42a261cb3eb04d474f7155279c1a8a8c30ac89b7dcb1721d92c3c02", - "sha256:def7400461c3a3f26e49078302e1c1b38f6752342c77e3cf72ce91ca69fb1bc1", - "sha256:df3de6b7726b52966edf29663e57306b23ef775faf0ac01a3e9f4012a24a4140", - "sha256:e1940dae14e715e2e02dfd5b0f64a52e8374a517a1e531ad9412319dc3ac7879", - "sha256:e4df1e3b3bec320790f699890d41c59d250f6beda159ea3c44c3f5bac1976940", - "sha256:e6900ecdd50ce0facf703f7a00df12374b74bbc8ad9fe0f6559947fb20f82364", - "sha256:ea438162a9fcbee3ecf36c23e6c68237479f89f962f82dae83dc15feeceb37e4", - "sha256:eb851b7df9dda52dc1415ebee12362047ce771fc36914586b2e9fcbd7d293b3e", - "sha256:ec31a99ca63bf3cd7f1a5ac9fe95c5e2d060d3c768a09bc1d16e235840861420", - "sha256:f0475242f447cc6cb8a9dd486d68b2ef7fbee84427124c232bff5f63b1fe11e5", - "sha256:f2fbf7db2012d4876fb0d66b5b9ba6591197b0f165db8d99371d976546472a24", - "sha256:f60012a73aa396be721558caa3a6fd49b3dd0033d1675c6d59c4502e870fcf0c", - "sha256:f8e604fe73ba048c06085beaf51147eaec7df856824bfe7b98657cf436623daf", - "sha256:f90a4cd061914a60bd51c68bcb4357086991bd0bb93d8aa66a6da7701370708f", - "sha256:f918a1a130a6dfe1d7fe0f105064141342e7dd1611f2e6a21cd2f5c8cb1cfb3e", - "sha256:fa518bcd7600c584bf42e6617ee8132869e877db2f76bcdc281ec6a4113a53ab", - "sha256:faefcc78f53a88f3076b7f8be0a8f8d35133a3ecf7f3770895c25f8813460f08", - "sha256:fcaeb7b57f1a1e071ebd748984359fef83ecb026325b9d4ca847c95bc7311c92", - "sha256:fd2d84f40633bc475ef2d5490b9c19543fbf18596dcb1b291e3a12ea5d722f7a", - "sha256:fdfc3a892927458d98f3d55428ae46b921d1f7543b89382fdb483f5640daaec8" + "sha256:02a0629ec053fc013808a85178524e3cb63a61dbc35b22499870194a63578fb9", + "sha256:07924c1b938798797d60c6308fa8ad3b3f0201802f82e4a2c41bb3fafb44cc28", + "sha256:07f59760ef99f31422c49038964b31c4dfcfeb5d2384ebfc71058a7c9adae2d2", + "sha256:0a3a1e9ee9728b2c1734f65d6a1d376c6f2f6fdcc13bb007a08cc4b1ff576dc5", + "sha256:0a90c373ea2975519b58dece25853dbcb9779b05cc46b4819cb1917e3b3215b6", + "sha256:0ad56edabcdb428c2e33bbf24f255fe2b43253b7d13a2cdbf05de955217313e6", + "sha256:0b581f47257a9fce535c4567782a8976002d6b8afa2c39ff616edf87cbeff712", + "sha256:0f8f741b6292c86059ed175d80eefa80997125b7c478fb8769fd9ac8943a16c0", + "sha256:0fc212779bf8411667234b3cdd34d53de6c2b8b8b958e1e12cb473a5f367c338", + "sha256:13c56de6518e14b9bf6edde23c4c39dac5b48dcf04160ea7bce8fca8397cdf86", + "sha256:142c0a5124d9bd0e2976089484af5c74f47bd3298f2ed651ef54ea728d2ea42c", + "sha256:14511a539afee6f9ab492b543060c7491c99924314977a55c98bfa2ee29ce78c", + "sha256:15a842bb369e00295392e7ce192de9dcbf136954614124a667f9f9f17d6a216f", + "sha256:16d4477bcb9fbbd7b5b0e4a5d9b493e42026c0bf1f06f723a9353f5153e75d30", + "sha256:1791ff70bc975b098fe6ecf04356a10e9e2bd7dc21fa7351c1742fdeb9b4966f", + "sha256:19b73643c802f4eaf13d97f7855d0fb527fbc92ab7013c4ad0e13a6ae0ed23bd", + "sha256:200a23239781f46149e6a415f1e870c5ef1e712939fe8fa63035cd053ac2638e", + "sha256:2249280b870e6a42c0d972339e9cc22ee98730a99cd7f2f727549af80dd5a963", + "sha256:2b431c777c9653e569986ecf69ff4a5dba281cded16043d348bf9ba505486f36", + "sha256:2cc3712a4b0b76a1d45a9302dd2f53ff339614b1c29603a911318f2357b04dd2", + "sha256:2fbb0ffc754490aff6dabbf28064be47f0f9ca0b9755976f945214965b3ace7e", + "sha256:32b922e13d4c0080d03e7b62991ad7f5007d9cd74e239c4b16bc85ae8b70252d", + "sha256:36785be22066966a27348444b40389f8444671630063edfb1a2eb04318721e17", + "sha256:37fe0f12aebb6a0e3e17bb4cd356b1286d2d18d2e93b2d39fe647138458b4bcb", + "sha256:3aea7eed3e55119635a74bbeb80b35e776bafccb70d97e8ff838816c124539f1", + "sha256:3c6afcf2338e7f374e8edc765c79fbcb4061d02b15dd5f8f314a4af2bdc7feb5", + "sha256:3ccb8ac2d3c71cda472b75af42818981bdacf48d2e21c36331b50b4f16930163", + "sha256:3d089d0b88996df627693639d123c8158cff41c0651f646cd8fd292c7da90eaf", + "sha256:3dd645e2b0dcb0fd05bf58e2e54c13875847687d0b71941ad2e757e5d89d4356", + "sha256:3e310838a5801795207c66c73ea903deda321e6146d6f282e85fa7e3e4854804", + "sha256:42cbde7789f5c0bcd6816cb29808e36c01b960fb5d29f11e052215aa85497c93", + "sha256:483b29f6f7ffa6af845107d4efe2e3fa8fb2693de8657bc1849f674296ff6a5a", + "sha256:4888e117dd41b9d34194d9e31631af70d3d526efc363085e3089ab1a62c32ed1", + "sha256:49fe9b04b6fa685bd39237d45fad89ba19e9163a1ccaa16611a812e682913496", + "sha256:4a5a844f68776a7715ecb30843b453f07ac89bad393431efbf7accca3ef599c1", + "sha256:4a916087371afd9648e1962e67403c53f9c49ca47b9680adbeef79da3a7811b0", + "sha256:4f676e21db2f8c72ff0936f895271e7a700aa1f8d31b40e4e43442ba94973899", + "sha256:518d2ca43c358929bf08f9079b617f1c2ca6e8848f83c1225c88caeac46e6cbc", + "sha256:5265505b3d61a0f56618c9b941dc54dc334dc6e660f1592d112cd103d914a6db", + "sha256:55cd1fa4ecfa6d9f14fbd97ac24803e6f73e897c738f771a9fe038f2f11ff07c", + "sha256:58b1d5dd591973d426cbb2da5e27ba0339209832b2f3315928c9790e13f159e8", + "sha256:59240685e7da61fb78f65a9f07f8108e36a83317c53f7b276b4175dc44151684", + "sha256:5b48e790e0355865197ad0aca8cde3d8ede347831e1959e158369eb3493d2191", + "sha256:5d4eea0761e37485c9b81400437adb11c40e13ef513375bbd6973e34100aeb06", + "sha256:648386ddd1e19b4a6abab69139b002bc49ebf065b596119f8f37c38e9ecee8ff", + "sha256:653647b8838cf83b2e7e6a0364f49af96deec64d2a6578324db58380cff82aca", + "sha256:6740a3e8d43a32629bb9b009017ea5b9e713b7210ba48ac8d4cb6d99d86c8ee8", + "sha256:6889469bfdc1eddf489729b471303739bf04555bb151fe8875931f8564309afc", + "sha256:68cb0a499f2c4a088fd2f521453e22ed3527154136a855c62e148b7883b99f9a", + "sha256:6aa97af1558a9bef4025f8f5d8c60d712e0a3b13a2fe875511defc6ee77a1ab7", + "sha256:6b73c67850ca7cae0f6c56f71e356d7e9fa25958d3e18a64927c2d930859b8e4", + "sha256:6c8e9340ce5a52f95fa7d3b552b35c7e8f3874d74a03a8a69279fd5fca5dc751", + "sha256:6ca91093a4a8da4afae7fe6a222c3b53ee4eef433ebfee4d54978a103435159e", + "sha256:754bbed1a4ca48479e9d4182a561d001bbf81543876cdded6f695ec3d465846b", + "sha256:762703bdd2b30983c1d9e62b4c88664df4a8a4d5ec0e9253b0231171f18f6d75", + "sha256:78f0b6877bfce7a3d1ff150391354a410c55d3cdce386f862926a4958ad5ab7e", + "sha256:7a07ced2b22f0cf0b55a6a510078174c31b6d8544f3bc00c2bcee52b3d613f74", + "sha256:7dca7081e9a0c3b6490a145593f6fe3173a94197f2cb9891183ef75e9d64c425", + "sha256:7e21b7031e17c6b0e445f42ccc77f79a97e2687023c5746bfb7a9e45e0921b84", + "sha256:7f5179583d7a6cdb981151dd349786cbc318bab54963a192692d945dd3f6435d", + "sha256:83cba698cfb3c2c5a7c3c6bac12fe6c6a51aae69513726be6411076185a8b24a", + "sha256:842c19a6ce894493563c3bd00d81d5100e8e57d70209e84d5491940fdb8b9e3a", + "sha256:84b8382a90539910b53a6307f7c35697bc7e6ffb25d9c1d4e998a13e842a5e83", + "sha256:8ba6f89cac95c0900d932c9efb7f0fb6ca47f6687feec41abcb1bd5e2bd45535", + "sha256:8bbe951244a838a51289ee53a6bae3a07f26d4e179b96fc7ddd3301caf0518eb", + "sha256:925d176a549f4832c6f69fa6026071294ab5910e82a0fe6c6228fce17b0706bd", + "sha256:92b68b79c0da2a980b1c4197e56ac3dd0c8a149b4603747c4378914a68706979", + "sha256:93da1d3db08a827eda74356f9f58884adb254e59b6664f64cc04cdff2cc19b0d", + "sha256:95f3b65d2392e1c5cec27cff08fdc0080270d5a1a4b2ea1d51d5f4a2620ff08d", + "sha256:9c4cb04a16b0f199a8c9bf807269b2f63b7b5b11425e4a6bd44bd6961d28282c", + "sha256:a624cc00ef2158e04188df5e3016385b9353638139a06fb77057b3498f794782", + "sha256:a649dfd735fff086e8a9d0503a9f0c7d01b7912a333c7ae77e1515c08c146dad", + "sha256:a94e52537a0e0a85429eda9e49f272ada715506d3b2431f64b8a3e34eb5f3e75", + "sha256:aa7ac11e294304e615b43f8c441fee5d40094275ed7311f3420d805fde9b07b4", + "sha256:b41b6321805c472f66990c2849e152aff7bc359eb92f781e3f606609eac877ad", + "sha256:b71b8666eeea69d6363248822078c075bac6ed135faa9216aa85f295ff009b1e", + "sha256:b9c2fe36d1f758b28121bef29ed1dee9b7a2453e997528e7d1ac99b94892527c", + "sha256:bb63804105143c7e24cee7db89e37cb3f3941f8e80c4379a0b355c52a52b6780", + "sha256:be5ef2f1fc586a7372bfc355986226484e06d1dc4f9402539872c8bb99e34b01", + "sha256:c142b88039b92e7e0cb2552e8967077e3179b22359e945574f5e2764c3953dcf", + "sha256:c14937af98c4cc362a1d4374806204dd51b1e12dded1ae30645c298e5a5c4cb1", + "sha256:ca449520e7484534a2a44faf629362cae62b660601432d04c482283c47eaebab", + "sha256:cd945871335a639275eee904caef90041568ce3b42f402c6959b460d25ae8732", + "sha256:d0b937b2a1988f184a3e9e577adaa8aede21ec0b38320d6009e02bd026db04fa", + "sha256:d126b52e4a473d40232ec2052a8b232270ed1f8c9571aaf33f73a14cc298c24f", + "sha256:d8761c3c891cc51e90bc9926d6d2f59b27beaf86c74622c8979380a29cc23ac3", + "sha256:d9ecb51120de61e4604650666d1f2b68444d46ae18fd492245a08f53ad2b7711", + "sha256:da584ff96ec95e97925174eb8237e32f626e7a1a97888cdd27ee2f1f24dd0ad8", + "sha256:dbcf360c9e3399b056a238523146ea77eeb2a596ce263b8814c900263e46031a", + "sha256:dbddc10776ca7ebf2a299c41a4dde8ea0d8e3547bfd731cb87af2e8f5bf8962d", + "sha256:dc73505153798c6f74854aba69cc75953888cf9866465196889c7cdd351e720c", + "sha256:e13de156137b7095442b288e72f33503a469aa1980ed856b43c353ac86390519", + "sha256:e1791c4aabd117653530dccd24108fa03cc6baf21f58b950d0a73c3b3b29a350", + "sha256:e75ba609dba23f2c95b776efb9dd3f0b78a76a151e96f96cc5b6b1b0004de66f", + "sha256:e79059d67bea28b53d255c1437b25391653263f0e69cd7dec170d778fdbca95e", + "sha256:ecd27a66740ffd621d20b9a2f2b5ee4129a56e27bfb9458a3bcc2e45794c96cb", + "sha256:f009c69bc8c53db5dfab72ac760895dc1f2bc1b62ab7408b253c8d1ec52459fc", + "sha256:f16bc1334853e91ddaaa1217045dd7be166170beec337576818461268a3de67f", + "sha256:f19169781dddae7478a32301b499b2858bc52fc45a112955e798ee307e294977", + "sha256:fa3060d885657abc549b2a0f8e1b79699290e5d83845141717c6c90c2df38311", + "sha256:fa41a64ac5b08b292906e248549ab48b69c5428f3987b09689ab2441f267d04d", + "sha256:fbf15aff64a163db29a91ed0868af181d6f68ec1a3a7d5afcfe4501252840bad", + "sha256:fe00a9057d100e69b4ae4a094203a708d65b0f345ed546fdef86498bf5390982" ], "markers": "python_version >= '3.8'", - "version": "==0.20.0" + "version": "==0.20.1" }, "rsa": { "hashes": [ - "sha256:90260d9058e514786967344d0ef75fa8727eed8a7d2e43ce9f4bcf1b536174f7", - "sha256:e38464a49c6c85d7f1351b0126661487a7e0a14a50f1675ec50eb34d4f20ef21" + "sha256:68635866661c6836b8d39430f97a996acbd61bfa49406748ea243539fe239762", + "sha256:e7bdbfdb5497da4c07dfd35530e1a902659db6ff241e39d9953cad06ebd0ae75" ], "markers": "python_version >= '3.6' and python_version < '4'", - "version": "==4.9" + "version": "==4.9.1" }, "sentry-sdk": { "hashes": [ - "sha256:49139c31ebcd398f4f6396b18910610a0c1602f6e67083240c33019d1f6aa30c", - "sha256:90f733b32e15dfc1999e6b7aca67a38688a567329de4d6e184154a73f96c6892" + "sha256:90f4f883f9eff294aff59af3d58c2d1b64e3927b28d5ada2b9b41f5aeda47daf", + "sha256:c58935bfff8af6a0856d37e8adebdbc7b3281c2b632ec823ef03cd108d216ff0" ], "index": "pypi", - "version": "==2.16.0" + "version": "==2.27.0" }, "six": { "hashes": [ @@ -763,11 +776,11 @@ }, "typing-extensions": { "hashes": [ - "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d", - "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8" + "sha256:a439e7c04b49fec3e5d3e2beaa21755cadbbdc391694e28ccdd36ca4a1408f8c", + "sha256:e6c81219bd689f51865d9e372991c540bda33a0379d5573cddb9a3a23f7caaef" ], "markers": "python_version >= '3.8'", - "version": "==4.12.2" + "version": "==4.13.2" }, "urllib3": { "hashes": [ @@ -787,79 +800,88 @@ }, "wrapt": { "hashes": [ - "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc", - "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81", - "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09", - "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e", - "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca", - "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0", - "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb", - "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487", - "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40", - "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c", - "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060", - "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202", - "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41", - "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9", - "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b", - "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664", - "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d", - "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362", - "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00", - "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc", - "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1", - "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267", - "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956", - "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966", - "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1", - "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228", - "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72", - "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d", - "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292", - "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0", - "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0", - "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36", - "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c", - "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5", - "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f", - "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73", - "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b", - "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2", - "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593", - "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39", - "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389", - "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf", - "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf", - "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89", - "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c", - "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c", - "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f", - "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440", - "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465", - "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136", - "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b", - "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8", - "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3", - "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8", - "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6", - "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e", - "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f", - "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c", - "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e", - "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8", - "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2", - "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020", - "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35", - "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d", - "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3", - "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537", - "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809", - "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d", - "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a", - "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4" + "sha256:08e7ce672e35efa54c5024936e559469436f8b8096253404faeb54d2a878416f", + "sha256:0a6e821770cf99cc586d33833b2ff32faebdbe886bd6322395606cf55153246c", + "sha256:0b929ac182f5ace000d459c59c2c9c33047e20e935f8e39371fa6e3b85d56f4a", + "sha256:129a150f5c445165ff941fc02ee27df65940fcb8a22a61828b1853c98763a64b", + "sha256:13e6afb7fe71fe7485a4550a8844cc9ffbe263c0f1a1eea569bc7091d4898555", + "sha256:1473400e5b2733e58b396a04eb7f35f541e1fb976d0c0724d0223dd607e0f74c", + "sha256:18983c537e04d11cf027fbb60a1e8dfd5190e2b60cc27bc0808e653e7b218d1b", + "sha256:1a7ed2d9d039bd41e889f6fb9364554052ca21ce823580f6a07c4ec245c1f5d6", + "sha256:1e1fe0e6ab7775fd842bc39e86f6dcfc4507ab0ffe206093e76d61cde37225c8", + "sha256:1fb5699e4464afe5c7e65fa51d4f99e0b2eadcc176e4aa33600a3df7801d6662", + "sha256:2696993ee1eebd20b8e4ee4356483c4cb696066ddc24bd70bcbb80fa56ff9061", + "sha256:35621ae4c00e056adb0009f8e86e28eb4a41a4bfa8f9bfa9fca7d343fe94f998", + "sha256:36ccae62f64235cf8ddb682073a60519426fdd4725524ae38874adf72b5f2aeb", + "sha256:3cedbfa9c940fdad3e6e941db7138e26ce8aad38ab5fe9dcfadfed9db7a54e62", + "sha256:3d57c572081fed831ad2d26fd430d565b76aa277ed1d30ff4d40670b1c0dd984", + "sha256:3fc7cb4c1c744f8c05cd5f9438a3caa6ab94ce8344e952d7c45a8ed59dd88392", + "sha256:4011d137b9955791f9084749cba9a367c68d50ab8d11d64c50ba1688c9b457f2", + "sha256:40d615e4fe22f4ad3528448c193b218e077656ca9ccb22ce2cb20db730f8d306", + "sha256:410a92fefd2e0e10d26210e1dfb4a876ddaf8439ef60d6434f21ef8d87efc5b7", + "sha256:41388e9d4d1522446fe79d3213196bd9e3b301a336965b9e27ca2788ebd122f3", + "sha256:468090021f391fe0056ad3e807e3d9034e0fd01adcd3bdfba977b6fdf4213ea9", + "sha256:49703ce2ddc220df165bd2962f8e03b84c89fee2d65e1c24a7defff6f988f4d6", + "sha256:4a721d3c943dae44f8e243b380cb645a709ba5bd35d3ad27bc2ed947e9c68192", + "sha256:4afd5814270fdf6380616b321fd31435a462019d834f83c8611a0ce7484c7317", + "sha256:4c82b8785d98cdd9fed4cac84d765d234ed3251bd6afe34cb7ac523cb93e8b4f", + "sha256:4db983e7bca53819efdbd64590ee96c9213894272c776966ca6306b73e4affda", + "sha256:582530701bff1dec6779efa00c516496968edd851fba224fbd86e46cc6b73563", + "sha256:58455b79ec2661c3600e65c0a716955adc2410f7383755d537584b0de41b1d8a", + "sha256:58705da316756681ad3c9c73fd15499aa4d8c69f9fd38dc8a35e06c12468582f", + "sha256:5bb1d0dbf99411f3d871deb6faa9aabb9d4e744d67dcaaa05399af89d847a91d", + "sha256:5c803c401ea1c1c18de70a06a6f79fcc9c5acfc79133e9869e730ad7f8ad8ef9", + "sha256:5cbabee4f083b6b4cd282f5b817a867cf0b1028c54d445b7ec7cfe6505057cf8", + "sha256:612dff5db80beef9e649c6d803a8d50c409082f1fedc9dbcdfde2983b2025b82", + "sha256:62c2caa1585c82b3f7a7ab56afef7b3602021d6da34fbc1cf234ff139fed3cd9", + "sha256:69606d7bb691b50a4240ce6b22ebb319c1cfb164e5f6569835058196e0f3a845", + "sha256:6d9187b01bebc3875bac9b087948a2bccefe464a7d8f627cf6e48b1bbae30f82", + "sha256:6ed6ffac43aecfe6d86ec5b74b06a5be33d5bb9243d055141e8cabb12aa08125", + "sha256:703919b1633412ab54bcf920ab388735832fdcb9f9a00ae49387f0fe67dad504", + "sha256:766d8bbefcb9e00c3ac3b000d9acc51f1b399513f44d77dfe0eb026ad7c9a19b", + "sha256:80dd7db6a7cb57ffbc279c4394246414ec99537ae81ffd702443335a61dbf3a7", + "sha256:8112e52c5822fc4253f3901b676c55ddf288614dc7011634e2719718eaa187dc", + "sha256:8c8b293cd65ad716d13d8dd3624e42e5a19cc2a2f1acc74b30c2c13f15cb61a6", + "sha256:8fdbdb757d5390f7c675e558fd3186d590973244fab0c5fe63d373ade3e99d40", + "sha256:91bd7d1773e64019f9288b7a5101f3ae50d3d8e6b1de7edee9c2ccc1d32f0c0a", + "sha256:95c658736ec15602da0ed73f312d410117723914a5c91a14ee4cdd72f1d790b3", + "sha256:99039fa9e6306880572915728d7f6c24a86ec57b0a83f6b2491e1d8ab0235b9a", + "sha256:9a2bce789a5ea90e51a02dfcc39e31b7f1e662bc3317979aa7e5538e3a034f72", + "sha256:9a7d15bbd2bc99e92e39f49a04653062ee6085c0e18b3b7512a4f2fe91f2d681", + "sha256:9abc77a4ce4c6f2a3168ff34b1da9b0f311a8f1cfd694ec96b0603dff1c79438", + "sha256:9e8659775f1adf02eb1e6f109751268e493c73716ca5761f8acb695e52a756ae", + "sha256:9fee687dce376205d9a494e9c121e27183b2a3df18037f89d69bd7b35bcf59e2", + "sha256:a5aaeff38654462bc4b09023918b7f21790efb807f54c000a39d41d69cf552cb", + "sha256:a604bf7a053f8362d27eb9fefd2097f82600b856d5abe996d623babd067b1ab5", + "sha256:abbb9e76177c35d4e8568e58650aa6926040d6a9f6f03435b7a522bf1c487f9a", + "sha256:acc130bc0375999da18e3d19e5a86403667ac0c4042a094fefb7eec8ebac7cf3", + "sha256:b18f2d1533a71f069c7f82d524a52599053d4c7166e9dd374ae2136b7f40f7c8", + "sha256:b4e42a40a5e164cbfdb7b386c966a588b1047558a990981ace551ed7e12ca9c2", + "sha256:b5e251054542ae57ac7f3fba5d10bfff615b6c2fb09abeb37d2f1463f841ae22", + "sha256:b60fb58b90c6d63779cb0c0c54eeb38941bae3ecf7a73c764c52c88c2dcb9d72", + "sha256:b870b5df5b71d8c3359d21be8f0d6c485fa0ebdb6477dda51a1ea54a9b558061", + "sha256:ba0f0eb61ef00ea10e00eb53a9129501f52385c44853dbd6c4ad3f403603083f", + "sha256:bb87745b2e6dc56361bfde481d5a378dc314b252a98d7dd19a651a3fa58f24a9", + "sha256:bb90fb8bda722a1b9d48ac1e6c38f923ea757b3baf8ebd0c82e09c5c1a0e7a04", + "sha256:bc570b5f14a79734437cb7b0500376b6b791153314986074486e0b0fa8d71d98", + "sha256:c86563182421896d73858e08e1db93afdd2b947a70064b813d515d66549e15f9", + "sha256:c958bcfd59bacc2d0249dcfe575e71da54f9dcf4a8bdf89c4cb9a68a1170d73f", + "sha256:d18a4865f46b8579d44e4fe1e2bcbc6472ad83d98e22a26c963d46e4c125ef0b", + "sha256:d5e2439eecc762cd85e7bd37161d4714aa03a33c5ba884e26c81559817ca0925", + "sha256:e3890b508a23299083e065f435a492b5435eba6e304a7114d2f919d400888cc6", + "sha256:e496a8ce2c256da1eb98bd15803a79bee00fc351f5dfb9ea82594a3f058309e0", + "sha256:e8b2816ebef96d83657b56306152a93909a83f23994f4b30ad4573b00bd11bb9", + "sha256:eaf675418ed6b3b31c7a989fd007fa7c3be66ce14e5c3b27336383604c9da85c", + "sha256:ec89ed91f2fa8e3f52ae53cd3cf640d6feff92ba90d62236a81e4e563ac0e991", + "sha256:ecc840861360ba9d176d413a5489b9a0aff6d6303d7e733e2c4623cfa26904a6", + "sha256:f09b286faeff3c750a879d336fb6d8713206fc97af3adc14def0cdd349df6000", + "sha256:f393cda562f79828f38a819f4788641ac7c4085f30f1ce1a68672baa686482bb", + "sha256:f917c1180fdb8623c2b75a99192f4025e412597c50b2ac870f156de8fb101119", + "sha256:fc78a84e2dfbc27afe4b2bd7c80c8db9bca75cc5b85df52bfe634596a1da846b", + "sha256:ff04ef6eec3eee8a5efef2401495967a916feaa353643defcc03fc74fe213b58" ], - "markers": "python_version >= '3.6'", - "version": "==1.16.0" + "markers": "python_version >= '3.8'", + "version": "==1.17.2" }, "zipp": { "hashes": [ @@ -873,19 +895,19 @@ "develop": { "alembic": { "hashes": [ - "sha256:203503117415561e203aa14541740643a611f641517f0209fcae63e9fa09f1a2", - "sha256:908e905976d15235fae59c9ac42c4c5b75cfcefe3d27c0fbf7ae15a37715d80e" + "sha256:1acdd7a3a478e208b0503cd73614d5e4c6efafa4e73518bb60e4f2846a37b1c5", + "sha256:496e888245a53adf1498fcab31713a469c65836f8de76e01399aa1c3e90dd213" ], "markers": "python_version >= '3.8'", - "version": "==1.13.3" + "version": "==1.14.1" }, "click": { "hashes": [ - "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28", - "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de" + "sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2", + "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a" ], "markers": "python_version >= '3.7'", - "version": "==8.1.7" + "version": "==8.1.8" }, "flask": { "hashes": [ @@ -897,11 +919,11 @@ }, "flask-migrate": { "hashes": [ - "sha256:5c532be17e7b43a223b7500d620edae33795df27c75811ddf32560f7d48ec617", - "sha256:dff7dd25113c210b069af280ea713b883f3840c1e3455274745d7355778c8622" + "sha256:1a336b06eb2c3ace005f5f2ded8641d534c18798d64061f6ff11f79e1434126d", + "sha256:24d8051af161782e0743af1b04a152d007bad9772b2bca67b7ec1e8ceeb3910d" ], "index": "pypi", - "version": "==4.0.7" + "version": "==4.1.0" }, "flask-sqlalchemy": { "hashes": [ @@ -937,19 +959,19 @@ }, "jinja2": { "hashes": [ - "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369", - "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d" + "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d", + "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67" ], "markers": "python_version >= '3.7'", - "version": "==3.1.4" + "version": "==3.1.6" }, "mako": { "hashes": [ - "sha256:260f1dbc3a519453a9c856dedfe4beb4e50bd5a26d96386cb6c80856556bb91a", - "sha256:48dbc20568c1d276a2698b36d968fa76161bf127194907ea6fc594fa81f943bc" + "sha256:99579a6f39583fa7e5630a28c3c1f440e4e97a414b80372649c0ce338da2ea28", + "sha256:baef24a52fc4fc514a0887ac600f9f1cff3d82c61d4d700a1fa84d597b88db59" ], "markers": "python_version >= '3.8'", - "version": "==1.3.5" + "version": "==1.3.10" }, "markupsafe": { "hashes": [ @@ -1059,11 +1081,11 @@ }, "typing-extensions": { "hashes": [ - "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d", - "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8" + "sha256:a439e7c04b49fec3e5d3e2beaa21755cadbbdc391694e28ccdd36ca4a1408f8c", + "sha256:e6c81219bd689f51865d9e372991c540bda33a0379d5573cddb9a3a23f7caaef" ], "markers": "python_version >= '3.8'", - "version": "==4.12.2" + "version": "==4.13.2" }, "werkzeug": { "hashes": [ From a303d0d6559712f1cd9994c8cb96702024d61e43 Mon Sep 17 00:00:00 2001 From: Adrian Edwards Date: Wed, 21 May 2025 10:25:23 +0200 Subject: [PATCH 200/206] add some swap space to fly config to try and fix the memory issue https://community.fly.io/t/ran-out-of-memory-and-crashed/19312/3 --- fly.toml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fly.toml b/fly.toml index 0479895..b313750 100644 --- a/fly.toml +++ b/fly.toml @@ -6,6 +6,8 @@ app = "classclockapi" primary_region = "den" +swap_size_mb = 512 + [http_service] internal_port = 8000 force_https = true From 49b5c931e686511fb987af72540d6d5047bb4baf Mon Sep 17 00:00:00 2001 From: Adrian Edwards Date: Wed, 21 May 2025 23:15:09 +0200 Subject: [PATCH 201/206] ignore more sensitive files in dockerignore --- .dockerignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.dockerignore b/.dockerignore index 9263423..2de57b2 100644 --- a/.dockerignore +++ b/.dockerignore @@ -9,4 +9,5 @@ tests/ .vscode/ __pycache__/ -.pytest_cache \ No newline at end of file +.pytest_cache +*.env \ No newline at end of file From 48811ed02904fda0074d71bf8849a00201be9ad3 Mon Sep 17 00:00:00 2001 From: Adrian Edwards Date: Wed, 21 May 2025 23:19:49 +0200 Subject: [PATCH 202/206] ignore virtual environments - make the container build its own --- .dockerignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.dockerignore b/.dockerignore index 2de57b2..18217f5 100644 --- a/.dockerignore +++ b/.dockerignore @@ -10,4 +10,5 @@ tests/ .vscode/ __pycache__/ .pytest_cache -*.env \ No newline at end of file +*.env +.venv \ No newline at end of file From ddbee5587c84cd2c286489ecb3006a26b7814ff7 Mon Sep 17 00:00:00 2001 From: Adrian Edwards Date: Wed, 21 May 2025 23:41:20 +0200 Subject: [PATCH 203/206] reduce to 1 worker to help reduce memory usage --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 0229ded..0cddf9c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -11,4 +11,4 @@ RUN pipenv install COPY . /classclock-api/ -ENTRYPOINT pipenv run gunicorn --workers 2 --bind 0.0.0.0 api:app +ENTRYPOINT pipenv run gunicorn --workers 1 --bind 0.0.0.0 api:app From 96995e3ed6b1f641e47992096600e4c474733926 Mon Sep 17 00:00:00 2001 From: Adrian Edwards Date: Wed, 3 Sep 2025 18:06:05 -0400 Subject: [PATCH 204/206] limit flask-migrate to the previous major version so flask migration still works https://github.com/miguelgrinberg/Flask-Migrate/discussions/558 --- Pipfile | 2 +- Pipfile.lock | 381 +++++++++++++++++++++++++-------------------------- 2 files changed, 186 insertions(+), 197 deletions(-) diff --git a/Pipfile b/Pipfile index c58ad49..aa3f98b 100644 --- a/Pipfile +++ b/Pipfile @@ -23,7 +23,7 @@ apispec-webframeworks = "~=0.5.2" mysql-connector-python = "8.0.24" python-jose = "*" python-dotenv = "*" -flask-migrate = "*" +flask-migrate = "~=3.0.0" requests = "*" sentry-sdk = "*" psycopg2-binary = "*" diff --git a/Pipfile.lock b/Pipfile.lock index cd2195a..669102b 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "56eb6e6a11a300d1ab875ccf88bd3a500155830693ba419558ef64bb34f1b7db" + "sha256": "f2e8690265236431a4831c0145e3a83db4636b070b8373468c1bef2ca5a3d4f3" }, "pipfile-spec": 6, "requires": { @@ -50,109 +50,96 @@ }, "certifi": { "hashes": [ - "sha256:0a816057ea3cdefcef70270d2c515e4506bbc954f417fa5ade2021213bb8f0c6", - "sha256:30350364dfe371162649852c63336a15c70c6510c2ad5015b21c2345311805f3" + "sha256:e564105f78ded564e3ae7c923924435e1daa7463faeab5bb932bc53ffae63407", + "sha256:f6c12493cfb1b06ba2ff328595af9350c65d6644968e5d3a2ffd78699af217a5" ], - "markers": "python_version >= '3.6'", - "version": "==2025.4.26" + "markers": "python_version >= '3.7'", + "version": "==2025.8.3" }, "charset-normalizer": { "hashes": [ - "sha256:005fa3432484527f9732ebd315da8da8001593e2cf46a3d817669f062c3d9ed4", - "sha256:046595208aae0120559a67693ecc65dd75d46f7bf687f159127046628178dc45", - "sha256:0c29de6a1a95f24b9a1aa7aefd27d2487263f00dfd55a77719b530788f75cff7", - "sha256:0c8c57f84ccfc871a48a47321cfa49ae1df56cd1d965a09abe84066f6853b9c0", - "sha256:0f5d9ed7f254402c9e7d35d2f5972c9bbea9040e99cd2861bd77dc68263277c7", - "sha256:18dd2e350387c87dabe711b86f83c9c78af772c748904d372ade190b5c7c9d4d", - "sha256:1b1bde144d98e446b056ef98e59c256e9294f6b74d7af6846bf5ffdafd687a7d", - "sha256:1c95a1e2902a8b722868587c0e1184ad5c55631de5afc0eb96bc4b0d738092c0", - "sha256:1cad5f45b3146325bb38d6855642f6fd609c3f7cad4dbaf75549bf3b904d3184", - "sha256:21b2899062867b0e1fde9b724f8aecb1af14f2778d69aacd1a5a1853a597a5db", - "sha256:24498ba8ed6c2e0b56d4acbf83f2d989720a93b41d712ebd4f4979660db4417b", - "sha256:25a23ea5c7edc53e0f29bae2c44fcb5a1aa10591aae107f2a2b2583a9c5cbc64", - "sha256:289200a18fa698949d2b39c671c2cc7a24d44096784e76614899a7ccf2574b7b", - "sha256:28a1005facc94196e1fb3e82a3d442a9d9110b8434fc1ded7a24a2983c9888d8", - "sha256:32fc0341d72e0f73f80acb0a2c94216bd704f4f0bce10aedea38f30502b271ff", - "sha256:36b31da18b8890a76ec181c3cf44326bf2c48e36d393ca1b72b3f484113ea344", - "sha256:3c21d4fca343c805a52c0c78edc01e3477f6dd1ad7c47653241cf2a206d4fc58", - "sha256:3fddb7e2c84ac87ac3a947cb4e66d143ca5863ef48e4a5ecb83bd48619e4634e", - "sha256:43e0933a0eff183ee85833f341ec567c0980dae57c464d8a508e1b2ceb336471", - "sha256:4a476b06fbcf359ad25d34a057b7219281286ae2477cc5ff5e3f70a246971148", - "sha256:4e594135de17ab3866138f496755f302b72157d115086d100c3f19370839dd3a", - "sha256:50bf98d5e563b83cc29471fa114366e6806bc06bc7a25fd59641e41445327836", - "sha256:5a9979887252a82fefd3d3ed2a8e3b937a7a809f65dcb1e068b090e165bbe99e", - "sha256:5baececa9ecba31eff645232d59845c07aa030f0c81ee70184a90d35099a0e63", - "sha256:5bf4545e3b962767e5c06fe1738f951f77d27967cb2caa64c28be7c4563e162c", - "sha256:6333b3aa5a12c26b2a4d4e7335a28f1475e0e5e17d69d55141ee3cab736f66d1", - "sha256:65c981bdbd3f57670af8b59777cbfae75364b483fa8a9f420f08094531d54a01", - "sha256:68a328e5f55ec37c57f19ebb1fdc56a248db2e3e9ad769919a58672958e8f366", - "sha256:6a0289e4589e8bdfef02a80478f1dfcb14f0ab696b5a00e1f4b8a14a307a3c58", - "sha256:6b66f92b17849b85cad91259efc341dce9c1af48e2173bf38a85c6329f1033e5", - "sha256:6c9379d65defcab82d07b2a9dfbfc2e95bc8fe0ebb1b176a3190230a3ef0e07c", - "sha256:6fc1f5b51fa4cecaa18f2bd7a003f3dd039dd615cd69a2afd6d3b19aed6775f2", - "sha256:70f7172939fdf8790425ba31915bfbe8335030f05b9913d7ae00a87d4395620a", - "sha256:721c76e84fe669be19c5791da68232ca2e05ba5185575086e384352e2c309597", - "sha256:7222ffd5e4de8e57e03ce2cef95a4c43c98fcb72ad86909abdfc2c17d227fc1b", - "sha256:75d10d37a47afee94919c4fab4c22b9bc2a8bf7d4f46f87363bcf0573f3ff4f5", - "sha256:76af085e67e56c8816c3ccf256ebd136def2ed9654525348cfa744b6802b69eb", - "sha256:770cab594ecf99ae64c236bc9ee3439c3f46be49796e265ce0cc8bc17b10294f", - "sha256:7a6ab32f7210554a96cd9e33abe3ddd86732beeafc7a28e9955cdf22ffadbab0", - "sha256:7c48ed483eb946e6c04ccbe02c6b4d1d48e51944b6db70f697e089c193404941", - "sha256:7f56930ab0abd1c45cd15be65cc741c28b1c9a34876ce8c17a2fa107810c0af0", - "sha256:8075c35cd58273fee266c58c0c9b670947c19df5fb98e7b66710e04ad4e9ff86", - "sha256:8272b73e1c5603666618805fe821edba66892e2870058c94c53147602eab29c7", - "sha256:82d8fd25b7f4675d0c47cf95b594d4e7b158aca33b76aa63d07186e13c0e0ab7", - "sha256:844da2b5728b5ce0e32d863af26f32b5ce61bc4273a9c720a9f3aa9df73b1455", - "sha256:8755483f3c00d6c9a77f490c17e6ab0c8729e39e6390328e42521ef175380ae6", - "sha256:915f3849a011c1f593ab99092f3cecfcb4d65d8feb4a64cf1bf2d22074dc0ec4", - "sha256:926ca93accd5d36ccdabd803392ddc3e03e6d4cd1cf17deff3b989ab8e9dbcf0", - "sha256:982bb1e8b4ffda883b3d0a521e23abcd6fd17418f6d2c4118d257a10199c0ce3", - "sha256:98f862da73774290f251b9df8d11161b6cf25b599a66baf087c1ffe340e9bfd1", - "sha256:9cbfacf36cb0ec2897ce0ebc5d08ca44213af24265bd56eca54bee7923c48fd6", - "sha256:a370b3e078e418187da8c3674eddb9d983ec09445c99a3a263c2011993522981", - "sha256:a955b438e62efdf7e0b7b52a64dc5c3396e2634baa62471768a64bc2adb73d5c", - "sha256:aa6af9e7d59f9c12b33ae4e9450619cf2488e2bbe9b44030905877f0b2324980", - "sha256:aa88ca0b1932e93f2d961bf3addbb2db902198dca337d88c89e1559e066e7645", - "sha256:aaeeb6a479c7667fbe1099af9617c83aaca22182d6cf8c53966491a0f1b7ffb7", - "sha256:aaf27faa992bfee0264dc1f03f4c75e9fcdda66a519db6b957a3f826e285cf12", - "sha256:b2680962a4848b3c4f155dc2ee64505a9c57186d0d56b43123b17ca3de18f0fa", - "sha256:b2d318c11350e10662026ad0eb71bb51c7812fc8590825304ae0bdd4ac283acd", - "sha256:b33de11b92e9f75a2b545d6e9b6f37e398d86c3e9e9653c4864eb7e89c5773ef", - "sha256:b3daeac64d5b371dea99714f08ffc2c208522ec6b06fbc7866a450dd446f5c0f", - "sha256:be1e352acbe3c78727a16a455126d9ff83ea2dfdcbc83148d2982305a04714c2", - "sha256:bee093bf902e1d8fc0ac143c88902c3dfc8941f7ea1d6a8dd2bcb786d33db03d", - "sha256:c72fbbe68c6f32f251bdc08b8611c7b3060612236e960ef848e0a517ddbe76c5", - "sha256:c9e36a97bee9b86ef9a1cf7bb96747eb7a15c2f22bdb5b516434b00f2a599f02", - "sha256:cddf7bd982eaa998934a91f69d182aec997c6c468898efe6679af88283b498d3", - "sha256:cf713fe9a71ef6fd5adf7a79670135081cd4431c2943864757f0fa3a65b1fafd", - "sha256:d11b54acf878eef558599658b0ffca78138c8c3655cf4f3a4a673c437e67732e", - "sha256:d41c4d287cfc69060fa91cae9683eacffad989f1a10811995fa309df656ec214", - "sha256:d524ba3f1581b35c03cb42beebab4a13e6cdad7b36246bd22541fa585a56cccd", - "sha256:daac4765328a919a805fa5e2720f3e94767abd632ae410a9062dff5412bae65a", - "sha256:db4c7bf0e07fc3b7d89ac2a5880a6a8062056801b83ff56d8464b70f65482b6c", - "sha256:dc7039885fa1baf9be153a0626e337aa7ec8bf96b0128605fb0d77788ddc1681", - "sha256:dccab8d5fa1ef9bfba0590ecf4d46df048d18ffe3eec01eeb73a42e0d9e7a8ba", - "sha256:dedb8adb91d11846ee08bec4c8236c8549ac721c245678282dcb06b221aab59f", - "sha256:e45ba65510e2647721e35323d6ef54c7974959f6081b58d4ef5d87c60c84919a", - "sha256:e53efc7c7cee4c1e70661e2e112ca46a575f90ed9ae3fef200f2a25e954f4b28", - "sha256:e635b87f01ebc977342e2697d05b56632f5f879a4f15955dfe8cef2448b51691", - "sha256:e70e990b2137b29dc5564715de1e12701815dacc1d056308e2b17e9095372a82", - "sha256:e8082b26888e2f8b36a042a58307d5b917ef2b1cacab921ad3323ef91901c71a", - "sha256:e8323a9b031aa0393768b87f04b4164a40037fb2a3c11ac06a03ffecd3618027", - "sha256:e92fca20c46e9f5e1bb485887d074918b13543b1c2a1185e69bb8d17ab6236a7", - "sha256:eb30abc20df9ab0814b5a2524f23d75dcf83cde762c161917a2b4b7b55b1e518", - "sha256:eba9904b0f38a143592d9fc0e19e2df0fa2e41c3c3745554761c5f6447eedabf", - "sha256:ef8de666d6179b009dce7bcb2ad4c4a779f113f12caf8dc77f0162c29d20490b", - "sha256:efd387a49825780ff861998cd959767800d54f8308936b21025326de4b5a42b9", - "sha256:f0aa37f3c979cf2546b73e8222bbfa3dc07a641585340179d768068e3455e544", - "sha256:f4074c5a429281bf056ddd4c5d3b740ebca4d43ffffe2ef4bf4d2d05114299da", - "sha256:f69a27e45c43520f5487f27627059b64aaf160415589230992cec34c5e18a509", - "sha256:fb707f3e15060adf5b7ada797624a6c6e0138e2a26baa089df64c68ee98e040f", - "sha256:fcbe676a55d7445b22c10967bceaaf0ee69407fbe0ece4d032b6eb8d4565982a", - "sha256:fdb20a30fe1175ecabed17cbf7812f7b804b8a315a25f24678bcdf120a90077f" + "sha256:00237675befef519d9af72169d8604a067d92755e84fe76492fef5441db05b91", + "sha256:02425242e96bcf29a49711b0ca9f37e451da7c70562bc10e8ed992a5a7a25cc0", + "sha256:027b776c26d38b7f15b26a5da1044f376455fb3766df8fc38563b4efbc515154", + "sha256:07a0eae9e2787b586e129fdcbe1af6997f8d0e5abaa0bc98c0e20e124d67e601", + "sha256:0cacf8f7297b0c4fcb74227692ca46b4a5852f8f4f24b3c766dd94a1075c4884", + "sha256:0e78314bdc32fa80696f72fa16dc61168fda4d6a0c014e0380f9d02f0e5d8a07", + "sha256:0f2be7e0cf7754b9a30eb01f4295cc3d4358a479843b31f328afd210e2c7598c", + "sha256:13faeacfe61784e2559e690fc53fa4c5ae97c6fcedb8eb6fb8d0a15b475d2c64", + "sha256:14c2a87c65b351109f6abfc424cab3927b3bdece6f706e4d12faaf3d52ee5efe", + "sha256:1606f4a55c0fd363d754049cdf400175ee96c992b1f8018b993941f221221c5f", + "sha256:16a8770207946ac75703458e2c743631c79c59c5890c80011d536248f8eaa432", + "sha256:18343b2d246dc6761a249ba1fb13f9ee9a2bcd95decc767319506056ea4ad4dc", + "sha256:18b97b8404387b96cdbd30ad660f6407799126d26a39ca65729162fd810a99aa", + "sha256:1bb60174149316da1c35fa5233681f7c0f9f514509b8e399ab70fea5f17e45c9", + "sha256:1e8ac75d72fa3775e0b7cb7e4629cec13b7514d928d15ef8ea06bca03ef01cae", + "sha256:1ef99f0456d3d46a50945c98de1774da86f8e992ab5c77865ea8b8195341fc19", + "sha256:2001a39612b241dae17b4687898843f254f8748b796a2e16f1051a17078d991d", + "sha256:23b6b24d74478dc833444cbd927c338349d6ae852ba53a0d02a2de1fce45b96e", + "sha256:252098c8c7a873e17dd696ed98bbe91dbacd571da4b87df3736768efa7a792e4", + "sha256:257f26fed7d7ff59921b78244f3cd93ed2af1800ff048c33f624c87475819dd7", + "sha256:2c322db9c8c89009a990ef07c3bcc9f011a3269bc06782f916cd3d9eed7c9312", + "sha256:30a96e1e1f865f78b030d65241c1ee850cdf422d869e9028e2fc1d5e4db73b92", + "sha256:30d006f98569de3459c2fc1f2acde170b7b2bd265dc1943e87e1a4efe1b67c31", + "sha256:31a9a6f775f9bcd865d88ee350f0ffb0e25936a7f930ca98995c05abf1faf21c", + "sha256:320e8e66157cc4e247d9ddca8e21f427efc7a04bbd0ac8a9faf56583fa543f9f", + "sha256:34a7f768e3f985abdb42841e20e17b330ad3aaf4bb7e7aeeb73db2e70f077b99", + "sha256:3653fad4fe3ed447a596ae8638b437f827234f01a8cd801842e43f3d0a6b281b", + "sha256:3cd35b7e8aedeb9e34c41385fda4f73ba609e561faedfae0a9e75e44ac558a15", + "sha256:3cfb2aad70f2c6debfbcb717f23b7eb55febc0bb23dcffc0f076009da10c6392", + "sha256:416175faf02e4b0810f1f38bcb54682878a4af94059a1cd63b8747244420801f", + "sha256:41d1fc408ff5fdfb910200ec0e74abc40387bccb3252f3f27c0676731df2b2c8", + "sha256:42e5088973e56e31e4fa58eb6bd709e42fc03799c11c42929592889a2e54c491", + "sha256:4ca4c094de7771a98d7fbd67d9e5dbf1eb73efa4f744a730437d8a3a5cf994f0", + "sha256:511729f456829ef86ac41ca78c63a5cb55240ed23b4b737faca0eb1abb1c41bc", + "sha256:53cd68b185d98dde4ad8990e56a58dea83a4162161b1ea9272e5c9182ce415e0", + "sha256:585f3b2a80fbd26b048a0be90c5aae8f06605d3c92615911c3a2b03a8a3b796f", + "sha256:5b413b0b1bfd94dbf4023ad6945889f374cd24e3f62de58d6bb102c4d9ae534a", + "sha256:5d8d01eac18c423815ed4f4a2ec3b439d654e55ee4ad610e153cf02faf67ea40", + "sha256:6aab0f181c486f973bc7262a97f5aca3ee7e1437011ef0c2ec04b5a11d16c927", + "sha256:6cf8fd4c04756b6b60146d98cd8a77d0cdae0e1ca20329da2ac85eed779b6849", + "sha256:6fb70de56f1859a3f71261cbe41005f56a7842cc348d3aeb26237560bfa5e0ce", + "sha256:6fce4b8500244f6fcb71465d4a4930d132ba9ab8e71a7859e6a5d59851068d14", + "sha256:70bfc5f2c318afece2f5838ea5e4c3febada0be750fcf4775641052bbba14d05", + "sha256:73dc19b562516fc9bcf6e5d6e596df0b4eb98d87e4f79f3ae71840e6ed21361c", + "sha256:74d77e25adda8581ffc1c720f1c81ca082921329452eba58b16233ab1842141c", + "sha256:78deba4d8f9590fe4dae384aeff04082510a709957e968753ff3c48399f6f92a", + "sha256:86df271bf921c2ee3818f0522e9a5b8092ca2ad8b065ece5d7d9d0e9f4849bcc", + "sha256:88ab34806dea0671532d3f82d82b85e8fc23d7b2dd12fa837978dad9bb392a34", + "sha256:8999f965f922ae054125286faf9f11bc6932184b93011d138925a1773830bbe9", + "sha256:8dcfc373f888e4fb39a7bc57e93e3b845e7f462dacc008d9749568b1c4ece096", + "sha256:939578d9d8fd4299220161fdd76e86c6a251987476f5243e8864a7844476ba14", + "sha256:96b2b3d1a83ad55310de8c7b4a2d04d9277d5591f40761274856635acc5fcb30", + "sha256:a2d08ac246bb48479170408d6c19f6385fa743e7157d716e144cad849b2dd94b", + "sha256:b256ee2e749283ef3ddcff51a675ff43798d92d746d1a6e4631bf8c707d22d0b", + "sha256:b5e3b2d152e74e100a9e9573837aba24aab611d39428ded46f4e4022ea7d1942", + "sha256:b89bc04de1d83006373429975f8ef9e7932534b8cc9ca582e4db7d20d91816db", + "sha256:bd28b817ea8c70215401f657edef3a8aa83c29d447fb0b622c35403780ba11d5", + "sha256:c60e092517a73c632ec38e290eba714e9627abe9d301c8c8a12ec32c314a2a4b", + "sha256:c6dbd0ccdda3a2ba7c2ecd9d77b37f3b5831687d8dc1b6ca5f56a4880cc7b7ce", + "sha256:c6e490913a46fa054e03699c70019ab869e990270597018cef1d8562132c2669", + "sha256:c6f162aabe9a91a309510d74eeb6507fab5fff92337a15acbe77753d88d9dcf0", + "sha256:c6fd51128a41297f5409deab284fecbe5305ebd7e5a1f959bee1c054622b7018", + "sha256:cc34f233c9e71701040d772aa7490318673aa7164a0efe3172b2981218c26d93", + "sha256:cc9370a2da1ac13f0153780040f465839e6cccb4a1e44810124b4e22483c93fe", + "sha256:ccf600859c183d70eb47e05a44cd80a4ce77394d1ac0f79dbd2dd90a69a3a049", + "sha256:ce571ab16d890d23b5c278547ba694193a45011ff86a9162a71307ed9f86759a", + "sha256:cf1ebb7d78e1ad8ec2a8c4732c7be2e736f6e5123a4146c5b89c9d1f585f8cef", + "sha256:d0e909868420b7049dafd3a31d45125b31143eec59235311fc4c57ea26a4acd2", + "sha256:d22dbedd33326a4a5190dd4fe9e9e693ef12160c77382d9e87919bce54f3d4ca", + "sha256:d716a916938e03231e86e43782ca7878fb602a125a91e7acb8b5112e2e96ac16", + "sha256:d79c198e27580c8e958906f803e63cddb77653731be08851c7df0b1a14a8fc0f", + "sha256:d95bfb53c211b57198bb91c46dd5a2d8018b3af446583aab40074bf7988401cb", + "sha256:e28e334d3ff134e88989d90ba04b47d84382a828c061d0d1027b1b12a62b39b1", + "sha256:ec557499516fc90fd374bf2e32349a2887a876fbf162c160e3c01b6849eaf557", + "sha256:fb6fecfd65564f208cbf0fba07f107fb661bcd1a7c389edbced3f7a493f70e37", + "sha256:fb731e5deb0c7ef82d698b0f4c5bb724633ee2a489401594c5c88b02e6cb15f7", + "sha256:fb7f67a1bfa6e40b438170ebdc8158b78dc465a5a67b6dde178a46987b244a72", + "sha256:fd10de089bcdcd1be95a2f73dbe6254798ec1bda9f450d5828c96f93e2536b9c", + "sha256:fdabf8315679312cfa71302f9bd509ded4f2f263fb5b765cf1433b39106c3cc9" ], "markers": "python_version >= '3.7'", - "version": "==3.4.2" + "version": "==3.4.3" }, "click": { "hashes": [ @@ -219,11 +206,11 @@ }, "flask-migrate": { "hashes": [ - "sha256:1a336b06eb2c3ace005f5f2ded8641d534c18798d64061f6ff11f79e1434126d", - "sha256:24d8051af161782e0743af1b04a152d007bad9772b2bca67b7ec1e8ceeb3910d" + "sha256:4d42e8f861d78cb6e9319afcba5bf76062e5efd7784184dd2a1cccd9de34a702", + "sha256:df9043d2050df3c0e0f6313f6b529b62c837b6033c20335e9d0b4acdf2c40e23" ], "index": "pypi", - "version": "==4.1.0" + "version": "==3.0.1" }, "flask-sqlalchemy": { "hashes": [ @@ -413,11 +400,11 @@ }, "mistune": { "hashes": [ - "sha256:1a32314113cff28aa6432e99e522677c8587fd83e3d51c29b82a52409c842bd9", - "sha256:a7035c21782b2becb6be62f8f25d3df81ccb4d6fa477a6525b15af06539f02a0" + "sha256:93691da911e5d9d2e23bc54472892aff676df27a75274962ff9edc210364266d", + "sha256:b5a7f801d389f724ec702840c11d8fc48f2b33519102fc7ee739e8177b672164" ], "markers": "python_version >= '3.8'", - "version": "==3.1.3" + "version": "==3.1.4" }, "mysql-connector-python": { "hashes": [ @@ -570,11 +557,11 @@ }, "pygments": { "hashes": [ - "sha256:61c16d2a8576dc0649d9f39e089b5f02bcd27fba10d8fb4dcc28173f7a45151f", - "sha256:9ea1544ad55cecf4b8242fab6dd35a93bbce657034b0611ee383099054ab6d8c" + "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887", + "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b" ], "markers": "python_version >= '3.8'", - "version": "==2.19.1" + "version": "==2.19.2" }, "python-dotenv": { "hashes": [ @@ -661,11 +648,11 @@ }, "requests": { "hashes": [ - "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760", - "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6" + "sha256:27babd3cda2a6d50b30443204ee89830707d396671944c998b5975b031ac2b2c", + "sha256:27d0316682c8a29834d3264820024b62a36942083d52caf2f14c0591336d3422" ], "index": "pypi", - "version": "==2.32.3" + "version": "==2.32.4" }, "rich": { "hashes": [ @@ -794,11 +781,11 @@ }, "sentry-sdk": { "hashes": [ - "sha256:8d4a0206b95fa5fe85e5e7517ed662e3888374bdc342c00e435e10e6d831aa6d", - "sha256:90862fe0616ded4572da6c9dadb363121a1ae49a49e21c418f0634e9d10b4c19" + "sha256:38c98e3cbb620dd3dd80a8d6e39c753d453dd41f8a9df581b0584c19a52bc926", + "sha256:e9e8f3c795044beb59f2c8f4c6b9b0f9779e5e604099882df05eec525e782cc6" ], "index": "pypi", - "version": "==2.29.1" + "version": "==2.35.2" }, "six": { "hashes": [ @@ -874,88 +861,90 @@ }, "wrapt": { "hashes": [ - "sha256:08e7ce672e35efa54c5024936e559469436f8b8096253404faeb54d2a878416f", - "sha256:0a6e821770cf99cc586d33833b2ff32faebdbe886bd6322395606cf55153246c", - "sha256:0b929ac182f5ace000d459c59c2c9c33047e20e935f8e39371fa6e3b85d56f4a", - "sha256:129a150f5c445165ff941fc02ee27df65940fcb8a22a61828b1853c98763a64b", - "sha256:13e6afb7fe71fe7485a4550a8844cc9ffbe263c0f1a1eea569bc7091d4898555", - "sha256:1473400e5b2733e58b396a04eb7f35f541e1fb976d0c0724d0223dd607e0f74c", - "sha256:18983c537e04d11cf027fbb60a1e8dfd5190e2b60cc27bc0808e653e7b218d1b", - "sha256:1a7ed2d9d039bd41e889f6fb9364554052ca21ce823580f6a07c4ec245c1f5d6", - "sha256:1e1fe0e6ab7775fd842bc39e86f6dcfc4507ab0ffe206093e76d61cde37225c8", - "sha256:1fb5699e4464afe5c7e65fa51d4f99e0b2eadcc176e4aa33600a3df7801d6662", - "sha256:2696993ee1eebd20b8e4ee4356483c4cb696066ddc24bd70bcbb80fa56ff9061", - "sha256:35621ae4c00e056adb0009f8e86e28eb4a41a4bfa8f9bfa9fca7d343fe94f998", - "sha256:36ccae62f64235cf8ddb682073a60519426fdd4725524ae38874adf72b5f2aeb", - "sha256:3cedbfa9c940fdad3e6e941db7138e26ce8aad38ab5fe9dcfadfed9db7a54e62", - "sha256:3d57c572081fed831ad2d26fd430d565b76aa277ed1d30ff4d40670b1c0dd984", - "sha256:3fc7cb4c1c744f8c05cd5f9438a3caa6ab94ce8344e952d7c45a8ed59dd88392", - "sha256:4011d137b9955791f9084749cba9a367c68d50ab8d11d64c50ba1688c9b457f2", - "sha256:40d615e4fe22f4ad3528448c193b218e077656ca9ccb22ce2cb20db730f8d306", - "sha256:410a92fefd2e0e10d26210e1dfb4a876ddaf8439ef60d6434f21ef8d87efc5b7", - "sha256:41388e9d4d1522446fe79d3213196bd9e3b301a336965b9e27ca2788ebd122f3", - "sha256:468090021f391fe0056ad3e807e3d9034e0fd01adcd3bdfba977b6fdf4213ea9", - "sha256:49703ce2ddc220df165bd2962f8e03b84c89fee2d65e1c24a7defff6f988f4d6", - "sha256:4a721d3c943dae44f8e243b380cb645a709ba5bd35d3ad27bc2ed947e9c68192", - "sha256:4afd5814270fdf6380616b321fd31435a462019d834f83c8611a0ce7484c7317", - "sha256:4c82b8785d98cdd9fed4cac84d765d234ed3251bd6afe34cb7ac523cb93e8b4f", - "sha256:4db983e7bca53819efdbd64590ee96c9213894272c776966ca6306b73e4affda", - "sha256:582530701bff1dec6779efa00c516496968edd851fba224fbd86e46cc6b73563", - "sha256:58455b79ec2661c3600e65c0a716955adc2410f7383755d537584b0de41b1d8a", - "sha256:58705da316756681ad3c9c73fd15499aa4d8c69f9fd38dc8a35e06c12468582f", - "sha256:5bb1d0dbf99411f3d871deb6faa9aabb9d4e744d67dcaaa05399af89d847a91d", - "sha256:5c803c401ea1c1c18de70a06a6f79fcc9c5acfc79133e9869e730ad7f8ad8ef9", - "sha256:5cbabee4f083b6b4cd282f5b817a867cf0b1028c54d445b7ec7cfe6505057cf8", - "sha256:612dff5db80beef9e649c6d803a8d50c409082f1fedc9dbcdfde2983b2025b82", - "sha256:62c2caa1585c82b3f7a7ab56afef7b3602021d6da34fbc1cf234ff139fed3cd9", - "sha256:69606d7bb691b50a4240ce6b22ebb319c1cfb164e5f6569835058196e0f3a845", - "sha256:6d9187b01bebc3875bac9b087948a2bccefe464a7d8f627cf6e48b1bbae30f82", - "sha256:6ed6ffac43aecfe6d86ec5b74b06a5be33d5bb9243d055141e8cabb12aa08125", - "sha256:703919b1633412ab54bcf920ab388735832fdcb9f9a00ae49387f0fe67dad504", - "sha256:766d8bbefcb9e00c3ac3b000d9acc51f1b399513f44d77dfe0eb026ad7c9a19b", - "sha256:80dd7db6a7cb57ffbc279c4394246414ec99537ae81ffd702443335a61dbf3a7", - "sha256:8112e52c5822fc4253f3901b676c55ddf288614dc7011634e2719718eaa187dc", - "sha256:8c8b293cd65ad716d13d8dd3624e42e5a19cc2a2f1acc74b30c2c13f15cb61a6", - "sha256:8fdbdb757d5390f7c675e558fd3186d590973244fab0c5fe63d373ade3e99d40", - "sha256:91bd7d1773e64019f9288b7a5101f3ae50d3d8e6b1de7edee9c2ccc1d32f0c0a", - "sha256:95c658736ec15602da0ed73f312d410117723914a5c91a14ee4cdd72f1d790b3", - "sha256:99039fa9e6306880572915728d7f6c24a86ec57b0a83f6b2491e1d8ab0235b9a", - "sha256:9a2bce789a5ea90e51a02dfcc39e31b7f1e662bc3317979aa7e5538e3a034f72", - "sha256:9a7d15bbd2bc99e92e39f49a04653062ee6085c0e18b3b7512a4f2fe91f2d681", - "sha256:9abc77a4ce4c6f2a3168ff34b1da9b0f311a8f1cfd694ec96b0603dff1c79438", - "sha256:9e8659775f1adf02eb1e6f109751268e493c73716ca5761f8acb695e52a756ae", - "sha256:9fee687dce376205d9a494e9c121e27183b2a3df18037f89d69bd7b35bcf59e2", - "sha256:a5aaeff38654462bc4b09023918b7f21790efb807f54c000a39d41d69cf552cb", - "sha256:a604bf7a053f8362d27eb9fefd2097f82600b856d5abe996d623babd067b1ab5", - "sha256:abbb9e76177c35d4e8568e58650aa6926040d6a9f6f03435b7a522bf1c487f9a", - "sha256:acc130bc0375999da18e3d19e5a86403667ac0c4042a094fefb7eec8ebac7cf3", - "sha256:b18f2d1533a71f069c7f82d524a52599053d4c7166e9dd374ae2136b7f40f7c8", - "sha256:b4e42a40a5e164cbfdb7b386c966a588b1047558a990981ace551ed7e12ca9c2", - "sha256:b5e251054542ae57ac7f3fba5d10bfff615b6c2fb09abeb37d2f1463f841ae22", - "sha256:b60fb58b90c6d63779cb0c0c54eeb38941bae3ecf7a73c764c52c88c2dcb9d72", - "sha256:b870b5df5b71d8c3359d21be8f0d6c485fa0ebdb6477dda51a1ea54a9b558061", - "sha256:ba0f0eb61ef00ea10e00eb53a9129501f52385c44853dbd6c4ad3f403603083f", - "sha256:bb87745b2e6dc56361bfde481d5a378dc314b252a98d7dd19a651a3fa58f24a9", - "sha256:bb90fb8bda722a1b9d48ac1e6c38f923ea757b3baf8ebd0c82e09c5c1a0e7a04", - "sha256:bc570b5f14a79734437cb7b0500376b6b791153314986074486e0b0fa8d71d98", - "sha256:c86563182421896d73858e08e1db93afdd2b947a70064b813d515d66549e15f9", - "sha256:c958bcfd59bacc2d0249dcfe575e71da54f9dcf4a8bdf89c4cb9a68a1170d73f", - "sha256:d18a4865f46b8579d44e4fe1e2bcbc6472ad83d98e22a26c963d46e4c125ef0b", - "sha256:d5e2439eecc762cd85e7bd37161d4714aa03a33c5ba884e26c81559817ca0925", - "sha256:e3890b508a23299083e065f435a492b5435eba6e304a7114d2f919d400888cc6", - "sha256:e496a8ce2c256da1eb98bd15803a79bee00fc351f5dfb9ea82594a3f058309e0", - "sha256:e8b2816ebef96d83657b56306152a93909a83f23994f4b30ad4573b00bd11bb9", - "sha256:eaf675418ed6b3b31c7a989fd007fa7c3be66ce14e5c3b27336383604c9da85c", - "sha256:ec89ed91f2fa8e3f52ae53cd3cf640d6feff92ba90d62236a81e4e563ac0e991", - "sha256:ecc840861360ba9d176d413a5489b9a0aff6d6303d7e733e2c4623cfa26904a6", - "sha256:f09b286faeff3c750a879d336fb6d8713206fc97af3adc14def0cdd349df6000", - "sha256:f393cda562f79828f38a819f4788641ac7c4085f30f1ce1a68672baa686482bb", - "sha256:f917c1180fdb8623c2b75a99192f4025e412597c50b2ac870f156de8fb101119", - "sha256:fc78a84e2dfbc27afe4b2bd7c80c8db9bca75cc5b85df52bfe634596a1da846b", - "sha256:ff04ef6eec3eee8a5efef2401495967a916feaa353643defcc03fc74fe213b58" + "sha256:02b551d101f31694fc785e58e0720ef7d9a10c4e62c1c9358ce6f63f23e30a56", + "sha256:042ec3bb8f319c147b1301f2393bc19dba6e176b7da446853406d041c36c7828", + "sha256:0610b46293c59a3adbae3dee552b648b984176f8562ee0dba099a56cfbe4df1f", + "sha256:0b02e424deef65c9f7326d8c19220a2c9040c51dc165cddb732f16198c168396", + "sha256:0b1831115c97f0663cb77aa27d381237e73ad4f721391a9bfb2fe8bc25fa6e77", + "sha256:0ed61b7c2d49cee3c027372df5809a59d60cf1b6c2f81ee980a091f3afed6a2d", + "sha256:0f5f51a6466667a5a356e6381d362d259125b57f059103dd9fdc8c0cf1d14139", + "sha256:16ecf15d6af39246fe33e507105d67e4b81d8f8d2c6598ff7e3ca1b8a37213f7", + "sha256:1f0b2f40cf341ee8cc1a97d51ff50dddb9fcc73241b9143ec74b30fc4f44f6cb", + "sha256:1f23fa283f51c890eda8e34e4937079114c74b4c81d2b2f1f1d94948f5cc3d7f", + "sha256:223db574bb38637e8230eb14b185565023ab624474df94d2af18f1cdb625216f", + "sha256:249f88ed15503f6492a71f01442abddd73856a0032ae860de6d75ca62eed8067", + "sha256:24c2ed34dc222ed754247a2702b1e1e89fdbaa4016f324b4b8f1a802d4ffe87f", + "sha256:273a736c4645e63ac582c60a56b0acb529ef07f78e08dc6bfadf6a46b19c0da7", + "sha256:281262213373b6d5e4bb4353bc36d1ba4084e6d6b5d242863721ef2bf2c2930b", + "sha256:30ce38e66630599e1193798285706903110d4f057aab3168a34b7fdc85569afc", + "sha256:33486899acd2d7d3066156b03465b949da3fd41a5da6e394ec49d271baefcf05", + "sha256:343e44b2a8e60e06a7e0d29c1671a0d9951f59174f3709962b5143f60a2a98bd", + "sha256:373342dd05b1d07d752cecbec0c41817231f29f3a89aa8b8843f7b95992ed0c7", + "sha256:3af60380ba0b7b5aeb329bc4e402acd25bd877e98b3727b0135cb5c2efdaefe9", + "sha256:3e62d15d3cfa26e3d0788094de7b64efa75f3a53875cdbccdf78547aed547a81", + "sha256:41b1d2bc74c2cac6f9074df52b2efbef2b30bdfe5f40cb78f8ca22963bc62977", + "sha256:423ed5420ad5f5529db9ce89eac09c8a2f97da18eb1c870237e84c5a5c2d60aa", + "sha256:46acc57b331e0b3bcb3e1ca3b421d65637915cfcd65eb783cb2f78a511193f9b", + "sha256:4da9f45279fff3543c371d5ababc57a0384f70be244de7759c85a7f989cb4ebe", + "sha256:507553480670cab08a800b9463bdb881b2edeed77dc677b0a5915e6106e91a58", + "sha256:53e5e39ff71b3fc484df8a522c933ea2b7cdd0d5d15ae82e5b23fde87d44cbd8", + "sha256:54a30837587c6ee3cd1a4d1c2ec5d24e77984d44e2f34547e2323ddb4e22eb77", + "sha256:5531d911795e3f935a9c23eb1c8c03c211661a5060aab167065896bbf62a5f85", + "sha256:55cbbc356c2842f39bcc553cf695932e8b30e30e797f961860afb308e6b1bb7c", + "sha256:59923aa12d0157f6b82d686c3fd8e1166fa8cdfb3e17b42ce3b6147ff81528df", + "sha256:5a03a38adec8066d5a37bea22f2ba6bbf39fcdefbe2d91419ab864c3fb515454", + "sha256:5a7b3c1ee8265eb4c8f1b7d29943f195c00673f5ab60c192eba2d4a7eae5f46a", + "sha256:5d4478d72eb61c36e5b446e375bbc49ed002430d17cdec3cecb36993398e1a9e", + "sha256:5ea5eb3c0c071862997d6f3e02af1d055f381b1d25b286b9d6644b79db77657c", + "sha256:604d076c55e2fdd4c1c03d06dc1a31b95130010517b5019db15365ec4a405fc6", + "sha256:656873859b3b50eeebe6db8b1455e99d90c26ab058db8e427046dbc35c3140a5", + "sha256:65d1d00fbfb3ea5f20add88bbc0f815150dbbde3b026e6c24759466c8b5a9ef9", + "sha256:6b538e31eca1a7ea4605e44f81a48aa24c4632a277431a6ed3f328835901f4fd", + "sha256:6fd1ad24dc235e4ab88cda009e19bf347aabb975e44fd5c2fb22a3f6e4141277", + "sha256:70d86fa5197b8947a2fa70260b48e400bf2ccacdcab97bb7de47e3d1e6312225", + "sha256:7171ae35d2c33d326ac19dd8facb1e82e5fd04ef8c6c0e394d7af55a55051c22", + "sha256:73d496de46cd2cdbdbcce4ae4bcdb4afb6a11234a1df9c085249d55166b95116", + "sha256:7425ac3c54430f5fc5e7b6f41d41e704db073309acfc09305816bc6a0b26bb16", + "sha256:74afa28374a3c3a11b3b5e5fca0ae03bef8450d6aa3ab3a1e2c30e3a75d023dc", + "sha256:758895b01d546812d1f42204bd443b8c433c44d090248bf22689df673ccafe00", + "sha256:79573c24a46ce11aab457b472efd8d125e5a51da2d1d24387666cd85f54c05b2", + "sha256:7e18f01b0c3e4a07fe6dfdb00e29049ba17eadbc5e7609a2a3a4af83ab7d710a", + "sha256:88547535b787a6c9ce4086917b6e1d291aa8ed914fdd3a838b3539dc95c12804", + "sha256:88bbae4d40d5a46142e70d58bf664a89b6b4befaea7b2ecc14e03cedb8e06c04", + "sha256:8cccf4f81371f257440c88faed6b74f1053eef90807b77e31ca057b2db74edb1", + "sha256:9baa544e6acc91130e926e8c802a17f3b16fbea0fd441b5a60f5cf2cc5c3deba", + "sha256:a36692b8491d30a8c75f1dfee65bef119d6f39ea84ee04d9f9311f83c5ad9390", + "sha256:a47681378a0439215912ef542c45a783484d4dd82bac412b71e59cf9c0e1cea0", + "sha256:a7c06742645f914f26c7f1fa47b8bc4c91d222f76ee20116c43d5ef0912bba2d", + "sha256:a9a2203361a6e6404f80b99234fe7fb37d1fc73487b5a78dc1aa5b97201e0f22", + "sha256:ab232e7fdb44cdfbf55fc3afa31bcdb0d8980b9b95c38b6405df2acb672af0e0", + "sha256:ad85e269fe54d506b240d2d7b9f5f2057c2aa9a2ea5b32c66f8902f768117ed2", + "sha256:af338aa93554be859173c39c85243970dc6a289fa907402289eeae7543e1ae18", + "sha256:afd964fd43b10c12213574db492cb8f73b2f0826c8df07a68288f8f19af2ebe6", + "sha256:b32888aad8b6e68f83a8fdccbf3165f5469702a7544472bdf41f582970ed3311", + "sha256:c31eebe420a9a5d2887b13000b043ff6ca27c452a9a22fa71f35f118e8d4bf89", + "sha256:caea3e9c79d5f0d2c6d9ab96111601797ea5da8e6d0723f77eabb0d4068d2b2f", + "sha256:cf30f6e3c077c8e6a9a7809c94551203c8843e74ba0c960f4a98cd80d4665d39", + "sha256:d40770d7c0fd5cbed9d84b2c3f2e156431a12c9a37dc6284060fb4bec0b7ffd4", + "sha256:d8a210b158a34164de8bb68b0e7780041a903d7b00c87e906fb69928bf7890d5", + "sha256:dc4a8d2b25efb6681ecacad42fca8859f88092d8732b170de6a5dddd80a1c8fa", + "sha256:df7d30371a2accfe4013e90445f6388c570f103d61019b6b7c57e0265250072a", + "sha256:e01375f275f010fcbf7f643b4279896d04e571889b8a5b3f848423d91bf07050", + "sha256:e1a4120ae5705f673727d3253de3ed0e016f7cd78dc463db1b31e2463e1f3cf6", + "sha256:e228514a06843cae89621384cfe3a80418f3c04aadf8a3b14e46a7be704e4235", + "sha256:e405adefb53a435f01efa7ccdec012c016b5a1d3f35459990afc39b6be4d5056", + "sha256:e6b13af258d6a9ad602d57d889f83b9d5543acd471eee12eb51f5b01f8eb1bc2", + "sha256:e6f40a8aa5a92f150bdb3e1c44b7e98fb7113955b2e5394122fa5532fec4b418", + "sha256:e71d5c6ebac14875668a1e90baf2ea0ef5b7ac7918355850c0908ae82bcb297c", + "sha256:ed7c635ae45cfbc1a7371f708727bf74690daedc49b4dba310590ca0bd28aa8a", + "sha256:f38e60678850c42461d4202739f9bf1e3a737c7ad283638251e79cc49effb6b6", + "sha256:f66eb08feaa410fe4eebd17f2a2c8e2e46d3476e9f8c783daa8e09e0faa666d0", + "sha256:f9b2601381be482f70e5d1051a5965c25fb3625455a2bf520b5a077b22afb775", + "sha256:fbd3c8319de8e1dc79d346929cd71d523622da527cca14e0c1d257e31c2b8b10", + "sha256:fd341868a4b6714a5962c1af0bd44f7c404ef78720c7de4892901e540417111c" ], "markers": "python_version >= '3.8'", - "version": "==1.17.2" + "version": "==1.17.3" }, "zipp": { "hashes": [ @@ -993,11 +982,11 @@ }, "flask-migrate": { "hashes": [ - "sha256:1a336b06eb2c3ace005f5f2ded8641d534c18798d64061f6ff11f79e1434126d", - "sha256:24d8051af161782e0743af1b04a152d007bad9772b2bca67b7ec1e8ceeb3910d" + "sha256:4d42e8f861d78cb6e9319afcba5bf76062e5efd7784184dd2a1cccd9de34a702", + "sha256:df9043d2050df3c0e0f6313f6b529b62c837b6033c20335e9d0b4acdf2c40e23" ], "index": "pypi", - "version": "==4.1.0" + "version": "==3.0.1" }, "flask-sqlalchemy": { "hashes": [ From c61725eff16de78a087a72fc60f28ae0f6e81418 Mon Sep 17 00:00:00 2001 From: Adrian Edwards Date: Wed, 3 Sep 2025 18:06:16 -0400 Subject: [PATCH 205/206] add new fields and migration for them --- common/db_schema.py | 2 ++ ..._add_audience_and_internal_description_.py | 30 +++++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 migrations/versions/9c3dd7f95cdc_add_audience_and_internal_description_.py diff --git a/common/db_schema.py b/common/db_schema.py index 0457560..c0bf213 100644 --- a/common/db_schema.py +++ b/common/db_schema.py @@ -44,6 +44,8 @@ class BellSchedule(db.Model): full_name = db.Column('bell_schedule_name', db.VARCHAR(length=75)) meeting_times = db.relationship("BellScheduleMeetingTime", cascade="save-update, merge,delete, delete-orphan") display_name = db.Column('bell_schedule_display_name', db.VARCHAR(length=75)) + audience = db.Column('audience', db.VARCHAR(length=75), nullable=False, server_default="everyone") + internal_description = db.Column('internal_description', db.VARCHAR(length=250), nullable=False, server_default="") creation_date = db.Column('creation_date', db.DateTime, default=datetime.utcnow()) last_modified = db.Column('last_modified', db.DateTime, diff --git a/migrations/versions/9c3dd7f95cdc_add_audience_and_internal_description_.py b/migrations/versions/9c3dd7f95cdc_add_audience_and_internal_description_.py new file mode 100644 index 0000000..03fd596 --- /dev/null +++ b/migrations/versions/9c3dd7f95cdc_add_audience_and_internal_description_.py @@ -0,0 +1,30 @@ +"""add audience and internal description to bell schedule + +Revision ID: 9c3dd7f95cdc +Revises: 2399c50496f7 +Create Date: 2025-09-03 18:05:04.456307 + +""" +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = '9c3dd7f95cdc' +down_revision = '2399c50496f7' +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.add_column('bellschedules', sa.Column('audience', sa.VARCHAR(length=75), server_default='everyone', nullable=False)) + op.add_column('bellschedules', sa.Column('internal_description', sa.VARCHAR(length=250), server_default='', nullable=False)) + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.drop_column('bellschedules', 'internal_description') + op.drop_column('bellschedules', 'audience') + # ### end Alembic commands ### From 4627e8310ad72d5cf4296455e054c0292e47d23f Mon Sep 17 00:00:00 2001 From: Adrian Edwards Date: Wed, 3 Sep 2025 18:35:10 -0400 Subject: [PATCH 206/206] exclude internal description from being returned to unauthenticated users --- blueprints/v0.py | 10 ++++++++-- common/helpers.py | 7 +++++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/blueprints/v0.py b/blueprints/v0.py index ef84b58..6fe37fc 100644 --- a/blueprints/v0.py +++ b/blueprints/v0.py @@ -355,7 +355,10 @@ def list_bellschedules(school_id): schedules = BellScheduleDB.query.filter_by(school_id=school_id, soft_deleted=False) - return respond(BellScheduleSchema(exclude=('school_id',)).dump(schedules, many=True)) + excluded_fields = exclude_unless_logged_in(['internal_description']) + excluded_fields.extend(('school_id',)) + + return respond(BellScheduleSchema(exclude=excluded_fields).dump(schedules, many=True)) @blueprint.route("/bellschedule/", strict_slashes=False, methods=['GET']) @check_headers @@ -397,7 +400,10 @@ def get_bellschedule(bell_schedule_id): if schedule.last_modified == since: return respond(code=304) #Not Modified - return respond(BellScheduleSchema(exclude=('soft_deleted',)).dump(schedule)) + excluded_fields = exclude_unless_logged_in(['internal_description']) + excluded_fields.extend(('soft_deleted',)) + + return respond(BellScheduleSchema(exclude=excluded_fields).dump(schedule)) @blueprint.route("/bellschedule", strict_slashes=False, methods=['POST']) diff --git a/common/helpers.py b/common/helpers.py index 100ac44..b5d8aeb 100644 --- a/common/helpers.py +++ b/common/helpers.py @@ -222,6 +222,13 @@ def get_api_user_id(): return "" +def exclude_unless_logged_in(fields: list): + is_admin = check_for_roles(["admin", "school admin"]) + if is_admin: + return [] + else: + return fields + def get_token_auth_header(): return get_valid_auth_header_of_type(AuthType.TOKEN)