Newer
Older
# -*- coding: utf-8 -*-
# copyright 2022 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact https://www.logilab.fr -- mailto:contact@logilab.fr
#
# This program is free software: you can redistribute it and/or modify it under
# the terms of the GNU Lesser General Public License as published by the Free
# Software Foundation, either version 2.1 of the License, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
# details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
from pyramid.config import Configurator
from pyramid.request import Request
from cubicweb.pyramid.core import CubicWebPyramidRequest
from cubicweb_api.api_transaction import ApiTransactionsRepository
class Context:
def __init__(self, request: Request):
self.request = request
self.cwreq: CubicWebPyramidRequest = request.cw_request
self.repo = self.cwreq.cnx.repo
def render(self):
raise NotImplementedError
class ApiV1Context(Context):
def __getitem__(self, subpath: str):
if subpath == "transaction":
return TransactionContext(self.request)
if subpath == "rql":
return RQLContext(self.request)
if subpath == "help":
return HelpContext(self.request)
class RQLContext(ApiV1Context):
def render(self):
query = self.request.json["query"]
params = self.request.json["params"]
if not query:
return {"error": "No query provided."}
rset = self.cwreq.execute(query, params)
return rset.rows
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
class TransactionContext(ApiV1Context):
def __init__(self, request):
super().__init__(request)
self._transactions: ApiTransactionsRepository = self.repo.api_transactions
def render(self):
action = self.request.json["action"]
if action == "begin":
return self._begin()
elif action == "execute":
return self._execute()
elif action == "commit":
return self._commit()
elif action == "rollback":
return self._rollback()
def _begin(self):
user = self.cwreq.user
return self._transactions.begin_transaction(user)
def _execute(self):
uuid = self.request.json["uuid"]
rql = self.request.json["query"]
params = self.request.json["params"]
rset = self._transactions[uuid].execute(rql, params)
return rset.rows
def _commit(self):
uuid = self.request.json["uuid"]
commit_result = self._transactions[uuid].commit()
self._transactions[uuid].rollback()
return commit_result
def _rollback(self):
uuid = self.request.json["uuid"]
rollback_result = self._transactions[uuid].rollback()
self._transactions.end_transaction(uuid)
return rollback_result
class HelpContext(ApiV1Context):
def render(self):
"""TO IMPLEMENT"""
pass
def includeme(config: Configurator):
repo = config.registry["cubicweb.repository"]
repo.api_transactions = ApiTransactionsRepository(repo)
config.add_route("api_v1", r"/api/v1/*traverse", factory=ApiV1Context)