apexdevkit 1.16.1__tar.gz → 1.16.3__tar.gz
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.
- {apexdevkit-1.16.1 → apexdevkit-1.16.3}/PKG-INFO +1 -1
- apexdevkit-1.16.3/apexdevkit/fastapi/request.py +31 -0
- {apexdevkit-1.16.1 → apexdevkit-1.16.3}/apexdevkit/fastapi/response.py +1 -67
- {apexdevkit-1.16.1 → apexdevkit-1.16.3}/apexdevkit/fluent.py +4 -1
- {apexdevkit-1.16.1 → apexdevkit-1.16.3}/apexdevkit/repository/mssql.py +11 -11
- apexdevkit-1.16.3/apexdevkit/testing/rest.py +226 -0
- {apexdevkit-1.16.1 → apexdevkit-1.16.3}/pyproject.toml +1 -1
- apexdevkit-1.16.1/apexdevkit/fastapi/request.py +0 -88
- apexdevkit-1.16.1/apexdevkit/fastapi/rest.py +0 -92
- apexdevkit-1.16.1/apexdevkit/testing/rest.py +0 -18
- {apexdevkit-1.16.1 → apexdevkit-1.16.3}/LICENSE +0 -0
- {apexdevkit-1.16.1 → apexdevkit-1.16.3}/README.md +0 -0
- {apexdevkit-1.16.1 → apexdevkit-1.16.3}/apexdevkit/__init__.py +0 -0
- {apexdevkit-1.16.1 → apexdevkit-1.16.3}/apexdevkit/annotation/__init__.py +0 -0
- {apexdevkit-1.16.1 → apexdevkit-1.16.3}/apexdevkit/annotation/deprecate.py +0 -0
- {apexdevkit-1.16.1 → apexdevkit-1.16.3}/apexdevkit/environment.py +0 -0
- {apexdevkit-1.16.1 → apexdevkit-1.16.3}/apexdevkit/error.py +0 -0
- {apexdevkit-1.16.1 → apexdevkit-1.16.3}/apexdevkit/fastapi/__init__.py +0 -0
- {apexdevkit-1.16.1 → apexdevkit-1.16.3}/apexdevkit/fastapi/builder.py +0 -0
- {apexdevkit-1.16.1 → apexdevkit-1.16.3}/apexdevkit/fastapi/dependable.py +0 -0
- {apexdevkit-1.16.1 → apexdevkit-1.16.3}/apexdevkit/fastapi/docs.py +0 -0
- {apexdevkit-1.16.1 → apexdevkit-1.16.3}/apexdevkit/fastapi/name.py +0 -0
- {apexdevkit-1.16.1 → apexdevkit-1.16.3}/apexdevkit/fastapi/resource.py +0 -0
- {apexdevkit-1.16.1 → apexdevkit-1.16.3}/apexdevkit/fastapi/router.py +0 -0
- {apexdevkit-1.16.1 → apexdevkit-1.16.3}/apexdevkit/fastapi/schema.py +0 -0
- {apexdevkit-1.16.1 → apexdevkit-1.16.3}/apexdevkit/fastapi/service.py +0 -0
- {apexdevkit-1.16.1 → apexdevkit-1.16.3}/apexdevkit/formatter.py +0 -0
- {apexdevkit-1.16.1 → apexdevkit-1.16.3}/apexdevkit/http/__init__.py +0 -0
- {apexdevkit-1.16.1 → apexdevkit-1.16.3}/apexdevkit/http/fake.py +0 -0
- {apexdevkit-1.16.1 → apexdevkit-1.16.3}/apexdevkit/http/fluent.py +0 -0
- {apexdevkit-1.16.1 → apexdevkit-1.16.3}/apexdevkit/http/httpx.py +0 -0
- {apexdevkit-1.16.1 → apexdevkit-1.16.3}/apexdevkit/http/json.py +0 -0
- {apexdevkit-1.16.1 → apexdevkit-1.16.3}/apexdevkit/http/url.py +0 -0
- {apexdevkit-1.16.1 → apexdevkit-1.16.3}/apexdevkit/key_fn.py +0 -0
- {apexdevkit-1.16.1 → apexdevkit-1.16.3}/apexdevkit/py.typed +0 -0
- {apexdevkit-1.16.1 → apexdevkit-1.16.3}/apexdevkit/repository/__init__.py +0 -0
- {apexdevkit-1.16.1 → apexdevkit-1.16.3}/apexdevkit/repository/base.py +0 -0
- {apexdevkit-1.16.1 → apexdevkit-1.16.3}/apexdevkit/repository/connector.py +0 -0
- {apexdevkit-1.16.1 → apexdevkit-1.16.3}/apexdevkit/repository/database.py +0 -0
- {apexdevkit-1.16.1 → apexdevkit-1.16.3}/apexdevkit/repository/decorator.py +0 -0
- {apexdevkit-1.16.1 → apexdevkit-1.16.3}/apexdevkit/repository/in_memory.py +0 -0
- {apexdevkit-1.16.1 → apexdevkit-1.16.3}/apexdevkit/repository/interface.py +0 -0
- {apexdevkit-1.16.1 → apexdevkit-1.16.3}/apexdevkit/repository/mongo.py +0 -0
- {apexdevkit-1.16.1 → apexdevkit-1.16.3}/apexdevkit/repository/sqlite.py +0 -0
- {apexdevkit-1.16.1 → apexdevkit-1.16.3}/apexdevkit/server.py +0 -0
- {apexdevkit-1.16.1 → apexdevkit-1.16.3}/apexdevkit/synchronization.py +0 -0
- {apexdevkit-1.16.1 → apexdevkit-1.16.3}/apexdevkit/testing/__init__.py +0 -0
- {apexdevkit-1.16.1 → apexdevkit-1.16.3}/apexdevkit/testing/database.py +0 -0
- {apexdevkit-1.16.1 → apexdevkit-1.16.3}/apexdevkit/testing/fake.py +0 -0
- {apexdevkit-1.16.1 → apexdevkit-1.16.3}/apexdevkit/value.py +0 -0
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
from typing import Any
|
|
5
|
+
|
|
6
|
+
from apexdevkit.http import Http, HttpMethod, JsonDict
|
|
7
|
+
from apexdevkit.http.fluent import HttpResponse
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@dataclass
|
|
11
|
+
class HttpRequest:
|
|
12
|
+
method: HttpMethod
|
|
13
|
+
http: Http
|
|
14
|
+
|
|
15
|
+
def with_endpoint(self, value: Any) -> HttpRequest:
|
|
16
|
+
self.http = self.http.with_endpoint(str(value))
|
|
17
|
+
|
|
18
|
+
return self
|
|
19
|
+
|
|
20
|
+
def with_param(self, name: str, value: Any) -> HttpRequest:
|
|
21
|
+
self.http = self.http.with_param(name, value)
|
|
22
|
+
|
|
23
|
+
return self
|
|
24
|
+
|
|
25
|
+
def with_json(self, value: JsonDict) -> HttpRequest:
|
|
26
|
+
self.http = self.http.with_json(value)
|
|
27
|
+
|
|
28
|
+
return self
|
|
29
|
+
|
|
30
|
+
def __call__(self) -> HttpResponse:
|
|
31
|
+
return self.http.request(self.method)
|
|
@@ -1,11 +1,8 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
1
|
from dataclasses import dataclass
|
|
4
|
-
from typing import Any, Iterable
|
|
2
|
+
from typing import Any, Iterable
|
|
5
3
|
|
|
6
4
|
from apexdevkit.error import DoesNotExistError, ExistsError, ForbiddenError
|
|
7
5
|
from apexdevkit.fastapi.name import RestfulName
|
|
8
|
-
from apexdevkit.http import JsonDict
|
|
9
6
|
|
|
10
7
|
|
|
11
8
|
@dataclass(frozen=True)
|
|
@@ -68,66 +65,3 @@ class RestfulResponse:
|
|
|
68
65
|
content["data"] = {self.name.singular: data}
|
|
69
66
|
|
|
70
67
|
return content
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
@dataclass
|
|
74
|
-
class RestResponse:
|
|
75
|
-
resource: RestfulName
|
|
76
|
-
json: JsonDict
|
|
77
|
-
http_code: int
|
|
78
|
-
|
|
79
|
-
def fail(self) -> Self:
|
|
80
|
-
if self.http_code == 422:
|
|
81
|
-
return self
|
|
82
|
-
|
|
83
|
-
return self.with_status("fail")
|
|
84
|
-
|
|
85
|
-
def success(self) -> Self:
|
|
86
|
-
return self.with_status("success")
|
|
87
|
-
|
|
88
|
-
def with_status(self, value: str) -> Self:
|
|
89
|
-
assert self.json.value_of("status").to(str) == value
|
|
90
|
-
|
|
91
|
-
return self
|
|
92
|
-
|
|
93
|
-
def with_code(self, value: int) -> Self:
|
|
94
|
-
assert self.http_code == value
|
|
95
|
-
|
|
96
|
-
if self.http_code != 422:
|
|
97
|
-
assert self.json.value_of("code").to(int) == value
|
|
98
|
-
|
|
99
|
-
return self
|
|
100
|
-
|
|
101
|
-
def message(self, value: str) -> Self:
|
|
102
|
-
return self.with_message(value)
|
|
103
|
-
|
|
104
|
-
def and_message(self, value: str) -> Self:
|
|
105
|
-
return self.with_message(value)
|
|
106
|
-
|
|
107
|
-
def with_message(self, value: str) -> Self:
|
|
108
|
-
assert self.json.value_of("error").to(dict) == {"message": value}, self.json
|
|
109
|
-
|
|
110
|
-
return self
|
|
111
|
-
|
|
112
|
-
def and_item(self, value: Any) -> Self:
|
|
113
|
-
return self.with_item(value)
|
|
114
|
-
|
|
115
|
-
def with_item(self, value: Any) -> Self:
|
|
116
|
-
return self.with_data(**{self.resource.singular: value})
|
|
117
|
-
|
|
118
|
-
def and_collection(self, value: list[Any]) -> Self:
|
|
119
|
-
return self.with_collection(value)
|
|
120
|
-
|
|
121
|
-
def with_collection(self, values: list[Any]) -> Self:
|
|
122
|
-
return self.with_data(**{self.resource.plural: values}, count=len(values))
|
|
123
|
-
|
|
124
|
-
def and_no_data(self) -> Self:
|
|
125
|
-
return self.no_data()
|
|
126
|
-
|
|
127
|
-
def no_data(self) -> Self:
|
|
128
|
-
return self.with_data()
|
|
129
|
-
|
|
130
|
-
def with_data(self, **kwargs: Any) -> Self:
|
|
131
|
-
assert self.json.value_of("data").to(dict) == {**kwargs}, self.json
|
|
132
|
-
|
|
133
|
-
return self
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
from dataclasses import dataclass
|
|
4
|
-
from typing import Callable, Generic, TypeVar
|
|
4
|
+
from typing import Any, Callable, Generic, TypeVar
|
|
5
5
|
|
|
6
6
|
ItemT = TypeVar("ItemT")
|
|
7
7
|
|
|
@@ -33,6 +33,9 @@ class FluentElement(Generic[ItemT]):
|
|
|
33
33
|
def to(self, a_type: Callable[[ItemT], ConvertedT]) -> ConvertedT:
|
|
34
34
|
return a_type(self.value)
|
|
35
35
|
|
|
36
|
+
def as_dict(self) -> dict[str, Any]:
|
|
37
|
+
return dict(self.value) # type: ignore
|
|
38
|
+
|
|
36
39
|
def __str__(self) -> str:
|
|
37
40
|
return str(self.value)
|
|
38
41
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
from dataclasses import dataclass
|
|
4
|
-
from typing import Any,
|
|
4
|
+
from typing import Any, Generic, Iterator, TypeVar
|
|
5
5
|
|
|
6
6
|
from pymssql.exceptions import DatabaseError
|
|
7
7
|
|
|
@@ -57,33 +57,33 @@ class MsSqlRepository(RepositoryBase[ItemT]):
|
|
|
57
57
|
self.db.execute(self.table.update(item)).fetch_none()
|
|
58
58
|
|
|
59
59
|
|
|
60
|
-
class SqlTable(
|
|
60
|
+
class SqlTable(Generic[ItemT]): # pragma: no cover
|
|
61
61
|
def count_all(self) -> DatabaseCommand:
|
|
62
|
-
|
|
62
|
+
raise NotImplementedError
|
|
63
63
|
|
|
64
64
|
def insert(self, item: ItemT) -> DatabaseCommand:
|
|
65
|
-
|
|
65
|
+
raise NotImplementedError
|
|
66
66
|
|
|
67
67
|
def select(self, item_id: str) -> DatabaseCommand:
|
|
68
|
-
|
|
68
|
+
raise NotImplementedError
|
|
69
69
|
|
|
70
70
|
def select_all(self) -> DatabaseCommand:
|
|
71
|
-
|
|
71
|
+
raise NotImplementedError
|
|
72
72
|
|
|
73
73
|
def delete(self, item_id: str) -> DatabaseCommand:
|
|
74
|
-
|
|
74
|
+
raise NotImplementedError
|
|
75
75
|
|
|
76
76
|
def delete_all(self) -> DatabaseCommand:
|
|
77
|
-
|
|
77
|
+
raise NotImplementedError
|
|
78
78
|
|
|
79
79
|
def update(self, item: ItemT) -> DatabaseCommand:
|
|
80
|
-
|
|
80
|
+
raise NotImplementedError
|
|
81
81
|
|
|
82
82
|
def load(self, data: dict[str, Any]) -> ItemT:
|
|
83
|
-
|
|
83
|
+
raise NotImplementedError
|
|
84
84
|
|
|
85
85
|
def exists(self, duplicate: ItemT) -> ExistsError:
|
|
86
|
-
|
|
86
|
+
raise NotImplementedError
|
|
87
87
|
|
|
88
88
|
|
|
89
89
|
@dataclass
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
from functools import cached_property
|
|
5
|
+
from typing import Any, Iterable, Self
|
|
6
|
+
|
|
7
|
+
from apexdevkit.fastapi.name import RestfulName
|
|
8
|
+
from apexdevkit.fastapi.request import HttpRequest
|
|
9
|
+
from apexdevkit.http import Http, HttpMethod, JsonDict
|
|
10
|
+
from apexdevkit.http.fluent import HttpResponse
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@dataclass(frozen=True)
|
|
14
|
+
class _RestResource:
|
|
15
|
+
http: Http
|
|
16
|
+
name: RestfulName
|
|
17
|
+
|
|
18
|
+
def create_one(self) -> _TestRequest:
|
|
19
|
+
return _TestRequest(
|
|
20
|
+
self.name,
|
|
21
|
+
HttpRequest(
|
|
22
|
+
HttpMethod.post,
|
|
23
|
+
self.http.with_endpoint(self.name.plural),
|
|
24
|
+
),
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
def create_many(self) -> _TestRequest:
|
|
28
|
+
return _TestRequest(
|
|
29
|
+
self.name,
|
|
30
|
+
HttpRequest(
|
|
31
|
+
HttpMethod.post,
|
|
32
|
+
self.http.with_endpoint(self.name.plural).with_endpoint("batch"),
|
|
33
|
+
),
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
def read_one(self) -> _TestRequest:
|
|
37
|
+
return _TestRequest(
|
|
38
|
+
self.name,
|
|
39
|
+
HttpRequest(
|
|
40
|
+
HttpMethod.get,
|
|
41
|
+
self.http.with_endpoint(self.name.plural),
|
|
42
|
+
),
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
def read_all(self) -> _TestRequest:
|
|
46
|
+
return _TestRequest(
|
|
47
|
+
self.name,
|
|
48
|
+
HttpRequest(
|
|
49
|
+
HttpMethod.get,
|
|
50
|
+
self.http.with_endpoint(self.name.plural),
|
|
51
|
+
),
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
def update_one(self) -> _TestRequest:
|
|
55
|
+
return _TestRequest(
|
|
56
|
+
self.name,
|
|
57
|
+
HttpRequest(
|
|
58
|
+
HttpMethod.patch,
|
|
59
|
+
self.http.with_endpoint(self.name.plural),
|
|
60
|
+
),
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
def update_many(self) -> _TestRequest:
|
|
64
|
+
return _TestRequest(
|
|
65
|
+
self.name,
|
|
66
|
+
HttpRequest(
|
|
67
|
+
HttpMethod.patch,
|
|
68
|
+
self.http.with_endpoint(self.name.plural),
|
|
69
|
+
),
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
def replace_one(self) -> _TestRequest:
|
|
73
|
+
return _TestRequest(
|
|
74
|
+
self.name,
|
|
75
|
+
HttpRequest(
|
|
76
|
+
HttpMethod.put,
|
|
77
|
+
self.http.with_endpoint(self.name.plural),
|
|
78
|
+
),
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
def replace_many(self) -> _TestRequest:
|
|
82
|
+
return _TestRequest(
|
|
83
|
+
self.name,
|
|
84
|
+
HttpRequest(
|
|
85
|
+
HttpMethod.put,
|
|
86
|
+
self.http.with_endpoint(self.name.plural).with_endpoint("batch"),
|
|
87
|
+
),
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
def delete_one(self) -> _TestRequest:
|
|
91
|
+
return _TestRequest(
|
|
92
|
+
self.name,
|
|
93
|
+
HttpRequest(
|
|
94
|
+
HttpMethod.delete,
|
|
95
|
+
self.http.with_endpoint(self.name.plural),
|
|
96
|
+
),
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
@dataclass
|
|
101
|
+
class _TestRequest:
|
|
102
|
+
resource: RestfulName
|
|
103
|
+
request: HttpRequest
|
|
104
|
+
|
|
105
|
+
def with_id(self, value: Any) -> Self:
|
|
106
|
+
self.request = self.request.with_endpoint(value)
|
|
107
|
+
|
|
108
|
+
return self
|
|
109
|
+
|
|
110
|
+
def from_collection(self, value: list[JsonDict]) -> Self:
|
|
111
|
+
return self.with_data(
|
|
112
|
+
JsonDict({self.resource.plural: [dict(item) for item in value]})
|
|
113
|
+
)
|
|
114
|
+
|
|
115
|
+
def and_data(self, value: JsonDict) -> Self:
|
|
116
|
+
return self.with_data(value)
|
|
117
|
+
|
|
118
|
+
def from_data(self, value: JsonDict) -> Self:
|
|
119
|
+
return self.with_data(value)
|
|
120
|
+
|
|
121
|
+
def with_data(self, value: JsonDict) -> Self:
|
|
122
|
+
self.request = self.request.with_json(value)
|
|
123
|
+
|
|
124
|
+
return self
|
|
125
|
+
|
|
126
|
+
def and_param(self, name: str, value: Any) -> Self:
|
|
127
|
+
return self.with_param(name, value)
|
|
128
|
+
|
|
129
|
+
def with_param(self, name: str, value: Any) -> Self:
|
|
130
|
+
self.request = self.request.with_param(name, str(value))
|
|
131
|
+
|
|
132
|
+
return self
|
|
133
|
+
|
|
134
|
+
@cached_property
|
|
135
|
+
def response(self) -> HttpResponse:
|
|
136
|
+
return self.request()
|
|
137
|
+
|
|
138
|
+
def unpack(self) -> JsonDict:
|
|
139
|
+
return JsonDict(self.response.json()["data"][self.resource.singular])
|
|
140
|
+
|
|
141
|
+
def unpack_many(self) -> Iterable[JsonDict]:
|
|
142
|
+
items = self.response.json()["data"][self.resource.plural]
|
|
143
|
+
|
|
144
|
+
return [JsonDict(item) for item in items]
|
|
145
|
+
|
|
146
|
+
def ensure(self) -> _Response:
|
|
147
|
+
return _Response(
|
|
148
|
+
resource=self.resource,
|
|
149
|
+
json=JsonDict(self.response.json()),
|
|
150
|
+
http_code=self.response.code(),
|
|
151
|
+
)
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
@dataclass
|
|
155
|
+
class _Response:
|
|
156
|
+
resource: RestfulName
|
|
157
|
+
json: JsonDict
|
|
158
|
+
http_code: int
|
|
159
|
+
|
|
160
|
+
def fail(self) -> Self:
|
|
161
|
+
if self.http_code == 422:
|
|
162
|
+
return self
|
|
163
|
+
|
|
164
|
+
return self.with_status("fail")
|
|
165
|
+
|
|
166
|
+
def success(self) -> Self:
|
|
167
|
+
return self.with_status("success")
|
|
168
|
+
|
|
169
|
+
def with_status(self, value: str) -> Self:
|
|
170
|
+
assert self.json.value_of("status").to(str) == value
|
|
171
|
+
|
|
172
|
+
return self
|
|
173
|
+
|
|
174
|
+
def with_code(self, value: int) -> Self:
|
|
175
|
+
assert self.http_code == value
|
|
176
|
+
|
|
177
|
+
if self.http_code != 422:
|
|
178
|
+
assert self.json.value_of("code").to(int) == value
|
|
179
|
+
|
|
180
|
+
return self
|
|
181
|
+
|
|
182
|
+
def message(self, value: str) -> Self:
|
|
183
|
+
return self.with_message(value)
|
|
184
|
+
|
|
185
|
+
def and_message(self, value: str) -> Self:
|
|
186
|
+
return self.with_message(value)
|
|
187
|
+
|
|
188
|
+
def with_message(self, value: str) -> Self:
|
|
189
|
+
assert self.json.value_of("error").as_dict() == {"message": value}, self.json
|
|
190
|
+
|
|
191
|
+
return self
|
|
192
|
+
|
|
193
|
+
def and_item(self, value: Any) -> Self:
|
|
194
|
+
return self.with_item(value)
|
|
195
|
+
|
|
196
|
+
def with_item(self, value: Any) -> Self:
|
|
197
|
+
return self.with_data(**{self.resource.singular: value})
|
|
198
|
+
|
|
199
|
+
def and_collection(self, value: list[Any]) -> Self:
|
|
200
|
+
return self.with_collection(value)
|
|
201
|
+
|
|
202
|
+
def with_collection(self, values: list[Any]) -> Self:
|
|
203
|
+
return self.with_data(**{self.resource.plural: values}, count=len(values))
|
|
204
|
+
|
|
205
|
+
def and_no_data(self) -> Self:
|
|
206
|
+
return self.no_data()
|
|
207
|
+
|
|
208
|
+
def no_data(self) -> Self:
|
|
209
|
+
return self.with_data()
|
|
210
|
+
|
|
211
|
+
def with_data(self, **kwargs: Any) -> Self:
|
|
212
|
+
assert self.json.value_of("data").as_dict() == {**kwargs}, self.json
|
|
213
|
+
|
|
214
|
+
return self
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
@dataclass(frozen=True)
|
|
218
|
+
class RestCollection(_RestResource):
|
|
219
|
+
def sub_resource(self, name: str) -> RestItem:
|
|
220
|
+
return RestItem(self.http.with_endpoint(self.name.plural), RestfulName(name))
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
@dataclass(frozen=True)
|
|
224
|
+
class RestItem(_RestResource):
|
|
225
|
+
def sub_resource(self, name: str) -> RestItem:
|
|
226
|
+
return RestItem(self.http.with_endpoint(self.name.singular), RestfulName(name))
|
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
|
-
from dataclasses import dataclass
|
|
4
|
-
from functools import cached_property
|
|
5
|
-
from typing import Any, Iterable, Self
|
|
6
|
-
|
|
7
|
-
from apexdevkit.fastapi.name import RestfulName
|
|
8
|
-
from apexdevkit.fastapi.response import RestResponse
|
|
9
|
-
from apexdevkit.http import Http, HttpMethod, JsonDict
|
|
10
|
-
from apexdevkit.http.fluent import HttpResponse
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
@dataclass
|
|
14
|
-
class HttpRequest:
|
|
15
|
-
method: HttpMethod
|
|
16
|
-
http: Http
|
|
17
|
-
|
|
18
|
-
def with_endpoint(self, value: Any) -> HttpRequest:
|
|
19
|
-
self.http = self.http.with_endpoint(str(value))
|
|
20
|
-
|
|
21
|
-
return self
|
|
22
|
-
|
|
23
|
-
def with_param(self, name: str, value: Any) -> HttpRequest:
|
|
24
|
-
self.http = self.http.with_param(name, value)
|
|
25
|
-
|
|
26
|
-
return self
|
|
27
|
-
|
|
28
|
-
def with_json(self, value: JsonDict) -> HttpRequest:
|
|
29
|
-
self.http = self.http.with_json(value)
|
|
30
|
-
|
|
31
|
-
return self
|
|
32
|
-
|
|
33
|
-
def __call__(self) -> HttpResponse:
|
|
34
|
-
return self.http.request(self.method)
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
@dataclass
|
|
38
|
-
class RestRequest:
|
|
39
|
-
resource: RestfulName
|
|
40
|
-
request: HttpRequest
|
|
41
|
-
|
|
42
|
-
def with_id(self, value: Any) -> Self:
|
|
43
|
-
self.request = self.request.with_endpoint(value)
|
|
44
|
-
|
|
45
|
-
return self
|
|
46
|
-
|
|
47
|
-
def from_collection(self, value: list[JsonDict]) -> Self:
|
|
48
|
-
return self.with_data(
|
|
49
|
-
JsonDict({self.resource.plural: [dict(item) for item in value]})
|
|
50
|
-
)
|
|
51
|
-
|
|
52
|
-
def and_data(self, value: JsonDict) -> Self:
|
|
53
|
-
return self.with_data(value)
|
|
54
|
-
|
|
55
|
-
def from_data(self, value: JsonDict) -> Self:
|
|
56
|
-
return self.with_data(value)
|
|
57
|
-
|
|
58
|
-
def with_data(self, value: JsonDict) -> Self:
|
|
59
|
-
self.request = self.request.with_json(value)
|
|
60
|
-
|
|
61
|
-
return self
|
|
62
|
-
|
|
63
|
-
def and_param(self, name: str, value: Any) -> Self:
|
|
64
|
-
return self.with_param(name, value)
|
|
65
|
-
|
|
66
|
-
def with_param(self, name: str, value: Any) -> Self:
|
|
67
|
-
self.request = self.request.with_param(name, str(value))
|
|
68
|
-
|
|
69
|
-
return self
|
|
70
|
-
|
|
71
|
-
@cached_property
|
|
72
|
-
def response(self) -> HttpResponse:
|
|
73
|
-
return self.request()
|
|
74
|
-
|
|
75
|
-
def unpack(self) -> JsonDict:
|
|
76
|
-
return JsonDict(self.response.json()["data"][self.resource.singular])
|
|
77
|
-
|
|
78
|
-
def unpack_many(self) -> Iterable[JsonDict]:
|
|
79
|
-
items = self.response.json()["data"][self.resource.plural]
|
|
80
|
-
|
|
81
|
-
return [JsonDict(item) for item in items]
|
|
82
|
-
|
|
83
|
-
def ensure(self) -> RestResponse:
|
|
84
|
-
return RestResponse(
|
|
85
|
-
resource=self.resource,
|
|
86
|
-
json=JsonDict(self.response.json()),
|
|
87
|
-
http_code=self.response.code(),
|
|
88
|
-
)
|
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
from dataclasses import dataclass
|
|
2
|
-
|
|
3
|
-
from apexdevkit.fastapi.name import RestfulName
|
|
4
|
-
from apexdevkit.fastapi.request import HttpRequest, RestRequest
|
|
5
|
-
from apexdevkit.http import Http, HttpMethod
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
@dataclass(frozen=True)
|
|
9
|
-
class RestResource:
|
|
10
|
-
http: Http
|
|
11
|
-
name: RestfulName
|
|
12
|
-
|
|
13
|
-
def create_one(self) -> RestRequest:
|
|
14
|
-
return RestRequest(
|
|
15
|
-
self.name,
|
|
16
|
-
HttpRequest(
|
|
17
|
-
HttpMethod.post,
|
|
18
|
-
self.http.with_endpoint(self.name.plural),
|
|
19
|
-
),
|
|
20
|
-
)
|
|
21
|
-
|
|
22
|
-
def create_many(self) -> RestRequest:
|
|
23
|
-
return RestRequest(
|
|
24
|
-
self.name,
|
|
25
|
-
HttpRequest(
|
|
26
|
-
HttpMethod.post,
|
|
27
|
-
self.http.with_endpoint(self.name.plural).with_endpoint("batch"),
|
|
28
|
-
),
|
|
29
|
-
)
|
|
30
|
-
|
|
31
|
-
def read_one(self) -> RestRequest:
|
|
32
|
-
return RestRequest(
|
|
33
|
-
self.name,
|
|
34
|
-
HttpRequest(
|
|
35
|
-
HttpMethod.get,
|
|
36
|
-
self.http.with_endpoint(self.name.plural),
|
|
37
|
-
),
|
|
38
|
-
)
|
|
39
|
-
|
|
40
|
-
def read_all(self) -> RestRequest:
|
|
41
|
-
return RestRequest(
|
|
42
|
-
self.name,
|
|
43
|
-
HttpRequest(
|
|
44
|
-
HttpMethod.get,
|
|
45
|
-
self.http.with_endpoint(self.name.plural),
|
|
46
|
-
),
|
|
47
|
-
)
|
|
48
|
-
|
|
49
|
-
def update_one(self) -> RestRequest:
|
|
50
|
-
return RestRequest(
|
|
51
|
-
self.name,
|
|
52
|
-
HttpRequest(
|
|
53
|
-
HttpMethod.patch,
|
|
54
|
-
self.http.with_endpoint(self.name.plural),
|
|
55
|
-
),
|
|
56
|
-
)
|
|
57
|
-
|
|
58
|
-
def update_many(self) -> RestRequest:
|
|
59
|
-
return RestRequest(
|
|
60
|
-
self.name,
|
|
61
|
-
HttpRequest(
|
|
62
|
-
HttpMethod.patch,
|
|
63
|
-
self.http.with_endpoint(self.name.plural),
|
|
64
|
-
),
|
|
65
|
-
)
|
|
66
|
-
|
|
67
|
-
def replace_one(self) -> RestRequest:
|
|
68
|
-
return RestRequest(
|
|
69
|
-
self.name,
|
|
70
|
-
HttpRequest(
|
|
71
|
-
HttpMethod.put,
|
|
72
|
-
self.http.with_endpoint(self.name.plural),
|
|
73
|
-
),
|
|
74
|
-
)
|
|
75
|
-
|
|
76
|
-
def replace_many(self) -> RestRequest:
|
|
77
|
-
return RestRequest(
|
|
78
|
-
self.name,
|
|
79
|
-
HttpRequest(
|
|
80
|
-
HttpMethod.put,
|
|
81
|
-
self.http.with_endpoint(self.name.plural).with_endpoint("batch"),
|
|
82
|
-
),
|
|
83
|
-
)
|
|
84
|
-
|
|
85
|
-
def delete_one(self) -> RestRequest:
|
|
86
|
-
return RestRequest(
|
|
87
|
-
self.name,
|
|
88
|
-
HttpRequest(
|
|
89
|
-
HttpMethod.delete,
|
|
90
|
-
self.http.with_endpoint(self.name.plural),
|
|
91
|
-
),
|
|
92
|
-
)
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
|
-
from dataclasses import dataclass
|
|
4
|
-
|
|
5
|
-
from apexdevkit.fastapi.name import RestfulName
|
|
6
|
-
from apexdevkit.fastapi.rest import RestResource
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
@dataclass(frozen=True)
|
|
10
|
-
class RestCollection(RestResource):
|
|
11
|
-
def sub_resource(self, name: str) -> RestItem:
|
|
12
|
-
return RestItem(self.http.with_endpoint(self.name.plural), RestfulName(name))
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
@dataclass(frozen=True)
|
|
16
|
-
class RestItem(RestResource):
|
|
17
|
-
def sub_resource(self, name: str) -> RestItem:
|
|
18
|
-
return RestItem(self.http.with_endpoint(self.name.singular), RestfulName(name))
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|