migration fixes
This commit is contained in:
parent
e31b6d450a
commit
5070ec2ac7
|
@ -1,4 +1,4 @@
|
||||||
# discours-backend-next
|
# discoursio-api
|
||||||
|
|
||||||
Tech stack:
|
Tech stack:
|
||||||
|
|
||||||
|
|
657
migrate.py
657
migrate.py
|
@ -1,5 +1,6 @@
|
||||||
''' cmd managed migration '''
|
''' cmd managed migration '''
|
||||||
import json
|
import json
|
||||||
|
import pprint
|
||||||
import base64
|
import base64
|
||||||
import re
|
import re
|
||||||
import frontmatter
|
import frontmatter
|
||||||
|
@ -15,343 +16,353 @@ from dateutil.parser import parse as date_parse
|
||||||
from orm.base import local_session
|
from orm.base import local_session
|
||||||
from orm import User
|
from orm import User
|
||||||
|
|
||||||
|
print = pprint.pprint
|
||||||
IMG_REGEX = r"\!\[(.*?)\]\((data\:image\/(png|jpeg|jpg);base64\,(.*?))\)"
|
IMG_REGEX = r"\!\[(.*?)\]\((data\:image\/(png|jpeg|jpg);base64\,(.*?))\)"
|
||||||
OLD_DATE = '2016-03-05 22:22:00.350000'
|
OLD_DATE = '2016-03-05 22:22:00.350000'
|
||||||
|
|
||||||
|
|
||||||
|
def extract_images(article):
|
||||||
|
''' extract b64 encoded images from markdown in article body '''
|
||||||
|
body = article['body']
|
||||||
|
images = []
|
||||||
|
matches = re.finditer(IMG_REGEX, body, re.IGNORECASE | re.MULTILINE)
|
||||||
|
for i, match in enumerate(matches, start=1):
|
||||||
|
ext = match.group(3)
|
||||||
|
link = '/static/upload/image-' + \
|
||||||
|
article['old_id'] + str(i) + '.' + ext
|
||||||
|
img = match.group(4)
|
||||||
|
if img not in images:
|
||||||
|
open('..' + link, 'wb').write(base64.b64decode(img))
|
||||||
|
images.append(img)
|
||||||
|
body = body.replace(match.group(2), link)
|
||||||
|
print(link)
|
||||||
|
article['body'] = body
|
||||||
|
return article
|
||||||
|
|
||||||
|
|
||||||
|
def users(users_by_oid, users_by_slug, users_data):
|
||||||
|
''' migrating users first '''
|
||||||
|
# limiting
|
||||||
|
limit = len(users_data)
|
||||||
|
if len(sys.argv) > 2: limit = int(sys.argv[2])
|
||||||
|
print('migrating %d users...' % limit)
|
||||||
|
counter = 0
|
||||||
|
for entry in users_data:
|
||||||
|
oid = entry['_id']
|
||||||
|
user = migrateUser(entry)
|
||||||
|
users_by_oid[oid] = user # full
|
||||||
|
del user['password']
|
||||||
|
del user['notifications']
|
||||||
|
# del user['oauth']
|
||||||
|
del user['emailConfirmed']
|
||||||
|
del user['username']
|
||||||
|
del user['email']
|
||||||
|
users_by_slug[user['slug']] = user # public
|
||||||
|
counter += 1
|
||||||
|
export_authors = dict(sorted(users_by_slug.items(), key=lambda item: item[1]['rating'])[-10:])
|
||||||
|
try:
|
||||||
|
open('migration/data/users.old_id.json', 'w').write(json.dumps(users_by_oid, cls=DateTimeEncoder)) # NOTE: by old_id
|
||||||
|
open('migration/data/users.slug.json', 'w').write(json.dumps(users_by_slug, cls=DateTimeEncoder)) # NOTE: by slug
|
||||||
|
print(str(len(users_by_slug.items())) + ' users migrated')
|
||||||
|
except Exception:
|
||||||
|
print('json dump error')
|
||||||
|
print(users_by_oid)
|
||||||
|
|
||||||
|
|
||||||
|
def topics(export_topics, topics_by_slug, topics_by_cat, topics_by_tag, cats_data, tags_data):
|
||||||
|
''' topics from categories and tags '''
|
||||||
|
# limiting
|
||||||
|
limit = len(cats_data) + len(tags_data)
|
||||||
|
if len(sys.argv) > 2: limit = int(sys.argv[2])
|
||||||
|
print('migrating %d topics...' % limit)
|
||||||
|
counter = 0
|
||||||
|
for cat in cats_data:
|
||||||
|
old_id = cat["createdBy"]
|
||||||
|
# cat["createdBy"] = user_id_map[old_id]
|
||||||
|
try: topic = migrateCategory(cat)
|
||||||
|
except Exception as e: raise e
|
||||||
|
topics_by_cat[topic['cat_id']] = topic
|
||||||
|
topics_by_slug[topic['slug']] = topic
|
||||||
|
counter += 1
|
||||||
|
for tag in tags_data:
|
||||||
|
old_id = tag["createdBy"]
|
||||||
|
tag["createdBy"] = user_id_map.get(old_id, 0)
|
||||||
|
topic = migrateTag(tag)
|
||||||
|
topics_by_tag[topic['tag_id']] = topic
|
||||||
|
if not topics_by_slug.get(topic['slug']): topics_by_slug[topic['slug']] = topic
|
||||||
|
counter += 1
|
||||||
|
export_topics = dict(topics_by_slug.items()) # sorted(topics_by_slug.items(), key=lambda item: str(item[1]['createdAt']))) # NOTE: sorting does not work :)
|
||||||
|
open('migration/data/topics.slug.json','w').write(json.dumps(topics_by_slug,
|
||||||
|
cls=DateTimeEncoder,
|
||||||
|
indent=4,
|
||||||
|
sort_keys=True,
|
||||||
|
ensure_ascii=False))
|
||||||
|
|
||||||
|
open('migration/data/topics.cat_id.json','w').write(json.dumps(topics_by_cat,
|
||||||
|
cls=DateTimeEncoder,
|
||||||
|
indent=4,
|
||||||
|
sort_keys=True,
|
||||||
|
ensure_ascii=False))
|
||||||
|
|
||||||
|
def shouts(content_data, shouts_by_slug, shouts_by_oid):
|
||||||
|
''' migrating content items one by one '''
|
||||||
|
# limiting
|
||||||
|
limit = len(content_data)
|
||||||
|
if len(sys.argv) > 2: limit = int(sys.argv[2])
|
||||||
|
print('migrating %d content items...' % limit)
|
||||||
|
counter = 0
|
||||||
|
discours_author = 0
|
||||||
|
errored = []
|
||||||
|
|
||||||
|
# limiting
|
||||||
|
try: limit = int(sys.argv[2]) if len(sys.argv) > 2 else len(content_data)
|
||||||
|
except ValueError: limit = len(content_data)
|
||||||
|
|
||||||
|
if not topics_by_cat:
|
||||||
|
with local_session() as session:
|
||||||
|
topics = session.query(Topic).all()
|
||||||
|
print("loaded %s topics" % len(topics))
|
||||||
|
for topic in topics:
|
||||||
|
topics_by_cat[topic.cat_id] = topic
|
||||||
|
|
||||||
|
for entry in content_data[:limit]:
|
||||||
|
try:
|
||||||
|
shout = migrateShout(entry, users_by_oid, topics_by_cat)
|
||||||
|
author = shout['authors'][0]
|
||||||
|
shout['authors'] = [ author.id, ]
|
||||||
|
shouts_by_slug[shout['slug']] = shout
|
||||||
|
shouts_by_oid[entry['_id']] = shout
|
||||||
|
line = str(counter+1) + ': ' + shout['slug'] + " @" + str(author.slug)
|
||||||
|
counter += 1
|
||||||
|
if author.slug == 'discours': discours_author += 1
|
||||||
|
print(line)
|
||||||
|
# open('./shouts.id.log', 'a').write(line + '\n')
|
||||||
|
except Exception as e:
|
||||||
|
print(entry['_id'])
|
||||||
|
errored.append(entry)
|
||||||
|
raise e
|
||||||
|
open('migration/data/shouts.old_id.json','w').write(json.dumps(shouts_by_oid, cls=DateTimeEncoder))
|
||||||
|
open('migration/data/shouts.slug.json','w').write(json.dumps(shouts_by_slug, cls=DateTimeEncoder))
|
||||||
|
print(str(counter) + '/' + str(len(content_data)) + ' content items were migrated')
|
||||||
|
print(str(discours_author) + ' authored by @discours')
|
||||||
|
|
||||||
|
def export_shouts(shouts_by_slug, export_articles, export_authors, content_dict):
|
||||||
|
# update what was just migrated or load json again
|
||||||
|
if len(export_authors.keys()) == 0:
|
||||||
|
export_authors = json.loads(open('../src/data/authors.json').read())
|
||||||
|
print(str(len(export_authors.items())) + ' exported authors loaded')
|
||||||
|
if len(export_articles.keys()) == 0:
|
||||||
|
export_articles = json.loads(open('../src/data/articles.json').read())
|
||||||
|
print(str(len(export_articles.items())) + ' exported articles loaded')
|
||||||
|
|
||||||
|
# limiting
|
||||||
|
limit = 33
|
||||||
|
if len(sys.argv) > 2: limit = int(sys.argv[2])
|
||||||
|
print('exporting %d articles to json...' % limit)
|
||||||
|
|
||||||
|
# filter
|
||||||
|
export_list = [i for i in shouts_by_slug.items() if i[1]['layout'] == 'article']
|
||||||
|
export_list = sorted(export_list, key=lambda item: item[1]['createdAt'] or OLD_DATE, reverse=True)
|
||||||
|
print(str(len(export_list)) + ' filtered')
|
||||||
|
export_list = export_list[:limit or len(export_list)]
|
||||||
|
|
||||||
|
for (slug, article) in export_list:
|
||||||
|
if article['layout'] == 'article':
|
||||||
|
export_slug(slug, export_articles, export_authors, content_dict)
|
||||||
|
|
||||||
|
def export_body(article, content_dict):
|
||||||
|
article = extract_images(article)
|
||||||
|
metadata = get_metadata(article)
|
||||||
|
content = frontmatter.dumps(frontmatter.Post(article['body'], **metadata))
|
||||||
|
open('../content/discours.io/'+slug+'.md', 'w').write(content)
|
||||||
|
open('../content/discours.io/'+slug+'.html', 'w').write(content_dict[article['old_id']]['body'])
|
||||||
|
|
||||||
|
def export_slug(slug, export_articles, export_authors, content_dict):
|
||||||
|
print('exporting %s ' % slug)
|
||||||
|
if export_authors == {}:
|
||||||
|
export_authors = json.loads(open('../src/data/authors.json').read())
|
||||||
|
print(str(len(export_authors.items())) + ' exported authors loaded')
|
||||||
|
if export_articles == {}:
|
||||||
|
export_articles = json.loads(open('../src/data/articles.json').read())
|
||||||
|
print(str(len(export_articles.items())) + ' exported articles loaded')
|
||||||
|
|
||||||
|
shout = shouts_by_slug.get(slug, False)
|
||||||
|
assert shout, 'no data error'
|
||||||
|
author = users_by_slug.get(shout['authors'][0]['slug'], None)
|
||||||
|
export_authors.update({shout['authors'][0]['slug']: author})
|
||||||
|
export_articles.update({shout['slug']: shout})
|
||||||
|
export_body(shout, content_dict)
|
||||||
|
comments([slug, ])
|
||||||
|
|
||||||
|
def comments(sluglist, export_comments, export_articles, shouts_by_slug, content_dict):
|
||||||
|
''' migrating comments on content items one '''
|
||||||
|
if len(sluglist) == 0:
|
||||||
|
export_articles = json.loads(open('../src/data/articles.json').read())
|
||||||
|
print(str(len(export_articles.items())) + ' articles were exported before')
|
||||||
|
if len(sluglist) == 0: sluglist = list(export_articles.keys())
|
||||||
|
|
||||||
|
if len(sluglist) > 0:
|
||||||
|
print('exporting comments for: ')
|
||||||
|
print(' '.join(sluglist))
|
||||||
|
for slug in sluglist:
|
||||||
|
shout = shouts_by_slug[slug]
|
||||||
|
old_id = shout['old_id']
|
||||||
|
content_item = content_dict.get(old_id, {})
|
||||||
|
if content_item.get('commentedAt', False):
|
||||||
|
comments = [ migrateComment(c) for c in comments_by_post.get(old_id, []) ]
|
||||||
|
if len(comments) > 0:
|
||||||
|
export_comments[slug] = comments
|
||||||
|
sys.stdout.write('.')
|
||||||
|
else:
|
||||||
|
|
||||||
|
print('exporting comments for top 10 commented articles...')
|
||||||
|
comments_by_shoutslug = {}
|
||||||
|
for content_item in content_data:
|
||||||
|
old_id = content_item['_id']
|
||||||
|
if content_item.get('commentedAt', False):
|
||||||
|
comments = [ migrateComment(c) for c in comments_by_post.get(old_id, []) ]
|
||||||
|
if len(comments) > 0:
|
||||||
|
shout = shouts_by_oid.get(old_id, { 'slug': 'abandoned-comments' })
|
||||||
|
comments_by_shoutslug[shout['slug']] = comments
|
||||||
|
|
||||||
|
top = dict(sorted(comments_by_shoutslug.items(), reverse=True, key=lambda c: len(c[1]))[:10])
|
||||||
|
export_comments.update(top)
|
||||||
|
|
||||||
|
print(str(len(export_comments.keys())) + ' articls with comments exported\n')
|
||||||
|
|
||||||
|
|
||||||
|
def export_finish(export_articles = {}, export_authors = {}, export_topics = {}, export_comments = {}):
|
||||||
|
open('../src/data/authors.json', 'w').write(json.dumps(export_authors,
|
||||||
|
cls=DateTimeEncoder,
|
||||||
|
indent=4,
|
||||||
|
sort_keys=True,
|
||||||
|
ensure_ascii=False))
|
||||||
|
print(str(len(export_authors.items())) + ' authors exported')
|
||||||
|
open('../src/data/topics.json', 'w').write(json.dumps(export_topics,
|
||||||
|
cls=DateTimeEncoder,
|
||||||
|
indent=4,
|
||||||
|
sort_keys=True,
|
||||||
|
ensure_ascii=False))
|
||||||
|
print(str(len(export_topics.keys())) + ' topics exported')
|
||||||
|
|
||||||
|
open('../src/data/articles.json', 'w').write(json.dumps(export_articles,
|
||||||
|
cls=DateTimeEncoder,
|
||||||
|
indent=4,
|
||||||
|
sort_keys=True,
|
||||||
|
ensure_ascii=False))
|
||||||
|
print(str(len(export_articles.items())) + ' articles exported')
|
||||||
|
open('../src/data/comments.json', 'w').write(json.dumps(export_comments,
|
||||||
|
cls=DateTimeEncoder,
|
||||||
|
indent=4,
|
||||||
|
sort_keys=True,
|
||||||
|
ensure_ascii=False))
|
||||||
|
print(str(len(export_comments.items())) + ' exported articles with comments')
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
users_data = json.loads(open('migration/data/users.json').read())
|
if len(sys.argv) > 1:
|
||||||
# users_dict = { x['_id']: x for x in users_data } # by id
|
cmd = sys.argv[1]
|
||||||
print(str(len(users_data)) + ' users loaded')
|
if cmd == "bson":
|
||||||
users_by_oid = {}
|
# decode bson
|
||||||
users_by_slug = {}
|
from migration import bson2json
|
||||||
|
bson2json.json_tables()
|
||||||
|
else:
|
||||||
|
|
||||||
with local_session() as session:
|
# preparing data
|
||||||
default_user = session.query(User).filter(User.id == 0).first()
|
|
||||||
if not default_user:
|
|
||||||
default_user = User.create(id = 0, email = "discours@discours.io", username = "discours", slug = "default", old_id = 0)
|
|
||||||
|
|
||||||
user_id_map = {}
|
users_data = json.loads(open('migration/data/users.json').read())
|
||||||
with local_session() as session:
|
# users_dict = { x['_id']: x for x in users_data } # by id
|
||||||
users = session.query(User).all()
|
print(str(len(users_data)) + ' users loaded')
|
||||||
for user in users:
|
users_by_oid = {}
|
||||||
user_id_map[user.old_id] = user.id
|
users_by_slug = {}
|
||||||
users_by_oid[user.old_id] = vars(user)
|
|
||||||
|
|
||||||
tags_data = json.loads(open('migration/data/tags.json').read())
|
with local_session() as session:
|
||||||
print(str(len(tags_data)) + ' tags loaded')
|
default_user = session.query(User).filter(User.id == 0).first()
|
||||||
|
if not default_user:
|
||||||
|
default_user = User.create(id = 0, email = "discours@discours.io", username = "discours", slug = "default", old_id = 0)
|
||||||
|
|
||||||
cats_data = json.loads(open('migration/data/content_item_categories.json').read())
|
user_id_map = {}
|
||||||
print(str(len(cats_data)) + ' cats loaded')
|
with local_session() as session:
|
||||||
topics_by_cat = {}
|
users_list = session.query(User).all()
|
||||||
topics_by_tag = {}
|
for user in users_list:
|
||||||
topics_by_slug = {}
|
user_id_map[user.old_id] = user.id
|
||||||
|
users_by_oid[user.old_id] = vars(user)
|
||||||
|
|
||||||
content_data = json.loads(open('migration/data/content_items.json').read())
|
tags_data = json.loads(open('migration/data/tags.json').read())
|
||||||
content_dict = { x['_id']: x for x in content_data }
|
print(str(len(tags_data)) + ' tags loaded')
|
||||||
print(str(len(content_data)) + ' content items loaded')
|
|
||||||
shouts_by_slug = {}
|
|
||||||
shouts_by_oid = {}
|
|
||||||
|
|
||||||
comments_data = json.loads(open('migration/data/comments.json').read())
|
cats_data = json.loads(open('migration/data/content_item_categories.json').read())
|
||||||
print(str(len(comments_data)) + ' comments loaded')
|
print(str(len(cats_data)) + ' cats loaded')
|
||||||
comments_by_post = {}
|
topics_by_cat = {}
|
||||||
|
topics_by_tag = {}
|
||||||
|
topics_by_slug = {}
|
||||||
|
|
||||||
# sort comments by old posts ids
|
content_data = json.loads(open('migration/data/content_items.json').read())
|
||||||
for old_comment in comments_data:
|
content_dict = { x['_id']: x for x in content_data }
|
||||||
cid = old_comment['contentItem']
|
print(str(len(content_data)) + ' content items loaded')
|
||||||
comments_by_post[cid] = comments_by_post.get(cid, [])
|
shouts_by_slug = {}
|
||||||
if not old_comment.get('deletedAt', True):
|
shouts_by_oid = {}
|
||||||
comments_by_post[cid].append(old_comment)
|
|
||||||
print(str(len(comments_by_post.keys())) + ' articles with comments')
|
|
||||||
|
|
||||||
export_articles = {} # slug: shout
|
comments_data = json.loads(open('migration/data/comments.json').read())
|
||||||
export_authors = {} # slug: user
|
print(str(len(comments_data)) + ' comments loaded')
|
||||||
export_comments = {} # shout-slug: comment[] (list)
|
comments_by_post = {}
|
||||||
export_topics = {} # slug: topic
|
# sort comments by old posts ids
|
||||||
|
for old_comment in comments_data:
|
||||||
|
cid = old_comment['contentItem']
|
||||||
|
comments_by_post[cid] = comments_by_post.get(cid, [])
|
||||||
|
if not old_comment.get('deletedAt', True):
|
||||||
|
comments_by_post[cid].append(old_comment)
|
||||||
|
print(str(len(comments_by_post.keys())) + ' articles with comments')
|
||||||
|
|
||||||
|
export_articles = {} # slug: shout
|
||||||
|
export_authors = {} # slug: user
|
||||||
|
export_comments = {} # shout-slug: comment[] (list)
|
||||||
|
export_topics = {} # slug: topic
|
||||||
|
|
||||||
def extract_images(article):
|
##################### COMMANDS ##########################3
|
||||||
''' extract b64 encoded images from markdown in article body '''
|
|
||||||
body = article['body']
|
|
||||||
images = []
|
|
||||||
matches = re.finditer(IMG_REGEX, body, re.IGNORECASE | re.MULTILINE)
|
|
||||||
for i, match in enumerate(matches, start=1):
|
|
||||||
ext = match.group(3)
|
|
||||||
link = '/static/upload/image-' + \
|
|
||||||
article['old_id'] + str(i) + '.' + ext
|
|
||||||
img = match.group(4)
|
|
||||||
if img not in images:
|
|
||||||
open('..' + link, 'wb').write(base64.b64decode(img))
|
|
||||||
images.append(img)
|
|
||||||
body = body.replace(match.group(2), link)
|
|
||||||
print(link)
|
|
||||||
article['body'] = body
|
|
||||||
return article
|
|
||||||
|
|
||||||
|
if cmd == "users":
|
||||||
def users(users_by_oid, users_by_slug, users_data):
|
users(users_by_oid, users_by_slug, users_data)
|
||||||
''' migrating users first '''
|
elif cmd == "topics":
|
||||||
# limiting
|
topics(export_topics, topics_by_slug, topics_by_cat, topics_by_tag, cats_data, tags_data)
|
||||||
limit = len(users_data)
|
elif cmd == "shouts":
|
||||||
if len(sys.argv) > 2: limit = int(sys.argv[2])
|
with local_session() as session:
|
||||||
print('migrating %d users...' % limit)
|
community = session.query(Community).filter(Community.id == 0).first()
|
||||||
counter = 0
|
if not community:
|
||||||
for entry in users_data:
|
Community.create(**{
|
||||||
oid = entry['_id']
|
'id' : 0,
|
||||||
user = migrateUser(entry)
|
'slug': 'discours.io',
|
||||||
users_by_oid[oid] = user # full
|
'name': 'Дискурс',
|
||||||
del user['password']
|
'pic': 'https://discours.io/images/logo-min.svg',
|
||||||
del user['notifications']
|
'createdBy': '0',
|
||||||
# del user['oauth']
|
'createdAt': date_parse(OLD_DATE)
|
||||||
del user['emailConfirmed']
|
})
|
||||||
del user['username']
|
shouts(content_data, shouts_by_slug, shouts_by_oid) # NOTE: listens limit
|
||||||
del user['email']
|
elif cmd == "comments":
|
||||||
users_by_slug[user['slug']] = user # public
|
for comment in comments_data:
|
||||||
counter += 1
|
migrateComment(comment)
|
||||||
export_authors = dict(sorted(users_by_slug.items(), key=lambda item: item[1]['rating'])[-10:])
|
elif cmd == "export_shouts":
|
||||||
open('migration/data/users.old_id.json', 'w').write(json.dumps(users_by_oid, cls=DateTimeEncoder)) # NOTE: by old_id
|
export_shouts(shouts_by_slug, export_articles, export_authors, content_dict)
|
||||||
open('migration/data/users.slug.json', 'w').write(json.dumps(users_by_slug, cls=DateTimeEncoder)) # NOTE: by old_id
|
elif cmd == "all":
|
||||||
print(str(len(users_by_slug.items())) + ' users migrated')
|
users(users_by_oid, users_by_slug, users_data)
|
||||||
|
topics(export_topics, topics_by_slug, topics_by_cat, topics_by_tag, cats_data, tags_data)
|
||||||
|
shouts(content_data, shouts_by_slug, shouts_by_oid)
|
||||||
def topics(export_topics, topics_by_slug, topics_by_cat, topics_by_tag, cats_data, tags_data):
|
cl = sys.argv[2] if len(sys.argv) > 2 else 10
|
||||||
''' topics from categories and tags '''
|
topOids = sorted([ c[0] for c in comments_by_post.items()], reverse=True, key=lambda i: len(i[1]))[-cl:]
|
||||||
# limiting
|
topSlugs = [ shouts_by_oid[oid]['slug'] for oid in topOids ]
|
||||||
limit = len(cats_data) + len(tags_data)
|
comments(topSlugs, export_comments, export_articles, shouts_by_slug, content_dict)
|
||||||
if len(sys.argv) > 2: limit = int(sys.argv[2])
|
elif cmd == 'slug':
|
||||||
print('migrating %d topics...' % limit)
|
export_slug(sys.argv[2], export_articles, export_authors, content_dict)
|
||||||
counter = 0
|
#export_finish(export_articles, export_authors, export_topics, export_comments)
|
||||||
for cat in cats_data:
|
else:
|
||||||
old_id = cat["createdBy"]
|
print('''
|
||||||
# cat["createdBy"] = user_id_map[old_id]
|
usage: python migrate.py bson
|
||||||
try: topic = migrateCategory(cat)
|
\n.. \ttopics <limit>
|
||||||
except Exception as e: raise e
|
\n.. \tusers <limit>
|
||||||
topics_by_cat[topic['cat_id']] = topic
|
\n.. \tshouts <limit>
|
||||||
topics_by_slug[topic['slug']] = topic
|
\n.. \texport_shouts <limit>
|
||||||
counter += 1
|
\n.. \tslug <slug>
|
||||||
for tag in tags_data:
|
\n.. \tall
|
||||||
old_id = tag["createdBy"]
|
''')
|
||||||
tag["createdBy"] = user_id_map.get(old_id, 0)
|
|
||||||
topic = migrateTag(tag)
|
|
||||||
topics_by_tag[topic['tag_id']] = topic
|
|
||||||
if not topics_by_slug.get(topic['slug']): topics_by_slug[topic['slug']] = topic
|
|
||||||
counter += 1
|
|
||||||
export_topics = dict(topics_by_slug.items()) # sorted(topics_by_slug.items(), key=lambda item: str(item[1]['createdAt']))) # NOTE: sorting does not work :)
|
|
||||||
open('migration/data/topics.slug.json','w').write(json.dumps(topics_by_slug,
|
|
||||||
cls=DateTimeEncoder,
|
|
||||||
indent=4,
|
|
||||||
sort_keys=True,
|
|
||||||
ensure_ascii=False))
|
|
||||||
|
|
||||||
open('migration/data/topics.cat_id.json','w').write(json.dumps(topics_by_cat,
|
|
||||||
cls=DateTimeEncoder,
|
|
||||||
indent=4,
|
|
||||||
sort_keys=True,
|
|
||||||
ensure_ascii=False))
|
|
||||||
|
|
||||||
def shouts(content_data, shouts_by_slug, shouts_by_oid):
|
|
||||||
''' migrating content items one by one '''
|
|
||||||
# limiting
|
|
||||||
limit = len(content_data)
|
|
||||||
if len(sys.argv) > 2: limit = int(sys.argv[2])
|
|
||||||
print('migrating %d content items...' % limit)
|
|
||||||
counter = 0
|
|
||||||
discours_author = 0
|
|
||||||
errored = []
|
|
||||||
|
|
||||||
# limiting
|
|
||||||
try: limit = int(sys.argv[2]) if len(sys.argv) > 2 else len(content_data)
|
|
||||||
except ValueError: limit = len(content_data)
|
|
||||||
|
|
||||||
if not topics_by_cat:
|
|
||||||
with local_session() as session:
|
|
||||||
topics = session.query(Topic).all()
|
|
||||||
print("loaded %s topics" % len(topics))
|
|
||||||
for topic in topics:
|
|
||||||
topics_by_cat[topic.cat_id] = topic
|
|
||||||
|
|
||||||
for entry in content_data[:limit]:
|
|
||||||
try:
|
|
||||||
shout = migrateShout(entry, users_by_oid, topics_by_cat)
|
|
||||||
author = shout['authors'][0]
|
|
||||||
shout['authors'] = [ author.id, ]
|
|
||||||
shouts_by_slug[shout['slug']] = shout
|
|
||||||
shouts_by_oid[entry['_id']] = shout
|
|
||||||
line = str(counter+1) + ': ' + shout['slug'] + " @" + str(author.slug)
|
|
||||||
counter += 1
|
|
||||||
if author.slug == 'discours': discours_author += 1
|
|
||||||
print(line)
|
|
||||||
# open('./shouts.id.log', 'a').write(line + '\n')
|
|
||||||
except Exception as e:
|
|
||||||
print(entry['_id'])
|
|
||||||
errored.append(entry)
|
|
||||||
raise e
|
|
||||||
open('migration/data/shouts.old_id.json','w').write(json.dumps(shouts_by_oid, cls=DateTimeEncoder))
|
|
||||||
open('migration/data/shouts.slug.json','w').write(json.dumps(shouts_by_slug, cls=DateTimeEncoder))
|
|
||||||
print(str(counter) + '/' + str(len(content_data)) + ' content items were migrated')
|
|
||||||
print(str(discours_author) + ' authored by @discours')
|
|
||||||
|
|
||||||
def export_shouts(shouts_by_slug, export_articles, export_authors, content_dict):
|
|
||||||
# update what was just migrated or load json again
|
|
||||||
if len(export_authors.keys()) == 0:
|
|
||||||
export_authors = json.loads(open('../src/data/authors.json').read())
|
|
||||||
print(str(len(export_authors.items())) + ' exported authors loaded')
|
|
||||||
if len(export_articles.keys()) == 0:
|
|
||||||
export_articles = json.loads(open('../src/data/articles.json').read())
|
|
||||||
print(str(len(export_articles.items())) + ' exported articles loaded')
|
|
||||||
|
|
||||||
# limiting
|
|
||||||
limit = 33
|
|
||||||
if len(sys.argv) > 2: limit = int(sys.argv[2])
|
|
||||||
print('exporting %d articles to json...' % limit)
|
|
||||||
|
|
||||||
# filter
|
|
||||||
export_list = [i for i in shouts_by_slug.items() if i[1]['layout'] == 'article']
|
|
||||||
export_list = sorted(export_list, key=lambda item: item[1]['createdAt'] or OLD_DATE, reverse=True)
|
|
||||||
print(str(len(export_list)) + ' filtered')
|
|
||||||
export_list = export_list[:limit or len(export_list)]
|
|
||||||
|
|
||||||
for (slug, article) in export_list:
|
|
||||||
if article['layout'] == 'article':
|
|
||||||
export_slug(slug, export_articles, export_authors, content_dict)
|
|
||||||
|
|
||||||
def export_body(article, content_dict):
|
|
||||||
article = extract_images(article)
|
|
||||||
metadata = get_metadata(article)
|
|
||||||
content = frontmatter.dumps(frontmatter.Post(article['body'], **metadata))
|
|
||||||
open('../content/discours.io/'+slug+'.md', 'w').write(content)
|
|
||||||
open('../content/discours.io/'+slug+'.html', 'w').write(content_dict[article['old_id']]['body'])
|
|
||||||
|
|
||||||
def export_slug(slug, export_articles, export_authors, content_dict):
|
|
||||||
print('exporting %s ' % slug)
|
|
||||||
if export_authors == {}:
|
|
||||||
export_authors = json.loads(open('../src/data/authors.json').read())
|
|
||||||
print(str(len(export_authors.items())) + ' exported authors loaded')
|
|
||||||
if export_articles == {}:
|
|
||||||
export_articles = json.loads(open('../src/data/articles.json').read())
|
|
||||||
print(str(len(export_articles.items())) + ' exported articles loaded')
|
|
||||||
|
|
||||||
shout = shouts_by_slug.get(slug, False)
|
|
||||||
assert shout, 'no data error'
|
|
||||||
author = users_by_slug.get(shout['authors'][0]['slug'], None)
|
|
||||||
export_authors.update({shout['authors'][0]['slug']: author})
|
|
||||||
export_articles.update({shout['slug']: shout})
|
|
||||||
export_body(shout, content_dict)
|
|
||||||
comments([slug, ])
|
|
||||||
|
|
||||||
def comments(sluglist, export_comments, export_articles, shouts_by_slug, content_dict):
|
|
||||||
''' migrating comments on content items one '''
|
|
||||||
if len(sluglist) == 0:
|
|
||||||
export_articles = json.loads(open('../src/data/articles.json').read())
|
|
||||||
print(str(len(export_articles.items())) + ' articles were exported before')
|
|
||||||
if len(sluglist) == 0: sluglist = list(export_articles.keys())
|
|
||||||
|
|
||||||
if len(sluglist) > 0:
|
|
||||||
print('exporting comments for: ')
|
|
||||||
print(' '.join(sluglist))
|
|
||||||
for slug in sluglist:
|
|
||||||
shout = shouts_by_slug[slug]
|
|
||||||
old_id = shout['old_id']
|
|
||||||
content_item = content_dict.get(old_id, {})
|
|
||||||
if content_item.get('commentedAt', False):
|
|
||||||
comments = [ migrateComment(c) for c in comments_by_post.get(old_id, []) ]
|
|
||||||
if len(comments) > 0:
|
|
||||||
export_comments[slug] = comments
|
|
||||||
sys.stdout.write('.')
|
|
||||||
else:
|
|
||||||
|
|
||||||
print('exporting comments for top 10 commented articles...')
|
|
||||||
comments_by_shoutslug = {}
|
|
||||||
for content_item in content_data:
|
|
||||||
old_id = content_item['_id']
|
|
||||||
if content_item.get('commentedAt', False):
|
|
||||||
comments = [ migrateComment(c) for c in comments_by_post.get(old_id, []) ]
|
|
||||||
if len(comments) > 0:
|
|
||||||
shout = shouts_by_oid.get(old_id, { 'slug': 'abandoned-comments' })
|
|
||||||
comments_by_shoutslug[shout['slug']] = comments
|
|
||||||
|
|
||||||
top = dict(sorted(comments_by_shoutslug.items(), reverse=True, key=lambda c: len(c[1]))[:10])
|
|
||||||
export_comments.update(top)
|
|
||||||
|
|
||||||
print(str(len(export_comments.keys())) + ' articls with comments exported\n')
|
|
||||||
|
|
||||||
|
|
||||||
def export_finish(export_articles = {}, export_authors = {}, export_topics = {}, export_comments = {}):
|
|
||||||
open('../src/data/authors.json', 'w').write(json.dumps(export_authors,
|
|
||||||
cls=DateTimeEncoder,
|
|
||||||
indent=4,
|
|
||||||
sort_keys=True,
|
|
||||||
ensure_ascii=False))
|
|
||||||
print(str(len(export_authors.items())) + ' authors exported')
|
|
||||||
open('../src/data/topics.json', 'w').write(json.dumps(export_topics,
|
|
||||||
cls=DateTimeEncoder,
|
|
||||||
indent=4,
|
|
||||||
sort_keys=True,
|
|
||||||
ensure_ascii=False))
|
|
||||||
print(str(len(export_topics.keys())) + ' topics exported')
|
|
||||||
|
|
||||||
open('../src/data/articles.json', 'w').write(json.dumps(export_articles,
|
|
||||||
cls=DateTimeEncoder,
|
|
||||||
indent=4,
|
|
||||||
sort_keys=True,
|
|
||||||
ensure_ascii=False))
|
|
||||||
print(str(len(export_articles.items())) + ' articles exported')
|
|
||||||
open('../src/data/comments.json', 'w').write(json.dumps(export_comments,
|
|
||||||
cls=DateTimeEncoder,
|
|
||||||
indent=4,
|
|
||||||
sort_keys=True,
|
|
||||||
ensure_ascii=False))
|
|
||||||
print(str(len(export_comments.items())) + ' exported articles with comments')
|
|
||||||
|
|
||||||
if len(sys.argv) > 1:
|
|
||||||
cmd = sys.argv[1]
|
|
||||||
if cmd == "users":
|
|
||||||
users(users_by_oid, users_by_slug, users_data)
|
|
||||||
elif cmd == "topics":
|
|
||||||
topics(export_topics, topics_by_slug, topics_by_cat, topics_by_tag, cats_data, tags_data)
|
|
||||||
elif cmd == "shouts":
|
|
||||||
with local_session() as session:
|
|
||||||
community = session.query(Community).filter(Community.id == 0).first()
|
|
||||||
if not community:
|
|
||||||
Community.create(**{
|
|
||||||
'id' : 0,
|
|
||||||
'slug': 'discours.io',
|
|
||||||
'name': 'Дискурс',
|
|
||||||
'pic': 'https://discours.io/images/logo-min.svg',
|
|
||||||
'createdBy': '0',
|
|
||||||
'createdAt': date_parse(OLD_DATE)
|
|
||||||
})
|
|
||||||
shouts(content_data, shouts_by_slug, shouts_by_oid) # NOTE: listens limit
|
|
||||||
elif cmd == "comments":
|
|
||||||
for comment in comments_data:
|
|
||||||
migrateComment(comment)
|
|
||||||
elif cmd == "export_shouts":
|
|
||||||
export_shouts(shouts_by_slug, export_articles, export_authors, content_dict)
|
|
||||||
elif cmd == "all":
|
|
||||||
users(users_by_oid, users_by_slug, users_data)
|
|
||||||
topics(export_topics, topics_by_slug, topics_by_cat, topics_by_tag, cats_data, tags_data)
|
|
||||||
shouts(content_data, shouts_by_slug, shouts_by_oid)
|
|
||||||
cl = sys.argv[2] if len(sys.argv) > 2 else 10
|
|
||||||
topOids = sorted([ c[0] for c in comments_by_post.items()], reverse=True, key=lambda i: len(i[1]))[-cl:]
|
|
||||||
topSlugs = [ shouts_by_oid[oid]['slug'] for oid in topOids ]
|
|
||||||
comments(topSlugs, export_comments, export_articles, shouts_by_slug, content_dict)
|
|
||||||
elif cmd == "bson":
|
|
||||||
from migration import bson2json
|
|
||||||
bson2json.json_tables()
|
|
||||||
elif cmd == 'slug':
|
|
||||||
export_slug(sys.argv[2], export_articles, export_authors, content_dict)
|
|
||||||
#export_finish(export_articles, export_authors, export_topics, export_comments)
|
|
||||||
else:
|
|
||||||
print('''
|
|
||||||
usage: python migrate.py bson
|
|
||||||
\n.. \ttopics <limit>
|
|
||||||
\n.. \tusers <limit>
|
|
||||||
\n.. \tshouts <limit>
|
|
||||||
\n.. \texport_shouts <limit>
|
|
||||||
\n.. \tslug <slug>
|
|
||||||
\n.. \tall
|
|
||||||
''')
|
|
||||||
|
|
|
@ -37,7 +37,7 @@ def get_metadata(r):
|
||||||
metadata['authors'] = r.get('authors')
|
metadata['authors'] = r.get('authors')
|
||||||
metadata['createdAt'] = r.get('createdAt', ts)
|
metadata['createdAt'] = r.get('createdAt', ts)
|
||||||
metadata['layout'] = r['layout']
|
metadata['layout'] = r['layout']
|
||||||
metadata['topics'] = [topic.slug for topic in r['topics']]
|
metadata['topics'] = [topic['slug'] for topic in r['topics']]
|
||||||
if r.get('cover', False):
|
if r.get('cover', False):
|
||||||
metadata['cover'] = r.get('cover')
|
metadata['cover'] = r.get('cover')
|
||||||
return metadata
|
return metadata
|
||||||
|
@ -200,31 +200,33 @@ def migrate(entry, users_by_oid, topics_by_oid):
|
||||||
assert user, 'could not get a user'
|
assert user, 'could not get a user'
|
||||||
|
|
||||||
shout_dict['authors'] = [ user, ]
|
shout_dict['authors'] = [ user, ]
|
||||||
try: s = Shout.create(**shout_dict)
|
try:
|
||||||
except Exception as e: raise e
|
with local_session() as session:
|
||||||
|
s = Shout.create(**shout_dict)
|
||||||
with local_session() as session:
|
if s:
|
||||||
shout_dict['id'] = s.id
|
# shout ratings
|
||||||
# shout ratings
|
shout_dict['ratings'] = []
|
||||||
shout_dict['ratings'] = []
|
for shout_rating_old in entry.get('ratings',[]):
|
||||||
for shout_rating_old in entry.get('ratings',[]):
|
rater = session.query(User).filter(User.old_id == shout_rating_old['createdBy']).first()
|
||||||
rater = session.query(User).filter(User.old_id == shout_rating_old['createdBy']).first()
|
if rater:
|
||||||
if rater:
|
shout_rating_dict = {
|
||||||
shout_rating_dict = {
|
'value': shout_rating_old['value'],
|
||||||
'value': shout_rating_old['value'],
|
'rater_id': rater.id,
|
||||||
'rater_id': rater.id,
|
'shout_id': s.id
|
||||||
'shout_id': s.id
|
}
|
||||||
}
|
cts = shout_rating_old.get('createdAt')
|
||||||
cts = shout_rating_old.get('createdAt')
|
if cts: shout_rating_dict['rater_id'] = date_parse(cts)
|
||||||
if cts: shout_rating_dict['rater_id'] = date_parse(cts)
|
try: shout_rating = ShoutRating.create(**shout_rating_dict)
|
||||||
try: shout_rating = ShoutRating.create(**shout_rating_dict)
|
except sqlalchemy.exc.IntegrityError: pass
|
||||||
except sqlalchemy.exc.IntegrityError: pass
|
shout_dict['ratings'].append(shout_rating_dict)
|
||||||
shout_dict['ratings'].append(shout_rating_dict)
|
# shout topics
|
||||||
# shout topics
|
shout_dict['id'] = s.id
|
||||||
shout_dict['topics'] = []
|
shout_dict['topics'] = []
|
||||||
for topic in r['topics']:
|
for topic in r['topics']:
|
||||||
ShoutTopic.create(**{ 'shout': s.id, 'topic': topic.id })
|
ShoutTopic.create(**{ 'shout': s.id, 'topic': topic['id'] })
|
||||||
shout_dict['topics'].append(topic.slug)
|
shout_dict['topics'].append(topic['slug'])
|
||||||
|
except Exception as e:
|
||||||
|
raise e
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
if not shout_dict['body']: r['body'] = 'body moved'
|
if not shout_dict['body']: r['body'] = 'body moved'
|
||||||
raise e
|
raise e
|
||||||
|
|
312
poetry.lock
generated
312
poetry.lock
generated
|
@ -32,20 +32,18 @@ trio = ["trio (>=0.16)"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ariadne"
|
name = "ariadne"
|
||||||
version = "0.13.0"
|
version = "0.3.0"
|
||||||
description = "Ariadne is a Python library for implementing GraphQL servers."
|
description = "Ariadne is a Python library for implementing GraphQL servers."
|
||||||
category = "main"
|
category = "main"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = "*"
|
python-versions = "*"
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
graphql-core = ">=3.1.0"
|
graphql-core-next = ">=1.0.1"
|
||||||
starlette = "<0.15"
|
starlette = ">=0.11.4"
|
||||||
|
typing = ">=3.6.0"
|
||||||
typing-extensions = ">=3.6.0"
|
typing-extensions = ">=3.6.0"
|
||||||
|
|
||||||
[package.extras]
|
|
||||||
asgi-file-uploads = ["python-multipart (>=0.0.5)"]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "asgiref"
|
name = "asgiref"
|
||||||
version = "3.4.1"
|
version = "3.4.1"
|
||||||
|
@ -59,11 +57,14 @@ tests = ["pytest", "pytest-asyncio", "mypy (>=0.800)"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "async-timeout"
|
name = "async-timeout"
|
||||||
version = "3.0.1"
|
version = "4.0.1"
|
||||||
description = "Timeout context manager for asyncio programs"
|
description = "Timeout context manager for asyncio programs"
|
||||||
category = "main"
|
category = "main"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.5.3"
|
python-versions = ">=3.6"
|
||||||
|
|
||||||
|
[package.dependencies]
|
||||||
|
typing-extensions = ">=3.6.5"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "authlib"
|
name = "authlib"
|
||||||
|
@ -168,7 +169,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cryptography"
|
name = "cryptography"
|
||||||
version = "35.0.0"
|
version = "36.0.0"
|
||||||
description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers."
|
description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers."
|
||||||
category = "main"
|
category = "main"
|
||||||
optional = false
|
optional = false
|
||||||
|
@ -179,16 +180,16 @@ cffi = ">=1.12"
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
docs = ["sphinx (>=1.6.5,!=1.8.0,!=3.1.0,!=3.1.1)", "sphinx-rtd-theme"]
|
docs = ["sphinx (>=1.6.5,!=1.8.0,!=3.1.0,!=3.1.1)", "sphinx-rtd-theme"]
|
||||||
docstest = ["doc8", "pyenchant (>=1.6.11)", "twine (>=1.12.0)", "sphinxcontrib-spelling (>=4.0.1)"]
|
docstest = ["pyenchant (>=1.6.11)", "twine (>=1.12.0)", "sphinxcontrib-spelling (>=4.0.1)"]
|
||||||
pep8test = ["black", "flake8", "flake8-import-order", "pep8-naming"]
|
pep8test = ["black", "flake8", "flake8-import-order", "pep8-naming"]
|
||||||
sdist = ["setuptools_rust (>=0.11.4)"]
|
sdist = ["setuptools_rust (>=0.11.4)"]
|
||||||
ssh = ["bcrypt (>=3.1.5)"]
|
ssh = ["bcrypt (>=3.1.5)"]
|
||||||
test = ["pytest (>=6.2.0)", "pytest-cov", "pytest-subtests", "pytest-xdist", "pretend", "iso8601", "pytz", "hypothesis (>=1.11.4,!=3.79.2)"]
|
test = ["pytest (>=6.2.0)", "pytest-cov", "pytest-subtests", "pytest-xdist", "pretend", "iso8601", "pytz", "hypothesis (>=1.11.4,!=3.79.2)"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "graphql-core"
|
name = "graphql-core-next"
|
||||||
version = "3.1.6"
|
version = "1.1.1"
|
||||||
description = "GraphQL implementation for Python, a port of GraphQL.js, the JavaScript reference implementation for GraphQL."
|
description = "GraphQL-core-next is a Python port of GraphQL.js, the JavaScript reference implementation for GraphQL."
|
||||||
category = "main"
|
category = "main"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.6,<4"
|
python-versions = ">=3.6,<4"
|
||||||
|
@ -222,7 +223,7 @@ python-versions = ">=3.5"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "httpcore"
|
name = "httpcore"
|
||||||
version = "0.13.7"
|
version = "0.14.3"
|
||||||
description = "A minimal low-level HTTP client."
|
description = "A minimal low-level HTTP client."
|
||||||
category = "main"
|
category = "main"
|
||||||
optional = false
|
optional = false
|
||||||
|
@ -230,6 +231,7 @@ python-versions = ">=3.6"
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
anyio = ">=3.0.0,<4.0.0"
|
anyio = ">=3.0.0,<4.0.0"
|
||||||
|
certifi = "*"
|
||||||
h11 = ">=0.11,<0.13"
|
h11 = ">=0.11,<0.13"
|
||||||
sniffio = ">=1.0.0,<2.0.0"
|
sniffio = ">=1.0.0,<2.0.0"
|
||||||
|
|
||||||
|
@ -238,7 +240,7 @@ http2 = ["h2 (>=3,<5)"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "httpx"
|
name = "httpx"
|
||||||
version = "0.20.0"
|
version = "0.21.1"
|
||||||
description = "The next generation HTTP client."
|
description = "The next generation HTTP client."
|
||||||
category = "main"
|
category = "main"
|
||||||
optional = false
|
optional = false
|
||||||
|
@ -247,7 +249,7 @@ python-versions = ">=3.6"
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
certifi = "*"
|
certifi = "*"
|
||||||
charset-normalizer = "*"
|
charset-normalizer = "*"
|
||||||
httpcore = ">=0.13.3,<0.14.0"
|
httpcore = ">=0.14.0,<0.15.0"
|
||||||
rfc3986 = {version = ">=1.3,<2", extras = ["idna2008"]}
|
rfc3986 = {version = ">=1.3,<2", extras = ["idna2008"]}
|
||||||
sniffio = "*"
|
sniffio = "*"
|
||||||
|
|
||||||
|
@ -288,7 +290,7 @@ totp = ["cryptography"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "psycopg2"
|
name = "psycopg2"
|
||||||
version = "2.9.1"
|
version = "2.9.2"
|
||||||
description = "psycopg2 - Python-PostgreSQL Database Adapter"
|
description = "psycopg2 - Python-PostgreSQL Database Adapter"
|
||||||
category = "main"
|
category = "main"
|
||||||
optional = false
|
optional = false
|
||||||
|
@ -296,7 +298,7 @@ python-versions = ">=3.6"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "psycopg2-binary"
|
name = "psycopg2-binary"
|
||||||
version = "2.9.1"
|
version = "2.9.2"
|
||||||
description = "psycopg2 - Python-PostgreSQL Database Adapter"
|
description = "psycopg2 - Python-PostgreSQL Database Adapter"
|
||||||
category = "main"
|
category = "main"
|
||||||
optional = false
|
optional = false
|
||||||
|
@ -304,7 +306,7 @@ python-versions = ">=3.6"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pycparser"
|
name = "pycparser"
|
||||||
version = "2.20"
|
version = "2.21"
|
||||||
description = "C parser in Python"
|
description = "C parser in Python"
|
||||||
category = "main"
|
category = "main"
|
||||||
optional = false
|
optional = false
|
||||||
|
@ -423,7 +425,7 @@ python-versions = ">=3.5"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "soupsieve"
|
name = "soupsieve"
|
||||||
version = "2.2.1"
|
version = "2.3.1"
|
||||||
description = "A modern CSS selector implementation for Beautiful Soup."
|
description = "A modern CSS selector implementation for Beautiful Soup."
|
||||||
category = "main"
|
category = "main"
|
||||||
optional = false
|
optional = false
|
||||||
|
@ -431,7 +433,7 @@ python-versions = ">=3.6"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sqlalchemy"
|
name = "sqlalchemy"
|
||||||
version = "1.4.26"
|
version = "1.4.27"
|
||||||
description = "Database Abstraction Library"
|
description = "Database Abstraction Library"
|
||||||
category = "main"
|
category = "main"
|
||||||
optional = false
|
optional = false
|
||||||
|
@ -463,14 +465,17 @@ sqlcipher = ["sqlcipher3-binary"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "starlette"
|
name = "starlette"
|
||||||
version = "0.14.2"
|
version = "0.17.1"
|
||||||
description = "The little ASGI library that shines."
|
description = "The little ASGI library that shines."
|
||||||
category = "main"
|
category = "main"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.6"
|
python-versions = ">=3.6"
|
||||||
|
|
||||||
|
[package.dependencies]
|
||||||
|
anyio = ">=3.0.0,<4"
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
full = ["aiofiles", "graphene", "itsdangerous", "jinja2", "python-multipart", "pyyaml", "requests"]
|
full = ["itsdangerous", "jinja2", "python-multipart", "pyyaml", "requests"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "transliterate"
|
name = "transliterate"
|
||||||
|
@ -484,12 +489,20 @@ python-versions = "*"
|
||||||
six = ">=1.1.0"
|
six = ">=1.1.0"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "typing-extensions"
|
name = "typing"
|
||||||
version = "3.10.0.2"
|
version = "3.7.4.3"
|
||||||
description = "Backported and Experimental Type Hints for Python 3.5+"
|
description = "Type Hints for Python"
|
||||||
category = "main"
|
category = "main"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = "*"
|
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "typing-extensions"
|
||||||
|
version = "4.0.0"
|
||||||
|
description = "Backported and Experimental Type Hints for Python 3.6+"
|
||||||
|
category = "main"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.6"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "urllib3"
|
name = "urllib3"
|
||||||
|
@ -535,16 +548,16 @@ anyio = [
|
||||||
{file = "anyio-3.3.4.tar.gz", hash = "sha256:67da67b5b21f96b9d3d65daa6ea99f5d5282cb09f50eb4456f8fb51dffefc3ff"},
|
{file = "anyio-3.3.4.tar.gz", hash = "sha256:67da67b5b21f96b9d3d65daa6ea99f5d5282cb09f50eb4456f8fb51dffefc3ff"},
|
||||||
]
|
]
|
||||||
ariadne = [
|
ariadne = [
|
||||||
{file = "ariadne-0.13.0-py3-none-any.whl", hash = "sha256:56bc3609a0512920f06e9312f8ea6db3c8e4a7cd77f31fbed388f5dba6d589c0"},
|
{file = "ariadne-0.3.0-py3-none-any.whl", hash = "sha256:c4b30b6138c7a9b8f890e80aed1303ae82deef70c3b7c5f218f7b2d620e046e8"},
|
||||||
{file = "ariadne-0.13.0.tar.gz", hash = "sha256:e00abd7eb5869b59a638f1e3a7743445bf387236048cf1b0eb9d7c506dcd37c5"},
|
{file = "ariadne-0.3.0.tar.gz", hash = "sha256:01ed4572ff9ee24c1b06f932e5516bcc2e2ba23d129fb5a0e9fe4a732eae74ad"},
|
||||||
]
|
]
|
||||||
asgiref = [
|
asgiref = [
|
||||||
{file = "asgiref-3.4.1-py3-none-any.whl", hash = "sha256:ffc141aa908e6f175673e7b1b3b7af4fdb0ecb738fc5c8b88f69f055c2415214"},
|
{file = "asgiref-3.4.1-py3-none-any.whl", hash = "sha256:ffc141aa908e6f175673e7b1b3b7af4fdb0ecb738fc5c8b88f69f055c2415214"},
|
||||||
{file = "asgiref-3.4.1.tar.gz", hash = "sha256:4ef1ab46b484e3c706329cedeff284a5d40824200638503f5768edb6de7d58e9"},
|
{file = "asgiref-3.4.1.tar.gz", hash = "sha256:4ef1ab46b484e3c706329cedeff284a5d40824200638503f5768edb6de7d58e9"},
|
||||||
]
|
]
|
||||||
async-timeout = [
|
async-timeout = [
|
||||||
{file = "async-timeout-3.0.1.tar.gz", hash = "sha256:0c3c816a028d47f659d6ff5c745cb2acf1f966da1fe5c19c77a70282b25f4c5f"},
|
{file = "async-timeout-4.0.1.tar.gz", hash = "sha256:b930cb161a39042f9222f6efb7301399c87eeab394727ec5437924a36d6eef51"},
|
||||||
{file = "async_timeout-3.0.1-py3-none-any.whl", hash = "sha256:4291ca197d287d274d0b6cb5d6f8f8f82d434ed288f962539ff18cc9012f9ea3"},
|
{file = "async_timeout-4.0.1-py3-none-any.whl", hash = "sha256:a22c0b311af23337eb05fcf05a8b51c3ea53729d46fb5460af62bee033cec690"},
|
||||||
]
|
]
|
||||||
authlib = [
|
authlib = [
|
||||||
{file = "Authlib-0.15.5-py2.py3-none-any.whl", hash = "sha256:ecf4a7a9f2508c0bb07e93a752dd3c495cfaffc20e864ef0ffc95e3f40d2abaf"},
|
{file = "Authlib-0.15.5-py2.py3-none-any.whl", hash = "sha256:ecf4a7a9f2508c0bb07e93a752dd3c495cfaffc20e864ef0ffc95e3f40d2abaf"},
|
||||||
|
@ -629,30 +642,30 @@ colorama = [
|
||||||
{file = "colorama-0.4.4.tar.gz", hash = "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b"},
|
{file = "colorama-0.4.4.tar.gz", hash = "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b"},
|
||||||
]
|
]
|
||||||
cryptography = [
|
cryptography = [
|
||||||
{file = "cryptography-35.0.0-cp36-abi3-macosx_10_10_x86_64.whl", hash = "sha256:d57e0cdc1b44b6cdf8af1d01807db06886f10177469312fbde8f44ccbb284bc9"},
|
{file = "cryptography-36.0.0-cp36-abi3-macosx_10_10_x86_64.whl", hash = "sha256:97199a13b772e74cdcdb03760c32109c808aff7cd49c29e9cf4b7754bb725d1d"},
|
||||||
{file = "cryptography-35.0.0-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:ced40344e811d6abba00295ced98c01aecf0c2de39481792d87af4fa58b7b4d6"},
|
{file = "cryptography-36.0.0-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:494106e9cd945c2cadfce5374fa44c94cfadf01d4566a3b13bb487d2e6c7959e"},
|
||||||
{file = "cryptography-35.0.0-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:54b2605e5475944e2213258e0ab8696f4f357a31371e538ef21e8d61c843c28d"},
|
{file = "cryptography-36.0.0-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:6fbbbb8aab4053fa018984bb0e95a16faeb051dd8cca15add2a27e267ba02b58"},
|
||||||
{file = "cryptography-35.0.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:7b7ceeff114c31f285528ba8b390d3e9cfa2da17b56f11d366769a807f17cbaa"},
|
{file = "cryptography-36.0.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:684993ff6f67000a56454b41bdc7e015429732d65a52d06385b6e9de6181c71e"},
|
||||||
{file = "cryptography-35.0.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2d69645f535f4b2c722cfb07a8eab916265545b3475fdb34e0be2f4ee8b0b15e"},
|
{file = "cryptography-36.0.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4c702855cd3174666ef0d2d13dcc879090aa9c6c38f5578896407a7028f75b9f"},
|
||||||
{file = "cryptography-35.0.0-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a2d0e0acc20ede0f06ef7aa58546eee96d2592c00f450c9acb89c5879b61992"},
|
{file = "cryptography-36.0.0-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d91bc9f535599bed58f6d2e21a2724cb0c3895bf41c6403fe881391d29096f1d"},
|
||||||
{file = "cryptography-35.0.0-cp36-abi3-manylinux_2_24_x86_64.whl", hash = "sha256:07bb7fbfb5de0980590ddfc7f13081520def06dc9ed214000ad4372fb4e3c7f6"},
|
{file = "cryptography-36.0.0-cp36-abi3-manylinux_2_24_x86_64.whl", hash = "sha256:b17d83b3d1610e571fedac21b2eb36b816654d6f7496004d6a0d32f99d1d8120"},
|
||||||
{file = "cryptography-35.0.0-cp36-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:7eba2cebca600a7806b893cb1d541a6e910afa87e97acf2021a22b32da1df52d"},
|
{file = "cryptography-36.0.0-cp36-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:8982c19bb90a4fa2aad3d635c6d71814e38b643649b4000a8419f8691f20ac44"},
|
||||||
{file = "cryptography-35.0.0-cp36-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:18d90f4711bf63e2fb21e8c8e51ed8189438e6b35a6d996201ebd98a26abbbe6"},
|
{file = "cryptography-36.0.0-cp36-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:24469d9d33217ffd0ce4582dfcf2a76671af115663a95328f63c99ec7ece61a4"},
|
||||||
{file = "cryptography-35.0.0-cp36-abi3-win32.whl", hash = "sha256:c10c797ac89c746e488d2ee92bd4abd593615694ee17b2500578b63cad6b93a8"},
|
{file = "cryptography-36.0.0-cp36-abi3-win32.whl", hash = "sha256:f6a5a85beb33e57998dc605b9dbe7deaa806385fdf5c4810fb849fcd04640c81"},
|
||||||
{file = "cryptography-35.0.0-cp36-abi3-win_amd64.whl", hash = "sha256:7075b304cd567694dc692ffc9747f3e9cb393cc4aa4fb7b9f3abd6f5c4e43588"},
|
{file = "cryptography-36.0.0-cp36-abi3-win_amd64.whl", hash = "sha256:2deab5ec05d83ddcf9b0916319674d3dae88b0e7ee18f8962642d3cde0496568"},
|
||||||
{file = "cryptography-35.0.0-pp36-pypy36_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:a688ebcd08250eab5bb5bca318cc05a8c66de5e4171a65ca51db6bd753ff8953"},
|
{file = "cryptography-36.0.0-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:2049f8b87f449fc6190350de443ee0c1dd631f2ce4fa99efad2984de81031681"},
|
||||||
{file = "cryptography-35.0.0-pp36-pypy36_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d99915d6ab265c22873f1b4d6ea5ef462ef797b4140be4c9d8b179915e0985c6"},
|
{file = "cryptography-36.0.0-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a776bae1629c8d7198396fd93ec0265f8dd2341c553dc32b976168aaf0e6a636"},
|
||||||
{file = "cryptography-35.0.0-pp36-pypy36_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:928185a6d1ccdb816e883f56ebe92e975a262d31cc536429041921f8cb5a62fd"},
|
{file = "cryptography-36.0.0-pp37-pypy37_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:aa94d617a4cd4cdf4af9b5af65100c036bce22280ebb15d8b5262e8273ebc6ba"},
|
||||||
{file = "cryptography-35.0.0-pp37-pypy37_pp73-macosx_10_10_x86_64.whl", hash = "sha256:ebeddd119f526bcf323a89f853afb12e225902a24d29b55fe18dd6fcb2838a76"},
|
{file = "cryptography-36.0.0-pp38-pypy38_pp73-macosx_10_10_x86_64.whl", hash = "sha256:5c49c9e8fb26a567a2b3fa0343c89f5d325447956cc2fc7231c943b29a973712"},
|
||||||
{file = "cryptography-35.0.0-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:22a38e96118a4ce3b97509443feace1d1011d0571fae81fc3ad35f25ba3ea999"},
|
{file = "cryptography-36.0.0-pp38-pypy38_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ef216d13ac8d24d9cd851776662f75f8d29c9f2d05cdcc2d34a18d32463a9b0b"},
|
||||||
{file = "cryptography-35.0.0-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eb80e8a1f91e4b7ef8b33041591e6d89b2b8e122d787e87eeb2b08da71bb16ad"},
|
{file = "cryptography-36.0.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:231c4a69b11f6af79c1495a0e5a85909686ea8db946935224b7825cfb53827ed"},
|
||||||
{file = "cryptography-35.0.0-pp37-pypy37_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:abb5a361d2585bb95012a19ed9b2c8f412c5d723a9836418fab7aaa0243e67d2"},
|
{file = "cryptography-36.0.0-pp38-pypy38_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:f92556f94e476c1b616e6daec5f7ddded2c082efa7cee7f31c7aeda615906ed8"},
|
||||||
{file = "cryptography-35.0.0-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:1ed82abf16df40a60942a8c211251ae72858b25b7421ce2497c2eb7a1cee817c"},
|
{file = "cryptography-36.0.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:d73e3a96c38173e0aa5646c31bf8473bc3564837977dd480f5cbeacf1d7ef3a3"},
|
||||||
{file = "cryptography-35.0.0.tar.gz", hash = "sha256:9933f28f70d0517686bd7de36166dda42094eac49415459d9bdf5e7df3e0086d"},
|
{file = "cryptography-36.0.0.tar.gz", hash = "sha256:52f769ecb4ef39865719aedc67b4b7eae167bafa48dbc2a26dd36fa56460507f"},
|
||||||
]
|
]
|
||||||
graphql-core = [
|
graphql-core-next = [
|
||||||
{file = "graphql-core-3.1.6.tar.gz", hash = "sha256:e65975b6a13878f9113a1fa5320760585b522d139944e005936b1b8358d0651a"},
|
{file = "GraphQL-core-next-1.1.1.tar.gz", hash = "sha256:76b52e7f654d8fc6abefc8583ebfd869a3939590813110ad27c0c0908b7d0659"},
|
||||||
{file = "graphql_core-3.1.6-py3-none-any.whl", hash = "sha256:c78d09596d347e1cffd266c5384abfedf43ed1eae08729773bebb3d527fe5a14"},
|
{file = "GraphQL_core_next-1.1.1-py3-none-any.whl", hash = "sha256:254187ad5f5acdfd521429d87fd3c05896dc1b74ddcb30b1fa37905dc1dc7c13"},
|
||||||
]
|
]
|
||||||
greenlet = [
|
greenlet = [
|
||||||
{file = "greenlet-1.1.2-cp27-cp27m-macosx_10_14_x86_64.whl", hash = "sha256:58df5c2a0e293bf665a51f8a100d3e9956febfbf1d9aaf8c0677cf70218910c6"},
|
{file = "greenlet-1.1.2-cp27-cp27m-macosx_10_14_x86_64.whl", hash = "sha256:58df5c2a0e293bf665a51f8a100d3e9956febfbf1d9aaf8c0677cf70218910c6"},
|
||||||
|
@ -715,12 +728,12 @@ html2text = [
|
||||||
{file = "html2text-2020.1.16.tar.gz", hash = "sha256:e296318e16b059ddb97f7a8a1d6a5c1d7af4544049a01e261731d2d5cc277bbb"},
|
{file = "html2text-2020.1.16.tar.gz", hash = "sha256:e296318e16b059ddb97f7a8a1d6a5c1d7af4544049a01e261731d2d5cc277bbb"},
|
||||||
]
|
]
|
||||||
httpcore = [
|
httpcore = [
|
||||||
{file = "httpcore-0.13.7-py3-none-any.whl", hash = "sha256:369aa481b014cf046f7067fddd67d00560f2f00426e79569d99cb11245134af0"},
|
{file = "httpcore-0.14.3-py3-none-any.whl", hash = "sha256:9a98d2416b78976fc5396ff1f6b26ae9885efbb3105d24eed490f20ab4c95ec1"},
|
||||||
{file = "httpcore-0.13.7.tar.gz", hash = "sha256:036f960468759e633574d7c121afba48af6419615d36ab8ede979f1ad6276fa3"},
|
{file = "httpcore-0.14.3.tar.gz", hash = "sha256:d10162a63265a0228d5807964bd964478cbdb5178f9a2eedfebb2faba27eef5d"},
|
||||||
]
|
]
|
||||||
httpx = [
|
httpx = [
|
||||||
{file = "httpx-0.20.0-py3-none-any.whl", hash = "sha256:33af5aad9bdc82ef1fc89219c1e36f5693bf9cd0ebe330884df563445682c0f8"},
|
{file = "httpx-0.21.1-py3-none-any.whl", hash = "sha256:208e5ef2ad4d105213463cfd541898ed9d11851b346473539a8425e644bb7c66"},
|
||||||
{file = "httpx-0.20.0.tar.gz", hash = "sha256:09606d630f070d07f9ff28104fbcea429ea0014c1e89ac90b4d8de8286c40e7b"},
|
{file = "httpx-0.21.1.tar.gz", hash = "sha256:02af20df486b78892a614a7ccd4e4e86a5409ec4981ab0e422c579a887acad83"},
|
||||||
]
|
]
|
||||||
idna = [
|
idna = [
|
||||||
{file = "idna-3.3-py3-none-any.whl", hash = "sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff"},
|
{file = "idna-3.3-py3-none-any.whl", hash = "sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff"},
|
||||||
|
@ -735,55 +748,59 @@ passlib = [
|
||||||
{file = "passlib-1.7.4.tar.gz", hash = "sha256:defd50f72b65c5402ab2c573830a6978e5f202ad0d984793c8dde2c4152ebe04"},
|
{file = "passlib-1.7.4.tar.gz", hash = "sha256:defd50f72b65c5402ab2c573830a6978e5f202ad0d984793c8dde2c4152ebe04"},
|
||||||
]
|
]
|
||||||
psycopg2 = [
|
psycopg2 = [
|
||||||
{file = "psycopg2-2.9.1-cp36-cp36m-win32.whl", hash = "sha256:7f91312f065df517187134cce8e395ab37f5b601a42446bdc0f0d51773621854"},
|
{file = "psycopg2-2.9.2-cp310-cp310-win32.whl", hash = "sha256:6796ac614412ce374587147150e56d03b7845c9e031b88aacdcadc880e81bb38"},
|
||||||
{file = "psycopg2-2.9.1-cp36-cp36m-win_amd64.whl", hash = "sha256:830c8e8dddab6b6716a4bf73a09910c7954a92f40cf1d1e702fb93c8a919cc56"},
|
{file = "psycopg2-2.9.2-cp310-cp310-win_amd64.whl", hash = "sha256:dfc32db6ce9ecc35a131320888b547199f79822b028934bb5b332f4169393e15"},
|
||||||
{file = "psycopg2-2.9.1-cp37-cp37m-win32.whl", hash = "sha256:89409d369f4882c47f7ea20c42c5046879ce22c1e4ea20ef3b00a4dfc0a7f188"},
|
{file = "psycopg2-2.9.2-cp36-cp36m-win32.whl", hash = "sha256:77d09a79f9739b97099d2952bbbf18eaa4eaf825362387acbb9552ec1b3fa228"},
|
||||||
{file = "psycopg2-2.9.1-cp37-cp37m-win_amd64.whl", hash = "sha256:7640e1e4d72444ef012e275e7b53204d7fab341fb22bc76057ede22fe6860b25"},
|
{file = "psycopg2-2.9.2-cp36-cp36m-win_amd64.whl", hash = "sha256:f65cba7924363e0d2f416041b48ff69d559548f2cb168ff972c54e09e1e64db8"},
|
||||||
{file = "psycopg2-2.9.1-cp38-cp38-win32.whl", hash = "sha256:079d97fc22de90da1d370c90583659a9f9a6ee4007355f5825e5f1c70dffc1fa"},
|
{file = "psycopg2-2.9.2-cp37-cp37m-win32.whl", hash = "sha256:b8816c6410fa08d2a022e4e38d128bae97c1855e176a00493d6ec62ccd606d57"},
|
||||||
{file = "psycopg2-2.9.1-cp38-cp38-win_amd64.whl", hash = "sha256:2c992196719fadda59f72d44603ee1a2fdcc67de097eea38d41c7ad9ad246e62"},
|
{file = "psycopg2-2.9.2-cp37-cp37m-win_amd64.whl", hash = "sha256:26322c3f114de1f60c1b0febf8fdd595c221b4f624524178f515d07350a71bd1"},
|
||||||
{file = "psycopg2-2.9.1-cp39-cp39-win32.whl", hash = "sha256:2087013c159a73e09713294a44d0c8008204d06326006b7f652bef5ace66eebb"},
|
{file = "psycopg2-2.9.2-cp38-cp38-win32.whl", hash = "sha256:77b9105ef37bc005b8ffbcb1ed6d8685bb0e8ce84773738aa56421a007ec5a7a"},
|
||||||
{file = "psycopg2-2.9.1-cp39-cp39-win_amd64.whl", hash = "sha256:bf35a25f1aaa8a3781195595577fcbb59934856ee46b4f252f56ad12b8043bcf"},
|
{file = "psycopg2-2.9.2-cp38-cp38-win_amd64.whl", hash = "sha256:91c7fd0fe9e6c118e8ff5b665bc3445781d3615fa78e131d0b4f8c85e8ca9ec8"},
|
||||||
{file = "psycopg2-2.9.1.tar.gz", hash = "sha256:de5303a6f1d0a7a34b9d40e4d3bef684ccc44a49bbe3eb85e3c0bffb4a131b7c"},
|
{file = "psycopg2-2.9.2-cp39-cp39-win32.whl", hash = "sha256:a761b60da0ecaf6a9866985bcde26327883ac3cdb90535ab68b8d784f02b05ef"},
|
||||||
|
{file = "psycopg2-2.9.2-cp39-cp39-win_amd64.whl", hash = "sha256:fd7ddab7d6afee4e21c03c648c8b667b197104713e57ec404d5b74097af21e31"},
|
||||||
|
{file = "psycopg2-2.9.2.tar.gz", hash = "sha256:a84da9fa891848e0270e8e04dcca073bc9046441eeb47069f5c0e36783debbea"},
|
||||||
]
|
]
|
||||||
psycopg2-binary = [
|
psycopg2-binary = [
|
||||||
{file = "psycopg2-binary-2.9.1.tar.gz", hash = "sha256:b0221ca5a9837e040ebf61f48899926b5783668b7807419e4adae8175a31f773"},
|
{file = "psycopg2-binary-2.9.2.tar.gz", hash = "sha256:234b1f48488b2f86aac04fb00cb04e5e9bcb960f34fa8a8e41b73149d581a93b"},
|
||||||
{file = "psycopg2_binary-2.9.1-cp310-cp310-macosx_10_14_x86_64.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl", hash = "sha256:24b0b6688b9f31a911f2361fe818492650795c9e5d3a1bc647acbd7440142a4f"},
|
{file = "psycopg2_binary-2.9.2-cp310-cp310-macosx_10_14_x86_64.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl", hash = "sha256:c0e1fb7097ded2cc44d9037cfc68ad86a30341261492e7de95d180e534969fb2"},
|
||||||
{file = "psycopg2_binary-2.9.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:542875f62bc56e91c6eac05a0deadeae20e1730be4c6334d8f04c944fcd99759"},
|
{file = "psycopg2_binary-2.9.2-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:717525cdc97b23182ff6f470fb5bf6f0bc796b5a7000c6f6699d6679991e4a5e"},
|
||||||
{file = "psycopg2_binary-2.9.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:661509f51531ec125e52357a489ea3806640d0ca37d9dada461ffc69ee1e7b6e"},
|
{file = "psycopg2_binary-2.9.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3865d0cd919349c45603bd7e80249a382c5ecf8106304cfd153282adf9684b6a"},
|
||||||
{file = "psycopg2_binary-2.9.1-cp310-cp310-manylinux_2_24_aarch64.whl", hash = "sha256:d92272c7c16e105788efe2cfa5d680f07e34e0c29b03c1908f8636f55d5f915a"},
|
{file = "psycopg2_binary-2.9.2-cp310-cp310-manylinux_2_24_aarch64.whl", hash = "sha256:daf6b5c62eb738872d61a1fa740d7768904911ba5a7e055ed72169d379b58beb"},
|
||||||
{file = "psycopg2_binary-2.9.1-cp310-cp310-manylinux_2_24_ppc64le.whl", hash = "sha256:736b8797b58febabb85494142c627bd182b50d2a7ec65322983e71065ad3034c"},
|
{file = "psycopg2_binary-2.9.2-cp310-cp310-manylinux_2_24_ppc64le.whl", hash = "sha256:3ac83656ff4fbe7f2a956ab085e3eb1d678df54759965d509bdd6a06ce520d49"},
|
||||||
{file = "psycopg2_binary-2.9.1-cp36-cp36m-macosx_10_14_x86_64.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl", hash = "sha256:c250a7ec489b652c892e4f0a5d122cc14c3780f9f643e1a326754aedf82d9a76"},
|
{file = "psycopg2_binary-2.9.2-cp310-cp310-win32.whl", hash = "sha256:a04cfa231e7d9b63639e62166a4051cb47ca599fa341463fa3e1c48585fcee64"},
|
||||||
{file = "psycopg2_binary-2.9.1-cp36-cp36m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:aef9aee84ec78af51107181d02fe8773b100b01c5dfde351184ad9223eab3698"},
|
{file = "psycopg2_binary-2.9.2-cp310-cp310-win_amd64.whl", hash = "sha256:c6e16e085fe6dc6c099ee0be56657aa9ad71027465ef9591d302ba230c404c7e"},
|
||||||
{file = "psycopg2_binary-2.9.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:123c3fb684e9abfc47218d3784c7b4c47c8587951ea4dd5bc38b6636ac57f616"},
|
{file = "psycopg2_binary-2.9.2-cp36-cp36m-macosx_10_14_x86_64.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl", hash = "sha256:53912199abb626a7249c662e72b70b4f57bf37f840599cec68625171435790dd"},
|
||||||
{file = "psycopg2_binary-2.9.1-cp36-cp36m-manylinux_2_24_aarch64.whl", hash = "sha256:995fc41ebda5a7a663a254a1dcac52638c3e847f48307b5416ee373da15075d7"},
|
{file = "psycopg2_binary-2.9.2-cp36-cp36m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:029e09a892b9ebc3c77851f69ce0720e1b72a9c6850460cee49b14dfbf9ccdd2"},
|
||||||
{file = "psycopg2_binary-2.9.1-cp36-cp36m-manylinux_2_24_ppc64le.whl", hash = "sha256:fbb42a541b1093385a2d8c7eec94d26d30437d0e77c1d25dae1dcc46741a385e"},
|
{file = "psycopg2_binary-2.9.2-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db1b03c189f85b8df29030ad32d521dd7dcb862fd5f8892035314f5b886e70ce"},
|
||||||
{file = "psycopg2_binary-2.9.1-cp36-cp36m-win32.whl", hash = "sha256:20f1ab44d8c352074e2d7ca67dc00843067788791be373e67a0911998787ce7d"},
|
{file = "psycopg2_binary-2.9.2-cp36-cp36m-manylinux_2_24_aarch64.whl", hash = "sha256:2eecbdc5fa5886f2dd6cc673ce4291cc0fb8900965315268960ad9c2477f8276"},
|
||||||
{file = "psycopg2_binary-2.9.1-cp36-cp36m-win_amd64.whl", hash = "sha256:f6fac64a38f6768e7bc7b035b9e10d8a538a9fadce06b983fb3e6fa55ac5f5ce"},
|
{file = "psycopg2_binary-2.9.2-cp36-cp36m-manylinux_2_24_ppc64le.whl", hash = "sha256:a77e98c68b0e6c51d4d6a994d22b30e77276cbd33e4aabdde03b9ad3a2c148aa"},
|
||||||
{file = "psycopg2_binary-2.9.1-cp37-cp37m-macosx_10_14_x86_64.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl", hash = "sha256:1e3a362790edc0a365385b1ac4cc0acc429a0c0d662d829a50b6ce743ae61b5a"},
|
{file = "psycopg2_binary-2.9.2-cp36-cp36m-win32.whl", hash = "sha256:bf31e6fdb4ec1f6d98a07f48836508ed6edd19b48b13bbf168fbc1bd014b4ca2"},
|
||||||
{file = "psycopg2_binary-2.9.1-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f8559617b1fcf59a9aedba2c9838b5b6aa211ffedecabca412b92a1ff75aac1a"},
|
{file = "psycopg2_binary-2.9.2-cp36-cp36m-win_amd64.whl", hash = "sha256:f9c37ecb173d76cf49e519133fd70851b8f9c38b6b8c1cb7fcfc71368d4cc6fc"},
|
||||||
{file = "psycopg2_binary-2.9.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a36c7eb6152ba5467fb264d73844877be8b0847874d4822b7cf2d3c0cb8cdcb0"},
|
{file = "psycopg2_binary-2.9.2-cp37-cp37m-macosx_10_14_x86_64.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl", hash = "sha256:a507db7758953b1b170c4310691a1a89877029b1e11b08ba5fc8ae3ddb35596b"},
|
||||||
{file = "psycopg2_binary-2.9.1-cp37-cp37m-manylinux_2_24_aarch64.whl", hash = "sha256:2f62c207d1740b0bde5c4e949f857b044818f734a3d57f1d0d0edc65050532ed"},
|
{file = "psycopg2_binary-2.9.2-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2e4bbcfb403221ea1953f3e0a85cef00ed15c1683a66cf35c956a7e37c33a4c4"},
|
||||||
{file = "psycopg2_binary-2.9.1-cp37-cp37m-manylinux_2_24_ppc64le.whl", hash = "sha256:cfc523edecddaef56f6740d7de1ce24a2fdf94fd5e704091856a201872e37f9f"},
|
{file = "psycopg2_binary-2.9.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f4dff0f15af6936c6fe6da7067b4216edbbe076ad8625da819cc066591b1133c"},
|
||||||
{file = "psycopg2_binary-2.9.1-cp37-cp37m-win32.whl", hash = "sha256:1e85b74cbbb3056e3656f1cc4781294df03383127a8114cbc6531e8b8367bf1e"},
|
{file = "psycopg2_binary-2.9.2-cp37-cp37m-manylinux_2_24_aarch64.whl", hash = "sha256:8d2aafe46eb87742425ece38130510fbb035787ee89a329af299029c4d9ae318"},
|
||||||
{file = "psycopg2_binary-2.9.1-cp37-cp37m-win_amd64.whl", hash = "sha256:1473c0215b0613dd938db54a653f68251a45a78b05f6fc21af4326f40e8360a2"},
|
{file = "psycopg2_binary-2.9.2-cp37-cp37m-manylinux_2_24_ppc64le.whl", hash = "sha256:37c8f00f7a2860bac9f7a54f03c243fc1dd9b367e5b2b52f5a02e5f4e9d8c49b"},
|
||||||
{file = "psycopg2_binary-2.9.1-cp38-cp38-macosx_10_14_x86_64.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl", hash = "sha256:35c4310f8febe41f442d3c65066ca93cccefd75013df3d8c736c5b93ec288140"},
|
{file = "psycopg2_binary-2.9.2-cp37-cp37m-win32.whl", hash = "sha256:ef97578fab5115e3af4334dd3376dea3c3a79328a3314b21ec7ced02920b916d"},
|
||||||
{file = "psycopg2_binary-2.9.1-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8c13d72ed6af7fd2c8acbd95661cf9477f94e381fce0792c04981a8283b52917"},
|
{file = "psycopg2_binary-2.9.2-cp37-cp37m-win_amd64.whl", hash = "sha256:7e6bd4f532c2cd297b81114526176b240109a1c52020adca69c3f3226c65dc18"},
|
||||||
{file = "psycopg2_binary-2.9.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:14db1752acdd2187d99cb2ca0a1a6dfe57fc65c3281e0f20e597aac8d2a5bd90"},
|
{file = "psycopg2_binary-2.9.2-cp38-cp38-macosx_10_14_x86_64.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl", hash = "sha256:eeee7b18c51d02e49bf1984d7af26e8843fe68e31fa1cbab5366ebdfa1c89ade"},
|
||||||
{file = "psycopg2_binary-2.9.1-cp38-cp38-manylinux_2_24_aarch64.whl", hash = "sha256:aed4a9a7e3221b3e252c39d0bf794c438dc5453bc2963e8befe9d4cd324dff72"},
|
{file = "psycopg2_binary-2.9.2-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:497372cc76e6cbce2f51b37be141f360a321423c03eb9be45524b1d123f4cd11"},
|
||||||
{file = "psycopg2_binary-2.9.1-cp38-cp38-manylinux_2_24_ppc64le.whl", hash = "sha256:da113b70f6ec40e7d81b43d1b139b9db6a05727ab8be1ee559f3a69854a69d34"},
|
{file = "psycopg2_binary-2.9.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5671699aff57d22a245b7f4bba89e3de97dc841c5e98bd7f685429b2b20eca47"},
|
||||||
{file = "psycopg2_binary-2.9.1-cp38-cp38-win32.whl", hash = "sha256:4235f9d5ddcab0b8dbd723dca56ea2922b485ea00e1dafacf33b0c7e840b3d32"},
|
{file = "psycopg2_binary-2.9.2-cp38-cp38-manylinux_2_24_aarch64.whl", hash = "sha256:b9d45374ba98c1184df9cce93a0b766097544f8bdfcd5de83ff10f939c193125"},
|
||||||
{file = "psycopg2_binary-2.9.1-cp38-cp38-win_amd64.whl", hash = "sha256:988b47ac70d204aed01589ed342303da7c4d84b56c2f4c4b8b00deda123372bf"},
|
{file = "psycopg2_binary-2.9.2-cp38-cp38-manylinux_2_24_ppc64le.whl", hash = "sha256:a1852c5bef7e5f52bd43fde5eda610d4df0fb2efc31028150933e84b4140d47a"},
|
||||||
{file = "psycopg2_binary-2.9.1-cp39-cp39-macosx_10_14_x86_64.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl", hash = "sha256:7360647ea04db2e7dff1648d1da825c8cf68dc5fbd80b8fb5b3ee9f068dcd21a"},
|
{file = "psycopg2_binary-2.9.2-cp38-cp38-win32.whl", hash = "sha256:108b0380969ddab7c8ef2a813a57f87b308b2f88ec15f1a1e7b653964a3cfb25"},
|
||||||
{file = "psycopg2_binary-2.9.1-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ca86db5b561b894f9e5f115d6a159fff2a2570a652e07889d8a383b5fae66eb4"},
|
{file = "psycopg2_binary-2.9.2-cp38-cp38-win_amd64.whl", hash = "sha256:14427437117f38e65f71db65d8eafd0e86837be456567798712b8da89db2b2dd"},
|
||||||
{file = "psycopg2_binary-2.9.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5ced67f1e34e1a450cdb48eb53ca73b60aa0af21c46b9b35ac3e581cf9f00e31"},
|
{file = "psycopg2_binary-2.9.2-cp39-cp39-macosx_10_14_x86_64.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl", hash = "sha256:578c279cd1ce04f05ae0912530ece00bab92854911808e5aec27588aba87e361"},
|
||||||
{file = "psycopg2_binary-2.9.1-cp39-cp39-manylinux_2_24_aarch64.whl", hash = "sha256:0f2e04bd2a2ab54fa44ee67fe2d002bb90cee1c0f1cc0ebc3148af7b02034cbd"},
|
{file = "psycopg2_binary-2.9.2-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4c2dea4deac3dd3687e32daeb0712ee96c535970dfdded37a11de6a21145ab0e"},
|
||||||
{file = "psycopg2_binary-2.9.1-cp39-cp39-manylinux_2_24_ppc64le.whl", hash = "sha256:3242b9619de955ab44581a03a64bdd7d5e470cc4183e8fcadd85ab9d3756ce7a"},
|
{file = "psycopg2_binary-2.9.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b592f09ff18cfcc9037b9a976fcd62db48cae9dbd5385f2471d4c2ba40c52b4d"},
|
||||||
{file = "psycopg2_binary-2.9.1-cp39-cp39-win32.whl", hash = "sha256:0b7dae87f0b729922e06f85f667de7bf16455d411971b2043bbd9577af9d1975"},
|
{file = "psycopg2_binary-2.9.2-cp39-cp39-manylinux_2_24_aarch64.whl", hash = "sha256:3a320e7a804f3886a599fea507364aaafbb8387027fffcdfbd34d96316c806c7"},
|
||||||
{file = "psycopg2_binary-2.9.1-cp39-cp39-win_amd64.whl", hash = "sha256:b4d7679a08fea64573c969f6994a2631908bb2c0e69a7235648642f3d2e39a68"},
|
{file = "psycopg2_binary-2.9.2-cp39-cp39-manylinux_2_24_ppc64le.whl", hash = "sha256:7585ca73dcfe326f31fafa8f96e6bb98ea9e9e46c7a1924ec8101d797914ae27"},
|
||||||
|
{file = "psycopg2_binary-2.9.2-cp39-cp39-win32.whl", hash = "sha256:9c0aaad07941419926b9bd00171e49fe6b06e42e5527fb91671e137fe6c93d77"},
|
||||||
|
{file = "psycopg2_binary-2.9.2-cp39-cp39-win_amd64.whl", hash = "sha256:aa2847d8073951dbc84c4f8b32c620764db3c2eb0d99a04835fecfab7d04816e"},
|
||||||
]
|
]
|
||||||
pycparser = [
|
pycparser = [
|
||||||
{file = "pycparser-2.20-py2.py3-none-any.whl", hash = "sha256:7582ad22678f0fcd81102833f60ef8d0e57288b6b5fb00323d101be910e35705"},
|
{file = "pycparser-2.21-py2.py3-none-any.whl", hash = "sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9"},
|
||||||
{file = "pycparser-2.20.tar.gz", hash = "sha256:2d475327684562c3a96cc71adf7dc8c4f0565175cf86b6d7a404ff4c771f15f0"},
|
{file = "pycparser-2.21.tar.gz", hash = "sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206"},
|
||||||
]
|
]
|
||||||
pydantic = [
|
pydantic = [
|
||||||
{file = "pydantic-1.8.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:05ddfd37c1720c392f4e0d43c484217b7521558302e7069ce8d318438d297739"},
|
{file = "pydantic-1.8.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:05ddfd37c1720c392f4e0d43c484217b7521558302e7069ce8d318438d297739"},
|
||||||
|
@ -873,59 +890,62 @@ sniffio = [
|
||||||
{file = "sniffio-1.2.0.tar.gz", hash = "sha256:c4666eecec1d3f50960c6bdf61ab7bc350648da6c126e3cf6898d8cd4ddcd3de"},
|
{file = "sniffio-1.2.0.tar.gz", hash = "sha256:c4666eecec1d3f50960c6bdf61ab7bc350648da6c126e3cf6898d8cd4ddcd3de"},
|
||||||
]
|
]
|
||||||
soupsieve = [
|
soupsieve = [
|
||||||
{file = "soupsieve-2.2.1-py3-none-any.whl", hash = "sha256:c2c1c2d44f158cdbddab7824a9af8c4f83c76b1e23e049479aa432feb6c4c23b"},
|
{file = "soupsieve-2.3.1-py3-none-any.whl", hash = "sha256:1a3cca2617c6b38c0343ed661b1fa5de5637f257d4fe22bd9f1338010a1efefb"},
|
||||||
{file = "soupsieve-2.2.1.tar.gz", hash = "sha256:052774848f448cf19c7e959adf5566904d525f33a3f8b6ba6f6f8f26ec7de0cc"},
|
{file = "soupsieve-2.3.1.tar.gz", hash = "sha256:b8d49b1cd4f037c7082a9683dfa1801aa2597fb11c3a1155b7a5b94829b4f1f9"},
|
||||||
]
|
]
|
||||||
sqlalchemy = [
|
sqlalchemy = [
|
||||||
{file = "SQLAlchemy-1.4.26-cp27-cp27m-macosx_10_14_x86_64.whl", hash = "sha256:c2f2114b0968a280f94deeeaa31cfbac9175e6ac7bd3058b3ce6e054ecd762b3"},
|
{file = "SQLAlchemy-1.4.27-cp27-cp27m-macosx_10_14_x86_64.whl", hash = "sha256:6afa9e4e63f066e0fd90a21db7e95e988d96127f52bfb298a0e9bec6999357a9"},
|
||||||
{file = "SQLAlchemy-1.4.26-cp27-cp27m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:91efbda4e6d311812f23996242bad7665c1392209554f8a31ec6db757456db5c"},
|
{file = "SQLAlchemy-1.4.27-cp27-cp27m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:ec1c908fa721f2c5684900cc8ff75555b1a5a2ae4f5a5694eb0e37a5263cea44"},
|
||||||
{file = "SQLAlchemy-1.4.26-cp27-cp27m-win32.whl", hash = "sha256:de996756d894a2d52c132742e3b6d64ecd37e0919ddadf4dc3981818777c7e67"},
|
{file = "SQLAlchemy-1.4.27-cp27-cp27m-win32.whl", hash = "sha256:0438bccc16349db2d5203598be6073175ce16d4e53b592d6e6cef880c197333e"},
|
||||||
{file = "SQLAlchemy-1.4.26-cp27-cp27m-win_amd64.whl", hash = "sha256:463ef692259ff8189be42223e433542347ae17e33f91c1013e9c5c64e2798088"},
|
{file = "SQLAlchemy-1.4.27-cp27-cp27m-win_amd64.whl", hash = "sha256:435b1980c1333ffe3ab386ad28d7b209590b0fa83ea8544d853e7a22f957331b"},
|
||||||
{file = "SQLAlchemy-1.4.26-cp27-cp27mu-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:c757ba1279b85b3460e72e8b92239dae6f8b060a75fb24b3d9be984dd78cfa55"},
|
{file = "SQLAlchemy-1.4.27-cp27-cp27mu-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:486f7916ef77213103467924ef25f5ea1055ae901f385fe4d707604095fdf6a9"},
|
||||||
{file = "SQLAlchemy-1.4.26-cp310-cp310-macosx_10_14_x86_64.whl", hash = "sha256:c24c01dcd03426a5fe5ee7af735906bec6084977b9027a3605d11d949a565c01"},
|
{file = "SQLAlchemy-1.4.27-cp310-cp310-macosx_10_14_x86_64.whl", hash = "sha256:d81c84c9d2523b3ea20f8e3aceea68615768a7464c0f9a9899600ce6592ec570"},
|
||||||
{file = "SQLAlchemy-1.4.26-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c46f013ff31b80cbe36410281675e1fb4eaf3e25c284fd8a69981c73f6fa4cb4"},
|
{file = "SQLAlchemy-1.4.27-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5881644fc51af7b232ab8d64f75c0f32295dfe88c2ee188023795cdbd4cf99b"},
|
||||||
{file = "SQLAlchemy-1.4.26-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:fb2aa74a6e3c2cebea38dd21633671841fbe70ea486053cba33d68e3e22ccc0a"},
|
{file = "SQLAlchemy-1.4.27-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:24828c5e74882cf41516740c0b150702bee4c6817d87d5c3d3bafef2e6896f80"},
|
||||||
{file = "SQLAlchemy-1.4.26-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad7e403fc1e3cb76e802872694e30d6ca6129b9bc6ad4e7caa48ca35f8a144f8"},
|
{file = "SQLAlchemy-1.4.27-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c7d0a1b1258efff7d7f2e6cfa56df580d09ba29d35a1e3f604f867e1f685feb2"},
|
||||||
{file = "SQLAlchemy-1.4.26-cp310-cp310-win32.whl", hash = "sha256:7ef421c3887b39c6f352e5022a53ac18de8387de331130481cb956b2d029cad6"},
|
{file = "SQLAlchemy-1.4.27-cp310-cp310-win32.whl", hash = "sha256:aadc6d1e58e14010ae4764d1ba1fd0928dbb9423b27a382ea3a1444f903f4084"},
|
||||||
{file = "SQLAlchemy-1.4.26-cp310-cp310-win_amd64.whl", hash = "sha256:908fad32c53b17aad12d722379150c3c5317c422437e44032256a77df1746292"},
|
{file = "SQLAlchemy-1.4.27-cp310-cp310-win_amd64.whl", hash = "sha256:9134e5810262203388b203c2022bbcbf1a22e89861eef9340e772a73dd9076fa"},
|
||||||
{file = "SQLAlchemy-1.4.26-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:1ef37c9ec2015ce2f0dc1084514e197f2f199d3dc3514190db7620b78e6004c8"},
|
{file = "SQLAlchemy-1.4.27-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:fa52534076394af7315306a8701b726a6521b591d95e8f4e5121c82f94790e8d"},
|
||||||
{file = "SQLAlchemy-1.4.26-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:090536fd23bf49077ee94ff97142bc5ee8bad24294c3d7c8d5284267c885dde7"},
|
{file = "SQLAlchemy-1.4.27-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2717ceae35e71de1f58b0d1ee7e773d3aab5c403c6e79e8d262277c7f7f95269"},
|
||||||
{file = "SQLAlchemy-1.4.26-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:e700d48056475d077f867e6a36e58546de71bdb6fdc3d34b879e3240827fefab"},
|
{file = "SQLAlchemy-1.4.27-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:2e93624d186ea7a738ada47314701c8830e0e4b021a6bce7fbe6f39b87ee1516"},
|
||||||
{file = "SQLAlchemy-1.4.26-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:295b90efef1278f27fe27d94a45460ae3c17f5c5c2b32c163e29c359740a1599"},
|
{file = "SQLAlchemy-1.4.27-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:987fe2f84ceaf744fa0e48805152abe485a9d7002c9923b18a4b2529c7bff218"},
|
||||||
{file = "SQLAlchemy-1.4.26-cp36-cp36m-win32.whl", hash = "sha256:cc6b21f19bc9d4cd77cbcba5f3b260436ce033f1053cea225b6efea2603d201e"},
|
{file = "SQLAlchemy-1.4.27-cp36-cp36m-win32.whl", hash = "sha256:2146ef996181e3d4dd20eaf1d7325eb62d6c8aa4dc1677c1872ddfa8561a47d9"},
|
||||||
{file = "SQLAlchemy-1.4.26-cp36-cp36m-win_amd64.whl", hash = "sha256:ba84026e84379326bbf2f0c50792f2ae56ab9c01937df5597b6893810b8ca369"},
|
{file = "SQLAlchemy-1.4.27-cp36-cp36m-win_amd64.whl", hash = "sha256:ad8ec6b69d03e395db48df8991aa15fce3cd23e378b73e01d46a26a6efd5c26d"},
|
||||||
{file = "SQLAlchemy-1.4.26-cp37-cp37m-macosx_10_14_x86_64.whl", hash = "sha256:f1e97c5f36b94542f72917b62f3a2f92be914b2cf33b80fa69cede7529241d2a"},
|
{file = "SQLAlchemy-1.4.27-cp37-cp37m-macosx_10_14_x86_64.whl", hash = "sha256:52f23a76544ed29573c0f3ee41f0ca1aedbab3a453102b60b540cc6fa55448ad"},
|
||||||
{file = "SQLAlchemy-1.4.26-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4c185c928e2638af9bae13acc3f70e0096eac76471a1101a10f96b80666b8270"},
|
{file = "SQLAlchemy-1.4.27-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fd421a14edf73cfe01e8f51ed8966294ee3b3db8da921cacc88e497fd6e977af"},
|
||||||
{file = "SQLAlchemy-1.4.26-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:bca660b76672e15d70a7dba5e703e1ce451a0257b6bd2028e62b0487885e8ae9"},
|
{file = "SQLAlchemy-1.4.27-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:10230364479429437f1b819a8839f1edc5744c018bfeb8d01320930f97695bc9"},
|
||||||
{file = "SQLAlchemy-1.4.26-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ff8f91a7b1c4a1c7772caa9efe640f2768828897044748f2458b708f1026e2d4"},
|
{file = "SQLAlchemy-1.4.27-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78943451ab3ffd0e27876f9cea2b883317518b418f06b90dadf19394534637e9"},
|
||||||
{file = "SQLAlchemy-1.4.26-cp37-cp37m-win32.whl", hash = "sha256:a95bf9c725012dcd7ea3cac16bf647054e0d62b31d67467d228338e6a163e4ff"},
|
{file = "SQLAlchemy-1.4.27-cp37-cp37m-win32.whl", hash = "sha256:a81e40dfa50ed3c472494adadba097640bfcf43db160ed783132045eb2093cb1"},
|
||||||
{file = "SQLAlchemy-1.4.26-cp37-cp37m-win_amd64.whl", hash = "sha256:07ac4461a1116b317519ddf6f34bcb00b011b5c1370ebeaaf56595504ffc7e84"},
|
{file = "SQLAlchemy-1.4.27-cp37-cp37m-win_amd64.whl", hash = "sha256:015511c52c650eebf1059ed8a21674d9d4ae567ebfd80fc73f8252faccd71864"},
|
||||||
{file = "SQLAlchemy-1.4.26-cp38-cp38-macosx_10_14_x86_64.whl", hash = "sha256:5039faa365e7522a8eb4736a54afd24a7e75dcc33b81ab2f0e6c456140f1ad64"},
|
{file = "SQLAlchemy-1.4.27-cp38-cp38-macosx_10_14_x86_64.whl", hash = "sha256:cc49fb8ff103900c20e4a9c53766c82a7ebbc183377fb357a8298bad216e9cdd"},
|
||||||
{file = "SQLAlchemy-1.4.26-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7e8ef103eaa72a857746fd57dda5b8b5961e8e82a528a3f8b7e2884d8506f0b7"},
|
{file = "SQLAlchemy-1.4.27-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9369f927f4d19b58322cfea8a51710a3f7c47a0e7f3398d94a4632760ecd74f6"},
|
||||||
{file = "SQLAlchemy-1.4.26-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:31f4426cfad19b5a50d07153146b2bcb372a279975d5fa39f98883c0ef0f3313"},
|
{file = "SQLAlchemy-1.4.27-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:6510f4a5029643301bdfe56b61e806093af2101d347d485c42a5535847d2c699"},
|
||||||
{file = "SQLAlchemy-1.4.26-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2feb028dc75e13ba93456a42ac042b255bf94dbd692bf80b47b22653bb25ccf8"},
|
{file = "SQLAlchemy-1.4.27-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:771eca9872b47a629010665ff92de1c248a6979b8d1603daced37773d6f6e365"},
|
||||||
{file = "SQLAlchemy-1.4.26-cp38-cp38-win32.whl", hash = "sha256:2ce42ad1f59eb85c55c44fb505f8854081ee23748f76b62a7f569cfa9b6d0604"},
|
{file = "SQLAlchemy-1.4.27-cp38-cp38-win32.whl", hash = "sha256:4d1d707b752137e6bf45720648e1b828d5e4881d690df79cca07f7217ea06365"},
|
||||||
{file = "SQLAlchemy-1.4.26-cp38-cp38-win_amd64.whl", hash = "sha256:dbf588ab09e522ac2cbd010919a592c6aae2f15ccc3cd9a96d01c42fbc13f63e"},
|
{file = "SQLAlchemy-1.4.27-cp38-cp38-win_amd64.whl", hash = "sha256:c035184af4e58e154b0977eea52131edd096e0754a88f7d5a847e7ccb3510772"},
|
||||||
{file = "SQLAlchemy-1.4.26-cp39-cp39-macosx_10_14_x86_64.whl", hash = "sha256:a6506c17b0b6016656783232d0bdd03fd333f1f654d51a14d93223f953903646"},
|
{file = "SQLAlchemy-1.4.27-cp39-cp39-macosx_10_14_x86_64.whl", hash = "sha256:bac949be7579fed824887eed6672f44b7c4318abbfb2004b2c6968818b535a2f"},
|
||||||
{file = "SQLAlchemy-1.4.26-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4a882dedb9dfa6f33524953c3e3d72bcf518a5defd6d5863150a821928b19ad3"},
|
{file = "SQLAlchemy-1.4.27-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4ac8306e04275d382d6393e557047b0a9d7ddf9f7ca5da9b3edbd9323ea75bd9"},
|
||||||
{file = "SQLAlchemy-1.4.26-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:1dee515578d04bc80c4f9a8c8cfe93f455db725059e885f1b1da174d91c4d077"},
|
{file = "SQLAlchemy-1.4.27-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:8327e468b1775c0dfabc3d01f39f440585bf4d398508fcbbe2f0d931c502337d"},
|
||||||
{file = "SQLAlchemy-1.4.26-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3c0c5f54560a92691d54b0768d67b4d3159e514b426cfcb1258af8c195577e8f"},
|
{file = "SQLAlchemy-1.4.27-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b02eee1577976acb4053f83d32b7826424f8b9f70809fa756529a52c6537eda4"},
|
||||||
{file = "SQLAlchemy-1.4.26-cp39-cp39-win32.whl", hash = "sha256:b86f762cee3709722ab4691981958cbec475ea43406a6916a7ec375db9cbd9e9"},
|
{file = "SQLAlchemy-1.4.27-cp39-cp39-win32.whl", hash = "sha256:5beeff18b4e894f6cb73c8daf2c0d8768844ef40d97032bb187d75b1ec8de24b"},
|
||||||
{file = "SQLAlchemy-1.4.26-cp39-cp39-win_amd64.whl", hash = "sha256:5c6774b34782116ad9bdec61c2dbce9faaca4b166a0bc8e7b03c2b870b121d94"},
|
{file = "SQLAlchemy-1.4.27-cp39-cp39-win_amd64.whl", hash = "sha256:8dbe5f639e6d035778ebf700be6d573f82a13662c3c2c3aa0f1dba303b942806"},
|
||||||
{file = "SQLAlchemy-1.4.26.tar.gz", hash = "sha256:6bc7f9d7d90ef55e8c6db1308a8619cd8f40e24a34f759119b95e7284dca351a"},
|
{file = "SQLAlchemy-1.4.27.tar.gz", hash = "sha256:d768359daeb3a86644f3854c6659e4496a3e6bba2b4651ecc87ce7ad415b320c"},
|
||||||
]
|
]
|
||||||
starlette = [
|
starlette = [
|
||||||
{file = "starlette-0.14.2-py3-none-any.whl", hash = "sha256:3c8e48e52736b3161e34c9f0e8153b4f32ec5d8995a3ee1d59410d92f75162ed"},
|
{file = "starlette-0.17.1-py3-none-any.whl", hash = "sha256:26a18cbda5e6b651c964c12c88b36d9898481cd428ed6e063f5f29c418f73050"},
|
||||||
{file = "starlette-0.14.2.tar.gz", hash = "sha256:7d49f4a27f8742262ef1470608c59ddbc66baf37c148e938c7038e6bc7a998aa"},
|
{file = "starlette-0.17.1.tar.gz", hash = "sha256:57eab3cc975a28af62f6faec94d355a410634940f10b30d68d31cb5ec1b44ae8"},
|
||||||
]
|
]
|
||||||
transliterate = [
|
transliterate = [
|
||||||
{file = "transliterate-1.10.2-py2.py3-none-any.whl", hash = "sha256:010a5021bf6021689c4fade0985f3f7b3db1f2f16a48a09a56797f171c08ed42"},
|
{file = "transliterate-1.10.2-py2.py3-none-any.whl", hash = "sha256:010a5021bf6021689c4fade0985f3f7b3db1f2f16a48a09a56797f171c08ed42"},
|
||||||
{file = "transliterate-1.10.2.tar.gz", hash = "sha256:bc608e0d48e687db9c2b1d7ea7c381afe0d1849cad216087d8e03d8d06a57c85"},
|
{file = "transliterate-1.10.2.tar.gz", hash = "sha256:bc608e0d48e687db9c2b1d7ea7c381afe0d1849cad216087d8e03d8d06a57c85"},
|
||||||
]
|
]
|
||||||
|
typing = [
|
||||||
|
{file = "typing-3.7.4.3-py2-none-any.whl", hash = "sha256:283d868f5071ab9ad873e5e52268d611e851c870a2ba354193026f2dfb29d8b5"},
|
||||||
|
{file = "typing-3.7.4.3.tar.gz", hash = "sha256:1187fb9c82fd670d10aa07bbb6cfcfe4bdda42d6fab8d5134f04e8c4d0b71cc9"},
|
||||||
|
]
|
||||||
typing-extensions = [
|
typing-extensions = [
|
||||||
{file = "typing_extensions-3.10.0.2-py2-none-any.whl", hash = "sha256:d8226d10bc02a29bcc81df19a26e56a9647f8b0a6d4a83924139f4a8b01f17b7"},
|
{file = "typing_extensions-4.0.0-py3-none-any.whl", hash = "sha256:829704698b22e13ec9eaf959122315eabb370b0884400e9818334d8b677023d9"},
|
||||||
{file = "typing_extensions-3.10.0.2-py3-none-any.whl", hash = "sha256:f1d25edafde516b146ecd0613dabcc61409817af4766fbbcfb8d1ad4ec441a34"},
|
{file = "typing_extensions-4.0.0.tar.gz", hash = "sha256:2cdf80e4e04866a9b3689a51869016d36db0814d84b8d8a568d22781d45d27ed"},
|
||||||
{file = "typing_extensions-3.10.0.2.tar.gz", hash = "sha256:49f75d16ff11f1cd258e1b988ccff82a3ca5570217d7ad8c5f48205dd99a677e"},
|
|
||||||
]
|
]
|
||||||
urllib3 = [
|
urllib3 = [
|
||||||
{file = "urllib3-1.26.7-py2.py3-none-any.whl", hash = "sha256:c4fdf4019605b6e5423637e01bc9fe4daef873709a7973e195ceba0a62bbc844"},
|
{file = "urllib3-1.26.7-py2.py3-none-any.whl", hash = "sha256:c4fdf4019605b6e5423637e01bc9fe4daef873709a7973e195ceba0a62bbc844"},
|
||||||
|
|
Loading…
Reference in New Issue
Block a user