<commit_before>package api

import "fmt"
import "errors"
import "strings"
import "io/ioutil"
import "net/url"
import "net/http"
import "encoding/json"

type Client interface {
	GetAuthToken(string, string) (string, error)
	GetHosts(string) ([]Host, error)
	CreateHost(string) (Host, error)
}

type Host struct {
	ID   string
	Name string
	URL  string
}

type HTTPClient struct {
	BaseURL string
}

type AuthResponse struct {
	Token string
}

func (api HTTPClient) GetAuthToken(username string, password string) (string, error) {
	resp, err := http.PostForm(api.BaseURL+"/signin",
		url.Values{"username": {username}, "password": {password}})

	if err != nil {
		return "", err
	}
	defer resp.Body.Close()

	var authResponse AuthResponse
	if err := DecodeResponse(resp, &authResponse); err != nil {
		return "", err
	}

	return authResponse.Token, nil
}

func (api HTTPClient) GetHosts(token string) ([]Host, error) {
	client := &http.Client{}
	req, err := http.NewRequest("GET", api.BaseURL+"/hosts", nil)
	if err != nil {
		return []Host{}, err
	}
	req.Header.Set("Authorization", "Token "+token)
	resp, err := client.Do(req)
	if err != nil {
		return []Host{}, err
	}
	var hosts []Host
	if err := DecodeResponse(resp, &hosts); err != nil {
		return []Host{}, err
	}
	return hosts, nil
}

func (api HTTPClient) CreateHost(token string, name string) (Host, error) {
	client := &http.Client{}
	v := url.Values{}
	v.Set("name", name)
	req, err := http.NewRequest("POST", api.BaseURL+"/hosts", strings.NewReader(v.Encode()))
	if err != nil {
		return Host{}, err
	}
	req.Header.Set("Authorization", "Token "+token)
	resp, err := client.Do(req)
	if err != nil {
		return Host{}, err
	}
	var host Host
	if err := DecodeResponse(resp, &host); err != nil {
		return Host{}, err
	}
	return host, nil
}

func DecodeResponse(resp *http.Response, v interface{}) error {
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return err
	}

	if resp.StatusCode < 200 || resp.StatusCode >= 400 {
		return errors.New(fmt.Sprintf("erroneous API response: %s", body))
	}

	if err := json.Unmarshal(body, &v); err != nil {<commit_msg>Refactor out some common logic<commit_after>package api

import "fmt"
import "errors"
import "strings"
import "io/ioutil"
import "net/url"
import "net/http"
import "encoding/json"

type Client interface {
	GetAuthToken(string, string) (string, error)
	GetHosts(string) ([]Host, error)
	CreateHost(string) (Host, error)
}

type Host struct {
	ID   string
	Name string
	URL  string
}

type HTTPClient struct {
	BaseURL string
}

type AuthResponse struct {
	Token string
}

func (api HTTPClient) GetAuthToken(username string, password string) (string, error) {
	resp, err := http.PostForm(api.BaseURL+"/signin",
		url.Values{"username": {username}, "password": {password}})

	if err != nil {
		return "", err
	}
	defer resp.Body.Close()

	var authResponse AuthResponse
	if err := DecodeResponse(resp, &authResponse); err != nil {
		return "", err
	}

	return authResponse.Token, nil
}

func (api HTTPClient) GetHosts(token string) ([]Host, error) {
	var hosts []Host

	req, err := http.NewRequest("GET", api.BaseURL+"/hosts", nil)
	if err != nil {
		return []Host{}, err
	}
	if err := DoRequest(req, token, &hosts); err != nil {
		return []Host{}, err
	}

	return hosts, nil
}

func (api HTTPClient) CreateHost(token string, name string) (Host, error) {
	var host Host

	v := url.Values{}
	v.Set("name", name)
	req, err := http.NewRequest("POST", api.BaseURL+"/hosts", strings.NewReader(v.Encode()))
	if err != nil {
		return Host{}, err
	}
	if err := DoRequest(req, token, &host); err != nil {
		return Host{}, err
	}

	return host, nil
}

func DoRequest(req *http.Request, token string, v interface{}) error {
	client := &http.Client{}
	req.Header.Set("Authorization", "Token "+token)
	resp, err := client.Do(req)
	if err != nil {
		return err
	}
	if err := DecodeResponse(resp, &v); err != nil {
		return err
	}
	return nil
}

func DecodeResponse(resp *http.Response, v interface{}) error {
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return err
	}

	if resp.StatusCode < 200 || resp.StatusCode >= 400 {
		return errors.New(fmt.Sprintf("erroneous API response: %s", body))
	}

	if err := json.Unmarshal(body, &v); err != nil {
{'fraction_non_alphanumeric': 0.15603003284842798, 'fraction_numerical': 0.0028155795401220087, 'mean_word_length': 4.217870257037943, 'pattern_counts': {'":': 4, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5338659', 'n_tokens_mistral': 1514, 'n_tokens_neox': 1464, 'n_words': 441}