Python
REST-API
asyncio
FUJITSUDay 16

大量のREST APIコールをasyncioで高速化してみた

これは Fujitsu Advent Calendar 2018 16日目 の記事です。(今年も大幅遅刻です。ごめんなさいごめんなさいごめんなさい。)

ほんでもって、時間切れが近いのでとりあえずソースだけ貼って一旦公開しますっ。解説は後で(できる限り25日のうちに)書く。(ごめんなさいごめんなさいごめんなさいごめんなさい。)

import asyncio

from functools import partial
import gitlab
from datetime import datetime
import config

def main():
gl = gitlab.Gitlab(config.gitlab_server, config.gitlab_token)
groups = gl.groups.list(all=True, as_list=True)
global loop
loop = asyncio.get_event_loop()
results = loop.run_until_complete(gather_results(groups))
progress('Finished')
for members in results:
for project in members:
print('%s: %d (%s)' %(project, len(members[project]), ','.join([m.username for m in members[project]])))
loop.close()

async def gather_results(groups):
coroutines = [asyncio.ensure_future(get_a_group(group)) for group in groups]
results = await asyncio.gather(*coroutines)
return results

async def get_a_group(group):
members = {}
progress('Start processing Group: %s' % group.full_path)
members[group.full_path] = await loop.run_in_executor(None, partial(group.members.list, all=True, as_list=True))
projects = await loop.run_in_executor(None, partial(group.projects.list, all=True, as_list=True))
for project in projects:
members[project.path] = await loop.run_in_executor(None, partial(group.members.list, all=True, as_list=True))
return members

def progress(msg):
print('%s: %s\n' %(datetime.now().isoformat(), msg))

if __name__ == '__main__':
main()

教訓: 暮れも押し迫りイベント目白押しなこの時期にアドカレ書いてる時間なんかとれんがな。(11月中に書きましょう。)