1. Tổng quan
Lớp học lập trình này hình dung một quy trình công việc khả thi của doanh nghiệp: lưu trữ, phân tích và tạo báo cáo hình ảnh. Hãy tưởng tượng tổ chức của bạn có một loạt ảnh chiếm dung lượng trong một tài nguyên hạn chế. Bạn muốn lưu trữ dữ liệu đó, phân tích các hình ảnh đó và quan trọng nhất là tạo một báo cáo tóm tắt các vị trí đã lưu trữ cùng với kết quả phân tích. Báo cáo này được tổng hợp và sẵn sàng để cấp quản lý sử dụng. Google Cloud cung cấp các công cụ để hiện thực hoá mục tiêu này, bằng cách sử dụng API của hai dòng sản phẩm của mình là Google Workspace (trước đây là G Suite hoặc Google Apps) và Google Cloud (trước đây là GCP).
Trong trường hợp của chúng ta, người dùng doanh nghiệp sẽ có hình ảnh trên Google Drive. Sẽ hợp lý khi bạn sao lưu những video đó để "đốt cháy" hơn, bộ nhớ rẻ hơn, chẳng hạn như các lớp bộ nhớ có trong Google Cloud Storage. Google Cloud Vision giúp nhà phát triển dễ dàng tích hợp các tính năng phát hiện thị giác vào các ứng dụng, chẳng hạn như phát hiện vật thể và mốc, nhận dạng ký tự quang học (OCR), v.v. Cuối cùng, bảng tính Google Trang tính là một công cụ trực quan hữu ích để tóm tắt toàn bộ quá trình này cho sếp của bạn.
Sau khi bạn hoàn thành lớp học lập trình này để xây dựng một giải pháp sử dụng toàn bộ Google Cloud, chúng tôi hy vọng bạn sẽ có cảm hứng để xây dựng một giải pháp có sức ảnh hưởng hơn nữa cho tổ chức của bạn hoặc cho khách hàng của bạn.
Kiến thức bạn sẽ học được
- Cách sử dụng Cloud Shell
- Cách xác thực yêu cầu API
- Cách cài đặt thư viện ứng dụng API của Google cho Python
- Cách bật Google API
- Cách tải tệp xuống từ Google Drive
- Cách tải đối tượng/blob lên Cloud Storage
- Cách phân tích dữ liệu bằng Cloud Vision
- Cách ghi hàng vào Google Trang tính
Bạn cần có
- Tài khoản Google (tài khoản Google Workspace có thể cần phải được quản trị viên phê duyệt)
- Một dự án Google Cloud có tài khoản thanh toán Google Cloud đang hoạt động
- Quen thuộc với lệnh shell/cửa sổ dòng lệnh của hệ điều hành
- Có kỹ năng cơ bản trong Python (2 hoặc 3), nhưng bạn có thể sử dụng bất kỳ ngôn ngữ nào được hỗ trợ
Việc có kinh nghiệm sử dụng 4 sản phẩm của Google Cloud nêu trên sẽ giúp ích nhưng không bắt buộc. Nếu có thời gian để làm quen với từng loại bài tập riêng biệt, thì bạn có thể tham gia lớp học lập trình cho từng bài tập trước khi giải quyết bài tập tại đây:
- Giới thiệu về Google Drive (Sử dụng các API của Google Workspace) (Python)
- Sử dụng Cloud Vision với Python (Python)
- Tạo công cụ báo cáo tuỳ chỉnh bằng API Trang tính (JS/Node)
- Tải đối tượng lên Google Cloud Storage (không cần lập trình)
Khảo sát
Bạn sẽ sử dụng hướng dẫn này như thế nào?
Bạn đánh giá thế nào về trải nghiệm sử dụng Python?
Bạn đánh giá thế nào về trải nghiệm sử dụng các dịch vụ của Google Cloud?
Bạn đánh giá thế nào về trải nghiệm sử dụng các dịch vụ của Google Workspace dành cho nhà phát triển?
Bạn có muốn xem thêm các từ khoá "hướng đến doanh nghiệp" không? lớp học lập trình so với nội dung giới thiệu tính năng sản phẩm?
2. Thiết lập và yêu cầu
Thiết lập môi trường theo tiến độ riêng
- Đăng nhập vào Google Cloud Console rồi tạo dự án mới hoặc sử dụng lại dự án hiện có. Nếu chưa có tài khoản Gmail hoặc Google Workspace, bạn phải tạo một tài khoản.
- Tên dự án là tên hiển thị của những người tham gia dự án này. Đây là một chuỗi ký tự không được API của Google sử dụng. Bạn có thể cập nhật thông tin này bất cứ lúc nào.
- Mã dự án phải là duy nhất trong tất cả các dự án Google Cloud và không thể thay đổi (bạn không thể thay đổi mã này sau khi đặt). Cloud Console sẽ tự động tạo một chuỗi duy nhất; thường bạn không quan tâm đến sản phẩm đó là gì. Trong hầu hết các lớp học lập trình, bạn sẽ cần tham chiếu đến Mã dự án (mã này thường được xác định là
PROJECT_ID
). Nếu không thích mã đã tạo, bạn có thể tạo một mã nhận dạng ngẫu nhiên khác. Ngoài ra, bạn có thể thử phương pháp của riêng mình và xem có được cung cấp hay không. Bạn không thể thay đổi thông tin này sau bước này và thông báo đó sẽ vẫn tồn tại trong thời gian của dự án. - Đối với thông tin của bạn, có giá trị thứ ba, Project Number (Số dự án) mà một số API sử dụng. Tìm hiểu thêm về cả ba giá trị này trong tài liệu này.
- Tiếp theo, bạn sẽ phải bật tính năng thanh toán trong Cloud Console để sử dụng API/tài nguyên trên đám mây. Việc chạy qua lớp học lập trình này sẽ không tốn nhiều chi phí. Để tắt các tài nguyên nhằm tránh bị tính phí ngoài hướng dẫn này, bạn có thể xoá các tài nguyên bạn đã tạo hoặc xoá toàn bộ dự án. Người dùng mới của Google Cloud đủ điều kiện tham gia chương trình Dùng thử miễn phí 300 USD.
Khởi động Cloud Shell
Tóm tắt
Mặc dù bạn có thể phát triển mã cục bộ trên máy tính xách tay, nhưng mục tiêu phụ của lớp học lập trình này là hướng dẫn bạn cách sử dụng Google Cloud Shell, một môi trường dòng lệnh chạy trên đám mây thông qua trình duyệt web hiện đại.
Kích hoạt Cloud Shell
- Trong Cloud Console, hãy nhấp vào Kích hoạt Cloud Shell .
Nếu trước đây bạn chưa từng khởi động Cloud Shell, thì bạn sẽ thấy một màn hình trung gian (dưới màn hình đầu tiên) mô tả về ứng dụng này. Nếu trường hợp đó xảy ra, hãy nhấp vào Tiếp tục (và bạn sẽ không thấy thông báo đó nữa). Màn hình một lần đó sẽ có dạng như sau:
Quá trình cấp phép và kết nối với Cloud Shell chỉ mất vài phút.
Máy ảo này chứa tất cả các công cụ phát triển mà bạn cần. Dịch vụ này cung cấp thư mục gốc 5 GB ổn định và chạy trong Google Cloud, giúp nâng cao đáng kể hiệu suất và khả năng xác thực của mạng. Trong lớp học lập trình này, đa số mọi người đều có thể thực hiện chỉ bằng một trình duyệt hoặc Chromebook.
Sau khi kết nối với Cloud Shell, bạn sẽ thấy mình đã được xác thực và dự án đã được đặt thành mã dự án.
- Chạy lệnh sau trong Cloud Shell để xác nhận rằng bạn đã được xác thực:
gcloud auth list
Kết quả lệnh
Credentialed Accounts ACTIVE ACCOUNT * <my_account>@<my_domain.com> To set the active account, run: $ gcloud config set account `ACCOUNT`
- Chạy lệnh sau trong Cloud Shell để xác nhận rằng lệnh gcloud biết về dự án của bạn:
gcloud config list project
Kết quả lệnh
[core] project = <PROJECT_ID>
Nếu chưa, bạn có thể thiết lập chế độ này bằng lệnh sau:
gcloud config set project <PROJECT_ID>
Kết quả lệnh
Updated property [core/project].
3. Xác nhận môi trường Python
Lớp học lập trình này yêu cầu bạn sử dụng ngôn ngữ Python (mặc dù thư viện ứng dụng Google API hỗ trợ nhiều ngôn ngữ, vì vậy, bạn có thể tạo một ngôn ngữ tương đương trong công cụ phát triển yêu thích và chỉ cần dùng Python làm mã giả). Cụ thể, lớp học lập trình này hỗ trợ Python 2 và 3, nhưng bạn nên chuyển sang 3.x càng sớm càng tốt.
Cloud Shell là một công cụ tiện lợi, được cung cấp trực tiếp từ Cloud Console mà không cần đến môi trường phát triển cục bộ. Vì vậy, hướng dẫn này có thể thực hiện hoàn toàn trên đám mây bằng trình duyệt web. Riêng đối với lớp học lập trình này, Cloud Shell đã cài đặt sẵn cả hai phiên bản Python.
Cloud Shell cũng cài đặt IPython: đây là một trình thông dịch Python tương tác cấp cao hơn mà chúng tôi khuyên bạn nên dùng, đặc biệt nếu bạn là thành viên của cộng đồng khoa học dữ liệu hoặc học máy. Nếu bạn ở đó, IPython sẽ là trình phiên dịch mặc định cho Jupyter Notebooks cũng như Colab, Jupyter Notebooks do Google Research lưu trữ.
IPython ưu tiên trình thông dịch Python 3 trước tiên nhưng sẽ quay lại sử dụng Python 2 nếu 3.x không có sẵn. Bạn có thể truy cập IPython từ Cloud Shell nhưng cũng có thể cài đặt trong môi trường phát triển cục bộ. Thoát bằng phím ^D (Ctrl-d) và chấp nhận ưu đãi để thoát. Kết quả mẫu khi bắt đầu ipython
sẽ có dạng như sau:
$ ipython Python 3.7.3 (default, Mar 4 2020, 23:11:43) Type 'copyright', 'credits' or 'license' for more information IPython 7.13.0 -- An enhanced Interactive Python. Type '?' for help. In [1]:
Nếu IPython không phải là lựa chọn ưu tiên của bạn, bạn hoàn toàn được chấp nhận sử dụng trình thông dịch tương tác Python tiêu chuẩn (Cloud Shell hoặc môi trường phát triển cục bộ) (cũng thoát bằng ^D):
$ python Python 2.7.13 (default, Sep 26 2018, 18:42:22) [GCC 6.3.0 20170516] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> $ python3 Python 3.7.3 (default, Mar 10 2020, 02:33:39) [GCC 6.3.0 20170516] on linux Type "help", "copyright", "credits" or "license" for more information. >>>
Lớp học lập trình này cũng giả định bạn có công cụ cài đặt pip
(trình quản lý gói Python và trình phân giải phần phụ thuộc). Nó đi kèm với các phiên bản 2.7.9+ hoặc 3.4+. Nếu bạn có phiên bản Python cũ hơn, hãy xem hướng dẫn này để biết hướng dẫn cài đặt. Tuỳ thuộc vào quyền của bạn, bạn có thể cần phải có sudo
hoặc quyền truy cập của siêu người dùng, nhưng nhìn chung thì không phải như vậy. Bạn cũng có thể sử dụng pip2
hoặc pip3
một cách rõ ràng để thực thi pip
cho các phiên bản Python cụ thể.
Phần còn lại của lớp học lập trình sẽ giả định rằng bạn đang sử dụng Python 3. Chúng tôi sẽ cung cấp các hướng dẫn cụ thể cho Python 2 nếu các hướng dẫn đó khác biệt đáng kể so với phiên bản 3.x.
[Không bắt buộc] Tạo và sử dụng môi trường ảo
Phần này là không bắt buộc và chỉ thực sự bắt buộc đối với những người phải sử dụng môi trường ảo cho lớp học lập trình này (theo thanh bên cảnh báo ở trên). Nếu chỉ có Python 3 trên máy tính, bạn chỉ cần đưa ra lệnh này để tạo một Virtualenv có tên my_env
(bạn có thể chọn tên khác nếu muốn):
virtualenv my_env
Tuy nhiên, nếu bạn có cả Python 2 & Trên máy tính, bạn nên cài đặt một Virtualenv Python 3. Bạn có thể thực hiện việc này với -p flag
như sau:
virtualenv -p python3 my_env
Nhập môi trường ảo mới tạo bằng cách "kích hoạt" sẽ như sau:
source my_env/bin/activate
Xác nhận bạn đang ở trong môi trường bằng cách quan sát dấu nhắc lệnh shell giờ đây đứng sau tên môi trường, tức là
(my_env) $
Bây giờ, bạn có thể pip install
mọi gói bắt buộc, thực thi mã trong chế độ này, v.v. Một lợi ích khác là nếu bạn làm rối hoàn toàn, gặp phải tình huống cài đặt Python bị lỗi, v.v., bạn có thể thổi bay toàn bộ môi trường này mà không ảnh hưởng đến phần còn lại của hệ thống.
4. Cài đặt thư viện ứng dụng API của Google cho Python
Lớp học lập trình này yêu cầu bạn sử dụng thư viện ứng dụng API của Google cho Python. Vì vậy, đây là một quy trình cài đặt đơn giản hoặc bạn có thể không phải làm gì cả.
Trước đây, bạn nên cân nhắc sử dụng Cloud Shell để thuận tiện. Bạn có thể xem toàn bộ hướng dẫn bằng trình duyệt web trên đám mây. Một lý do khác để sử dụng Cloud Shell là nhiều công cụ phát triển và thư viện cần thiết phổ biến đã cài đặt trước.
*Cài đặt thư viện ứng dụng
(không bắt buộc) Bạn có thể bỏ qua bước này nếu đang sử dụng Cloud Shell hoặc một môi trường cục bộ nơi bạn đã cài đặt thư viện ứng dụng. Bạn chỉ cần làm việc này nếu đang phát triển cục bộ và chưa (hoặc chưa chắc chắn) bạn đã cài đặt ứng dụng đó. Cách dễ nhất là sử dụng pip
(hoặc pip3
) để cài đặt (bao gồm cả việc cập nhật chính pip
nếu cần):
pip install -U pip google-api-python-client oauth2client
Xác nhận cài đặt
Lệnh này sẽ cài đặt thư viện ứng dụng cũng như mọi gói mà nó phụ thuộc vào. Cho dù bạn đang sử dụng Cloud Shell hay môi trường của riêng bạn, hãy xác minh thư viện ứng dụng đã được cài đặt bằng cách nhập các gói cần thiết và xác nhận rằng không có lỗi nhập (hoặc đầu ra):
python3 -c "import googleapiclient, httplib2, oauth2client"
Nếu sử dụng Python 2 (từ Cloud Shell), bạn sẽ nhận được cảnh báo cho biết dịch vụ này đã ngừng hỗ trợ:
******************************************************************************* Python 2 is deprecated. Upgrade to Python 3 as soon as possible. See https://cloud.google.com/python/docs/python2-sunset To suppress this warning, create an empty ~/.cloudshell/no-python-warning file. The command will automatically proceed in seconds or on any key. *******************************************************************************
Khi bạn có thể chạy lệnh nhập "kiểm thử" đó thành công (không có lỗi/đầu ra), bạn đã có thể bắt đầu trò chuyện với các API của Google!
Tóm tắt
Vì đây là lớp học lập trình trung cấp, nên giả định rằng bạn đã có kinh nghiệm tạo & bằng cách sử dụng các dự án trong bảng điều khiển. Nếu bạn mới sử dụng các API của Google và API Google Workspace, trước tiên hãy thử tham gia lớp học lập trình giới thiệu về API Google Workspace. Ngoài ra, nếu bạn biết cách tạo (hoặc sử dụng lại) thông tin đăng nhập hiện có cho tài khoản người dùng (không phải tài khoản dịch vụ), hãy thả tệp client_secret.json
vào thư mục công việc của mình, bỏ qua mô-đun tiếp theo rồi chuyển đến phần "Bật API của Google".
5. *Cho phép các yêu cầu API (uỷ quyền của người dùng)
Bạn có thể bỏ qua phần này nếu đã tạo thông tin đăng nhập uỷ quyền tài khoản người dùng và bạn đã quen thuộc với quy trình này. Uỷ quyền này khác với uỷ quyền tài khoản dịch vụ có kỹ thuật khác, vì vậy, vui lòng tiếp tục ở bên dưới.
Giới thiệu về việc uỷ quyền (cùng với một số phương thức xác thực)
Để gửi yêu cầu tới các API, ứng dụng của bạn cần có quyền truy cập thích hợp. Xác thực, một từ tương tự, mô tả thông tin đăng nhập. Bạn xác thực chính mình khi đăng nhập vào Tài khoản Google bằng thông tin đăng nhập và mật khẩu. Sau khi xác thực, bước tiếp theo là liệu bạn có (hay nói đúng hơn là mã của bạn) có được uỷ quyền để truy cập vào dữ liệu hay không, chẳng hạn như các tệp blob trên Cloud Storage hoặc các tệp cá nhân của người dùng trên Google Drive.
Các API của Google hỗ trợ nhiều loại hình uỷ quyền, nhưng một trong những cách phổ biến nhất đối với người dùng API G Suite là uỷ quyền người dùng vì ứng dụng mẫu trong lớp học lập trình này truy cập vào dữ liệu thuộc về người dùng cuối. Những người dùng cuối đó phải cấp quyền cho ứng dụng của bạn truy cập vào dữ liệu của họ. Tức là mã của bạn phải lấy thông tin đăng nhập OAuth2 của tài khoản người dùng.
Để lấy thông tin đăng nhập OAuth2 cho việc uỷ quyền của người dùng, hãy quay lại trình quản lý API rồi chọn "Credentials" (Thông tin xác thực) trên bảng điều hướng bên trái:
Khi truy cập vào đó, bạn sẽ thấy tất cả thông tin đăng nhập của mình trong ba phần riêng biệt:
Đầu tiên là dành cho khoá API, ID ứng dụng khách OAuth 2.0 thứ hai và tài khoản dịch vụ OAuth2 cuối cùng mà chúng tôi đang sử dụng ở giữa.
Đang tạo thông tin xác thực
Từ trang Thông tin xác thực, hãy nhấp vào nút + Tạo thông tin xác thực ở trên cùng. Sau đó, một hộp thoại sẽ xuất hiện để bạn chọn "Mã ứng dụng khách OAuth":
Trên màn hình tiếp theo, bạn có 2 thao tác: định cấu hình "màn hình yêu cầu đồng ý" cấp phép của ứng dụng và chọn loại ứng dụng:
Nếu chưa thiết lập màn hình xin phép, bạn sẽ thấy cảnh báo trong bảng điều khiển và cần thiết lập ngay bây giờ. (Bỏ qua các bước tiếp theo này nếu màn hình xin phép của bạn đã được thiết lập.)
Màn hình xin phép bằng Oauth
Nhấp vào "Định cấu hình màn hình đồng ý" nơi bạn chọn một ứng dụng "Bên ngoài" ứng dụng (hoặc "Nội bộ" nếu bạn là khách hàng G Suite):
Xin lưu ý rằng để phục vụ mục đích của bài tập này, bạn không cần chọn giải pháp nào vì bạn sẽ không xuất bản mẫu của lớp học lập trình của mình. Hầu hết mọi người sẽ chọn "Bên ngoài" được đưa đến một màn hình phức tạp hơn, nhưng bạn thực sự chỉ cần hoàn tất "Tên ứng dụng" trường ở trên cùng:
Hiện tại, bạn chỉ cần đặt tên ứng dụng. Vì vậy, hãy chọn một người phản ánh lớp học lập trình bạn đang thực hiện sau đó nhấp vào Save (Lưu).
Tạo mã ứng dụng khách OAuth (xác thực tài khoản người dùng)
Bây giờ, hãy quay lại thẻ Thông tin xác thực để tạo Mã ứng dụng khách OAuth2. Tại đây, bạn sẽ thấy nhiều mã ứng dụng khách OAuth mà bạn có thể tạo:
Chúng tôi đang phát triển một công cụ dòng lệnh, đó là Other (Khác), hãy chọn công cụ đó sau đó nhấp vào nút Create (Tạo). Chọn tên mã ứng dụng khách phản ánh ứng dụng mà bạn đang tạo hoặc chỉ cần lấy tên mặc định, thường là "Ứng dụng khác N".
Đang lưu thông tin đăng nhập
- Một hộp thoại có thông tin xác thực mới sẽ xuất hiện; nhấp vào OK để đóng
- Quay lại trang Thông tin xác thực, di chuyển xuống phần "Mã ứng dụng khách OAuth2" hãy tìm và nhấp vào biểu tượng tải xuống ở ngoài cùng bên phải của ID ứng dụng khách mới tạo của bạn.
- Thao tác này sẽ mở hộp thoại để lưu tệp có tên
client_secret-
LONG-HASH-STRING
.apps.googleusercontent.com.json
, có thể nằm trong thư mục Downloads (Tệp đã tải xuống). Bạn nên rút ngắn thành tên dễ dùng hơn nhưclient_secret.json
(tên mà ứng dụng mẫu sử dụng), sau đó lưu tên này vào thư mục/thư mục mà bạn sẽ tạo ứng dụng mẫu trong lớp học lập trình này.
Tóm tắt
Bây giờ, bạn đã sẵn sàng bật các API của Google được sử dụng trong lớp học lập trình này. Ngoài ra, đối với tên ứng dụng trong màn hình xin phép bằng OAuth, chúng tôi đã chọn "Bản minh hoạ API tầm nhìn". Vì vậy, bạn có thể thấy thông tin này trong một số ảnh chụp màn hình sắp tới.
6. Bật Google API
Lớp học lập trình này sử dụng bốn (4) API Google Cloud, một cặp của Google Cloud (Cloud Storage và Cloud Vision) và một cặp API khác của Google Workspace (Google Drive và Google Trang tính). Dưới đây là hướng dẫn chung để bật các API của Google. Sau khi bạn biết cách bật một API, các API khác cũng tương tự như vậy.
Bất kể bạn muốn sử dụng API nào của Google trong ứng dụng của mình, bạn phải bật API đó. Bạn có thể bật API bằng dòng lệnh hoặc từ bảng điều khiển Cloud. Quy trình bật API giống hệt nhau, vì vậy, sau khi bật một API, bạn có thể bật các API khác theo cách tương tự.
Cách 1: Giao diện dòng lệnh gcloud
(Cloud Shell hoặc môi trường cục bộ)
Mặc dù việc bật API từ Cloud Console phổ biến hơn, nhưng một số nhà phát triển lại thích làm mọi việc từ dòng lệnh. Để thực hiện việc này, bạn cần tra cứu "tên dịch vụ" của API. URL này có dạng như sau: SERVICE_NAME
.googleapis.com
. Bạn có thể tìm thấy những sản phẩm này trong Biểu đồ Sản phẩm được hỗ trợ hoặc bạn có thể truy vấn những sản phẩm đó theo phương thức lập trình bằng API Khám phá của Google.
Được trang bị thông tin này, bằng cách sử dụng Cloud Shell (hoặc môi trường phát triển cục bộ của bạn với công cụ dòng lệnh gcloud
đã cài đặt), bạn có thể bật một API hoặc dịch vụ như sau:
gcloud services enable SERVICE_NAME.googleapis.com
Ví dụ 1: Bật Cloud Vision API
gcloud services enable vision.googleapis.com
Ví dụ 2: Bật nền tảng điện toán không máy chủ Google App Engine
gcloud services enable appengine.googleapis.com
Ví dụ 3: Bật nhiều API với một yêu cầu. Ví dụ: nếu lớp học lập trình này có người xem triển khai một ứng dụng bằng Cloud Translation API cho App Engine, Cloud Functions và Cloud Run, thì dòng lệnh sẽ là:
gcloud services enable appengine.googleapis.com cloudfunctions.googleapis.com artifactregistry.googleapis.com run.googleapis.com translate.googleapis.com
Lệnh này bật App Engine, Cloud Functions, Cloud Run và Cloud Translation API. Ngoài ra, bạn cũng có thể sử dụng Cloud Artifact Registry vì đó là nơi hệ thống Cloud Build phải đăng ký hình ảnh vùng chứa để có thể triển khai Cloud Run.
Ngoài ra, có một vài lệnh để truy vấn các API cần bật hoặc API nào đã được bật cho dự án của bạn.
Ví dụ 4: Truy vấn các API của Google hiện có để bật cho dự án của bạn
gcloud services list --available --filter="name:googleapis.com"
Ví dụ 5: Đã bật truy vấn các API của Google cho dự án của bạn
gcloud services list
Để biết thêm thông tin về các lệnh trên, hãy xem tài liệu về cách bật và tắt dịch vụ cũng như dịch vụ liệt kê.
Cách 2: Cloud Console
Bạn cũng có thể bật các API của Google trong Trình quản lý API. Trong Cloud Console, hãy chuyển đến Trình quản lý API. Trên trang tổng quan này, bạn sẽ thấy một số thông tin về lưu lượng truy cập cho ứng dụng của mình, biểu đồ thể hiện yêu cầu liên quan đến ứng dụng, lỗi mà ứng dụng tạo ra và thời gian phản hồi của ứng dụng:
Bên dưới các biểu đồ này là danh sách các API của Google được bật cho dự án của bạn:
Để bật (hoặc tắt) API, hãy nhấp vào Bật API và dịch vụ ở trên cùng:
Hoặc, chuyển đến thanh điều hướng bên trái rồi chọn API & Dịch vụ → Thư viện:
Dù bằng cách nào, bạn cũng sẽ được chuyển đến trang Thư viện API:
Nhập tên API để tìm kiếm và xem kết quả phù hợp:
Chọn API bạn muốn bật rồi nhấp vào nút Enable (Bật):
Quy trình bật tất cả API là như nhau, bất kể bạn muốn sử dụng API nào của Google.
Chi phí
Bạn có thể sử dụng nhiều API của Google mà không mất phí. Tuy nhiên, khi sử dụng hầu hết các sản phẩm và API của Google Cloud, bạn sẽ phải trả phí. Khi bật Cloud API, bạn có thể được yêu cầu có một tài khoản thanh toán đang hoạt động. Tuy nhiên, một số sản phẩm của Google Cloud có tính năng "Luôn miễn phí" mà bạn phải vượt quá để chịu phí thanh toán.
Người dùng mới của Google Cloud đủ điều kiện Dùng thử miễn phí với giá hiện tại là 300 USD cho 90 ngày đầu tiên. Các lớp học lập trình thường không phải phát sinh nhiều khoản phí hoặc bất kỳ khoản thanh toán nào. Vì vậy, bạn nên tạm ngưng dùng thử miễn phí cho đến khi thực sự sẵn sàng dùng thử, đặc biệt vì đây là ưu đãi một lần. Hạn mức cấp miễn phí sẽ không hết hạn và áp dụng bất kể bạn có sử dụng ưu đãi Dùng thử miễn phí hay không.
Người dùng nên tham khảo thông tin về giá của bất kỳ API nào trước khi bật (ví dụ: trang giá Cloud Vision API ), đặc biệt là cần lưu ý xem API đó có bậc miễn phí hay không và nếu có thì đó là bậc nào. Nếu không vượt quá giới hạn tổng hợp hằng ngày hoặc hằng tháng đã chỉ định, thì bạn sẽ không phải chịu bất kỳ khoản phí nào. Mức giá và bậc miễn phí khác nhau giữa các API nhóm sản phẩm của Google. Ví dụ:
- Google Cloud — mỗi sản phẩm được tính phí theo cách khác nhau và thường theo mô hình trả tiền cho mỗi lần sử dụng; xem thông tin về bậc miễn phí ở trên.
- Google Maps – có một bộ API và cung cấp cho người dùng khoản tín dụng miễn phí hằng tháng trị giá 200 USD.
- API Google Workspace (trước đây là G Suite) — cung cấp mức sử dụng (tối đa là một số giới hạn) theo phí thuê bao hằng tháng của Google Workspace. Như vậy, bạn sẽ không phải thanh toán trực tiếp API cho các ứng dụng như Gmail, Google Drive, Lịch, Tài liệu, Trang tính hoặc Trang trình bày.
Các sản phẩm của Google được tính phí theo cách khác nhau, vì vậy, hãy nhớ tham khảo tài liệu thích hợp về thông tin đó.
Tóm tắt
Giờ đây, khi đã bật Cloud Vision, hãy bật ba API còn lại (Google Drive, Cloud Storage, Google Trang tính) theo cách tương tự. Trên Cloud Shell, hãy dùng gcloud services enable
hoặc trên bảng điều khiển Cloud:
- Quay lại Thư viện API
- Bắt đầu tìm kiếm bằng cách nhập một vài chữ cái trong tên tìm kiếm
- Chọn API mong muốn và
- Bật
Tạo bọt, xả nước rồi thực hiện lại thao tác này. Đối với Cloud Storage, bạn có thể chọn "Google Cloud Storage JSON API". Cloud Storage API cũng yêu cầu một tài khoản thanh toán đang hoạt động.
7. Bước 0: Thiết lập tính năng nhập và mã uỷ quyền
Đây là khởi đầu của một đoạn mã có quy mô trung bình, vì vậy, việc tuân theo các phương pháp linh hoạt sẽ giúp đảm bảo một cơ sở hạ tầng chung, ổn định và hoạt động tốt trước khi xử lý ứng dụng chính. Xác minh client_secret.json
có sẵn trong thư mục hiện tại của bạn và khởi động ipython
rồi nhập đoạn mã sau hoặc lưu vào analyze_gsimg.py
rồi chạy đoạn mã đó từ shell (nên dùng đoạn mã sau vì chúng ta sẽ tiếp tục thêm vào mã mẫu):
from __future__ import print_function
from googleapiclient import discovery, http
from httplib2 import Http
from oauth2client import file, client, tools
# process credentials for OAuth2 tokens
SCOPES = 'https://www.googleapis.com/auth/drive.readonly'
store = file.Storage('storage.json')
creds = store.get()
if not creds or creds.invalid:
flow = client.flow_from_clientsecrets('client_secret.json', SCOPES)
creds = tools.run_flow(flow, store)
# create API service endpoints
HTTP = creds.authorize(Http())
DRIVE = discovery.build('drive', 'v3', http=HTTP)
Thành phần cốt lõi này bao gồm các khối mã để nhập mô-đun/gói, xử lý thông tin xác thực người dùng và tạo điểm cuối của dịch vụ API. Các thành phần quan trọng của mã bạn nên xem xét:
- Việc nhập hàm
print()
sẽ giúp mẫu Python 2-3 này tương thích, và các lệnh nhập thư viện Google sẽ cung cấp mọi công cụ cần thiết để giao tiếp với các API của Google. - Biến
SCOPES
đại diện cho các quyền yêu cầu người dùng gửi. Hiện chỉ có một quyền duy nhất: quyền đọc dữ liệu trong Google Drive của họ - Phần còn lại của mã xử lý thông tin xác thực sẽ đọc trong mã thông báo OAuth2 đã lưu vào bộ nhớ đệm, có thể cập nhật lên mã truy cập mới có mã làm mới nếu mã truy cập ban đầu đã hết hạn.
- Nếu chưa tạo mã thông báo nào hoặc không truy xuất được mã truy cập hợp lệ vì một lý do khác, thì người dùng phải thực hiện quy trình 3 bên (3LO) của OAuth2: tạo hộp thoại với các quyền được yêu cầu và nhắc người dùng chấp nhận. Sau khi họ làm xong, ứng dụng sẽ tiếp tục, nếu không
tools.run_flow()
sẽ gửi một ngoại lệ và quá trình thực thi sẽ tạm dừng. - Sau khi người dùng cấp quyền, một ứng dụng HTTP sẽ được tạo để giao tiếp với máy chủ và tất cả yêu cầu sẽ được ký bằng thông tin xác thực của người dùng vì mục đích bảo mật. Sau đó, một điểm cuối dịch vụ tới API Google Drive (phiên bản 3) sẽ được tạo bằng ứng dụng HTTP đó rồi chỉ định cho
DRIVE
.
Chạy ứng dụng
Vào lần đầu tiên bạn thực thi tập lệnh, tập lệnh sẽ không có quyền truy cập vào các tệp của người dùng trên Drive (của bạn). Kết quả sẽ có dạng như sau khi quá trình thực thi bị tạm dừng:
$ python3 ./analyze_gsimg.py /usr/local/lib/python3.6/site-packages/oauth2client/_helpers.py:255: UserWarning: Cannot access storage.json: No such file or directory warnings.warn(_MISSING_FILE_MESSAGE.format(filename)) Your browser has been opened to visit: https://accounts.google.com/o/oauth2/auth?client_id=LONG-STRING.apps.googleusercontent.com&redirect_uri=http%3A%2F%2Flocalhost%3A8080%2F&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fdrive.readonly&access_type=offline&response_type=code If your browser is on a different machine then exit and re-run this application with the command-line parameter --noauth_local_webserver
Nếu bạn đang chạy từ Cloud Shell, hãy chuyển đến "Từ Cloud Shell" sau đó di chuyển trở lại để xem các màn hình có liên quan trong mục "Từ môi trường phát triển cục bộ" khi thích hợp.
Từ môi trường phát triển cục bộ
Tập lệnh dòng lệnh bị tạm dừng khi cửa sổ trình duyệt mở ra. Bạn có thể thấy trang cảnh báo trông như thế này:
Đây là mối lo ngại chính đáng vì bạn đang cố chạy một ứng dụng truy cập vào dữ liệu người dùng. Vì đây chỉ là ứng dụng minh hoạ và bạn là nhà phát triển nên chúng tôi hy vọng bạn đủ tin tưởng để tiếp tục. Để hiểu rõ hơn về điều này, hãy đặt mình vào vị trí của người dùng: bạn được yêu cầu cho phép mã của người khác truy cập vào dữ liệu của bạn. Nếu định xuất bản một ứng dụng như thế này thì bạn sẽ thực hiện quy trình xác minh để người dùng không thấy màn hình này.
Sau khi nhấp vào liên kết "chuyển đến "không an toàn" ứng dụng" , bạn sẽ nhận được hộp thoại quyền truy cập OAuth2 trông giống như dưới đây — chúng tôi luôn cải thiện giao diện người dùng nên đừng lo lắng nếu giao diện này không hoàn toàn khớp:
Hộp thoại quy trình OAuth2 phản ánh các quyền mà nhà phát triển đang yêu cầu (thông qua biến SCOPES
). Trong trường hợp này, bạn có thể xem và tải xuống từ Google Drive của người dùng. Trong mã xử lý ứng dụng, các phạm vi cấp quyền này xuất hiện dưới dạng URI, nhưng các phạm vi này được dịch sang ngôn ngữ được chỉ định theo ngôn ngữ của người dùng. Ở đây, người dùng phải cấp quyền rõ ràng cho(các) quyền được yêu cầu, nếu không, hệ thống sẽ gửi một ngoại lệ để tập lệnh không xử lý thêm.
Thậm chí bạn có thể nhận được một hộp thoại nữa yêu cầu bạn xác nhận:
LƯU Ý: Một số trình duyệt sử dụng nhiều trình duyệt web được đăng nhập vào các tài khoản khác nhau, do đó yêu cầu uỷ quyền này có thể chuyển đến thẻ/cửa sổ trình duyệt không chính xác và bạn có thể phải cắt và dán đường liên kết cho yêu cầu này vào một trình duyệt đã đăng nhập bằng đúng tài khoản.
Của Cloud Shell
Từ Cloud Shell, không có cửa sổ trình duyệt nào bật lên khiến bạn bị mắc kẹt. Nhận thấy thông báo chẩn đoán ở dưới cùng là dành cho bạn:
If your browser is on a different machine then exit and re-run this application with the command-line parameter --noauth_local_webserver
Bạn sẽ phải ^C (Ctrl-C hoặc nhấn phím khác để tạm dừng thực thi tập lệnh) và chạy tập lệnh đó từ shell của bạn với cờ bổ sung. Khi chạy theo cách này, bạn sẽ nhận được kết quả sau:
$ python3 analyze_gsimg.py --noauth_local_webserver /usr/local/lib/python3.7/site-packages/oauth2client/_helpers.py:255: UserWarning: Cannot access storage.json: No such file or directory warnings.warn(_MISSING_FILE_MESSAGE.format(filename)) Go to the following link in your browser: https://accounts.google.com/o/oauth2/auth?client_id=LONG-STRING.apps.googleusercontent.com&redirect_uri=urn%3Aietf%3Awg%3Aoauth%3A2.0%3Aoob&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fdrive.readonly&access_type=offline&response_type=code Enter verification code:
(Bỏ qua cảnh báo vì chúng tôi biết storage.json
chưa được tạo và) Làm theo hướng dẫn trong một thẻ trình duyệt khác với URL đó, bạn sẽ nhận được trải nghiệm gần giống với những gì được mô tả ở trên đối với môi trường phát triển cục bộ (xem ảnh chụp màn hình ở trên). Ở cuối màn hình sẽ là màn hình cuối cùng có mã xác minh để nhập vào Cloud Shell:
Sao chép và dán mã này vào cửa sổ dòng lệnh.
Tóm tắt
Ngoài "Authentication successful
", đừng mong đợi bất kỳ kết quả bổ sung nào. Hãy nhớ rằng đây chỉ là chế độ thiết lập... bạn chưa làm gì cả. Những việc bạn đã làm là bắt đầu thành công hành trình hướng đến điều có nhiều khả năng thực thi đúng ngay từ lần đầu tiên. (Tuyệt vời nhất là bạn chỉ được nhắc uỷ quyền một lần; tất cả các lần thực thi kế tiếp đều bỏ qua bước này vì các quyền của bạn đã được lưu vào bộ nhớ đệm.) Bây giờ, hãy làm cho mã thực hiện một số công việc thực tế dẫn đến kết quả thực tế.
Khắc phục sự cố
Nếu bạn nhận được thông báo lỗi thay vì không có kết quả, thì có thể là do một hoặc nhiều nguyên nhân, có thể là do nguyên nhân sau:
8. Bước 1: Tải hình ảnh xuống từ Google Drive
Ở bước trước, bạn nên tạo mã dưới dạng analyze_gsimg.py
rồi chỉnh sửa tại đó. Cũng có thể bạn chỉ cần cắt và dán trực tiếp mọi thứ vào iPython hoặc shell Python tiêu chuẩn. Tuy nhiên, công việc này sẽ cồng kềnh hơn vì chúng ta sẽ tiếp tục xây dựng ứng dụng theo từng phần.
Giả sử ứng dụng của bạn đã được uỷ quyền và tạo điểm cuối của dịch vụ API. Trong mã của bạn, biến này được biểu thị bằng biến DRIVE
. Bây giờ, hãy tìm một tệp hình ảnh trên Google Drive của bạn và
đặt phương thức đó thành một biến tên là NAME
. Nhập số đó cùng với hàm drive_get_img()
sau ngay bên dưới mã ở Bước 0:
FILE = 'YOUR_IMG_ON_DRIVE' # fill-in with name of your Drive file
def drive_get_img(fname):
'download file from Drive and return file info & binary if found'
# search for file on Google Drive
rsp = DRIVE.files().list(q="name='%s'" % fname,
fields='files(id,name,mimeType,modifiedTime)'
).execute().get('files', [])
# download binary & return file info if found, else return None
if rsp:
target = rsp[0] # use first matching file
fileId = target['id']
fname = target['name']
mtype = target['mimeType']
binary = DRIVE.files().get_media(fileId=fileId).execute()
return fname, mtype, target['modifiedTime'], binary
Tập hợp files()
trên Drive có một phương thức list()
thực hiện truy vấn (tham số q
) cho tệp được chỉ định. Tham số fields
dùng để chỉ định những giá trị trả về mà bạn quan tâm. Tại sao lại phải trả về mọi thứ và làm chậm tốc độ của mọi thứ nếu bạn không quan tâm đến các giá trị khác? Nếu bạn chưa quen với mặt nạ trường để lọc giá trị trả về của API, hãy xem bài đăng này trên blog và . Nếu không, hãy thực thi truy vấn và lấy thuộc tính files
được trả về, mặc định là một mảng danh sách trống nếu không có kết quả trùng khớp.
Nếu không có kết quả, phần còn lại của hàm sẽ bị bỏ qua và None
được trả về (ngầm ẩn). Nếu không, hãy lấy phản hồi phù hợp đầu tiên (rsp[0]
), trả về tên tệp, MIMEtype, dấu thời gian sửa đổi gần đây nhất và cuối cùng là tải trọng nhị phân của hàm get_media()
(thông qua mã nhận dạng tệp) cũng nằm trong bộ sưu tập files()
. (Tên phương thức có thể khác một chút với các thư viện ứng dụng ngôn ngữ khác.)
Phần cuối cùng là phần "chính" điều khiển toàn bộ ứng dụng:
if __name__ == '__main__':
# download img file & info from Drive
rsp = drive_get_img(FILE)
if rsp:
fname, mtype, ftime, data = rsp
print('Downloaded %r (%s, %s, size: %d)' % (fname, mtype, ftime, len(data)))
else:
print('ERROR: Cannot download %r from Drive' % fname)
Giả sử một hình ảnh có tên section-work-card-img_2x.jpg
trên Drive và được đặt thành FILE
, khi thực thi tập lệnh thành công, bạn sẽ thấy kết quả xác nhận rằng nó có thể đọc tệp từ Drive (nhưng không được lưu vào máy tính của bạn):
$ python3 analyze_gsimg.py Downloaded 'section-work-card-img_2x.jpg' (image/jpeg, 2020-02-27T09:27:22.095Z, size: 27781)
Khắc phục sự cố
Nếu bạn không nhận được kết quả thành công như trên, thì có thể là do một hoặc nhiều nguyên nhân, có lẽ là do nguyên nhân sau:
Tóm tắt
Trong phần này, bạn đã tìm hiểu cách (trong 2 lệnh gọi API riêng biệt) kết nối với API Drive để truy vấn một tệp cụ thể rồi tải tệp đó xuống. Trường hợp sử dụng cho doanh nghiệp: lưu trữ dữ liệu trên Drive của bạn và có thể phân tích dữ liệu đó, chẳng hạn như bằng các công cụ của Google Cloud. Mã cho ứng dụng của bạn ở giai đoạn này phải khớp với mã trong kho lưu trữ tại step1-drive/analyze_gsimg.py
.
Đọc thêm về cách tải tệp xuống trên Google Drive tại đây hoặc xem bài đăng này trên blog và . Phần này của lớp học lập trình gần giống với toàn bộ lớp học lập trình giới thiệu về API Google Workspace – thay vì tải tệp xuống, phần này sẽ hiển thị 100 tệp/thư mục đầu tiên trên Google Drive của người dùng và sử dụng một phạm vi hạn chế hơn.
9. Bước 2: Lưu trữ tệp vào Cloud Storage
Bước tiếp theo là thêm tính năng hỗ trợ cho Google Cloud Storage. Để làm được việc này, chúng ta cần nhập một gói Python khác là io
. Đảm bảo rằng phần trên cùng của lệnh nhập giờ đây có dạng như sau:
from __future__ import print_function
import io
Ngoài tên tệp trên Drive, chúng tôi cần một số thông tin về nơi lưu trữ tệp này trên Cloud Storage, cụ thể là tên của "bộ chứa" bạn sẽ đặt nó vào và bất kỳ "thư mục mẹ" nào (các) tiền tố. Tìm hiểu thêm về điều này trong giây lát:
FILE = 'YOUR_IMG_ON_DRIVE'
BUCKET = 'YOUR_BUCKET_NAME'
PARENT = '' # YOUR IMG FILE PREFIX
Lưu ý về bộ chứa: Cloud Storage cung cấp bộ nhớ blob vô định hình. Khi tải tệp lên tại đó, hệ thống không hiểu khái niệm về loại tệp, đuôi tệp, v.v., giống như cách mà Google Drive thực hiện. Chúng chỉ là "blob" lên Cloud Storage. Ngoài ra, không có khái niệm nào về thư mục hoặc thư mục con trong Cloud Storage.
Có, bạn có thể dùng dấu gạch chéo (/
) trong tên tệp để thể hiện tính trừu tượng của nhiều thư mục con, nhưng vào cuối ngày, tất cả các blob của bạn sẽ được gộp vào một nhóm còn "/
" chỉ là các ký tự trong tên tệp. Hãy xem trang quy ước đặt tên bộ chứa và đối tượng để biết thêm thông tin.
Bước 1 ở trên đã yêu cầu phạm vi "chỉ có thể đọc" trên Drive. Hiện tại, đó là tất cả những gì bạn cần. Giờ đây, bạn bắt buộc phải có quyền tải (đọc-ghi) lên Cloud Storage. Thay đổi SCOPES
từ một biến chuỗi đơn thành một mảng (bộ dữ liệu Python [hoặc danh sách]) của phạm vi quyền để có dạng như sau:
SCOPES = (
'https://www.googleapis.com/auth/drive.readonly',
'https://www.googleapis.com/auth/devstorage.full_control',
)
Bây giờ, hãy tạo một điểm cuối dịch vụ tới Cloud Storage ngay bên dưới điểm cuối cho Drive. Xin lưu ý rằng chúng ta đã thay đổi một chút lệnh gọi để sử dụng lại cùng một đối tượng máy khách HTTP vì không cần phải tạo đối tượng mới khi đối tượng đó có thể là tài nguyên dùng chung.
# create API service endpoints
HTTP = creds.authorize(Http())
DRIVE = discovery.build('drive', 'v3', http=HTTP)
GCS = discovery.build('storage', 'v1', http=HTTP)
Bây giờ, hãy thêm hàm này (sau drive_get_img()
) để tải lên Cloud Storage:
def gcs_blob_upload(fname, bucket, media, mimetype):
'upload an object to a Google Cloud Storage bucket'
# build blob metadata and upload via GCS API
body = {'name': fname, 'uploadType': 'multipart', 'contentType': mimetype}
return GCS.objects().insert(bucket=bucket, body=body,
media_body=http.MediaIoBaseUpload(io.BytesIO(media), mimetype),
fields='bucket,name').execute()
Lệnh gọi objects.().insert()
yêu cầu phải có tên bộ chứa, siêu dữ liệu tệp và chính blob nhị phân. Để lọc ra các giá trị trả về, biến fields
chỉ yêu cầu tên bộ chứa và tên đối tượng được trả về từ API. Để tìm hiểu thêm về các mặt nạ trường này đối với các yêu cầu đọc API, hãy xem bài đăng này và .
Bây giờ, hãy tích hợp việc sử dụng gcs_blob_upload()
vào ứng dụng chính:
# upload file to GCS
gcsname = '%s/%s'% (PARENT, fname)
rsp = gcs_blob_upload(gcsname, BUCKET, data, mtype)
if rsp:
print('Uploaded %r to GCS bucket %r' % (rsp['name'], rsp['bucket']))
else:
print('ERROR: Cannot upload %r to Cloud Storage' % gcsname)
Biến gcsname
hợp nhất mọi "thư mục con mẹ" (các) tên được thêm vào chính tên tệp và khi có tiền tố tên bộ chứa, cho ra hiển thị bạn đang lưu trữ tệp tại "/bucket/parent.../filename
". Trượt phần này ngay sau hàm print()
đầu tiên ngay phía trên mệnh đề else
để toàn bộ "main" sẽ có dạng như sau:
if __name__ == '__main__':
# download img file & info from Drive
rsp = drive_get_img(FILE)
if rsp:
fname, mtype, ftime, data = rsp
print('Downloaded %r (%s, %s, size: %d)' % (fname, mtype, ftime, len(data)))
# upload file to GCS
gcsname = '%s/%s'% (PARENT, fname)
rsp = gcs_blob_upload(gcsname, BUCKET, data, mtype)
if rsp:
print('Uploaded %r to GCS bucket %r' % (rsp['name'], rsp['bucket']))
else:
print('ERROR: Cannot upload %r to Cloud Storage' % gcsname)
else:
print('ERROR: Cannot download %r from Drive' % fname)
Giả sử chúng ta chỉ định một bộ chứa có tên là "vision-demo
" bằng "analyzed_imgs
" dưới dạng "thư mục con mẹ". Sau khi bạn đặt các biến đó và chạy lại tập lệnh, section-work-card-img_2x.jpg
sẽ được tải xuống từ Drive rồi tải lên Cloud Storage phải không? KHÔNG!
$ python3 analyze_gsimg.py Downloaded 'section-work-card-img_2x.jpg' (image/jpeg, 2020-02-27T09:27:22.095Z, size: 27781) Traceback (most recent call last): File "analyze_gsimg.py", line 85, in <module> io.BytesIO(data), mimetype=mtype), mtype) File "analyze_gsimg.py", line 72, in gcs_blob_upload media_body=media, fields='bucket,name').execute() File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/googleapiclient/_helpers.py", line 134, in positional_wrapper return wrapped(*args, **kwargs) File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/googleapiclient/http.py", line 898, in execute raise HttpError(resp, content, uri=self.uri) googleapiclient.errors.HttpError: <HttpError 403 when requesting https://storage.googleapis.com/upload/storage/v1/b/PROJECT_ID/o?fields=bucket%2Cname&alt=json&uploadType=multipart returned "Insufficient Permission">
Hãy xem lại, mặc dù tải xuống Drive thành công nhưng tải lên Cloud Storage không thành công. Tại sao?
Lý do là khi ban đầu chúng tôi cho phép ứng dụng này ở Bước 1, chúng tôi chỉ cấp quyền truy cập chỉ đọc vào Google Drive. Mặc dù đã thêm phạm vi đọc-ghi cho Cloud Storage, nhưng chúng tôi chưa bao giờ nhắc người dùng cấp quyền truy cập đó. Để làm cho nó hoạt động, chúng ta cần loại bỏ tệp storage.json
bị thiếu phạm vi này và chạy lại.
Sau khi bạn uỷ quyền lại (xác nhận thông tin này bằng cách xem bên trong storage.json
và xem cả hai phạm vi ở đó), kết quả của bạn sẽ như mong đợi:
$ python3 analyze_gsimg.py . . . Authentication successful. Downloaded 'section-work-card-img_2x.jpg' (image/jpeg, 2020-02-27T09:27:22.095Z, size: 27781) Uploaded 'analyzed_imgs/section-work-card-img_2x.jpg' to GCS bucket 'vision-demo'
Tóm tắt
Đây là một vấn đề lớn, trong đó bạn sẽ thấy cách chuyển tệp giữa cả hai hệ thống lưu trữ trên đám mây trong tương đối ít dòng mã. Trường hợp sử dụng của doanh nghiệp ở đây là sao lưu một tài nguyên có thể bị hạn chế để "đá" như đã đề cập trước đó. Cloud Storage cung cấp các lớp bộ nhớ khác nhau, tuỳ thuộc vào việc bạn truy cập vào dữ liệu của mình thường xuyên, hằng tháng, hằng quý hay hằng năm.
Tất nhiên, thỉnh thoảng các nhà phát triển sẽ hỏi chúng tôi về lý do có cả Google Drive và Cloud Storage. Suy cho cùng, không phải cả hai nền tảng này đều là bộ nhớ tệp trên đám mây sao? Đó là lý do chúng tôi tạo video này. Mã của bạn ở giai đoạn này phải khớp với mã trong kho lưu trữ tại step2-gcs/analyze_gsimg.py
.
10. Bước 3: Phân tích bằng Cloud Vision
Mặc dù hiện tại chúng tôi biết rằng bạn có thể di chuyển dữ liệu giữa Google Cloud và Google Workspace, nhưng chúng tôi chưa phân tích gì cả. Vì vậy, đã đến lúc gửi hình ảnh đến Cloud Vision để chú thích nhãn còn gọi là phát hiện đối tượng. Để làm như vậy, chúng ta cần mã hoá dữ liệu Base64, tức là một mô-đun Python khác là base64
. Đảm bảo phần nhập trên cùng của bạn giờ đây có dạng như sau:
from __future__ import print_function
import base64
import io
Theo mặc định, Vision API trả về tất cả các nhãn tìm thấy. Để đảm bảo tính nhất quán, chúng ta chỉ yêu cầu 5 kết quả hàng đầu (tất nhiên người dùng có thể điều chỉnh). Chúng ta sẽ sử dụng một biến không đổi TOP
cho việc này; thêm nó vào tất cả các hằng số khác:
FILE = 'YOUR_IMG_ON_DRIVE'
BUCKET = 'YOUR_BUCKET_NAME'
PARENT = '' # YOUR IMG FILE PREFIX
TOP = 5 # TOP # of VISION LABELS TO SAVE
Giống như các bước trước, chúng ta cần một phạm vi quyền khác, lần này dành cho API Vision. Cập nhật SCOPES
bằng chuỗi của nó:
SCOPES = (
'https://www.googleapis.com/auth/drive.readonly',
'https://www.googleapis.com/auth/devstorage.full_control',
'https://www.googleapis.com/auth/cloud-vision',
)
Bây giờ, hãy tạo một điểm cuối dịch vụ tới Cloud Vision để điểm cuối này khớp với các điểm cuối khác như sau:
# create API service endpoints
HTTP = creds.authorize(Http())
DRIVE = discovery.build('drive', 'v3', http=HTTP)
GCS = discovery.build('storage', 'v1', http=HTTP)
VISION = discovery.build('vision', 'v1', http=HTTP)
Bây giờ, hãy thêm hàm này để gửi tải trọng hình ảnh đến Cloud Vision:
def vision_label_img(img, top):
'send image to Vision API for label annotation'
# build image metadata and call Vision API to process
body = {'requests': [{
'image': {'content': img},
'features': [{'type': 'LABEL_DETECTION', 'maxResults': top}],
}]}
rsp = VISION.images().annotate(body=body).execute().get('responses', [{}])[0]
# return top labels for image as CSV for Sheet (row)
if 'labelAnnotations' in rsp:
return ', '.join('(%.2f%%) %s' % (
label['score']*100., label['description']) \
for label in rsp['labelAnnotations'])
Lệnh gọi images().annotate()
yêu cầu dữ liệu và các tính năng API mong muốn. 5 giới hạn nhãn hàng đầu cũng là một phần của tải trọng (nhưng hoàn toàn không bắt buộc). Nếu lệnh gọi thành công, tải trọng sẽ trả về 5 nhãn hàng đầu của đối tượng cùng với điểm tin cậy của một đối tượng có trong hình ảnh. (Nếu không có phản hồi nào trả về, hãy chỉ định một từ điển Python trống để câu lệnh if
sau đây không bị lỗi.) Hàm này chỉ đối chiếu dữ liệu đó vào một chuỗi CSV để sử dụng trong báo cáo sau cùng.
5 dòng sau gọi vision_label_img()
phải được đặt ngay sau khi tải thành công lên Cloud Storage:
# process w/Vision
rsp = vision_label_img(base64.b64encode(data).decode('utf-8'), TOP)
if rsp:
print('Top %d labels from Vision API: %s' % (TOP, rsp))
else:
print('ERROR: Vision API cannot analyze %r' % fname)
Với phần bổ sung đó, toàn bộ trình điều khiển chính sẽ có dạng như sau:
if __name__ == '__main__':
# download img file & info from Drive
rsp = drive_get_img(FILE)
if rsp:
fname, mtype, ftime, data = rsp
print('Downloaded %r (%s, %s, size: %d)' % (fname, mtype, ftime, len(data)))
# upload file to GCS
gcsname = '%s/%s'% (PARENT, fname)
rsp = gcs_blob_upload(gcsname, BUCKET, data, mtype)
if rsp:
print('Uploaded %r to GCS bucket %r' % (rsp['name'], rsp['bucket']))
# process w/Vision
rsp = vision_label_img(base64.b64encode(data).decode('utf-8'), TOP)
if rsp:
print('Top %d labels from Vision API: %s' % (TOP, rsp))
else:
print('ERROR: Vision API cannot analyze %r' % fname)
else:
print('ERROR: Cannot upload %r to Cloud Storage' % gcsname)
else:
print('ERROR: Cannot download %r from Drive' % fname)
Việc xoá storage.json
để làm mới phạm vi và chạy lại ứng dụng đã cập nhật sẽ dẫn đến kết quả tương tự như sau, lưu ý rằng việc thêm bản phân tích Cloud Vision:
$ python3 analyze_gsimg.py . . . Authentication successful. Downloaded 'section-work-card-img_2x.jpg' (image/jpeg, 2020-02-27T09:27:22.095Z, size: 27781) Uploaded 'analyzed_imgs/section-work-card-img_2x.jpg' to GCS bucket 'vision-demo' Top 5 labels from Vision API: (89.94%) Sitting, (86.09%) Interior design, (82.08%) Furniture, (81.52%) Table, (80.85%) Room
Tóm tắt
Không phải ai cũng có chuyên môn về công nghệ học máy để tạo và huấn luyện mô hình học máy của riêng mình nhằm phân tích dữ liệu. Nhóm Google Cloud đã cung cấp một số mô hình huấn luyện trước của Google để sử dụng chung và triển khai chúng sau các API, giúp dân chủ hoá AI và ML cho mọi người.
Nếu là nhà phát triển và có thể gọi API, thì bạn có thể sử dụng công nghệ học máy. Cloud Vision chỉ là một trong những dịch vụ API mà bạn có thể dùng để phân tích dữ liệu của mình. Tìm hiểu thêm về các mạng khác tại đây. Mã của bạn bây giờ phải khớp với nội dung trong kho lưu trữ tại step3-vision/analyze_gsimg.py
.
11. Bước 4: Tạo báo cáo bằng Google Trang tính
Tại thời điểm này, bạn đã có thể lưu trữ và phân tích dữ liệu của công ty, nhưng điều còn thiếu là bản tóm tắt công việc này. Hãy sắp xếp tất cả các kết quả vào một báo cáo duy nhất mà bạn có thể giao cho sếp của mình. Tính năng nào dễ sử dụng hơn cho việc quản lý so với một bảng tính?
Bạn không cần nhập thêm dữ liệu cho API Google Trang tính. Thông tin mới duy nhất cần thiết là mã tệp của một bảng tính hiện có đã được định dạng và đang chờ hàng dữ liệu mới, do đó, hằng số SHEET
. Bạn nên tạo bảng tính mới giống như sau:
URL cho bảng tính đó sẽ có dạng như sau: https://docs.google.com/spreadsheets/d/
FILE_ID
/edit
. Lấy FILE_ID
đó và gán làm một sting cho SHEET
.
Chúng ta cũng xâm nhập vào một hàm nhỏ có tên k_ize()
. Hàm này chuyển đổi các byte thành kilobyte, định nghĩa hàm này là một lambda
Python vì đây là một mã 1 đơn giản. Cả hai đều được tích hợp với các hằng số khác đều có dạng như sau:
k_ize = lambda b: '%6.2fK' % (b/1000.) # bytes to kBs
FILE = 'YOUR_IMG_ON_DRIVE'
BUCKET = 'YOUR_BUCKET_NAME'
PARENT = '' # YOUR IMG FILE PREFIX
SHEET = 'YOUR_SHEET_ID'
TOP = 5 # TOP # of VISION LABELS TO SAVE
Giống như các bước trước, chúng ta cần một phạm vi quyền khác, lần này là tính năng đọc-ghi cho API Trang tính. SCOPES
hiện có cả 4 thành phần cần thiết:
SCOPES = (
'https://www.googleapis.com/auth/drive.readonly',
'https://www.googleapis.com/auth/devstorage.full_control',
'https://www.googleapis.com/auth/cloud-vision',
'https://www.googleapis.com/auth/spreadsheets',
)
Bây giờ, hãy tạo một điểm cuối dịch vụ vào Google Trang tính ở gần các điểm cuối khác, vì vậy, điểm cuối có dạng như sau:
# create API service endpoints
HTTP = creds.authorize(Http())
DRIVE = discovery.build('drive', 'v3', http=HTTP)
GCS = discovery.build('storage', 'v1', http=HTTP)
VISION = discovery.build('vision', 'v1', http=HTTP)
SHEETS = discovery.build('sheets', 'v4', http=HTTP)
Chức năng của sheet_append_row()
rất đơn giản: lấy một hàng dữ liệu và mã của một Trang tính, sau đó thêm hàng đó vào Trang tính đó:
def sheet_append_row(sheet, row):
'append row to a Google Sheet, return #cells added'
# call Sheets API to write row to Sheet (via its ID)
rsp = SHEETS.spreadsheets().values().append(
spreadsheetId=sheet, range='Sheet1',
valueInputOption='USER_ENTERED', body={'values': [row]}
).execute()
if rsp:
return rsp.get('updates').get('updatedCells')
Lệnh gọi spreadsheets().values().append()
yêu cầu mã tệp của Trang tính, một dải ô, cách nhập dữ liệu và bản thân dữ liệu đó. Mã tệp rất đơn giản, dải ô được cung cấp trong ký hiệu A1. Một phạm vi của "Sheet1
" nghĩa là toàn bộ Trang tính—thông tin này báo hiệu cho API để thêm hàng sau tất cả dữ liệu trong Trang tính. Có hai lựa chọn về cách thêm dữ liệu vào Trang tính, đó là "RAW
" (nhập nguyên văn dữ liệu chuỗi) hoặc "USER_ENTERED
" (ghi dữ liệu như thể người dùng đã nhập dữ liệu đó trên bàn phím bằng ứng dụng Google Trang tính, giữ nguyên mọi tính năng định dạng ô).
Nếu lệnh gọi thành công, thì giá trị trả về không thực sự hữu ích, vì vậy, chúng ta đã chọn nhận số lượng ô được cập nhật theo yêu cầu API. Dưới đây là mã gọi hàm đó:
# push results to Sheet, get cells-saved count
fsize = k_ize(len(data))
row = [PARENT,
'=HYPERLINK("storage.cloud.google.com/%s/%s", "%s")' % (
BUCKET, gcsname, fname), mtype, ftime, fsize, rsp
]
rsp = sheet_append_row(SHEET, row)
if rsp:
print('Updated %d cells in Google Sheet' % rsp)
else:
print('ERROR: Cannot write row to Google Sheets')
Google Trang tính có các cột biểu thị dữ liệu, chẳng hạn như mọi "thư mục con" mẹ vị trí của tệp được lưu trữ trên Cloud Storage (bộ chứa + tên tệp), MIME của tệp, kích thước tệp (ban đầu tính bằng byte, nhưng được chuyển đổi thành kilobyte với k_ize()
) và chuỗi nhãn Cloud Vision. Ngoài ra, xin lưu ý vị trí đã lưu trữ là một siêu liên kết để người quản lý của bạn có thể nhấp vào để xác nhận vị trí đã được sao lưu an toàn.
Thêm khối mã ở trên ngay sau khi hiển thị kết quả lấy từ Cloud Vision, phần chính điều khiển ứng dụng hiện đã hoàn tất, mặc dù có cấu trúc hơi phức tạp:
if __name__ == '__main__':
# download img file & info from Drive
rsp = drive_get_img(FILE)
if rsp:
fname, mtype, ftime, data = rsp
print('Downloaded %r (%s, %s, size: %d)' % (fname, mtype, ftime, len(data)))
# upload file to GCS
gcsname = '%s/%s'% (PARENT, fname)
rsp = gcs_blob_upload(gcsname, BUCKET, data, mtype)
if rsp:
print('Uploaded %r to GCS bucket %r' % (rsp['name'], rsp['bucket']))
# process w/Vision
rsp = vision_label_img(base64.b64encode(data).decode('utf-8'))
if rsp:
print('Top %d labels from Vision API: %s' % (TOP, rsp))
# push results to Sheet, get cells-saved count
fsize = k_ize(len(data))
row = [PARENT,
'=HYPERLINK("storage.cloud.google.com/%s/%s", "%s")' % (
BUCKET, gcsname, fname), mtype, ftime, fsize, rsp
]
rsp = sheet_append_row(SHEET, row)
if rsp:
print('Updated %d cells in Google Sheet' % rsp)
else:
print('ERROR: Cannot write row to Google Sheets')
else:
print('ERROR: Vision API cannot analyze %r' % fname)
else:
print('ERROR: Cannot upload %r to Cloud Storage' % gcsname)
else:
print('ERROR: Cannot download %r from Drive' % fname)
Việc xoá storage.json
một lần cuối và chạy lại ứng dụng đã cập nhật sẽ dẫn đến kết quả tương tự như sau, lưu ý rằng việc bổ sung bản phân tích Cloud Vision:
$ python3 analyze_gsimg.py . . . Authentication successful. Downloaded 'section-work-card-img_2x.jpg' (image/jpeg, 2020-02-27T09:27:22.095Z, size: 27781) Uploaded 'analyzed_imgs/section-work-card-img_2x.jpg' to GCS bucket 'vision-demo' Top 5 labels from Vision API: (89.94%) Sitting, (86.09%) Interior design, (82.08%) Furniture, (81.52%) Table, (80.85%) Room Updated 6 cells in Google Sheet
Dòng đầu ra bổ sung, mặc dù hữu ích, được hiển thị rõ hơn bằng cách xem nhanh Google Trang tính đã cập nhật, với dòng cuối cùng (hàng 7 trong ví dụ bên dưới) được thêm vào tập dữ liệu hiện có được thêm vào trước đó:
Tóm tắt
Trong 3 bước đầu tiên của hướng dẫn này, bạn đã kết nối với Google Workspace và Google Cloud API để di chuyển và phân tích dữ liệu, chiếm 80% tổng lượng công việc. Tuy nhiên, sau cùng, điều này không có ý nghĩa gì nếu bạn không thể trình bày cho ban quản lý tất cả những gì bạn đã làm được. Để trình bày trực quan các kết quả một cách trực quan hơn, hãy tóm tắt tất cả kết quả trong một báo cáo đã tạo.
Để nâng cao hơn nữa tính hữu ích của việc phân tích, ngoài việc ghi kết quả vào bảng tính, có thể cải tiến là lập chỉ mục 5 nhãn hàng đầu này cho mỗi hình ảnh để xây dựng cơ sở dữ liệu nội bộ cho phép nhân viên được uỷ quyền truy vấn hình ảnh theo nhóm tìm kiếm. Tuy nhiên, chúng tôi sẽ để điều này là một bài tập dành cho người đọc.
Hiện tại, kết quả của chúng ta ở trong một Trang tính và quản lý có thể truy cập được. Mã cho ứng dụng của bạn ở giai đoạn này phải khớp với mã trong kho lưu trữ tại step4-sheets/analyze_gsimg.py
. Bước cuối cùng là dọn dẹp và biến đổi mã đó thành một tập lệnh hữu dụng.
12. *Bước cuối cùng: tái cấu trúc
(không bắt buộc) Thật tốt khi có một ứng dụng hoạt động tốt, tuy nhiên chúng ta có thể cải thiện ứng dụng đó không? Có, đặc biệt là ứng dụng chính có vẻ lộn xộn. Hãy đặt biến đó vào hàm riêng và điều chỉnh để cho phép hoạt động đầu vào của người dùng thay vì các hằng số cố định. Chúng ta sẽ làm việc đó bằng mô-đun argparse
. Ngoài ra, hãy khởi chạy một thẻ trình duyệt web để hiển thị Trang tính sau khi chúng ta đã ghi hàng dữ liệu vào đó. Bạn có thể thực hiện việc này bằng mô-đun webbrowser
. Kết hợp các lệnh nhập này với các lệnh nhập khác để các lệnh nhập hàng đầu trông giống như sau:
from __future__ import print_function
import argparse
import base64
import io
import webbrowser
Để có thể sử dụng mã này trong các ứng dụng khác, chúng ta cần có khả năng ngăn chặn kết quả đầu ra, vì vậy hãy thêm cờ DEBUG
để thực hiện việc này, thêm dòng này vào cuối phần hằng số ở gần phía trên cùng:
DEBUG = False
Bây giờ là về phần nội dung chính. Khi chúng tôi tạo mẫu này, chắc hẳn bạn sẽ bắt đầu cảm thấy "không thoải mái" vì mã của chúng ta sẽ thêm một cấp độ lồng khác với mỗi dịch vụ được thêm. Nếu bạn cảm thấy như vậy, hãy yên tâm vì điều này sẽ khiến mã trở nên phức tạp hơn (như mô tả trong bài đăng này trên blog về Thử nghiệm của Google).
Làm theo phương pháp hay nhất này, hãy sắp xếp lại phần chính của ứng dụng thành một hàm và return
tại mỗi "điểm ngắt" thay vì lồng nhau (trả về None
nếu có bất kỳ bước nào không thành công và True
nếu tất cả đều thành công):
def main(fname, bucket, sheet_id, folder, top, debug):
'"main()" drives process from image download through report generation'
# download img file & info from Drive
rsp = drive_get_img(fname)
if not rsp:
return
fname, mtype, ftime, data = rsp
if debug:
print('Downloaded %r (%s, %s, size: %d)' % (fname, mtype, ftime, len(data)))
# upload file to GCS
gcsname = '%s/%s'% (folder, fname)
rsp = gcs_blob_upload(gcsname, bucket, data, mtype)
if not rsp:
return
if debug:
print('Uploaded %r to GCS bucket %r' % (rsp['name'], rsp['bucket']))
# process w/Vision
rsp = vision_label_img(base64.b64encode(data).decode('utf-8'))
if not rsp:
return
if debug:
print('Top %d labels from Vision API: %s' % (top, rsp))
# push results to Sheet, get cells-saved count
fsize = k_ize(len(data))
row = [folder,
'=HYPERLINK("storage.cloud.google.com/%s/%s", "%s")' % (
bucket, gcsname, fname), mtype, ftime, fsize, rsp
]
rsp = sheet_append_row(sheet_id, row)
if not rsp:
return
if debug:
print('Added %d cells to Google Sheet' % rsp)
return True
Nó gọn gàng và rõ ràng hơn, bỏ lại cảm giác chuỗi if-else
đệ quy đó, đồng thời giảm độ phức tạp của mã như mô tả ở trên. Phần cuối cùng của câu đố là tạo ra một "cuộc sống thực" trình điều khiển chính, cho phép tuỳ chỉnh người dùng và giảm thiểu đầu ra (trừ phi người dùng muốn):
if __name__ == '__main__':
# args: [-hv] [-i imgfile] [-b bucket] [-f folder] [-s Sheet ID] [-t top labels]
parser = argparse.ArgumentParser()
parser.add_argument("-i", "--imgfile", action="store_true",
default=FILE, help="image file filename")
parser.add_argument("-b", "--bucket_id", action="store_true",
default=BUCKET, help="Google Cloud Storage bucket name")
parser.add_argument("-f", "--folder", action="store_true",
default=PARENT, help="Google Cloud Storage image folder")
parser.add_argument("-s", "--sheet_id", action="store_true",
default=SHEET, help="Google Sheet Drive file ID (44-char str)")
parser.add_argument("-t", "--viz_top", action="store_true",
default=TOP, help="return top N (default %d) Vision API labels" % TOP)
parser.add_argument("-v", "--verbose", action="store_true",
default=DEBUG, help="verbose display output")
args = parser.parse_args()
print('Processing file %r... please wait' % args.imgfile)
rsp = main(args.imgfile, args.bucket_id,
args.sheet_id, args.folder, args.viz_top, args.verbose)
if rsp:
sheet_url = 'https://docs.google.com/spreadsheets/d/%s/edit' % args.sheet_id
print('DONE: opening web browser to it, or see %s' % sheet_url)
webbrowser.open(sheet_url, new=1, autoraise=True)
else:
print('ERROR: could not process %r' % args.imgfile)
Nếu tất cả các bước đều thành công, tập lệnh sẽ khởi chạy một trình duyệt web cho bảng tính được chỉ định mà tại đó hàng dữ liệu mới đã được thêm.
Tóm tắt
Không cần xoá storage.json
vì không có thay đổi nào về phạm vi. Chạy lại ứng dụng đã cập nhật cho thấy một cửa sổ trình duyệt mới mở ra Trang tính được sửa đổi, có ít dòng đầu ra hơn và đưa ra tuỳ chọn -h
cho người dùng thấy các tuỳ chọn của họ, bao gồm cả -v
để khôi phục các dòng đầu ra hiện đang bị chặn đã thấy trước đó:
$ python3 analyze_gsimg.py Processing file 'section-work-card-img_2x.jpg'... please wait DONE: opening web browser to it, or see https://docs.google.com/spreadsheets/d/SHEET_ID/edit $ python3 analyze_gsimg.py -h usage: analyze_gsimg.py [-h] [-i] [-t] [-f] [-b] [-s] [-v] optional arguments: -h, --help show this help message and exit -i, --imgfile image file filename -t, --viz_top return top N (default 5) Vision API labels -f, --folder Google Cloud Storage image folder -b, --bucket_id Google Cloud Storage bucket name -s, --sheet_id Google Sheet Drive file ID (44-char str) -v, --verbose verbose display output
Các tuỳ chọn khác cho phép người dùng chọn các tên tệp khác nhau trên Drive, "thư mục con" trên Cloud Storage và tên bộ chứa, chữ "N" trên cùng kết quả từ Cloud Vision và mã tệp bảng tính (Trang tính). Với những lần cập nhật cuối cùng này, phiên bản cuối cùng của mã giờ đây sẽ khớp với toàn bộ nội dung trong kho lưu trữ tại final/analyze_gsimg.py
cũng như ở đây:
'''
analyze_gsimg.py - analyze Google Workspace image processing workflow
Download image from Google Drive, archive to Google Cloud Storage, send
to Google Cloud Vision for processing, add results row to Google Sheet.
'''
from __future__ import print_function
import argparse
import base64
import io
import webbrowser
from googleapiclient import discovery, http
from httplib2 import Http
from oauth2client import file, client, tools
k_ize = lambda b: '%6.2fK' % (b/1000.) # bytes to kBs
FILE = 'YOUR_IMG_ON_DRIVE'
BUCKET = 'YOUR_BUCKET_NAME'
PARENT = '' # YOUR IMG FILE PREFIX
SHEET = 'YOUR_SHEET_ID'
TOP = 5 # TOP # of VISION LABELS TO SAVE
DEBUG = False
# process credentials for OAuth2 tokens
SCOPES = (
'https://www.googleapis.com/auth/drive.readonly',
'https://www.googleapis.com/auth/devstorage.full_control',
'https://www.googleapis.com/auth/cloud-vision',
'https://www.googleapis.com/auth/spreadsheets',
)
store = file.Storage('storage.json')
creds = store.get()
if not creds or creds.invalid:
flow = client.flow_from_clientsecrets('client_secret.json', SCOPES)
creds = tools.run_flow(flow, store)
# create API service endpoints
HTTP = creds.authorize(Http())
DRIVE = discovery.build('drive', 'v3', http=HTTP)
GCS = discovery.build('storage', 'v1', http=HTTP)
VISION = discovery.build('vision', 'v1', http=HTTP)
SHEETS = discovery.build('sheets', 'v4', http=HTTP)
def drive_get_img(fname):
'download file from Drive and return file info & binary if found'
# search for file on Google Drive
rsp = DRIVE.files().list(q="name='%s'" % fname,
fields='files(id,name,mimeType,modifiedTime)'
).execute().get('files', [])
# download binary & return file info if found, else return None
if rsp:
target = rsp[0] # use first matching file
fileId = target['id']
fname = target['name']
mtype = target['mimeType']
binary = DRIVE.files().get_media(fileId=fileId).execute()
return fname, mtype, target['modifiedTime'], binary
def gcs_blob_upload(fname, bucket, media, mimetype):
'upload an object to a Google Cloud Storage bucket'
# build blob metadata and upload via GCS API
body = {'name': fname, 'uploadType': 'multipart', 'contentType': mimetype}
return GCS.objects().insert(bucket=bucket, body=body,
media_body=http.MediaIoBaseUpload(io.BytesIO(media), mimetype),
fields='bucket,name').execute()
def vision_label_img(img, top):
'send image to Vision API for label annotation'
# build image metadata and call Vision API to process
body = {'requests': [{
'image': {'content': img},
'features': [{'type': 'LABEL_DETECTION', 'maxResults': top}],
}]}
rsp = VISION.images().annotate(body=body).execute().get('responses', [{}])[0]
# return top labels for image as CSV for Sheet (row)
if 'labelAnnotations' in rsp:
return ', '.join('(%.2f%%) %s' % (
label['score']*100., label['description']) \
for label in rsp['labelAnnotations'])
def sheet_append_row(sheet, row):
'append row to a Google Sheet, return #cells added'
# call Sheets API to write row to Sheet (via its ID)
rsp = SHEETS.spreadsheets().values().append(
spreadsheetId=sheet, range='Sheet1',
valueInputOption='USER_ENTERED', body={'values': [row]}
).execute()
if rsp:
return rsp.get('updates').get('updatedCells')
def main(fname, bucket, sheet_id, folder, top, debug):
'"main()" drives process from image download through report generation'
# download img file & info from Drive
rsp = drive_get_img(fname)
if not rsp:
return
fname, mtype, ftime, data = rsp
if debug:
print('Downloaded %r (%s, %s, size: %d)' % (fname, mtype, ftime, len(data)))
# upload file to GCS
gcsname = '%s/%s'% (folder, fname)
rsp = gcs_blob_upload(gcsname, bucket, data, mtype)
if not rsp:
return
if debug:
print('Uploaded %r to GCS bucket %r' % (rsp['name'], rsp['bucket']))
# process w/Vision
rsp = vision_label_img(base64.b64encode(data).decode('utf-8'), top)
if not rsp:
return
if debug:
print('Top %d labels from Vision API: %s' % (top, rsp))
# push results to Sheet, get cells-saved count
fsize = k_ize(len(data))
row = [folder,
'=HYPERLINK("storage.cloud.google.com/%s/%s", "%s")' % (
bucket, gcsname, fname), mtype, ftime, fsize, rsp
]
rsp = sheet_append_row(sheet_id, row)
if not rsp:
return
if debug:
print('Added %d cells to Google Sheet' % rsp)
return True
if __name__ == '__main__':
# args: [-hv] [-i imgfile] [-b bucket] [-f folder] [-s Sheet ID] [-t top labels]
parser = argparse.ArgumentParser()
parser.add_argument("-i", "--imgfile", action="store_true",
default=FILE, help="image file filename")
parser.add_argument("-b", "--bucket_id", action="store_true",
default=BUCKET, help="Google Cloud Storage bucket name")
parser.add_argument("-f", "--folder", action="store_true",
default=PARENT, help="Google Cloud Storage image folder")
parser.add_argument("-s", "--sheet_id", action="store_true",
default=SHEET, help="Google Sheet Drive file ID (44-char str)")
parser.add_argument("-t", "--viz_top", action="store_true",
default=TOP, help="return top N (default %d) Vision API labels" % TOP)
parser.add_argument("-v", "--verbose", action="store_true",
default=DEBUG, help="verbose display output")
args = parser.parse_args()
print('Processing file %r... please wait' % args.imgfile)
rsp = main(args.imgfile, args.bucket_id,
args.sheet_id, args.folder, args.viz_top, args.verbose)
if rsp:
sheet_url = 'https://docs.google.com/spreadsheets/d/%s/edit' % args.sheet_id
print('DONE: opening web browser to it, or see %s' % sheet_url)
webbrowser.open(sheet_url, new=1, autoraise=True)
else:
print('ERROR: could not process %r' % args.imgfile)
Chúng tôi sẽ cố gắng cập nhật nội dung của hướng dẫn này, nhưng sẽ có những trường hợp kho lưu trữ có phiên bản mã mới nhất.
13. Xin chúc mừng!
Chắc chắn là bạn đã tìm hiểu được rất nhiều điều trong lớp học lập trình này và bạn đã đạt được điều đó qua một trong những lớp học lập trình dài hơn. Kết quả là bạn đã xử lý một tình huống có thể xảy ra cho doanh nghiệp với khoảng 130 dòng Python, tận dụng toàn bộ Google Cloud và Google Workspace, đồng thời di chuyển dữ liệu giữa các nền tảng này để xây dựng một giải pháp hiệu quả. Bạn có thể khám phá kho lưu trữ nguồn mở cho tất cả phiên bản của ứng dụng này (xem thêm thông tin bên dưới).
Dọn dẹp
- Việc sử dụng Google Cloud API là không miễn phí trong khi API Google Workspace chịu phí thuê bao hằng tháng của Google Workspace (người dùng Gmail tiêu dùng có phí hằng tháng bằng 0), nên người dùng Google Workspace không cần phải dọn dẹp/ngừng hoạt động API. Đối với Google Cloud, bạn có thể chuyển đến trang tổng quan Cloud Console rồi kiểm tra "thẻ" Thanh toán để biết chi phí ước tính.
- Đối với Cloud Vision, bạn được phép thực hiện miễn phí một số lượng lệnh gọi API cố định mỗi tháng. Vì vậy, miễn là bạn không vượt quá các giới hạn đó, bạn không cần phải tắt tính năng nào và bạn cũng không phải vô hiệu hoá/xoá dự án của mình. Bạn có thể xem thêm thông tin về hạn mức miễn phí và thanh toán của Vision API trên trang giá của API Vision.
- Một số người dùng Cloud Storage nhận được dung lượng bộ nhớ miễn phí mỗi tháng. Nếu hình ảnh bạn lưu trữ bằng lớp học lập trình này không khiến bạn vượt quá hạn mức đó, thì bạn sẽ không phải chịu bất kỳ khoản phí nào. Bạn có thể xem thêm thông tin về việc thanh toán và hạn mức miễn phí của GCS trên trang giá của GCS. Bạn có thể xem và dễ dàng xoá các blob từ trình duyệt Cloud Storage.
- Việc bạn sử dụng Google Drive cũng có thể có một hạn mức bộ nhớ. Nếu vượt quá (hoặc gần đạt đến hạn mức này), bạn thực sự có thể cân nhắc sử dụng công cụ bạn đã tạo trong lớp học lập trình này để lưu trữ những hình ảnh đó vào Cloud Storage nhằm có thêm dung lượng trên Drive. Bạn có thể xem thêm thông tin về bộ nhớ Google Drive trên trang giá phù hợp cho người dùng Google Workspace Basic hoặc người dùng Gmail/người tiêu dùng.
Mặc dù hầu hết các gói Google Workspace Business và Enterprise đều có bộ nhớ không giới hạn, nhưng việc này có thể khiến thư mục của bạn trên Drive trở nên lộn xộn và/hoặc quá tải. Ngoài ra, ứng dụng bạn đã tạo trong phần hướng dẫn này là một cách hay để lưu trữ các tệp không liên quan và dọn dẹp Google Drive.
Phiên bản thay thế
Trong khi final/analyze_gsimg.py
là "cuối cùng" phiên bản chính thức mà bạn đang thực hiện trong hướng dẫn này, nhưng nó chưa phải là kết thúc của câu chuyện. Phiên bản hoàn thiện của ứng dụng có một vấn đề là phiên bản này sử dụng các thư viện xác thực cũ không còn được dùng nữa. Chúng tôi chọn cách này vì tại thời điểm viết bài này, các thư viện xác thực mới không hỗ trợ một số thành phần chính: Quản lý việc lưu trữ mã thông báo OAuth và an toàn luồng.
Thư viện xác thực hiện tại (mới hơn)
Tuy nhiên, đến một thời điểm nào đó, các thư viện xác thực cũ sẽ không còn được hỗ trợ nữa. Vì vậy, bạn nên xem lại các phiên bản sử dụng thư viện xác thực mới hơn (hiện tại) trong thư mục alt
của kho lưu trữ ngay cả khi các thư viện đó không an toàn theo luồng (nhưng bạn có thể tự xây dựng giải pháp của riêng mình). Tìm tệp có tên *newauth*
.
Thư viện ứng dụng sản phẩm Google Cloud
Tất cả nhà phát triển đều nên sử dụng thư viện ứng dụng của sản phẩm này khi dùng API Google Cloud. Rất tiếc, các API không phải của Google Cloud hiện không có các thư viện như vậy. Việc sử dụng các thư viện cấp thấp hơn cho phép việc sử dụng API nhất quán và các tính năng sẽ dễ đọc hơn. Tương tự như đề xuất ở trên, bạn có thể xem các phiên bản thay thế sử dụng thư viện ứng dụng sản phẩm của Google Cloud trong thư mục alt
của kho lưu trữ. Tìm tệp có tên *-gcp*
.
Uỷ quyền tài khoản dịch vụ
Khi làm việc hoàn toàn trên đám mây, thường không có dữ liệu của con người và dữ liệu thuộc quyền sở hữu của người dùng (con người). Đó là lý do người dùng chủ yếu sử dụng tài khoản dịch vụ và hoạt động uỷ quyền tài khoản dịch vụ cho Google Cloud. Tuy nhiên, các tài liệu trên Google Workspace thường thuộc quyền sở hữu của người dùng (con người). Đó là lý do hướng dẫn này sử dụng phương thức uỷ quyền dành cho tài khoản người dùng. Điều đó không có nghĩa là bạn không thể sử dụng API Google Workspace với tài khoản dịch vụ. Miễn là các tài khoản đó có cấp truy cập thích hợp, chúng chắc chắn có thể được sử dụng trong các ứng dụng. Tương tự như các phiên bản trên, bạn sẽ có thể xem các phiên bản thay thế sử dụng phương thức uỷ quyền tài khoản dịch vụ trong thư mục alt
của kho lưu trữ. Tìm tệp có tên *-svc*
.
Danh mục phiên bản thay thế
Dưới đây, bạn sẽ tìm thấy tất cả phiên bản thay thế của final/analyze_gsimg.py
, mỗi phiên bản có một hoặc nhiều thuộc tính nêu trên. Trong tên tệp của mỗi phiên bản, hãy tìm:
- "
oldauth
" đối với các phiên bản sử dụng thư viện xác thực cũ (ngoàifinal/analyze_gsimg.py
) - "
newauth
" đối với những người sử dụng thư viện xác thực hiện tại/mới hơn - "
gcp
" đối với những người sử dụng thư viện ứng dụng sản phẩm Google Cloud, chẳng hạn như google-cloud-storage, v.v. - "
svc
" đối với những người sử dụng xác thực tài khoản dịch vụ ("tài khoản svc") thay vì tài khoản người dùng
Dưới đây là tất cả các phiên bản:
Tên tệp | Mô tả |
| Mẫu chính; dùng các thư viện xác thực cũ |
| Giống như |
| Giống như |
| Giống như |
| Giống như |
| Giống như |
| Giống như |
| Giống như |
Khi kết hợp với final/analyze_gsimg.py
ban đầu , bạn có thể kết hợp mọi cách có thể có của giải pháp cuối cùng, bất kể môi trường phát triển API của Google, đồng thời có thể chọn cách phù hợp nhất với nhu cầu của mình. Ngoài ra, hãy xem alt/README.md
để xem nội dung giải thích tương tự.
Nghiên cứu bổ sung
Dưới đây là một vài ý tưởng về cách bạn có thể thực hiện bài tập này thêm một hoặc hai bước nữa. Bạn có thể mở rộng vấn đề mà giải pháp hiện tại có thể xử lý để thực hiện các cải tiến sau:
- (nhiều hình ảnh trong thư mục) Thay vì xử lý một hình ảnh, giả sử bạn có hình ảnh trong thư mục Google Drive.
- (nhiều hình ảnh trong tệp ZIP) Thay vì một thư mục hình ảnh, vậy còn tệp lưu trữ ZIP chứa các tệp hình ảnh thì sao? Nếu sử dụng Python, hãy cân nhắc sử dụng mô-đun
zipfile
. - (phân tích nhãn Tầm nhìn) Nhóm các hình ảnh tương tự lại với nhau, có thể bắt đầu bằng cách tìm các nhãn phổ biến nhất, sau đó đến nhãn phổ biến thứ 2, v.v.
- (tạo biểu đồ) Tiếp theo #3, tạo biểu đồ bằng API Trang tính dựa trên phân loại và phân loại Vision API
- (phân loại tài liệu) Thay vì phân tích hình ảnh bằng Cloud Vision API, giả sử bạn có các tệp PDF cần phân loại bằng Cloud Natural Language API. Sử dụng các giải pháp ở trên, các tệp PDF này có thể ở trong thư mục Drive hoặc tệp lưu trữ ZIP trên Drive.
- (tạo bản trình bày) Sử dụng API Trang trình bày để tạo một bản trình bày từ nội dung của báo cáo Google Trang tính. Để có cảm hứng, hãy xem bài đăng trên blog này và về cách tạo trang trình bày từ dữ liệu bảng tính.
- (xuất dưới dạng PDF) Xuất bảng tính và/hoặc bản trình bày dưới dạng PDF, tuy nhiên, đây không phải là tính năng của API Trang tính và API Trang trình bày. Gợi ý: API Google Drive. Điểm cộng: hợp nhất cả tệp PDF trên Trang tính và Trang trình bày thành một tệp PDF chính bằng các công cụ như Ghostscript (Linux, Windows) hoặc
Combine PDF Pages.action
(Mac OS X).
Tìm hiểu thêm
Lớp học lập trình
- Giới thiệu về API của Google Workspace (API Google Drive) (Python)
- Sử dụng Cloud Vision với Python (Python)
- Tạo công cụ báo cáo tuỳ chỉnh (API Google Trang tính) (JS/Node)
- Tải đối tượng lên Google Cloud Storage (không cần lập trình)
Giải pháp chung
Google Workspace
- Trang chủ API Google Drive
- Trang chủ API Google Trang tính
- Tổng quan về Google Workspace dành cho nhà phát triển và tài liệu
Google Cloud
- Trang chủ của Google Cloud Storage
- Trang chủ của Google Cloud Vision và bản minh hoạ trực tiếp
- Tài liệu về API Cloud Vision
- Tài liệu về việc gắn nhãn hình ảnh cho Vision API
- Python trên Google Cloud
- Thư viện ứng dụng sản phẩm Google Cloud
- Tài liệu của Google Cloud
Giấy phép
Tác phẩm này được cấp phép theo Giấy phép chung Ghi nhận tác giả Creative Commons 2.0.