py-client-cap 0.1.7__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- py_client_cap/__init__.py +4 -0
- py_client_cap/crud_php_api.py +143 -0
- py_client_cap/crud_php_table.py +87 -0
- py_client_cap/manager.py +28 -0
- py_client_cap/models/__init__.py +4 -0
- py_client_cap/models/apiresponse.py +18 -0
- py_client_cap/models/column.py +8 -0
- py_client_cap/models/item.py +12 -0
- py_client_cap/models/table.py +30 -0
- py_client_cap-0.1.7.dist-info/METADATA +228 -0
- py_client_cap-0.1.7.dist-info/RECORD +13 -0
- py_client_cap-0.1.7.dist-info/WHEEL +5 -0
- py_client_cap-0.1.7.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import requests
|
|
2
|
+
from dataclasses import dataclass, asdict
|
|
3
|
+
from typing import Optional, Dict, Any, List
|
|
4
|
+
from .models import ApiResponse, Item, Column, Table
|
|
5
|
+
|
|
6
|
+
class CrudPHPApi:
|
|
7
|
+
def __init__(self, base_url: str, api_key: Optional[str] = None, timeout: int = 10):
|
|
8
|
+
self.base_url = base_url.rstrip("/")
|
|
9
|
+
self.timeout = timeout
|
|
10
|
+
self.session = requests.Session()
|
|
11
|
+
default_headers = {
|
|
12
|
+
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36',
|
|
13
|
+
'Content-Type': 'application/json',
|
|
14
|
+
'Accept': 'application/json'
|
|
15
|
+
}
|
|
16
|
+
if api_key:
|
|
17
|
+
default_headers['Authorization'] = f"Bearer {api_key}"
|
|
18
|
+
default_headers['X-App-Token'] = api_key
|
|
19
|
+
self.session.headers.update(default_headers)
|
|
20
|
+
|
|
21
|
+
def _request(self, method: str, endpoint: str, data: Optional[Dict] = None, params: Optional[Dict] = None, headers: Optional[Dict] = None) -> ApiResponse:
|
|
22
|
+
url = f"{self.base_url}/{endpoint.lstrip('/')}"
|
|
23
|
+
try:
|
|
24
|
+
kwargs = {
|
|
25
|
+
"method": method.upper(),
|
|
26
|
+
"url": url,
|
|
27
|
+
"json": data,
|
|
28
|
+
"params": params,
|
|
29
|
+
"timeout": self.timeout
|
|
30
|
+
}
|
|
31
|
+
if headers is not None:
|
|
32
|
+
kwargs["headers"] = headers
|
|
33
|
+
res = self.session.request(**kwargs)
|
|
34
|
+
try:
|
|
35
|
+
payload = res.json() if res.content else None
|
|
36
|
+
except ValueError:
|
|
37
|
+
payload = res.text
|
|
38
|
+
if res.ok:
|
|
39
|
+
return ApiResponse(status_code=res.status_code, success=True, data=payload)
|
|
40
|
+
else:
|
|
41
|
+
error_msg = payload.get("message") if isinstance(payload, dict) and "message" in payload else res.text
|
|
42
|
+
return ApiResponse(status_code=res.status_code, success=False, error=error_msg, raw_response=payload)
|
|
43
|
+
except requests.exceptions.RequestException as err:
|
|
44
|
+
return ApiResponse(status_code=0, success=False, error=f"Connection Error: {str(err)}")
|
|
45
|
+
|
|
46
|
+
def create(self, endpoint: str, payload: Dict[str, Any], headers: Optional[Dict] = None) -> ApiResponse:
|
|
47
|
+
return self._request("POST", endpoint, data=payload, headers=headers)
|
|
48
|
+
|
|
49
|
+
def read(self, endpoint: str, item_id: Optional[int] = None, query_params: Optional[Dict] = None, headers: Optional[Dict] = None) -> ApiResponse:
|
|
50
|
+
return self._request("GET", f"{endpoint}/{item_id}" if item_id else endpoint, params=query_params, headers=headers)
|
|
51
|
+
|
|
52
|
+
def update(self, endpoint: str, item_id: int, payload: Dict[str, Any], headers: Optional[Dict] = None) -> ApiResponse:
|
|
53
|
+
return self._request("PUT", f"{endpoint}/{item_id}", data=payload, headers=headers)
|
|
54
|
+
|
|
55
|
+
def delete(self, endpoint: str, item_id: int, headers: Optional[Dict] = None) -> ApiResponse:
|
|
56
|
+
return self._request("DELETE", f"{endpoint}/{item_id}", headers=headers)
|
|
57
|
+
|
|
58
|
+
def export_table_structure(self, openapi_endpoint: str, table_name: str) -> ApiResponse:
|
|
59
|
+
response = self.read(openapi_endpoint)
|
|
60
|
+
if not response.success:
|
|
61
|
+
return response
|
|
62
|
+
|
|
63
|
+
openapi_data = response.data
|
|
64
|
+
if not isinstance(openapi_data, dict):
|
|
65
|
+
return ApiResponse(status_code=400, success=False, error="Invalid OpenAPI response")
|
|
66
|
+
|
|
67
|
+
schemas = openapi_data.get("components", {}).get("schemas", {})
|
|
68
|
+
|
|
69
|
+
table_schema = schemas.get(table_name)
|
|
70
|
+
if not table_schema:
|
|
71
|
+
table_schema = schemas.get(f"read-{table_name}")
|
|
72
|
+
if not table_schema:
|
|
73
|
+
list_schema = schemas.get(f"list-{table_name}")
|
|
74
|
+
if list_schema:
|
|
75
|
+
table_schema = list_schema.get("properties", {}).get("records", {}).get("items", {})
|
|
76
|
+
|
|
77
|
+
if not table_schema or "properties" not in table_schema:
|
|
78
|
+
return ApiResponse(status_code=404, success=False, error=f"Table schema for '{table_name}' not found in OpenAPI specification")
|
|
79
|
+
|
|
80
|
+
properties = table_schema["properties"]
|
|
81
|
+
columns = []
|
|
82
|
+
init_params = []
|
|
83
|
+
|
|
84
|
+
for col_name, col_details in properties.items():
|
|
85
|
+
openapi_type = col_details.get("type", "string")
|
|
86
|
+
type_mapping = {
|
|
87
|
+
"integer": "int",
|
|
88
|
+
"number": "float",
|
|
89
|
+
"boolean": "bool",
|
|
90
|
+
"string": "str"
|
|
91
|
+
}
|
|
92
|
+
py_type = type_mapping.get(openapi_type, "str")
|
|
93
|
+
|
|
94
|
+
default_value = col_details.get("default")
|
|
95
|
+
|
|
96
|
+
if default_value is not None:
|
|
97
|
+
if py_type == "str":
|
|
98
|
+
default_repr = f"'{default_value}'"
|
|
99
|
+
else:
|
|
100
|
+
default_repr = str(default_value)
|
|
101
|
+
init_param = f"{col_name}: {py_type} = {default_repr}"
|
|
102
|
+
else:
|
|
103
|
+
fallback = "''" if py_type == "str" else ("0" if py_type in ["int", "float"] else "False")
|
|
104
|
+
init_param = f"{col_name}: {py_type} = {fallback}"
|
|
105
|
+
|
|
106
|
+
columns.append(Column(name=col_name, data_type=py_type))
|
|
107
|
+
init_params.append(init_param)
|
|
108
|
+
|
|
109
|
+
class_name = f"{table_name.capitalize()}Table"
|
|
110
|
+
class_body = f"class {class_name}:\n"
|
|
111
|
+
for column in columns:
|
|
112
|
+
class_body += f" {column.name}: {column.data_type}\n"
|
|
113
|
+
|
|
114
|
+
class_body += " def __init__(self, " + ', '.join(init_params) + "):\n"
|
|
115
|
+
init_assignments = [f"self.{column.name} = {column.name}" for column in columns]
|
|
116
|
+
class_body += " " + "\n ".join(init_assignments) + "\n"
|
|
117
|
+
|
|
118
|
+
class_body += "\n def to_dict(self) -> Dict[str, Any]:\n"
|
|
119
|
+
class_body += " return {\n"
|
|
120
|
+
for column in columns:
|
|
121
|
+
class_body += f" '{column.name}': self.{column.name},\n"
|
|
122
|
+
class_body += " }"
|
|
123
|
+
|
|
124
|
+
return ApiResponse(status_code=200, success=True, data={
|
|
125
|
+
"class_name": class_name,
|
|
126
|
+
"class_body": class_body
|
|
127
|
+
})
|
|
128
|
+
|
|
129
|
+
def list_tables(self) -> List[str]:
|
|
130
|
+
"""Estrae e normalizza la lista univoca di tutte le tabelle dai path OpenAPI."""
|
|
131
|
+
response = self.read('openapi')
|
|
132
|
+
|
|
133
|
+
if not response.success or not isinstance(response.data, dict):
|
|
134
|
+
return []
|
|
135
|
+
|
|
136
|
+
paths = response.data.get("paths", {})
|
|
137
|
+
tables = set()
|
|
138
|
+
for path in paths.keys():
|
|
139
|
+
parts = path.strip("/").split("/")
|
|
140
|
+
if len(parts) >= 2 and parts[0] == "records":
|
|
141
|
+
tables.add(parts[1])
|
|
142
|
+
|
|
143
|
+
return sorted(list(tables))
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
from typing import Optional, Dict, Any, List, Union
|
|
2
|
+
from .models import ApiResponse
|
|
3
|
+
from py_client_cap import CrudPHPApi
|
|
4
|
+
|
|
5
|
+
class CrudPHPTable(CrudPHPApi):
|
|
6
|
+
def __init__(self, base_url: str, table_name: str, api_key: Optional[str] = None, timeout: int = 10):
|
|
7
|
+
super().__init__(base_url=base_url, api_key=api_key, timeout=timeout)
|
|
8
|
+
self.table_name = table_name.strip("/")
|
|
9
|
+
self.last_total_count: Optional[int] = None
|
|
10
|
+
|
|
11
|
+
def _build_table_endpoint(self, action_path: str = "") -> str:
|
|
12
|
+
parts = ["records", self.table_name]
|
|
13
|
+
if action_path:
|
|
14
|
+
parts.append(str(action_path).lstrip("/"))
|
|
15
|
+
return "/".join(parts)
|
|
16
|
+
|
|
17
|
+
def list_rows(
|
|
18
|
+
self,
|
|
19
|
+
filters: Optional[Union[str, List[str]]] = None,
|
|
20
|
+
logic: str = "and", # "and" oppure "or"
|
|
21
|
+
order: Optional[Union[str, List[str]]] = None,
|
|
22
|
+
page: Optional[int] = None,
|
|
23
|
+
size: Optional[int] = None,
|
|
24
|
+
query_params: Optional[Dict[str, Any]] = None,
|
|
25
|
+
headers: Optional[Dict[str, str]] = None
|
|
26
|
+
) -> ApiResponse:
|
|
27
|
+
endpoint = self._build_table_endpoint()
|
|
28
|
+
params = dict(query_params) if query_params else {}
|
|
29
|
+
|
|
30
|
+
if filters:
|
|
31
|
+
if isinstance(filters, list):
|
|
32
|
+
if logic.lower() == "or":
|
|
33
|
+
for i, f in enumerate(filters, start=1):
|
|
34
|
+
params[f"filter{i}"] = f
|
|
35
|
+
else:
|
|
36
|
+
params["filter[]"] = filters
|
|
37
|
+
else:
|
|
38
|
+
params["filter"] = filters
|
|
39
|
+
|
|
40
|
+
if order:
|
|
41
|
+
if isinstance(order, list):
|
|
42
|
+
params["order[]"] = order
|
|
43
|
+
else:
|
|
44
|
+
params["order"] = order
|
|
45
|
+
|
|
46
|
+
if page is not None:
|
|
47
|
+
params["page"] = page
|
|
48
|
+
if size is not None:
|
|
49
|
+
params["size"] = size
|
|
50
|
+
|
|
51
|
+
response = self._request("GET", endpoint, params=params, headers=headers)
|
|
52
|
+
|
|
53
|
+
# --- PARTE CORRETTA ---
|
|
54
|
+
if response.success and isinstance(response.data, dict):
|
|
55
|
+
# Prima verifica se c'è la chiave metadata "results" (totale assoluto)
|
|
56
|
+
if "results" in response.data:
|
|
57
|
+
self.last_total_count = response.data.get("results")
|
|
58
|
+
else:
|
|
59
|
+
# Fallback: conta i record fisici ricevuti nella pagina
|
|
60
|
+
records = response.data.get("records")
|
|
61
|
+
if isinstance(records, list):
|
|
62
|
+
self.last_total_count = len(records)
|
|
63
|
+
else:
|
|
64
|
+
self.last_total_count = 0
|
|
65
|
+
elif response.success and isinstance(response.data, list):
|
|
66
|
+
self.last_total_count = len(response.data)
|
|
67
|
+
|
|
68
|
+
return response
|
|
69
|
+
|
|
70
|
+
def get_row(self, row_id: Any, query_params: Optional[Dict] = None, headers: Optional[Dict] = None) -> ApiResponse:
|
|
71
|
+
endpoint = self._build_table_endpoint(row_id)
|
|
72
|
+
return self._request("GET", endpoint, params=query_params, headers=headers)
|
|
73
|
+
|
|
74
|
+
def insert_row(self, payload: Dict[str, Any], headers: Optional[Dict] = None) -> ApiResponse:
|
|
75
|
+
endpoint = self._build_table_endpoint()
|
|
76
|
+
return self._request("POST", endpoint, data=payload, headers=headers)
|
|
77
|
+
|
|
78
|
+
def update_row(self, row_id: Any, payload: Dict[str, Any], headers: Optional[Dict] = None) -> ApiResponse:
|
|
79
|
+
endpoint = self._build_table_endpoint(row_id)
|
|
80
|
+
return self._request("PUT", endpoint, data=payload, headers=headers)
|
|
81
|
+
|
|
82
|
+
def delete_row(self, row_id: Any, headers: Optional[Dict] = None) -> ApiResponse:
|
|
83
|
+
endpoint = self._build_table_endpoint(row_id)
|
|
84
|
+
return self._request("DELETE", endpoint, headers=headers)
|
|
85
|
+
|
|
86
|
+
def to_class(self, headers: Optional[Dict] = None) -> ApiResponse:
|
|
87
|
+
return self.export_table_structure('openapi', self.table_name)
|
py_client_cap/manager.py
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
from typing import List, Optional
|
|
2
|
+
from py_client_cap import CrudPHPApi, CrudPHPTable
|
|
3
|
+
|
|
4
|
+
class CrudPHPDB:
|
|
5
|
+
def __init__(self, base_url: str, api_key: Optional[str] = None, timeout: int = 10):
|
|
6
|
+
self.api = CrudPHPApi(base_url=base_url, api_key=api_key, timeout=timeout)
|
|
7
|
+
self._tables_cache: Optional[List[str]] = None
|
|
8
|
+
self._base_url = base_url
|
|
9
|
+
self._api_key = api_key
|
|
10
|
+
self._timeout = timeout
|
|
11
|
+
|
|
12
|
+
def list_tables(self) -> List[str]:
|
|
13
|
+
if self._tables_cache is None:
|
|
14
|
+
self._tables_cache = self.api.list_tables()
|
|
15
|
+
return self._tables_cache
|
|
16
|
+
|
|
17
|
+
def table(self, table_name: str, raise_if_not_found: bool = False) -> Optional[CrudPHPTable]:
|
|
18
|
+
tables = self.list_tables()
|
|
19
|
+
if table_name not in tables:
|
|
20
|
+
if raise_if_not_found:
|
|
21
|
+
raise KeyError(f"La tabella '{table_name}' non è stata trovata.")
|
|
22
|
+
return None
|
|
23
|
+
return CrudPHPTable(
|
|
24
|
+
base_url=self._base_url,
|
|
25
|
+
table_name=table_name,
|
|
26
|
+
api_key=self._api_key,
|
|
27
|
+
timeout=self._timeout
|
|
28
|
+
)
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
from typing import Optional, Dict, Any
|
|
2
|
+
from dataclasses import dataclass, asdict
|
|
3
|
+
|
|
4
|
+
@dataclass
|
|
5
|
+
class ApiResponse:
|
|
6
|
+
status_code: int
|
|
7
|
+
success: bool
|
|
8
|
+
data: Optional[Any] = None
|
|
9
|
+
error: Optional[str] = None
|
|
10
|
+
raw_response: Optional[Dict] = None
|
|
11
|
+
|
|
12
|
+
def to_dict(self) -> Dict[str, Any]:
|
|
13
|
+
return {
|
|
14
|
+
"status_code": self.status_code,
|
|
15
|
+
"success": self.success,
|
|
16
|
+
"data": self.data,
|
|
17
|
+
"error": self.error
|
|
18
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
from dataclasses import dataclass, asdict
|
|
2
|
+
from typing import Optional
|
|
3
|
+
|
|
4
|
+
@dataclass
|
|
5
|
+
class Item:
|
|
6
|
+
id: Optional[int] = None
|
|
7
|
+
title: str = ""
|
|
8
|
+
description: str = ""
|
|
9
|
+
status: str = "active"
|
|
10
|
+
|
|
11
|
+
def to_dict(self):
|
|
12
|
+
return {k: v for k, v in asdict(self).items() if v is not None}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
from typing import Any, List, Optional
|
|
3
|
+
from .column import Column
|
|
4
|
+
|
|
5
|
+
@dataclass
|
|
6
|
+
class Table:
|
|
7
|
+
name: str
|
|
8
|
+
columns: List[Column]
|
|
9
|
+
|
|
10
|
+
def export_table_structure(self) -> str:
|
|
11
|
+
# Implementazione della funzione per esportare la struttura della tabella
|
|
12
|
+
class_name = f"{self.name.capitalize()}Table"
|
|
13
|
+
class_body = f"class {class_name}:\n"
|
|
14
|
+
|
|
15
|
+
# Aggiungi gli attributi delle colonne
|
|
16
|
+
for column in self.columns:
|
|
17
|
+
class_body += f" {column.name}: {column.data_type}\n"
|
|
18
|
+
|
|
19
|
+
# Aggiungi il metodo per creare un oggetto della tabella
|
|
20
|
+
class_body += " def __init__(self, " + ', '.join([f"{column.name}: {column.data_type}" for column in self.columns]) + "):\n"
|
|
21
|
+
class_body += " self." + ', '.join([f"{column.name} = {column.name}" for column in self.columns])
|
|
22
|
+
|
|
23
|
+
# Aggiungi il metodo per esportare la struttura della tabella
|
|
24
|
+
class_body += "\n def to_dict(self) -> Dict[str, Any]:\n"
|
|
25
|
+
class_body += " return {\n"
|
|
26
|
+
for column in self.columns:
|
|
27
|
+
class_body += f" '{column.name}': self.{column.name},\n"
|
|
28
|
+
class_body += " }"
|
|
29
|
+
|
|
30
|
+
return class_body
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: py_client_cap
|
|
3
|
+
Version: 0.1.7
|
|
4
|
+
Summary: Client Python e libreria REST API per la gestione automatizzata di database tramite backend PHP CRUD (codice su Git). Integrazione rapida via HTTP e JSON
|
|
5
|
+
Home-page: https://www.newstechnology.eu
|
|
6
|
+
Author: Daniele Frulla
|
|
7
|
+
Author-email: daniele.frulla@newstechnology.eu
|
|
8
|
+
Keywords: python,php,crud,rest-api,database-manager,git-repo,php-crud-api
|
|
9
|
+
Description-Content-Type: text/markdown
|
|
10
|
+
Requires-Dist: requests==2.34.2
|
|
11
|
+
Dynamic: author
|
|
12
|
+
Dynamic: author-email
|
|
13
|
+
Dynamic: description
|
|
14
|
+
Dynamic: description-content-type
|
|
15
|
+
Dynamic: home-page
|
|
16
|
+
Dynamic: keywords
|
|
17
|
+
Dynamic: requires-dist
|
|
18
|
+
Dynamic: summary
|
|
19
|
+
|
|
20
|
+
# Libreria Python Client CRUD PHP API
|
|
21
|
+
|
|
22
|
+
Questo documento racchiude tutto il necessario per utilizzare la libreria: le istruzioni d'uso (README), il codice sorgente completo e la suite di test unitari con mock.
|
|
23
|
+
Le api che si andranno ad utilizzare sono quelle create con la libreria [PHPCrudApi](https://github.com/mevdschee/php-crud-api)
|
|
24
|
+
|
|
25
|
+
## Installazione
|
|
26
|
+
|
|
27
|
+
1. **PIP**:
|
|
28
|
+
```python
|
|
29
|
+
pip install py_client_cap
|
|
30
|
+
```
|
|
31
|
+
## Uso
|
|
32
|
+
|
|
33
|
+
### 1. Utilizzo della libreria
|
|
34
|
+
|
|
35
|
+
```python
|
|
36
|
+
from py_client_cap import CrudPHPDB
|
|
37
|
+
|
|
38
|
+
base_url = "http://127.0.0.1:8082/modules/api/index.php"
|
|
39
|
+
api_key = "test-token"
|
|
40
|
+
|
|
41
|
+
db = CrudPHPDB(base_url=base_url, api_key=api_key)
|
|
42
|
+
|
|
43
|
+
# Ritorna le tabelle
|
|
44
|
+
tables = db.list_tables()
|
|
45
|
+
|
|
46
|
+
# Usa le tabelle
|
|
47
|
+
table_client = db.table( 'Tabella1', raise_if_not_found=True)
|
|
48
|
+
response_records = table_client.list_rows(page=1,size=1)
|
|
49
|
+
records_count = table_client.last_total_count
|
|
50
|
+
|
|
51
|
+
#Il totale delle tabelle viene restituito solo se la ricerca e' con page=x
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
# Gestire le Tabelle
|
|
55
|
+
|
|
56
|
+
## Classe CrudPHPTable
|
|
57
|
+
|
|
58
|
+
La classe `CrudPHPTable` è stata creata per gestire le operazioni su una tabella PHP API. Questa classe estende la classe base `CrudPHPApi` e aggiunge funzionalità per elencare i record, selezionare un singolo record, inserire un nuovo record, aggiornare un record esistente e eliminare un record.
|
|
59
|
+
|
|
60
|
+
### Costruttore
|
|
61
|
+
|
|
62
|
+
```python
|
|
63
|
+
def __init__(self, base_url: str, table_name: str, api_key: Optional[str] = None, timeout: int = 10):
|
|
64
|
+
"""
|
|
65
|
+
Inizializza la classe CrudPHPTable.
|
|
66
|
+
|
|
67
|
+
Args:
|
|
68
|
+
base_url (str): URL base del server PHP API.
|
|
69
|
+
table_name (str): Nome della tabella a cui si intende accedere.
|
|
70
|
+
api_key (str, optional): Chiave API per autenticazione. Default è None.
|
|
71
|
+
timeout (int, optional): Timeout per le richieste HTTP. Default è 10.
|
|
72
|
+
"""
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Metodi
|
|
76
|
+
|
|
77
|
+
#### `_build_table_endpoint`
|
|
78
|
+
|
|
79
|
+
```python
|
|
80
|
+
def _build_table_endpoint(self, action_path: str = "") -> str:
|
|
81
|
+
"""
|
|
82
|
+
Costruisce l'endpoint della tabella.
|
|
83
|
+
|
|
84
|
+
Args:
|
|
85
|
+
action_path (str, optional): Percorso di azione specifico. Default è None.
|
|
86
|
+
|
|
87
|
+
Returns:
|
|
88
|
+
str: Endpoint della tabella.
|
|
89
|
+
"""
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
#### `list_rows`
|
|
93
|
+
|
|
94
|
+
```python
|
|
95
|
+
def list_rows(
|
|
96
|
+
self,
|
|
97
|
+
filters: Optional[Union[str, List[str]]] = None,
|
|
98
|
+
logic: str = "and", # "and" oppure "or"
|
|
99
|
+
order: Optional[Union[str, List[str]]] = None,
|
|
100
|
+
page: Optional[int] = None,
|
|
101
|
+
size: Optional[int] = None,
|
|
102
|
+
query_params: Optional[Dict[str, Any]] = None,
|
|
103
|
+
headers: Optional[Dict[str, str]] = None
|
|
104
|
+
) -> ApiResponse:
|
|
105
|
+
"""
|
|
106
|
+
Effettua una richiesta GET per elencare i record della tabella.
|
|
107
|
+
|
|
108
|
+
Args:
|
|
109
|
+
filters (Union[str, List[str]], optional): Filtro da applicare alle query. Default è None.
|
|
110
|
+
logic (str, optional): Logica di filtre ("and" o "or"). Default è "and".
|
|
111
|
+
order (Union[str, List[str]], optional): Ordinamento delle risposte. Default è None.
|
|
112
|
+
page (int, optional): Pagina di risposta da ottenere. Default è None.
|
|
113
|
+
size (int, optional): Numero di record per pagina. Default è None.
|
|
114
|
+
query_params (Dict[str, Any], optional): Parametri di query. Default è None.
|
|
115
|
+
headers (Dict[str, str], optional): Header HTTP. Default è None.
|
|
116
|
+
|
|
117
|
+
Returns:
|
|
118
|
+
ApiResponse: Risposta della richiesta.
|
|
119
|
+
"""
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
#### `get_row`
|
|
123
|
+
|
|
124
|
+
```python
|
|
125
|
+
def get_row(self, row_id: Any, query_params: Optional[Dict[str, Any]] = None, headers: Optional[Dict[str, str]] = None) -> ApiResponse:
|
|
126
|
+
"""
|
|
127
|
+
Effettua una richiesta GET per selezionare un singolo record della tabella.
|
|
128
|
+
|
|
129
|
+
Args:
|
|
130
|
+
row_id (Any): Identificatore del record.
|
|
131
|
+
query_params (Dict[str, Any], optional): Parametri di query. Default è None.
|
|
132
|
+
headers (Dict[str, str], optional): Header HTTP. Default è None.
|
|
133
|
+
|
|
134
|
+
Returns:
|
|
135
|
+
ApiResponse: Risposta della richiesta.
|
|
136
|
+
"""
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
#### `insert_row`
|
|
140
|
+
|
|
141
|
+
```python
|
|
142
|
+
def insert_row(self, payload: Dict[str, Any], headers: Optional[Dict[str, str]] = None) -> ApiResponse:
|
|
143
|
+
"""
|
|
144
|
+
Effettua una richiesta POST per inserire un nuovo record nella tabella.
|
|
145
|
+
|
|
146
|
+
Args:
|
|
147
|
+
payload (Dict[str, Any]): Payload del nuovo record.
|
|
148
|
+
headers (Dict[str, str], optional): Header HTTP. Default è None.
|
|
149
|
+
|
|
150
|
+
Returns:
|
|
151
|
+
ApiResponse: Risposta della richiesta.
|
|
152
|
+
"""
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
#### `update_row`
|
|
156
|
+
|
|
157
|
+
```python
|
|
158
|
+
def update_row(self, row_id: Any, payload: Dict[str, Any], headers: Optional[Dict[str, str]] = None) -> ApiResponse:
|
|
159
|
+
"""
|
|
160
|
+
Effettua una richiesta PUT per aggiornare un record esistente nella tabella.
|
|
161
|
+
|
|
162
|
+
Args:
|
|
163
|
+
row_id (Any): Identificatore del record.
|
|
164
|
+
payload (Dict[str, Any]): Payload dell'aggiornamento.
|
|
165
|
+
headers (Dict[str, str], optional): Header HTTP. Default è None.
|
|
166
|
+
|
|
167
|
+
Returns:
|
|
168
|
+
ApiResponse: Risposta della richiesta.
|
|
169
|
+
"""
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
#### `delete_row`
|
|
173
|
+
|
|
174
|
+
```python
|
|
175
|
+
def delete_row(self, row_id: Any, headers: Optional[Dict[str, str]] = None) -> ApiResponse:
|
|
176
|
+
"""
|
|
177
|
+
Effettua una richiesta DELETE per eliminare un record dalla tabella.
|
|
178
|
+
|
|
179
|
+
Args:
|
|
180
|
+
row_id (Any): Identificatore del record.
|
|
181
|
+
headers (Dict[str, str], optional): Header HTTP. Default è None.
|
|
182
|
+
|
|
183
|
+
Returns:
|
|
184
|
+
ApiResponse: Risposta della richiesta.
|
|
185
|
+
"""
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
#### `to_class`
|
|
189
|
+
|
|
190
|
+
```python
|
|
191
|
+
def to_class(self, headers: Optional[Dict] = None) -> ApiResponse:
|
|
192
|
+
"""
|
|
193
|
+
Effettua una richiesta GET per esportare la struttura della tabella in formato OpenAPI.
|
|
194
|
+
|
|
195
|
+
Args:
|
|
196
|
+
headers (Dict[str, str], optional): Header HTTP. Default è None.
|
|
197
|
+
|
|
198
|
+
Returns:
|
|
199
|
+
ApiResponse: Risposta della richiesta.
|
|
200
|
+
"""
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
### Note
|
|
204
|
+
|
|
205
|
+
- L'API REST è gestita automaticamente dalla classe `CrudPHPApi`, che estende `requests.Session`.
|
|
206
|
+
- Il metodo `_build_table_endpoint` costruisce l'endpoint della tabella.
|
|
207
|
+
- I metodi `list_rows`, `get_row`, `insert_row`, `update_row`, `delete_row` effettuano richieste HTTP GET, POST, PUT e DELETE rispettivamente.
|
|
208
|
+
- Il metodo `to_class` effettua una richiesta GET per esportare la struttura della tabella in formato OpenAPI.
|
|
209
|
+
- L'API REST richiede autenticazione tramite una chiave API se specificata.
|
|
210
|
+
|
|
211
|
+
## Esempio di utilizzo
|
|
212
|
+
|
|
213
|
+
```python
|
|
214
|
+
# Importazione della classe CrudPHPTable
|
|
215
|
+
from py_client_cap import CrudPHPTable
|
|
216
|
+
|
|
217
|
+
# Configurazione del client
|
|
218
|
+
base_url = "http://example.com/api"
|
|
219
|
+
api_key = "your_api_key_here"
|
|
220
|
+
|
|
221
|
+
# Creazione dell'oggetto CrudPHPTable
|
|
222
|
+
table_client = CrudPHPTable(base_url=base_url, api_key=api_key)
|
|
223
|
+
|
|
224
|
+
# Elenco dei record della tabella
|
|
225
|
+
response = table_client.list_rows()
|
|
226
|
+
print(response)
|
|
227
|
+
|
|
228
|
+
Questo esempio mostra come utilizzare la classe 'CrudPHPTable' per effettuare operazioni di liste e selezione di record su una tabella PHP API.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
py_client_cap/__init__.py,sha256=RV6Jph8QIp0NHnxj8ykvzZHWs5rG8r1-Y_MfxWYtUkc,160
|
|
2
|
+
py_client_cap/crud_php_api.py,sha256=sNy3uUTuI0IKNw-fhTr5XSpoS6tfcn1CwJ-gqxuOyL4,6661
|
|
3
|
+
py_client_cap/crud_php_table.py,sha256=UERZvDs_tHarWKmRg-qDaiPsddOBNNo3CRShKg4Ub9g,3751
|
|
4
|
+
py_client_cap/manager.py,sha256=FxEQh9tc6N4jFNgOLG0CKALpDd3_B3HyTrPHcCKGtr8,1091
|
|
5
|
+
py_client_cap/models/__init__.py,sha256=aVKe51v5ve_nfsoA1iqGh02pIvqCZ-LJ16paZenHwDY,141
|
|
6
|
+
py_client_cap/models/apiresponse.py,sha256=hsKKa8Y1BNRIPuI8I7ZCgCgzSGM1cvutIa-YlNrFvus,467
|
|
7
|
+
py_client_cap/models/column.py,sha256=Bj1NeWOp0DEojIdD6O4P49--nJX9RgBJXZXKrSckxcQ,160
|
|
8
|
+
py_client_cap/models/item.py,sha256=BAoBlf2RVX1N-fWMd6G1MCvzy34eSXs6uERHKrEvoyY,291
|
|
9
|
+
py_client_cap/models/table.py,sha256=hLUpzcIh3LPUJZ8jkDGaZgDnLfjnDiieJzl1dJQzj2E,1248
|
|
10
|
+
py_client_cap-0.1.7.dist-info/METADATA,sha256=St2xdlEiO6pTkuFYtwjbjOYCb6TQjrDa3pC65-gU5r4,7198
|
|
11
|
+
py_client_cap-0.1.7.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
|
|
12
|
+
py_client_cap-0.1.7.dist-info/top_level.txt,sha256=-0C4bPZLCM4dW6HC_6VrL2WSWXjjeakObCd3sB-_fgI,14
|
|
13
|
+
py_client_cap-0.1.7.dist-info/RECORD,,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
py_client_cap
|