From b420281fd0e6f0656495fbed82dabb1d90539aad Mon Sep 17 00:00:00 2001 From: Justintime50 <39606064+Justintime50@users.noreply.github.com> Date: Mon, 19 Aug 2024 16:49:15 -0600 Subject: [PATCH 1/3] feat: adds concurrent_insurance_buy go script --- .gitignore | 21 +-- .../golang/concurrent_insurance_buy/README.md | 11 ++ .../concurrent_insurance_buy.go | 163 ++++++++++++++++++ .../golang/concurrent_insurance_buy/go.mod | 5 + .../golang/concurrent_insurance_buy/go.sum | 56 ++++++ .../concurrent_insurance_buy/sample.csv | 8 + 6 files changed, 254 insertions(+), 10 deletions(-) create mode 100644 community/golang/concurrent_insurance_buy/README.md create mode 100644 community/golang/concurrent_insurance_buy/concurrent_insurance_buy.go create mode 100644 community/golang/concurrent_insurance_buy/go.mod create mode 100644 community/golang/concurrent_insurance_buy/go.sum create mode 100644 community/golang/concurrent_insurance_buy/sample.csv diff --git a/.gitignore b/.gitignore index 2f7be862..1d1c7c41 100644 --- a/.gitignore +++ b/.gitignore @@ -4,12 +4,11 @@ __pycache__ .idea .vscode *.egg-info -/vendor -bin -node_modules -target -venv +*.sw* +*results.csv +/.dummy /.editorconfig +/.eslintignore /.eslintrc /.flake8 /.golangci.yml @@ -20,11 +19,13 @@ venv /easycop.yml /easypost_java_style.xml /layout_rules.xml +/official/tools/build_doc_json_responses/responses/ +/official/tools/build_doc_json_responses/tests/cassettes/ /phpcs.xml /pyproject.toml /style_suppressions.xml -/.dummy -/.eslintignore -*.sw* -/official/tools/build_doc_json_responses/responses/ -/official/tools/build_doc_json_responses/tests/cassettes/ +bin +node_modules +target +vendor +venv diff --git a/community/golang/concurrent_insurance_buy/README.md b/community/golang/concurrent_insurance_buy/README.md new file mode 100644 index 00000000..87b2152c --- /dev/null +++ b/community/golang/concurrent_insurance_buy/README.md @@ -0,0 +1,11 @@ +# Concurrently Buy Insurance + +This script allows you to concurrently buy EasyPost insurance. It will work with EasyPost Shipments or standalone Insurance. Use the `sample.csv` file as a template, fill in the details, and run the script. + +## Usage + +After running the script, a CSV file will be saved with the success status of each insurance purchase attempt and the time it took. If there are errors, those messages will be included. + +```shell +EASYPOST_API_KEY=123... CSV=sample.csv go run concurrent_insurance_buy.go +``` diff --git a/community/golang/concurrent_insurance_buy/concurrent_insurance_buy.go b/community/golang/concurrent_insurance_buy/concurrent_insurance_buy.go new file mode 100644 index 00000000..70970828 --- /dev/null +++ b/community/golang/concurrent_insurance_buy/concurrent_insurance_buy.go @@ -0,0 +1,163 @@ +package main + +import ( + "encoding/csv" + "errors" + "fmt" + "io" + "math" + "os" + "strconv" + "time" + + "github.com/EasyPost/easypost-go/v4" +) + +/* +* Concurrently buy EasyPost Insurance via a CSV file +* +* Usage: EASYPOST_API_KEY=123... CSV=sample.csv go run concurrent_insurance_buy.go + */ + +func main() { + scriptStart := time.Now() + + records := getCsvRecords() + + client := easypost.New(os.Getenv("EASYPOST_API_KEY")) + numOfGoroutines := int(math.Min(float64(len(records)), 20)) + semaphore := make(chan bool, numOfGoroutines) + lineMessageList := make([][]string, 0) + lineMessageList = append(lineMessageList, []string{"Reference", "Tracking Code", "Time Elapsed", "Success", "Message"}) + + // Iterate over our set of data and create an Insurance record for each line in the CSV + for i, line := range records { + semaphore <- true + + go func(lineNumber int, currentLine []string) { + goroutineStartTime := time.Now() + + reference := currentLine[0] + tracking_code := currentLine[1] + carrier_string := currentLine[2] + amount := currentLine[3] + to_address_id := currentLine[4] + from_address_id := currentLine[5] + + success, message := createInsurance(client, reference, tracking_code, carrier_string, amount, to_address_id, from_address_id) + + elapsedTime := time.Since(goroutineStartTime) + lineMessage := []string{reference, tracking_code, elapsedTime.String(), success, message} + lineMessageList = append(lineMessageList, lineMessage) + + <-semaphore + }(i, line) + } + + // Gather up goroutines + for i := 0; i < cap(semaphore); i++ { + semaphore <- true + } + + file, err := os.Create("insurance_buy_results.csv") + handleGoErr(err) + defer file.Close() + writer := csv.NewWriter(file) + defer writer.Flush() + writer.WriteAll(lineMessageList) + + elapsedTotal := time.Since(scriptStart) + fmt.Printf("\nTotal time elapsed: %s\n", elapsedTotal) +} + +// getCsvRecords builds the set of data without including the header and validates it +func getCsvRecords() [][]string { + file, err := os.Open(os.Getenv("CSV")) + handleGoErr(err) + defer file.Close() + reader := csv.NewReader(file) + + lineNumber := 0 + records := make([][]string, 0) + for { + record, err := reader.Read() + // Ensure rows have valid data + if err != nil { + if err == io.EOF { + break + } + handleGoErr(err) + } + if len(record) != 6 { + handleGoErr(err) + } + + // Skip header + if lineNumber == 0 { + lineNumber++ + continue + } + + // Ensure `Amount` column is a valid float + _, err = strconv.ParseFloat(record[3], 64) + if err != nil { + handleGoErr(err) + } + + lineNumber++ + records = append(records, record) + } + + return records +} + +// handleGoErr prints the error to stderr and exits, should be used for Go errors and not EasyPost errors +func handleGoErr(err error) { + if err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } +} + +// createInsurance creates an Insurance based on if the Tracker has a Shipment or not +func createInsurance(client *easypost.Client, reference string, tracking_code string, carrier_string string, amount string, to_address_id string, from_address_id string) (string, string) { + // We first get the tracker to know if there is a Shipment or not so we know which Insurance endpoint to hit + tracker, err := client.GetTracker(tracking_code) + var eperr *easypost.APIError + if errors.As(err, &eperr) { + return "false", eperr.Message + } + + if tracker.ShipmentID != "" { + // shipment.Tracker is just the amount and not the object + _, err := client.InsureShipment(tracker.ShipmentID, amount) + var eperr *easypost.APIError + if errors.As(err, &eperr) { + return "false", eperr.Message + } + + return "true", "" + } else { + // If no shipment ID, it's a standalone insurance + _, err := client.CreateInsurance( + &easypost.Insurance{ + ToAddress: &easypost.Address{ + ID: to_address_id, + }, + FromAddress: &easypost.Address{ + ID: from_address_id, + }, + Reference: reference, + Carrier: carrier_string, + TrackingCode: tracking_code, + Amount: amount, + }, + ) + var eperr *easypost.APIError + if errors.As(err, &eperr) { + return "false", eperr.Message + } + + return "true", "" + } +} diff --git a/community/golang/concurrent_insurance_buy/go.mod b/community/golang/concurrent_insurance_buy/go.mod new file mode 100644 index 00000000..d65a60dc --- /dev/null +++ b/community/golang/concurrent_insurance_buy/go.mod @@ -0,0 +1,5 @@ +module github.com/EasyPost/examples/community/golang/concurrent_insurance_buy + +go 1.16 + +require github.com/EasyPost/easypost-go/v4 v4.6.0 diff --git a/community/golang/concurrent_insurance_buy/go.sum b/community/golang/concurrent_insurance_buy/go.sum new file mode 100644 index 00000000..2af204d6 --- /dev/null +++ b/community/golang/concurrent_insurance_buy/go.sum @@ -0,0 +1,56 @@ +github.com/EasyPost/easypost-go/v4 v4.6.0 h1:wxMK4wkGEG5vW/4Vdy3rwE9iqww1eQ1xS6oYWUZbhrc= +github.com/EasyPost/easypost-go/v4 v4.6.0/go.mod h1:WGoS4tmjHquhooMNmY6RirP+KWeYV/akcf/Jg9Q6fsk= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ= +github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= +github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= +github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/modocache/gover v0.0.0-20171022184752-b58185e213c5/go.mod h1:caMODM3PzxT8aQXRPkAt8xlV/e7d7w8GM5g0fa5F0D8= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4= +golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/community/golang/concurrent_insurance_buy/sample.csv b/community/golang/concurrent_insurance_buy/sample.csv new file mode 100644 index 00000000..d0bd024b --- /dev/null +++ b/community/golang/concurrent_insurance_buy/sample.csv @@ -0,0 +1,8 @@ +Reference,Tracking Code,Carrier String,Amount,To Address (optional),From Address (optional) +ref_1,EZ1000000001,USPS,100.00,, +ref_2,EZ2000000002,USPS,200.00,, +ref_3,EZ3000000003,USPS,300.00,, +ref_4,EZ4000000004,USPS,400.00,, +ref_5,EZ5000000005,USPS,500.00,, +ref_6,EZ6000000006,USPS,600.00,, +ref_7,EZ7000000007,USPS,700.00,, From b14ad430eb8aeee5ce3e412873df543d8fc98cb7 Mon Sep 17 00:00:00 2001 From: Justintime50 <39606064+Justintime50@users.noreply.github.com> Date: Tue, 20 Aug 2024 14:52:58 -0600 Subject: [PATCH 2/3] docs: better documentation and param input handling --- .gitignore | 1 + .../golang/concurrent_insurance_buy/README.md | 22 +++++++++++++++--- .../concurrent_insurance_buy.go | 23 ++++++++++++------- .../concurrent_insurance_buy/sample.csv | 2 +- 4 files changed, 36 insertions(+), 12 deletions(-) diff --git a/.gitignore b/.gitignore index 1d1c7c41..3daba8a7 100644 --- a/.gitignore +++ b/.gitignore @@ -25,6 +25,7 @@ __pycache__ /pyproject.toml /style_suppressions.xml bin +bulkins node_modules target vendor diff --git a/community/golang/concurrent_insurance_buy/README.md b/community/golang/concurrent_insurance_buy/README.md index 87b2152c..25f91806 100644 --- a/community/golang/concurrent_insurance_buy/README.md +++ b/community/golang/concurrent_insurance_buy/README.md @@ -1,11 +1,27 @@ # Concurrently Buy Insurance -This script allows you to concurrently buy EasyPost insurance. It will work with EasyPost Shipments or standalone Insurance. Use the `sample.csv` file as a template, fill in the details, and run the script. +This script allows you to concurrently buy EasyPost Insurance. It works when insuring EasyPost Shipments or when buying standalone Insurance for a package bought outside of the EasyPost ecosystem. Use the `sample.csv` file as a template, fill in the details (do not delete the header), and run the script. + +## Things to Know + +- You must follow the `sample.csv` template or the script will not work correctly. Do not delete the header row +- Only run the script once! Running the script multiple times with the same data will create duplicate insurance objects and fees +- The script will spin up 20 concurrent requests at a time + - Because requests are sent concurrently, they may complete in a different order than they were specified in the original CSV. Sorting the results CSV by Tracking Code and the original `sample.csv` will allow you to match up requests with input data for debugging purchases in the event of errors +- The status of each request will be saved to a CSV once the script is complete. Each line will include error messages if there were any, the time each request took, and the status of the request +- If there are errors reported in the results CSV, correct input data as necessary and run the script again + - NOTE: Ensure you delete successful rows from the `sample.csv` file before running the script again. Failure to do so will result in duplicate insurance objects and fees (eg: If I had 5 rows, 3 succeeded, 2 failed - I would remove the 3 rows with a success status of true so that my sample CSV contained the 2 rows that initially failed, I'd correct the data as needed, and re-run the script with only those two failed rows) +- It's recommended to run the `sample.csv` file as-is with a test API key to get a feel for how it works prior to loading real data and using a production API key ## Usage -After running the script, a CSV file will be saved with the success status of each insurance purchase attempt and the time it took. If there are errors, those messages will be included. +```shell +EASYPOST_API_KEY=123... CSV=path/to/sample.csv go run concurrent_insurance_buy.go +``` + +## Development ```shell -EASYPOST_API_KEY=123... CSV=sample.csv go run concurrent_insurance_buy.go +# To build a standalone binary of this tool (eg: call it bulkins) +go build -o bulkins ``` diff --git a/community/golang/concurrent_insurance_buy/concurrent_insurance_buy.go b/community/golang/concurrent_insurance_buy/concurrent_insurance_buy.go index 70970828..eac22f22 100644 --- a/community/golang/concurrent_insurance_buy/concurrent_insurance_buy.go +++ b/community/golang/concurrent_insurance_buy/concurrent_insurance_buy.go @@ -13,18 +13,20 @@ import ( "github.com/EasyPost/easypost-go/v4" ) -/* -* Concurrently buy EasyPost Insurance via a CSV file -* -* Usage: EASYPOST_API_KEY=123... CSV=sample.csv go run concurrent_insurance_buy.go - */ +// Concurrently buy EasyPost Insurance via a CSV file +// Usage: EASYPOST_API_KEY=123... CSV=sample.csv go run concurrent_insurance_buy.go func main() { scriptStart := time.Now() records := getCsvRecords() - client := easypost.New(os.Getenv("EASYPOST_API_KEY")) + apiKeyParam := os.Getenv("EASYPOST_API_KEY") + if apiKeyParam == "" { + handleGoErr(errors.New("EASYPOST_API_KEY param not set")) + } + + client := easypost.New(apiKeyParam) numOfGoroutines := int(math.Min(float64(len(records)), 20)) semaphore := make(chan bool, numOfGoroutines) lineMessageList := make([][]string, 0) @@ -44,6 +46,7 @@ func main() { to_address_id := currentLine[4] from_address_id := currentLine[5] + fmt.Printf("Sending request for %s...\n", tracking_code) success, message := createInsurance(client, reference, tracking_code, carrier_string, amount, to_address_id, from_address_id) elapsedTime := time.Since(goroutineStartTime) @@ -72,7 +75,12 @@ func main() { // getCsvRecords builds the set of data without including the header and validates it func getCsvRecords() [][]string { - file, err := os.Open(os.Getenv("CSV")) + csvParam := os.Getenv("CSV") + if csvParam == "" { + handleGoErr(errors.New("CSV parameter not set")) + } + + file, err := os.Open(csvParam) handleGoErr(err) defer file.Close() reader := csv.NewReader(file) @@ -129,7 +137,6 @@ func createInsurance(client *easypost.Client, reference string, tracking_code st } if tracker.ShipmentID != "" { - // shipment.Tracker is just the amount and not the object _, err := client.InsureShipment(tracker.ShipmentID, amount) var eperr *easypost.APIError if errors.As(err, &eperr) { diff --git a/community/golang/concurrent_insurance_buy/sample.csv b/community/golang/concurrent_insurance_buy/sample.csv index d0bd024b..6f7a95f3 100644 --- a/community/golang/concurrent_insurance_buy/sample.csv +++ b/community/golang/concurrent_insurance_buy/sample.csv @@ -1,4 +1,4 @@ -Reference,Tracking Code,Carrier String,Amount,To Address (optional),From Address (optional) +Reference,Tracking Code,Carrier String,Amount,To Address ID (optional),From Address ID (optional) ref_1,EZ1000000001,USPS,100.00,, ref_2,EZ2000000002,USPS,200.00,, ref_3,EZ3000000003,USPS,300.00,, From f8c69eb2e65d888e4aff7bee927fd35ab75b609c Mon Sep 17 00:00:00 2001 From: Justintime50 <39606064+Justintime50@users.noreply.github.com> Date: Tue, 20 Aug 2024 16:43:46 -0600 Subject: [PATCH 3/3] fix: clarify optional reference, cleanup error handling --- .../concurrent_insurance_buy.go | 16 +++++++--------- .../golang/concurrent_insurance_buy/sample.csv | 16 ++++++++-------- 2 files changed, 15 insertions(+), 17 deletions(-) diff --git a/community/golang/concurrent_insurance_buy/concurrent_insurance_buy.go b/community/golang/concurrent_insurance_buy/concurrent_insurance_buy.go index eac22f22..fb2addb4 100644 --- a/community/golang/concurrent_insurance_buy/concurrent_insurance_buy.go +++ b/community/golang/concurrent_insurance_buy/concurrent_insurance_buy.go @@ -30,7 +30,7 @@ func main() { numOfGoroutines := int(math.Min(float64(len(records)), 20)) semaphore := make(chan bool, numOfGoroutines) lineMessageList := make([][]string, 0) - lineMessageList = append(lineMessageList, []string{"Reference", "Tracking Code", "Time Elapsed", "Success", "Message"}) + lineMessageList = append(lineMessageList, []string{"Tracking Code", "Reference", "Time Elapsed", "Success", "Message"}) // Iterate over our set of data and create an Insurance record for each line in the CSV for i, line := range records { @@ -39,18 +39,18 @@ func main() { go func(lineNumber int, currentLine []string) { goroutineStartTime := time.Now() - reference := currentLine[0] - tracking_code := currentLine[1] + tracking_code := currentLine[0] + reference := currentLine[1] carrier_string := currentLine[2] amount := currentLine[3] to_address_id := currentLine[4] from_address_id := currentLine[5] fmt.Printf("Sending request for %s...\n", tracking_code) - success, message := createInsurance(client, reference, tracking_code, carrier_string, amount, to_address_id, from_address_id) + success, message := createInsurance(client, tracking_code, reference, carrier_string, amount, to_address_id, from_address_id) elapsedTime := time.Since(goroutineStartTime) - lineMessage := []string{reference, tracking_code, elapsedTime.String(), success, message} + lineMessage := []string{tracking_code, reference, elapsedTime.String(), success, message} lineMessageList = append(lineMessageList, lineMessage) <-semaphore @@ -108,9 +108,7 @@ func getCsvRecords() [][]string { // Ensure `Amount` column is a valid float _, err = strconv.ParseFloat(record[3], 64) - if err != nil { - handleGoErr(err) - } + handleGoErr(err) lineNumber++ records = append(records, record) @@ -128,7 +126,7 @@ func handleGoErr(err error) { } // createInsurance creates an Insurance based on if the Tracker has a Shipment or not -func createInsurance(client *easypost.Client, reference string, tracking_code string, carrier_string string, amount string, to_address_id string, from_address_id string) (string, string) { +func createInsurance(client *easypost.Client, tracking_code string, reference string, carrier_string string, amount string, to_address_id string, from_address_id string) (string, string) { // We first get the tracker to know if there is a Shipment or not so we know which Insurance endpoint to hit tracker, err := client.GetTracker(tracking_code) var eperr *easypost.APIError diff --git a/community/golang/concurrent_insurance_buy/sample.csv b/community/golang/concurrent_insurance_buy/sample.csv index 6f7a95f3..db63e28c 100644 --- a/community/golang/concurrent_insurance_buy/sample.csv +++ b/community/golang/concurrent_insurance_buy/sample.csv @@ -1,8 +1,8 @@ -Reference,Tracking Code,Carrier String,Amount,To Address ID (optional),From Address ID (optional) -ref_1,EZ1000000001,USPS,100.00,, -ref_2,EZ2000000002,USPS,200.00,, -ref_3,EZ3000000003,USPS,300.00,, -ref_4,EZ4000000004,USPS,400.00,, -ref_5,EZ5000000005,USPS,500.00,, -ref_6,EZ6000000006,USPS,600.00,, -ref_7,EZ7000000007,USPS,700.00,, +Tracking Code,Reference (optional),Carrier String,Amount,To Address ID (optional),From Address ID (optional) +EZ1000000001,ref_1,USPS,100.00,, +EZ2000000002,ref_2,USPS,200.00,, +EZ3000000003,,USPS,300.00,, +EZ4000000004,,USPS,400.00,, +EZ5000000005,,USPS,500.00,, +EZ6000000006,,USPS,600.00,, +EZ7000000007,,USPS,700.00,,