Upgrade from 2.0 to API 4.0

Even after updating to API 4.0 key, my application is still not working.

Dim client As New FlightXML2SoapClient() ← Working
Dim r As ArrayOfAirlineFlightScheduleStruct ← Working

Two above declarations are working fine but the below code is causing the error. "Connecting to the server machine ‘flightxml.flightaware.com’ failed.

r = client.AirlineFlightSchedules(iEPOCTIME_Start, iEPOCTIME_End, strDepartAirportICAO, strArrivalAirportICAO, strAirlineICAO, strAirlineFlightNumber, 10, 0)

Could you please help me fix the error?

Try updating flightxml.flightaware.com to https://aeroapi.flightaware.com/aeroapi

Be advised that your code will fundamentally need changes to use the new functions of AeroAPI v4, since the v2 functions are completely different. Simply changing the API key to v4 and changing the server hostname won’t be the only things you need to do in order to upgrade. Also note that v4 doesn’t support SOAP, so you will need to migrate to a REST interface.

As you explained, changing to 4.0 key doesn’t resolve the issue. :frowning: Is there a sample code using 4.0 to download the flight schedules?

The address must be built in the class FlightXML2SoapClient(). There is no place to change the path to https://aeroapi.flightaware.com/aeroapi. Is there a class I can use for downloading flight schedules??

Airline Schedules in v4 is documented here: AeroAPI Developer Portal - FlightAware

We don’t provide any C# examples or libraries for interfacing with v4 at this time, however REST services are generally more easily interfaced without the need for custom libraries to serialize/deserialize responses. For a generic example, try looking at Tutorial: Make HTTP requests in a .NET console app using C# | Microsoft Docs

I will take a look. Thank you.

Hi, I’m still trying to figure out the way to retrieve the data. Could you please a sample code to use " GET /schedules/{date_start}/{date_end}"?

I get the unauthorized access error message even though I’m using the correct API key. I guess I’m not using it in a correct way.

Could you please show me the sample codes to call REST API with keys and return data? The sample codes don’t have to be VB.NET, but VB.net or C# are preferred.

Try

            Dim Uri As String
            Dim param As String
            Dim statuscode As HttpStatusCode
            Dim dataStream As Stream = Nothing
            Dim StreamReader As StreamReader
            Dim ResponseFromServer As String

            Uri = "https://aeroapi.flightaware.com/aeroapi"
            param = "x-apikey=" & mySystemSettings.aeroapikey

            Try
                Dim request As WebRequest = WebRequest.Create(Uri)
                request.Timeout = 120000
                request.Method = "POST"

                Dim byteArray As Byte() = System.Text.Encoding.UTF8.GetBytes(param)

                request.ContentType = "application/x-www-form-urlencoded"
                request.ContentLength = byteArray.Length
                dataStream = request.GetRequestStream()
                dataStream.Write(byteArray, 0, byteArray.Length)
                dataStream.Close()

                Dim WebResponse As WebResponse = request.GetResponse() <------ Error here "The remote server returned an error: (401) Unauthorized."

                dataStream = WebResponse.GetResponseStream()
                StreamReader = New StreamReader(dataStream)
                ResponseFromServer = StreamReader.ReadToEnd()
                dataStream.Close()
                WebResponse.Close()
                statuscode = HttpStatusCode.OK



                'convert the response to a dictionary   
                Dim Jss As New JavaScriptSerializer()
                Dim Dict As Dictionary(Of String, String) = Jss.
            Deserialize(Of Dictionary(Of String, String))(ResponseFromServer)

                'return value assigned to the key
                Dim Result = Dict("response")

                'Console.WriteLine("Response Code: " & Result)


            Catch ex As WebException
                If ex.Response IsNot Nothing Then
                    dataStream = ex.Response.GetResponseStream()
                    Dim reader As New StreamReader(dataStream)
                    statuscode = DirectCast(ex.Response, HttpWebResponse).StatusCode
                    ResponseFromServer = ex.Message
                Else
                    Dim resp As String = ""
                    statuscode = HttpStatusCode.ExpectationFailed
                    ResponseFromServer = "Unknown Error"
                End If

            Catch ex As Exception
                statuscode = HttpStatusCode.ExpectationFailed
                ResponseFromServer = "Unknown Error"
            End Try

We have a C# code example for AeroAPI on the product page under the AeroAPI Code Snippets section:

Otherwise there’s a couple issues that will prevent the code as presented from working. The first one is the source of the unauthorized error, but if the rest are left more unexpected errors may occur during the request phase.

  1. The api key should be provided in the request header, not a request parameter
  2. The resource is expects a GET request method, but the code is using POST
  3. Only the API’s base URI has been defined, this will need to be combined with the resource to make the request. Maybe use a pattern like the following to build the resource address:
api_base = "https://aeroapi.flightaware.com/aeroapi"
date_start = "2022-05-25"
date_end = "2022-05-26"
api_endpoint = "/schedules/" & date_start & "/" & date_end
uri = api_base & api_endpoint

Also, it’s worth noting that WebRequest has recently been marked as obsolete in .NET and is no longer recommended for new development work.

Thank you. I successfully called the service to download data.

I now have another question about the API. What is the equivalent to the old function “AirlineFlightSchedules”? I’m trying to get data filtered by date start, date end, arrival airport, airline and flight number. Could you please show me an example of these parameters? Also, do you have any sandbox for development? I can see you are charging me of using API calls during my development. (It is not a big deal. I’m just wondering)

The GET /schedules/{date_start}/{date_end} is the updated version of AirlineFlightSchedules. The Documentation Portal includes all the additional query-string parameters that should allow for all the functionality you’re familiar with from the old version.

Additionally, even if you don’t provide your API key to the interactive documents you can still populate the fields and use the TRY button to generate an example curl command so you can have complete example URIs to reference in development. The full response schema is also documented too.

Thank you. I’m almost set. Do you have an example of a script to parse the return result too?

I finished developing a new module to retrieve flight data and parse. Thank you for your support.

1 Like

Hi Dogrock, the c# code example you provide a link to does not work. Would you be able to provide a working code sample please?

It looks like the browser formatting is breaking the example on copy-paste, while that gets fixed there’s a more “raw” version for the same example that should work:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading.Tasks;

namespace AeroApi4Sample
{
    public class FlightsResult
    {
        public List<Flight> Flights { get; set; }
    }

    public class Flight
    {
        public string Ident { get; set; }

        [JsonPropertyName("fa_flight_id")]
        public string FaFlightId { get; set; }

        [JsonPropertyName("scheduled_out")]
        public DateTime ScheduledOut { get; set; }
        
        [JsonPropertyName("actual_out")]
        public DateTime? ActualOut { get; set; }
    }

    public class Program
    {
        static void Main( string[] args )
        {
            Console.Write( "API Key: " );
            var strApiKey = Console.ReadLine();

            Console.Write( "Ident to look up (e.g., UAL47): " );
            var strIdentToLookUp = Console.ReadLine();

            var flights = GetFlights( strApiKey, strIdentToLookUp ).Result;
            
            if( flights == null )
            {
                return;
            }

            var nextFlightToDepart = flights.Where( 
                f => f.ActualOut == null 
                ).OrderBy( f => f.ScheduledOut ).First();

            Console.WriteLine( 
                string.Format( 
                    "Next departure of {0} is {1} at {2}", 
                    strIdentToLookUp,
                    nextFlightToDepart.FaFlightId, 
                    nextFlightToDepart.ScheduledOut 
                    ) 
                );
        }

        private static async Task<List<Flight>> GetFlights( string strApiKey, string strIdent )
        {
            using( var client = new HttpClient() )
            {
                client.DefaultRequestHeaders.Accept.Clear();
                client.DefaultRequestHeaders.Accept.Add(
                    new MediaTypeWithQualityHeaderValue( "application/json" )
                    );
                client.DefaultRequestHeaders.Add( 
                    "x-apikey", 
                    strApiKey 
                    );

                FlightsResult flightResult = null;
                var response = await client.GetAsync(
                    "https://aeroapi.flightaware.com/aeroapi/flights/" + strIdent
                    );
                var contentStream = await response.Content.ReadAsStreamAsync();

                if( response.IsSuccessStatusCode )
                {
                    flightResult = await JsonSerializer.DeserializeAsync<FlightsResult>(
                        contentStream, 
                        new JsonSerializerOptions 
                        {
                            PropertyNameCaseInsensitive = true
                        }
                        );
                }
                else
                {
                    Console.Error.WriteLine( "API call failed: " + response );
                    return null;
                }

                return flightResult.Flights;
            }
        }
    }
}