|
| 1 | +# coding: utf-8 |
| 2 | + |
| 3 | +from __future__ import unicode_literals, absolute_import |
| 4 | + |
| 5 | +from logging import Logger |
| 6 | +from multiprocessing import Manager, Process |
| 7 | +from os import getpid |
| 8 | + |
| 9 | +from boxsdk.auth.cooperatively_managed_oauth2 import CooperativelyManagedOAuth2 |
| 10 | +from boxsdk.network.logging_network import LoggingNetwork |
| 11 | +from boxsdk.util.log import setup_logging |
| 12 | +from boxsdk import Client |
| 13 | + |
| 14 | +from auth import authenticate, CLIENT_ID, CLIENT_SECRET |
| 15 | + |
| 16 | + |
| 17 | +def main(): |
| 18 | + # Create a multiprocessing manager to use as the token store |
| 19 | + global tokens, refresh_lock |
| 20 | + manager = Manager() |
| 21 | + tokens = manager.Namespace() |
| 22 | + refresh_lock = manager.Lock() |
| 23 | + |
| 24 | + # Authenticate in master process |
| 25 | + oauth2, tokens.access, tokens.refresh = authenticate(CooperativelyManagedOAuth2) |
| 26 | + |
| 27 | + # Create 2 worker processes and wait on them to finish |
| 28 | + workers = [] |
| 29 | + for _ in range(2): |
| 30 | + worker_process = Process(target=worker) |
| 31 | + worker_process.start() |
| 32 | + workers.append(worker_process) |
| 33 | + for worker_process in workers: |
| 34 | + worker_process.join() |
| 35 | + |
| 36 | + |
| 37 | +def _retrive_tokens(): |
| 38 | + return tokens.access, tokens.refresh |
| 39 | + |
| 40 | + |
| 41 | +def _store_tokens(access_token, refresh_token): |
| 42 | + tokens.access, tokens.refresh = access_token, refresh_token |
| 43 | + |
| 44 | + |
| 45 | +def worker(): |
| 46 | + # Set up a logging network, but use the LoggingProxy so we can see which PID is generating messages |
| 47 | + logger = setup_logging(name='boxsdk.network.{0}'.format(getpid())) |
| 48 | + logger_proxy = LoggerProxy(logger) |
| 49 | + logging_network = LoggingNetwork(logger) |
| 50 | + |
| 51 | + # Create a coop oauth2 instance. |
| 52 | + # Tokens will be retrieved from and stored to the multiprocessing Namespace. |
| 53 | + # A multiprocessing Lock will be used to synchronize token refresh. |
| 54 | + # The tokens from the master process are used for initial auth. |
| 55 | + # Whichever process needs to refresh |
| 56 | + oauth2 = CooperativelyManagedOAuth2( |
| 57 | + retrieve_tokens=_retrive_tokens, |
| 58 | + client_id=CLIENT_ID, |
| 59 | + client_secret=CLIENT_SECRET, |
| 60 | + store_tokens=_store_tokens, |
| 61 | + network_layer=logging_network, |
| 62 | + access_token=tokens.access, |
| 63 | + refresh_token=tokens.refresh, |
| 64 | + refresh_lock=refresh_lock, |
| 65 | + ) |
| 66 | + client = Client(oauth2, network_layer=logging_network) |
| 67 | + _do_work(client) |
| 68 | + |
| 69 | + |
| 70 | +def _do_work(client): |
| 71 | + # Do some work in a worker process. |
| 72 | + # To see token refresh, perhaps put this in a loop (and don't forget to sleep for a bit between requests). |
| 73 | + me = client.user(user_id='me').get() |
| 74 | + items = client.folder('0').get_items(10) |
| 75 | + |
| 76 | + |
| 77 | +class LoggerProxy(Logger): |
| 78 | + """ |
| 79 | + Proxy for a logger that injects the current PID before log messages. |
| 80 | + """ |
| 81 | + def __init__(self, logger): |
| 82 | + self._logger_log = logger._log |
| 83 | + logger._log = self._log |
| 84 | + self._preamble = 'PID {0}: '.format(getpid()) |
| 85 | + |
| 86 | + def _log(self, level, msg, args, exc_info=None, extra=None): |
| 87 | + msg = self._preamble + msg |
| 88 | + return self._logger_log(level, msg, args, exc_info=exc_info, extra=extra) |
| 89 | + |
| 90 | + |
| 91 | +if __name__ == '__main__': |
| 92 | + main() |
0 commit comments