def run_template(self) -> None: """Send a template based email.""" if self.message_file is not None: raise ArgumentError('cannot specify message file for template') if self.template not in templates: raise ArgumentError(f'template "{self.template}" not found') log.debug(f'using {self.template} template') Template = templates[self.template] if len(self.options) != Template.required: raise ArgumentError( f'"{self.template}" requires {Template.required} positional arguments ' f'but {len(self.options)} provided from --opts') self.mail = Template(*self.options, self.address, self.recipients, subject=self.subject, cc=self.cc, bcc=self.bcc, attach=self.attachments) if self.dry_run: print(self.mail) else: self.server.send(self.mail) self.log_message()
def __enter__(self) -> RefittDaemonApp: """Initialize resources.""" if not self.services_requested and not self.all_services: raise ArgumentError('No services specified') if self.services_requested and self.all_services: raise ArgumentError( 'Passing named services AND --all is redundant') return self
def check_names(self) -> None: """Validate table name arguments with --all flag.""" if self.names and self.all_names: raise ArgumentError('cannot use --all with named objects') if self.all_names: self.names = list(tables()) else: for name in self.names: if name not in tables(): raise ArgumentError(f'"{name}" is not a recognized table')
def check_arguments(self) -> None: """Additional logical validation of arguments.""" actions = 'gen_key', 'gen_secret', 'gen_token', 'revoke_all' actions_specified = map(functools.partial(getattr, self), actions) # noqa: typing? if not any(actions_specified): raise ArgumentError(f'Must specify action')
def run_basic(self) -> None: """Send a basic email without any template.""" if self.options: raise ArgumentError('cannot specify --opts w/out template') if self.message_file in (None, '-'): message = sys.stdin.read() else: with open(self.message_file, mode='r') as source: message = source.read() msg_type = 'text' if self.message_text else 'html' msg_form = {msg_type: message} self.mail = Mail(self.address, self.recipients, subject=self.subject, cc=self.cc, bcc=self.bcc, **{ **msg_form, 'attach': self.attachments }) if self.dry_run: print(self.mail) else: self.server.send(self.mail) self.log_message()
def request_method(self) -> Callable[..., dict]: """Bound method of `request` module by accessing named `method`.""" method = self.method.lower() try: return getattr(request, method) except AttributeError: raise ArgumentError(f'Method not supported \'{method}\'')
def check_args(self): """Validate method, position arguments, etc.""" for option in self.options: if '==' not in option: raise ArgumentError( f'Positional arguments should have assignment syntax, \'{option}\'' )
def empty_action(self) -> None: """Empty the trash folder and clear database.""" if self.paths: raise ArgumentError('unexpected arguments: ' + ', '.join(self.paths)) # unlink all files and folders in trash cursor = self.database.execute('SELECT * FROM TRASH') contents = cursor.fetchall() for *metadata, name, fullpath in contents: path = os.path.join(self.trash_path, name) if not os.path.exists(path): continue if os.path.isdir(path): rmdir(path) else: os.remove(path) log.ok(f'removed {len(contents)} items from {self.trash_path}') # purge database cursor.execute('DROP TABLE TRASH') cursor.execute(CREATE_TABLE) # so queries do not fail # warn on remaining items try: remaining = len(os.listdir(self.trash_path)) if remaining > 0: log.error(f'{remaining} items still in {self.trash_path}') except PermissionError: # NOTE: macOS pitches a fit trying reading ~/.Trash log.error(f'permission denied: could not list {self.trash_path}') return
def run(self) -> None: """Business logic for `config set`.""" site = SITE config_path = get_site() for key in ('local', 'user', 'system'): if getattr(self, key) is True: site = key init_config(key) config_path = get_site(key) if not os.path.exists(config_path): raise RuntimeError(f'{config_path} does not exist') # parse variable specification if '.' not in self.varpath: raise ArgumentError('missing section in variable path') section, *subsections, variable = self.varpath.split('.') config = {section: {}} config_section = config[section] for subsection in subsections: if subsection not in config_section: config_section[subsection] = dict() config_section = config_section[subsection] config_section[variable] = self.value update_config(site, config)
def get_client(self) -> Type[ClientInterface]: """Check for client interface based on name.""" try: return broker_map[self.broker] except KeyError as error: raise ArgumentError( f'No broker with name \'{self.broker}\'') from error
def run(self) -> None: """Show usage/help/version or defer to group.""" if self.resource in RESOURCES: status = RESOURCES[self.resource].main(sys.argv[3:]) raise CompletedCommand(status) else: raise ArgumentError(f'"{self.resource}" is not a GPU resource.')
def run(self) -> None: """Show usage/help/version or defer to group.""" if self.device in DEVICES: status = DEVICES[self.device].main(sys.argv[2:3]) raise CompletedCommand(status) else: raise ArgumentError(f'"{self.device}" is not a device.')
def get_path(target: str) -> Tuple[str, List[str]]: """The top-level table name and possibly the member relationship path.""" table, *relationships = target.split('.') if table not in tables: raise ArgumentError(f'Table does not exist, \'{table}\'') check_relation(tables[table], *relationships) return table, relationships
def run(self) -> None: """Show usage/help/version or defer to command.""" if self.command in COMMANDS: status = COMMANDS[self.command].main(sys.argv[4:]) raise CompletedCommand(status) else: raise ArgumentError(f'"{self.command}" is not a command.')
def list_action(self) -> None: """List files from database.""" if self.paths: raise ArgumentError('unexpected arguments: ' + ', '.join(self.paths)) cursor = self.database.execute('SELECT * FROM TRASH') for *metadata, name, fullpath in cursor.fetchall(): print(f'{name} -> {fullpath}')
def check_relation(target: Base, *path: str) -> Union[Base, Column]: try: if not path: return target else: if hasattr(target, 'relationships') and path[0] in target.relationships: return check_relation(target.relationships[path[0]], *path[1:]) else: return check_relation(getattr(target, path[0]), *path[1:]) except AttributeError as error: raise ArgumentError(str(error)) from error
def run(self) -> None: """Run monitor.""" if not self.format_csv and self.no_header: raise ArgumentError('--no-header only applies to --csv mode.') mem_attr = 'used' if self.memory_actual else 'percent' if not self.memory_actual and self.human_readable: raise ArgumentError('"--human-readable" only applies to "--actual" values.') log.handlers[0] = PLAIN_HANDLER if self.format_csv: log.handlers[0] = CSV_HANDLER if not self.no_header: print(f'timestamp,hostname,resource,memory_{mem_attr}') formatter = functools.partial(format_size, scale_units=self.human_readable) while True: time.sleep(self.sample_rate) value = getattr(psutil.virtual_memory(), mem_attr) log.debug(formatter(value))
def run(self) -> None: """Start REFITT Web-API server.""" if ((self.certfile is None and self.keyfile is not None) or (self.certfile is not None and self.keyfile is None)): raise ArgumentError( '--certfile and --keyfile must be specified together.') if self.dev_mode: api.run('localhost', self.port, debug=True) else: self.run_gunicorn()
def start(self) -> None: """Start service.""" if not self.is_locked: self.process = Popen( ['refitt', 'service', *shlex.split(self.argv)], stdout=sys.stdout, stderr=sys.stderr, cwd=self.cwd) self.started = datetime.now() self.lock() log.info(f'Started \'{self.name}\' service') else: raise ArgumentError( f'Service \'{self.name}\' already running ({self.pid})')
def run(self) -> None: """Run monitor.""" if not self.format_csv and self.no_header: raise ArgumentError('--no-header only applies to --csv mode.') log.handlers[0] = PLAIN_HANDLER if self.format_csv: log.handlers[0] = CSV_HANDLER if not self.no_header: print('timestamp,hostname,resource,gpu_id,gpu_percent') smi = SMIData() while True: time.sleep(self.sample_rate) for gpu_id, gpu_percent in smi.percent.items(): log.debug(f'[{gpu_id}] {gpu_percent}')
def start_services(self) -> None: """Load definitions and start services.""" if self.daemon_mode: self.run_daemon() config = self.get_config() if not self.services_requested: self.services_requested = list(config) else: for service in self.services_requested: if service not in config: raise ArgumentError( f'Service \'{service}\' not in configuration') for name in self.services_requested: self.services[name] = DaemonService(name, **config[name]) self.services[name].start()
def run(self) -> None: """Run monitor.""" if not self.format_csv and self.no_header: raise ArgumentError('--no-header only applies to --csv mode.') log.handlers[0] = PLAIN_HANDLER if self.format_csv: log.handlers[0] = CSV_HANDLER if not self.no_header: if not self.all_cores: print('timestamp,hostname,resource,cpu_percent') else: print('timestamp,hostname,resource,cpu_id,cpu_percent') if not self.all_cores: log_usage = functools.partial(cpu_total, log.debug) else: log_usage = functools.partial(cpu_per_core, log.debug) while True: time.sleep(self.sample_rate) log_usage()
def check_args(self): for option in self.filters: if '==' not in option: raise ArgumentError( f'Positional arguments should have equality syntax, \'{option}\'' )