Skip to content

Commit 3075155

Browse files
author
Dogukan Erenel
committed
* Added combined call to AlchemyAPI call to get all keywords and entities all in once.
1 parent 00da770 commit 3075155

File tree

3 files changed

+328
-9
lines changed

3 files changed

+328
-9
lines changed

Scripts/Services/AlchemyAPI/AlchemyAPI.cs

Lines changed: 123 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,13 @@ public class AlchemyAPI : IWatsonService {
3535

3636
#region Private Data
3737
private const string SERVICE_ID = "AlchemyAPIV1";
38+
private static string mp_ApiKey = null;
39+
3840
private static fsSerializer sm_Serializer = new fsSerializer();
3941
#endregion
4042

4143
#region Entity Extraction
4244
private const string SERVICE_ENTITY_EXTRACTION = "/calls/text/TextGetRankedNamedEntities";
43-
private string mp_ApiKey = null;
4445

4546
public delegate void OnGetEntityExtraction( EntityExtractionData entityExtractionData, string data );
4647

@@ -123,6 +124,127 @@ private void OnGetEntityExtractionResponse(RESTConnector.Request req, RESTConnec
123124

124125
#endregion
125126

127+
#region Combined Call
128+
129+
private const string SERVICE_COMBINED_CALLS = "/calls/text/TextGetCombinedData";
130+
131+
public delegate void OnGetCombinedCall( CombinedCallData combinedCallData, string data);
132+
133+
//http://access.alchemyapi.com/calls/text/TextGetRankedNamedEntities
134+
135+
public bool GetCombinedCall(OnGetCombinedCall callback, string text,
136+
bool includeEntity = true,
137+
bool includeKeywoard = true,
138+
bool includeTaxonomy = false,
139+
bool includeConcept = false,
140+
bool includeFeed = false,
141+
bool includeDocEmotion = false,
142+
bool includeRelation = false,
143+
bool includePubDate = false,
144+
bool includeDocSentiment = false,
145+
bool includePageImage = false,
146+
bool includeImageKW = false)
147+
{
148+
if (callback == null)
149+
throw new ArgumentNullException("callback");
150+
if (string.IsNullOrEmpty(text))
151+
throw new WatsonException("GetCombinedCall needs to have some text to work.");
152+
if (string.IsNullOrEmpty(mp_ApiKey))
153+
mp_ApiKey = Config.Instance.GetVariableValue("ALCHEMY_API_KEY");
154+
if (string.IsNullOrEmpty(mp_ApiKey))
155+
throw new WatsonException("GetCombinedCall - ALCHEMY_API_KEY needs to be defined in config.json");
156+
if( !includeEntity
157+
&& !includeKeywoard
158+
&& !includeTaxonomy
159+
&& !includeConcept
160+
&& !includeFeed
161+
&& !includeDocEmotion
162+
&& !includeRelation
163+
&& !includePubDate
164+
&& !includeDocSentiment
165+
&& !includePageImage
166+
&& !includeImageKW)
167+
throw new WatsonException("GetCombinedCall - There should be some service included.");
168+
169+
RESTConnector connector = RESTConnector.GetConnector(SERVICE_ID, SERVICE_COMBINED_CALLS);
170+
if (connector == null)
171+
return false;
172+
173+
GetCombinedCallRequest req = new GetCombinedCallRequest();
174+
req.Callback = callback;
175+
176+
List<string> requestServices = new List<string>();
177+
if (includeEntity)
178+
requestServices.Add("entity");
179+
if(includeKeywoard)
180+
requestServices.Add("keyword");
181+
if(includeTaxonomy)
182+
requestServices.Add("taxonomy");
183+
if(includeConcept)
184+
requestServices.Add("concept");
185+
if(includeFeed)
186+
requestServices.Add("feed");
187+
if(includeDocEmotion)
188+
requestServices.Add("doc-emotion");
189+
if(includeRelation)
190+
requestServices.Add("relation");
191+
if(includePubDate)
192+
requestServices.Add("pub-date");
193+
if(includeDocSentiment)
194+
requestServices.Add("doc-sentiment");
195+
if(includePageImage)
196+
requestServices.Add("page-image");
197+
if(includeImageKW)
198+
requestServices.Add("image-kw");
199+
200+
req.Parameters["apikey"] = mp_ApiKey;
201+
req.Parameters["text"] = text;
202+
req.Parameters["extract"] = string.Join(",", requestServices.ToArray());
203+
req.Parameters["outputMode"] = "json";
204+
req.Parameters["showSourceText"] = "1";
205+
206+
req.OnResponse = OnGetCombinedCallResponse;
207+
req.Data = text;
208+
209+
return connector.Send(req);
210+
}
211+
212+
private class GetCombinedCallRequest : RESTConnector.Request
213+
{
214+
public string Data { get; set;}
215+
public OnGetCombinedCall Callback { get; set; }
216+
};
217+
218+
private void OnGetCombinedCallResponse(RESTConnector.Request req, RESTConnector.Response resp)
219+
{
220+
CombinedCallData combinedCallData = new CombinedCallData();
221+
if (resp.Success)
222+
{
223+
try
224+
{
225+
fsData data = null;
226+
fsResult r = fsJsonParser.Parse(Encoding.UTF8.GetString(resp.Data), out data);
227+
if (!r.Succeeded)
228+
throw new WatsonException(r.FormattedMessages);
229+
230+
object obj = combinedCallData;
231+
r = sm_Serializer.TryDeserialize(data, obj.GetType(), ref obj);
232+
if (!r.Succeeded)
233+
throw new WatsonException(r.FormattedMessages);
234+
}
235+
catch (Exception e)
236+
{
237+
Log.Error("AlchemyAPI", "OnGetCombinedCallResponse Exception: {0}", e.ToString());
238+
resp.Success = false;
239+
}
240+
}
241+
242+
if (((GetCombinedCallRequest)req).Callback != null)
243+
((GetCombinedCallRequest)req).Callback(resp.Success ? combinedCallData : null, ((GetCombinedCallRequest)req).Data);
244+
}
245+
246+
#endregion
247+
126248
#region IWatsonService interface
127249
/// <exclude />
128250
public string GetServiceID()

Scripts/Services/AlchemyAPI/DataModels.cs

Lines changed: 197 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
using FullSerializer;
1919
using System.Text;
20+
using System.Collections.Generic;
2021
using IBM.Watson.DeveloperCloud.Services.ESRI.v1;
2122

2223
namespace IBM.Watson.DeveloperCloud.Services.AlchemyAPI.v1
@@ -637,6 +638,50 @@ public override string ToString()
637638

638639
return string.Format("[Entity: type={0} - EntityType={8}, relevance={1}, knowledgeGraph={2}, count={3}, text={4}, disambiguated={5}, quotations={6}, sentiment={7}]", type, relevance, knowledgeGraph, count, text, disambiguated, stringBuilder.ToString(), sentiment, EntityType);
639640
}
641+
642+
public bool HasGeographicInformation
643+
{
644+
get
645+
{
646+
string geoString = null;
647+
if (disambiguated != null)
648+
{
649+
geoString = disambiguated.geo;
650+
}
651+
return !string.IsNullOrEmpty(geoString);
652+
}
653+
}
654+
655+
private PositionOnMap _GeoLocation = null;
656+
public PositionOnMap GeoLocation
657+
{
658+
get
659+
{
660+
if (_GeoLocation == null)
661+
{
662+
string geoString = null;
663+
if (disambiguated != null)
664+
{
665+
geoString = disambiguated.geo;
666+
if (!string.IsNullOrEmpty(geoString))
667+
{
668+
string[] geoValues = geoString.Split(' ');
669+
if (geoValues != null && geoValues.Length == 2)
670+
{
671+
double latitute = 0;
672+
double longitutde = 0;
673+
674+
if (double.TryParse(geoValues[0], out latitute) && double.TryParse(geoValues[1], out longitutde))
675+
{
676+
_GeoLocation = new PositionOnMap(latitute, longitutde, disambiguated.name);
677+
}
678+
}
679+
}
680+
}
681+
}
682+
return _GeoLocation;
683+
}
684+
}
640685
};
641686

642687
[fsObject]
@@ -697,4 +742,156 @@ public override string ToString()
697742
return string.Format("[Sentiment: type={0}, score={1}, mixed={2}]", type, score, mixed);
698743
}
699744
};
745+
746+
[fsObject]
747+
public class CombinedCallData
748+
{
749+
public string status { get; set; }
750+
public string totalTransactions { get; set; }
751+
public string language { get; set; }
752+
public string text { get; set; }
753+
public Keyword[] keywords { get; set; }
754+
public Entity[] entities { get; set; }
755+
public Sentiment docSentiment{ get; set; }
756+
public Concept[] concepts{ get; set; }
757+
public Relation[] relations{ get; set; }
758+
public Taxonomy[] taxonomy{ get; set; }
759+
public DocEmotions[] docEmotions{ get; set; }
760+
761+
public bool HasData
762+
{
763+
get
764+
{
765+
return EntityCombined != null && EntityCombined.Count > 0;
766+
}
767+
}
768+
769+
private List<string> _EntityCombined = null;
770+
public List<string> EntityCombined
771+
{
772+
get
773+
{
774+
if (_EntityCombined == null)
775+
{
776+
_EntityCombined = new List<string>();
777+
778+
for (int i = 0; keywords != null && i < keywords.Length; i++)
779+
{
780+
if(!_EntityCombined.Contains(keywords[i].text))
781+
_EntityCombined.Add(keywords[i].text);
782+
}
783+
784+
for (int i = 0; entities != null && i < entities.Length; i++)
785+
{
786+
if(!_EntityCombined.Contains(entities[i].text))
787+
_EntityCombined.Add(entities[i].text);
788+
}
789+
}
790+
791+
return _EntityCombined;
792+
}
793+
}
794+
795+
public string EntityCombinedCommaSeperated
796+
{
797+
get
798+
{
799+
if (EntityCombined.Count > 0)
800+
return string.Join(",", EntityCombined.ToArray());
801+
return "";
802+
}
803+
}
804+
};
805+
806+
807+
[fsObject]
808+
public class Keyword
809+
{
810+
public string text { get; set; }
811+
public string relevance { get; set; }
812+
public KnowledgeGraph knowledgeGraph{ get; set; }
813+
public Sentiment sentiment { get; set; }
814+
815+
};
816+
817+
[fsObject]
818+
public class Concept
819+
{
820+
public string text { get; set; }
821+
public string relevance { get; set; }
822+
public KnowledgeGraph knowledgeGraph{ get; set; }
823+
public string website { get; set; }
824+
public string geo { get; set; }
825+
public string dbpedia { get; set; }
826+
public string freebase { get; set; }
827+
public string yago { get; set; }
828+
public string opencyc{ get; set; }
829+
public string ciaFactbook{ get; set; }
830+
public string census{ get; set; }
831+
public string geonames{ get; set; }
832+
public string musicBrainz{ get; set; }
833+
public string crunchbase{ get; set; }
834+
};
835+
836+
[fsObject]
837+
public class Relation
838+
{
839+
public string sentence { get; set; }
840+
public Subject subject { get; set; }
841+
public Entity entity { get; set; }
842+
public Action action { get; set; }
843+
public ObjectData @object { get; set; }
844+
};
845+
846+
[fsObject]
847+
public class Subject
848+
{
849+
public string text { get; set; }
850+
public Sentiment sentiment { get; set; }
851+
};
852+
853+
[fsObject]
854+
public class Action
855+
{
856+
public string text { get; set; }
857+
public string lemmatized { get; set; }
858+
public Verb verb { get; set; }
859+
};
860+
861+
[fsObject]
862+
public class Verb
863+
{
864+
public string text { get; set; }
865+
public string tense { get; set; }
866+
public string negated { get; set; }
867+
};
868+
869+
[fsObject]
870+
public class ObjectData
871+
{
872+
public string text { get; set; }
873+
public Sentiment sentiment { get; set; }
874+
public Sentiment sentimentFromSubject{ get; set; }
875+
public Entity entity { get; set; }
876+
};
877+
878+
[fsObject]
879+
public class Taxonomy
880+
{
881+
public string label { get; set; }
882+
public string score { get; set; }
883+
public string confident { get; set; }
884+
};
885+
886+
[fsObject]
887+
public class DocEmotions
888+
{
889+
public string anger { get; set; }
890+
public string disgust { get; set; }
891+
public string fear { get; set; }
892+
public string joy { get; set; }
893+
public string sadness { get; set; }
894+
};
895+
896+
700897
}

Scripts/UnitTests/TestAlchemyAPI.cs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,12 @@ public override IEnumerator RunTest()
4141
Log.Status("TestAlchemyAPI", "Test Started");
4242

4343
m_NumberOfTestEntityExtraction = 6;
44-
m_AlchemnyAPI.GetEntityExtraction(OnGetEntityExtraction, "How are you Watson?");
45-
m_AlchemnyAPI.GetEntityExtraction(OnGetEntityExtraction, "How can Watson help patients?");
46-
m_AlchemnyAPI.GetEntityExtraction(OnGetEntityExtraction, "Where is Watson?"); //Name
47-
m_AlchemnyAPI.GetEntityExtraction(OnGetEntityExtraction, "Where is Paris?"); //Location
48-
m_AlchemnyAPI.GetEntityExtraction(OnGetEntityExtraction, "Which ships are close to Karratha"); //location with name
49-
m_AlchemnyAPI.GetEntityExtraction(OnGetEntityExtraction, "Are you artifical intelligence?");
44+
m_AlchemnyAPI.GetCombinedCall(OnGetCombinedCall, "How are you Watson?");
45+
m_AlchemnyAPI.GetCombinedCall(OnGetCombinedCall, "How can Watson help patients?");
46+
m_AlchemnyAPI.GetCombinedCall(OnGetCombinedCall, "Where is Watson?"); //Name
47+
m_AlchemnyAPI.GetCombinedCall(OnGetCombinedCall, "Where is Paris?"); //Location
48+
m_AlchemnyAPI.GetCombinedCall(OnGetCombinedCall, "Which ships are close to Karratha"); //location with name
49+
m_AlchemnyAPI.GetCombinedCall(OnGetCombinedCall, "Are you artifical intelligence?");
5050

5151
while(! m_EntityExtractionTested )
5252
yield return null;
@@ -56,10 +56,10 @@ public override IEnumerator RunTest()
5656

5757

5858

59-
private void OnGetEntityExtraction(EntityExtractionData entityExtractionData, string data)
59+
private void OnGetCombinedCall(CombinedCallData combinedCallData, string data)
6060
{
6161
m_NumberOfTestEntityExtraction--;
62-
Log.Status("TestAlchemyAPI", "Remaining: {0}, Has Geo Information: {1}, Geo: {2}, OnGetEntityExtraction: {3}", m_NumberOfTestEntityExtraction, entityExtractionData.HasGeographicInformation, (entityExtractionData.HasGeographicInformation?entityExtractionData.GeoLocation.ToString(): "None"), entityExtractionData);
62+
Log.Status("TestAlchemyAPI", "Remaining: {0}, original text:{1}, OnGetCombinedCall: {2}", m_NumberOfTestEntityExtraction, data, combinedCallData.EntityCombinedCommaSeperated);
6363

6464
if(m_NumberOfTestEntityExtraction <= 0){
6565
Test( true );

0 commit comments

Comments
 (0)