@ -23,7 +23,8 @@
import json
import json
import logging
import logging
from odoo import http
from odoo import http
from odoo . http import request
from odoo . http import request , Response
from ast import literal_eval
_logger = logging . getLogger ( __name__ )
_logger = logging . getLogger ( __name__ )
@ -38,80 +39,83 @@ class RestApi(http.Controller):
user_id = request . env [ ' res.users ' ] . search ( [ ( ' api_key ' , ' = ' , api_key ) ] )
user_id = request . env [ ' res.users ' ] . search ( [ ( ' api_key ' , ' = ' , api_key ) ] )
if api_key is not None and user_id :
if api_key is not None and user_id :
response = True
return True
elif not user_id :
elif not user_id :
response = ( ' <html><body><h2>Invalid <i>API Key</i> '
return Response ( json . dumps ( { ' message ' : ' Invalid API Key ' } ) , status = 401 )
' !</h2></body></html> ' )
return Response ( json . dumps ( { ' message ' : ' No API Key Provided ' } ) , status = 400 )
else :
response = ( " <html><body><h2>No <i>API Key</i> Provided "
def simplest_type ( self , input ) :
" !</h2></body></html> " )
""" Try cast input into native Python class, otherwise return as string """
try :
return response
return literal_eval ( input )
except :
if input == ' true ' :
return True
if input == ' false ' :
return False
return input
def generate_response ( self , method , model , rec_id ) :
def generate_response ( self , method , * * query ) :
""" This function is used to generate the response based on the type
""" This function is used to generate the response based on the type
of request and the parameters given """
of request and the parameters given """
model = query . pop ( ' model ' )
option = request . env [ ' connection.api ' ] . search (
option = request . env [ ' connection.api ' ] . search (
[ ( ' model_id ' , ' = ' , model ) ] , limit = 1 )
[ ( ' model_id ' , ' = ' , model ) ] , limit = 1 )
model_name = option . model_id . model
model_name = option . model_id . model
model_display_name = option . model_id . name
if method != ' DELETE ' :
data = { }
try :
data = json . loads ( request . httprequest . data )
data = json . loads ( request . httprequest . data )
else :
except :
data = { }
pass
fields = [ ]
fields = [ ]
if data :
if data :
for field in data [ ' fields ' ] :
for field in data [ ' fields ' ] :
fields . append ( field )
fields . append ( field )
if not fields and method != ' DELETE ' :
if ' * ' in fields :
return ( " <html><body><h2>No fields selected for the model "
fields = [ ]
" </h2></body></html> " )
record_fields = request . env [
str ( model_name ) ] . fields_get ( [ ] , attributes = [ ' type ' ] )
for field , value in record_fields . items ( ) :
value_type = value . get ( ' type ' )
if not ( value_type == ' binary ' or value_type == ' datetime ' ) :
fields . append ( field )
if not option :
if not option :
return ( " <html><body><h2>No Record Created for the model "
return Response ( json . dumps ( { ' message ' : f ' No Record Created for the model. Please contact your admininstrator to enable { method } method for { model_display_name } record. ' } ) , status = 403 )
" </h2></body></html> " )
try :
try :
if method == ' GET ' :
if method == ' GET ' :
fields = [ ]
if not fields :
for field in data [ ' fields ' ] :
fields . append ( ' id ' )
fields . append ( field )
if not option . is_get :
if not option . is_get :
return ( " <html><body><h2>Method Not Allowed "
return Response (
" </h2></body></html> " )
json . dumps ( { ' message ' : f ' Method not allowed. Please contact your admininstrator to enable { method } method for { model_display_name } record. ' } ) ,
status = 405 )
else :
else :
datas = [ ]
domains = [ ]
if rec_id != 0 :
for key , value in query . items ( ) :
partner_records = request . env [
domains . append ( ( key , ' = ' , self . simplest_type ( value ) ) )
str ( model_name ) ] . search_read (
partner_records = request . env [
domain = [ ( ' id ' , ' = ' , rec_id ) ] ,
str ( model_name ) ] . search_read (
fields = fields
domain = domains ,
)
fields = fields
data = json . dumps ( {
)
' records ' : partner_records
return Response (
} )
json . dumps ( {
datas . append ( data )
return request . make_response ( data = datas )
else :
partner_records = request . env [
str ( model_name ) ] . search_read (
domain = [ ] ,
fields = fields
)
data = json . dumps ( {
' records ' : partner_records
' records ' : partner_records
} )
} )
datas . append ( data )
)
return request . make_response ( data = datas )
if method == ' POST ' :
except :
if not option . is_post :
return ( " <html><body><h2>Invalid JSON Data "
return Response (
" </h2></body></html> " )
json . dumps ( { ' message ' : f ' Method not allowed. Please contact your admininstrator to enable { method } method for { model_display_name } record. ' } ) ,
if method == ' POST ' :
status = 405 )
if not option . is_post :
if not data or ' values ' not in data :
return ( " <html><body><h2>Method Not Allowed "
return Response ( json . dumps ( { ' message ' : ' No Data Provided ' } ) , status = 403 )
" </h2></body></html> " )
else :
try :
try :
data = json . loads ( request . httprequest . data )
data = json . loads ( request . httprequest . data )
datas = [ ]
new_resource = request . env [ str ( model_name ) ] . create (
new_resource = request . env [ str ( model_name ) ] . create (
data [ ' values ' ] )
data [ ' values ' ] )
partner_records = request . env [
partner_records = request . env [
@ -119,71 +123,61 @@ class RestApi(http.Controller):
domain = [ ( ' id ' , ' = ' , new_resource . id ) ] ,
domain = [ ( ' id ' , ' = ' , new_resource . id ) ] ,
fields = fields
fields = fields
)
)
new_data = json . dumps ( { ' New resource ' : partner_records , } )
return Response ( json . dumps ( { ' new_record ' : partner_records } ) , status = 201 )
datas . append ( new_data )
return request . make_response ( data = datas )
except :
except :
return ( " <html><body><h2>Invalid JSON Data "
return Response ( json . dumps ( { ' message ' : ' Invalid JSON Data ' } ) , status = 403 )
" </h2></body></html> " )
if method == ' PUT ' :
if method == ' PUT ' :
if not option . is_put :
if not option . is_put :
return Response (
return ( " <html><body><h2>Method Not Allowed "
json . dumps ( { ' message ' : f ' Method not allowed. Please contact your admininstrator to enable { method } method for { model_display_name } record. ' } ) ,
" </h2></body></html> " )
status = 405 )
else :
if rec_id == 0 :
if not ' id ' in query :
return ( " <html><body><h2>No ID Provided "
return Response ( json . dumps ( { ' message ' : ' No ID Provided ' } ) , status = 403 )
" </h2></body></html> " )
if not data or ' values ' not in data :
else :
return Response ( json . dumps ( { ' message ' : ' No Data Provided ' } ) , status = 403 )
resource = request . env [ str ( model_name ) ] . browse (
int ( rec_id ) )
resource = request . env [ str ( model_name ) ] . browse (
if not resource . exists ( ) :
int ( query . get ( ' id ' ) ) )
return ( " <html><body><h2>Resource not found "
if not resource . exists ( ) :
" </h2></body></html> " )
return Response ( json . dumps ( { ' message ' : ' Resource not found ' } ) , status = 404 )
else :
try :
try :
datas = [ ]
data = json . loads ( request . httprequest . data )
data = json . loads ( request . httprequest . data )
resource . write ( data [ ' values ' ] )
resource . write ( data [ ' values ' ] )
partner_records = request . env [
partner_records = request . env [
str ( model_name ) ] . search_read (
str ( model_name ) ] . search_read (
domain = [ ( ' id ' , ' = ' , resource . id ) ] ,
domain = [ ( ' id ' , ' = ' , resource . id ) ] ,
fields = fields
fields = fields
)
)
return Response ( json . dumps ( { ' updated_record ' : partner_records } ) )
new_data = json . dumps (
{ ' Updated resource ' : partner_records ,
except :
} )
return Response ( json . dumps ( { ' message ' : ' Invalid JSON value(s) passed ' } ) , status = 403 )
datas . append ( new_data )
if method == ' DELETE ' :
return request . make_response ( data = datas )
if not option . is_delete :
return Response (
except :
json . dumps ( { ' message ' : f ' Method not allowed. Please contact your admininstrator to enable { method } method for { model_display_name } record. ' } ) ,
return ( " <html><body><h2>Invalid JSON Data "
status = 405 )
" !</h2></body></html> " )
if method == ' DELETE ' :
if not ' id ' in query :
if not option . is_delete :
return Response ( json . dumps ( { ' message ' : ' No ID Provided ' } ) , status = 403 )
return ( " <html><body><h2>Method Not Allowed "
" </h2></body></html> " )
resource = request . env [ str ( model_name ) ] . browse (
else :
int ( query . get ( ' id ' ) ) )
if rec_id == 0 :
if not resource . exists ( ) :
return ( " <html><body><h2>No ID Provided "
return Response ( json . dumps ( { ' message ' : ' Resource not found ' } ) , status = 404 )
" </h2></body></html> " )
else :
else :
resource = request . env [ str ( model_name ) ] . browse (
int ( rec_id ) )
records = request . env [
if not resource . exists ( ) :
str ( model_name ) ] . search_read (
return ( " <html><body><h2>Resource not found "
domain = [ ( ' id ' , ' = ' , resource . id ) ] ,
" </h2></body></html> " )
fields = fields
else :
)
resource . unlink ( )
records = request . env [
return Response ( json . dumps ( { ' message ' : ' Resource deleted ' , ' data ' : records } ) , status = 202 )
str ( model_name ) ] . search_read (
except :
domain = [ ( ' id ' , ' = ' , resource . id ) ] ,
return Response ( json . dumps ( { ' message ' : ' Internal Server Error ' } ) , status = 500 )
fields = [ ' id ' , ' display_name ' ]
)
remove = json . dumps (
{ " Resource deleted " : records ,
} )
resource . unlink ( )
return request . make_response ( data = remove )
@http . route ( [ ' /send_request ' ] , type = ' http ' ,
@http . route ( [ ' /send_request ' ] , type = ' http ' ,
auth = ' none ' ,
auth = ' none ' ,
@ -196,7 +190,7 @@ class RestApi(http.Controller):
http_method = request . httprequest . method
http_method = request . httprequest . method
api_key = request . httprequest . headers . get ( ' api-key ' )
api_key = request . httprequest . headers . get ( ' api-key ' )
auth_api = self . auth_api_key ( api_key )
auth_api = self . auth_api_key ( api_key )
model = kw . get ( ' model ' )
model = kw . pop ( ' model ' )
username = request . httprequest . headers . get ( ' login ' )
username = request . httprequest . headers . get ( ' login ' )
password = request . httprequest . headers . get ( ' password ' )
password = request . httprequest . headers . get ( ' password ' )
request . session . authenticate ( request . session . db , username ,
request . session . authenticate ( request . session . db , username ,
@ -204,17 +198,12 @@ class RestApi(http.Controller):
model_id = request . env [ ' ir.model ' ] . search (
model_id = request . env [ ' ir.model ' ] . search (
[ ( ' model ' , ' = ' , model ) ] )
[ ( ' model ' , ' = ' , model ) ] )
if not model_id :
if not model_id :
return ( " <html><body><h3>Invalid model, check spelling or maybe "
return Response ( json . dumps (
" the related "
{ ' message ' : ' Invalid model, check spelling or maybe the related module is not installed ' } ) ,
" module is not installed "
status = 403 )
" </h3></body></html> " )
if auth_api == True :
if auth_api == True :
if not kw . get ( ' Id ' ) :
result = self . generate_response ( http_method , model = model_id . id , * * kw )
rec_id = 0
else :
rec_id = int ( kw . get ( ' Id ' ) )
result = self . generate_response ( http_method , model_id . id , rec_id )
return result
return result
else :
else :
return auth_api
return auth_api
@ -239,5 +228,4 @@ class RestApi(http.Controller):
" api-key " : api_key } )
" api-key " : api_key } )
return request . make_response ( data = datas )
return request . make_response ( data = datas )
except :
except :
return ( " <html><body><h2>wrong login credentials "
return Response ( json . dumps ( { ' message ' : ' wrong login credentials ' } ) , status = 401 )
" </h2></body></html> " )