如何在AWS Lambda上使用tabula阅读pdf?

2023-12-21

“我知道我们必须下载 Java 才能运行,我在 IDE 上执行了该操作,并且成功了。但不知道如何在 AWS Lambda 上下载它。如果有人能帮助我,我将不胜感激。

我认为代码本身产生了我所期望的结果,但是,java正是我所需要的。

这是我收到的错误:

`

'[ERROR] JavaNotFoundError: javacommand is not found from this Python process.Please ensure Java is installed and PATH is set forjavaTraceback (most recent call last): File "/var/task/lambda_function.py", line 30, in lambda_handler tables = tabula.read_pdf(io.BytesIO(file_content), pages='all') File "/opt/python/tabula/io.py", line 425, in read_pdf output = _run(java_options, tabula_options, path, encoding) File "/opt/python/tabula/io.py", line 99, in _run raise JavaNotFoundError(JAVA_NOT_FOUND_ERROR)'

            import json
            import boto3
            import pandas as pd
            import io
            import re
            import tabula
            import numpy as np
            def f_remove_accents(old):
                """
            #    Removes common accent characters, lower form.
            #    Uses: regex.
                """
                new = old.lower()
                new = re.sub(r'[àáâãäå]', 'a', new)
                new = re.sub(r'[èéêë]', 'e', new)
                new = re.sub(r'[ìíîï]', 'i', new)
                new = re.sub(r'[òóôõö]', 'o', new)
                new = re.sub(r'[ùúûü]', 'u', new)
                new = re.sub(r'[ç]', 'c', new)
                return new
            def lambda_handler(event, context):
                s3 = boto3.client("s3")
                if event:
                    s3_records = event["Records"][0]
                    bucket_name = str(s3_records["s3"]["bucket"]["name"])
                    file_name = str(s3_records["s3"]["object"]["key"])
                    file_obj = s3.get_object(Bucket=bucket_name, Key=file_name)
                    file_content = file_obj["Body"].read()
            
                    tables = tabula.read_pdf(io.BytesIO(file_content), pages='all')
            
            
                    # Create an empty DataFrame to store all the modified tables
                    modified_tables = []
            
                    # Apply functions to the content of each table
                    for table in tables:
                        # Convert the DataFrame to a NumPy array
                        table_array = table.values.astype(str)
            
                        # Remove accents
                        remove_accents_func = np.vectorize(f_remove_accents)
                        table_array = remove_accents_func(table_array)
            
                        # Replace ';' with ' '
                        table_array = np.char.replace(table_array, ';', ' ')
            
                        # Convert to upper case
                        table_array = np.char.upper(table_array)
            
                        # Create a new DataFrame with the modified array
                        modified_table = pd.DataFrame(table_array, columns=table.columns)
            
                        # Append the modified table to the list
                        modified_tables.append(modified_table)
            
                    # Concatenate all the modified tables into a single DataFrame
                    final_df = pd.concat(modified_tables, ignore_index=True)
            
                    # Save the final DataFrame as a CSV file
                    name_of_return_file = f'{file_name[:-4]}_return.csv'
                    final_df.to_csv(name_of_return_file, sep=';', index=False)
            
                    # Read the CSV file content
                    with open(name_of_return_file, 'rb') as file:
                        csv_content = file.read()
            
                    # Upload the CSV file to the destination bucket
                    s3.put_object(Body=csv_content, Bucket='bucket-recebendo', Key=name_of_return_file)

这就是我如何在 Lambda 上建立并运行表格。我使用了Lambda的OCI能力来打包需求。

首先,我使用 VSCode 创建文件夹结构来放置 lambda 函数和 Docker 文件。

我创建了一个名为“lambda_function.py”的文件,其中包含上面列出的代码。我创建了一个 pip requests.txt 文件,其中包含以下库(您不应该使用它,而应该使用固定版本,我这样做只是为了速度)

我确实必须更改您的代码,并且我进行了以下更改(导入语句)

import json
import boto3
import pandas as pd
import io
import re
from tabula.io import read_pdf
import numpy as np
..
..

因为我收到错误“AttributeError: module 'tabula' has no attribute 'read_pdf'”

pandas
numpy
tabula-py
boto3

然后我创建了我的 Docker 文件(非常粗糙,没有优化,只是为了引导它并让它运行 - 你肯定想改进它)

FROM public.ecr.aws/lambda/python:3.10
COPY requirements.txt ${LAMBDA_TASK_ROOT}
COPY lambda_function.py ${LAMBDA_TASK_ROOT}
RUN yum install java-17-amazon-corretto-devel -y
RUN pip install --upgrade pip
RUN pip install --no-cache-dir -r requirements.txt
CMD [ "lambda_function.lambda_handler" ]

这就是我的布局:

├── Dockerfile
├── lambda_function.py
└── requirements.txt

然后,我运行以下命令在本地构建容器映像,然后将其上传到亚马逊 ecr(我创建了一个 ecr 存储库)

docker build -t lambda-tabula:1.0.0 . 
aws ecr get-login-password --region eu-west-1 | docker login --username AWS --password-stdin xxxx.dkr.ecr.eu-west-1.amazonaws.com
docker tag lambda-tabula:1.0.0 xxxx.dkr.ecr.eu-west-1.amazonaws.com/lambda-oci-demo:1.0.1
docker push xxxx.dkr.ecr.eu-west-1.amazonaws.com/lambda-oci-demo:1.0.1

我现在在 ECR 中有我的图像,我可以通过 arn 引用它(“xxxxx.dkr.ecr.eu-west-1.amazonaws.com/lambda-oci-demo:1.0.0”)

然后,我创建了一个新的 Lambda 函数,指定 OCI 图像,然后指向该图像。我为该函数创建了一个角色,该角色也将提供对此特定 S3 存储桶的权限。

您可以在以下位置获取更多详细信息文档在这里 https://docs.aws.amazon.com/lambda/latest/dg/python-image.html

这允许该函数运行,尽管由于当前函数想要写入只读文件系统而失败并出现不同的错误,因此我将 name_of_return_file = f'{file_name[:-4]}_return.csv' 更改为 name_of_return_file = f'/tmp/{file_name[:-4]}_return.csv'

一旦我解决了这个问题,效果就很好。这是更新后的代码

import json
import boto3
import pandas as pd
import io
import re
from tabula.io import read_pdf
import numpy as np
def f_remove_accents(old):
            new = old.lower()
            new = re.sub(r'[àáâãäå]', 'a', new)
            new = re.sub(r'[èéêë]', 'e', new)
            new = re.sub(r'[ìíîï]', 'i', new)
            new = re.sub(r'[òóôõö]', 'o', new)
            new = re.sub(r'[ùúûü]', 'u', new)
            new = re.sub(r'[ç]', 'c', new)
            return new
def lambda_handler(event, context):
            s3 = boto3.client("s3")
            if event:
                    #s3_records = event["Records"][0]
                    #bucket_name = str(s3_records["s3"]["bucket"]["name"])
                    #file_name = str(s3_records["s3"]["object"]["key"])
                    #file_obj = s3.get_object(Bucket=bucket_name, Key=file_name)
                    file_obj = s3.get_object(Bucket="tabula-demo", Key="invoice.pdf")
                    file_content = file_obj["Body"].read()
            
                    tables = read_pdf(io.BytesIO(file_content), pages='all')
            
            
                    # Create an empty DataFrame to store all the modified tables
                    modified_tables = []
            
                    # Apply functions to the content of each table
                    for table in tables:
                        # Convert the DataFrame to a NumPy array
                        table_array = table.values.astype(str)
            
                        # Remove accents
                        remove_accents_func = np.vectorize(f_remove_accents)
                        table_array = remove_accents_func(table_array)
            
                        # Replace ';' with ' '
                        table_array = np.char.replace(table_array, ';', ' ')
            
                        # Convert to upper case
                        table_array = np.char.upper(table_array)
            
                        # Create a new DataFrame with the modified array
                        modified_table = pd.DataFrame(table_array, columns=table.columns)
            
                        # Append the modified table to the list
                        modified_tables.append(modified_table)
            
                    # Concatenate all the modified tables into a single DataFrame
                    final_df = pd.concat(modified_tables, ignore_index=True)
            
                    # Save the final DataFrame as a CSV file
                    #name_of_return_file = f'{file_name[:-4]}_return.csv'
                    name_of_return_file = '/tmp/test_return.csv'
                    final_df.to_csv(name_of_return_file, sep=';', index=False)
            
                    # Read the CSV file content
                    with open(name_of_return_file, 'rb') as file:
                        csv_content = file.read()
            
                    # Upload the CSV file to the destination bucket
                    s3.put_object(Body=csv_content, Bucket='094459-lambda-libs', Key=name_of_return_file)

笔记!我必须修改上面的代码,因为我对文件进行了硬编码,因为我不知道您的输入文件是什么。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在AWS Lambda上使用tabula阅读pdf? 的相关文章

随机推荐

  • PHP中的短语分割算法

    不知道如何解释 让我们举个例子 说我想拆分句子 今天是个好日子 into today today is today is a today is a great today is a great day is is a is a great
  • 如何将图像调色板缩小为特定颜色?

    我正在使用 Python 程序来创建十字绣方案 并且需要将图像中的颜色减少为特定的牙线颜色像这样 http www dmc usa com Products Needlework Threads Embroidery Threads med
  • javascript方法链中的输入参数是如何填充的?

    我正在尝试真正了解 javascript 工作原理的细节 在方法链接期间 有时一个方法会返回到另一个具有命名输入参数的方法 例如 在 D3 中 模式如下所示 d3 select body selectAll p data dataset e
  • 使用 Backbone.js 的 JS 模板系统

    我正在寻找一些好的模板系统 可以与 Backbone js 等 MVC 框架一起使用 我知道这样一个系统 jQuery 模板 然而 由于某些原因 它已经停止 因此我正在寻找其他一些不错的选择 请建议从视图角度足够灵活的东西 例如 基于某些逻
  • Spring Boot属性在初始化时加载,并尊重所有属性并根据属性文件中的值控制@Aspect

    我们正在使用从外部文件加载属性 PropertySources 现在我想启用 禁用 Aspect基于属性 我尝试使用 ConditionalOnExpression这不起作用 我通过创建一个 bean 进行了同样的尝试propertypla
  • “您可能需要一个额外的加载器来处理这些加载器的结果。”

    我目前正在尝试为 ReactJs 构建一个状态管理库 但是一旦我将它实现到我的 React 项目中 使用create react app 它开始丢弃此错误 Failed to compile path to agile dist runti
  • QProcess 在未 waitForFinished() 时不发出信号

    下面的代码中省略了waitForFinished 使 QProcess 停止发出信号 这到底是怎么回事 这是 Qt 的错误吗 5 7 请注意 此代码与 QtConcurrent 并行运行 但这不应该改变任何事情 不是吗 Afaik 在其他线
  • [decl.constexpr].5 到底是什么意思?

    该标准关于常量表达式函数 decl constexpr 第 5 点规定 对于非模板 非默认 constexpr 函数或非模板 非默认 非继承 constexpr 构造函数 如果不存在参数值 则函数或构造函数的调用可以是核心常量的计算子表达式
  • 导出到 Excel 不适用于 SSL (https) 下的 IE

    我一直在尝试修复安全网站 https 上的某些内容 该网站是一个生成 CSV 文件的 导出到 Excel 按钮 它适用于 Firefox Chrome 等 但不适用于 Internet Explorer 我已经更改了标头 消除了无缓存 还编
  • 自移动批处理文件

    我正在寻找一种方法让批处理文件在执行后将其自身移动到已知位置 自动移动 似乎是最恰当的名字 但我确信它有一个技术术语 我想移动批处理文件after所有其他代码都已运行 move C temp move me bat D temp move
  • 溢出的签名/未签名作业及其结果

    我正在阅读 Stroustrup 的书 C 编程语言第 4 版 并且有三个关于溢出赋值的问题 特别是对有符号 无符号字符 如书中所示 首先 根据标准5 4段 如果在计算表达式时 结果不是 数学定义或不在可表示值的范围内 它的类型 行为未定义
  • HTML5 svg 不工作

    我使用的是 Chrome 版本 5 0 375 55 和 Firefox 版本 3 5 9 但我无法获取下面的 HTML5 代码来显示一个框
  • VBA/VB6 集合到底是什么?

    对于整数键 索引速度为O N 所以看起来它是一个列表 但显然 wqw 的评论无法在 VB6 For Each 循环中正确循环键和值 https stackoverflow com q 57066954 1261153 字符串键的访问时间是O
  • subversion authz 路径包含空格

    如何为包含空格的路径设置 authz 文件 我尝试了各种方法来逃离这个空间 但都不起作用 some path some 20path some path some path 我刚刚检查了 svn 源代码和文件解析器 在 libsvn sub
  • 词干提取的逆过程

    我使用 lucene 雪球分析器来执行词干提取 结果是没有意义的话 我提到了这个question https stackoverflow com questions 190775 stemming algorithm that produc
  • 电话格式的 HTML 电话链接 [重复]

    这个问题在这里已经有答案了 我正在为手机制作一个 html 链接 这就是我所拥有的 a href 1 888 888 8888 a 手机会识别这一点 还是我需要将其更改为 a href 1 888 888 8888 a uri 中允许使用视
  • ASP.Net Core 上具有自动再生功能的内存缓存

    我想没有内置的方法可以实现这一点 我有一些缓存数据 需要始终保持最新 间隔几十分钟 它的生成大约需要 1 2 分钟 因此有时会导致请求超时 为了优化性能 我将其放入内存缓存中 使用Cache GetOrCreateAsync 所以我确信可以
  • Haskell 中的随机整数 [重复]

    这个问题在这里已经有答案了 我正在学习 Haskell 并学习我想生成一个随机的 Int 类型 我很困惑 因为下面的代码有效 基本上 我想要一个 Int 而不是 IO Int 在 ghci 中 这是有效的 Prelude gt import
  • 如何使用 Spring Cloud 和 Netflix OSS 在微服务之间路由

    在使用 Spring Cloud 开发微服务期间 我们开始使用 Zuul 作为从外部到微服务的任何连接以及任何需要联系另一个微服务的微服务的代理 一段时间后 我们得出结论 Zuul 被设计为边缘服务 仅代理从外部到微服务的流量 并且不应用于
  • 如何在AWS Lambda上使用tabula阅读pdf?

    我知道我们必须下载 Java 才能运行 我在 IDE 上执行了该操作 并且成功了 但不知道如何在 AWS Lambda 上下载它 如果有人能帮助我 我将不胜感激 我认为代码本身产生了我所期望的结果 但是 java正是我所需要的 这是我收到的