如何通过批处理文件执行 Python 代码并传递参数 - 使用 argparse
Posted
技术标签:
【中文标题】如何通过批处理文件执行 Python 代码并传递参数 - 使用 argparse【英文标题】:How execute Python code and pass argument via Batch file -using argparse 【发布时间】:2021-07-06 04:08:24 【问题描述】:我正在尝试通过批处理文件执行 Python 代码,而无需将参数硬编码到 Python 行中。相反,我想在批处理本身上指定任何其他参数。 但是当我运行 .bat 文件时,什么都没有发生。
我的过程:
使用 -argparse 在 Python 代码中创建了一个用于查找参数和凭据的函数。
创建了一个“应该”提供参数和凭据的批处理文件。
Python代码中的函数:image2json.py
import os
import imghdr
import json
version = "1.0.0.1"
downscale = 2048
bytelimit = 9000000
countlimit = 16
inputdir = None
outputdir = None
authjson = None
def get_args() -> dict:
import argparse
# Parse external arguments, and return as dictionary
arg_parser = argparse.ArgumentParser()
arg_parser.add_argument(
"-i", "--inputpath",
required=True,
help="The path to the input folder.")
arg_parser.add_argument(
"-o",
"--outputpath",
required=True,
help="The path to the output folder.")
arg_parser.add_argument(
"-c",
"--credentials",
required=True,
help="The path to the credentials JSON-file.")
return vars(arg_parser.parse_args())
args = get_args()
inputdir = args['inputpath']
outputdir = args['outputpath']
authjson = args['credentials']
def load_image(file_path: str, flags=None):
import imageio
import cv2
ext = file_path[-3:].lower()
if ext != "gif":
return cv2.imread(file_path, flags)
else:
gif = imageio.mimread(file_path)
img = cv2.cvtColor(gif[0], cv2.COLOR_RGB2BGR)
return img
def build_error_json(message: str):
import json
error_dict = dict()
error_dict['error'] = message
serialized = json.dumps(error_dict)
return serialized
def batch_request(image_batch):
from google.cloud import vision_v1
from google.cloud.vision_v1 import enums
from google.cloud.vision_v1 import types
from google.protobuf.json_format import MessageToJson
annotator_client = vision_v1.ImageAnnotatorClient.from_service_account_json(authjson)
features = [
types.Feature(type=enums.Feature.Type.TEXT_DETECTION) #TEXT_DETECTION DOCUMENT_TEXT_DETECTION
]
requests = []
for name, image in image_batch.items():
request = types.AnnotateImageRequest(image = image, features = features)
requests.append(request)
response = annotator_client.batch_annotate_images(requests)
for name, annotation_response in zip(image_batch.keys(), response.responses):
out_json = os.path.join(outputdir, name + ".json")
if annotation_response.error.message:
print("Annotation Error: " + name)
serialized = build_error_json(response.error.message)
with open(out_json, "w") as o:
o.write(serialized)
continue
try:
if (len(annotation_response.full_text_annotation.text) > 0):
serialized = MessageToJson(annotation_response.full_text_annotation)
else:
serialized = build_error_json("Text not found.")
except Exception as e:
serialized = build_error_json(str(e))
print("Annotation Done: " + name)
with open(out_json, "w") as o:
o.write(serialized)
def get_credentials():
try:
auth = os.environ['GOOGLE_APPLICATION_CREDENTIALS']
except:
auth = None
if (authjson is not None):
print('The credentials taken from system environment')
return auth
dirname = os.path.dirname(os.path.realpath(__file__))
jsons = list()
(_, _, filenames) = next(os.walk(dirname))
for file in filenames:
if file.endswith(".json"):
jsons.append(os.path.join(dirname, file))
if (len(jsons) == 1):
print('The credentials taken from local json: ' + os.path.basename(jsons[0]))
return jsons[0]
else:
print('Credentials is not found. Please specify the credentials explicitly.')
return None
def detect_text_batch(imagefiles):
import io
import numpy as np
import tempfile
import cv2
from google.cloud.vision_v1 import types
with tempfile.TemporaryDirectory() as tmpdirname:
current_batch_size = 0
current_batch_images = dict()
for path in imagefiles:
image_name = os.path.basename(path)
try:
m = load_image(path, cv2.IMREAD_ANYCOLOR)
except Exception as e:
print("File opening error: " + image_name)
out_json = os.path.join(outputdir, image_name + ".json")
serialized = build_error_json(str(e))
continue
h, w = m.shape[:2]
maxside = max(w, h)
scale = downscale / maxside
if (scale < 1):
m = cv2.resize(m, dsize=(0, 0), fx=scale, fy=scale)
tmp_path = os.path.join(tmpdirname, image_name) + '.jpg'
cv2.imwrite(tmp_path, m, [int(cv2.IMWRITE_JPEG_QUALITY), 90])
if (os.path.exists(tmp_path)):
with io.open(tmp_path, 'rb') as image_file:
content = image_file.read()
size = len(content)
if (current_batch_size + size >= bytelimit or len(current_batch_images) == countlimit):
batch_request(current_batch_images)
current_batch_images.clear()
current_batch_size = 0
image = types.Image(content = content)
current_batch_size = current_batch_size + size
current_batch_images[image_name] = image
else:
#report error
print("Tempfile saving error: " + image_name)
out_json = os.path.join(outputdir, image_name + ".json")
serialized = build_error_json('Tempfile saving error! ' + image_name)
with open(out_json, "w") as o:
o.write(serialized)
if (len(current_batch_images) > 0):
batch_request(current_batch_images)
print('Version: ' + version)
args = get_args()
inputdir = args['inputpath']
outputdir = args['outputpath']
authjson = args['credentials']
if (authjson is None):
print('Credentials is not specified, starting auto search...')
authjson = get_credentials()
(_, _, filenames) = next(os.walk(inputdir))
imagefiles = list()
for filename in filenames:
fullpath = os.path.join(inputdir, filename)
if (imghdr.what(fullpath) is not None):
imagefiles.append(fullpath)
else:
print("Not an image: " + filename)
out_json = os.path.join(outputdir, filename + ".json")
serialized = build_error_json("Not an image.")
with open(out_json, "w") as o:
o.write(serialized)
if (len(imagefiles) > 0):
detect_text_batch(imagefiles)
批处理文件包含的内容:myStart.bat
python "image2json.py" -i "C:\Project\images" -o "C:\Project\json" -c "C:\Project\\VisionCredentials.json"
批处理文件显示运行没有错误,但 image2json.py 文件没有执行。
C:\WINDOWS\system32>python "C:\Project\image2json.py" -i ./images -o ./json -c VisionCredentials.json
Version: 1.0.0.1
Traceback (most recent call last):
File "C:\Project\image2json.py", line 202, in <module>
(_, _, filenames) = next(os.walk(inputdir))
StopIteration
目录截图:
Screenshot
我想问是否有人可以帮助我了解如何以最佳方式修复它。
目标是在运行“Start.bat”文件时执行“image2json.py”文件。 代码的概念是 OCR 结果。详解:使用 google vision API 将图像文件的文本提取为 JSON 文件。
这是我第一次提问所以请随时问我 添加/编辑任何缺失或让你觉得可能 帮助您理解主题。 提前致谢。
【问题讨论】:
那么您目前遇到的问题是什么?您需要告诉我们发生了什么/没有发生什么、错误代码等。%-i
中的%
的目的是什么?
好的,所以您需要做的一件事是将批处理文件重命名为其他名称。 start
是cmd
的内部命令。所以重命名为myStart.cmd
然后在batch-file
中使用以下行,看看会发生什么。 python "%~dp0image2json.py" -i ./images -o ./json -c VisionCredentials.json
您可以通过编辑在问题中发布您的错误吗?
我很确定这是权限错误,它会看到文件,但特别说打开它时出错。凭证 JSON 文件是否具有正确的凭证?你手动测试过这些文件吗?
是的,视觉 API 可以正常工作。凭据是正确的,我只是对其进行测试以确定。 prnt.sc/119nzpo
【参考方案1】:
set ARG1="-i ./images"
set ARG2="-o ./json"
set ARG3="-c VisionCredentials.json"
python C:\Project\image2json.py %ARG1% %ARG2% %ARG3%
试试这个。
【讨论】:
谢谢,重点是控制批处理文件中的参数。因此,即使 .py 文件的目录或位置发生变化,您也应该能够通过编辑批处理文件来处理它。以上是关于如何通过批处理文件执行 Python 代码并传递参数 - 使用 argparse的主要内容,如果未能解决你的问题,请参考以下文章
Python函数:使用批处理文件将参数从.txt文件传递给python函数并执行函数
Python核心技术与实战——十三|Python中参数传递机制