Anda Lacacima

Anda Lacacima

1598923425

How to Use Google’s reCAPTCHA with Golang

Introduction

It’s always a good practice to prevent malicious software from engaging in abusive activities on your web application. The most popular tool to achieve that is Google’s reCAPTCHA. At the current state, it supports v2 and v3. In this article, we will focus on v3, as it requires less interaction with users and enables analytics.

Prerequisites

  • Go environment (instructions)
  • An already registered website on Google’s reCAPTCHA console
  • A new directory, e.x recaptcha-endpoints, inside your GOPATH where all of our code will live

Getting started

After registering your website, a new API key and secret pair will be generated. To make reCAPTCHA work, it requires changes on both frontend and backend services of your web application. We will only demonstrate on how to use it on the backend service, as Google’s documentation is pretty straight forward regarding the challenge placement on the frontend.

Implementation

We will implement a simple server with a single endpoint to handle the login of users, given an email and password, protected with Google reCAPTCHA.

The way to verify a reCAPTCHA token is to make a POST request on [https://www.google.com/recaptcha/api/siteverify](https://www.google.com/recaptcha/api/siteverify) followed by the secret and the response token as URL parameters. Then evaluate the response to find out if the challenge was successful. Source code is about to follow.

package main

import (
	"encoding/json"
	"errors"
	"log"
	"net/http"
	"os"
	"time"
)

const siteVerifyURL = "https://www.google.com/recaptcha/api/siteverify"

type LoginRequest struct {
	Email             string `json:"email"`
	Password          string `json:"password"`
	RecaptchaResponse string `json:"g-recaptcha-response"`
}

type SiteVerifyResponse struct {
	Success     bool      `json:"success"`
	Score       float64   `json:"score"`
	Action      string    `json:"action"`
	ChallengeTS time.Time `json:"challenge_ts"`
	Hostname    string    `json:"hostname"`
	ErrorCodes  []string  `json:"error-codes"`
}

func main() {
	// Get recaptcha secret from env variable.
	secret := os.Getenv("RECAPTCHA_SECRET")
	
	// Define endpoint to handle login.
	http.HandleFunc("/login", Login(secret))

	log.Println("Server starting at port 8080...")

	if err := http.ListenAndServe(":8080", nil); err != nil {
		log.Fatal(err)
	}
}

func Login(secret string) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		// Decode request body.
		var body LoginRequest
		if err := json.NewDecoder(r.Body).Decode(&body); err != nil {
			http.Error(w, "Bad Request", http.StatusBadRequest)
			return
		}

		// Check and verify the recaptcha response token.
		if err := CheckRecaptcha(secret, body.RecaptchaResponse); err != nil {
			http.Error(w, "Unauthorized", http.StatusUnauthorized)
			return
		}

		// Check login credentials.
    		// ....

		w.WriteHeader(http.StatusOK)
	}
}

func CheckRecaptcha(secret, response string) error {
	req, err := http.NewRequest(http.MethodPost, siteVerifyURL, nil)
	if err != nil {
		return err
	}

	// Add necessary request parameters.
	q := req.URL.Query()
	q.Add("secret", secret)
	q.Add("response", response)
	req.URL.RawQuery = q.Encode()

	// Make request
	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		return err
	}
	defer resp.Body.Close()

	// Decode response.
	var body SiteVerifyResponse
	if err = json.NewDecoder(resp.Body).Decode(&body); err != nil {
		return err
	}

	// Check recaptcha verification success.
	if !body.Success {
		return errors.New("unsuccessful recaptcha verify request")
	}

	// Check response score.
	if body.Score < 0.5 {
		return errors.New("lower received score than expected")
	}

	// Check response action.
	if body.Action != "login" {
		return errors.New("mismatched recaptcha action")
	}

	return nil
}

Let’s dive into it step by step

  • A const variable to hold Google’s reCAPTCHA request link
  • LoginRequest struct that contains the user email and password to validate credentials, plus an extra field for reCAPTCHA token.
  • SiteVerifyResponse struct to decode the response from Google reCAPTCHA API.
  • The main function to define the login endpoint handler, passing the reCAPTCHA secret as argument.
  • The Login function that operates as handler where at first decodes the request body. Then checks and verifies the reCAPTCHA token calling the CheckRecaptcha function and finally validate the provided credentials.
  • The CheckRecaptcha function that does all the work regarding reCAPTCHA verification. Accepts the secret and response token as arguments, constructs the proper POST request and makes it. Decode the response into the SiteVerifyResponse struct and checks if the verification was successful, compares the received score against a provided minimum (0.5) and also checks the action name (login)

You can set custom action names for any operation on your website, by setting the _data-action_ attribute. In this way you can have access to a detailed break down of data in admin console and can apply different business logic for each action (e.g. 2FA authentication for login with low scores).

Middleware

The above solution does the work, although it doesn’t scale while your web server is growing. It requires code duplication, generic code inside handlers and an extra field inside each struct, which used to decode requests body.

To avoid all that, we can implement a middleware to handle all the reCAPTCHA verification and apply to any endpoint is required. The previous code now becomes.

package main

import (
	"bytes"
	"encoding/json"
	"errors"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"time"
)

const siteVerifyURL = "https://www.google.com/recaptcha/api/siteverify"

type LoginRequest struct {
	Email    string `json:"email"`
	Password string `json:"password"`
}

type SiteVerifyResponse struct {
	Success     bool      `json:"success"`
	Score       float64   `json:"score"`
	Action      string    `json:"action"`
	ChallengeTS time.Time `json:"challenge_ts"`
	Hostname    string    `json:"hostname"`
	ErrorCodes  []string  `json:"error-codes"`
}

type SiteVerifyRequest struct {
	RecaptchaResponse string `json:"g-recaptcha-response"`
}

func main() {
	// Get recaptcha secret from env variable.
	secret := os.Getenv("RECAPTCHA_SECRET")

	// Define endpoint to handle login.
	http.Handle("/login", RecaptchaMiddleware(secret)(Login()))

	log.Println("Server starting at port 8080...")

	if err := http.ListenAndServe(":8080", nil); err != nil {
		log.Fatal(err)
	}
}

func Login() http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		// Decode request body.
		var body LoginRequest
		if err := json.NewDecoder(r.Body).Decode(&body); err != nil {
			http.Error(w, "Bad Request", http.StatusBadRequest)
			return
		}

		// Check login credentials.
		// ...

		w.WriteHeader(http.StatusOK)
	}
}

func CheckRecaptcha(secret, response string) error {
	req, err := http.NewRequest(http.MethodPost, siteVerifyURL, nil)
	if err != nil {
		return err
	}

	// Add necessary request parameters.
	q := req.URL.Query()
	q.Add("secret", secret)
	q.Add("response", response)
	req.URL.RawQuery = q.Encode()

	// Make request
	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		return err
	}
	defer resp.Body.Close()

	// Decode response.
	var body SiteVerifyResponse
	if err = json.NewDecoder(resp.Body).Decode(&body); err != nil {
		return err
	}

	// Check recaptcha verification success.
	if !body.Success {
		return errors.New("unsuccessful recaptcha verify request")
	}

	// Check response score.
	if body.Score < 0.5 {
		return errors.New("lower received score than expected")
	}

	// Check response action.
	if body.Action != "login" {
		return errors.New("mismatched recaptcha action")
	}

	return nil
}

func RecaptchaMiddleware(secret string) func(http.Handler) http.Handler {
	return func(next http.Handler) http.Handler {
		return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
			// Get the reCaptcha response token from default request body field 'g-recaptcha-response'.
			bodyBytes, err := ioutil.ReadAll(r.Body)
			if err != nil {
				http.Error(w, "Unauthorized", http.StatusUnauthorized)
				return
			}

			// Unmarshal body into struct.
			var body SiteVerifyRequest
			if err := json.Unmarshal(bodyBytes, &body); err != nil {
				http.Error(w, "Unauthorized", http.StatusUnauthorized)
				return
			}

			// Restore request body to read more than once.
			r.Body = ioutil.NopCloser(bytes.NewBuffer(bodyBytes))

			// Check and verify the recaptcha response token.
			if err := CheckRecaptcha(secret, body.RecaptchaResponse); err != nil {
				http.Error(w, "unauthorized", http.StatusUnauthorized)
				return
			}

			next.ServeHTTP(w, r)
		})
	}
}

We will mention the changes against the first version of our code.

  1. The RecaptchaResponse field has been removed from the LoginRequest struct as is no longer need it.
  2. A new struct SiteVerifyRequest has been introduced and will be used in middleware function to retrieve the reCAPTCHA token from request body.
  3. The Login handler function is now wrapped by RecaptchaMiddleware.
  4. Any source code regarding reCAPTCHA has been removed from handler.
  5. A new function RecaptchaMiddleware that accepts a secret has been created, that operates as middleware. Contains all the code regarding Google’s reCAPTCHA verification. Reads and decodes the request body into SiteVerityRequest struct, then checks and verifies the reCAPTCHA at the same way as before.
  6. There is a tricky part at line 125 that needs attention. In Go, http request body is an io.ReadCloser type that can be read only once. For that reason we have to restore it, to be able to use it again in any following handler.

That’s all the differences regarding the first version of our solution. In this way the code it’s a lot cleaner, handlers only contain the business logic that have been created for and the Google’s reCAPTCHA verification happens to a single place, inside the middleware.

Source code

I have implemented an open source package that handles Google’s reCAPTCHA verification that supports both v2 and v3. An out of the box middleware is also included. You can find it on GitHub.

#google-recaptcha #go #google #recaptcha #golang

What is GEEK

Buddha Community

How to Use Google’s reCAPTCHA with Golang
Anda Lacacima

Anda Lacacima

1598923425

How to Use Google’s reCAPTCHA with Golang

Introduction

It’s always a good practice to prevent malicious software from engaging in abusive activities on your web application. The most popular tool to achieve that is Google’s reCAPTCHA. At the current state, it supports v2 and v3. In this article, we will focus on v3, as it requires less interaction with users and enables analytics.

Prerequisites

  • Go environment (instructions)
  • An already registered website on Google’s reCAPTCHA console
  • A new directory, e.x recaptcha-endpoints, inside your GOPATH where all of our code will live

Getting started

After registering your website, a new API key and secret pair will be generated. To make reCAPTCHA work, it requires changes on both frontend and backend services of your web application. We will only demonstrate on how to use it on the backend service, as Google’s documentation is pretty straight forward regarding the challenge placement on the frontend.

Implementation

We will implement a simple server with a single endpoint to handle the login of users, given an email and password, protected with Google reCAPTCHA.

The way to verify a reCAPTCHA token is to make a POST request on [https://www.google.com/recaptcha/api/siteverify](https://www.google.com/recaptcha/api/siteverify) followed by the secret and the response token as URL parameters. Then evaluate the response to find out if the challenge was successful. Source code is about to follow.

package main

import (
	"encoding/json"
	"errors"
	"log"
	"net/http"
	"os"
	"time"
)

const siteVerifyURL = "https://www.google.com/recaptcha/api/siteverify"

type LoginRequest struct {
	Email             string `json:"email"`
	Password          string `json:"password"`
	RecaptchaResponse string `json:"g-recaptcha-response"`
}

type SiteVerifyResponse struct {
	Success     bool      `json:"success"`
	Score       float64   `json:"score"`
	Action      string    `json:"action"`
	ChallengeTS time.Time `json:"challenge_ts"`
	Hostname    string    `json:"hostname"`
	ErrorCodes  []string  `json:"error-codes"`
}

func main() {
	// Get recaptcha secret from env variable.
	secret := os.Getenv("RECAPTCHA_SECRET")
	
	// Define endpoint to handle login.
	http.HandleFunc("/login", Login(secret))

	log.Println("Server starting at port 8080...")

	if err := http.ListenAndServe(":8080", nil); err != nil {
		log.Fatal(err)
	}
}

func Login(secret string) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		// Decode request body.
		var body LoginRequest
		if err := json.NewDecoder(r.Body).Decode(&body); err != nil {
			http.Error(w, "Bad Request", http.StatusBadRequest)
			return
		}

		// Check and verify the recaptcha response token.
		if err := CheckRecaptcha(secret, body.RecaptchaResponse); err != nil {
			http.Error(w, "Unauthorized", http.StatusUnauthorized)
			return
		}

		// Check login credentials.
    		// ....

		w.WriteHeader(http.StatusOK)
	}
}

func CheckRecaptcha(secret, response string) error {
	req, err := http.NewRequest(http.MethodPost, siteVerifyURL, nil)
	if err != nil {
		return err
	}

	// Add necessary request parameters.
	q := req.URL.Query()
	q.Add("secret", secret)
	q.Add("response", response)
	req.URL.RawQuery = q.Encode()

	// Make request
	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		return err
	}
	defer resp.Body.Close()

	// Decode response.
	var body SiteVerifyResponse
	if err = json.NewDecoder(resp.Body).Decode(&body); err != nil {
		return err
	}

	// Check recaptcha verification success.
	if !body.Success {
		return errors.New("unsuccessful recaptcha verify request")
	}

	// Check response score.
	if body.Score < 0.5 {
		return errors.New("lower received score than expected")
	}

	// Check response action.
	if body.Action != "login" {
		return errors.New("mismatched recaptcha action")
	}

	return nil
}

Let’s dive into it step by step

  • A const variable to hold Google’s reCAPTCHA request link
  • LoginRequest struct that contains the user email and password to validate credentials, plus an extra field for reCAPTCHA token.
  • SiteVerifyResponse struct to decode the response from Google reCAPTCHA API.
  • The main function to define the login endpoint handler, passing the reCAPTCHA secret as argument.
  • The Login function that operates as handler where at first decodes the request body. Then checks and verifies the reCAPTCHA token calling the CheckRecaptcha function and finally validate the provided credentials.
  • The CheckRecaptcha function that does all the work regarding reCAPTCHA verification. Accepts the secret and response token as arguments, constructs the proper POST request and makes it. Decode the response into the SiteVerifyResponse struct and checks if the verification was successful, compares the received score against a provided minimum (0.5) and also checks the action name (login)

You can set custom action names for any operation on your website, by setting the _data-action_ attribute. In this way you can have access to a detailed break down of data in admin console and can apply different business logic for each action (e.g. 2FA authentication for login with low scores).

Middleware

The above solution does the work, although it doesn’t scale while your web server is growing. It requires code duplication, generic code inside handlers and an extra field inside each struct, which used to decode requests body.

To avoid all that, we can implement a middleware to handle all the reCAPTCHA verification and apply to any endpoint is required. The previous code now becomes.

package main

import (
	"bytes"
	"encoding/json"
	"errors"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"time"
)

const siteVerifyURL = "https://www.google.com/recaptcha/api/siteverify"

type LoginRequest struct {
	Email    string `json:"email"`
	Password string `json:"password"`
}

type SiteVerifyResponse struct {
	Success     bool      `json:"success"`
	Score       float64   `json:"score"`
	Action      string    `json:"action"`
	ChallengeTS time.Time `json:"challenge_ts"`
	Hostname    string    `json:"hostname"`
	ErrorCodes  []string  `json:"error-codes"`
}

type SiteVerifyRequest struct {
	RecaptchaResponse string `json:"g-recaptcha-response"`
}

func main() {
	// Get recaptcha secret from env variable.
	secret := os.Getenv("RECAPTCHA_SECRET")

	// Define endpoint to handle login.
	http.Handle("/login", RecaptchaMiddleware(secret)(Login()))

	log.Println("Server starting at port 8080...")

	if err := http.ListenAndServe(":8080", nil); err != nil {
		log.Fatal(err)
	}
}

func Login() http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		// Decode request body.
		var body LoginRequest
		if err := json.NewDecoder(r.Body).Decode(&body); err != nil {
			http.Error(w, "Bad Request", http.StatusBadRequest)
			return
		}

		// Check login credentials.
		// ...

		w.WriteHeader(http.StatusOK)
	}
}

func CheckRecaptcha(secret, response string) error {
	req, err := http.NewRequest(http.MethodPost, siteVerifyURL, nil)
	if err != nil {
		return err
	}

	// Add necessary request parameters.
	q := req.URL.Query()
	q.Add("secret", secret)
	q.Add("response", response)
	req.URL.RawQuery = q.Encode()

	// Make request
	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		return err
	}
	defer resp.Body.Close()

	// Decode response.
	var body SiteVerifyResponse
	if err = json.NewDecoder(resp.Body).Decode(&body); err != nil {
		return err
	}

	// Check recaptcha verification success.
	if !body.Success {
		return errors.New("unsuccessful recaptcha verify request")
	}

	// Check response score.
	if body.Score < 0.5 {
		return errors.New("lower received score than expected")
	}

	// Check response action.
	if body.Action != "login" {
		return errors.New("mismatched recaptcha action")
	}

	return nil
}

func RecaptchaMiddleware(secret string) func(http.Handler) http.Handler {
	return func(next http.Handler) http.Handler {
		return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
			// Get the reCaptcha response token from default request body field 'g-recaptcha-response'.
			bodyBytes, err := ioutil.ReadAll(r.Body)
			if err != nil {
				http.Error(w, "Unauthorized", http.StatusUnauthorized)
				return
			}

			// Unmarshal body into struct.
			var body SiteVerifyRequest
			if err := json.Unmarshal(bodyBytes, &body); err != nil {
				http.Error(w, "Unauthorized", http.StatusUnauthorized)
				return
			}

			// Restore request body to read more than once.
			r.Body = ioutil.NopCloser(bytes.NewBuffer(bodyBytes))

			// Check and verify the recaptcha response token.
			if err := CheckRecaptcha(secret, body.RecaptchaResponse); err != nil {
				http.Error(w, "unauthorized", http.StatusUnauthorized)
				return
			}

			next.ServeHTTP(w, r)
		})
	}
}

We will mention the changes against the first version of our code.

  1. The RecaptchaResponse field has been removed from the LoginRequest struct as is no longer need it.
  2. A new struct SiteVerifyRequest has been introduced and will be used in middleware function to retrieve the reCAPTCHA token from request body.
  3. The Login handler function is now wrapped by RecaptchaMiddleware.
  4. Any source code regarding reCAPTCHA has been removed from handler.
  5. A new function RecaptchaMiddleware that accepts a secret has been created, that operates as middleware. Contains all the code regarding Google’s reCAPTCHA verification. Reads and decodes the request body into SiteVerityRequest struct, then checks and verifies the reCAPTCHA at the same way as before.
  6. There is a tricky part at line 125 that needs attention. In Go, http request body is an io.ReadCloser type that can be read only once. For that reason we have to restore it, to be able to use it again in any following handler.

That’s all the differences regarding the first version of our solution. In this way the code it’s a lot cleaner, handlers only contain the business logic that have been created for and the Google’s reCAPTCHA verification happens to a single place, inside the middleware.

Source code

I have implemented an open source package that handles Google’s reCAPTCHA verification that supports both v2 and v3. An out of the box middleware is also included. You can find it on GitHub.

#google-recaptcha #go #google #recaptcha #golang

Mike  Kozey

Mike Kozey

1656151740

Test_cov_console: Flutter Console Coverage Test

Flutter Console Coverage Test

This small dart tools is used to generate Flutter Coverage Test report to console

How to install

Add a line like this to your package's pubspec.yaml (and run an implicit flutter pub get):

dev_dependencies:
  test_cov_console: ^0.2.2

How to run

run the following command to make sure all flutter library is up-to-date

flutter pub get
Running "flutter pub get" in coverage...                            0.5s

run the following command to generate lcov.info on coverage directory

flutter test --coverage
00:02 +1: All tests passed!

run the tool to generate report from lcov.info

flutter pub run test_cov_console
---------------------------------------------|---------|---------|---------|-------------------|
File                                         |% Branch | % Funcs | % Lines | Uncovered Line #s |
---------------------------------------------|---------|---------|---------|-------------------|
lib/src/                                     |         |         |         |                   |
 print_cov.dart                              |  100.00 |  100.00 |   88.37 |...,149,205,206,207|
 print_cov_constants.dart                    |    0.00 |    0.00 |    0.00 |    no unit testing|
lib/                                         |         |         |         |                   |
 test_cov_console.dart                       |    0.00 |    0.00 |    0.00 |    no unit testing|
---------------------------------------------|---------|---------|---------|-------------------|
 All files with unit testing                 |  100.00 |  100.00 |   88.37 |                   |
---------------------------------------------|---------|---------|---------|-------------------|

Optional parameter

If not given a FILE, "coverage/lcov.info" will be used.
-f, --file=<FILE>                      The target lcov.info file to be reported
-e, --exclude=<STRING1,STRING2,...>    A list of contains string for files without unit testing
                                       to be excluded from report
-l, --line                             It will print Lines & Uncovered Lines only
                                       Branch & Functions coverage percentage will not be printed
-i, --ignore                           It will not print any file without unit testing
-m, --multi                            Report from multiple lcov.info files
-c, --csv                              Output to CSV file
-o, --output=<CSV-FILE>                Full path of output CSV file
                                       If not given, "coverage/test_cov_console.csv" will be used
-t, --total                            Print only the total coverage
                                       Note: it will ignore all other option (if any), except -m
-p, --pass=<MINIMUM>                   Print only the whether total coverage is passed MINIMUM value or not
                                       If the value >= MINIMUM, it will print PASSED, otherwise FAILED
                                       Note: it will ignore all other option (if any), except -m
-h, --help                             Show this help

example run the tool with parameters

flutter pub run test_cov_console --file=coverage/lcov.info --exclude=_constants,_mock
---------------------------------------------|---------|---------|---------|-------------------|
File                                         |% Branch | % Funcs | % Lines | Uncovered Line #s |
---------------------------------------------|---------|---------|---------|-------------------|
lib/src/                                     |         |         |         |                   |
 print_cov.dart                              |  100.00 |  100.00 |   88.37 |...,149,205,206,207|
lib/                                         |         |         |         |                   |
 test_cov_console.dart                       |    0.00 |    0.00 |    0.00 |    no unit testing|
---------------------------------------------|---------|---------|---------|-------------------|
 All files with unit testing                 |  100.00 |  100.00 |   88.37 |                   |
---------------------------------------------|---------|---------|---------|-------------------|

report for multiple lcov.info files (-m, --multi)

It support to run for multiple lcov.info files with the followings directory structures:
1. No root module
<root>/<module_a>
<root>/<module_a>/coverage/lcov.info
<root>/<module_a>/lib/src
<root>/<module_b>
<root>/<module_b>/coverage/lcov.info
<root>/<module_b>/lib/src
...
2. With root module
<root>/coverage/lcov.info
<root>/lib/src
<root>/<module_a>
<root>/<module_a>/coverage/lcov.info
<root>/<module_a>/lib/src
<root>/<module_b>
<root>/<module_b>/coverage/lcov.info
<root>/<module_b>/lib/src
...
You must run test_cov_console on <root> dir, and the report would be grouped by module, here is
the sample output for directory structure 'with root module':
flutter pub run test_cov_console --file=coverage/lcov.info --exclude=_constants,_mock --multi
---------------------------------------------|---------|---------|---------|-------------------|
File                                         |% Branch | % Funcs | % Lines | Uncovered Line #s |
---------------------------------------------|---------|---------|---------|-------------------|
lib/src/                                     |         |         |         |                   |
 print_cov.dart                              |  100.00 |  100.00 |   88.37 |...,149,205,206,207|
lib/                                         |         |         |         |                   |
 test_cov_console.dart                       |    0.00 |    0.00 |    0.00 |    no unit testing|
---------------------------------------------|---------|---------|---------|-------------------|
 All files with unit testing                 |  100.00 |  100.00 |   88.37 |                   |
---------------------------------------------|---------|---------|---------|-------------------|
---------------------------------------------|---------|---------|---------|-------------------|
File - module_a -                            |% Branch | % Funcs | % Lines | Uncovered Line #s |
---------------------------------------------|---------|---------|---------|-------------------|
lib/src/                                     |         |         |         |                   |
 print_cov.dart                              |  100.00 |  100.00 |   88.37 |...,149,205,206,207|
lib/                                         |         |         |         |                   |
 test_cov_console.dart                       |    0.00 |    0.00 |    0.00 |    no unit testing|
---------------------------------------------|---------|---------|---------|-------------------|
 All files with unit testing                 |  100.00 |  100.00 |   88.37 |                   |
---------------------------------------------|---------|---------|---------|-------------------|
---------------------------------------------|---------|---------|---------|-------------------|
File - module_b -                            |% Branch | % Funcs | % Lines | Uncovered Line #s |
---------------------------------------------|---------|---------|---------|-------------------|
lib/src/                                     |         |         |         |                   |
 print_cov.dart                              |  100.00 |  100.00 |   88.37 |...,149,205,206,207|
lib/                                         |         |         |         |                   |
 test_cov_console.dart                       |    0.00 |    0.00 |    0.00 |    no unit testing|
---------------------------------------------|---------|---------|---------|-------------------|
 All files with unit testing                 |  100.00 |  100.00 |   88.37 |                   |
---------------------------------------------|---------|---------|---------|-------------------|

Output to CSV file (-c, --csv, -o, --output)

flutter pub run test_cov_console -c --output=coverage/test_coverage.csv

#### sample CSV output file:
File,% Branch,% Funcs,% Lines,Uncovered Line #s
lib/,,,,
test_cov_console.dart,0.00,0.00,0.00,no unit testing
lib/src/,,,,
parser.dart,100.00,100.00,97.22,"97"
parser_constants.dart,100.00,100.00,100.00,""
print_cov.dart,100.00,100.00,82.91,"29,49,51,52,171,174,177,180,183,184,185,186,187,188,279,324,325,387,388,389,390,391,392,393,394,395,398"
print_cov_constants.dart,0.00,0.00,0.00,no unit testing
All files with unit testing,100.00,100.00,86.07,""

Installing

Use this package as an executable

Install it

You can install the package from the command line:

dart pub global activate test_cov_console

Use it

The package has the following executables:

$ test_cov_console

Use this package as a library

Depend on it

Run this command:

With Dart:

 $ dart pub add test_cov_console

With Flutter:

 $ flutter pub add test_cov_console

This will add a line like this to your package's pubspec.yaml (and run an implicit dart pub get):

dependencies:
  test_cov_console: ^0.2.2

Alternatively, your editor might support dart pub get or flutter pub get. Check the docs for your editor to learn more.

Import it

Now in your Dart code, you can use:

import 'package:test_cov_console/test_cov_console.dart';

example/lib/main.dart

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        // This is the theme of your application.
        //
        // Try running your application with "flutter run". You'll see the
        // application has a blue toolbar. Then, without quitting the app, try
        // changing the primarySwatch below to Colors.green and then invoke
        // "hot reload" (press "r" in the console where you ran "flutter run",
        // or simply save your changes to "hot reload" in a Flutter IDE).
        // Notice that the counter didn't reset back to zero; the application
        // is not restarted.
        primarySwatch: Colors.blue,
        // This makes the visual density adapt to the platform that you run
        // the app on. For desktop platforms, the controls will be smaller and
        // closer together (more dense) than on mobile platforms.
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key? key, required this.title}) : super(key: key);

  // This widget is the home page of your application. It is stateful, meaning
  // that it has a State object (defined below) that contains fields that affect
  // how it looks.

  // This class is the configuration for the state. It holds the values (in this
  // case the title) provided by the parent (in this case the App widget) and
  // used by the build method of the State. Fields in a Widget subclass are
  // always marked "final".

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      // This call to setState tells the Flutter framework that something has
      // changed in this State, which causes it to rerun the build method below
      // so that the display can reflect the updated values. If we changed
      // _counter without calling setState(), then the build method would not be
      // called again, and so nothing would appear to happen.
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    // This method is rerun every time setState is called, for instance as done
    // by the _incrementCounter method above.
    //
    // The Flutter framework has been optimized to make rerunning build methods
    // fast, so that you can just rebuild anything that needs updating rather
    // than having to individually change instances of widgets.
    return Scaffold(
      appBar: AppBar(
        // Here we take the value from the MyHomePage object that was created by
        // the App.build method, and use it to set our appbar title.
        title: Text(widget.title),
      ),
      body: Center(
        // Center is a layout widget. It takes a single child and positions it
        // in the middle of the parent.
        child: Column(
          // Column is also a layout widget. It takes a list of children and
          // arranges them vertically. By default, it sizes itself to fit its
          // children horizontally, and tries to be as tall as its parent.
          //
          // Invoke "debug painting" (press "p" in the console, choose the
          // "Toggle Debug Paint" action from the Flutter Inspector in Android
          // Studio, or the "Toggle Debug Paint" command in Visual Studio Code)
          // to see the wireframe for each widget.
          //
          // Column has various properties to control how it sizes itself and
          // how it positions its children. Here we use mainAxisAlignment to
          // center the children vertically; the main axis here is the vertical
          // axis because Columns are vertical (the cross axis would be
          // horizontal).
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headline4,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }
}

Author: DigitalKatalis
Source Code: https://github.com/DigitalKatalis/test_cov_console 
License: BSD-3-Clause license

#flutter #dart #test 

Google's TPU's being primed for the Quantum Jump

The liquid-cooled Tensor Processing Units, built to slot into server racks, can deliver up to 100 petaflops of compute.

The liquid-cooled Tensor Processing Units, built to slot into server racks, can deliver up to 100 petaflops of compute.

As the world is gearing towards more automation and AI, the need for quantum computing has also grown exponentially. Quantum computing lies at the intersection of quantum physics and high-end computer technology, and in more than one way, hold the key to our AI-driven future.

Quantum computing requires state-of-the-art tools to perform high-end computing. This is where TPUs come in handy. TPUs or Tensor Processing Units are custom-built ASICs (Application Specific Integrated Circuits) to execute machine learning tasks efficiently. TPUs are specific hardware developed by Google for neural network machine learning, specially customised to Google’s Machine Learning software, Tensorflow.

The liquid-cooled Tensor Processing units, built to slot into server racks, can deliver up to 100 petaflops of compute. It powers Google products like Google Search, Gmail, Google Photos and Google Cloud AI APIs.

#opinions #alphabet #asics #floq #google #google alphabet #google quantum computing #google tensorflow #google tensorflow quantum #google tpu #google tpus #machine learning #quantum computer #quantum computing #quantum computing programming #quantum leap #sandbox #secret development #tensorflow #tpu #tpus

Art  Lind

Art Lind

1602990000

Get Google Trends using Python

In this post, we will show how we can use Python to get data from Google Trends. Let’s have a look at the top trending searches for today in the US (14th of March, 2020). As we can see, the top search is about Coronavirus tips with more than 2M searches, and at the 7th position is Rick Pitino with around 100K searches.

Image for post

Python package for getting the Google Trends

We will use the pytrends package which is an unofficial API for Google Trends which allows a simple interface for automating downloading of reports from Google Trends. The main feature is to allow the script to login to Google on your behalf to enable a higher rate limit. At this point, I want to mention that I couldn’t use this package and I created a new anaconda environment installing the pandas 0.25 version.

You can install the pytrends package with pip:

pip install pytrends

#google-trends #how-to-use-google-trend #google #google-api #python

Why Use WordPress? What Can You Do With WordPress?

Can you use WordPress for anything other than blogging? To your surprise, yes. WordPress is more than just a blogging tool, and it has helped thousands of websites and web applications to thrive. The use of WordPress powers around 40% of online projects, and today in our blog, we would visit some amazing uses of WordPress other than blogging.
What Is The Use Of WordPress?

WordPress is the most popular website platform in the world. It is the first choice of businesses that want to set a feature-rich and dynamic Content Management System. So, if you ask what WordPress is used for, the answer is – everything. It is a super-flexible, feature-rich and secure platform that offers everything to build unique websites and applications. Let’s start knowing them:

1. Multiple Websites Under A Single Installation
WordPress Multisite allows you to develop multiple sites from a single WordPress installation. You can download WordPress and start building websites you want to launch under a single server. Literally speaking, you can handle hundreds of sites from one single dashboard, which now needs applause.
It is a highly efficient platform that allows you to easily run several websites under the same login credentials. One of the best things about WordPress is the themes it has to offer. You can simply download them and plugin for various sites and save space on sites without losing their speed.

2. WordPress Social Network
WordPress can be used for high-end projects such as Social Media Network. If you don’t have the money and patience to hire a coder and invest months in building a feature-rich social media site, go for WordPress. It is one of the most amazing uses of WordPress. Its stunning CMS is unbeatable. And you can build sites as good as Facebook or Reddit etc. It can just make the process a lot easier.
To set up a social media network, you would have to download a WordPress Plugin called BuddyPress. It would allow you to connect a community page with ease and would provide all the necessary features of a community or social media. It has direct messaging, activity stream, user groups, extended profiles, and so much more. You just have to download and configure it.
If BuddyPress doesn’t meet all your needs, don’t give up on your dreams. You can try out WP Symposium or PeepSo. There are also several themes you can use to build a social network.

3. Create A Forum For Your Brand’s Community
Communities are very important for your business. They help you stay in constant connection with your users and consumers. And allow you to turn them into a loyal customer base. Meanwhile, there are many good technologies that can be used for building a community page – the good old WordPress is still the best.
It is the best community development technology. If you want to build your online community, you need to consider all the amazing features you get with WordPress. Plugins such as BB Press is an open-source, template-driven PHP/ MySQL forum software. It is very simple and doesn’t hamper the experience of the website.
Other tools such as wpFoRo and Asgaros Forum are equally good for creating a community blog. They are lightweight tools that are easy to manage and integrate with your WordPress site easily. However, there is only one tiny problem; you need to have some technical knowledge to build a WordPress Community blog page.

4. Shortcodes
Since we gave you a problem in the previous section, we would also give you a perfect solution for it. You might not know to code, but you have shortcodes. Shortcodes help you execute functions without having to code. It is an easy way to build an amazing website, add new features, customize plugins easily. They are short lines of code, and rather than memorizing multiple lines; you can have zero technical knowledge and start building a feature-rich website or application.
There are also plugins like Shortcoder, Shortcodes Ultimate, and the Basics available on WordPress that can be used, and you would not even have to remember the shortcodes.

5. Build Online Stores
If you still think about why to use WordPress, use it to build an online store. You can start selling your goods online and start selling. It is an affordable technology that helps you build a feature-rich eCommerce store with WordPress.
WooCommerce is an extension of WordPress and is one of the most used eCommerce solutions. WooCommerce holds a 28% share of the global market and is one of the best ways to set up an online store. It allows you to build user-friendly and professional online stores and has thousands of free and paid extensions. Moreover as an open-source platform, and you don’t have to pay for the license.
Apart from WooCommerce, there are Easy Digital Downloads, iThemes Exchange, Shopify eCommerce plugin, and so much more available.

6. Security Features
WordPress takes security very seriously. It offers tons of external solutions that help you in safeguarding your WordPress site. While there is no way to ensure 100% security, it provides regular updates with security patches and provides several plugins to help with backups, two-factor authorization, and more.
By choosing hosting providers like WP Engine, you can improve the security of the website. It helps in threat detection, manage patching and updates, and internal security audits for the customers, and so much more.

Read More

#use of wordpress #use wordpress for business website #use wordpress for website #what is use of wordpress #why use wordpress #why use wordpress to build a website