├── fred_go_toolkit.go ├── .travis.yml ├── LICENSE.md ├── fred_toolkit_v1_test.go ├── sources_toolkit_v1.go ├── README.md ├── tag_toolkit_v1_test.go ├── tag_toolkit_v1.go ├── sources_toolkit_v1_test.go ├── constants.go ├── unused_structs.go ├── categories_toolkit_v1.go ├── categories_toolkit_v1_test.go ├── params.go ├── releases_toolkit_v1.go ├── releases_toolkit_v1_test.go ├── series_toolkit_v1.go ├── fred_toolkit_v1.go └── series_toolkit_v1_test.go /fred_go_toolkit.go: -------------------------------------------------------------------------------- 1 | /* 2 | Package fred_go_toolkit is a GoLang toolkit for retrieving the Federal Reserve Economic Data. FRED contains frequently updated US macro and regional economic time series at annual, quarterly, monthly, weekly, and daily frequencies. FRED aggregates economic data from a variety of sources - most of which are US government agencies. The economic time series in FRED contains observation or measurement periods associated with data values. For instance, the US unemployment rate for the month of January, 1990 was 5.4 percent and for the month of January, 2000 was 4.0 percent. 3 | */ 4 | package fred_go_toolkit 5 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | go: 3 | - master 4 | env: 5 | matrix: 6 | secure: LK/8UxB21vbGOk5sPLEZOHWiyYNnEk5/FymVfDYnDARxGXReIY1ZNuzgSB2ot92uFJI2YvxDjxGLxB8MMlqMbsj41zJrxX+1bsiCdNuHu9BMygENM/lify2S8nSZCMdWSgQleiWHtFLSYKQnPN1jVvXZCuxqs+rYHso84GYmPzHiwwC4rc2prcb4jJsSTrt2P+EEPoHT9JBhIAkUp5vnBUAmijuuNbP+THg9SLLhjTTXq8E7TkQT2I1uBWUBO400UeV5VvHrOAOVshXDOwkE9ogoyfsZjb8ZuLSLLwoJ65E1npFMkxJSKBy7WUAO2vpHhTlqCASv5dwXIUMVB7A0bL7AeTlihwBuCcCmfYnA1Dljaw+9ZYxYa6lFIuIT8MaRGAh6m/4mYHFq5yOLQH5AvJX5eXBc3uPBvfqbvtCxRUUZXfGrS/adWFpuplZCPcw8RdLznmQZckk1DzudXHihS4JmPGRKjC8Tt+5nRnIWLVow5H1/zcRXIcDHfJB3xlJIIFLD5Tx9zkW10rkMZbi1x07a9g9yiDzJFUPmg9fm/IzVELvbHQa3sjyva0SMz38be7+v2WfMUQcJvmOZnFNUPy5NiSJAVKx+gAEooJfDQ/bg6ntGFfZm266uNQRYzckJciJIhSVeV0oPl+Pz16k3Mo7fl7xvyRoakMmLVZODu/I= 7 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) <2016> 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /fred_toolkit_v1_test.go: -------------------------------------------------------------------------------- 1 | package fred_go_toolkit 2 | 3 | import ( 4 | "os" 5 | "testing" 6 | 7 | . "github.com/smartystreets/goconvey/convey" 8 | ) 9 | 10 | var ( 11 | apiKey = "" 12 | xmlFredClient = &FredClient{} 13 | jsonFredClient = &FredClient{} 14 | ) 15 | 16 | func TestMain(m *testing.M) { 17 | 18 | apiKey = os.Getenv("FRED_API_KEY") 19 | 20 | fredConfig := FredConfig{ 21 | APIKey: apiKey, 22 | FileType: FileTypeXML, 23 | LogFile: "", 24 | } 25 | 26 | var err error 27 | 28 | xmlFredClient, err = CreateFredClient(fredConfig) 29 | 30 | if err != nil { 31 | panic(err.Error()) 32 | } 33 | 34 | fredConfig.FileType = FileTypeJSON 35 | 36 | jsonFredClient, err = CreateFredClient(fredConfig) 37 | if err != nil { 38 | panic(err.Error()) 39 | } 40 | 41 | ret := m.Run() 42 | os.Exit(ret) 43 | } 44 | 45 | func TestUpdateAPIKEY(t *testing.T) { 46 | 47 | key := "" 48 | 49 | Convey("", t, func() { 50 | err := xmlFredClient.UpdateAPIKEY(key) 51 | 52 | So(err, ShouldNotBeNil) 53 | }) 54 | 55 | key = "23235234215423452345324" 56 | 57 | Convey("", t, func() { 58 | err := jsonFredClient.UpdateAPIKEY(key) 59 | 60 | So(err, ShouldNotBeNil) 61 | }) 62 | 63 | } 64 | -------------------------------------------------------------------------------- /sources_toolkit_v1.go: -------------------------------------------------------------------------------- 1 | package fred_go_toolkit 2 | 3 | // Source is a single instance of a FRED Source. 4 | type Source struct { 5 | ID int `json:"id" xml:"id,attr"` 6 | Start string `json:"realtime_start" xml:"realtime_start,attr"` 7 | End string `json:"realtime_end" xml:"realtime_end,attr"` 8 | Name string `json:"name" xml:"name,attr"` 9 | Link string `json:"link" xml:"link,attr"` 10 | } 11 | 12 | // GetSources will get all sources of economic data. 13 | // 14 | // Schema for the request and response objects and source for the documentation can be found at the following link: https://research.stlouisfed.org/docs/api/fred/sources.html 15 | func (f *FredClient) GetSources(params map[string]interface{}) (*FredType, error) { 16 | 17 | fc, err := f.operate(params, sourcesParam) 18 | 19 | if err != nil { 20 | f.logError(sourcesParam, err) 21 | return nil, err 22 | } 23 | 24 | return fc, nil 25 | 26 | } 27 | 28 | // GetSource will get a source of economic data. 29 | // 30 | // Schema for the request and response objects and source for the documentation can be found at the following link: https://research.stlouisfed.org/docs/api/fred/source.html 31 | func (f *FredClient) GetSource(params map[string]interface{}) (*FredType, error) { 32 | 33 | fc, err := f.operate(params, sourceParam) 34 | 35 | if err != nil { 36 | f.logError(sourceParam, err) 37 | return nil, err 38 | } 39 | 40 | return fc, nil 41 | 42 | } 43 | 44 | // GetSourceReleases will get the releases for a source. 45 | // 46 | // Schema for the request and response objects and source for the documentation can be found at the following link: https://research.stlouisfed.org/docs/api/fred/source_releases.html 47 | func (f *FredClient) GetSourceReleases(params map[string]interface{}) (*FredType, error) { 48 | 49 | fc, err := f.operate(params, sourceReleasesParam) 50 | 51 | if err != nil { 52 | f.logError(sourceReleasesParam, err) 53 | return nil, err 54 | } 55 | 56 | return fc, nil 57 | 58 | } 59 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # fred_go_toolkit 2 | FRED GoLang Toolkit for Federal Reserve Economic Data 3 | 4 | [![Build Status](https://travis-ci.org/nswekosk/fred_go_toolkit.png?branch=master)](https://travis-ci.org/nswekosk/fred_go_toolkit) 5 | 6 | [![GoDoc](https://godoc.org/github.com/nswekosk/fred_go_toolkit?status.svg)](https://godoc.org/github.com/nswekosk/fred_go_toolkit) 7 | 8 | This is a GoLang toolkit for working with the Federal Reserve Economic Data. FRED contains frequently updated US macro and regional economic time series at annual, quarterly, monthly, weekly, and daily frequencies. FRED aggregates economic data from a variety of sources - most of which are US government agencies. The economic time series in FRED contains observation or measurement periods associated with data values. For instance, the US unemployment rate for the month of January, 1990 was 5.4 percent and for the month of January, 2000 was 4.0 percent. 9 | 10 | ## Installation 11 | 12 | Setup Go environment. 13 | Run 'go get github.com/nswekosk/fred_go_toolkit' 14 | 15 | ## Get a FRED API key 16 | 17 | Sign up for a Fred API key: [http://api.stlouisfed.org/api_key.html](http://api.stlouisfed.org/api_key.html) 18 | 19 | ## Usage Example 20 | 21 | fredConfig := FredConfig{ 22 | APIKey: 'api-key', 23 | FileType: FileTypeJSON, 24 | LogFile: "log.log", 25 | } 26 | 27 | client := CreateFredClient(fredConfig) 28 | 29 | File types and log files are optional. You can use local constants 'FileTypeJSON' ('json') 30 | or 'FileTypeXML' ('xml'). If no file type is specified, the default type is XML. 31 | 32 | params := make(map[string]interface{}) 33 | 34 | These will be your input parameters for the API call. The value is of 35 | type interface{} because it can take int's, string's, or booleans. 36 | Each will be converted to string format for the url. 37 | 38 | params["category_id"] = 125 39 | 40 | url: 'https://api.stlouisfed.org/fred/category?category_id=125&api_key=apiKey&file_type=json' 41 | 42 | fc, err := client.GetRecord(params) 43 | 44 | fc is of type FredClient. This contains all necessary attributes for all 45 | responses for the available API calls. 46 | 47 | 48 | if err != nil { 49 | fmt.Println(err) 50 | } 51 | 52 | NOTE: Logging is automatically generated once you run the client. The log 53 | file will be created in the directory in which the client is instantiated. 54 | -------------------------------------------------------------------------------- /tag_toolkit_v1_test.go: -------------------------------------------------------------------------------- 1 | package fred_go_toolkit 2 | 3 | import ( 4 | "testing" 5 | 6 | . "github.com/smartystreets/goconvey/convey" 7 | ) 8 | 9 | func TestGetTags(t *testing.T) { 10 | 11 | params := make(map[string]interface{}) 12 | 13 | Convey("", t, func() { 14 | tags, err := xmlFredClient.GetTags(params) 15 | So(err, ShouldBeNil) 16 | 17 | Convey("", func() { 18 | So(tags, ShouldNotBeNil) 19 | So(len(tags.Tags), ShouldBeGreaterThanOrEqualTo, 100) 20 | }) 21 | }) 22 | 23 | Convey("", t, func() { 24 | tags, err := jsonFredClient.GetTags(params) 25 | 26 | So(err, ShouldBeNil) 27 | Convey("", func() { 28 | So(tags, ShouldNotBeNil) 29 | So(len(tags.Tags), ShouldBeGreaterThanOrEqualTo, 100) 30 | 31 | }) 32 | }) 33 | } 34 | 35 | func TestGetRelatedTags(t *testing.T) { 36 | 37 | params := make(map[string]interface{}) 38 | 39 | params["tag_names"] = "monetary aggregates;weekly" 40 | 41 | Convey("", t, func() { 42 | tags, err := xmlFredClient.GetRelatedTags(params) 43 | So(err, ShouldBeNil) 44 | 45 | Convey("", func() { 46 | So(tags, ShouldNotBeNil) 47 | So(len(tags.Tags), ShouldBeGreaterThanOrEqualTo, 13) 48 | So(tags.Tags[0].GroupID, ShouldContainSubstring, "geot") 49 | So(tags.Tags[0].Name, ShouldContainSubstring, "nation") 50 | 51 | }) 52 | }) 53 | 54 | Convey("", t, func() { 55 | tags, err := jsonFredClient.GetRelatedTags(params) 56 | 57 | So(err, ShouldBeNil) 58 | Convey("", func() { 59 | So(tags, ShouldNotBeNil) 60 | So(len(tags.Tags), ShouldBeGreaterThanOrEqualTo, 13) 61 | So(tags.Tags[0].GroupID, ShouldContainSubstring, "geot") 62 | So(tags.Tags[0].Name, ShouldContainSubstring, "nation") 63 | }) 64 | }) 65 | } 66 | 67 | func TestGetTagSeries(t *testing.T) { 68 | 69 | params := make(map[string]interface{}) 70 | 71 | params["tag_names"] = "slovenia;food;oecd" 72 | 73 | Convey("", t, func() { 74 | tags, err := xmlFredClient.GetTagSeries(params) 75 | So(err, ShouldBeNil) 76 | 77 | Convey("", func() { 78 | So(tags, ShouldNotBeNil) 79 | So(len(tags.Seriess), ShouldBeGreaterThanOrEqualTo, 18) 80 | So(tags.Seriess[0].ID, ShouldContainSubstring, "CPGDFD02SIA657N") 81 | }) 82 | }) 83 | 84 | Convey("", t, func() { 85 | tags, err := jsonFredClient.GetTagSeries(params) 86 | 87 | So(err, ShouldBeNil) 88 | Convey("", func() { 89 | So(tags, ShouldNotBeNil) 90 | So(len(tags.Seriess), ShouldBeGreaterThanOrEqualTo, 18) 91 | So(tags.Seriess[0].ID, ShouldContainSubstring, "CPGDFD02SIA657N") 92 | }) 93 | }) 94 | 95 | } 96 | -------------------------------------------------------------------------------- /tag_toolkit_v1.go: -------------------------------------------------------------------------------- 1 | package fred_go_toolkit 2 | 3 | // Tag is a single instance of a FRED tag. 4 | type Tag struct { 5 | Name string `json:"name" xml:"name,attr"` 6 | GroupID string `json:"group_id" xml:"group_id,attr"` 7 | Notes string `json:"notes" xml:"notes,attr"` 8 | Created string `json:"created" xml:"created,attr"` 9 | Popularity int `json:"popularity" xml:"popularity,attr"` 10 | SeriesCount int `json:"series_count" xml:"series_count,attr"` 11 | } 12 | 13 | // GetTags will get FRED tags. 14 | // Optionally, filter results by tag name, tag group, or search. 15 | // FRED tags are attributes assigned to series. 16 | // See the related request GetRelatedTags. 17 | // 18 | // Schema for the request and response objects and source for the documentation can be found at the following link: https://research.stlouisfed.org/docs/api/fred/tags.html 19 | func (f *FredClient) GetTags(params map[string]interface{}) (*FredType, error) { 20 | 21 | fc, err := f.operate(params, tagsParam) 22 | 23 | if err != nil { 24 | f.logError(tagsParam, err) 25 | return nil, err 26 | } 27 | 28 | return fc, nil 29 | 30 | } 31 | 32 | // GetRelatedTags will get the related FRED tags for one or more FRED tags. 33 | // Optionally, filter results by tag group or search. 34 | // 35 | // FRED tags are attributes assigned to series. 36 | // Related FRED tags are the tags assigned to series that match all tags in the tag_names parameter and no tags in the exclude_tag_names parameter. 37 | // See the related request GetTags. 38 | // 39 | // Schema for the request and response objects and source for the documentation can be found at the following link: https://research.stlouisfed.org/docs/api/fred/related_tags.html 40 | func (f *FredClient) GetRelatedTags(params map[string]interface{}) (*FredType, error) { 41 | 42 | fc, err := f.operate(params, relatedTagsParam) 43 | 44 | if err != nil { 45 | f.logError(relatedTagsParam, err) 46 | return nil, err 47 | } 48 | 49 | return fc, nil 50 | 51 | } 52 | 53 | // GetTagSeries will get the series matching all tags in the tag_names parameter and no tags in the exclude_tag_names parameter. 54 | // 55 | // Schema for the request and response objects and source for the documentation can be found at the following link: https://research.stlouisfed.org/docs/api/fred/tags_series.html 56 | func (f *FredClient) GetTagSeries(params map[string]interface{}) (*FredType, error) { 57 | 58 | fc, err := f.operate(params, tagsSeriesParam) 59 | 60 | if err != nil { 61 | f.logError(tagsSeriesParam, err) 62 | return nil, err 63 | } 64 | 65 | return fc, nil 66 | 67 | } 68 | -------------------------------------------------------------------------------- /sources_toolkit_v1_test.go: -------------------------------------------------------------------------------- 1 | package fred_go_toolkit 2 | 3 | import ( 4 | "testing" 5 | 6 | . "github.com/smartystreets/goconvey/convey" 7 | ) 8 | 9 | func TestGetSources(t *testing.T) { 10 | 11 | params := make(map[string]interface{}) 12 | 13 | Convey("", t, func() { 14 | srcs, err := xmlFredClient.GetSources(params) 15 | So(err, ShouldBeNil) 16 | 17 | Convey("", func() { 18 | So(srcs, ShouldNotBeNil) 19 | So(len(srcs.Sources), ShouldBeGreaterThanOrEqualTo, 58) 20 | So(srcs.Sources[0].Name, ShouldContainSubstring, "Board of Governors of the Federal Reserve System") 21 | }) 22 | }) 23 | 24 | Convey("", t, func() { 25 | srcs, err := jsonFredClient.GetSources(params) 26 | 27 | So(err, ShouldBeNil) 28 | Convey("", func() { 29 | So(srcs, ShouldNotBeNil) 30 | So(len(srcs.Sources), ShouldBeGreaterThanOrEqualTo, 58) 31 | So(srcs.Sources[0].Name, ShouldContainSubstring, "Board of Governors of the Federal Reserve System") 32 | }) 33 | }) 34 | 35 | } 36 | 37 | func TestGetSource(t *testing.T) { 38 | 39 | params := make(map[string]interface{}) 40 | 41 | params["source_id"] = 1 42 | 43 | Convey("", t, func() { 44 | src, err := xmlFredClient.GetSource(params) 45 | So(err, ShouldBeNil) 46 | 47 | Convey("", func() { 48 | So(src, ShouldNotBeNil) 49 | So(len(src.Sources), ShouldBeGreaterThanOrEqualTo, 1) 50 | So(src.Sources[0].Name, ShouldContainSubstring, "Board of Governors of the Federal Reserve System") 51 | 52 | }) 53 | }) 54 | 55 | Convey("", t, func() { 56 | src, err := jsonFredClient.GetSource(params) 57 | 58 | So(err, ShouldBeNil) 59 | Convey("", func() { 60 | So(src, ShouldNotBeNil) 61 | So(len(src.Sources), ShouldBeGreaterThanOrEqualTo, 1) 62 | So(src.Sources[0].Name, ShouldContainSubstring, "Board of Governors of the Federal Reserve System") 63 | 64 | }) 65 | }) 66 | 67 | } 68 | 69 | func TestGetSourceReleases(t *testing.T) { 70 | 71 | params := make(map[string]interface{}) 72 | 73 | params["source_id"] = 1 74 | 75 | Convey("", t, func() { 76 | rls, err := xmlFredClient.GetSourceReleases(params) 77 | So(err, ShouldBeNil) 78 | 79 | Convey("", func() { 80 | So(rls, ShouldNotBeNil) 81 | So(len(rls.Releases), ShouldBeGreaterThanOrEqualTo, 26) 82 | So(rls.Releases[0].Name, ShouldContainSubstring, "G.17 Industrial Production and Capacity Utilization") 83 | 84 | }) 85 | }) 86 | 87 | Convey("", t, func() { 88 | rls, err := jsonFredClient.GetSourceReleases(params) 89 | 90 | So(err, ShouldBeNil) 91 | Convey("", func() { 92 | So(rls, ShouldNotBeNil) 93 | So(len(rls.Releases), ShouldBeGreaterThanOrEqualTo, 26) 94 | So(rls.Releases[0].Name, ShouldContainSubstring, "G.17 Industrial Production and Capacity Utilization") 95 | 96 | }) 97 | }) 98 | 99 | } 100 | -------------------------------------------------------------------------------- /constants.go: -------------------------------------------------------------------------------- 1 | package fred_go_toolkit 2 | 3 | const ( 4 | ////////////////////////////////////////////////// 5 | // fileTypeJSON will return json data from API. // 6 | ////////////////////////////////////////////////// 7 | 8 | FileTypeJSON = "json" 9 | 10 | //////////////////////////////////////////////// 11 | // fileTypeXML will return xml data from API. // 12 | //////////////////////////////////////////////// 13 | 14 | FileTypeXML = "xml" 15 | 16 | ////////////////// 17 | // FRED API URL // 18 | ////////////////// 19 | 20 | apiURL = "https://api.stlouisfed.org/fred" 21 | 22 | //////////// 23 | // errors // 24 | //////////// 25 | 26 | errorNoAPIKey = "Operation may not be performed without an APIKEY. APIKEY's can be retrieved at your research.stlouisfed.org user account." 27 | errorNoParameters = "No parameters were added. Please update you parameter input." 28 | errorLibraryFail = "There was an error in processing the query. Please contact the client administrator." 29 | errorInvalidAPIKey = "API key is invalid. Please supply a valid API key." 30 | errorIncorrectFileType = "You must provide a valid file type in order to use this client. Ex: '', 'json', 'xml'" 31 | //////////////////////////// 32 | // paramLookup attributes // 33 | //////////////////////////// 34 | 35 | paramLookupExt = "extension" 36 | paramLookupParams = "params" 37 | 38 | /////////////////////// 39 | // method type param // 40 | /////////////////////// 41 | 42 | categoryParam = "CATEGORY" 43 | categoryChildrenParam = "CATEGORY_CHILDREN" 44 | categoryRelatedParam = "CATEGORY_RELATED" 45 | categorySeriesParam = "CATEGORY_SERIES" 46 | categoryTagsParam = "CATEGORY_TAGS" 47 | categoryRelatedTagsParam = "CATEGORY_RELATED_TAGS" 48 | 49 | releasesParam = "RELEASES" 50 | releasesDatesParam = "RELEASES_DATES" 51 | releaseParam = "RELEASE" 52 | releaseDatesParam = "RELEASE_DATES" 53 | releaseSeriesParam = "RELEASE_SERIES" 54 | releaseSourcesParam = "RELEASE_SOURCES" 55 | releaseTagsParam = "RELEASE_TAGS" 56 | releaseRelatedTagsParam = "RELEASE_RELATED_TAGS" 57 | releaseTablesParam = "RELEASE_TABLES" 58 | 59 | seriesParam = "SERIES" 60 | seriesCategoriesParam = "SERIES_CATEGORIES" 61 | seriesObservationsParam = "SERIES_OBSERVATIONS" 62 | seriesReleaseParam = "SERIES_RELEASE" 63 | seriesSearchParam = "SERIES_SEARCH" 64 | seriesSearchTagsParam = "SERIES_SEARCH_TAGS" 65 | seriesSearchRelatedTagsParam = "SERIES_SEARCH_RELATED_TAGS" 66 | seriesTagsParam = "SERIES_TAGS" 67 | seriesUpdatesParam = "SERIES_UPDATES" 68 | seriesVintagedatesParam = "SERIES_VINTAGEDATES" 69 | 70 | sourcesParam = "SOURCES" 71 | sourceParam = "SOURCE" 72 | sourceReleasesParam = "SOURCE_RELEASES" 73 | 74 | tagsParam = "TAGS" 75 | relatedTagsParam = "RELATED_TAGS" 76 | tagsSeriesParam = "TAGS_SERIES" 77 | ) 78 | -------------------------------------------------------------------------------- /unused_structs.go: -------------------------------------------------------------------------------- 1 | package fred_go_toolkit 2 | 3 | /* 4 | type Releases struct { 5 | Start string `json:"realtime_start" xml:"realtime_start"` 6 | End string `json:"realtime_end" xml:"realtime_end"` 7 | OrderBy string `json:"order_by" xml:"order_by"` 8 | SortOrder string `json:"sort_order" xml:"sort_order"` 9 | Count int `json:"count" xml:"count"` 10 | Offset int `json:"offset" xml:"offset"` 11 | Limit int `json:"limit" xml:"limit"` 12 | //ReleaseCol []Release `json:"releases" xml:"releases"` 13 | } 14 | 15 | type ReleaseDates struct { 16 | Start string `json:"realtime_start" xml:"realtime_start"` 17 | End string `json:"realtime_end" xml:"realtime_end"` 18 | OrderBy string `json:"order_by" xml:"order_by"` 19 | SortOrder string `json:"sort_order" xml:"sort_order"` 20 | Count int `json:"count" xml:"count"` 21 | Offset int `json:"offset" xml:"offset"` 22 | Limit int `json:"limit" xml:"limit"` 23 | //ReleaseDatesCol []ReleaseDate `json:"release_dates" xml:"release_dates"` 24 | } 25 | 26 | type Seriess struct { 27 | Start string `json:"realtime_start" xml:"realtime_start"` 28 | End string `json:"realtime_end" xml:"realtime_end"` 29 | //SeriesCol []Series `json:"seriess" xml:"seriess"` 30 | } 31 | 32 | type Observations struct { 33 | Start string `json:"realtime_start" xml:"realtime_start"` 34 | End string `json:"realtime_end" xml:"realtime_end"` 35 | ObsStart string `json:"observation_start" xml:"observation_start"` 36 | ObsEnd string `json:"observation_end" xml:"observation_end"` 37 | Units string `json:"units" xml:"units"` 38 | OutputType int `json:"output_type" xml:"output_type"` 39 | FileType string `json:"file_type" xml:"file_type"` 40 | OrderBy string `json:"order_by" xml:"order_by"` 41 | SortOrder string `json:"sort_order" xml:"sort_order"` 42 | Count int `json:"count" xml:"count"` 43 | Offset int `json:"offset" xml:"offset"` 44 | Limit int `json:"limit" xml:"limit"` 45 | //Observations []Observation `json:"observations" xml:"observations"` 46 | } 47 | 48 | type VintageDates struct { 49 | Start string `json:"realtime_start" xml:"realtime_start"` 50 | End string `json:"realtime_end" xml:"realtime_end"` 51 | OrderBy string `json:"order_by" xml:"order_by"` 52 | SortOrder string `json:"sort_order" xml:"sort_order"` 53 | Count int `json:"count" xml:"count"` 54 | Offset int `json:"offset" xml:"offset"` 55 | Limit int `json:"limit" xml:"limit"` 56 | VintageDates []string `json:"vintage_dates" xml:"vintage_dates"` 57 | } 58 | 59 | type Sources struct { 60 | Start string `json:"realtime_start" xml:"realtime_start"` 61 | End string `json:"realtime_end" xml:"realtime_end"` 62 | OrderBy string `json:"order_by" xml:"order_by"` 63 | SortOrder string `json:"sort_order" xml:"sort_order"` 64 | Count int `json:"count" xml:"count"` 65 | Offset int `json:"offset" xml:"offset"` 66 | Limit int `json:"limit" xml:"limit"` 67 | //SourcesCol []Source `json:"sources" xml:"sources"` 68 | } 69 | 70 | type Tags struct { 71 | Start string `json:"realtime_start" xml:"realtime_start"` 72 | End string `json:"realtime_end" xml:"realtime_end"` 73 | OrderBy string `json:"order_by" xml:"order_by"` 74 | SortOrder string `json:"sort_order" xml:"sort_order"` 75 | Count int `json:"count" xml:"count"` 76 | Offset int `json:"offset" xml:"offset"` 77 | Limit int `json:"limit" xml:"limit"` 78 | //Tags []Tag `json:"tag" xml:"tag"` 79 | //Sources []Source `json:"sources" xml:"sources"` 80 | } 81 | */ 82 | -------------------------------------------------------------------------------- /categories_toolkit_v1.go: -------------------------------------------------------------------------------- 1 | package fred_go_toolkit 2 | 3 | // Categories represents a collection of FRED categories. 4 | type Categories struct { 5 | CategoryCol []Category `json:"categories"` 6 | } 7 | 8 | // Category is a single instance of a FRED category. 9 | type Category struct { 10 | ID int `json:"id" xml:"id,attr"` 11 | Name string `json:"name" xml:"name,attr"` 12 | ParentID int `json:"parent_id" xml:"parent_id,attr"` 13 | } 14 | 15 | // GetCategory will get a category. 16 | // 17 | // Schema for the request and response objects and source for the documentation can be found at the following link: https://research.stlouisfed.org/docs/api/fred/category.html 18 | func (f *FredClient) GetCategory(params map[string]interface{}) (*FredType, error) { 19 | 20 | fc, err := f.operate(params, categoryParam) 21 | 22 | if err != nil { 23 | f.logError(categoryParam, err) 24 | return nil, err 25 | } 26 | 27 | return fc, nil 28 | 29 | } 30 | 31 | // GetCategoryChildren will get the child categories for a specified parent category. 32 | // 33 | // Schema for the request and response objects and source for the documentation can be found at the following link: https://research.stlouisfed.org/docs/api/fred/category_children.html 34 | func (f *FredClient) GetCategoryChildren(params map[string]interface{}) (*FredType, error) { 35 | 36 | fc, err := f.operate(params, categoryChildrenParam) 37 | 38 | if err != nil { 39 | f.logError(categoryChildrenParam, err) 40 | return nil, err 41 | } 42 | 43 | return fc, nil 44 | 45 | } 46 | 47 | // GetRelatedCategory will get the related categories for a category. 48 | // A related category is a one-way relation between 2 categories that is not part of a parent-child category hierarchy. 49 | // Most categories do not have related categories. 50 | // 51 | // Schema for the request and response objects and source for the documentation can be found at the following link: https://research.stlouisfed.org/docs/api/fred/category_related.html 52 | func (f *FredClient) GetRelatedCategory(params map[string]interface{}) (*FredType, error) { 53 | 54 | fc, err := f.operate(params, categoryRelatedParam) 55 | 56 | if err != nil { 57 | f.logError(categoryRelatedParam, err) 58 | return nil, err 59 | } 60 | 61 | return fc, nil 62 | 63 | } 64 | 65 | // GetCategorySeries will get the series in a category. 66 | // 67 | // Schema for the request and response objects and source for the documentation can be found at the following link: https://research.stlouisfed.org/docs/api/fred/category_series.html 68 | func (f *FredClient) GetCategorySeries(params map[string]interface{}) (*FredType, error) { 69 | 70 | fc, err := f.operate(params, categorySeriesParam) 71 | 72 | if err != nil { 73 | f.logError(categorySeriesParam, err) 74 | return nil, err 75 | } 76 | 77 | return fc, nil 78 | 79 | } 80 | 81 | // GetCategoryTags will get the FRED tags for a category. 82 | // Optionally, filter results by tag name, tag group, or search. 83 | // Series are assigned tags and categories. 84 | // Indirectly through series, it is possible to get the tags for a category. 85 | // No tags exist for a category that does not have series. 86 | // See the related request GetCategoryRelatedTags. 87 | // 88 | // Schema for the request and response objects and source for the documentation can be found at the following link: https://research.stlouisfed.org/docs/api/fred/category_tags.html 89 | func (f *FredClient) GetCategoryTags(params map[string]interface{}) (*FredType, error) { 90 | 91 | fc, err := f.operate(params, categoryTagsParam) 92 | 93 | if err != nil { 94 | f.logError(categoryTagsParam, err) 95 | return nil, err 96 | } 97 | 98 | return fc, nil 99 | 100 | } 101 | 102 | // GetCategoryRelatedTags will get the related FRED tags for one or more FRED tags within a category. 103 | // Optionally, filter results by tag group or search. 104 | // 105 | // FRED tags are attributes assigned to series. 106 | // For this request, related FRED tags are the tags assigned to series that match all tags in the tag_names parameter, no tags in the exclude_tag_names parameter, and the category set by the category_id parameter. 107 | // See the related request GetCategoryTags. 108 | // 109 | // Series are assigned tags and categories. 110 | // Indirectly through series, it is possible to get the tags for a category. 111 | // No tags exist for a category that does not have series. 112 | // 113 | // Schema for the request and response objects and source for the documentation can be found at the following link: https://research.stlouisfed.org/docs/api/fred/category_related_tags.html 114 | func (f *FredClient) GetCategoryRelatedTags(params map[string]interface{}) (*FredType, error) { 115 | 116 | fc, err := f.operate(params, categoryRelatedTagsParam) 117 | 118 | if err != nil { 119 | f.logError(categoryRelatedTagsParam, err) 120 | return nil, err 121 | } 122 | 123 | return fc, nil 124 | 125 | } 126 | -------------------------------------------------------------------------------- /categories_toolkit_v1_test.go: -------------------------------------------------------------------------------- 1 | package fred_go_toolkit 2 | 3 | import ( 4 | "testing" 5 | 6 | . "github.com/smartystreets/goconvey/convey" 7 | ) 8 | 9 | func TestGetCategory(t *testing.T) { 10 | 11 | params := make(map[string]interface{}) 12 | 13 | params["category_id"] = 125 14 | 15 | Convey("", t, func() { 16 | ctg, err := xmlFredClient.GetCategory(params) 17 | So(err, ShouldBeNil) 18 | 19 | Convey("", func() { 20 | So(ctg, ShouldNotBeNil) 21 | So(len(ctg.Categories), ShouldBeGreaterThanOrEqualTo, 1) 22 | So(ctg.Categories[0].ID, ShouldBeLessThanOrEqualTo, 125) 23 | So(ctg.Categories[0].Name, ShouldContainSubstring, "Trade Balance") 24 | So(ctg.Categories[0].ParentID, ShouldBeLessThanOrEqualTo, 13) 25 | 26 | }) 27 | }) 28 | 29 | Convey("", t, func() { 30 | ctg, err := jsonFredClient.GetCategory(params) 31 | 32 | So(err, ShouldBeNil) 33 | Convey("", func() { 34 | So(ctg, ShouldNotBeNil) 35 | So(len(ctg.Categories), ShouldBeGreaterThanOrEqualTo, 1) 36 | So(ctg.Categories[0].ID, ShouldBeLessThanOrEqualTo, 125) 37 | So(ctg.Categories[0].Name, ShouldContainSubstring, "Trade Balance") 38 | So(ctg.Categories[0].ParentID, ShouldBeLessThanOrEqualTo, 13) 39 | }) 40 | }) 41 | 42 | } 43 | 44 | func TestGetCategoryChildren(t *testing.T) { 45 | 46 | params := make(map[string]interface{}) 47 | 48 | params["category_id"] = 13 49 | 50 | Convey("", t, func() { 51 | ctgs, err := xmlFredClient.GetCategoryChildren(params) 52 | So(err, ShouldBeNil) 53 | 54 | Convey("", func() { 55 | So(ctgs, ShouldNotBeNil) 56 | So(len(ctgs.Categories), ShouldBeGreaterThanOrEqualTo, 5) 57 | So(ctgs.Categories[0].ID, ShouldBeLessThanOrEqualTo, 16) 58 | So(ctgs.Categories[0].Name, ShouldContainSubstring, "Exports") 59 | So(ctgs.Categories[0].ParentID, ShouldBeLessThanOrEqualTo, 13) 60 | }) 61 | }) 62 | 63 | Convey("", t, func() { 64 | ctgs, err := jsonFredClient.GetCategoryChildren(params) 65 | 66 | So(err, ShouldBeNil) 67 | Convey("", func() { 68 | So(ctgs, ShouldNotBeNil) 69 | So(len(ctgs.Categories), ShouldBeGreaterThanOrEqualTo, 5) 70 | So(ctgs.Categories[0].ID, ShouldBeLessThanOrEqualTo, 16) 71 | So(ctgs.Categories[0].Name, ShouldContainSubstring, "Exports") 72 | So(ctgs.Categories[0].ParentID, ShouldBeLessThanOrEqualTo, 13) 73 | }) 74 | }) 75 | 76 | } 77 | 78 | func TestGetRelatedCategory(t *testing.T) { 79 | 80 | params := make(map[string]interface{}) 81 | 82 | params["category_id"] = 32073 83 | 84 | Convey("", t, func() { 85 | ctg, err := xmlFredClient.GetRelatedCategory(params) 86 | So(err, ShouldBeNil) 87 | 88 | Convey("", func() { 89 | So(ctg, ShouldNotBeNil) 90 | So(len(ctg.Categories), ShouldBeGreaterThanOrEqualTo, 7) 91 | So(ctg.Categories[0].ID, ShouldBeLessThanOrEqualTo, 149) 92 | So(ctg.Categories[0].Name, ShouldContainSubstring, "Arkansas") 93 | So(ctg.Categories[0].ParentID, ShouldBeLessThanOrEqualTo, 27281) 94 | }) 95 | }) 96 | 97 | Convey("", t, func() { 98 | ctg, err := jsonFredClient.GetRelatedCategory(params) 99 | 100 | So(err, ShouldBeNil) 101 | Convey("", func() { 102 | So(ctg, ShouldNotBeNil) 103 | So(len(ctg.Categories), ShouldBeGreaterThanOrEqualTo, 7) 104 | So(ctg.Categories[0].ID, ShouldBeLessThanOrEqualTo, 149) 105 | So(ctg.Categories[0].Name, ShouldContainSubstring, "Arkansas") 106 | So(ctg.Categories[0].ParentID, ShouldBeLessThanOrEqualTo, 27281) 107 | }) 108 | }) 109 | 110 | } 111 | 112 | func TestGetCategorySeries(t *testing.T) { 113 | 114 | params := make(map[string]interface{}) 115 | 116 | params["category_id"] = 125 117 | 118 | Convey("", t, func() { 119 | srs, err := xmlFredClient.GetCategorySeries(params) 120 | So(err, ShouldBeNil) 121 | 122 | Convey("", func() { 123 | So(srs, ShouldNotBeNil) 124 | So(len(srs.Seriess), ShouldBeGreaterThanOrEqualTo, 24) 125 | So(srs.Seriess[0].ID, ShouldBeLessThanOrEqualTo, "BOPBCA") 126 | So(srs.Seriess[0].Title, ShouldContainSubstring, "Balance on Current Account") 127 | }) 128 | }) 129 | 130 | Convey("", t, func() { 131 | srs, err := jsonFredClient.GetCategorySeries(params) 132 | 133 | So(err, ShouldBeNil) 134 | Convey("", func() { 135 | So(srs, ShouldNotBeNil) 136 | So(len(srs.Seriess), ShouldBeGreaterThanOrEqualTo, 24) 137 | So(srs.Seriess[0].ID, ShouldBeLessThanOrEqualTo, "BOPBCA") 138 | So(srs.Seriess[0].Title, ShouldContainSubstring, "Balance on Current Account") 139 | }) 140 | }) 141 | 142 | } 143 | 144 | func TestGetCategoryTags(t *testing.T) { 145 | 146 | params := make(map[string]interface{}) 147 | 148 | params["category_id"] = 125 149 | 150 | Convey("", t, func() { 151 | tags, err := xmlFredClient.GetCategoryTags(params) 152 | So(err, ShouldBeNil) 153 | 154 | Convey("", func() { 155 | So(tags, ShouldNotBeNil) 156 | 157 | So(len(tags.Tags), ShouldBeGreaterThanOrEqualTo, tags.Count) 158 | So(tags.Tags[0].Name, ShouldContainSubstring, "bea") 159 | So(tags.Tags[0].GroupID, ShouldContainSubstring, "src") 160 | }) 161 | }) 162 | 163 | Convey("", t, func() { 164 | tags, err := jsonFredClient.GetCategoryTags(params) 165 | 166 | So(err, ShouldBeNil) 167 | Convey("", func() { 168 | So(tags, ShouldNotBeNil) 169 | So(len(tags.Tags), ShouldBeGreaterThanOrEqualTo, tags.Count) 170 | So(tags.Tags[0].Name, ShouldContainSubstring, "bea") 171 | So(tags.Tags[0].GroupID, ShouldContainSubstring, "src") 172 | }) 173 | }) 174 | 175 | } 176 | 177 | func TestGetCategoryRelatedTags(t *testing.T) { 178 | 179 | params := make(map[string]interface{}) 180 | 181 | params["category_id"] = 125 182 | params["tag_names"] = "services;quarterly" 183 | 184 | Convey("", t, func() { 185 | tags, err := xmlFredClient.GetCategoryRelatedTags(params) 186 | So(err, ShouldBeNil) 187 | 188 | Convey("", func() { 189 | So(tags, ShouldNotBeNil) 190 | So(len(tags.Tags), ShouldBeGreaterThanOrEqualTo, tags.Count) 191 | So(tags.Tags[0].Name, ShouldContainSubstring, "balance") 192 | So(tags.Tags[0].GroupID, ShouldContainSubstring, "gen") 193 | }) 194 | }) 195 | 196 | Convey("", t, func() { 197 | tags, err := jsonFredClient.GetCategoryRelatedTags(params) 198 | 199 | So(err, ShouldBeNil) 200 | Convey("", func() { 201 | So(tags, ShouldNotBeNil) 202 | So(len(tags.Tags), ShouldBeGreaterThanOrEqualTo, tags.Count) 203 | So(tags.Tags[0].Name, ShouldContainSubstring, "balance") 204 | So(tags.Tags[0].GroupID, ShouldContainSubstring, "gen") 205 | }) 206 | }) 207 | 208 | } 209 | -------------------------------------------------------------------------------- /params.go: -------------------------------------------------------------------------------- 1 | package fred_go_toolkit 2 | 3 | var paramsLookup = map[string]map[string]interface{}{ 4 | 5 | ///////////////////////// 6 | // CATEGORY PARAMATERS // 7 | ///////////////////////// 8 | 9 | categoryParam: { 10 | paramLookupExt: "/category", 11 | paramLookupParams: []string{"category_id"}, 12 | }, 13 | categoryChildrenParam: { 14 | paramLookupExt: "/category/children", 15 | paramLookupParams: []string{"category_id", "realtime_start", "realtime_end"}, 16 | }, 17 | categoryRelatedParam: { 18 | paramLookupExt: "/category/related", 19 | paramLookupParams: []string{"category_id", "realtime_start", "realtime_end"}, 20 | }, 21 | categorySeriesParam: { 22 | paramLookupExt: "/category/series", 23 | paramLookupParams: []string{"category_id", "realtime_start", "realtime_end", "limit", "offset", "order_by", "sort_order", "filter_variable", "filter_value", "tag_names", "exclude_tag_names"}, 24 | }, 25 | categoryTagsParam: { 26 | paramLookupExt: "/category/tags", 27 | paramLookupParams: []string{"category_id", "realtime_start", "realtime_end", "limit", "offset", "order_by", "sort_order", "tag_names", "tag_group_id", "search_text"}, 28 | }, 29 | categoryRelatedTagsParam: { 30 | paramLookupExt: "/category/related_tags", 31 | paramLookupParams: []string{"category_id", "realtime_start", "realtime_end", "limit", "offset", "order_by", "sort_order", "tag_names", "exclude_tag_names", "tag_group_id", "search_text"}, 32 | }, 33 | 34 | //////////////////////// 35 | // RELEASE PARAMATERS // 36 | //////////////////////// 37 | 38 | releasesParam: { 39 | paramLookupExt: "/releases", 40 | paramLookupParams: []string{"realtime_start", "realtime_end", "limit", "offset", "order_by", "sort_order"}, 41 | }, 42 | releasesDatesParam: { 43 | paramLookupExt: "/releases/dates", 44 | paramLookupParams: []string{"realtime_start", "realtime_end", "limit", "offset", "order_by", "sort_order", "include_release_dates_with_no_data"}, 45 | }, 46 | releaseParam: { 47 | paramLookupExt: "/release", 48 | paramLookupParams: []string{"release_id", "realtime_start", "realtime_end"}, 49 | }, 50 | releaseDatesParam: { 51 | paramLookupExt: "/release/dates", 52 | paramLookupParams: []string{"release_id", "realtime_start", "realtime_end", "limit", "offset", "order_by", "sort_order", "include_release_dates_with_no_data"}, 53 | }, 54 | releaseSeriesParam: { 55 | paramLookupExt: "/release/series", 56 | paramLookupParams: []string{"release_id", "realtime_start", "realtime_end", "limit", "offset", "order_by", "sort_order", "filter_variable", "filter_value", "tag_names", "exclude_tag_names"}, 57 | }, 58 | releaseSourcesParam: { 59 | paramLookupExt: "/release/sources", 60 | paramLookupParams: []string{"release_id", "realtime_start", "realtime_end"}, 61 | }, 62 | releaseTagsParam: { 63 | paramLookupExt: "/release/tags", 64 | paramLookupParams: []string{"release_id", "realtime_start", "realtime_end", "tag_names", "tag_group_id", "search_text", "limit", "offset", "order_by", "sort_order"}, 65 | }, 66 | releaseRelatedTagsParam: { 67 | paramLookupExt: "/release/related_tags", 68 | paramLookupParams: []string{"release_id", "realtime_start", "realtime_end", "tag_names", "tag_group_id", "exclude_tag_names", "search_text", "limit", "offset", "order_by", "sort_order"}, 69 | }, 70 | releaseTablesParam: { 71 | paramLookupExt: "/release/tables", 72 | paramLookupParams: []string{"release_id", "element_id", "include_observation_values", "observation_date"}, 73 | }, 74 | 75 | /////////////////////// 76 | // SERIES PARAMATERS // 77 | /////////////////////// 78 | 79 | seriesParam: { 80 | paramLookupExt: "/series", 81 | paramLookupParams: []string{"series_id", "realtime_start", "realtime_end"}, 82 | }, 83 | seriesCategoriesParam: { 84 | paramLookupExt: "/series/categories", 85 | paramLookupParams: []string{"series_id", "realtime_start", "realtime_end"}, 86 | }, 87 | seriesObservationsParam: { 88 | paramLookupExt: "/series/observations", 89 | paramLookupParams: []string{"series_id", "realtime_start", "realtime_end", "limit", "offset", "sort_order", "observation_start", "observation_end", "units", "frequency", "aggregation_method", "output_type", "vintage_dates"}, 90 | }, 91 | seriesReleaseParam: { 92 | paramLookupExt: "/series/release", 93 | paramLookupParams: []string{"series_id", "realtime_start", "realtime_end"}, 94 | }, 95 | seriesSearchParam: { 96 | paramLookupExt: "/series/search", 97 | paramLookupParams: []string{"search_text", "search_type", "realtime_start", "realtime_end", "tag_names", "exclude_tag_names", "limit", "offset", "order_by", "sort_order", "filter_variable", "filter_value"}, 98 | }, 99 | seriesSearchTagsParam: { 100 | paramLookupExt: "/series/search/tags", 101 | paramLookupParams: []string{"series_search_text", "realtime_start", "realtime_end", "tag_names", "tag_group_id", "tag_search_text", "limit", "offset", "order_by", "sort_order"}, 102 | }, 103 | seriesSearchRelatedTagsParam: { 104 | paramLookupExt: "/series/search/related_tags", 105 | paramLookupParams: []string{"series_search_text", "realtime_start", "realtime_end", "tag_names", "tag_group_id", "tag_search_text", "limit", "offset", "order_by", "sort_order"}, 106 | }, 107 | seriesTagsParam: { 108 | paramLookupExt: "/series/tags", 109 | paramLookupParams: []string{"series_id", "realtime_start", "realtime_end", "order_by", "sort_order"}, 110 | }, 111 | seriesUpdatesParam: { 112 | paramLookupExt: "/series/updates", 113 | paramLookupParams: []string{"realtime_start", "realtime_end", "limit", "offset", "filter_value"}, 114 | }, 115 | seriesVintagedatesParam: { 116 | paramLookupExt: "/series/vintagedates", 117 | paramLookupParams: []string{"series_id", "realtime_start", "realtime_end", "limit", "offset", "sort_order"}, 118 | }, 119 | 120 | //////////////////////// 121 | // SOURCES PARAMATERS // 122 | //////////////////////// 123 | 124 | sourcesParam: { 125 | paramLookupExt: "/sources", 126 | paramLookupParams: []string{"realtime_start", "realtime_end", "limit", "offset", "order_by", "sort_order"}, 127 | }, 128 | sourceParam: { 129 | paramLookupExt: "/source", 130 | paramLookupParams: []string{"source_id", "realtime_start", "realtime_end"}, 131 | }, 132 | sourceReleasesParam: { 133 | paramLookupExt: "/source/releases", 134 | paramLookupParams: []string{"source_id", "realtime_start", "realtime_end", "limit", "offset", "order_by", "sort_order"}, 135 | }, 136 | 137 | ///////////////////// 138 | // TAGS PARAMATERS // 139 | ///////////////////// 140 | 141 | tagsParam: { 142 | paramLookupExt: "/tags", 143 | paramLookupParams: []string{"realtime_start", "realtime_end", "tag_names", "tag_group_id", "search_text", "limit", "offset", "order_by", "sort_order"}, 144 | }, 145 | relatedTagsParam: { 146 | paramLookupExt: "/related_tags", 147 | paramLookupParams: []string{"realtime_start", "realtime_end", "limit", "offset", "order_by", "sort_order", "tag_names", "exclude_tag_names", "tag_group_id"}, 148 | }, 149 | tagsSeriesParam: { 150 | paramLookupExt: "/tags/series", 151 | paramLookupParams: []string{"tag_names", "exclude_tag_names", "realtime_start", "realtime_end", "limit", "offset", "order_by", "sort_order"}, 152 | }, 153 | } 154 | -------------------------------------------------------------------------------- /releases_toolkit_v1.go: -------------------------------------------------------------------------------- 1 | package fred_go_toolkit 2 | 3 | import ( 4 | "errors" 5 | "io/ioutil" 6 | ) 7 | 8 | // Release is a single instance of a release of FRED economic data. 9 | type Release struct { 10 | ID int `json:"id" xml:"id,attr"` 11 | Start string `json:"realtime_start" xml:"realtime_start,attr"` 12 | End string `json:"realtime_end" xml:"realtime_end,attr"` 13 | Name string `json:"name" xml:"name,attr"` 14 | PressRelease bool `json:"press_release" xml:"press_release,attr"` 15 | Link string `json:"link" xml:"link,attr"` 16 | } 17 | 18 | // ReleaseDate is a single instance of a release date of FRED economic data. 19 | type ReleaseDate struct { 20 | ID int `json:"release_id" xml:"release_id,attr"` 21 | Name string `json:"release_name" xml:"release_name,attr"` 22 | Date string `json:"date" xml:",chardata"` 23 | } 24 | 25 | // GetReleases will get all releases of economic data. 26 | // 27 | // Schema for the request and response objects and source for the documentation can be found at the following link: https://research.stlouisfed.org/docs/api/fred/releases.html 28 | func (f *FredClient) GetReleases(params map[string]interface{}) (*FredType, error) { 29 | 30 | fc, err := f.operate(params, releasesParam) 31 | 32 | if err != nil { 33 | f.logError(releasesParam, err) 34 | return nil, err 35 | } 36 | 37 | return fc, nil 38 | 39 | } 40 | 41 | // GetReleasesDates will get release dates for all releases of economic data. 42 | // Note that release dates are published by data sources and do not necessarily represent when data will be available on the FRED or ALFRED websites. 43 | // 44 | // Schema for the request and response objects and source for the documentation can be found at the following link: https://research.stlouisfed.org/docs/api/fred/releases_dates.html 45 | func (f *FredClient) GetReleasesDates(params map[string]interface{}) (*FredType, error) { 46 | 47 | fc, err := f.operate(params, releaseDatesParam) 48 | 49 | if err != nil { 50 | f.logError(releaseDatesParam, err) 51 | return nil, err 52 | } 53 | 54 | return fc, nil 55 | 56 | } 57 | 58 | // GetRelease will get a release of economic data. 59 | // 60 | // Schema for the request and response objects and source for the documentation can be found at the following link: https://research.stlouisfed.org/docs/api/fred/release.html 61 | func (f *FredClient) GetRelease(params map[string]interface{}) (*FredType, error) { 62 | 63 | fc, err := f.operate(params, releaseParam) 64 | 65 | if err != nil { 66 | f.logError(releaseParam, err) 67 | return nil, err 68 | } 69 | 70 | return fc, nil 71 | 72 | } 73 | 74 | // GetReleaseDates will get release dates for a release of economic data. 75 | // Note that release dates are published by data sources and do not necessarily represent when data will be available on the FRED or ALFRED websites. 76 | // 77 | // Schema for the request and response objects and source for the documentation can be found at the following link: https://research.stlouisfed.org/docs/api/fred/release_dates.html 78 | func (f *FredClient) GetReleaseDates(params map[string]interface{}) (*FredType, error) { 79 | 80 | fc, err := f.operate(params, releaseDatesParam) 81 | 82 | if err != nil { 83 | f.logError(releaseDatesParam, err) 84 | return nil, err 85 | } 86 | 87 | return fc, nil 88 | 89 | } 90 | 91 | // GetReleaseSeries will get the series on a release of economic data. 92 | // 93 | // Schema for the request and response objects and source for the documentation can be found at the following link: https://research.stlouisfed.org/docs/api/fred/release_series.html 94 | func (f *FredClient) GetReleaseSeries(params map[string]interface{}) (*FredType, error) { 95 | 96 | fc, err := f.operate(params, releaseSeriesParam) 97 | 98 | if err != nil { 99 | f.logError(releaseSeriesParam, err) 100 | return nil, err 101 | } 102 | 103 | return fc, nil 104 | 105 | } 106 | 107 | // GetReleaseSources will get the sources for a Release of economic data. 108 | // 109 | // Schema for the request and response objects and source for the documentation can be found at the following link: https://research.stlouisfed.org/docs/api/fred/release_sources.html 110 | func (f *FredClient) GetReleaseSources(params map[string]interface{}) (*FredType, error) { 111 | 112 | fc, err := f.operate(params, releaseSourcesParam) 113 | 114 | if err != nil { 115 | f.logError(releaseSourcesParam, err) 116 | return nil, err 117 | } 118 | 119 | return fc, nil 120 | 121 | } 122 | 123 | // GetReleaseTags will get the FRED tags for a release. 124 | // Optionally, filter results by tag name, tag group, or search. 125 | // Series are assigned tags and releases. 126 | // Indirectly through series, it is possible to get the tags for a release. 127 | // See the related request GetReleaseRelatedTags. 128 | // 129 | // Schema for the request and response objects and source for the documentation can be found at the following link: https://research.stlouisfed.org/docs/api/fred/release_tags.html 130 | func (f *FredClient) GetReleaseTags(params map[string]interface{}) (*FredType, error) { 131 | 132 | fc, err := f.operate(params, releaseTagsParam) 133 | 134 | if err != nil { 135 | f.logError(releaseTagsParam, err) 136 | return nil, err 137 | } 138 | 139 | return fc, nil 140 | 141 | } 142 | 143 | // GetReleaseRelatedTags will get the related FRED tags for one or more FRED tags within a release. 144 | // Optionally, filter results by tag group or search. 145 | // 146 | // FRED tags are attributes assigned to series. 147 | // For this request, related FRED tags are the tags assigned to series that match all tags in the tag_names parameter, no tags in the exclude_tag_names parameter, and the release set by the release_id parameter. 148 | // See the related request GetReleaseTags. 149 | // 150 | // Series are assigned tags and releases. 151 | // Indirectly through series, it is possible to get the tags for a release. 152 | // 153 | // Schema for the request and response objects and source for the documentation can be found at the following link: https://research.stlouisfed.org/docs/api/fred/release_related_tags.html 154 | func (f *FredClient) GetReleaseRelatedTags(params map[string]interface{}) (*FredType, error) { 155 | 156 | fc, err := f.operate(params, releaseRelatedTagsParam) 157 | 158 | if err != nil { 159 | f.logError(releaseRelatedTagsParam, err) 160 | return nil, err 161 | } 162 | 163 | return fc, nil 164 | 165 | } 166 | 167 | // GetReleaseTables will get release table trees for a given release. 168 | // You can go directly to the tree structure by passing the appropriate ElementId. 169 | // You may also use a drill-down approach to start at the root (top most) element by leaving the element_id off. 170 | // 171 | // Note that release dates are published by data sources and do not necessarily represent when data will be available on the FRED or ALFRED websites. 172 | // 173 | // Schema for the request and response objects and source for the documentation can be found at the following link: https://research.stlouisfed.org/docs/api/fred/release_tables.html 174 | func (f *FredClient) GetReleaseTables(params map[string]interface{}) (string, error) { 175 | if err := f.validateAPIKEY(); err != nil { 176 | 177 | return "", err 178 | 179 | } 180 | 181 | resp, err := f.callAPI(params, "RELEASE_TABLES") 182 | 183 | if err != nil { 184 | return "", err 185 | } 186 | 187 | res, err := ioutil.ReadAll(resp.Body) 188 | if err != nil { 189 | f.log("[GetReleaseTables] READ ERROR: " + err.Error()) 190 | return "", errors.New(errorLibraryFail) 191 | } 192 | 193 | return string(res), nil 194 | 195 | } 196 | -------------------------------------------------------------------------------- /releases_toolkit_v1_test.go: -------------------------------------------------------------------------------- 1 | package fred_go_toolkit 2 | 3 | import ( 4 | "testing" 5 | 6 | . "github.com/smartystreets/goconvey/convey" 7 | ) 8 | 9 | func TestGetReleases(t *testing.T) { 10 | 11 | params := make(map[string]interface{}) 12 | 13 | Convey("", t, func() { 14 | rls, err := xmlFredClient.GetReleases(params) 15 | So(err, ShouldBeNil) 16 | 17 | Convey("", func() { 18 | So(rls, ShouldNotBeNil) 19 | So(len(rls.Releases), ShouldBeGreaterThanOrEqualTo, 158) 20 | So(rls.Releases[0].Name, ShouldContainSubstring, "Advance Monthly Sales for Retail and Food Services") 21 | 22 | }) 23 | }) 24 | 25 | Convey("", t, func() { 26 | rls, err := jsonFredClient.GetReleases(params) 27 | 28 | So(err, ShouldBeNil) 29 | Convey("", func() { 30 | So(rls, ShouldNotBeNil) 31 | So(len(rls.Releases), ShouldBeGreaterThanOrEqualTo, 158) 32 | So(rls.Releases[0].Name, ShouldContainSubstring, "Advance Monthly Sales for Retail and Food Services") 33 | }) 34 | }) 35 | 36 | } 37 | 38 | func TestGetReleasesDates(t *testing.T) { 39 | 40 | params := make(map[string]interface{}) 41 | 42 | params["release_id"] = 82 43 | 44 | Convey("", t, func() { 45 | dts, err := xmlFredClient.GetReleasesDates(params) 46 | So(err, ShouldBeNil) 47 | 48 | Convey("", func() { 49 | So(dts, ShouldNotBeNil) 50 | So(dts.ReleaseDates[0].Date, ShouldContainSubstring, "1997-02-10") 51 | }) 52 | }) 53 | 54 | Convey("", t, func() { 55 | dts, err := jsonFredClient.GetReleasesDates(params) 56 | 57 | So(err, ShouldBeNil) 58 | Convey("", func() { 59 | So(dts, ShouldNotBeNil) 60 | So(dts.ReleaseDates[0].Date, ShouldContainSubstring, "1997-02-10") 61 | }) 62 | }) 63 | 64 | } 65 | 66 | func TestGetRelease(t *testing.T) { 67 | 68 | params := make(map[string]interface{}) 69 | 70 | params["release_id"] = 53 71 | 72 | Convey("", t, func() { 73 | rls, err := xmlFredClient.GetRelease(params) 74 | So(err, ShouldBeNil) 75 | 76 | Convey("", func() { 77 | So(rls, ShouldNotBeNil) 78 | So(len(rls.Releases), ShouldBeGreaterThanOrEqualTo, 1) 79 | So(rls.Releases[0].ID, ShouldBeGreaterThanOrEqualTo, 53) 80 | So(rls.Releases[0].Name, ShouldContainSubstring, "Gross Domestic Product") 81 | }) 82 | }) 83 | 84 | Convey("", t, func() { 85 | rls, err := jsonFredClient.GetRelease(params) 86 | 87 | So(err, ShouldBeNil) 88 | Convey("", func() { 89 | So(rls, ShouldNotBeNil) 90 | So(len(rls.Releases), ShouldBeGreaterThanOrEqualTo, 1) 91 | So(rls.Releases[0].ID, ShouldBeGreaterThanOrEqualTo, 53) 92 | So(rls.Releases[0].Name, ShouldContainSubstring, "Gross Domestic Product") 93 | }) 94 | }) 95 | 96 | } 97 | 98 | func TestGetReleaseDates(t *testing.T) { 99 | 100 | params := make(map[string]interface{}) 101 | 102 | params["release_id"] = 82 103 | 104 | Convey("", t, func() { 105 | rlsDts, err := xmlFredClient.GetReleaseDates(params) 106 | So(err, ShouldBeNil) 107 | 108 | Convey("", func() { 109 | So(rlsDts, ShouldNotBeNil) 110 | So(len(rlsDts.ReleaseDates), ShouldBeGreaterThanOrEqualTo, 17) 111 | 112 | }) 113 | }) 114 | 115 | Convey("", t, func() { 116 | rlsDts, err := jsonFredClient.GetReleaseDates(params) 117 | 118 | So(err, ShouldBeNil) 119 | Convey("", func() { 120 | So(rlsDts, ShouldNotBeNil) 121 | So(len(rlsDts.ReleaseDates), ShouldBeGreaterThanOrEqualTo, 17) 122 | 123 | }) 124 | }) 125 | 126 | } 127 | 128 | func TestGetReleaseSeries(t *testing.T) { 129 | 130 | params := make(map[string]interface{}) 131 | 132 | params["release_id"] = 51 133 | 134 | Convey("", t, func() { 135 | srs, err := xmlFredClient.GetReleaseSeries(params) 136 | So(err, ShouldBeNil) 137 | 138 | Convey("", func() { 139 | So(srs, ShouldNotBeNil) 140 | So(len(srs.Seriess), ShouldBeGreaterThanOrEqualTo, 39) 141 | So(srs.Seriess[0].ID, ShouldBeGreaterThanOrEqualTo, "BOMTVLM133S") 142 | So(srs.Seriess[0].Title, ShouldBeGreaterThanOrEqualTo, "U.S. Imports of Services - Travel") 143 | 144 | }) 145 | }) 146 | 147 | Convey("", t, func() { 148 | srs, err := jsonFredClient.GetReleaseSeries(params) 149 | 150 | So(err, ShouldBeNil) 151 | Convey("", func() { 152 | So(srs, ShouldNotBeNil) 153 | So(len(srs.Seriess), ShouldBeGreaterThanOrEqualTo, 39) 154 | So(srs.Seriess[0].ID, ShouldBeGreaterThanOrEqualTo, "BOMTVLM133S") 155 | So(srs.Seriess[0].Title, ShouldBeGreaterThanOrEqualTo, "U.S. Imports of Services - Travel") 156 | }) 157 | }) 158 | 159 | } 160 | 161 | func TestGetReleaseSources(t *testing.T) { 162 | 163 | params := make(map[string]interface{}) 164 | 165 | params["release_id"] = 51 166 | 167 | Convey("", t, func() { 168 | srs, err := xmlFredClient.GetReleaseSources(params) 169 | So(err, ShouldBeNil) 170 | 171 | Convey("", func() { 172 | So(srs, ShouldNotBeNil) 173 | So(len(srs.Sources), ShouldBeGreaterThanOrEqualTo, 2) 174 | So(srs.Sources[0].ID, ShouldBeGreaterThanOrEqualTo, 18) 175 | So(srs.Sources[0].Name, ShouldContainSubstring, "U.S. Bureau of Economic Analysis") 176 | 177 | }) 178 | }) 179 | 180 | Convey("", t, func() { 181 | srs, err := jsonFredClient.GetReleaseSources(params) 182 | 183 | So(err, ShouldBeNil) 184 | Convey("", func() { 185 | So(srs, ShouldNotBeNil) 186 | So(len(srs.Sources), ShouldBeGreaterThanOrEqualTo, 2) 187 | So(srs.Sources[0].ID, ShouldBeGreaterThanOrEqualTo, 18) 188 | So(srs.Sources[0].Name, ShouldContainSubstring, "U.S. Bureau of Economic Analysis") 189 | }) 190 | }) 191 | 192 | } 193 | 194 | func TestGetReleaseTags(t *testing.T) { 195 | 196 | params := make(map[string]interface{}) 197 | 198 | params["release_id"] = 86 199 | 200 | Convey("", t, func() { 201 | tags, err := xmlFredClient.GetReleaseTags(params) 202 | So(err, ShouldBeNil) 203 | 204 | Convey("", func() { 205 | So(tags, ShouldNotBeNil) 206 | So(tags.Tags[0].GroupID, ShouldContainSubstring, "gen") 207 | So(tags.Tags[0].Name, ShouldContainSubstring, "commercial") 208 | }) 209 | }) 210 | 211 | Convey("", t, func() { 212 | tags, err := jsonFredClient.GetReleaseTags(params) 213 | 214 | So(err, ShouldBeNil) 215 | Convey("", func() { 216 | So(tags, ShouldNotBeNil) 217 | So(tags.Tags[0].GroupID, ShouldContainSubstring, "gen") 218 | So(tags.Tags[0].Name, ShouldContainSubstring, "commercial") 219 | }) 220 | }) 221 | 222 | } 223 | 224 | func TestGetReleaseRelatedTags(t *testing.T) { 225 | 226 | params := make(map[string]interface{}) 227 | 228 | params["release_id"] = 86 229 | params["tag_names"] = "sa;foreign" 230 | 231 | Convey("", t, func() { 232 | tags, err := xmlFredClient.GetReleaseRelatedTags(params) 233 | So(err, ShouldBeNil) 234 | 235 | Convey("", func() { 236 | So(tags, ShouldNotBeNil) 237 | So(tags.Tags[0].GroupID, ShouldContainSubstring, "gen") 238 | So(tags.Tags[0].Name, ShouldContainSubstring, "commercial") 239 | }) 240 | }) 241 | 242 | Convey("", t, func() { 243 | tags, err := jsonFredClient.GetReleaseRelatedTags(params) 244 | 245 | So(err, ShouldBeNil) 246 | Convey("", func() { 247 | So(tags, ShouldNotBeNil) 248 | So(tags.Tags[0].GroupID, ShouldContainSubstring, "gen") 249 | So(tags.Tags[0].Name, ShouldContainSubstring, "commercial") 250 | }) 251 | }) 252 | 253 | } 254 | 255 | func TestGetReleaseTables(t *testing.T) { 256 | 257 | params := make(map[string]interface{}) 258 | 259 | params["release_id"] = 53 260 | params["element_id"] = 12886 261 | 262 | Convey("", t, func() { 263 | res, err := xmlFredClient.GetReleaseTables(params) 264 | So(err, ShouldBeNil) 265 | 266 | Convey("", func() { 267 | So(res, ShouldNotBeBlank) 268 | }) 269 | }) 270 | 271 | Convey("", t, func() { 272 | res, err := jsonFredClient.GetReleaseTables(params) 273 | 274 | So(err, ShouldBeNil) 275 | Convey("", func() { 276 | So(res, ShouldNotBeBlank) 277 | }) 278 | }) 279 | 280 | } 281 | -------------------------------------------------------------------------------- /series_toolkit_v1.go: -------------------------------------------------------------------------------- 1 | package fred_go_toolkit 2 | 3 | // Series is a single instance of a FRED series. 4 | type Series struct { 5 | ID string `json:"id" xml:"id,attr"` 6 | Start string `json:"realtime_start" xml:"realtime_start,attr"` 7 | End string `json:"realtime_end" xml:"realtime_end,attr"` 8 | Title string `json:"title" xml:"title,attr"` 9 | ObsStart string `json:"observation_start" xml:"observation_start,attr"` 10 | ObsEnd string `json:"observation_end" xml:"observation_end,attr"` 11 | Frequency string `json:"annual" xml:"annual,attr"` 12 | FrequencyShort string `json:"frequency_short" xml:"frequency_short,attr"` 13 | Units string `json:"units" xml:"units,attr"` 14 | UnitsShort string `json:"units_short" xml:"units_short,attr"` 15 | SeasonalAdjustment string `json:"seasonal_adjustment" xml:"seasonal_adjustment,attr"` 16 | SeasonalAdustmentShort string `json:"seasonal_adjustment_short" xml:"seasonal_adjustment_short,attr"` 17 | LastUpdated string `json:"last_updated" xml:"last_updated,attr"` 18 | Popularity int `json:"popularity" xml:"popularity,attr"` 19 | Notes string `json:"notes" xml:"notes,attr"` 20 | } 21 | 22 | // Observation is a single instance of a FRED observation. 23 | type Observation struct { 24 | Start string `json:"realtime_start" xml:"realtime_start,attr"` 25 | End string `json:"realtime_end" xml:"realtime_end,attr"` 26 | Date string `json:"date" xml:"date,attr"` 27 | Value string `json:"value" xml:"value,attr"` 28 | } 29 | 30 | // GetSeries will get an economic data series. 31 | // 32 | // Schema for the request and response objects and source for the documentation can be found at the following link: https://research.stlouisfed.org/docs/api/fred/series.html 33 | func (f *FredClient) GetSeries(params map[string]interface{}) (*FredType, error) { 34 | 35 | fc, err := f.operate(params, seriesParam) 36 | 37 | if err != nil { 38 | f.logError(seriesParam, err) 39 | return nil, err 40 | } 41 | 42 | return fc, nil 43 | 44 | } 45 | 46 | // GetSeriesCategories will get the categories for an economic data series. 47 | // 48 | // Schema for the request and response objects and source for the documentation can be found at the following link: https://research.stlouisfed.org/docs/api/fred/series_categories.html 49 | func (f *FredClient) GetSeriesCategories(params map[string]interface{}) (*FredType, error) { 50 | 51 | fc, err := f.operate(params, seriesCategoriesParam) 52 | 53 | if err != nil { 54 | f.logError(seriesCategoriesParam, err) 55 | return nil, err 56 | } 57 | 58 | return fc, nil 59 | 60 | } 61 | 62 | // GetReleaseObservations will get the observations or data values for an economic data series. 63 | // 64 | // Schema for the request and response objects and source for the documentation can be found at the following link: https://research.stlouisfed.org/docs/api/fred/series_observations.html 65 | func (f *FredClient) GetSeriesObservations(params map[string]interface{}) (*FredType, error) { 66 | 67 | fc, err := f.operate(params, seriesObservationsParam) 68 | 69 | if err != nil { 70 | f.logError(seriesObservationsParam, err) 71 | return nil, err 72 | } 73 | 74 | return fc, nil 75 | 76 | } 77 | 78 | // GetSeriesRelease will get the release for an economic data series. 79 | // 80 | // Schema for the request and response objects and source for the documentation can be found at the following link: https://research.stlouisfed.org/docs/api/fred/series_release.html 81 | func (f *FredClient) GetSeriesRelease(params map[string]interface{}) (*FredType, error) { 82 | 83 | fc, err := f.operate(params, seriesReleaseParam) 84 | 85 | if err != nil { 86 | f.logError(seriesReleaseParam, err) 87 | return nil, err 88 | } 89 | 90 | return fc, nil 91 | 92 | } 93 | 94 | // GetSeriesSearch will get economic data series that match keywords. 95 | // 96 | // Schema for the request and response objects and source for the documentation can be found at the following link: https://research.stlouisfed.org/docs/api/fred/series_search.html 97 | func (f *FredClient) GetSeriesSearch(params map[string]interface{}) (*FredType, error) { 98 | 99 | fc, err := f.operate(params, seriesSearchParam) 100 | 101 | if err != nil { 102 | f.logError(seriesSearchParam, err) 103 | return nil, err 104 | } 105 | 106 | return fc, nil 107 | 108 | } 109 | 110 | // GetSeriesSearchTags will get the FRED tags for a series search. 111 | // Optionally, filter results by tag name, tag group, or tag search. 112 | // See the related request GetSeriesSearchRelatedTags. 113 | // 114 | // Schema for the request and response objects and source for the documentation can be found at the following link: https://research.stlouisfed.org/docs/api/fred/series_search_tags.html 115 | func (f *FredClient) GetSeriesSearchTags(params map[string]interface{}) (*FredType, error) { 116 | 117 | fc, err := f.operate(params, seriesSearchTagsParam) 118 | 119 | if err != nil { 120 | f.logError(seriesSearchTagsParam, err) 121 | return nil, err 122 | } 123 | 124 | return fc, nil 125 | 126 | } 127 | 128 | // GetSeriesSearchRelatedTags will get teh related tags for a series search. 129 | // Optionally, filter results by tag group or tag search. 130 | // 131 | // FRED tags are attributes assigned to series. 132 | // For this request, related FRED tags are the tags assigned to series that match all tags in the tag_names parameter, no tags in the exclude_tag_names parameter, and the search words set by the series_search_text parameter. 133 | // See the related request GetSeriesSearchTags. 134 | // 135 | // Schema for the request and response objects and source for the documentation can be found at the following link: https://research.stlouisfed.org/docs/api/fred/series_search_related_tags.html 136 | func (f *FredClient) GetSeriesSearchRelatedTags(params map[string]interface{}) (*FredType, error) { 137 | 138 | fc, err := f.operate(params, seriesSearchRelatedTagsParam) 139 | 140 | if err != nil { 141 | f.logError(seriesSearchRelatedTagsParam, err) 142 | return nil, err 143 | } 144 | 145 | return fc, nil 146 | 147 | } 148 | 149 | // GetSeriesTags will get the tags for an economic data series. 150 | // 151 | // Schema for the request and response objects and source for the documentation can be found at the following link: https://research.stlouisfed.org/docs/api/fred/series_tags.html 152 | func (f *FredClient) GetSeriesTags(params map[string]interface{}) (*FredType, error) { 153 | 154 | fc, err := f.operate(params, seriesTagsParam) 155 | 156 | if err != nil { 157 | f.logError(seriesTagsParam, err) 158 | return nil, err 159 | } 160 | 161 | return fc, nil 162 | 163 | } 164 | 165 | // GetSeriesUpdates will get economic data series sorted by when observations were updated on the FRED® server (attribute last_updated). 166 | // Results are limited to series updated within the last two weeks. 167 | // 168 | // Schema for the request and response objects and source for the documentation can be found at the following link: https://research.stlouisfed.org/docs/api/fred/series_updates.html 169 | func (f *FredClient) GetSeriesUpdates(params map[string]interface{}) (*FredType, error) { 170 | 171 | fc, err := f.operate(params, seriesUpdatesParam) 172 | 173 | if err != nil { 174 | f.logError(seriesUpdatesParam, err) 175 | return nil, err 176 | } 177 | 178 | return fc, nil 179 | 180 | } 181 | 182 | // GetSeriesVintageDates will get the dates in history when a series' data values were revised or new data values were released. Vintage dates are the release dates for a series excluding release dates when the data for the series did not change. 183 | // 184 | // Schema for the request and response objects and source for the documentation can be found at the following link: https://research.stlouisfed.org/docs/api/fred/series_vintagedates.html 185 | func (f *FredClient) GetSeriesVintageDates(params map[string]interface{}) (*FredType, error) { 186 | 187 | fc, err := f.operate(params, seriesVintagedatesParam) 188 | 189 | if err != nil { 190 | f.logError(seriesVintagedatesParam, err) 191 | return nil, err 192 | } 193 | 194 | return fc, nil 195 | 196 | } 197 | -------------------------------------------------------------------------------- /fred_toolkit_v1.go: -------------------------------------------------------------------------------- 1 | package fred_go_toolkit 2 | 3 | import ( 4 | "encoding/json" 5 | "encoding/xml" 6 | "errors" 7 | "fmt" 8 | "log" 9 | "net/http" 10 | "os" 11 | "reflect" 12 | "strconv" 13 | "strings" 14 | ) 15 | 16 | // FredType represents the response object for all responses from the FRED api. 17 | type FredType struct { 18 | Start string `json:"realtime_start" xml:"realtime_start"` 19 | End string `json:"realtime_end" xml:"realtime_end"` 20 | ObsStart string `json:"observation_start" xml:"observation_start"` 21 | ObsEnd string `json:"observation_end" xml:"observation_end"` 22 | Units string `json:"units" xml:"units"` 23 | OutputType int `json:"output_type" xml:"output_type"` 24 | FileType string `json:"file_type" xml:"file_type"` 25 | OrderBy string `json:"order_by" xml:"order_by"` 26 | SortOrder string `json:"sort_order" xml:"sort_order"` 27 | Count int `json:"count" xml:"count"` 28 | Offset int `json:"offset" xml:"offset"` 29 | Limit int `json:"limit" xml:"limit"` 30 | Categories []Category `json:"categories" xml:"category"` 31 | Releases []Release `json:"releases" xml:"release"` 32 | Seriess []Series `json:"seriess" xml:"series"` 33 | Observations []Observation `json:"observations" xml:"observation"` 34 | VintageDates []string `json:"vintage_dates" xml:"vintage_date"` 35 | Tags []Tag `json:"tags" xml:"tag"` 36 | Sources []Source `json:"sources" xml:"source"` 37 | ReleaseDates []ReleaseDate `json:"release_dates" xml:"release_date"` 38 | } 39 | 40 | // FredClient is the main instance to call the FRED API. 41 | // All methods are a member of an instance of the FredClient. 42 | type FredClient struct { 43 | APIKEY string 44 | fileType string 45 | requestURL string 46 | logFile *os.File 47 | hasLogs bool 48 | } 49 | 50 | // FredConfig contains the necessary configuration for using the FredClient. 51 | // Requests can return either XML or JSON by setting the FileType parameter to xml or json. Note that the default value of FileType is xml. 52 | // The FredClient will only log to a local log file at the moment. This log file is set using the LogFile variable. 53 | // An APIKey can be retrieved at the following link: https://research.stlouisfed.org/docs/api/api_key.html 54 | type FredConfig struct { 55 | APIKey string 56 | FileType string 57 | LogFile string 58 | } 59 | 60 | // CreateFredClient creates an instance of a FRED client. 61 | func CreateFredClient(config FredConfig) (*FredClient, error) { 62 | 63 | if err := validateConfig(&config); err != nil { 64 | return nil, err 65 | } 66 | 67 | var f os.File 68 | var hasLogs bool 69 | 70 | if config.LogFile != "" { 71 | f, err := os.OpenFile(config.LogFile, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666) 72 | if err != nil { 73 | fmt.Println("Error opening log file: %v", err.Error()) 74 | return nil, err 75 | } 76 | log.SetOutput(f) 77 | hasLogs = true 78 | } 79 | 80 | return &FredClient{ 81 | APIKEY: config.APIKey, 82 | fileType: config.FileType, 83 | requestURL: apiURL, 84 | hasLogs: hasLogs, 85 | logFile: &f, 86 | }, nil 87 | } 88 | 89 | func validateConfig(config *FredConfig) error { 90 | 91 | if sameStr(config.APIKey, "") { 92 | return errors.New(errorNoAPIKey) 93 | } 94 | 95 | if config.FileType != "" && config.FileType != FileTypeXML && config.FileType != FileTypeJSON { 96 | return errors.New(errorIncorrectFileType) 97 | } 98 | 99 | return nil 100 | 101 | } 102 | 103 | // UpdateAPIKEY updates the API KEY for the client. 104 | func (f *FredClient) UpdateAPIKEY(APIKey string) error { 105 | 106 | if APIKey == "" || len(APIKey) != 32 { 107 | f.log(errorInvalidAPIKey) 108 | return errors.New(errorInvalidAPIKey) 109 | } 110 | 111 | f.APIKEY = APIKey 112 | 113 | url := strings.Split(f.requestURL, "?") 114 | 115 | f.requestURL = url[0] + "?api_key=" + APIKey 116 | 117 | return nil 118 | } 119 | 120 | // validateAPIKEY validates that an APIKEY exists. 121 | 122 | func (f *FredClient) validateAPIKEY() error { 123 | if sameStr(f.APIKEY, "") { 124 | return errors.New(errorNoAPIKey) 125 | } 126 | return nil 127 | } 128 | 129 | // callAPI creates the url and makes a GET request to the API. 130 | 131 | func (f *FredClient) callAPI(params map[string]interface{}, paramType string) (*http.Response, error) { 132 | 133 | url := f.formatUrl(f.requestURL, params, paramType) 134 | 135 | resp, err := http.Get(url) 136 | 137 | if err != nil { 138 | f.log("[callAPI] Error with HTTP Call: " + err.Error()) 139 | return nil, errors.New(errorLibraryFail) 140 | } 141 | 142 | return resp, nil 143 | } 144 | 145 | // decodeObj decodes the object in the format specified by ther user. 146 | 147 | func (f *FredClient) decodeObj(resp *http.Response, obj *FredType) (*FredType, error) { 148 | var err error 149 | 150 | switch f.fileType { 151 | case FileTypeJSON: 152 | err = json.NewDecoder(resp.Body).Decode(obj) 153 | 154 | if err != nil { 155 | f.log("[decodeObj] JSON ERROR: " + err.Error()) 156 | return nil, errors.New(errorLibraryFail) 157 | } 158 | case FileTypeXML: 159 | err = xml.NewDecoder(resp.Body).Decode(obj) 160 | 161 | if err != nil { 162 | f.log("[decodeObj] XML ERROR: " + err.Error()) 163 | return nil, errors.New(errorLibraryFail) 164 | } 165 | default: 166 | err = xml.NewDecoder(resp.Body).Decode(obj) 167 | 168 | if err != nil { 169 | f.log("[decodeObj] DEFAULT ERROR: " + err.Error()) 170 | return nil, errors.New(errorLibraryFail) 171 | } 172 | 173 | } 174 | 175 | return obj, nil 176 | 177 | } 178 | 179 | // operate runs the operation based parameter type. 180 | 181 | func (f *FredClient) operate(params map[string]interface{}, paramType string) (*FredType, error) { 182 | if err := f.validateAPIKEY(); err != nil { 183 | return nil, err 184 | } 185 | 186 | resp, err := f.callAPI(params, paramType) 187 | 188 | if err != nil { 189 | f.log("[operate] callAPI Error " + err.Error()) 190 | return nil, err 191 | } 192 | 193 | obj := &FredType{} 194 | 195 | obj, err = f.decodeObj(resp, obj) 196 | if err != nil { 197 | fmt.Printf("[operate] decodeObj Error " + err.Error()) 198 | return nil, err 199 | } 200 | 201 | return obj, nil 202 | } 203 | 204 | // formatUrl formats the url per the API specifications. 205 | func (f *FredClient) formatUrl(url string, params map[string]interface{}, paramType string) string { 206 | 207 | url += paramsLookup[paramType][paramLookupExt].(string) 208 | firstParam := true 209 | 210 | if len(params) != 0 { 211 | for paramKey, paramVal := range params { 212 | if !sameStr(paramKey, "") || !sameStr(paramVal.(string), "") { 213 | for _, param := range paramsLookup[paramType][paramLookupParams].([]string) { 214 | paramOp := "&" 215 | if sameStr(paramKey, param) { 216 | if firstParam { 217 | paramOp = "?" 218 | firstParam = false 219 | } 220 | 221 | val := "" 222 | kind := reflect.TypeOf(paramVal).Kind() 223 | 224 | switch kind { 225 | case reflect.String: 226 | val = paramVal.(string) 227 | val = strings.Replace(val, " ", "+", -1) 228 | break 229 | case reflect.Int: 230 | val = strconv.Itoa(paramVal.(int)) 231 | break 232 | case reflect.Bool: 233 | val = strconv.FormatBool(paramVal.(bool)) 234 | break 235 | } 236 | 237 | url += (paramOp + paramKey + "=" + val) 238 | } 239 | } 240 | } 241 | } 242 | url += "&" 243 | } else { 244 | url += "?" 245 | } 246 | 247 | fileType := "" 248 | if len(f.fileType) != 0 { 249 | fileType = f.fileType 250 | } 251 | 252 | url += "api_key=" + f.APIKEY + "&file_type=" + fileType 253 | 254 | return url 255 | } 256 | 257 | func sameStr(str1 string, str2 string) bool { 258 | if strings.Compare(str1, str2) == 0 { 259 | return true 260 | } 261 | return false 262 | } 263 | 264 | func (f *FredClient) log(logMes string) { 265 | if f.hasLogs { 266 | log.Println(logMes) 267 | } 268 | } 269 | 270 | func (f *FredClient) logError(method string, err error) { 271 | if f.hasLogs { 272 | log.Fatalf("METHOD: %v ERROR: %v", method, err.Error()) 273 | f.logFile.Close() 274 | } 275 | } 276 | -------------------------------------------------------------------------------- /series_toolkit_v1_test.go: -------------------------------------------------------------------------------- 1 | package fred_go_toolkit 2 | 3 | import ( 4 | "testing" 5 | 6 | . "github.com/smartystreets/goconvey/convey" 7 | ) 8 | 9 | func TestGetSeries(t *testing.T) { 10 | 11 | params := make(map[string]interface{}) 12 | 13 | params["series_id"] = "GNPCA" 14 | 15 | Convey("", t, func() { 16 | srs, err := xmlFredClient.GetSeries(params) 17 | So(err, ShouldBeNil) 18 | 19 | Convey("", func() { 20 | So(srs, ShouldNotBeNil) 21 | So(srs.Seriess[0].ID, ShouldBeGreaterThanOrEqualTo, "GNPCA") 22 | So(srs.Seriess[0].Title, ShouldBeGreaterThanOrEqualTo, "Real Gross National Product") 23 | 24 | }) 25 | }) 26 | 27 | Convey("", t, func() { 28 | srs, err := jsonFredClient.GetSeries(params) 29 | 30 | So(err, ShouldBeNil) 31 | Convey("", func() { 32 | So(srs, ShouldNotBeNil) 33 | So(srs.Seriess[0].ID, ShouldBeGreaterThanOrEqualTo, "GNPCA") 34 | So(srs.Seriess[0].Title, ShouldBeGreaterThanOrEqualTo, "Real Gross National Product") 35 | }) 36 | }) 37 | 38 | } 39 | 40 | func TestGetSeriesCategories(t *testing.T) { 41 | 42 | params := make(map[string]interface{}) 43 | 44 | params["series_id"] = "EXJPUS" 45 | 46 | Convey("", t, func() { 47 | srsCts, err := xmlFredClient.GetSeriesCategories(params) 48 | So(err, ShouldBeNil) 49 | 50 | Convey("", func() { 51 | So(srsCts, ShouldNotBeNil) 52 | So(len(srsCts.Categories), ShouldBeGreaterThanOrEqualTo, 2) 53 | So(srsCts.Categories[0].ID, ShouldBeGreaterThanOrEqualTo, 95) 54 | So(srsCts.Categories[0].Name, ShouldContainSubstring, "Monthly Rates") 55 | }) 56 | }) 57 | 58 | Convey("", t, func() { 59 | srsCts, err := jsonFredClient.GetSeriesCategories(params) 60 | 61 | So(err, ShouldBeNil) 62 | Convey("", func() { 63 | So(srsCts, ShouldNotBeNil) 64 | So(len(srsCts.Categories), ShouldBeGreaterThanOrEqualTo, 2) 65 | So(srsCts.Categories[0].ID, ShouldBeGreaterThanOrEqualTo, 95) 66 | So(srsCts.Categories[0].Name, ShouldContainSubstring, "Monthly Rates") 67 | }) 68 | }) 69 | 70 | } 71 | 72 | func TestGetSeriesObservations(t *testing.T) { 73 | 74 | params := make(map[string]interface{}) 75 | 76 | params["series_id"] = "GNPCA" 77 | 78 | Convey("", t, func() { 79 | srsObs, err := xmlFredClient.GetSeriesObservations(params) 80 | So(err, ShouldBeNil) 81 | 82 | Convey("", func() { 83 | So(srsObs, ShouldNotBeNil) 84 | So(len(srsObs.Observations), ShouldBeGreaterThanOrEqualTo, 84) 85 | 86 | }) 87 | }) 88 | 89 | Convey("", t, func() { 90 | srsObs, err := jsonFredClient.GetSeriesObservations(params) 91 | 92 | So(err, ShouldBeNil) 93 | Convey("", func() { 94 | So(srsObs, ShouldNotBeNil) 95 | So(len(srsObs.Observations), ShouldBeGreaterThanOrEqualTo, 84) 96 | 97 | }) 98 | }) 99 | 100 | } 101 | 102 | func TestGetSeriesRelease(t *testing.T) { 103 | 104 | params := make(map[string]interface{}) 105 | 106 | params["series_id"] = "IRA" 107 | 108 | Convey("", t, func() { 109 | srsRls, err := xmlFredClient.GetSeriesRelease(params) 110 | So(err, ShouldBeNil) 111 | 112 | Convey("", func() { 113 | So(srsRls, ShouldNotBeNil) 114 | So(len(srsRls.Releases), ShouldBeGreaterThanOrEqualTo, 1) 115 | So(srsRls.Releases[0].Name, ShouldContainSubstring, "H.6 Money Stock Measures") 116 | So(srsRls.Releases[0].ID, ShouldBeGreaterThanOrEqualTo, 21) 117 | 118 | }) 119 | }) 120 | 121 | Convey("", t, func() { 122 | srsRls, err := jsonFredClient.GetSeriesRelease(params) 123 | 124 | So(err, ShouldBeNil) 125 | Convey("", func() { 126 | So(srsRls, ShouldNotBeNil) 127 | So(len(srsRls.Releases), ShouldBeGreaterThanOrEqualTo, 1) 128 | So(srsRls.Releases[0].Name, ShouldContainSubstring, "H.6 Money Stock Measures") 129 | So(srsRls.Releases[0].ID, ShouldBeGreaterThanOrEqualTo, 21) 130 | }) 131 | }) 132 | 133 | } 134 | 135 | func TestGetSeriesSearch(t *testing.T) { 136 | 137 | params := make(map[string]interface{}) 138 | 139 | params["search_text"] = "monetary service index" 140 | 141 | Convey("", t, func() { 142 | srs, err := xmlFredClient.GetSeriesSearch(params) 143 | So(err, ShouldBeNil) 144 | 145 | Convey("", func() { 146 | So(srs, ShouldNotBeNil) 147 | So(len(srs.Seriess), ShouldBeGreaterThanOrEqualTo, 25) 148 | So(srs.Seriess[0].ID, ShouldContainSubstring, "MSIM2") 149 | So(srs.Seriess[0].Title, ShouldContainSubstring, "Monetary Services Index: M2 (preferred)") 150 | }) 151 | }) 152 | 153 | Convey("", t, func() { 154 | srs, err := jsonFredClient.GetSeriesSearch(params) 155 | 156 | So(err, ShouldBeNil) 157 | Convey("", func() { 158 | So(srs, ShouldNotBeNil) 159 | So(len(srs.Seriess), ShouldBeGreaterThanOrEqualTo, 25) 160 | So(srs.Seriess[0].ID, ShouldContainSubstring, "MSIM2") 161 | So(srs.Seriess[0].Title, ShouldContainSubstring, "Monetary Services Index: M2 (preferred)") 162 | }) 163 | }) 164 | 165 | } 166 | 167 | func TestGetSeriesSearchTags(t *testing.T) { 168 | 169 | params := make(map[string]interface{}) 170 | 171 | params["series_search_text"] = "monetary service index" 172 | 173 | Convey("", t, func() { 174 | tags, err := xmlFredClient.GetSeriesSearchTags(params) 175 | So(err, ShouldBeNil) 176 | 177 | Convey("", func() { 178 | So(tags, ShouldNotBeNil) 179 | So(len(tags.Tags), ShouldBeGreaterThanOrEqualTo, 18) 180 | 181 | }) 182 | }) 183 | 184 | Convey("", t, func() { 185 | tags, err := jsonFredClient.GetSeriesSearchTags(params) 186 | 187 | So(err, ShouldBeNil) 188 | Convey("", func() { 189 | So(tags, ShouldNotBeNil) 190 | So(len(tags.Tags), ShouldBeGreaterThanOrEqualTo, 18) 191 | 192 | }) 193 | }) 194 | 195 | } 196 | 197 | func TestGetSeriesSearchRelatedTags(t *testing.T) { 198 | 199 | params := make(map[string]interface{}) 200 | 201 | params["series_search_text"] = "mortgage rate" 202 | params["tag_names"] = "30-year;frb" 203 | 204 | Convey("", t, func() { 205 | tags, err := xmlFredClient.GetSeriesSearchRelatedTags(params) 206 | So(err, ShouldBeNil) 207 | 208 | Convey("", func() { 209 | So(tags, ShouldNotBeNil) 210 | So(len(tags.Tags), ShouldBeGreaterThanOrEqualTo, 10) 211 | So(tags.Tags[0].Name, ShouldContainSubstring, "conventional") 212 | }) 213 | }) 214 | 215 | Convey("", t, func() { 216 | tags, err := jsonFredClient.GetSeriesSearchRelatedTags(params) 217 | 218 | So(err, ShouldBeNil) 219 | Convey("", func() { 220 | So(tags, ShouldNotBeNil) 221 | So(len(tags.Tags), ShouldBeGreaterThanOrEqualTo, 10) 222 | So(tags.Tags[0].Name, ShouldContainSubstring, "conventional") 223 | }) 224 | }) 225 | 226 | } 227 | 228 | func TestGetSeriesTags(t *testing.T) { 229 | 230 | params := make(map[string]interface{}) 231 | 232 | params["series_id"] = "STLFSI" 233 | 234 | Convey("", t, func() { 235 | tags, err := xmlFredClient.GetSeriesTags(params) 236 | So(err, ShouldBeNil) 237 | 238 | Convey("", func() { 239 | So(tags, ShouldNotBeNil) 240 | So(len(tags.Tags), ShouldBeGreaterThanOrEqualTo, 8) 241 | So(tags.Tags[0].Name, ShouldContainSubstring, "nsa") 242 | 243 | }) 244 | }) 245 | 246 | Convey("", t, func() { 247 | tags, err := jsonFredClient.GetSeriesTags(params) 248 | 249 | So(err, ShouldBeNil) 250 | Convey("", func() { 251 | So(tags, ShouldNotBeNil) 252 | So(len(tags.Tags), ShouldBeGreaterThanOrEqualTo, 8) 253 | So(tags.Tags[0].Name, ShouldContainSubstring, "nsa") 254 | 255 | }) 256 | }) 257 | 258 | } 259 | 260 | func TestGetSeriesUpdates(t *testing.T) { 261 | 262 | params := make(map[string]interface{}) 263 | 264 | Convey("", t, func() { 265 | srs, err := xmlFredClient.GetSeriesUpdates(params) 266 | So(err, ShouldBeNil) 267 | 268 | Convey("", func() { 269 | So(srs, ShouldNotBeNil) 270 | }) 271 | }) 272 | 273 | Convey("", t, func() { 274 | srs, err := jsonFredClient.GetSeriesUpdates(params) 275 | 276 | So(err, ShouldBeNil) 277 | Convey("", func() { 278 | So(srs, ShouldNotBeNil) 279 | }) 280 | }) 281 | 282 | } 283 | 284 | func TestGetSeriesVintageDates(t *testing.T) { 285 | 286 | params := make(map[string]interface{}) 287 | 288 | params["series_id"] = "GNPCA" 289 | 290 | Convey("", t, func() { 291 | vds, err := xmlFredClient.GetSeriesVintageDates(params) 292 | So(err, ShouldBeNil) 293 | 294 | Convey("", func() { 295 | So(vds, ShouldNotBeNil) 296 | So(len(vds.VintageDates), ShouldBeGreaterThanOrEqualTo, 162) 297 | 298 | }) 299 | }) 300 | 301 | Convey("", t, func() { 302 | vds, err := jsonFredClient.GetSeriesVintageDates(params) 303 | 304 | So(err, ShouldBeNil) 305 | Convey("", func() { 306 | So(vds, ShouldNotBeNil) 307 | So(len(vds.VintageDates), ShouldBeGreaterThanOrEqualTo, 162) 308 | 309 | }) 310 | }) 311 | 312 | } 313 | --------------------------------------------------------------------------------