diff --git a/rest_api_odoo/controllers/main.py b/rest_api_odoo/controllers/main.py
index 37169cd3b..20b057bc6 100644
--- a/rest_api_odoo/controllers/main.py
+++ b/rest_api_odoo/controllers/main.py
@@ -23,7 +23,8 @@
import json
import logging
from odoo import http
-from odoo.http import request
+from odoo.http import request, Response
+from ast import literal_eval
_logger = logging.getLogger(__name__)
@@ -38,80 +39,83 @@ class RestApi(http.Controller):
user_id = request.env['res.users'].search([('api_key', '=', api_key)])
if api_key is not None and user_id:
- response = True
+ return True
elif not user_id:
- response = ('
Invalid API Key '
- '!
')
- else:
- response = ("No API Key Provided "
- "!
")
-
- return response
+ return Response(json.dumps({'message': 'Invalid API Key'}), status=401)
+ return Response(json.dumps({'message': 'No API Key Provided'}), status=400)
+
+ def simplest_type(self, input):
+ """Try cast input into native Python class, otherwise return as string"""
+ try:
+ 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
of request and the parameters given"""
+ model = query.pop('model')
option = request.env['connection.api'].search(
[('model_id', '=', model)], limit=1)
model_name = option.model_id.model
+ model_display_name = option.model_id.name
- if method != 'DELETE':
+ data = {}
+ try:
data = json.loads(request.httprequest.data)
- else:
- data = {}
+ except:
+ pass
+
fields = []
if data:
for field in data['fields']:
fields.append(field)
- if not fields and method != 'DELETE':
- return ("No fields selected for the model"
- "
")
+ if '*' in fields:
+ fields = []
+ 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:
- return ("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)
try:
if method == 'GET':
- fields = []
- for field in data['fields']:
- fields.append(field)
+ if not fields:
+ fields.append('id')
if not option.is_get:
- return ("Method Not Allowed"
- "
")
+ return Response(
+ json.dumps({'message': f'Method not allowed. Please contact your admininstrator to enable {method} method for {model_display_name} record.'}),
+ status=405)
else:
- datas = []
- if rec_id != 0:
- partner_records = request.env[
- str(model_name)].search_read(
- domain=[('id', '=', rec_id)],
- fields=fields
- )
- data = json.dumps({
- 'records': partner_records
- })
- 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({
+ domains = []
+ for key, value in query.items():
+ domains.append((key, '=', self.simplest_type(value)))
+ partner_records = request.env[
+ str(model_name)].search_read(
+ domain=domains,
+ fields=fields
+ )
+ return Response(
+ json.dumps({
'records': partner_records
})
- datas.append(data)
- return request.make_response(data=datas)
- except:
- return ("Invalid JSON Data"
- "
")
- if method == 'POST':
- if not option.is_post:
- return ("Method Not Allowed"
- "
")
- else:
+ )
+ if method == 'POST':
+ if not option.is_post:
+ return Response(
+ json.dumps({'message': f'Method not allowed. Please contact your admininstrator to enable {method} method for {model_display_name} record.'}),
+ status=405)
+ if not data or 'values' not in data:
+ return Response(json.dumps({'message': 'No Data Provided'}), status=403)
+
try:
data = json.loads(request.httprequest.data)
- datas = []
new_resource = request.env[str(model_name)].create(
data['values'])
partner_records = request.env[
@@ -119,71 +123,61 @@ class RestApi(http.Controller):
domain=[('id', '=', new_resource.id)],
fields=fields
)
- new_data = json.dumps({'New resource': partner_records, })
- datas.append(new_data)
- return request.make_response(data=datas)
+ return Response(json.dumps({'new_record': partner_records}), status=201)
except:
- return ("Invalid JSON Data"
- "
")
- if method == 'PUT':
- if not option.is_put:
- return ("Method Not Allowed"
- "
")
- else:
- if rec_id == 0:
- return ("No ID Provided"
- "
")
- else:
- resource = request.env[str(model_name)].browse(
- int(rec_id))
- if not resource.exists():
- return ("Resource not found"
- "
")
- else:
- try:
- datas = []
- data = json.loads(request.httprequest.data)
- resource.write(data['values'])
- partner_records = request.env[
- str(model_name)].search_read(
- domain=[('id', '=', resource.id)],
- fields=fields
- )
- new_data = json.dumps(
- {'Updated resource': partner_records,
- })
- datas.append(new_data)
- return request.make_response(data=datas)
-
- except:
- return ("Invalid JSON Data "
- "!
")
- if method == 'DELETE':
- if not option.is_delete:
- return ("Method Not Allowed"
- "
")
- else:
- if rec_id == 0:
- return ("No ID Provided"
- "
")
+ return Response(json.dumps({'message': 'Invalid JSON Data'}), status=403)
+ if method == 'PUT':
+ if not option.is_put:
+ return Response(
+ json.dumps({'message': f'Method not allowed. Please contact your admininstrator to enable {method} method for {model_display_name} record.'}),
+ status=405)
+
+ if not 'id' in query:
+ return Response(json.dumps({'message': 'No ID Provided'}), status=403)
+ if not data or 'values' not in data:
+ return Response(json.dumps({'message': 'No Data Provided'}), status=403)
+
+ resource = request.env[str(model_name)].browse(
+ int(query.get('id')))
+ if not resource.exists():
+ return Response(json.dumps({'message': 'Resource not found'}), status=404)
+
+ try:
+ data = json.loads(request.httprequest.data)
+ resource.write(data['values'])
+ partner_records = request.env[
+ str(model_name)].search_read(
+ domain=[('id', '=', resource.id)],
+ fields=fields
+ )
+ return Response(json.dumps({'updated_record': partner_records}))
+
+ except:
+ return Response(json.dumps({'message': 'Invalid JSON value(s) passed'}), status=403)
+ if method == 'DELETE':
+ if not option.is_delete:
+ return Response(
+ json.dumps({'message': f'Method not allowed. Please contact your admininstrator to enable {method} method for {model_display_name} record.'}),
+ status=405)
+
+ if not 'id' in query:
+ return Response(json.dumps({'message': 'No ID Provided'}), status=403)
+
+ resource = request.env[str(model_name)].browse(
+ int(query.get('id')))
+ if not resource.exists():
+ return Response(json.dumps({'message': 'Resource not found'}), status=404)
else:
- resource = request.env[str(model_name)].browse(
- int(rec_id))
- if not resource.exists():
- return ("Resource not found"
- "
")
- else:
-
- records = request.env[
- str(model_name)].search_read(
- domain=[('id', '=', resource.id)],
- fields=['id', 'display_name']
- )
- remove = json.dumps(
- {"Resource deleted": records,
- })
- resource.unlink()
- return request.make_response(data=remove)
+
+ records = request.env[
+ str(model_name)].search_read(
+ domain=[('id', '=', resource.id)],
+ fields=fields
+ )
+ resource.unlink()
+ return Response(json.dumps({'message': 'Resource deleted', 'data': records}), status=202)
+ except:
+ return Response(json.dumps({'message': 'Internal Server Error'}), status=500)
@http.route(['/send_request'], type='http',
auth='none',
@@ -196,7 +190,7 @@ class RestApi(http.Controller):
http_method = request.httprequest.method
api_key = request.httprequest.headers.get('api-key')
auth_api = self.auth_api_key(api_key)
- model = kw.get('model')
+ model = kw.pop('model')
username = request.httprequest.headers.get('login')
password = request.httprequest.headers.get('password')
request.session.authenticate(request.session.db, username,
@@ -204,17 +198,12 @@ class RestApi(http.Controller):
model_id = request.env['ir.model'].search(
[('model', '=', model)])
if not model_id:
- return ("Invalid model, check spelling or maybe "
- "the related "
- "module is not installed"
- "
")
+ return Response(json.dumps(
+ {'message': 'Invalid model, check spelling or maybe the related module is not installed'}),
+ status=403)
if auth_api == True:
- if not kw.get('Id'):
- rec_id = 0
- else:
- rec_id = int(kw.get('Id'))
- result = self.generate_response(http_method, model_id.id, rec_id)
+ result = self.generate_response(http_method, model=model_id.id, **kw)
return result
else:
return auth_api
@@ -239,5 +228,4 @@ class RestApi(http.Controller):
"api-key": api_key})
return request.make_response(data=datas)
except:
- return ("wrong login credentials"
- "
")
+ return Response(json.dumps({'message': 'wrong login credentials'}), status=401)
diff --git a/rest_api_odoo/static/description/index.html b/rest_api_odoo/static/description/index.html
index bf41854b7..11a198179 100644
--- a/rest_api_odoo/static/description/index.html
+++ b/rest_api_odoo/static/description/index.html
@@ -217,7 +217,7 @@
First of all, we have to add a new parameter in odoo conf.
file.
- server_wide_modules = web, base, rest_api_odoo
+ server_wide_modules = web, base, rest_api_odoo
- This will allow us to send request to server without
selecting database first.
- Incase if you have to
uninstall the module , you have to remove this parameter.
@@ -251,10 +251,10 @@
Next you have to select the database and login.
We have attached Postman collections through which
you can
- authenticate rest api.
+ authenticate REST api.
First, extract the zip file. Then, you will obtain the JSON-format file, which you can directly import into POSTMAN.
- The url format will be like this - http://cybrosys:8016/odoo_connect
+ The url format will be like this - http://cybrosys:8016/odoo_connect
Replace 'cybrosys:8016' with your localhost port number.
You have to provide database name, username and password
@@ -266,9 +266,9 @@
This key will be used when sending api requests to
database.
- The response will be like this - {"Status": "auth
+ The response will be like this - {"Status": "auth
successful", "User": "Mitchell Admin", "api-key":
- "66c2ebab-d4dc-42f0-87d0-d1646e887569"}.
+ "66c2ebab-d4dc-42f0-87d0-d1646e887569"}.
- - You can send GET request to retrieve data from the
+
- You can send
GET
request to retrieve data from the
database.
- The postman collection has been provided with app files for
@@ -318,15 +318,16 @@
- Model can be passed as argument as the technical name , and
also if you want
- specific record you can provide the id as well.
+ specific record you can provide any related fields to the module as well.
- - The format for GET method will be like this - http://cybrosys:8016/send_request?model=res.partner&Id=10.
+
- The format for GET method will be like this -
http://cybrosys:8016/send_request?model=res.partner&Id=10.
- We can specify the fields inside the JSON data, and it will
- be like this - {"fields": ["name", "email"]}.
- - This is the format of api response - {"records": [{"id":
+ be like this -
{"fields": ["name", "email"]}
.
+ - This is the format of api response -
{"records": [{"id":
10, "email": "deco.addict82@example.com", "name": "Deco
- Addict"}]}.
+ Addict"}]}
. If no fields are passed , it will returns
+ just the record's ID. To get all of the fields, set the fields to wildcard - {"fields": ["*"]}
.
@@ -338,7 +339,7 @@
- - Using POST method , you can create new records in the
+
- Using
POST
method , you can create new records in the
database.
- Just make sure you enabled POST method for the model record
@@ -351,18 +352,18 @@
- You can make use of the postman collection that we have
added with app files.
- - The format for sending POST request will be like this - http://cybrosys:8016/send_request?model=res.partner.
+
- The format for sending POST request will be like this -
http://cybrosys:8016/send_request?model=res.partner.
- - This is the format for JSON data - {
+
- This is the format for JSON data -
{
"fields" :["name", "phone"] ,
"values": {"name": "abc",
"phone":"55962441552"
- } }.
+ } }.
- Make sure the data entered in correct format otherwise you
will get 'Invalid JSON data' message.
- - Response will be in this format - {"New resource":
- [{"id": 51, "name": "abc", "phone": "55962441552"}]}.
+
- Response will be in this format -
{"New resource":
+ [{"id": 51, "name": "abc", "phone": "55962441552"}]}
.
@@ -373,7 +374,7 @@
Update Records
- - Updation of records in the database can be done with PUT
+
- Updation of records in the database can be done with
PUT
method.
- You have to provide the model and also the id or the record
@@ -383,14 +384,14 @@
will be always have to send request with your login
credentials. Otherwise, it will be showing access denied.
- - The format for sending PUT request will be like this - http://cybrosys:8016/send_request?model=res.partner&Id=46.
+
- The format for sending PUT request will be like this -
http://cybrosys:8016/send_request?model=res.partner&Id=46.
- Here too you have to provide the JSON data through which the
updates will be done.
- - The response format will be like this - {"Updated
+
- The response format will be like this -
{"Updated
resource": [{"id": 46, "email": "abc@example.com", "name":
- "Toni"}]}.
+ "Toni"}]}.
@@ -401,7 +402,7 @@
- - Database records can be deleted by sending DELETE method
+
- Database records can be deleted by sending
DELETE
method
request.
- For the deletion we have to provide the Model and the record
@@ -410,11 +411,11 @@
- Make sure you have permission to delete files for the
selected model in the rest api record.
- - The delete request format will be like this - http://cybrosys:8016/send_request?model=res.partner&Id=46.
+
- The delete request format will be like this -
http://cybrosys:8016/send_request?model=res.partner&Id=46.
- - The response after successful deletion will be -
+
- The response after successful deletion will be -
{"Resource deleted": [{"id": 46, "email": "abc@example.com",
- "name": "Toni"}]}.
+ "name": "Toni"}]}.