Skip to content

Commit

Permalink
singleton
Browse files Browse the repository at this point in the history
  • Loading branch information
faithoflifedev committed Sep 2, 2024
1 parent dfa07c5 commit 4ac90a6
Show file tree
Hide file tree
Showing 20 changed files with 112 additions and 128 deletions.
8 changes: 8 additions & 0 deletions packages/google_vision/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# Changelog

## 1.4.0

* switch to Singleton

## 1.3.0+4

* switch to Singleton

## 1.3.0+4

* readme update
Expand Down
32 changes: 21 additions & 11 deletions packages/google_vision/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,19 @@
[![pub package](https://img.shields.io/pub/v/google_vision.svg)](https://pub.dartlang.org/packages/google_vision)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

Native [Dart](https://dart.dev/) package that integrates Google Vision features, including image labeling, face, logo, and landmark detection, optical character recognition (OCR), and detection of explicit content, into applications.
Native [Dart](https://dart.dev/) package that integrates Google Vision features, including image labeling, face, logo, and landmark detection, optical character recognition (OCR), and detection of explicit content, into your applications.

**If you are looking at integrating the Google Vision API into your `Flutter` SDK application then you might want to take a look at my related package [google_vision_flutter](https://pub.dev/packages/google_vision_flutter), which provides a widget that wraps the functionality provided by this `Dart` SDK focussed package.**

- [Google Vision Images REST API Client](#google-vision-images-rest-api-client)
- [Project Status](#project-status)
- [Recent Changes](#recent-changes)
- [New for v1.4.0](#new-for-v140)
- [New for v1.3.0](#new-for-v130)
- [New for v1.2.0](#new-for-v120)
- [New for v1.0.8](#new-for-v108)
- [New for v1.0.7](#new-for-v107)
- [Getting Started](#getting-started)
- [pubspec.yaml](#pubspecyaml)
- [Obtaining Authorization Credentials](#obtaining-authorization-credentials)
- [Obtaining Authentication/Authorization Credentials](#obtaining-authenticationauthorization-credentials)
- [Usage of the Cloud Vision API](#usage-of-the-cloud-vision-api)
- [New Helper Methods](#new-helper-methods)
- [Usage with Flutter](#usage-with-flutter)
Expand All @@ -23,8 +25,8 @@ Native [Dart](https://dart.dev/) package that integrates Google Vision features,
- [Contributors](#contributors)
- [Contributing](#contributing)

## Project Status

## Project Status

[![Build Status](https://github.com/faithoflifedev/google_vision/workflows/Dart/badge.svg)](https://github.com/faithoflifedev/google_vision/actions) [![github last commit](https://shields.io/github/last-commit/faithoflifedev/google_vision)](https://shields.io/github/last-commit/faithoflifedev/google_vision) [![github build](https://img.shields.io/github/actions/workflow/status/faithoflifedev/google_vision_workspace/dart.yaml?branch=main)](https://shields.io/github/workflow/status/faithoflifedev/google_vision/Dart) [![github issues](https://shields.io/github/issues/faithoflifedev/google_vision)](https://shields.io/github/issues/faithoflifedev/google_vision)

Expand All @@ -34,17 +36,25 @@ Please feel free to submit PRs for any additional helper methods, or report an [

## Recent Changes

### New for v1.4.0
- A breaking change from the previous version is that the `GoogleVision` class now follows the Singleton design pattern. Now the object is instantiated as follows:
```dart
// Old method from v1.3.x and earlier
// final googleVision = await GoogleVision.withJwtFile('service_credentials.json');
// New
final googleVision = await GoogleVision().withJwtFile('service_credentials.json');
```

### New for v1.3.0
- This version of the package supports both the `image` and `file` annotation APIs for Google Vision. The previous versions of the package supported only the `image` API.
- A number of methods and classes have been **Deprecated** in this version. All the provided examples still work without any changes, so the changes in this package should not cause any issue to existing code.
- The `file` functionality added to this release allows for the annotation of file formats that have pages or frames, specifically `pdf`, `tiff` and `gif`. Google Vision allows annotation of up to 5 pages/frames.

### New for v1.2.0
- helper methods that simplify any `single` detection so a simple face detection can be performed with the `faceDetection(JsonImage jsonImage)` method, see the table below.

### New for v1.0.8
- web entities and pages detection [https://cloud.google.com/vision/docs/detecting-web](https://cloud.google.com/vision/docs/detecting-web), provides urls of web pages that match the specified image


## Getting Started

### pubspec.yaml
Expand All @@ -54,7 +64,7 @@ To use this package, add the dependency to your `pubspec.yaml` file:
```yaml
dependencies:
...
google_vision: ^1.3.0+4
google_vision: ^1.4.0
```
### Obtaining Authentication/Authorization Credentials
Expand All @@ -68,7 +78,7 @@ Both of the authorization/authentication methods listed above assume that you al
### Usage of the Cloud Vision API
```dart
final googleVision = await GoogleVision.withApiKey(
final googleVision = await GoogleVision().withApiKey(
Platform.environment['GOOGLE_VISION_API_KEY'] ?? '[YOUR API KEY]',
// additionalHeaders: {'com.xxx.xxx': 'X-Ios-Bundle-Identifier'},
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import 'package:universal_io/io.dart';

void main() async {
final googleVision =
await GoogleVision.withJwtFile('service_credentials.json');
await GoogleVision().withJwtFile('service_credentials.json');

print('checking...');

Expand Down
2 changes: 1 addition & 1 deletion packages/google_vision/example/doument_text_detection.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import 'package:google_vision/google_vision.dart';

void main() async {
final googleVision =
await GoogleVision.withJwtFile('service_credentials.json');
await GoogleVision().withJwtFile('service_credentials.json');

print('checking...');

Expand Down
2 changes: 1 addition & 1 deletion packages/google_vision/example/example.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import 'package:google_vision/google_vision.dart';

void main() async {
final googleVision =
await GoogleVision.withJwtFile('service_credentials.json');
await GoogleVision().withJwtFile('service_credentials.json');

final requests = AnnotationRequests(requests: [
AnnotationRequest(
Expand Down
5 changes: 1 addition & 4 deletions packages/google_vision/example/face_detection.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,7 @@ import 'package:google_vision/google_vision.dart';
import 'package:universal_io/io.dart';

void main() async {
// final googleVision =
// await GoogleVision.withJwtFile('service_credentials.json');

final googleVision = GoogleVision.withApiKey(
final googleVision = GoogleVision().withApiKey(
Platform.environment['GOOGLE_VISION_API_KEY'] ?? '[YOUR API KEY]',
// additionalHeaders: {'com.xxx.xxx': 'X-Ios-Bundle-Identifier'},
);
Expand Down
4 changes: 2 additions & 2 deletions packages/google_vision/example/label_detection.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import 'package:google_vision/google_vision.dart';

void main() async {
final googleVision =
await GoogleVision.withJwtFile('service_credentials.json');
await GoogleVision().withJwtFile('service_credentials.json');

print('checking...');

Expand All @@ -13,7 +13,7 @@ void main() async {
for (var entityAnnotation in entityAnnotations) {
print('Description: - ${entityAnnotation.description}');

print('Score: - ${entityAnnotation.boundingPoly?.normalizedVertices}');
print('Score: - ${entityAnnotation.score}');
}

print('done.');
Expand Down
2 changes: 1 addition & 1 deletion packages/google_vision/example/landmark_detection.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import 'package:google_vision/google_vision.dart';

void main() async {
final googleVision =
await GoogleVision.withJwtFile('service_credentials.json');
await GoogleVision().withJwtFile('service_credentials.json');

print('checking...');

Expand Down
2 changes: 1 addition & 1 deletion packages/google_vision/example/logo_detection.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import 'package:google_vision/google_vision.dart';

void main() async {
final googleVision =
await GoogleVision.withJwtFile('service_credentials.json');
await GoogleVision().withJwtFile('service_credentials.json');

print('checking...');

Expand Down
2 changes: 1 addition & 1 deletion packages/google_vision/example/text_detection.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import 'package:universal_io/io.dart';

void main() async {
final googleVision =
await GoogleVision.withJwtFile('service_credentials.json');
await GoogleVision().withJwtFile('service_credentials.json');

final imageFile = File('sample_image/structures.png').readAsBytesSync();

Expand Down
2 changes: 1 addition & 1 deletion packages/google_vision/example/web_detection.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import 'package:universal_io/io.dart';

void main() async {
final googleVision =
await GoogleVision.withJwtFile('service_credentials.json');
await GoogleVision().withJwtFile('service_credentials.json');

final imageFile = File('sample_image/structures.png').readAsBytesSync();

Expand Down
1 change: 0 additions & 1 deletion packages/google_vision/lib/google_vision.dart
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,5 @@ export 'src/provider/files.dart';
export 'src/provider/images.dart';
export 'src/provider/oauth.dart';

export 'src/util/logging_interceptors.dart';
export 'src/util/serializable_image.dart';
export 'src/util/util.dart';
2 changes: 1 addition & 1 deletion packages/google_vision/lib/meta.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@ library meta;
import 'dart:convert' show json;

final pubSpec = json.decode(
'{"name":"google_vision","version":"1.3.0+4","homepage":"https://github.com/faithoflifedev/google_vision/tree/main/packages/google_vision","environment":{"sdk":">=3.2.0 <4.0.0"},"description":"Allows you to add Google Visions image labeling, face, logo, and landmark detection, OCR, and detection of explicit content, into cross platform applications.","dependencies":{"args":"^2.5.0","collection":"^1.18.0","crypto_keys_plus":"^0.4.0","dio":"^5.6.0","http":"^1.2.2","image":"^4.1.7","jose_plus":"^0.4.6","json_annotation":"^4.9.0","loggy":"^2.0.3","mime":"^1.0.6","retrofit":"^4.2.0","universal_io":"^2.2.2"},"dev_dependencies":{"build_runner":"^2.4.11","grinder":"^0.9.5","json_serializable":"^6.8.0","lints":"^4.0.0","publish_tools":"^1.0.0+4","retrofit_generator":"^8.2.0"},"executables":{"vision":""},"repository":"https://github.com/faithoflifedev/google_vision","funding":["https://www.buymeacoffee.com/faithoflif2"]}');
'{"name":"google_vision","version":"1.4.0","homepage":"https://github.com/faithoflifedev/google_vision/tree/main/packages/google_vision","environment":{"sdk":">=3.2.0 <4.0.0"},"description":"Allows you to add Google Visions image labeling, face, logo, and landmark detection, OCR, and detection of explicit content, into cross platform applications.","dependencies":{"args":"^2.5.0","collection":"^1.18.0","crypto_keys_plus":"^0.4.0","dio":"^5.6.0","http":"^1.2.2","image":"^4.1.7","jose_plus":"^0.4.6","json_annotation":"^4.9.0","mime":"^1.0.6","retrofit":"^4.2.0","universal_io":"^2.2.2"},"dev_dependencies":{"build_runner":"^2.4.11","grinder":"^0.9.5","json_serializable":"^6.8.0","lints":"^4.0.0","publish_tools":"^1.0.0+4","retrofit_generator":"^8.2.1"},"executables":{"vision":""},"repository":"https://github.com/faithoflifedev/google_vision","funding":["https://www.buymeacoffee.com/faithoflif2"]}');
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class VisionCropHintCommand extends VisionHelper {

@override
void run() async {
final googleVision = await GoogleVision.withJwtFile(
final googleVision = await GoogleVision().withJwtFile(
globalResults!['credential-file'],
'https://www.googleapis.com/auth/cloud-vision');

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ abstract class VisionHelper extends Command {

Future<void> initializeGoogleVision() async {
_googleVision =
await GoogleVision.withJwtFile(globalResults!['credential-file']);
await GoogleVision().withJwtFile(globalResults!['credential-file']);

pages =
(argResults!['pages'] as String?)?.split(',').map(int.parse).toList();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class VisionSafeSearchCommand extends VisionHelper {

@override
void run() async {
final googleVision = await GoogleVision.withJwtFile(
final googleVision = await GoogleVision().withJwtFile(
globalResults!['credential-file'],
'https://www.googleapis.com/auth/cloud-vision');

Expand Down
85 changes: 47 additions & 38 deletions packages/google_vision/lib/src/google_vision_base.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,49 +2,48 @@ import 'dart:io';

import 'package:dio/dio.dart';
import 'package:google_vision/google_vision.dart';
import 'package:loggy/loggy.dart';

/// Integrates Google Vision features, including painter labeling, face, logo,
/// and landmark detection, optical character recognition (OCR), and detection
/// of explicit content, into applications.
class GoogleVision with UiLoggy {
static final dio = Dio();
static final DateTime tokenExpiry = DateTime(2010, 0, 0);
static final accept = 'application/json';
static final contentType = 'application/json; charset=UTF-8';
class GoogleVision {
static final GoogleVision _instance = GoogleVision._internal();

static String? _apiKey;
static String? _token;
static TokenGenerator? tokenGenerator;
final dio = Dio();
final tokenExpiry = DateTime(2010, 0, 0);

static final _imagesClient = ImagesClient(dio);
final _filesClient = FilesClient(dio);
late final _imagesClient = ImagesClient(dio);
late final _filesClient = FilesClient(dio);

static const accept = 'application/json';
static const contentType = 'application/json; charset=UTF-8';

TokenGenerator? tokenGenerator;
String? _apiKey;
String? _token;

GoogleVisionImage get image => GoogleVisionImage(this, _imagesClient);

GoogleVisionFile get file => GoogleVisionFile(this, _filesClient);

GoogleVision() {
Loggy.initLoggy(
logPrinter: const PrettyPrinter(),
logOptions: LogOptions(LogLevel.off),
);
set apiKey(String apiKey) => _apiKey = apiKey;

GoogleVision.dio.interceptors.add(LoggingInterceptors());
}
// Private constructor
GoogleVision._internal();

factory GoogleVision() => _instance;

void setAuthHeader() {
if (_token != null) {
GoogleVision.dio.options.headers[HttpHeaders.authorizationHeader] =
'Bearer $_token';
dio.options.headers[HttpHeaders.authorizationHeader] = 'Bearer $_token';
}

if (_apiKey != null) {
GoogleVision.dio.options.queryParameters['key'] = _apiKey;
dio.options.queryParameters['key'] = _apiKey;
}
}

static Future<void> _confirmToken() async {
Future<void> confirmToken() async {
if (tokenGenerator == null) {
throw Exception();
} else {
Expand All @@ -59,52 +58,62 @@ class GoogleVision with UiLoggy {
}

/// Authenticate using an API key.
static GoogleVision withApiKey(
GoogleVision withApiKey(
String apiKey, {
Map<String, String>? additionalHeaders,
}) {
_apiKey = apiKey;
this.apiKey = apiKey;

if (additionalHeaders != null) {
dio.options.headers.addAll(additionalHeaders);
}

return GoogleVision();
return this;
}

/// Authenticate using the supplied token generator
static Future<GoogleVision> withGenerator(TokenGenerator generator) async {
Future<GoogleVision> withGenerator(TokenGenerator generator) async {
final googleVision = GoogleVision();

GoogleVision.tokenGenerator = generator;
googleVision.tokenGenerator = generator;

await _confirmToken();
await googleVision.confirmToken();

return googleVision;
}

/// Authenticated with JWT.
static Future<GoogleVision> withJwt(String credentials,
[String scope = 'https://www.googleapis.com/auth/cloud-platform']) async {
Future<GoogleVision> withJwt(
String credentials, [
String scope = 'https://www.googleapis.com/auth/cloud-platform',
]) async {
GoogleVision googleVision = GoogleVision();

tokenGenerator =
JwtGenerator(credentials: credentials, scope: scope, dio: dio);
googleVision.tokenGenerator = JwtGenerator(
credentials: credentials,
scope: scope,
dio: googleVision.dio,
);

await _confirmToken();
await googleVision.confirmToken();

return googleVision;
}

/// Authenticated with JWT.
static Future<GoogleVision> withJwtFile(String credentialsFileName,
[String scope = 'https://www.googleapis.com/auth/cloud-platform']) async {
Future<GoogleVision> withJwtFile(
String credentialsFileName, [
String scope = 'https://www.googleapis.com/auth/cloud-platform',
]) async {
GoogleVision googleVision = GoogleVision();

tokenGenerator = JwtGenerator.fromFile(
credentialsFile: credentialsFileName, scope: scope, dio: dio);
googleVision.tokenGenerator = JwtGenerator.fromFile(
credentialsFile: credentialsFileName,
scope: scope,
dio: googleVision.dio,
);

await _confirmToken();
await googleVision.confirmToken();

return googleVision;
}
Expand Down
Loading

0 comments on commit 4ac90a6

Please sign in to comment.