init from AzureVision
This commit is contained in:
Родитель
eb656fc473
Коммит
bdf824cfab
|
@ -0,0 +1,9 @@
|
|||
^misc$
|
||||
^\.vs$
|
||||
\.sln$
|
||||
\.Rproj$
|
||||
\.Rxproj$
|
||||
^\.Rproj\.user$
|
||||
^LICENSE\.md$
|
||||
azure-pipelines.yml
|
||||
SECURITY.md
|
|
@ -34,3 +34,5 @@ vignettes/*.pdf
|
|||
|
||||
# Shiny token, see https://shiny.rstudio.com/articles/shinyapps.html
|
||||
rsconnect/
|
||||
|
||||
misc/
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
Package: AzureCognitive
|
||||
Title: Interface to Azure Cognitive Services
|
||||
Version: 0.0.1
|
||||
Authors@R: c(
|
||||
person("Hong", "Ooi", , "hongooi@microsoft.com", role = c("aut", "cre")),
|
||||
person("Microsoft", role="cph")
|
||||
)
|
||||
Description: An interface to the Azure Cognitive Services REST API.
|
||||
URL: https://github.com/Azure/AzureCognitive https://github.com/Azure/AzureR
|
||||
BugReports: https://github.com/Azure/AzureCognitive/issues
|
||||
License: MIT + file LICENSE
|
||||
Depends:
|
||||
R (>= 3.3)
|
||||
Imports:
|
||||
AzureAuth,
|
||||
AzureRMR,
|
||||
jsonlite,
|
||||
httr (>= 1.3)
|
||||
Roxygen: list(markdown=TRUE)
|
||||
RoxygenNote: 6.1.1
|
23
LICENSE
23
LICENSE
|
@ -1,21 +1,2 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) Microsoft Corporation.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE
|
||||
YEAR: 2019
|
||||
COPYRIGHT HOLDER: Microsoft
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
# MIT License
|
||||
|
||||
Copyright (c) Microsoft Corporation.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE
|
|
@ -0,0 +1,3 @@
|
|||
# Generated by roxygen2: do not edit by hand
|
||||
|
||||
import(AzureRMR)
|
|
@ -0,0 +1,46 @@
|
|||
#' @import AzureRMR
|
||||
NULL
|
||||
|
||||
globalVariables(c("self", "private"))
|
||||
|
||||
.onLoad <- function(libname, pkgname)
|
||||
{
|
||||
add_methods()
|
||||
}
|
||||
|
||||
|
||||
add_methods <- function()
|
||||
{
|
||||
az_resource_group$set("public", "create_cognitive_service", overwrite=TRUE,
|
||||
function(name, location=self$location, subdomain=name, kind="ComputerVision", sku="S1", properties=list(), ...)
|
||||
{
|
||||
if(!is.null(subdomain))
|
||||
properties <- utils::modifyList(properties, list(customSubDomainName=subdomain))
|
||||
|
||||
az_cognitive_service$new(self$token, self$subscription, self$name,
|
||||
type="Microsoft.CognitiveServices/accounts",
|
||||
name=name,
|
||||
location=location,
|
||||
kind="ComputerVision",
|
||||
sku=list(name=sku),
|
||||
properties=properties,
|
||||
...)
|
||||
})
|
||||
|
||||
az_resource_group$set("public", "get_cognitive_service", overwrite=TRUE,
|
||||
function(name)
|
||||
{
|
||||
az_cognitive_service$new(self$token, self$subscription, self$name,
|
||||
type="Microsoft.CognitiveServices/accounts",
|
||||
name=name)
|
||||
})
|
||||
|
||||
az_resource_group$set("public", "delete_cognitive_service", overwrite=TRUE,
|
||||
function(name, confirm=TRUE, wait=FALSE)
|
||||
{
|
||||
az_cognitive_service$new(self$token, self$subscription, self$name,
|
||||
type="Microsoft.CognitiveServices/accounts",
|
||||
name=name,
|
||||
deployed_properties=list(NULL))$delete(confirm=confirm, wait=wait)
|
||||
})
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
az_cognitive_service <- R6::R6Class("az_cognitive_service", inherit=AzureRMR::az_resource,
|
||||
|
||||
public=list(
|
||||
list_keys=function()
|
||||
{
|
||||
unlist(private$res_op("listKeys", http_verb="POST"))
|
||||
},
|
||||
|
||||
regen_key=function(key=1)
|
||||
{
|
||||
body=list(keyName=paste0("Key", key))
|
||||
unlist(private$res_op("regenerateKey", body=body, http_verb="POST"))
|
||||
},
|
||||
|
||||
list_skus=function()
|
||||
{
|
||||
private$res_op("skus")$value
|
||||
},
|
||||
|
||||
get_endpoint=function()
|
||||
{
|
||||
cognitive_endpoint(self$properties$endpoint, self$kind, key=self$list_keys()[1])
|
||||
}
|
||||
))
|
||||
|
|
@ -0,0 +1,117 @@
|
|||
cognitive_endpoint <- function(url, type, key=NULL, aad_token=NULL, cognitive_token=NULL)
|
||||
{
|
||||
type <- normalize_cognitive_type(type)
|
||||
url <- httr::parse_url(url)
|
||||
url$path <- get_api_path(type)
|
||||
|
||||
object <- list(url=url, key=key, aad_token=aad_token, cognitive_token=cognitive_token)
|
||||
class(object) <- c(paste0(type, "_endpoint"), "cognitive_endpoint")
|
||||
|
||||
object
|
||||
}
|
||||
|
||||
|
||||
call_cognitive_endpoint <- function(endpoint, operation, options=list(), headers=list(), body=NULL, encode="json",
|
||||
http_verb=c("GET", "POST", "PUT", "PATCH", "DELETE", "HEAD"),
|
||||
http_status_handler=c("stop", "warn", "message", "pass"))
|
||||
{
|
||||
url <- endpoint$url
|
||||
url$path <- file.path(url$path, operation)
|
||||
url$query <- options
|
||||
|
||||
if(encode == "json")
|
||||
{
|
||||
# manually convert to json to avoid issues with nulls
|
||||
body <- jsonlite::toJSON(body, auto_unbox=TRUE, digits=22, null="null")
|
||||
encode <- "raw"
|
||||
}
|
||||
else if(encode == "raw")
|
||||
headers$`content-type` <- "application/octet-stream"
|
||||
|
||||
headers <- add_cognitive_auth(endpoint, headers)
|
||||
verb <- match.arg(http_verb)
|
||||
res <- httr::VERB(verb, url, headers, body=body, encode=encode)
|
||||
|
||||
process_cognitive_response(res, match.arg(http_status_handler))
|
||||
}
|
||||
|
||||
|
||||
add_cognitive_auth <- function(endpoint, headers)
|
||||
{
|
||||
headers <- if(!is.null(endpoint$key))
|
||||
c(headers, `Ocp-Apim-Subscription-Key`=unname(endpoint$key))
|
||||
else if(is_azure_auth(endpoint$aad_token))
|
||||
{
|
||||
token <- endpoint$aad_token
|
||||
if(!token$validate())
|
||||
token$refresh()
|
||||
c(headers, Authorization=paste("Bearer", AzureAuth::extract_jwt(token)))
|
||||
}
|
||||
else stop("No supported authentication method found", call.=FALSE)
|
||||
|
||||
do.call(httr::add_headers, headers)
|
||||
}
|
||||
|
||||
|
||||
process_cognitive_response <- function(response, handler)
|
||||
{
|
||||
if(handler != "pass")
|
||||
{
|
||||
cont <- httr::content(response)
|
||||
handler <- get(paste0(handler, "_for_status"), getNamespace("httr"))
|
||||
handler(response, paste0("complete Cognitive Services operation. Message:\n",
|
||||
sub("\\.$", "", cognitive_error_message(cont))))
|
||||
|
||||
cont
|
||||
}
|
||||
else response
|
||||
}
|
||||
|
||||
|
||||
cognitive_error_message <- function(cont)
|
||||
{
|
||||
if(is.raw(cont))
|
||||
cont <- jsonlite::fromJSON(rawToChar(cont))
|
||||
|
||||
msg <- if(is.character(cont))
|
||||
cont
|
||||
else if(is.list(cont))
|
||||
{
|
||||
if(is.character(cont$message))
|
||||
cont$message
|
||||
else if(is.list(cont$error) && is.character(cont$error$message))
|
||||
cont$error$message
|
||||
else ""
|
||||
}
|
||||
else ""
|
||||
|
||||
paste0(strwrap(msg), collapse="\n")
|
||||
}
|
||||
|
||||
|
||||
# kind - api
|
||||
# ComputerVision - vision/v2.0
|
||||
# Face - face/v1.0
|
||||
# LUIS - luis/v2.0
|
||||
# CustomVision.Training - customvision/v3.0
|
||||
# CustomVision.Prediction - customvision/v3.0
|
||||
# ContentModerator - contentmoderator/moderate/v1.0
|
||||
# Text - text/analytics/v2.0
|
||||
get_api_path <- function(type)
|
||||
{
|
||||
switch(type,
|
||||
computervision="vision/v2.0",
|
||||
face="face/v1.0",
|
||||
luis="luis/v2.0",
|
||||
customvision=, customvision_training=, customvision_prediction="customvision/v3.0",
|
||||
contentmoderator="contentmoderator/moderate/v1.0",
|
||||
text="text/analytics/v2.0",
|
||||
stop("Unknown cognitive service", call.=FALSE)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
normalize_cognitive_type <- function(type)
|
||||
{
|
||||
tolower(gsub("\\.", "_", type))
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
variables:
|
||||
- group: GH
|
||||
- name: R_LIBS_USER
|
||||
value: '$(Agent.BuildDirectory)/R/library'
|
||||
|
||||
pool:
|
||||
vmImage: 'ubuntu-latest'
|
||||
|
||||
container: $[variables['rockerImage']]
|
||||
|
||||
steps:
|
||||
- bash: |
|
||||
export CLOUDYR_REPO=$(echo $(Build.Repository.Name) | sed "s/Azure/cloudyr/")
|
||||
git push --prune https://$(ghPat)@github.com/$CLOUDYR_REPO +refs/remotes/origin/*:refs/heads/* +refs/tags/*:refs/tags/*
|
||||
displayName: 'Copy to Cloudyr'
|
||||
condition: eq(variables['Build.SourceBranch'], 'refs/heads/master')
|
||||
|
||||
- bash: |
|
||||
echo "options(repos = '$(cranRepo)')" > ~/.Rprofile
|
||||
echo ".libPaths(c('$R_LIBS_USER', .libPaths()))" >> ~/.Rprofile
|
||||
mkdir -p $R_LIBS_USER
|
||||
displayName: 'Setup R library directory'
|
||||
|
||||
- task: CacheBeta@0
|
||||
inputs:
|
||||
key: ./DESCRIPTION | "$(rockerImage)" | "$(cranRepo)"
|
||||
path: $(R_LIBS_USER)
|
||||
displayName: 'Caching packages'
|
||||
|
||||
- bash: |
|
||||
Rscript -e "pkgs <- c('remotes', 'rcmdcheck', 'drat'); if(length(find.package(pkgs, quiet=TRUE)) != length(pkgs)) install.packages(pkgs)"
|
||||
Rscript -e "remotes::install_deps(dependencies=TRUE)"
|
||||
displayName: 'Installing package dependencies'
|
||||
|
||||
- bash: |
|
||||
Rscript -e "f <- pkgbuild::build(dest_path='$(Build.ArtifactStagingDirectory)'); rcmdcheck::rcmdcheck(f, args='--no-manual', error_on='warning', check_dir='check')"
|
||||
displayName: 'Checking package'
|
||||
|
||||
# - bash: |
|
||||
# export PKGBUILD_GZ=$(ls $(Build.ArtifactStagingDirectory)/*.gz)
|
||||
# mkdir drat
|
||||
# cd drat
|
||||
# git init
|
||||
# git config user.email "dummy@example.com"
|
||||
# git config user.name "Azure Pipelines"
|
||||
# git remote add upstream "https://$(ghPat)@github.com/cloudyr/cloudyr.github.io.git"
|
||||
# git fetch upstream
|
||||
# git checkout master
|
||||
# Rscript -e "drat::insertPackage('$PKGBUILD_GZ', repodir='./drat')"
|
||||
# git add --all
|
||||
# git commit -m "add $PKGBUILD_GZ (build $(Build.BuildId))"
|
||||
# git push
|
||||
# displayName: 'Update Cloudyr drat'
|
||||
# condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/master'))
|
||||
|
Загрузка…
Ссылка в новой задаче