cloudyr / aws.lambda Goto Github PK
View Code? Open in Web Editor NEWAWS Lambda Client Package
Home Page: https://cran.r-project.org/package=aws.lambda
License: GNU General Public License v3.0
AWS Lambda Client Package
Home Page: https://cran.r-project.org/package=aws.lambda
License: GNU General Public License v3.0
These are OK .
> list_functions()
list()
> hello <- system.file("templates", "helloworld.js", package = "aws.lambda")
> requireNamespace("aws.iam")
> id <- aws.iam::get_caller_identity()[["Account"]]
> role <- paste0("arn:aws:iam::", id, ":role/lambda_basic_execution")
> id
[1] "429492368957"
> role
[1] "arn:aws:iam::429492368957:role/lambda_basic_execution"
Until ...
> **func <- create_function(name = "helloworld", func = hello,
+ handler = "helloworld.handler", role = role)**
adding: helloworld.js (deflated 8%)
$url
[1] "https://lambda.us-east-1.amazonaws.com/2015-03-31/functions"
$status_code
[1] 400
$headers
$`content-type`
[1] "application/json"
$date
[1] "Thu, 24 Aug 2017 21:19:52 GMT"
$`x-amzn-errortype`
[1] "InvalidParameterValueException"
$`x-amzn-requestid`
[1] "f8291245-8911-11e7-a3f2-dbe51e4b1bcf"
$`content-length`
[1] "90"
$connection
[1] "keep-alive"
attr(,"class")
[1] "insensitive" "list"
$all_headers
$all_headers[[1]]
$all_headers[[1]]$status
[1] 400
$all_headers[[1]]$version
[1] "HTTP/1.1"
$all_headers[[1]]$headers
$`content-type`
[1] "application/json"
$date
[1] "Thu, 24 Aug 2017 21:19:52 GMT"
$`x-amzn-errortype`
[1] "InvalidParameterValueException"
$`x-amzn-requestid`
[1] "f8291245-8911-11e7-a3f2-dbe51e4b1bcf"
$`content-length`
[1] "90"
$connection
[1] "keep-alive"
attr(,"class")
[1] "insensitive" "list"
$cookies
[1] domain flag path secure expiration name value
<0 rows> (or 0-length row.names)
$content
$content$Type
[1] "User"
$content$message
[1] "The role defined for the function cannot be assumed by Lambda."
$date
[1] "2017-08-24 21:19:52 GMT"
$times
redirect namelookup connect pretransfer starttransfer total
0.000000 0.000076 0.000079 0.000341 0.106718 0.106756
$request
<request>
POST https://lambda.us-east-1.amazonaws.com/2015-03-31/functions
Output: write_memory
Options:
* useragent: libcurl/7.54.0 r-curl/2.8.1 httr/1.3.1
* post: TRUE
* postfieldsize: 471
* postfields: as.raw(c(0x7b, 0x22, 0x43, 0x6f, 0x64, 0x65, 0x22, 0x3a, 0x7b, 0x22, 0x5a, 0x69, 0x70, 0x46, 0x69, 0x6c, 0x65, 0x22, 0x3a, 0x22, 0x55, 0x45, 0x73, 0x44, 0x42, 0x42, 0x51, 0x41, 0x41, 0x67, 0x41, 0x49, 0x41, 0x44, 0x4e, 0x79, 0x47, 0x45, 0x76, 0x4d, 0x4e, 0x47, 0x54, 0x49, 0x55, 0x77, 0x41, 0x41, 0x41, 0x46, 0x6f, 0x41, 0x41, 0x41, 0x41, 0x4e, 0x41, 0x41, 0x41, 0x41, 0x61, 0x47, 0x56, 0x73, 0x62, 0x47, 0x39, 0x33, 0x62, 0x33, 0x4a, 0x73, 0x5a, 0x43, 0x35, 0x71, 0x63, 0x30, 0x75, 0x74, 0x4b, 0x4d,
0x67, 0x76, 0x4b, 0x69, 0x6e, 0x57, 0x79, 0x30, 0x6a, 0x4d, 0x53, 0x38, 0x6c, 0x4a, 0x4c, 0x56, 0x4b, 0x77, 0x56, 0x55, 0x67, 0x72, 0x7a, 0x55, 0x73, 0x75, 0x79, 0x63, 0x7a, 0x50, 0x55, 0x39, 0x42, 0x49, 0x4c, 0x55, 0x76, 0x4e, 0x4b, 0x39, 0x46, 0x52, 0x53, 0x4d, 0x37, 0x50, 0x4b, 0x30, 0x6d, 0x74, 0x4b, 0x4e, 0x46, 0x55, 0x71, 0x4f, 0x62, 0x6c, 0x55, 0x67, 0x41, 0x43, 0x4b, 0x46, 0x2b, 0x76, 0x75, 0x44, 0x51, 0x35, 0x4f, 0x54, 0x55, 0x31, 0x52, 0x55, 0x50, 0x64, 0x49, 0x7a, 0x55, 0x6e, 0x4a, 0x31,
0x39, 0x48, 0x6f, 0x54, 0x79, 0x2f, 0x4b, 0x43, 0x64, 0x46, 0x55, 0x56, 0x33, 0x54, 0x6d, 0x70, 0x65, 0x72, 0x46, 0x6f, 0x67, 0x42, 0x55, 0x45, 0x73, 0x42, 0x41, 0x68, 0x34, 0x44, 0x46, 0x41, 0x41, 0x43, 0x41, 0x41, 0x67, 0x41, 0x4d, 0x33, 0x49, 0x59, 0x53, 0x38, 0x77, 0x30, 0x5a, 0x4d, 0x68, 0x54, 0x41, 0x41, 0x41, 0x41, 0x57, 0x67, 0x41, 0x41, 0x41, 0x41, 0x30, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x51, 0x41, 0x41, 0x41, 0x4b, 0x53, 0x42, 0x41, 0x41, 0x41, 0x41, 0x41, 0x47,
0x68, 0x6c, 0x62, 0x47, 0x78, 0x76, 0x64, 0x32, 0x39, 0x79, 0x62, 0x47, 0x51, 0x75, 0x61, 0x6e, 0x4e, 0x51, 0x53, 0x77, 0x55, 0x47, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x45, 0x41, 0x41, 0x51, 0x41, 0x37, 0x41, 0x41, 0x41, 0x41, 0x66, 0x67, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x22, 0x7d, 0x2c, 0x22, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x3a, 0x22, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x22, 0x2c, 0x22, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69,
0x70, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x3a, 0x22, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x22, 0x2c, 0x22, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x22, 0x3a, 0x22, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x2e, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x22, 0x2c, 0x22, 0x52, 0x6f, 0x6c, 0x65, 0x22, 0x3a, 0x22, 0x61, 0x72, 0x6e, 0x3a, 0x61, 0x77, 0x73, 0x3a, 0x69, 0x61, 0x6d, 0x3a, 0x3a, 0x34, 0x32, 0x39, 0x34, 0x39, 0x32, 0x33, 0x36, 0x38, 0x39, 0x35, 0x37,
0x3a, 0x72, 0x6f, 0x6c, 0x65, 0x2f, 0x6c, 0x61, 0x6d, 0x62, 0x64, 0x61, 0x5f, 0x62, 0x61, 0x73, 0x69, 0x63, 0x5f, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x2c, 0x22, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x22, 0x3a, 0x22, 0x6e, 0x6f, 0x64, 0x65, 0x6a, 0x73, 0x36, 0x2e, 0x31, 0x30, 0x22, 0x7d))
Headers:
* Accept: application/json, text/xml, application/xml, */*
* Content-Type:
* host: lambda.us-east-1.amazonaws.com
* x-amz-date: 20170824T211737Z
* x-amz-content-sha256: 138800f21abd7f296fc7e6829855336aa479a28567299ad710580d0aa6a5121c
* Authorization: AWS4-HMAC-SHA256 Credential=AKIAJY37HJUB2BLHZ3ZA/20170824/us-east-1/lambda/aws4_request, SignedHeaders=host;x-amz-date, Signature=23e1de83c9d4690f5f9bdd600f7033c26f6da672634c276d3ce0b568f0294d0f
$handle
<curl handle> (empty)
attr(,"class")
[1] "aws_error"
attr(,"headers")
$`content-type`
[1] "application/json"
$date
[1] "Thu, 24 Aug 2017 21:19:52 GMT"
$`x-amzn-errortype`
[1] "InvalidParameterValueException"
$`x-amzn-requestid`
[1] "f8291245-8911-11e7-a3f2-dbe51e4b1bcf"
$`content-length`
[1] "90"
$connection
[1] "keep-alive"
attr(,"class")
[1] "insensitive" "list"
attr(,"request_canonical")
[1] "POST\n/2015-03-31/functions\n\nhost:lambda.us-east-1.amazonaws.com\nx-amz-date:20170824T211737Z\n\nhost;x-amz-date\n138800f21abd7f296fc7e6829855336aa479a28567299ad710580d0aa6a5121c"
attr(,"request_string_to_sign")
[1] "AWS4-HMAC-SHA256\n20170824T211737Z\n20170824/us-east-1/lambda/aws4_request\n24203a375dcd7b119ef2520e2c48e5dfb74c10d5d92fed6d60afd205a2370125"
attr(,"request_signature")
[1] "AWS4-HMAC-SHA256 Credential=AKIAJY37HJUB2BLHZ3ZA/20170824/us-east-1/lambda/aws4_request, SignedHeaders=host;x-amz-date, Signature=23e1de83c9d4690f5f9bdd600f7033c26f6da672634c276d3ce0b568f0294d0f"
Error in lambdaHTTP(verb = "POST", action = act, body = b, ...) :
Bad Request (HTTP 400).
The session_token
in lambdaHTTP
is not being read from locate_credentials
or environment like it should, and default arg value is NULL
which is causing temporary credentials to not work.
More details at cloudyr/aws.signature#19 (comment)
It does work in s3HTTP
, since it is using session_token = Sys.getenv("AWS_SESSION_TOKEN")
in the argument list.
utils::zip
is fragile (might not point to the right place). Since zip is (potentially) very important during create_function
(etc), investigate using r-lib/zip instead to avoid pitfalls.
This requires that tests be in place before doing so (because it's a significant refactor), but it will greaaaaatly simplify the code.
As an R user, I'd like to create lambda functions that use R, so that I can use AWS Lambda effectively.
This version will only allow base (or maybe the recommended packages), using the published layers (hopefully from bakdata/aws-lambda-r-runtime#58).
Ideally it will detect that their function wants other packages and throw an error, at least.
Hi,
Can you point me to some repository which does the exact opposite of this package.... A lambda function that my nodejs can call which can in turn run certain R scripts or R packages and get the results back to nodejs
Regards
SD
This package is not being actively maintained. If you're interested in contributing or taking over, please express your interest here.
The UpdateAlias endpoint accept arguments that we don't deal with:
Adding RevisionId should be trivial, but adding RoutingConfig will evidently be more complicated. Consider doing them one at a time.
Lambda function to take snapshot or backup of RDS database and store in S3
My IAM policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"rds:CreateDBSnapshot"
],
"Resource": "arn:aws:rds:us-west-1:**************:db:*"
},
{
"Sid": "VisualEditor1",
"Effect": "Allow",
"Action": [
"s3:PutObjects",
"s3:ListBuckets"
],
"Resource": "arn:aws:s3:::maurice-rdsbackup-bucket"
}
]
}
and the lambda function:
import boto3
import datetime
#connecting to the RDS database
def lambda_handler(event, context):
print("Connecting to RDS")
client = boto3.client('rds')
#creating the database snapshot
print("RDS snapshot backups started at %s...\n" % datetime.datetime.now())
client.create_db_snapshot(
DBInstanceIdentifier='maurice-testdatabase-instance',
DBSnapshotIdentifier='mauricesnapshot2',
Tags=[
{
'Key': 'name',
'Value': 'my-test-database'
},
]
)
print("saving snapshot to S3 bucket")
s3 = boto3.resource("s3")
s3.Object("maurice-rdsbackup-bucket", "DBSnapshotIdentifier").upload_file("DBSnapshotIdentifier")
Please specify whether your issue is about:
If you are reporting (1) a bug or (2) a question about code, please supply:
traceback()
run immediately after the error occurssessionInfo()
Put your code here:
## load package
library("aws.lambda")
## code goes here
## session info for your system
sessionInfo()
invoke_function
has an argument LogType. When it's set to "Tail", the response includes a "X-Amz-Log-Result" element with that requested log.
This will require a change in the structure of how things are called, but should be dealt with. Right now it only returns the payload even when you request the log.
Please specify whether your issue is about:
## load package
library("aws.lambda")
Sys.setenv("AWS_DEFAULT_REGION" = "us-west-2") # Needed for me to do manually for some reason
Sys.setenv(TZ = "GMT")
handler <- function(...) {
lambdaFunction = paste(
Sys.getenv("ENVIRONMENT"), Sys.getenv("LAMBDA_FN_NAME"),
sep = "-"
)
payload = list(user_id = "1", event = "events.invite.email")
result <- invoke_function(
name = lambdaFunction,
payload = toJSON(payload, auto_unbox = TRUE),
type = "RequestResponse",
log = "None"
)
return(fromJSON(toJSON(list(code = 0))))
}
Session Info:
R version 3.6.1 (2019-07-05)
Platform: x86_64-pc-linux-gnu (64-bit)
Running under: Amazon Linux AMI 2018.03
Matrix products: default
BLAS: /opt/R/lib/libRblas.so
LAPACK: /opt/R/lib/libRlapack.so
locale:
[1] LC_CTYPE=en_US.UTF-8 LC_NUMERIC=C
[3] LC_TIME=en_US.UTF-8 LC_COLLATE=en_US.UTF-8
[5] LC_MONETARY=en_US.UTF-8 LC_MESSAGES=en_US.UTF-8
[7] LC_PAPER=en_US.UTF-8 LC_NAME=C
[9] LC_ADDRESS=C LC_TELEPHONE=C
[11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] lubridate_1.7.4 feather_0.3.5 aws.lambda_0.1.6 aws.s3_0.3.12
[5] data.table_1.12.2 jsonlite_1.6 httr_1.4.1 logging_0.10-108
loaded via a namespace (and not attached):
[1] Rcpp_1.0.2 magrittr_1.5 xml2_1.2.2
[4] hms_0.5.1 aws.signature_0.5.2 R6_2.4.0
[7] rlang_0.4.0 stringr_1.4.0 tools_3.6.1
[10] digest_0.6.20 tibble_2.1.3 crayon_1.3.4
[13] base64enc_0.1-3 vctrs_0.2.0 curl_4.1
[16] zeallot_0.1.0 stringi_1.4.3 compiler_3.6.1
[19] pillar_1.4.2 backports_1.1.4 pkgconfig_2.0.2
Note I am using a custom runtime in aws lambda to execute this code. Communication to aws.s3 works great and I know the correct roles are being assumed.
This works fine when running on my local machine which makes me think there is something wrong with how this package performs specifically when running on the aws lambda runtime environment
I get an error trying to run funclist <- sapply(list_functions(), get_function_name)
Error in lambdaHTTP(verb = "GET", action = act, query = query, ...) :
Forbidden (HTTP 403).
I downloaded and isntalled the Amazon Command Line Interface, configured it and requested a session token:
aws sts get-session-token --duration-seconds 129600
This returns:
{
"Credentials": {
"SecretAccessKey": "mysecretkey",
"SessionToken": "mytoken",
"Expiration": "2019-12-22T10:06:25Z",
"AccessKeyId": "mykey"
}
}
Now I place these into R
and try and run the command:
Sys.setenv("AWS_ACCESS_KEY_ID" = "myKey",
"AWS_SECRET_ACCESS_KEY" = "mysecretkey",
"AWS_DEFAULT_REGION" = "us-east-1",
"AWS_SESSION_TOKEN" = "mytoken")
library("aws.lambda")
# get list of all current functions
funclist <- sapply(list_functions(), get_function_name)
$url
[1] "https://lambda.us-east-1.amazonaws.com/2015-03-31/functions"
$status_code
[1] 403
$headers
$date
[1] "Fri, 20 Dec 2019 22:07:56 GMT"
$`content-type`
[1] "application/json"
$`content-length`
[1] "68"
$`x-amzn-requestid`
[1] "d8ce0ace-8bf6-4389-b463-3017e4a6b3d2"
$`x-amzn-errortype`
[1] "UnrecognizedClientException"
attr(,"class")
[1] "insensitive" "list"
$all_headers
$all_headers[[1]]
$all_headers[[1]]$status
[1] 403
$all_headers[[1]]$version
[1] "HTTP/2"
$all_headers[[1]]$headers
$date
[1] "Fri, 20 Dec 2019 22:07:56 GMT"
$`content-type`
[1] "application/json"
$`content-length`
[1] "68"
$`x-amzn-requestid`
[1] "d8ce0ace-8bf6-4389-b463-3017e4a6b3d2"
$`x-amzn-errortype`
[1] "UnrecognizedClientException"
attr(,"class")
[1] "insensitive" "list"
$cookies
[1] domain flag path secure expiration name value
<0 rows> (or 0-length row.names)
$content
$content$message
[1] "The security token included in the request is invalid."
$date
[1] "2019-12-20 22:07:56 GMT"
$times
redirect namelookup connect pretransfer starttransfer total
0.000000 0.000092 0.000096 0.000169 0.012340 0.012375
$request
<request>
GET https://lambda.us-east-1.amazonaws.com/2015-03-31/functions
Output: write_memory
Options:
* useragent: libcurl/7.61.1 r-curl/4.2 httr/1.4.1
* httpget: TRUE
Headers:
* Accept: application/json, text/xml, application/xml, */*
* host: lambda.us-east-1.amazonaws.com
* x-amz-date: 20191220T220756Z
* x-amz-content-sha256: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
* Authorization: AWS4-HMAC-SHA256 Credential=ASIAWHR6YUDAWYUQTFYX/20191220/us-east-1/lambda/aws4_request, SignedHeaders=host;x-amz-date;x-amz-security-token, Signature=e1355c335bbbe82492be4fa9711595c454665a0d545e10ec2428a1cd8b18b7bd
$handle
<curl handle> (empty)
attr(,"class")
[1] "aws_error"
attr(,"headers")
$date
[1] "Fri, 20 Dec 2019 22:07:56 GMT"
$`content-type`
[1] "application/json"
$`content-length`
[1] "68"
$`x-amzn-requestid`
[1] "d8ce0ace-8bf6-4389-b463-3017e4a6b3d2"
$`x-amzn-errortype`
[1] "UnrecognizedClientException"
attr(,"class")
[1] "insensitive" "list"
attr(,"request_canonical")
[1] "GET\n/2015-03-31/functions\n\nhost:lambda.us-east-1.amazonaws.com\nx-amz-date:20191220T220756Z\nx-amz-security-token:FwoGZXIvYXdzEJj//////////wEaDDCkOajvq4oNbLUpRiKCAadxzJRVwFRKqZxB+HZuA//fk/OSDxaaSBlFvGn5RZQY5WMez94HUoGRydehHBbYr8QR0sgUB8v+0H5CccCwY+NQGkWkaLqo4WQ0Wp1Ei5rk5ZmYOXGl8Ysxe9xucCgT9WQeSyypVX9565whmUdBNGkIxDye3kq7NDZnQkk4qN+fGNEo4Yv17wUyKMbJqluF1gPmI281BKAHkJ6zp9eZCalw7Xip7dNYsyUs1Z3X3TXyTJ8=\n\nhost;x-amz-date;x-amz-security-token\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
attr(,"request_string_to_sign")
[1] "AWS4-HMAC-SHA256\n20191220T220756Z\n20191220/us-east-1/lambda/aws4_request\nd1dfb6de14af6af22e080b350be20299e370f92315adb3f786b8a443b7179655"
attr(,"request_signature")
[1] "AWS4-HMAC-SHA256 Credential=ASIAWHR6YUDAWYUQTFYX/20191220/us-east-1/lambda/aws4_request, SignedHeaders=host;x-amz-date;x-amz-security-token, Signature=e1355c335bbbe82492be4fa9711595c454665a0d545e10ec2428a1cd8b18b7bd"
It looks like The security token is invalid. How do I get a valid token?
I'm setting up tests to use mocks, so we don't actually hit the API. This feels important for this package, since a lot of the calls can cost actual money (although we'd have to call a lot of them quite a lot for it to add up, but still).
However, I'd also like to check that the API itself hasn't changed.
Set up... something... to actually check the API. I'm thinking probably a special github action? We'll have to look into what makes sense. Just run it periodically, independent of changes to the package. Come to think of it, maybe this should happen via a lambda...
I am trying to run the examples in the README and getting the following error:
Error in lambdaHTTP(verb = "POST", action = act, body = b, ...) :
Bad Request (HTTP 400).
After running:
library("aws.lambda")
plus <- system.file("templates", "plus.js", package = "aws.lambda")
# get IAM role for Lambda execution
requireNamespace("aws.iam")
id <- aws.iam::get_caller_identity()[["Account"]]
role <- paste0("arn:aws:iam::", id, ":role/lambda_basic_execution")
if (!"plus" %in% funclist) {
func <- create_function(name = "plus", func = plus,
handler = "plus.handler", role = role)
} else {
func <- get_function("plus")
}
I placed my keys in the .Renviron
file which I verified with Sys.getenv
. One clue may be that the text preceeding error reads:
adding: plus.js (deflated 17%)
$url
[1] "https://lambda.us-east-1.amazonaws.com/2015-03-31/functions"
$status_code
[1] 400
$headers
$`content-type`
[1] "application/json"
$date
[1] "Wed, 14 Jun 2017 15:42:51 GMT"
$`x-amzn-errortype`
[1] "InvalidParameterValueException"
$`x-amzn-requestid`
**redacted**
$`content-length`
[1] "90"
$connection
[1] "keep-alive"
attr(,"class")
[1] "insensitive" "list"
$all_headers
$all_headers[[1]]
$all_headers[[1]]$status
[1] 400
$all_headers[[1]]$version
[1] "HTTP/1.1"
$all_headers[[1]]$headers
$`content-type`
[1] "application/json"
$date
[1] "Wed, 14 Jun 2017 15:42:51 GMT"
$`x-amzn-errortype`
[1] "InvalidParameterValueException"
$`x-amzn-requestid`
**redacted**
$`content-length`
[1] "90"
$connection
[1] "keep-alive"
attr(,"class")
[1] "insensitive" "list"
$cookies
[1] domain flag path secure expiration name value
<0 rows> (or 0-length row.names)
$content
$content$Type
[1] "User"
$content$message
[1] "The role defined for the function cannot be assumed by Lambda."
...
Also funclist <- sapply(list_functions(), get_function_name)
is empty even though I have functions added to my account. Do you have any ideas on a fix?
Thanks!
The api accepts ClientContext, to pass to the context object of the function. We don't accept that parameter, likely because it has to be base64-encoded and may otherwise be... weird. I'm pretty sure httr can handle it and make it ~easy, though.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.