Neat Samples: F#, Freebase and DGML

Jomo Fisher – I recently posted about the freebase web service here. This sample reads biological classifications and renders them in DGML. The result is a huge graph, here’s a little piece of it:

animals

Code Snippet

  1. // FreebaseDgml.fsx
  2. // Example of reading from freebase.com in F# using DataContract and JSON serializer and write the result
  3. // in .dgml format.
  4. // by Jomo Fisher
  5. #r "System.Runtime.Serialization"
  6. #r "System.ServiceModel.Web"
  7. #r "System.Web"
  8. #r "System.Xml"
  9.   
  10. open System
  11. open System.IO
  12. open System.Net
  13. open System.Text
  14. open System.Web
  15. open System.Collections.Generic
  16. open System.Security.Authentication
  17. open System.Runtime.Serialization
  18.   
  19. [<DataContract>]
  20. type Result<'TResult> = {
  21.     [<field: DataMember(Name="code") >]
  22.     Code:string
  23.     [<field: DataMember(Name="result") >]
  24.     Result:'TResult
  25.     [<field: DataMember(Name="message") >]
  26.     Message:string
  27.     }
  28.  
  29. [<DataContract>]
  30. type Classification = {
  31.     [<field: DataMember(Name="name") >]
  32.     Name:string
  33.     [<field: DataMember(Name="higher_classification") >]
  34.     HigherClassification:string
  35.     [<field: DataMember(Name="lower_classifications") >]
  36.     LowerClassifications:string array
  37.     }
  38.   
  39. let Query<'T>(query:string) : 'T =
  40.     let query = query.Replace("'","\"")
  41.     let queryUrl = sprintf "https://api.freebase.com/api/service/mqlread?query=%s" "{\"query\":"+query+"}"
  42.   
  43.     let request : HttpWebRequest = downcast WebRequest.Create(queryUrl)
  44.     request.Method <- "GET"
  45.     request.ContentType <- "application/x-www-form-urlencoded"
  46.   
  47.     let response = request.GetResponse()
  48.   
  49.     let result =
  50.         try
  51.             use reader = new StreamReader(response.GetResponseStream())
  52.             reader.ReadToEnd();
  53.         finally
  54.             response.Close()
  55.   
  56.     let data = Encoding.Unicode.GetBytes(result);
  57.     let stream = new MemoryStream()
  58.     stream.Write(data, 0, data.Length);
  59.     stream.Position <- 0L
  60.      
  61.     let ser = Json.DataContractJsonSerializer(typeof<Result<'T>>)
  62.     let result = ser.ReadObject(stream) :?> Result<'T>
  63.     if result.Code<>"/api/status/ok" then
  64.         raise (InvalidOperationException(result.Message))
  65.     else
  66.         result.Result
  67.   
  68. let classifications = Query<Classification array>("[{'type':'/biology/organism_classification','name':null,'higher_classification':null,'lower_classifications':[]}]")
  69.  
  70.  
  71. let sb = StringBuilder()
  72.   
  73. sb.Append("<DirectedGraph xmlns='https://schemas.microsoft.com/vs/2009/dgml'>\n") |> ignore
  74.  
  75. sb.Append(" <Links>\n") |> ignore
  76. for classification in classifications do
  77.     if classification.LowerClassifications<>null then
  78.         for lower in classification.LowerClassifications do
  79.             sb.AppendFormat("  <Link Source=\"{0}\" Target=\"{1}\"/>\n",classification.Name,lower) |> ignore
  80. sb.Append(" </Links>\n") |> ignore
  81. sb.Append("</DirectedGraph>\n") |> ignore
  82.  
  83. printfn "%s" (sb.ToString()) // Paste the results of this into a .dgml file.           

 

This posting is provided "AS IS" with no warranties, and confers no rights.