The field 'Commons' not defined in freebase provider for fsharp - f#

I'm having some problems with the freebase api. I have managed to put a key to the freebase provider so I don't see any 403 errors, relating quota restrictions. But since I used a google api key, commons is not being recognized when I hit "alt + enter". But while I'm writing, the provider manages to show me data.
[<Literal>]
let FreebaseApiKey = "AIzaSyCOn15-T31Ls"
type FreebaseDataWithKey = FreebaseDataProvider<Key=FreebaseApiKey>
let dataWithKey = FreebaseDataWithKey.GetDataContext()
let travelDestinations = dataWithKey.Commons.Travel.``Travel destinations``
let all = travelDestinations |> Seq.toList
let first = all.Head.Name
As you can see, I have access to Travel Destinations, so the provider shows me data correctly but when I execute it:
Script.fsx(17,38): error FS0039: The field, constructor or member 'Commons' is not defined
The weird thing is that if I delete the google key, and use the provider, this error does not happen. Any clues?

In a provider like freebase, we need to do things asynchronously, and that unfortunately causes the error reporting not to be very good (see https://github.com/fsharp/fsharp/issues/280)
What's probably happening is that freebase is returning errors due to the api key not being right or something similar, and does errors are not surfacing, as the toplevel objects are already cached. You can either look under Fiddler to see the json being returned, use data.DataContext.SendingQuery or data.DataContext.SendingRequest, or clean the cache by deleting the FreebaseSchema and FreebaseRuntime folders under your temporary internet files system folder.
We recently tried to change this to cause errors to surface by generating the toplevel types synchronously, but that caused other problems (https://github.com/fsharp/FSharp.Data/issues/522)

Related

UI5-Application: Call to functionimport works ONLY in WebIDE but fails everywhere else

We are developing a custom UI5 application.
It is developed in the WebIDE, and therefore deployed as a BSP.
When we use the underlying model for calls ( currently 3, no CRUD ), we chose the path of using ONLY functionimports to communicate with the backend.
All of them work with the POST method.
And all of them work ONLY inside the WebIDE.
Once, I access the BSP URL otherwise, we get HTTP 500 error with "error while requesting the ressource.
We already created links, to enable special portfowarding, no result.
Let's stick to my URL from the BSP first.
I paste it into my 3 browsers: 500.
We also created a special non dialogue-user with proper roles and permissions, and in the SICF tree we assigned it .
Again, when calling from inside the WebIDE, the functionimport-calls work, otherwise not.
Error-Logs are empty.
Dumps do not happen.
ST05 trace shows where 500 is passed, deeply inside the HTTP framework, yet no chance to spot the code location, neither a breaktpoint.
In SICF logon-settings we have:
Types all, also flagged "all", SAML: inherited from parent node, sec-sessions Not limited, fix user and pw, sec: Standard, auth:Standard Sap user.
The gui-options contain ONLY one flag: ~CHECK_CSRF_TOKEN 0.
In my client I use :
Where the model is initialized as :
function initModelV2() {
var sUrl = "/sap/opu/odata/sap/Z_this_is_a_company_secret_service/";
var oModel = new sap.ui.model.odata.v2.ODataModel(sUrl);
sap.ui.getCore().setModel(oModel);
}
What else can I do to get "at least closer" to the reason, WHY ?
I could solve it, and believe it or not, sometimes simple logic helps.
I debugged the backend of CL_HTTP_RESPONSE, and once I saw, GET_STATUS, I thought to look for SET_STATUS.
There it was:
this.rModel.setHeaders( {"X-Requested-With" : "X" } );
Was missing.
Though I set it in the manifest of my model, it was not passed.
Once set in the code, it worked.
I wonder, why it is not accepted in manifest.
I have an assumption.
1st: I have this in my manifest ( yellow arrow shows, where i HAD it set up before):
But I also have an instantiation in my code, in servicebindings.js with this code
Can it be, that, in the end, I have accidently created 2 models ?

F# SqlProvider - how to access stored procedure results?

I am using SQLProvider from NuGet (https://www.nuget.org/packages/SQLProvider/ v1.1.42) in an F# project to access our MSSQL database.
I am referring to the sample code from here, https://fsprojects.github.io/SQLProvider/core/programmability.html and also the source code tests on GitHub, https://github.com/fsprojects/SQLProvider/blob/master/tests/SqlProvider.Tests/scripts/MySqlTests.fsx.
#r #"....\packages\SQLProvider.1.1.42\lib\net451\FSharp.Data.SqlProvider.dll"
#r #"....\System.Data.Linq.dll"
open System
open FSharp.Data.Sql
open FSharp.Data.Sql.Common
open System.Data.Linq
type SeriesResult = { .. fields .. }
[<Literal>]
let ConnectionString = #"connStr"
type Sql = SqlDataProvider<
ConnectionString = ConnectionString,
DatabaseVendor = Common.DatabaseProviderTypes.MSSQLSERVER>
let db = Sql.GetDataContext()
let test =
[
for f in db.Procedures.MyStoredProcedure.Invoke("param").ResultSet do
yield f.MapTo<SeriesResult>()
]
I need to access results from the call to MyStoredProcedure, but ResultSet errors with error FS0039: The field, constructor or member 'ResultSet' is not defined". I also get this for ColumnValues, and on MapTo (presumably because the type is unknown).
Is there an additional library I should be referencing?
I have: FSharp.Core, FSharp.Data, FSharp.Data.SqlProvider, mscorelib, System, System.Core, System.Data, System.Data.Linq, System.Xml.Linq
Thanks!
(wanted to tag with SQLProvider - but can't!)
One possible reason for this is that the intelli-sense thread probably timed out waiting for a response from the SQL provider.
The stored procs and the set of types to carry the result ResultSet are computed lazily (when you type the .). This is good in one way as it means the provider doesn't introspect the entire database on instantiation, pulling in lots of stuff you're probably not going to use. However it does have the side effect, of needing to do a non-trivial amount of work in the . completion on the first request, we cache the result after that. I believe Microsoft have a metric that says any intelli-sense work should complete in 250ms, but what the actual thread timeout is I'm not sure. With a language like C# and F# hitting a response target of 250ms can be a big ask on large solutions, but throw a database in the mix (even a small local database) this becomes a very hard target to hit.
Quite why it didn't recover and try again until you added the references, will only be known to Visual Studio; Usually however just closing and re-opening the file is enough. In rare cases unload the project from the solution and reload.

F# WsdlService type provider proxy

I am following the MSDN tutorial for the WsdlService type provider found here. When I run it at home, it works as expected. When I write the same code at work, I am getting a design time exception:
The type provider
'Microsoft.FSharp.Data.TypeProviders.DesignTime.DataProviders'
reported an error: Error: Cannot obtain Metadata from
http://msrmaps.com/TerraService2.asmx?WSDL
Work does use a proxy and I have to alter the web.config to use a default proxy when consuming WSDL from a C# project in VS2012. When I looked at the parameters for the type provider, I don't see a mention about a proxy. Does anyone have any suggestions?
Thanks in advance.
Expanding on Tomas's answer...
This is a common pattern in the built-in type providers today:
At design time, if you need any kind of non-default configuration (e.g. credentials, proxy config, ...), the type provider will not work. You need to download some schema file locally (e.g. DB schema file, ODATA $metadata file, WSDL schema file...), and point the type provider at that, usually by passing LocalSchemaFile="...", ForceUpdate=false in the static constructor. This feeds the TP all the info it needs to generate the types.
Then, you set all of your non-default config programmatically on the objects that are created for you, so that everything works at runtime.
Here's another example of essentially the same issue, where this pattern is used to set credentials.
In the case of WSDL, below is the programmatic approach to set the proxy after-the-fact (i.e. step #2). Cribbed entirely from this answer, which is exactly what you want, in C#. You'll probably need to play with this a bit to make it work for you.
#r "System.ServiceModel.dll"
#r "FSharp.Data.TypeProviders.dll"
open Microsoft.FSharp.Data.TypeProviders
type Terra = WsdlService< ServiceUri="N/A", ForceUpdate = false,
LocalSchemaFile = #"C:\temp\terra.wsdlschema">
let terra = Terra.GetTerraServiceSoap()
let binding = terra.DataContext.Endpoint.Binding :?> System.ServiceModel.BasicHttpBinding
binding.ProxyAddress <- System.Uri("http://127.0.0.1:8888")
binding.BypassProxyOnLocal <- false
binding.UseDefaultWebProxy <- false
terra.GetPlaceList("New York", 1, false)
I'm not connecting through a proxy, so I have no way of actually testing this, but I think you should be able to use local WSDL file to load the type provider in the designer.
Try downloading the WSDL schema (from http://msrmaps.com/TerraService2.asmx?WSDL) and saving that to a local file (such as C:\temp\terra.wsdlschema). Then you should be able to write:
#r "System.ServiceModel.dll"
#r "FSharp.Data.TypeProviders.dll"
open Microsoft.FSharp.Data.TypeProviders
type Terra = WsdlService< ServiceUri="N/A", ForceUpdate = false,
LocalSchemaFile = #"C:\temp\terra.wsdlschema">
let terra = Terra.GetTerraServiceSoap()
terra.GetPlaceList("New York", 1, false)
The ServiceUri parameter seems to be required, but it should be ignored if you add ForceUpdate=false. It should only require the cached WSDL file. I'm not entirely sure how to configure the runtime to use your config file setting, but I'm sure this can be done in some way (either it just works or you can pass something to the GetTerraServiceSoap method).
Sadly, the type provider does not statically know (at design time) where to look for the config file, so it ignores it.

Windev Quickbooks SDK OpenConnection2

I've been trying to find a way to connect my Windev application using the Quickbooks SDK.
I wish to connect to my local QB instance using the qbXML API.
I've been able to get a reference to the library using :
myconnection = new object Automation "QBXMLRP2.RequestProcessor"
However, when it comes to the OpenConnection2 method, I only get errors. Either "missing parameter" or "invalid parameter". I am aware that I should pass a "localQBD" type to the function, but I have not found out how to reference it. The following represents my invalid script.
myconnection>>OpenConnection2("","My Test App", localQBD)
How can I achieve a connection to QB through Windev?
After much searching, I have found that I was on the right path using the automation variable type.
However, I have yet to find how to reference the constants provided by the library. Instead, I declare them beforehand like so
CONSTANT
omSingleUser = 0
omMultiUser = 1
omDontCare = 2
qbStopOnError = 0
qbContinueOnError = 1
ctLocalQBD = 1
ctLocalQBDLaunchUI = 3
FIN
Which gives us this working example
myconnection = new object Automation "QBXMLRP2.RequestProcessor"
ticket = myconnection>>BeginSession("",::omDontCare)
XMLresponse = myconnection>>ProcessRequest(ticket,XMLrequest)
myconnection>>EndSession(ticket)
myconnection>>CloseConnection()
delete myconnection
A huge thanks goes to Frank Cazabon for showing me the proper constant values.
I have a complete external WinDev component that accesses QB and a helper program that can generate the WinDev calls in the correct order with the correct spelling and provides an OSR for all the QuickBooks fields and modules.
I have a similar product for the Clarion language and am in the final stages of the WinDev version. Contact me if you are interested. qbsnap at wybatap.com

REXML :: RuntimeError (entity expansion has grown too large)

After upgrading to Ruby-1.9.3-p392 today, REXML throws a Runtime Error when attempting to retrieve an XML response over a certain size - everything works fine and no error is thrown when receiving under 25 XML records, but once a certain XML response length threshold is reached, I get this error:
Error occurred while parsing request parameters.
Contents:
RuntimeError (entity expansion has grown too large):
/.rvm/rubies/ruby-1.9.3-p392/lib/ruby/1.9.1/rexml/text.rb:387:in `block in unnormalize'
I realize this was changed in the most recent Ruby version:
http://www.ruby-lang.org/en/news/2013/02/22/rexml-dos-2013-02-22/
As a quick fix, I've changed the size of REXML::Document.entity_expansion_text_limit to a larger number and the error goes away.
Is there a less risky solution?
This issue is generated when you send too much content as XML response.
To fix this issue : You need to restrict the data(< 10k) in the individual node (Instead of sending the whole data, show truncated data and provide a seperate link to view full content)
The error is being raised from the below file :
ruby-2.1.2/lib/ruby/2.1.0/rexml/text.rb
# Unescapes all possible entities
def Text::unnormalize( string, doctype=nil, filter=nil, illegal=nil )
sum = 0
string.gsub( /\r\n?/, "\n" ).gsub( REFERENCE ) {
s = Text.expand($&, doctype, filter)
if sum + s.bytesize > Security.entity_expansion_text_limit
raise "entity expansion has grown too large"
else
sum += s.bytesize
end
s
}
end
The limit ruby-2.1.2/lib/ruby/2.1.0/rexml/text.rb defaults to 10240 which means 10k data per node.
REXML already defaults to only allow 10000 entity substitutions per document, so the maximum amount of text that can be generated by entity substitution will be around 98 megabytes. (Refer https://www.ruby-lang.org/en/news/2013/02/22/rexml-dos-2013-02-22/ )
That sounds like a LOT of XML. Do you really need to get all of it? Maybe you can just request certain fields from the remote server? One option might be to try another XML parser (Nokogiri for example). Another option to maybe use something other than XML as a transport (JSON? Binary?).

Resources