@ -2,7 +2,8 @@ import json
import os
import os
from collections import defaultdict
from collections import defaultdict
from pyld import jsonld
from pyld import jsonld
import logging
from flask import Response as FlaskResponse
class Leaf ( dict ) :
class Leaf ( dict ) :
@ -11,18 +12,17 @@ class Leaf(dict):
_context = { }
_context = { }
def __init__ ( self ,
def __init__ ( self ,
id = None ,
* args ,
context = None ,
* * kwargs ) :
vocab = None ,
prefix = None ,
id = kwargs . pop ( " id " , None )
frame = None ) :
context = kwargs . pop ( " context " , self . _context )
super ( Leaf , self ) . __init__ ( )
vocab = kwargs . pop ( " vocab " , None )
prefix = kwargs . pop ( " prefix " , None )
frame = kwargs . pop ( " frame " , None )
super ( Leaf , self ) . __init__ ( * args , * * kwargs )
if context is not None :
if context is not None :
self . context = context
self . context = context
elif self . _context :
self . context = self . _context
else :
self . context = { }
if frame is not None :
if frame is not None :
self . _frame = frame
self . _frame = frame
self . _prefix = prefix
self . _prefix = prefix
@ -60,10 +60,11 @@ class Leaf(dict):
def get_id ( self , id ) :
def get_id ( self , id ) :
"""
"""
This is not the most elegant solution to change the @id attribute , but it
Get id , dealing with prefixes
is the quickest way to have it included in the dictionary without extra
boilerplate .
"""
"""
# This is not the most elegant solution to change the @id attribute,
# but it is the quickest way to have it included in the dictionary
# without extra boilerplate.
if id and self . _prefix and " : " not in id :
if id and self . _prefix and " : " not in id :
return " {} {} " . format ( self . _prefix , id )
return " {} {} " . format ( self . _prefix , id )
else :
else :
@ -97,7 +98,7 @@ class Leaf(dict):
return context
return context
def compact ( self ) :
def compact ( self ) :
return jsonld . compact ( self , self . context)
return jsonld . compact ( self , self . get_ context( self . context ) )
def frame ( self , frame = None , options = None ) :
def frame ( self , frame = None , options = None ) :
if frame is None :
if frame is None :
@ -106,84 +107,100 @@ class Leaf(dict):
options = { }
options = { }
return jsonld . frame ( self , frame , options )
return jsonld . frame ( self , frame , options )
def jsonable ( self , parameters = False , frame = None , options = None , context = None ) :
def jsonld ( self , frame = None , options = None ,
context = None , removeContext = None ) :
if removeContext is None :
removeContext = Response . _context # Loop?
if frame is None :
if frame is None :
frame = self . _frame
frame = self . _frame
if options is None :
options = { }
if context is None :
if context is None :
context = self . _context
context = self . context
return jsonld . compact ( jsonld . frame ( self , frame , options ) , context )
else :
#if parameters:
context = self . get_context ( context )
#resp["parameters"] = self.params
# For some reason, this causes errors with pyld
#elif self.extra_params:
# if options is None:
#resp["extra_parameters"] = self.extra_params
# options = {"expandContext": context.copy() }
#return resp
js = self
if frame :
logging . debug ( " Framing: %s " , json . dumps ( self , indent = 4 ) )
def to_JSON ( self ) :
logging . debug ( " Framing with %s " , json . dumps ( frame , indent = 4 ) )
return json . dumps ( self ,
js = jsonld . frame ( js , frame , options )
logging . debug ( " Result: %s " , json . dumps ( js , indent = 4 ) )
logging . debug ( " Compacting with %s " , json . dumps ( context , indent = 4 ) )
js = jsonld . compact ( js , context , options )
logging . debug ( " Result: %s " , json . dumps ( js , indent = 4 ) )
if removeContext == context :
del js [ " @context " ]
return js
def to_JSON ( self , removeContext = None ) :
return json . dumps ( self . jsonld ( removeContext = removeContext ) ,
default = lambda o : o . __dict__ ,
default = lambda o : o . __dict__ ,
sort_keys = True , indent = 4 )
sort_keys = True , indent = 4 )
def flask ( self ,
in_headers = False ,
url = " http://demos.gsi.dit.upm.es/senpy/senpy.jsonld " ) :
"""
Return the values and error to be used in flask
"""
js = self . jsonld ( )
headers = None
if in_headers :
ctx = js [ " @context " ]
headers = {
" Link " : ( ' < %s >; '
' rel= " http://www.w3.org/ns/json-ld#context " ; '
' type= " application/ld+json " ' % url )
}
del js [ " @context " ]
return FlaskResponse ( json . dumps ( js ) ,
status = self . get ( " status " , 200 ) ,
headers = headers ,
mimetype = " application/json " )
class Response ( Leaf ) :
class Response ( Leaf ) :
_frame = { " @context " : {
_context = Leaf . get_context ( " {} /context.jsonld " . format (
" analysis " : {
os . path . dirname ( os . path . realpath ( __file__ ) ) ) )
" @container " : " @set " ,
_frame = {
" @id " : " prov:wasInformedBy "
" @context " : _context ,
} ,
" analysis " : {
" date " : {
" @explicit " : True ,
" @id " : " dc:date " ,
" maxPolarityValue " : { } ,
" @type " : " xsd:dateTime "
" minPolarityValue " : { } ,
} ,
" name " : { } ,
" dc " : " http://purl.org/dc/terms/ " ,
" version " : { } ,
" dc:subject " : {
} ,
" @type " : " @id "
" entries " : { }
} ,
" emotions " : {
" @container " : " @set " ,
" @id " : " onyx:hasEmotionSet "
} ,
" entries " : {
" @container " : " @set " ,
" @id " : " prov:generated "
} ,
" marl " : " http://www.gsi.dit.upm.es/ontologies/marl/ns# " ,
" nif " : " http://persistence.uni-leipzig.org/nlp2rdf/ontologies/nif-core# " ,
" onyx " : " http://www.gsi.dit.upm.es/ontologies/onyx/ns# " ,
" opinions " : {
" @container " : " @set " ,
" @id " : " marl:hasOpinion "
} ,
" prov " : " http://www.w3.org/ns/prov# " ,
" rdfs " : " http://www.w3.org/2000/01/rdf-schema# " ,
" strings " : {
" @container " : " @set " ,
" @reverse " : " nif:hasContext "
} ,
" wnaffect " : " http://www.gsi.dit.upm.es/ontologies/wnaffect# " ,
" xsd " : " http://www.w3.org/2001/XMLSchema# "
} ,
" analysis " : { } ,
" entries " : { }
}
}
def __init__ ( self , context = None , * args , * * kwargs ) :
def __init__ ( self , * args , * * kwargs ) :
context = kwargs . pop ( " context " , None )
frame = kwargs . pop ( " frame " , None )
if context is None :
if context is None :
context = " {} /context.jsonld " . format ( os . path . dirname (
context = self . _context
os . path . realpath ( __file__ ) ) )
self . context = context
super ( Response , self ) . __init__ ( * args , context = context , * * kwargs )
super ( Response , self ) . __init__ (
self . analysis = [ ]
* args , context = context , frame = frame , * * kwargs )
self . entries = [ ]
if self . _frame is not None and " entries " in self . _frame :
self . analysis = [ ]
self . entries = [ ]
def jsonld ( self , frame = None , options = None , context = None , removeContext = { } ) :
return super ( Response , self ) . jsonld ( frame ,
options ,
context ,
removeContext )
class Entry ( Leaf ) :
class Entry ( Leaf ) :
_context = {
_context = {
" @vocab " : " http://persistence.uni-leipzig.org/nlp2rdf/ontologies/nif-core# "
" @vocab " : ( " http://persistence.uni-leipzig.org/ "
" nlp2rdf/ontologies/nif-core# " )
}
}
def __init__ ( self , text = None , emotion_sets = None , opinions = None , * * kwargs ) :
def __init__ ( self , text = None , emotion_sets = None , opinions = None , * * kwargs ) :
super ( Entry , self ) . __init__ ( * * kwargs )
super ( Entry , self ) . __init__ ( * * kwargs )
if text :
if text :
@ -191,10 +208,12 @@ class Entry(Leaf):
self . emotionSets = emotion_sets if emotion_sets else [ ]
self . emotionSets = emotion_sets if emotion_sets else [ ]
self . opinions = opinions if opinions else [ ]
self . opinions = opinions if opinions else [ ]
class Opinion ( Leaf ) :
class Opinion ( Leaf ) :
_context = {
_context = {
" @vocab " : " http://www.gsi.dit.upm.es/ontologies/marl/ns# "
" @vocab " : " http://www.gsi.dit.upm.es/ontologies/marl/ns# "
}
}
def __init__ ( self , polarityValue = None , hasPolarity = None , * args , * * kwargs ) :
def __init__ ( self , polarityValue = None , hasPolarity = None , * args , * * kwargs ) :
super ( Opinion , self ) . __init__ ( * args ,
super ( Opinion , self ) . __init__ ( * args ,
* * kwargs )
* * kwargs )
@ -206,6 +225,7 @@ class Opinion(Leaf):
class EmotionSet ( Leaf ) :
class EmotionSet ( Leaf ) :
_context = { }
_context = { }
def __init__ ( self , emotions = None , * args , * * kwargs ) :
def __init__ ( self , emotions = None , * args , * * kwargs ) :
if not emotions :
if not emotions :
emotions = [ ]
emotions = [ ]
@ -214,10 +234,16 @@ class EmotionSet(Leaf):
* * kwargs )
* * kwargs )
self . emotions = emotions or [ ]
self . emotions = emotions or [ ]
class Emotion ( Leaf ) :
class Emotion ( Leaf ) :
_context = { }
_context = { }
class Error ( Leaf ) :
class Error ( Response ) :
# A better pattern would be this:
# http://flask.pocoo.org/docs/0.10/patterns/apierrors/
_frame = { }
_context = { }
def __init__ ( self , * args , * * kwargs ) :
def __init__ ( self , * args , * * kwargs ) :
super ( Error , self ) . __init__ ( * args )
super ( Error , self ) . __init__ ( * args , * * kwargs )
self . update ( kwargs )