feat[resource_management]: add ResourcePathManager class to allow users to specify alternate search paths

for resources in order to fit with their own deployment structure layout.
The ResourcePathManager class allows to add absolute or relative additionnal search paths where resources can be located (for instance tflite files).
This commit is contained in:
Firefly35 2023-04-20 11:48:33 +02:00
parent 331692577e
commit 3f695daa17
6 changed files with 115 additions and 0 deletions

View File

@ -188,6 +188,8 @@ cc_library(
srcs = [ srcs = [
"resource_util.cc", "resource_util.cc",
"resource_util_internal.h", "resource_util_internal.h",
"resource_path_manager.cc",
"resource_path_manager.h",
] + select({ ] + select({
"//conditions:default": ["resource_util_default.cc"], "//conditions:default": ["resource_util_default.cc"],
"//mediapipe:android": ["resource_util_android.cc"], "//mediapipe:android": ["resource_util_android.cc"],

View File

@ -0,0 +1,47 @@
// Copyright 2019 The MediaPipe Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "mediapipe/util/resource_path_manager.h"
#include <iostream>
#include "absl/strings/str_split.h"
#include "mediapipe/framework/deps/file_path.h"
#include "mediapipe/framework/port/file_helpers.h"
#include "mediapipe/framework/port/ret_check.h"
namespace mediapipe {
std::vector<std::string> resource_search_paths_;
void ResourcePathManager::AddSearchPath(const std::string& path)
{
resource_search_paths_.push_back(path);
}
absl::StatusOr<std::string> ResourcePathManager::ResolveFilePath(const std::string& path)
{
if (absl::StartsWith(path, "/")) {
return path;
}
for (auto & resource_path: resource_search_paths_) {
auto file_path = file::JoinPath(resource_path, path);
if (file::Exists(file_path).ok()) {
return file_path;
}
}
return absl::NotFoundError("No file " + path + " found in declared search paths");
}
} // namespace mediapipe

View File

@ -0,0 +1,36 @@
// Copyright 2019 The MediaPipe Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef MEDIAPIPE_UTIL_RESOURCE_PATH_MANAGER_H_
#define MEDIAPIPE_UTIL_RESOURCE_PATH_MANAGER_H_
#include <string>
#include "mediapipe/framework/port/statusor.h"
namespace mediapipe {
// The ResourcePathManager provides additionnal search paths handling for resources (tflite...) locations.
class ResourcePathManager {
public:
// Adds a path to search resources for.
static void AddSearchPath(const std::string& path);
// Tries to resolve a filepath from path and previously added search path.
// Either return the filepath when it exists, or absl::NotFoundError when the path doesn't exists.
static absl::StatusOr<std::string> ResolveFilePath(const std::string& path);
};
} // namespace mediapipe
#endif // MEDIAPIPE_UTIL_RESOURCE_UTIL_H_

View File

@ -21,6 +21,7 @@
#include "mediapipe/framework/port/statusor.h" #include "mediapipe/framework/port/statusor.h"
#include "mediapipe/util/android/asset_manager_util.h" #include "mediapipe/util/android/asset_manager_util.h"
#include "mediapipe/util/android/file/base/helpers.h" #include "mediapipe/util/android/file/base/helpers.h"
#include "mediapipe/util/resource_path_manager.h"
namespace mediapipe { namespace mediapipe {
@ -79,6 +80,15 @@ absl::StatusOr<std::string> PathToResourceAsFile(const std::string& path) {
} }
} }
// try to load file in potentially declared resource paths
{
auto status_or_path = ResourcePathManager::ResolveFilePath(path);
if (status_or_path.ok()) {
LOG(INFO) << "Successfully loaded: " << path;
return status_or_path;
}
}
// If that fails, assume it was a relative path, and try just the base name. // If that fails, assume it was a relative path, and try just the base name.
{ {
const size_t last_slash_idx = path.find_last_of("\\/"); const size_t last_slash_idx = path.find_last_of("\\/");

View File

@ -22,6 +22,7 @@
#include "mediapipe/framework/port/ret_check.h" #include "mediapipe/framework/port/ret_check.h"
#include "mediapipe/framework/port/statusor.h" #include "mediapipe/framework/port/statusor.h"
#include "mediapipe/util/resource_util.h" #include "mediapipe/util/resource_util.h"
#include "mediapipe/util/resource_path_manager.h"
namespace mediapipe { namespace mediapipe {
@ -59,6 +60,15 @@ absl::StatusOr<std::string> PathToResourceAsFile(const std::string& path) {
return path; return path;
} }
// try to load file in potentially declared resource paths
{
auto status_or_path = ResourcePathManager::ResolveFilePath(path);
if (status_or_path.ok()) {
LOG(INFO) << "Successfully loaded: " << path;
return status_or_path;
}
}
// Try to load a relative path or a base filename as is. // Try to load a relative path or a base filename as is.
{ {
auto status_or_path = PathToResourceAsFileInternal(path); auto status_or_path = PathToResourceAsFileInternal(path);

View File

@ -18,6 +18,7 @@
#include "mediapipe/framework/deps/file_path.h" #include "mediapipe/framework/deps/file_path.h"
#include "mediapipe/framework/port/file_helpers.h" #include "mediapipe/framework/port/file_helpers.h"
#include "mediapipe/framework/port/statusor.h" #include "mediapipe/framework/port/statusor.h"
#include "mediapipe/util/resource_path_manager.h"
ABSL_FLAG( ABSL_FLAG(
std::string, resource_root_dir, "", std::string, resource_root_dir, "",
@ -43,6 +44,15 @@ absl::StatusOr<std::string> PathToResourceAsFile(const std::string& path) {
return path; return path;
} }
// try to load file in potentially declared resource paths
{
auto status_or_path = ResourcePathManager::ResolveFilePath(path);
if (status_or_path.ok()) {
LOG(INFO) << "Successfully loaded: " << path;
return status_or_path;
}
}
// Try to load the file from bazel-bin. If it does not exist, fall back to the // Try to load the file from bazel-bin. If it does not exist, fall back to the
// resource folder. // resource folder.
auto bazel_path = JoinPath("bazel-bin", path); auto bazel_path = JoinPath("bazel-bin", path);