#!/usr/bin/env -S uv run import argparse import asyncio import logging from pathlib import Path from typing import Any, Type from src.commands import create_migration, delete_auth0_users, prepare_users from src.file_processor.base import BaseAsyncFileProcessor, ReaderT, WriterT logging.basicConfig( format='[%(asctime)s][%(levelname)s] %(message)s', ) logger = logging.getLogger('users_cleanup') async def run_command(command_cls: Type[BaseAsyncFileProcessor[ReaderT, WriterT]], **kwargs: Any) -> None: command = command_cls(**kwargs) await command.process() def main() -> None: parser = argparse.ArgumentParser( 'Users Cleanup', description='Read the list of users from csv and deactivating them.' ) parser.add_argument('-v', '--verbose', action='store_true', default=False, help='Enable verbose mode.') subparsers = parser.add_subparsers() # ------------------------ PREPARE USERS ------------------------ prepare_parser = subparsers.add_parser('prepare', help='Prepare the list of users from csv.') prepare_parser.add_argument('--fi', required=True, type=Path, help='The file path to the input CSV.') prepare_parser.add_argument('--fo', type=Path, default=Path('result/validated.csv'), help='Path to results file.') prepare_parser.add_argument( '--email-key', type=str, default='email', help='The CSV column header for the email address.' ) prepare_parser.add_argument( '--concurrency', type=int, default=10, help='The number of concurrent processes to use.' ) prepare_parser.set_defaults(command=prepare_users.PrepareUsers) # ------------------------ DELETE AUTH0 USERS ------------------------ delete_auth0_parser = subparsers.add_parser('delete_auth0_users', help='Delete auth0 users based on validated csv') delete_auth0_parser.add_argument( '--fi', type=Path, default=Path('result/validated.csv'), help='The file path to the input CSV.' ) delete_auth0_parser.add_argument( '--fo', type=Path, default=Path('result/delete_auth0_users.csv'), help='Path to results file.' ) delete_auth0_parser.add_argument( '--concurrency', type=int, default=10, help='The number of concurrent processes to use.' ) delete_auth0_parser.add_argument( '-y', '--yes', dest='skip_confirmation', default=False, action='store_true', help='Do not ask for confirmation.' ) delete_auth0_parser.set_defaults(command=delete_auth0_users.DeleteAuth0Users) # ------------------------ CREATE MIGRATION ------------------------ migration_parser = subparsers.add_parser( 'create_migration', help='Create migration for neo4j based on validated csv.' ) migration_parser.add_argument( '--fi', type=Path, default=Path('result/validated.csv'), help='The file path to the input CSV.' ) migration_parser.add_argument( '--fo', type=Path, default=Path('result/migration.cypher'), help='Path to results file.' ) migration_parser.add_argument('--task_id', help='JIRA task id.', required=True) migration_parser.add_argument('--identifier', help='username', required=True) migration_parser.add_argument('--batch_size', type=int, default=1, help='Number of rows to process in batch.') migration_parser.add_argument('--changeset_suffix', type=str, default='', help='Suffix for changeset name.') migration_parser.set_defaults(concurrency=1, decider=create_migration.get_command_cls) # ------------------------ PROCESS ------------------------ args = vars(parser.parse_args()) is_verbose = args.pop('verbose') if is_verbose: logger.setLevel(logging.DEBUG) else: logger.setLevel(logging.INFO) if 'command' not in args and 'decider' not in args: raise ValueError('Must specify "command" or "decider"') command_cls = args.pop('command', None) if command_cls is None: decider = args.pop('decider') command_cls = decider(**args) asyncio.run(run_command(command_cls, **args)) if __name__ == '__main__': main()