@ -2,7 +2,8 @@ import json
import os
from collections import defaultdict
from pyld import jsonld
import logging
from flask import Response as FlaskResponse
class Leaf ( dict ) :
@ -11,18 +12,17 @@ class Leaf(dict):
_context = { }
def __init__ ( self ,
id = None ,
context = None ,
vocab = None ,
prefix = None ,
frame = None ) :
super ( Leaf , self ) . __init__ ( )
* args ,
* * kwargs ) :
id = kwargs . pop ( " id " , None )
context = kwargs . pop ( " context " , self . _context )
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 :
self . context = context
elif self . _context :
self . context = self . _context
else :
self . context = { }
if frame is not None :
self . _frame = frame
self . _prefix = prefix
@ -60,10 +60,11 @@ class Leaf(dict):
def get_id ( self , id ) :
"""
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 .
Get id , dealing with prefixes
"""
# 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 :
return " {} {} " . format ( self . _prefix , id )
else :
@ -97,7 +98,7 @@ class Leaf(dict):
return context
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 ) :
if frame is None :
@ -106,84 +107,100 @@ class Leaf(dict):
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 :
frame = self . _frame
if options is None :
options = { }
if context is None :
context = self . _context
return jsonld . compact ( jsonld . frame ( self , frame , options ) , context )
#if parameters:
#resp["parameters"] = self.params
#elif self.extra_params:
#resp["extra_parameters"] = self.extra_params
#return resp
def to_JSON ( self ) :
return json . dumps ( self ,
context = self . context
else :
context = self . get_context ( context )
# For some reason, this causes errors with pyld
# if options is None:
# options = {"expandContext": context.copy() }
js = self
if frame :
logging . debug ( " Framing: %s " , json . dumps ( self , indent = 4 ) )
logging . debug ( " Framing with %s " , json . dumps ( frame , indent = 4 ) )
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__ ,
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 ) :
_frame = { " @context " : {
" analysis " : {
" @container " : " @set " ,
" @id " : " prov:wasInformedBy "
} ,
" date " : {
" @id " : " dc:date " ,
" @type " : " xsd:dateTime "
} ,
" dc " : " http://purl.org/dc/terms/ " ,
" dc:subject " : {
" @type " : " @id "
} ,
" 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 " : { }
_context = Leaf . get_context ( " {} /context.jsonld " . format (
os . path . dirname ( os . path . realpath ( __file__ ) ) ) )
_frame = {
" @context " : _context ,
" analysis " : {
" @explicit " : True ,
" maxPolarityValue " : { } ,
" minPolarityValue " : { } ,
" name " : { } ,
" version " : { } ,
} ,
" 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 :
context = " {} /context.jsonld " . format ( os . path . dirname (
os . path . realpath ( __file__ ) ) )
super ( Response , self ) . __init__ ( * args , context = context , * * kwargs )
self . analysis = [ ]
self . entries = [ ]
context = self . _context
self . context = context
super ( Response , self ) . __init__ (
* args , context = context , frame = frame , * * kwargs )
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 ) :
_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 ) :
super ( Entry , self ) . __init__ ( * * kwargs )
if text :
@ -191,10 +208,12 @@ class Entry(Leaf):
self . emotionSets = emotion_sets if emotion_sets else [ ]
self . opinions = opinions if opinions else [ ]
class Opinion ( Leaf ) :
_context = {
" @vocab " : " http://www.gsi.dit.upm.es/ontologies/marl/ns# "
}
def __init__ ( self , polarityValue = None , hasPolarity = None , * args , * * kwargs ) :
super ( Opinion , self ) . __init__ ( * args ,
* * kwargs )
@ -206,6 +225,7 @@ class Opinion(Leaf):
class EmotionSet ( Leaf ) :
_context = { }
def __init__ ( self , emotions = None , * args , * * kwargs ) :
if not emotions :
emotions = [ ]
@ -214,10 +234,16 @@ class EmotionSet(Leaf):
* * kwargs )
self . emotions = emotions or [ ]
class Emotion ( Leaf ) :
_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 ) :
super ( Error , self ) . __init__ ( * args )
self . update ( kwargs )
super ( Error , self ) . __init__ ( * args , * * kwargs )