opendata-api 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 10b8aa1b9cba390f86ec972ce6c02667c5bf90c6
4
+ data.tar.gz: 757f9601ea75c14add7387494ecb594d5546072d
5
+ SHA512:
6
+ metadata.gz: 20305e4c5809641911c815f6b4a786a01c4ef185ce3358dc8617cf22632c17dee9c0ac360dc5341720a07d86e54646a0cab7c2ea0352f4aa39fed768238d6b27
7
+ data.tar.gz: 5bcedb4a342de52a1332ea2a9be5b879bca876306541e65bc90042c723b86e1da62b9cae6e8486e66537cb68e04a85b0aa7c5222c10038f8408d77a68f11076f
@@ -0,0 +1,2 @@
1
+ %��z��Ҫ*��NYX�V�J({���vI�‹�dQ*�N�{��CB��a݇`e� cn!�7_��r�(� |4�6����(�À~�x󈶲�I<�i�����C��/Ym ��#�-�������l_�.P!$~|���
2
+ �(��}�P,MzF�>��
Binary file
@@ -0,0 +1,80 @@
1
+ require 'net/http'
2
+ require 'net/https'
3
+ require 'uri'
4
+ require 'json'
5
+ require 'openssl'
6
+
7
+ require_relative './opendata-api/config'
8
+ require_relative './opendata-api/request'
9
+
10
+ module OpenDataAPI
11
+ def self.init(api_key)
12
+ raise "OpenData API Key required" if api_key.empty?
13
+
14
+ uri_base = URI.parse(OpenDataAPI::Constants::BASE_URL)
15
+ http_base = Net::HTTP.new(uri_base.host, uri_base.port)
16
+
17
+ # Store API Key as class variable
18
+ OpenDataAPIRequest.set_api_key(api_key)
19
+
20
+ # Store URI and HTTP base as class variables
21
+ OpenDataAPIRequest.set_uri_base(uri_base)
22
+ OpenDataAPIRequest.set_http_base(http_base)
23
+ end
24
+
25
+ def self.run(args)
26
+ api_requests = []
27
+ args.each do |arg|
28
+ case arg[:api_name]
29
+ when 'traffic_volume_counts'
30
+ # Request for Traffic Volume Counts API
31
+ uri_traffic_volume_counts_api = URI.parse(
32
+ OpenDataAPI::Constants::TrafficVolumeCountsAPI::BASE_URL +
33
+ OpenDataAPI::Constants::TrafficVolumeCountsAPI::API_ENDPOINT +
34
+ OpenDataAPI::Constants::TrafficVolumeCountsAPI.query_string_params(arg[:format], arg[:table], arg[:limit])
35
+ )
36
+ request_for_traffic_volume_counts_api = {
37
+ api_name: arg[:api_name],
38
+ api_instance: OpenDataAPIRequest.new(OpenDataAPIRequest.http_base, uri_traffic_volume_counts_api, OpenDataAPIRequest.api_key)
39
+ }
40
+ api_requests << request_for_traffic_volume_counts_api
41
+ when 'trip_planner'
42
+ # Request for Trip Planner API
43
+ uri_trip_planner_api = URI.parse(
44
+ OpenDataAPI::Constants::TripPlannerAPI::BASE_URL +
45
+ OpenDataAPI::Constants::TripPlannerAPI::API_ENDPOINT +
46
+ OpenDataAPI::Constants::TripPlannerAPI.query_string_params(arg[:format], arg[:coord_lat], arg[:coord_long], arg[:coord_radius])
47
+ )
48
+ request_for_trip_planner_api = {
49
+ api_name: arg[:api_name],
50
+ api_instance: OpenDataAPIRequest.new(OpenDataAPIRequest.http_base, uri_trip_planner_api, OpenDataAPIRequest.api_key)
51
+ }
52
+ api_requests << request_for_trip_planner_api
53
+ else
54
+ raise ArgumentError.new("Invalid API Name")
55
+ end
56
+ end
57
+
58
+ begin
59
+ # Start HTTP(S) Session to re-use across multiple requests
60
+ Net::HTTP.start(OpenDataAPIRequest.uri_base.hostname, OpenDataAPIRequest.uri_base.port,
61
+ :use_ssl => OpenDataAPIRequest.uri_base.scheme == 'https') do |http_session|
62
+ puts http_session.use_ssl? ? "OpenData API HTTPS Session" : "OpenData API HTTP Session"
63
+
64
+ http_session.verify_mode = OpenSSL::SSL::VERIFY_NONE
65
+ http_session.read_timeout = OpenDataAPI::Constants::READ_TIMEOUT
66
+
67
+ response = {}
68
+ # Request #1 to each API (i.e. Traffic Volume Counts API, Trip Planner API, etc)
69
+ api_requests.each do |request|
70
+ _res = request[:api_instance].fetch(http_session, request[:api_instance].request, OpenDataAPI::Constants::REQUEST_LIMIT)
71
+ # puts JSON.pretty_generate(JSON.parse(_res.body))
72
+ response[request[:api_name].to_sym] = _res.body
73
+ end
74
+ response
75
+ end
76
+ rescue Exception => e
77
+ raise "Exception opening TCP connection: #{e}"
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,29 @@
1
+ module OpenDataAPI
2
+ module Constants
3
+ # Transport for NSW (TfNSW) Open Data API
4
+ BASE_URL = 'https://api.transport.nsw.gov.au'
5
+ READ_TIMEOUT = 500
6
+ REQUEST_LIMIT = 3
7
+
8
+ # Traffic Volume Counts API
9
+ module TrafficVolumeCountsAPI
10
+ BASE_URL = 'https://api.transport.nsw.gov.au/v1'
11
+ API_ENDPOINT = '/roads/spatial'
12
+ PARAM_FORMAT = 'geojson'
13
+ def self.query_string_params(format, table, limit)
14
+ "?format=#{format}&q=select%20*%20from%20#{table}%20limit%20#{limit}%20"
15
+ end
16
+ end
17
+
18
+ # Trip Planner API
19
+ module TripPlannerAPI
20
+ BASE_URL = 'https://api.np.transport.nsw.gov.au/v1'
21
+ API_ENDPOINT = '/tp/coord'
22
+ PARAM_FORMAT = 'rapidJSON'
23
+ def self.query_string_params(format, coord_lat = '-33.8688', coord_long = '151.2093', coord_radius = '1000')
24
+ "?outputFormat=#{format}&coord=#{coord_long}%3A#{coord_lat}%3AEPSG%3A4326&inclFilter=1&" +
25
+ "type_1=GIS_POINT&radius_1=#{coord_radius}&PoisOnMapMacro=true&version=10.2.1.42"
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,83 @@
1
+ class OpenDataAPIRequest
2
+ attr_reader :request, :api_key
3
+
4
+ @@api_key = ''
5
+ @@uri_base = ''
6
+ @@http_base = ''
7
+
8
+ def initialize(http, uri, api_key)
9
+ @http = http
10
+ @uri = uri
11
+ @api_key = api_key
12
+ @request = self.generate_request_for_api(uri, api_key)
13
+ end
14
+
15
+ def self.api_key()
16
+ @@api_key
17
+ end
18
+
19
+ def self.set_api_key(api_key)
20
+ @@api_key = api_key
21
+ end
22
+
23
+ def self.uri_base()
24
+ @@uri_base
25
+ end
26
+
27
+ def self.set_uri_base(uri_base)
28
+ @@uri_base = uri_base
29
+ end
30
+
31
+ def self.http_base()
32
+ @@http_base
33
+ end
34
+
35
+ def self.set_http_base(http_base)
36
+ @@http_base = http_base
37
+ end
38
+
39
+ def generate_request_for_api(uri, api_key)
40
+ # puts "Generating Request for URI: #{uri.to_s}\nURI Host/Port: #{uri.host}, #{uri.port}"
41
+ request = Net::HTTP::Get.new(uri)
42
+
43
+ request.initialize_http_header({
44
+ "Accept" => "application/json",
45
+ "Content-Type" => "application/json",
46
+ "Authorization" => "apikey #{api_key}",
47
+ "User-Agent" => "ruby/net::http"
48
+ })
49
+ # puts "Generated Request with Headers: #{request.to_hash.inspect}"
50
+ request
51
+ end
52
+
53
+ # Fetch specific request
54
+ def fetch(http_session, request, limit = 10)
55
+ raise "Too many HTTP redirects" if limit == 0
56
+ response = http_session.request(request) # Net::HTTPResponse object
57
+
58
+ case response
59
+ when Net::HTTPSuccess then
60
+ if response['content-type'] =~ /json/i
61
+ # puts """Response:\n\t
62
+ # Code: #{response.code}\n\t
63
+ # Message: #{response.message}\n\t
64
+ # Class: #{response.class.name}\n\t
65
+ # Headers: \n #{JSON.pretty_generate(response.to_hash)}
66
+ # Body: \n #{JSON.pretty_generate(JSON.parse(response.body))}
67
+ # """
68
+ # puts "Response code #{response.code} for request to: #{request.uri}"
69
+ response
70
+ else
71
+ raise Exception.new("Only JSON response supported")
72
+ end
73
+ when Net::HTTPRedirection then
74
+ location = response['location']
75
+ # puts Net::HTTP.get(URI.parse(location))
76
+ warn "Redirected to #{location}"
77
+ request = Net::HTTP::Get.new(location)
78
+ self.fetch(http_session, request, limit - 1)
79
+ else
80
+ raise Exception.new("Unsupported HTTP Response #{response.inspect}")
81
+ end
82
+ end
83
+ end
metadata ADDED
@@ -0,0 +1,68 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: opendata-api
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Luke Schoen
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain:
11
+ - |
12
+ -----BEGIN CERTIFICATE-----
13
+ MIIDdDCCAlygAwIBAgIBATANBgkqhkiG9w0BAQUFADBAMRIwEAYDVQQDDAlsdGZz
14
+ Y2hvZW4xFTATBgoJkiaJk/IsZAEZFgVnbWFpbDETMBEGCgmSJomT8ixkARkWA2Nv
15
+ bTAeFw0xNzEyMjIwNTUxMTVaFw0xODEyMjIwNTUxMTVaMEAxEjAQBgNVBAMMCWx0
16
+ ZnNjaG9lbjEVMBMGCgmSJomT8ixkARkWBWdtYWlsMRMwEQYKCZImiZPyLGQBGRYD
17
+ Y29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvvj7phLRWC1L2w4j
18
+ ZVkfFvZXKo/07aDPvch+oHiHfTwaCnxVrSLAKJmx2TjVrJlVkJfIA9hOhHksWvzJ
19
+ jihVNhscy1O/6zTP62peu0BVg7PFEGtXqljMSSEKuJOfq33vCp0dVXBZ6mOYebCE
20
+ 0qv5XRNi4pFHLcdccOu3Kt5KKlXPt9QaeLIEvbe6PSLCoP3iuchgVsX0uV/av8U/
21
+ l983GW73fdiHaSaIAlzOgBlNEEYKk39DE/5JkT7fIQV++KGVcQegQG5xbbwKzXNL
22
+ cs+FDku1z6iTx5s+dPe5P3vC58YW+JUc+cRLotQDvVwL4SQi/UT4Bpmm20Aa8n6N
23
+ AAI1KwIDAQABo3kwdzAJBgNVHRMEAjAAMAsGA1UdDwQEAwIEsDAdBgNVHQ4EFgQU
24
+ Na7MnwCNDJXxjxzj4YnsfFJh9mYwHgYDVR0RBBcwFYETbHRmc2Nob2VuQGdtYWls
25
+ LmNvbTAeBgNVHRIEFzAVgRNsdGZzY2hvZW5AZ21haWwuY29tMA0GCSqGSIb3DQEB
26
+ BQUAA4IBAQBfQvJI8uICi7Q0aEecxTI69lYW9HWWpkfkcohriNoC2t0DipKUB6vl
27
+ U12RzmfUctLPDOymMechUgu22FneFFSP0zN1ajehbWDUPNTw/KKW8eL9rsQtbs/4
28
+ hvd0fQGfAfRBGs2S6OJ78bD/R9elp1nTz0C/hmuKc88DNnVOIizBb/40mjH8FgSO
29
+ U6WBxl3dGZ/mzbvLKjVpRoG0P1CdhDXkHScpBbAvfLwm2W1wsB2EQckKKIfMWflp
30
+ ewIPdCDEuyq9+uvAyBA8yqLcFO22IV+tO5sVQlK176dm/YMu/4XahSgWWabxb3M5
31
+ i1pV9bobg0pMrHjsh9BCO8rI+hKrNudb
32
+ -----END CERTIFICATE-----
33
+ date: 2017-12-22 00:00:00.000000000 Z
34
+ dependencies: []
35
+ description: Wrapper for Transport for New South Wales (TfNSW) Open Data APIs
36
+ email: ltfschoen@gmail.com
37
+ executables: []
38
+ extensions: []
39
+ extra_rdoc_files: []
40
+ files:
41
+ - lib/opendata-api.rb
42
+ - lib/opendata-api/config.rb
43
+ - lib/opendata-api/request.rb
44
+ homepage: https://github.com/ltfschoen/opendata-api
45
+ licenses:
46
+ - MIT
47
+ metadata: {}
48
+ post_install_message:
49
+ rdoc_options: []
50
+ require_paths:
51
+ - lib
52
+ required_ruby_version: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: 2.1.0
57
+ required_rubygems_version: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: 2.2.0
62
+ requirements: []
63
+ rubyforge_project:
64
+ rubygems_version: 2.6.14
65
+ signing_key:
66
+ specification_version: 4
67
+ summary: OpenData API
68
+ test_files: []
Binary file