Browse Source

Add pagination support

* Simplify error handling for all methods
pull/345/head
drpsyko101 9 months ago
parent
commit
fa298553b4
  1. 212
      rest_api_odoo/controllers/main.py
  2. 10
      rest_api_odoo/static/description/index.html

212
rest_api_odoo/controllers/main.py

@ -70,171 +70,143 @@ class RestApi(http.Controller):
def generate_response(self, method, **query): 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(
[("model_id", "=", model)], limit=1
)
model_name = option.model_id.model
model_display_name = option.model_id.name
try: try:
data = json.loads(request.httprequest.data) model = query.pop("model")
except Exception: option = request.env["connection.api"].search(
data = {} [("model_id", "=", model)], limit=1
)
fields = [] model_name = option.model_id.model
if data: model_display_name = option.model_id.name
for field in data["fields"]:
fields.append(field)
# Return records' ID by default if not specified try:
if not fields: data = json.loads(request.httprequest.data)
fields.append("id") except Exception:
data = {}
# Get all model's fields if wildcard is used
if "*" in fields:
fields = [] fields = []
record_fields = request.env[str(model_name)].fields_get( if data:
[], attributes=["type"] for field in data["fields"]:
)
for field, value in record_fields.items():
value_type = value.get("type")
if not (value_type == "binary"):
fields.append(field) fields.append(field)
if not option:
return Response( # Return records' ID by default if not specified
json.dumps( if not fields:
{ fields.append("id")
"message": f"No Record Created for the model. Please contact your admininstrator to enable {method} method for {model_display_name} record."
} # Get all model's fields if wildcard is used
), if "*" in fields:
status=403, fields = []
) record_fields = request.env[str(model_name)].fields_get(
if method == "GET": [], attributes=["type"]
if not option.is_get:
return Response(
json.dumps(
{
"message": f"Method not allowed. Please contact your admininstrator to enable {method} method for {model_display_name} record."
}
),
status=405,
) )
for field, value in record_fields.items():
value_type = value.get("type")
if not (value_type == "binary"):
fields.append(field)
if not option:
raise NotImplementedError("No Record Created for the model. ")
if method == "GET":
if not option.is_get:
raise NameError()
limit = 0
if query.get("limit"):
limit = int(str(query.get("limit")))
offset = 0
if query.get("offset"):
offset = int(str(query.get("offset")))
domains = [] domains = []
for key, value in query.items(): for key, value in query.items():
domains.append((key, "=", self.simplest_type(value))) if not (key == "limit" or key == "offset"):
partner_records = request.env[str(model_name)].search_read( domains.append((key, "=", self.simplest_type(value)))
domain=domains, fields=fields partner_records = request.env[str(model_name)].search_read(
) domains, fields, limit=limit, offset=offset
)
return Response(
json.dumps({"records": self.sanitize_records(partner_records)})
)
if method == "POST":
if not option.is_post:
return Response( return Response(
json.dumps( json.dumps({"records": self.sanitize_records(partner_records)})
{
"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: if method == "POST":
return Response(json.dumps({"message": "No Data Provided"}), status=403) if not option.is_post:
raise NotImplementedError()
if not data or "values" not in data:
raise ValueError("No Data Provided")
try:
data = json.loads(request.httprequest.data) data = json.loads(request.httprequest.data)
new_resource = request.env[str(model_name)].create(data["values"]) new_resource = request.env[str(model_name)].create(data["values"])
partner_records = request.env[str(model_name)].search_read( partner_records = request.env[str(model_name)].search_read(
domain=[("id", "=", new_resource.id)], fields=fields [("id", "=", new_resource.id)], fields
) )
return Response( return Response(
json.dumps({"new_record": self.sanitize_records(partner_records)}), json.dumps({"new_record": self.sanitize_records(partner_records)}),
status=201, status=201,
) )
except Exception: if method == "PUT":
return Response( if not option.is_put:
json.dumps({"message": "Invalid JSON Data"}), status=403 raise NotImplementedError()
)
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 "id" not in query: if "id" not in query:
return Response(json.dumps({"message": "No ID Provided"}), status=403) raise ValueError("No ID Provided")
if not data or "values" not in data: if not data or "values" not in data:
return Response(json.dumps({"message": "No Data Provided"}), status=403) raise ValueError("No Data Provided")
resource_id = str(query.get("id")) resource_id = str(query.get("id"))
resource = request.env[str(model_name)].browse(int(resource_id)) resource = request.env[str(model_name)].browse(int(resource_id))
if not resource.exists(): if not resource.exists():
return Response( raise ValueError("Resource not found")
json.dumps({"message": "Resource not found"}), status=404
)
try:
data = json.loads(request.httprequest.data) data = json.loads(request.httprequest.data)
resource.write(data["values"]) resource.write(data["values"])
partner_records = request.env[str(model_name)].search_read( partner_records = request.env[str(model_name)].search_read(
domain=[("id", "=", resource.id)], fields=fields [("id", "=", resource.id)], fields
) )
return Response( return Response(
json.dumps( json.dumps(
{"updated_record": self.sanitize_records(partner_records)} {"updated_record": self.sanitize_records(partner_records)}
) )
) )
if method == "DELETE":
if not option.is_delete:
raise NotImplementedError()
except Exception: if "id" not in query:
return Response( raise ValueError("No ID Provided")
json.dumps({"message": "Invalid JSON value(s) passed"}),
status=403, resource_id = str(query.get("id"))
resource = request.env[str(model_name)].browse(int(resource_id))
if not resource.exists():
raise ValueError("Resource not found")
partner_records = request.env[str(model_name)].search_read(
[("id", "=", resource.id)], fields
) )
if method == "DELETE": resource.unlink()
if not option.is_delete:
return Response( return Response(
json.dumps( json.dumps(
{ {
"message": f"Method not allowed. Please contact your admininstrator to enable {method} method for {model_display_name} record." "message": "Resource deleted",
"data": self.sanitize_records(partner_records),
} }
), ),
status=405, status=202,
)
if "id" not in query:
return Response(json.dumps({"message": "No ID Provided"}), status=403)
resource_id = str(query.get("id"))
resource = request.env[str(model_name)].browse(int(resource_id))
if not resource.exists():
return Response(
json.dumps({"message": "Resource not found"}), status=404
) )
partner_records = request.env[str(model_name)].search_read( # If not using any method above, simply return an error
domain=[("id", "=", resource.id)], fields=fields raise NotImplementedError()
) except ValueError as e:
resource.unlink() return Response(json.dumps({"message": e.args[0]}), status=403)
except NotImplementedError as e:
return Response( return Response(
json.dumps( json.dumps(
{ {
"message": "Resource deleted", "message": f"Method not allowed. {e.args[0]}Please contact your admininstrator to enable {method} method for {model_display_name or 'this'} record."
"data": self.sanitize_records(partner_records),
} }
), ),
status=202, status=405,
)
except Exception:
return Response(
json.dumps({"message": "Internal server error"}), status=500
) )
# If not using any method above, simply return an error
return Response(json.dumps({"message": "Method not allowed"}), status=405)
@http.route( @http.route(
["/send_request"], ["/send_request"],
@ -290,7 +262,7 @@ class RestApi(http.Controller):
datas = json.dumps( datas = json.dumps(
{"Status": "auth successful", "User": user.name, "api-key": api_key} {"Status": "auth successful", "User": user.name, "api-key": api_key}
) )
return Response(datas, status=200) return Response(datas)
except Exception: except Exception:
return Response( return Response(
json.dumps({"message": "wrong login credentials"}), status=401 json.dumps({"message": "wrong login credentials"}), status=401

10
rest_api_odoo/static/description/index.html

@ -323,11 +323,15 @@
<li>The format for GET method will be like this - <code>http://cybrosys:8016/send_request?model=res.partner&Id=10.</code> <li>The format for GET method will be like this - <code>http://cybrosys:8016/send_request?model=res.partner&Id=10.</code>
</li> </li>
<li>We can specify the fields inside the JSON data, and it will <li>We can specify the fields inside the JSON data, and it will
be like this - <code>{"fields": ["name", "email"]}</code>.</li> be like this - <code>{"fields": ["name", "email"]}</code>.
If no fields are passed , it will returns just the record's ID.
To get all of the fields, set the fields to wildcard - <code>{"fields": ["*"]}</code>.
Pagination can also be used by adding <code>{"limit": 10, "offset": 0}</code>
to the query parameter above.
</li>
<li>This is the format of api response - <code>{"records": [{"id": <li>This is the format of api response - <code>{"records": [{"id":
10, "email": "deco.addict82@example.com", "name": "Deco 10, "email": "deco.addict82@example.com", "name": "Deco
Addict"}]}</code>. If no fields are passed , it will returns Addict"}]}</code>.
just the record's ID. To get all of the fields, set the fields to wildcard - <code>{"fields": ["*"]}</code>.
</li> </li>
</ul> </ul>

Loading…
Cancel
Save