def read_from_file(file_name): if not path.exists(file_name): raise typer.BadParameter( '{0} can not be found, please specify the full path'.format( file_name)) if file_name.endswith('.txt'): with open(file_name, 'r') as file: keywords = file.read().split('\n') keywords = [ keyword.strip('"').strip("'").strip(' ').strip('\n').strip( '\t').strip() for keyword in keywords if keyword ] print(keywords) return keywords elif file_name.endswith('.csv'): with open(file_name, 'r') as file: csv_content = file.read().split('\n') keywords = [ keyword.split(',')[0].strip('"').strip("'").strip("`").strip( ' ').strip('\n').strip('\t').strip() for keyword in csv_content if keyword ] print(keywords) return keywords else: raise typer.BadParameter('File should be TXT or CSV')
def export_file(export_to_file, final_response, delimiter): full_path = '' if len(export_to_file.split('/')) == 1: save_path = os.getenv('SEO_DO_SAVE_TO') if not save_path: save_path = os.path.expanduser('~') else: if not path.exists(save_path): raise typer.BadParameter( '{0}, No such directory, please check it again'.format( save_path)) save_path = save_path if save_path.endswith('/') else save_path + '/' full_path = save_path + export_to_file else: save_path = '/'.join(export_to_file.split('/')[:-1]) if not path.exists(save_path): raise typer.BadParameter( '{0}, No such directory, please check it again'.format( save_path)) full_path = export_to_file with open(full_path, 'w') as file: writer = csv.writer(file, delimiter=delimiter) writer.writerows(final_response)
def eve_esi( ctx: typer.Context, version: str = typer.Option( "latest", "--version", help="Esi schema version to load from Eve Esi Jobs app data directory", ), schema_path: Optional[Path] = typer.Option( None, "--schema-path", "-s", help="Path to local schema file." ), ): """ Welcome to Eve Esi Jobs. Get started by downloading a schema, or checkout the docs at: https://eve-esi-jobs.readthedocs.io/en/latest/ """ config = make_config_from_env() typer.echo(f"Logging at {config.log_path}") ctx.obj = {} start = perf_counter_ns() ctx.obj["start_time"] = start logger.info("loading schema") ctx.obj["config"] = config schema = None schema_source = "" if schema_path is not None: try: schema_text = schema_path.read_text() schema = json.loads(schema_text) typer.echo(f"Loaded schema from {schema_path}") schema_source = str(schema_path) except FileNotFoundError as ex: logger.exception("Error loading schema from file.") raise typer.BadParameter( f"Error loading schema from {schema_path}. " f"Error: {ex.__class__.__name__} msg: {ex}." ) else: schema = load_schema(config.app_dir, version) schema_source = str(config.app_dir) + f"version: {version}" if schema is None: typer.echo("Schema not found in app data, attempting to download.") typer.echo("Consider using `eve-esi schema download` to save a local copy,") typer.echo("or provide a valid local path to the schema.") schema = download_json(config.schema_url) schema_source = config.schema_url try: operation_manifest = OperationManifest(schema) except Exception as ex: logger.exception( "Tried to make operation_manifest with invalid schema. version: %s, source: %s, error: %s, msg: %s", version, schema_source, ex.__class__.__name__, ex, ) raise typer.BadParameter( "The provided schema was invalid. please try a different one." ) ctx.obj["operation_manifest"] = operation_manifest typer.echo(f"Loaded ESI schema version {operation_manifest.version}.\n")
def _base_principal_validator( principals: List[str], *, special_vals: AbstractSet[str] = frozenset()) -> List[str]: """ This validator ensures the principal IDs are valid UUIDs prefixed with valid Globus ID beginnings. It will optionally determine if a provided principal exists in a set of "special" values. """ groups_beginning = "urn:globus:groups:id:" auth_beginning = "urn:globus:auth:identity:" for p in principals: if special_vals and p in special_vals: continue valid_beggining = False for beggining in [groups_beginning, auth_beginning]: if p.startswith(beggining): uuid = p[len(beggining):] try: UUID(uuid, version=4) except ValueError: raise typer.BadParameter( f"Principal could not be parsed as a valid identifier: {p}" ) else: valid_beggining = True if not valid_beggining: raise typer.BadParameter( f"Principal could not be parsed as a valid identifier: {p}") return principals
def flow_input_validator(body: str) -> str: """ Flow inputs can be either YAML or JSON formatted We can encompass these with just the YAML load checking, but we need a more generic error message than is provided by the other validators """ # Callbacks are run regardless of whether an option was explicitly set. # Handle the scenario where the default value for an option is empty if not body: return body body = input_validator(body) try: yaml_body = yaml.safe_load(body) except yaml.YAMLError as e: raise typer.BadParameter(f"Invalid flow input: {e}") try: yaml_to_json = json.dumps(yaml_body) except TypeError as e: raise typer.BadParameter( f"Unable to translate flow input to JSON: {e}") return yaml_to_json
def getDbUrl(user: str, passwd: str, host: str, db: str) -> str: user = user or os.environ.get("MYSQL_USER") if not user: raise typer.BadParameter('user未指定') passwd = passwd if passwd is not None else os.environ.get("MYSQL_PASSWORD") if passwd is None: raise typer.BadParameter('passwd未指定') host = host or os.environ.get("MYSQL_HOST") if not host: raise typer.BadParameter('host未指定') db = db or os.environ.get("MYSQL_DATABASE") if not db: raise typer.BadParameter('db未指定') dbUrl = "mysql+mysqlconnector://%s:%s@%s/%s?charset=utf8mb4" % ( user, passwd, host, db, ) return dbUrl
def flow_display( flow_id: str = typer.Argument("", show_default=False), flow_definition: str = typer.Option( "", help= ("JSON or YAML representation of the Flow to display. May be provided as a filename " "or a raw string representing a JSON object or YAML definition."), callback=input_validator, show_default=False, ), output_format: ImageOutputFormat = typer.Option( ImageOutputFormat.json, "--format", "-f", help="Output display format.", case_sensitive=False, show_default=True, ), flows_endpoint: str = flows_env_var_option, ): """ Visualize a local or deployed Flow defintion. If providing a Flows's ID, You must have either created the Flow or be present in the Flow's "flow_viewers" list to view it. """ if not flow_definition and not flow_id: raise typer.BadParameter( "Either FLOW_ID or --flow_definition should be set.") if flow_definition and flow_id: raise typer.BadParameter( "Only one of FLOW_ID or --flow_definition should be set.") fc = create_flows_client(CLIENT_ID, flows_endpoint) rr = RequestRunner( functools.partial(fc.get_flow, flow_id), format=output_format, verbose=False, watch=False, ) if flow_id: result = rr.run() if result.is_api_error: rr.format = (output_format if output_format in { ImageOutputFormat.json, ImageOutputFormat.yaml } else ImageOutputFormat.json) rr.render(result) raise typer.Exit(1) else: flow_dict = result.data["definition"] else: flow_dict = process_input(flow_definition) if output_format in {ImageOutputFormat.json, ImageOutputFormat.yaml}: rr.render_as_result(flow_dict) else: output_format.visualize(flow_dict)
def manifest_callback(value: Path): if not value.exists(): raise typer.BadParameter(f"Manifest file '{value}' does not exist.") if not value.is_file(): raise typer.BadParameter(f"Given manifest '{value}' must be a file.") if not value.name.endswith(".json"): raise typer.BadParameter("Manifest must be in JSON format.") return value.resolve()
def validate_url(value: str) -> typing.Optional[str]: if not value: return None url = yarl.URL(value.strip().lower()) if url.host is None: raise typer.BadParameter(f"The host '{url.host}' is invalid") if url.scheme not in ("http", "https"): raise typer.BadParameter(f"The scheme '{url.scheme}' is not allowed") return value
def verify_tags(tags: List): tag_dict = {} try: for tag in tags: key, value = tag.split(",") if re.match(r"^\w+$", key) and re.match(r"^\w+$", value): tag_dict[key] = value else: raise typer.BadParameter(f"{key},{value}") return tag_dict except Exception as e: raise typer.BadParameter(e)
def workorder( ctx: typer.Context, path_in: str = typer.Argument(..., help="Path to the workorder file."), path_out: str = typer.Argument( "./tmp", help="Path to be prepended to the workorder output path."), dry_run: bool = typer.Option( False, "-d", "--dry-run", help=""" Not implemented yet. Dry-run will perform all operations up to but not including making the actual http requests. This will detect some missed settings and parameters, but does not find mistakes that can only be checked on the server, eg. a non-existant type_id. """, ), ): """Load a workorder and do it.""" if dry_run: typer.BadParameter("not implemented yet.") path_in = validate_input_path(path_in) file_path = Path(path_in) try: esi_work_order = EsiWorkOrder.deserialize_file(file_path) except Exception as ex: logger.exception( "Error deserializing workorder from file: %s. Error: %s, msg: %s", file_path, ex.__class__.__name__, ex, ) raise typer.BadParameter( f"Error decoding workorder at {file_path}, msg: {ex}") # NOTE: path is not checked with results of template values. path_out = validate_output_path(path_out) output_path_string = str(path_out / Path(esi_work_order.output_path)) esi_work_order.update_attributes({"ewo_output_path": output_path_string}) operation_manifest = ctx.obj["operation_manifest"] observer = EsiObserver() try: do_workorder(esi_work_order, operation_manifest, observers=[observer]) except Exception as ex: raise typer.BadParameter( f"Error doing the job. {ex.__class__.__name__}: {ex}") report_on_jobs(esi_work_order.jobs) report_finished_task(ctx)
def select_anime_slug(slug: Optional[str]) -> str: def get_choices(context: Dict[str, str]) -> List[Dict[str, Union[str, Anime]]]: animes = get_animes() if context.get("filter"): animes = filter_animes(context["filter"], animes=animes) return [ {"name": anime.full_title(), "value": anime} for anime in sorted((a for a in animes), key=lambda a: a.title) ] if slug is None: questions = [ { "type": "input", "name": "filter", "message": "Apply a filter (Press [ENTER] to ignore):", }, { "type": "list", "name": "anime", "message": "Select an anime:", "choices": get_choices, }, ] answers = prompt(questions) if "anime" not in answers: raise typer.BadParameter(f"No choice selected.") return answers["anime"].slug.slug return slug
def font_callback(value: bool): """ Does this font exist on this operating system? """ try: font = ImageFont.truetype(value) # noqa: F841 except OSError: raise typer.BadParameter(f"'{value}' font not found.") return value
def name_callback(ctx: typer.Context, value: str): if ctx.resilient_parsing: return typer.echo("Validating name") if value != "Camila": raise typer.BadParameter("Only Camila is allowed") return value
def set_env_key( key: str = typer.Argument( ..., help="Key to set. Must exist in config.", case_sensitive=False, callback=lambda x: x.upper(), ), value: str = typer.Argument(..., help="Value to set for key."), ): """ Set a configuration key/value pair. """ if key not in settings.fields: fields_list = "\n".join([k for k in settings.fields]) raise typer.BadParameter(f"{key}. Config options are: \n{fields_list}\n") res, _, _ = set_key(config_path, key, value) if res: console.print( f":thumbs_up_dark_skin_tone: Set {key} to {value}", style="bold green" ) else: console.print( f":thumbs_down_dark_skin_tone: Could not set {key} to {value}", style="bold red", )
def name_callback(ctx: typer.Context, param: typer.CallbackParam, value: str): if ctx.resilient_parsing: return print(f"Validating param: {param.name}") if value != "Camila": raise typer.BadParameter("Only Camila is allowed") return value
def validate_param_ranges(value: List[int]) -> List[int]: if len(value) % 2 == 0: return value raise typer.BadParameter( "Parameter ranges list must be of even length, " + "each odd element is the start of the range and the next one is the end of the range" )
def role_callback_breaks_completion(role:str): # This breaks completion typer.echo(f"Validating parameter: role") if role.upper() in VALID_ROLES: return role.upper() raise typer.BadParameter(f"Select one from {VALID_ROLES}")
def _process_flow_input(flow_input: str, input_format) -> Mapping[str, Any]: flow_input_dict = {} if flow_input is not None: if input_format is InputFormat.json: try: flow_input_dict = json.loads(flow_input) except json.JSONDecodeError as e: raise typer.BadParameter(f"Invalid JSON for input schema: {e}") elif input_format is InputFormat.yaml: try: flow_input_dict = yaml.safe_load(flow_input) except yaml.YAMLError as e: raise typer.BadParameter(f"Invalid YAML for input schema: {e}") return flow_input_dict
def validate_url(value): try: if value is not None: Site(url=value) return value except ValidationError as err: raise typer.BadParameter(str(err))
def multiservice( config_path: str = typer.Option('~/.multiservice.yml', '--config', '-c'), # noqa custom_command: str = typer.Option('', '--execute', '-e'), # noqa command: str = typer.Argument(...), # noqa services: Optional[List[str]] = typer.Argument(None), # noqa ) -> None: config = parse_config(config_path) if command == 'edit': editor = config.get('editor') if not editor: raise typer.BadParameter('Please set "editor" in the config') return run(f'{editor} {config_path}') elif command == 'execute': code = custom_command else: code = get_command_from_config(command=command, config=config) services = services or list(config['services']) code = wrap_command_in_template(command=code, config=config) execute_for_services(command=command, code=code, services=services, config=config)
def load_callbacks(file_path: Path) -> CallbackCollection: try: callback_collection = CallbackCollection.deserialize_file(file_path) return callback_collection except Exception as ex: raise typer.BadParameter( f"Error decoding callback string. {ex.__class__.__name__}, {ex}")
def get_params_from_file(file_path: Optional[Path]) -> Optional[List[Dict]]: if file_path is not None: if file_path.is_file(): file_data = load_data_file(file_path) if not isinstance(file_data, list): raise typer.BadParameter( f"{file_path} is not a list of dicts. 1") if not file_data: raise typer.BadParameter(f"{file_path} had no data.") if not isinstance(file_data[0], dict): raise typer.BadParameter( f"{file_path} is not a list of dicts.") return file_data raise typer.BadParameter(f"{file_path} is not a file.") return None
def make_storage_folder(path: Path) -> Path: try: path.mkdir(exist_ok=True) except FileNotFoundError as e: raise typer.BadParameter(f'No such file or directory: {path}') from e return path
def validate_board(value: str) -> str: parts = get_parts() if value in set(parts.keys()): return value raise typer.BadParameter( "Invalid board " + value + " available boards are: " + str(parts) )
def cli_observe( url: typing.Optional[str] = typer.Argument( default=None, file_okay=False, dir_okay=False, help="The URL to parse its hyperlinks", callback=validate_url), scheme: typing.Optional[str] = typer.Option( None, "-s", "--scheme", file_okay=False, dir_okay=False, help="The URL to parse its hyperlinks"), hostname: typing.Optional[str] = typer.Option( None, "-h", "--host", "--hostname", file_okay=False, dir_okay=False, help="The URL to parse its hyperlinks"), port: typing.Optional[int] = typer.Option( None, "-p", "--port", file_okay=False, dir_okay=False, help="The URL to parse its hyperlinks"), limit: int = typer.Option( 50, "-l", "--limit", min=0, file_okay=False, dir_okay=False, help="The limit of rows to show (value: 0 is means no limit)"), log_level: LogLevel = typer.Option( LogLevel.INFO, "--log-level", file_okay=False, dir_okay=False, help="The level of app logging", case_sensitive=False, callback=lambda v: v.upper(), )): configure_logging(log_level=log_level) if url is not None: return CommandProvider().provide_show_by_url(url=url, limit=limit) if scheme is not None and hostname is not None: return CommandProvider().provide_show_by_url_params(scheme=scheme, hostname=hostname, port=port, limit=limit) raise typer.BadParameter( "Neither URL nor scheme with hostname are passed in the parameters")
def list_topics(value: Optional[str]): if value is None: return value topics = value.split(",") for topic in topics: if topic not in TOPICS: raise typer.BadParameter(f"topic {topic} not recognized") return topics
def is_valid_date(date: str): try: validated_date = datetime.datetime.strptime(date, '%Y-%m-%d') if datetime.datetime.strptime(dt_now, '%Y-%m-%d') < validated_date: raise ValueError except ValueError: raise typer.BadParameter(INVALID_DATE_MESSAGE) return date
def validate_nearest_distance(value: int) -> int: if value < 0: raise typer.BadParameter( "Invalid distance value: " + str(value) + " non-negative integer expected" ) return value
def _url_callback(url: str) -> Union[str, None]: """Checks url is valid""" if url == "latest": return url if validators.url(url): return url else: raise typer.BadParameter(f"Please check {url} is a valid url")