Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
senpy
senpy
Commits
ff8d1207
Commit
ff8d1207
authored
Nov 04, 2014
by
J. Fernando Sánchez
Browse files
Improved plugins (reload, imp)
parent
bdf19927
Changes
7
Hide whitespace changes
Inline
Side-by-side
app.py
View file @
ff8d1207
...
...
@@ -21,7 +21,7 @@ This class shows how to use the nif_server module to create custom services.
'''
import
config
from
flask
import
Flask
from
senpy
import
Senpy
from
senpy
.extensions
import
Senpy
app
=
Flask
(
__name__
)
...
...
@@ -30,4 +30,4 @@ sp.init_app(app)
if
__name__
==
'__main__'
:
app
.
debug
=
config
.
DEBUG
app
.
run
()
app
.
run
(
use_reloader
=
False
)
senpy/__init__.py
View file @
ff8d1207
...
...
@@ -18,6 +18,8 @@
Sentiment analysis server in Python
'''
VERSION
=
"0.2.4"
import
extensions
import
blueprints
import
plugins
...
...
senpy/blueprints.py
View file @
ff8d1207
...
...
@@ -22,43 +22,13 @@ import json
nif_blueprint
=
Blueprint
(
"NIF Sentiment Analysis Server"
,
__name__
)
PARAMS
=
{
"input"
:
{
"aliases"
:
[
"i"
,
"input"
],
"required"
:
True
,
"help"
:
"Input text"
},
"informat"
:
{
"aliases"
:
[
"f"
,
"informat"
],
"required"
:
False
,
"default"
:
"text"
,
"options"
:
[
"turtle"
,
"text"
],
},
"intype"
:
{
"aliases"
:
[
"intype"
,
"t"
],
"required"
:
False
,
"default"
:
"direct"
,
"options"
:
[
"direct"
,
"url"
,
"file"
],
},
"outformat"
:
{
"aliases"
:
[
"outformat"
,
"o"
],
"default"
:
"json-ld"
,
"required"
:
False
,
"options"
:
[
"json-ld"
],
},
"algorithm"
:
{
"aliases"
:
[
"algorithm"
,
"a"
,
"algo"
],
"required"
:
False
,
},
"language"
:
{
"aliases"
:
[
"language"
,
"l"
],
"required"
:
False
,
"options"
:
[
"es"
,
"en"
],
},
"urischeme"
:
{
"aliases"
:
[
"urischeme"
,
"u"
],
"required"
:
False
,
"default"
:
"RFC5147String"
,
"options"
:
"RFC5147String"
},
}
BASIC_PARAMS
=
{
"algorithm"
:
{
"aliases"
:
[
"algorithm"
,
"a"
,
"algo"
],
"required"
:
False
,
},
}
def
get_algorithm
(
req
):
return
get_params
(
req
,
params
=
{
"algorithm"
:
PARAMS
[
"algorithm"
]})
def
get_params
(
req
,
params
=
PARAMS
):
def
get_params
(
req
,
params
=
BASIC_PARAMS
):
indict
=
None
if
req
.
method
==
'POST'
:
indict
=
req
.
form
...
...
@@ -113,35 +83,44 @@ def basic_analysis(params):
@
nif_blueprint
.
route
(
'/'
,
methods
=
[
'POST'
,
'GET'
])
def
home
(
entries
=
None
):
try
:
algo
=
get_algorithm
(
request
)[
"algorithm"
]
specific_params
=
PARAMS
.
copy
()
specific_params
.
update
(
current_app
.
senpy
.
parameters
(
algo
))
algo
=
get_params
(
request
).
get
(
"algorithm"
,
None
)
specific_params
=
current_app
.
senpy
.
parameters
(
algo
)
params
=
get_params
(
request
,
specific_params
)
except
ValueError
as
ex
:
return
ex
.
message
response
=
current_app
.
senpy
.
analyse
(
**
params
)
return
jsonify
(
response
)
@
nif_blueprint
.
route
(
"/default"
)
def
default
():
return
current_app
.
senpy
.
default_plugin
#return plugins(action="list", plugin=current_app.senpy.default_algorithm)
@
nif_blueprint
.
route
(
'/plugins/'
,
methods
=
[
'POST'
,
'GET'
])
@
nif_blueprint
.
route
(
'/plugins/<plugin>'
,
methods
=
[
'POST'
,
'GET'
])
@
nif_blueprint
.
route
(
'/plugins/<plugin>/<action>'
,
methods
=
[
'POST'
,
'GET'
])
def
plugins
(
plugin
=
None
,
action
=
"list"
):
print
current_app
.
senpy
.
plugins
.
keys
()
filt
=
{}
if
plugin
:
plugs
=
{
plugin
:
current_app
.
senpy
.
plugins
[
plugin
]}
else
:
plugs
=
current_app
.
senpy
.
plugins
filt
[
"name"
]
=
plugin
plugs
=
current_app
.
senpy
.
filter_plugins
(
**
filt
)
if
plugin
and
not
plugs
:
return
"Plugin not found"
,
400
if
action
==
"list"
:
dic
=
{
plug
:
plugs
[
plug
].
jsonable
(
True
)
for
plug
in
plugs
}
with_params
=
request
.
args
.
get
(
"params"
,
""
)
==
"1"
dic
=
{
plug
:
plugs
[
plug
].
jsonable
(
with_params
)
for
plug
in
plugs
}
return
jsonify
(
dic
)
el
if
action
==
"disable"
:
plug
s
[
plugin
].
enabled
=
False
if
action
==
"disable"
:
current_app
.
senpy
.
disable_
plug
in
(
plugin
)
return
"Ok"
elif
action
==
"enable"
:
plugs
[
plugin
].
enabled
=
True
current_app
.
senpy
.
enable_plugin
(
plugin
)
return
"Ok"
elif
action
==
"reload"
:
current_app
.
senpy
.
reload_plugin
(
plugin
)
return
"Ok"
else
:
return
"action '{}' not allowed"
.
format
(
action
),
40
4
return
"action '{}' not allowed"
.
format
(
action
),
40
0
if
__name__
==
'__main__'
:
import
config
...
...
senpy/extensions.py
View file @
ff8d1207
import
os
import
sys
import
imp
ortlib
import
imp
from
flask
import
current_app
from
collections
import
defaultdict
from
.plugins
import
SentimentPlugin
,
EmotionPlugin
try
:
from
flask
import
_app_ctx_stack
as
stack
...
...
@@ -18,7 +20,7 @@ class Senpy(object):
self
.
app
=
app
base_folder
=
os
.
path
.
join
(
os
.
path
.
dirname
(
__file__
),
"plugins"
)
self
.
search_folders
=
(
folder
for
folder
in
(
base_folder
,
plugin_folder
)
self
.
search_folders
=
(
folder
for
folder
in
(
base_folder
,
plugin_folder
,
'/tmp/plugins'
)
if
folder
and
os
.
path
.
isdir
(
folder
))
if
app
is
not
None
:
...
...
@@ -41,24 +43,49 @@ class Senpy(object):
app
.
register_blueprint
(
nif_blueprint
)
def
analyse
(
self
,
**
params
):
algo
=
None
print
(
"analysing with params: {}"
.
format
(
params
))
if
"algorithm"
in
params
:
algo
=
params
[
"algorithm"
]
if
algo
in
self
.
plugins
and
self
.
plugins
[
algo
].
enabled
:
plug
=
self
.
plugins
[
algo
]
resp
=
plug
.
analyse
(
**
params
)
resp
.
analysis
.
append
(
plug
.
jsonable
())
return
resp
return
{
"status"
:
500
,
"message"
:
"No valid algorithm"
}
elif
self
.
plugins
:
algo
=
self
.
default_plugin
if
algo
in
self
.
plugins
and
self
.
plugins
[
algo
].
enabled
:
plug
=
self
.
plugins
[
algo
]
resp
=
plug
.
analyse
(
**
params
)
resp
.
analysis
.
append
(
plug
.
jsonable
())
return
resp
else
:
return
{
"status"
:
500
,
"message"
:
"No valid algorithm"
}
@
property
def
default_plugin
(
self
):
if
self
.
plugins
:
candidate
=
self
.
filter_plugins
(
enabled
=
True
).
keys
()[
0
]
print
(
"Default: {}"
.
format
(
candidate
))
return
candidate
else
:
return
Exception
(
"No algorithm"
)
def
parameters
(
self
,
algo
):
if
algo
in
self
.
plugins
:
if
hasattr
(
self
.
plugins
[
algo
],
"parameters"
):
return
self
.
plugins
[
algo
].
parameters
return
{}
return
getattr
(
self
.
plugins
.
get
(
algo
or
self
.
default_plugin
),
"params"
,
{})
def
enable_plugin
(
self
,
plugin
):
self
.
plugins
[
plugin
].
disable
()
def
disable_plugin
(
self
,
plugin
):
self
.
plugins
[
plugin
].
disable
()
def
reload_plugin
(
self
,
plugin
):
print
(
"Reloading {}"
.
format
(
plugin
))
plug
=
self
.
plugins
[
plugin
]
nplug
=
self
.
_load_plugin
(
plug
.
module
,
plug
.
path
)
del
self
.
plugins
[
plugin
]
self
.
plugins
[
nplug
.
name
]
=
nplug
def
_load_plugin
(
self
,
plugin
,
search_folder
,
enabled
=
True
):
sys
.
path
.
append
(
search_folder
)
tmp
=
importlib
.
import_module
(
plugin
).
plugin
(
fp
,
pathname
,
desc
)
=
imp
.
find_module
(
plugin
)
tmp
=
imp
.
load_module
(
plugin
,
fp
,
pathname
,
desc
).
plugin
sys
.
path
.
remove
(
search_folder
)
tmp
.
path
=
search_folder
try
:
...
...
@@ -68,19 +95,19 @@ class Senpy(object):
tmp
.
repo
=
None
if
not
hasattr
(
tmp
,
"enabled"
):
tmp
.
enabled
=
enabled
tmp
.
module
=
plugin
return
tmp
def
_load_plugins
(
self
):
#print(sys.path)
#print(search_folder)
plugins
=
{}
for
search_folder
in
self
.
search_folders
:
for
item
in
os
.
listdir
(
search_folder
):
if
os
.
path
.
isdir
(
os
.
path
.
join
(
search_folder
,
item
))
\
and
os
.
path
.
exists
(
os
.
path
.
join
(
search_folder
,
item
,
"__init__.py"
)):
plugins
[
item
]
=
self
.
_load_plugin
(
item
,
search_folder
)
plugin
=
self
.
_load_plugin
(
item
,
search_folder
)
plugins
[
plugin
.
name
]
=
plugin
return
plugins
...
...
@@ -105,6 +132,20 @@ class Senpy(object):
self
.
_plugins
=
self
.
_load_plugins
()
return
self
.
_plugins
def
filter_plugins
(
self
,
**
kwargs
):
def
matches
(
plug
):
res
=
all
(
getattr
(
plug
,
k
,
None
)
==
v
for
(
k
,
v
)
in
kwargs
.
items
())
print
(
"matching {} with {}: {}"
.
format
(
plug
.
name
,
kwargs
,
res
))
return
res
if
not
kwargs
:
return
self
.
plugins
else
:
return
{
n
:
p
for
n
,
p
in
self
.
plugins
.
items
()
if
matches
(
p
)}
def
sentiment_plugins
(
self
):
return
(
plugin
for
plugin
in
self
.
plugins
if
isinstance
(
plugin
,
SentimentPlugin
))
if
__name__
==
'__main__'
:
from
flask
import
Flask
app
=
Flask
(
__name__
)
...
...
senpy/plugins.py
View file @
ff8d1207
PARAMS
=
{
"input"
:
{
"aliases"
:
[
"i"
,
"input"
],
"required"
:
True
,
"help"
:
"Input text"
},
"informat"
:
{
"aliases"
:
[
"f"
,
"informat"
],
"required"
:
False
,
"default"
:
"text"
,
"options"
:
[
"turtle"
,
"text"
],
},
"intype"
:
{
"aliases"
:
[
"intype"
,
"t"
],
"required"
:
False
,
"default"
:
"direct"
,
"options"
:
[
"direct"
,
"url"
,
"file"
],
},
"outformat"
:
{
"aliases"
:
[
"outformat"
,
"o"
],
"default"
:
"json-ld"
,
"required"
:
False
,
"options"
:
[
"json-ld"
],
},
"language"
:
{
"aliases"
:
[
"language"
,
"l"
],
"required"
:
False
,
"options"
:
[
"es"
,
"en"
],
},
"urischeme"
:
{
"aliases"
:
[
"urischeme"
,
"u"
],
"required"
:
False
,
"default"
:
"RFC5147String"
,
"options"
:
"RFC5147String"
},
}
class
SenpyPlugin
(
object
):
def
__init__
(
self
,
name
=
None
,
version
=
None
,
params
=
None
):
def
__init__
(
self
,
name
=
None
,
version
=
None
,
extraparams
=
None
,
params
=
None
):
print
(
"Initing {}"
.
format
(
name
))
self
.
name
=
name
self
.
version
=
version
self
.
params
=
params
or
[]
if
params
:
self
.
params
=
params
else
:
self
.
params
=
PARAMS
.
copy
()
if
extraparams
:
self
.
params
.
update
(
extraparams
)
self
.
extraparams
=
extraparams
or
{}
self
.
enabled
=
True
def
analyse
(
self
,
*
args
,
**
kwargs
):
pass
def
activat
e
(
self
):
pass
def
enabl
e
(
self
):
self
.
enabled
=
True
def
d
eactivat
e
(
self
):
pass
def
d
isabl
e
(
self
):
self
.
enabled
=
False
def
jsonable
(
self
,
parameters
=
False
):
resp
=
{
"@id"
:
"{}_{}"
.
format
(
self
.
name
,
self
.
version
),
"enabled"
:
self
.
enabled
,
}
if
self
.
repo
:
resp
[
"repo"
]
=
self
.
repo
.
remotes
[
0
].
url
if
parameters
:
resp
[
"parameters"
]
=
self
.
params
,
resp
[
"parameters"
]
=
self
.
params
elif
self
.
extraparams
:
resp
[
"extra_parameters"
]
=
self
.
extraparams
return
resp
class
SentimentPlugin
(
SenpyPlugin
):
...
...
senpy/plugins/sentiment140/__init__.py
View file @
ff8d1207
...
...
@@ -3,20 +3,20 @@ import json
import
sys
print
(
sys
.
path
)
from
senpy.plugins
import
SentimentPlugin
from
senpy.models
import
Response
,
Opinion
,
Entry
class
Sentiment140Plugin
(
SentimentPlugin
):
parameters
=
{
EXTRA_PARAMS
=
{
"language"
:
{
"aliases"
:
[
"language"
,
"l"
],
"required"
:
False
,
"options"
:
[
"es"
,
"en"
,
"auto"
],
}
}
def
__init__
(
self
,
**
kwargs
):
super
(
Sentiment140Plugin
,
self
).
__init__
(
name
=
"Sentiment140"
,
version
=
"1.0"
,
super
(
Sentiment140Plugin
,
self
).
__init__
(
name
=
"sentiment140"
,
version
=
"2.0"
,
extraparams
=
self
.
EXTRA_PARAMS
,
**
kwargs
)
def
analyse
(
self
,
**
params
):
...
...
@@ -44,5 +44,4 @@ class Sentiment140Plugin(SentimentPlugin):
response
.
entries
.
append
(
entry
)
return
response
plugin
=
Sentiment140Plugin
()
setup.py
View file @
ff8d1207
from
setuptools
import
setup
import
senpy
setup
(
name
=
'senpy'
,
packages
=
[
'senpy'
],
# this must be the same as the name above
version
=
'0.2.3'
,
version
=
senpy
.
VERSION
,
description
=
'''
A sentiment analysis server implementation. Designed to be
\
extendable, so new algorithms and sources can be used.
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment