tiferet-fast 0.1.0__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.
- tiferet_fast-0.1.0/LICENSE +21 -0
- tiferet_fast-0.1.0/PKG-INFO +283 -0
- tiferet_fast-0.1.0/README.md +263 -0
- tiferet_fast-0.1.0/pyproject.toml +47 -0
- tiferet_fast-0.1.0/setup.cfg +4 -0
- tiferet_fast-0.1.0/tiferet_fast/__init__.py +15 -0
- tiferet_fast-0.1.0/tiferet_fast/contexts/__init__.py +7 -0
- tiferet_fast-0.1.0/tiferet_fast/contexts/fast.py +207 -0
- tiferet_fast-0.1.0/tiferet_fast/contexts/request.py +62 -0
- tiferet_fast-0.1.0/tiferet_fast/contracts/__init__.py +10 -0
- tiferet_fast-0.1.0/tiferet_fast/contracts/fast.py +84 -0
- tiferet_fast-0.1.0/tiferet_fast/data/__init__.py +10 -0
- tiferet_fast-0.1.0/tiferet_fast/data/fast.py +146 -0
- tiferet_fast-0.1.0/tiferet_fast/handlers/__init__.py +8 -0
- tiferet_fast-0.1.0/tiferet_fast/handlers/fast.py +99 -0
- tiferet_fast-0.1.0/tiferet_fast/models/__init__.py +9 -0
- tiferet_fast-0.1.0/tiferet_fast/models/fast.py +119 -0
- tiferet_fast-0.1.0/tiferet_fast/proxies/__init__.py +3 -0
- tiferet_fast-0.1.0/tiferet_fast/proxies/yaml/__init__.py +8 -0
- tiferet_fast-0.1.0/tiferet_fast/proxies/yaml/fast.py +143 -0
- tiferet_fast-0.1.0/tiferet_fast.egg-info/PKG-INFO +283 -0
- tiferet_fast-0.1.0/tiferet_fast.egg-info/SOURCES.txt +23 -0
- tiferet_fast-0.1.0/tiferet_fast.egg-info/dependency_links.txt +1 -0
- tiferet_fast-0.1.0/tiferet_fast.egg-info/requires.txt +7 -0
- tiferet_fast-0.1.0/tiferet_fast.egg-info/top_level.txt +1 -0
@@ -0,0 +1,21 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2025 Great Strength Systems
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
@@ -0,0 +1,283 @@
|
|
1
|
+
Metadata-Version: 2.4
|
2
|
+
Name: tiferet-fast
|
3
|
+
Version: 0.1.0
|
4
|
+
Summary: An extension of the Tiferet Framework for the Fast API.
|
5
|
+
Author-email: "Andrew Shatz, Great Strength Systems" <andrew@greatstrength.me>
|
6
|
+
License: MIT
|
7
|
+
Project-URL: Homepage, https://github.com/greatstrength/tiferet-fast
|
8
|
+
Project-URL: Repository, https://github.com/greatstrength/tiferet-fast
|
9
|
+
Project-URL: Download, https://github.com/greatstrength/tiferet-fast
|
10
|
+
Requires-Python: >=3.10
|
11
|
+
Description-Content-Type: text/markdown
|
12
|
+
License-File: LICENSE
|
13
|
+
Requires-Dist: tiferet>=1.1.2
|
14
|
+
Requires-Dist: fastapi>=0.118.0
|
15
|
+
Requires-Dist: starlette-context>=0.4.0
|
16
|
+
Provides-Extra: test
|
17
|
+
Requires-Dist: pytest>=8.3.3; extra == "test"
|
18
|
+
Requires-Dist: pytest_env>=1.1.5; extra == "test"
|
19
|
+
Dynamic: license-file
|
20
|
+
|
21
|
+
# Tiferet Fast - A FastAPI Extension for the Tiferet Framework
|
22
|
+
|
23
|
+
## Introduction
|
24
|
+
|
25
|
+
Tiferet Fast elevates the Tiferet Python framework by enabling developers to build high-performance, asynchronous APIs using FastAPI, grounded in Domain-Driven Design (DDD) principles. Inspired by the concept of beauty in harmony, this extension integrates Tiferet’s command-driven architecture with FastAPI’s modern, declarative routing and automatic OpenAPI documentation. The result is a robust, modular platform for crafting scalable web services that transform complex business logic into elegant, extensible API designs.
|
26
|
+
|
27
|
+
This tutorial guides you through creating a streamlined calculator API, leveraging Tiferet’s commands and configurations while introducing FastAPI-specific interfaces and endpoints. For a deeper understanding of Tiferet’s core concepts, refer to the [Tiferet documentation](https://github.com/greatstrength/tiferet).
|
28
|
+
|
29
|
+
## Getting Started with Tiferet Fast
|
30
|
+
|
31
|
+
Begin your Tiferet Fast journey by setting up your development environment. This guide assumes familiarity with Tiferet’s core setup.
|
32
|
+
|
33
|
+
### Installing Python
|
34
|
+
|
35
|
+
Tiferet Fast requires Python 3.10 or later. Follow the detailed [Python installation instructions](https://github.com/greatstrength/tiferet?tab=readme-ov-file#installing-python) in the Tiferet README for your platform (Windows, macOS, or Linux). Verify your installation with:
|
36
|
+
|
37
|
+
```bash
|
38
|
+
python3.10 --version
|
39
|
+
```
|
40
|
+
|
41
|
+
### Setting Up a Virtual Environment
|
42
|
+
|
43
|
+
Create a dedicated virtual environment named `tiferet_fast_app` to manage dependencies:
|
44
|
+
|
45
|
+
```bash
|
46
|
+
# Create the Environment
|
47
|
+
# Windows
|
48
|
+
python -m venv tiferet_fast_app
|
49
|
+
|
50
|
+
# macOS/Linux
|
51
|
+
python3.10 -m venv tiferet_fast_app
|
52
|
+
|
53
|
+
# Activate the Environment
|
54
|
+
# Windows (Command Prompt)
|
55
|
+
tiferet_fast_app\Scripts\activate
|
56
|
+
|
57
|
+
# Windows (PowerShell)
|
58
|
+
.\tiferet_fast_app\Scripts\Activate.ps1
|
59
|
+
|
60
|
+
# macOS/Linux
|
61
|
+
source tiferet_fast_app/bin/activate
|
62
|
+
```
|
63
|
+
|
64
|
+
Exit the environment with `deactivate` when finished.
|
65
|
+
|
66
|
+
## Your First Calculator API
|
67
|
+
|
68
|
+
With your environment ready, install dependencies and configure the project structure to build a dynamic calculator API using Tiferet Fast.
|
69
|
+
|
70
|
+
### Installing Tiferet Fast
|
71
|
+
|
72
|
+
In your activated virtual environment, install the Tiferet Fast extension using pip:
|
73
|
+
|
74
|
+
```bash
|
75
|
+
# Windows
|
76
|
+
pip install tiferet_fast
|
77
|
+
|
78
|
+
# macOS/Linux
|
79
|
+
pip3 install tiferet_fast
|
80
|
+
```
|
81
|
+
|
82
|
+
Note: If developing locally, replace with the appropriate local installation command.
|
83
|
+
|
84
|
+
### Project Structure
|
85
|
+
|
86
|
+
Adapt Tiferet’s project structure to incorporate FastAPI, adding a dedicated API script:
|
87
|
+
|
88
|
+
```plaintext
|
89
|
+
project_root/
|
90
|
+
├── basic_calc.py
|
91
|
+
├── calc_cli.py
|
92
|
+
├── calc_fast_api.py
|
93
|
+
├── app/
|
94
|
+
├── commands/
|
95
|
+
│ ├── __init__.py
|
96
|
+
│ ├── calc.py
|
97
|
+
│ └── settings.py
|
98
|
+
└── configs/
|
99
|
+
├── __init__.py
|
100
|
+
├── app.yml
|
101
|
+
├── container.yml
|
102
|
+
├── error.yml
|
103
|
+
├── feature.yml
|
104
|
+
├── fast.yml
|
105
|
+
└── logging.yml
|
106
|
+
```
|
107
|
+
|
108
|
+
The `app/commands/` and `app/configs/` directories align with Tiferet’s structure (see [Tiferet README](https://github.com/greatstrength/tiferet?tab=readme-ov-file#project-structure)). The `calc_fast_api.py` script initializes and runs the FastAPI application, while `fast.yml` defines router and routing configurations.
|
109
|
+
|
110
|
+
## Crafting the Calculator API
|
111
|
+
|
112
|
+
Extend Tiferet’s calculator application into a powerful API by reusing its commands and configurations, enhanced with FastAPI-specific functionality.
|
113
|
+
|
114
|
+
### Defining Base and Arithmetic Command Classes
|
115
|
+
|
116
|
+
Leverage Tiferet’s `BasicCalcCommand` (`app/commands/settings.py`) for input validation and arithmetic commands (`AddNumber`, `SubtractNumber`, `MultiplyNumber`, `DivideNumber`, `ExponentiateNumber` in `app/commands/calc.py`) for core operations. These remain unchanged from the original calculator app; refer to the [Tiferet README](https://github.com/greatstrength/tiferet?tab=readme-ov-file#defining-base-and-arithmetic-command-classes) for details.
|
117
|
+
|
118
|
+
### Configuring the Calculator API
|
119
|
+
|
120
|
+
Reuse Tiferet’s `container.yml` ([here](https://github.com/greatstrength/tiferet?tab=readme-ov-file#configuring-the-container-in-configscontaineryml)), `error.yml` ([here](https://github.com/greatstrength/tiferet?tab=readme-ov-file#configuring-the-errors-in-configserroryml)), and `feature.yml` ([here](https://github.com/greatstrength/tiferet?tab=readme-ov-file#configuring-the-features-in-configsfeatureyml)) for command mappings, error handling, and feature workflows. Introduce a FastAPI-specific interface in `app.yml` and routing configurations in `fast.yml`.
|
121
|
+
|
122
|
+
#### Configuring the App Interface in `configs/app.yml`
|
123
|
+
|
124
|
+
Enhance `app/configs/app.yml` with the `calc_fast_api` interface:
|
125
|
+
|
126
|
+
```yaml
|
127
|
+
interfaces:
|
128
|
+
calc_fast_api:
|
129
|
+
name: Basic Calculator API
|
130
|
+
description: Perform basic calculator operations via FastAPI
|
131
|
+
module_path: tiferet_fast.contexts.fast
|
132
|
+
class_name: FastApiContext
|
133
|
+
attrs:
|
134
|
+
fast_api_handler:
|
135
|
+
module_path: tiferet_fast.handlers.fast
|
136
|
+
class_name: FastApiHandler
|
137
|
+
fast_repo:
|
138
|
+
module_path: tiferet_fast.proxies.yaml.fast
|
139
|
+
class_name: FastYamlProxy
|
140
|
+
params:
|
141
|
+
fast_config_file: app/configs/fast.yml
|
142
|
+
```
|
143
|
+
|
144
|
+
#### Configuring Routers, Routes, and Error Status Codes in `configs/fast.yml`
|
145
|
+
|
146
|
+
Define FastAPI routers, routes, and error mappings in `app/configs/fast.yml`:
|
147
|
+
|
148
|
+
```yaml
|
149
|
+
fast:
|
150
|
+
routers:
|
151
|
+
calc:
|
152
|
+
name: calc
|
153
|
+
prefix: /calc
|
154
|
+
routes:
|
155
|
+
add:
|
156
|
+
path: /add
|
157
|
+
methods: [POST, GET]
|
158
|
+
status_code: 200
|
159
|
+
subtract:
|
160
|
+
path: /subtract
|
161
|
+
methods: [POST, GET]
|
162
|
+
status_code: 200
|
163
|
+
multiply:
|
164
|
+
path: /multiply
|
165
|
+
methods: [POST, GET]
|
166
|
+
status_code: 200
|
167
|
+
divide:
|
168
|
+
path: /divide
|
169
|
+
methods: [POST, GET]
|
170
|
+
status_code: 200
|
171
|
+
sqrt:
|
172
|
+
path: /sqrt
|
173
|
+
methods: [POST, GET]
|
174
|
+
status_code: 200
|
175
|
+
errors:
|
176
|
+
DIVIDE_BY_ZERO: 400
|
177
|
+
```
|
178
|
+
|
179
|
+
The `prefix` ensures all routes are prefixed with `/calc`. Each route’s endpoint (e.g., `calc.add`) aligns with the corresponding feature ID in `feature.yml`. Routes specify a `path`, supported HTTP `methods`, and a default `status_code` of 200. The `errors` section maps error codes from `error.yml` to HTTP status codes, ensuring proper error handling.
|
180
|
+
|
181
|
+
This configuration enables `FastApiContext` to orchestrate FastAPI operations seamlessly.
|
182
|
+
|
183
|
+
### Initializing and Demonstrating the API in `calc_fast_api.py`
|
184
|
+
|
185
|
+
Create `calc_fast_api.py` to initialize the API and define endpoints:
|
186
|
+
|
187
|
+
```python
|
188
|
+
"""Tiferet Fast Calculator Initialization Script"""
|
189
|
+
|
190
|
+
# *** imports
|
191
|
+
|
192
|
+
# ** infra
|
193
|
+
from tiferet import App
|
194
|
+
from tiferet_fast.contexts.fast import FastApiContext
|
195
|
+
from starlette.requests import Request
|
196
|
+
from starlette.responses import JSONResponse
|
197
|
+
import uvicorn
|
198
|
+
|
199
|
+
# *** functions
|
200
|
+
|
201
|
+
# * function: view_func
|
202
|
+
async def view_func(request: Request):
|
203
|
+
'''
|
204
|
+
Call the view function whenever a route endpoint is invoked.
|
205
|
+
|
206
|
+
:param context: The Fast API context.
|
207
|
+
:type context: FastApiContext
|
208
|
+
:param kwargs: Additional keyword arguments.
|
209
|
+
:type kwargs: dict
|
210
|
+
:return: The result of the view function.
|
211
|
+
:rtype: Any
|
212
|
+
'''
|
213
|
+
|
214
|
+
data = await request.json() if request.headers.get('content-type') == 'application/json' else {}
|
215
|
+
data.update(dict(request.query_params))
|
216
|
+
data.update(dict(request.path_params))
|
217
|
+
|
218
|
+
# Format header data from the request headers.
|
219
|
+
headers = dict(request.headers)
|
220
|
+
|
221
|
+
# Execute the feature from the request endpoint.
|
222
|
+
response, status_code = context.run(
|
223
|
+
feature_id=request.scope['route'].name,
|
224
|
+
headers=headers,
|
225
|
+
data=data,
|
226
|
+
)
|
227
|
+
|
228
|
+
# Return the response.
|
229
|
+
return JSONResponse(response, status_code=status_code)
|
230
|
+
|
231
|
+
# *** exec
|
232
|
+
|
233
|
+
# Create the Fast API context.
|
234
|
+
context: FastApiContext = App().load_interface('calc_fast_api')
|
235
|
+
|
236
|
+
# Build the FastAPI app.
|
237
|
+
context.build_fast_app(view_func=view_func)
|
238
|
+
|
239
|
+
# Define the fast_app for external use (e.g., for FastAPI CLI or ASGI servers).
|
240
|
+
def fast_app():
|
241
|
+
'''
|
242
|
+
Create and return the FastAPI app for testing.
|
243
|
+
|
244
|
+
:return: The FastAPI app.
|
245
|
+
:rtype: FastAPI
|
246
|
+
'''
|
247
|
+
|
248
|
+
return context.fast_app
|
249
|
+
|
250
|
+
# Run the FastAPI app if this script is executed directly.
|
251
|
+
if __name__ == '__main__':
|
252
|
+
uvicorn.run(context.fast_app, host='127.0.0.1', port=8000)
|
253
|
+
```
|
254
|
+
|
255
|
+
This script initializes the Tiferet application, loads the `calc_fast_api` interface, and dynamically handles RESTful endpoints for arithmetic operations using FastAPI’s asynchronous routing.
|
256
|
+
|
257
|
+
### Demonstrating the Calculator API
|
258
|
+
|
259
|
+
Launch the API:
|
260
|
+
|
261
|
+
```bash
|
262
|
+
python3 calc_fast_api.py
|
263
|
+
```
|
264
|
+
|
265
|
+
Test endpoints using curl or tools like Postman:
|
266
|
+
|
267
|
+
```bash
|
268
|
+
# Add two numbers
|
269
|
+
curl -X POST http://127.0.0.1:8000/calc/add -H "Content-Type: application/json" -d '{"a": 1, "b": 2}'
|
270
|
+
# Output: 3
|
271
|
+
|
272
|
+
# Calculate square root
|
273
|
+
curl -X POST http://127.0.0.1:8000/calc/sqrt -H "Content-Type: application/json" -d '{"a": 16}'
|
274
|
+
# Output: 4.0
|
275
|
+
|
276
|
+
# Division by zero
|
277
|
+
curl -X POST http://127.0.0.1:8000/calc/divide -H "Content-Type: application/json" -d '{"a": 5, "b": 0}'
|
278
|
+
# Output: {"error_code": "DIVIDE_BY_ZERO", "text": "Cannot divide by zero"}
|
279
|
+
```
|
280
|
+
|
281
|
+
## Conclusion
|
282
|
+
|
283
|
+
Tiferet Fast empowers developers to craft high-performance, asynchronous FastAPI applications within Tiferet’s DDD framework, as demonstrated in this calculator tutorial. By reusing Tiferet’s commands and configurations and introducing a FastAPI interface, you’ve built a scalable, intuitive API with minimal effort. Expand its capabilities by integrating authentication, advanced features like trigonometric operations, or combining with Tiferet’s CLI or TUI contexts. Explore the [Tiferet documentation](https://github.com/greatstrength/tiferet) for advanced DDD techniques, and experiment with `app/configs/` to customize your API, transforming complex web applications into clear, purposeful solutions.
|
@@ -0,0 +1,263 @@
|
|
1
|
+
# Tiferet Fast - A FastAPI Extension for the Tiferet Framework
|
2
|
+
|
3
|
+
## Introduction
|
4
|
+
|
5
|
+
Tiferet Fast elevates the Tiferet Python framework by enabling developers to build high-performance, asynchronous APIs using FastAPI, grounded in Domain-Driven Design (DDD) principles. Inspired by the concept of beauty in harmony, this extension integrates Tiferet’s command-driven architecture with FastAPI’s modern, declarative routing and automatic OpenAPI documentation. The result is a robust, modular platform for crafting scalable web services that transform complex business logic into elegant, extensible API designs.
|
6
|
+
|
7
|
+
This tutorial guides you through creating a streamlined calculator API, leveraging Tiferet’s commands and configurations while introducing FastAPI-specific interfaces and endpoints. For a deeper understanding of Tiferet’s core concepts, refer to the [Tiferet documentation](https://github.com/greatstrength/tiferet).
|
8
|
+
|
9
|
+
## Getting Started with Tiferet Fast
|
10
|
+
|
11
|
+
Begin your Tiferet Fast journey by setting up your development environment. This guide assumes familiarity with Tiferet’s core setup.
|
12
|
+
|
13
|
+
### Installing Python
|
14
|
+
|
15
|
+
Tiferet Fast requires Python 3.10 or later. Follow the detailed [Python installation instructions](https://github.com/greatstrength/tiferet?tab=readme-ov-file#installing-python) in the Tiferet README for your platform (Windows, macOS, or Linux). Verify your installation with:
|
16
|
+
|
17
|
+
```bash
|
18
|
+
python3.10 --version
|
19
|
+
```
|
20
|
+
|
21
|
+
### Setting Up a Virtual Environment
|
22
|
+
|
23
|
+
Create a dedicated virtual environment named `tiferet_fast_app` to manage dependencies:
|
24
|
+
|
25
|
+
```bash
|
26
|
+
# Create the Environment
|
27
|
+
# Windows
|
28
|
+
python -m venv tiferet_fast_app
|
29
|
+
|
30
|
+
# macOS/Linux
|
31
|
+
python3.10 -m venv tiferet_fast_app
|
32
|
+
|
33
|
+
# Activate the Environment
|
34
|
+
# Windows (Command Prompt)
|
35
|
+
tiferet_fast_app\Scripts\activate
|
36
|
+
|
37
|
+
# Windows (PowerShell)
|
38
|
+
.\tiferet_fast_app\Scripts\Activate.ps1
|
39
|
+
|
40
|
+
# macOS/Linux
|
41
|
+
source tiferet_fast_app/bin/activate
|
42
|
+
```
|
43
|
+
|
44
|
+
Exit the environment with `deactivate` when finished.
|
45
|
+
|
46
|
+
## Your First Calculator API
|
47
|
+
|
48
|
+
With your environment ready, install dependencies and configure the project structure to build a dynamic calculator API using Tiferet Fast.
|
49
|
+
|
50
|
+
### Installing Tiferet Fast
|
51
|
+
|
52
|
+
In your activated virtual environment, install the Tiferet Fast extension using pip:
|
53
|
+
|
54
|
+
```bash
|
55
|
+
# Windows
|
56
|
+
pip install tiferet_fast
|
57
|
+
|
58
|
+
# macOS/Linux
|
59
|
+
pip3 install tiferet_fast
|
60
|
+
```
|
61
|
+
|
62
|
+
Note: If developing locally, replace with the appropriate local installation command.
|
63
|
+
|
64
|
+
### Project Structure
|
65
|
+
|
66
|
+
Adapt Tiferet’s project structure to incorporate FastAPI, adding a dedicated API script:
|
67
|
+
|
68
|
+
```plaintext
|
69
|
+
project_root/
|
70
|
+
├── basic_calc.py
|
71
|
+
├── calc_cli.py
|
72
|
+
├── calc_fast_api.py
|
73
|
+
├── app/
|
74
|
+
├── commands/
|
75
|
+
│ ├── __init__.py
|
76
|
+
│ ├── calc.py
|
77
|
+
│ └── settings.py
|
78
|
+
└── configs/
|
79
|
+
├── __init__.py
|
80
|
+
├── app.yml
|
81
|
+
├── container.yml
|
82
|
+
├── error.yml
|
83
|
+
├── feature.yml
|
84
|
+
├── fast.yml
|
85
|
+
└── logging.yml
|
86
|
+
```
|
87
|
+
|
88
|
+
The `app/commands/` and `app/configs/` directories align with Tiferet’s structure (see [Tiferet README](https://github.com/greatstrength/tiferet?tab=readme-ov-file#project-structure)). The `calc_fast_api.py` script initializes and runs the FastAPI application, while `fast.yml` defines router and routing configurations.
|
89
|
+
|
90
|
+
## Crafting the Calculator API
|
91
|
+
|
92
|
+
Extend Tiferet’s calculator application into a powerful API by reusing its commands and configurations, enhanced with FastAPI-specific functionality.
|
93
|
+
|
94
|
+
### Defining Base and Arithmetic Command Classes
|
95
|
+
|
96
|
+
Leverage Tiferet’s `BasicCalcCommand` (`app/commands/settings.py`) for input validation and arithmetic commands (`AddNumber`, `SubtractNumber`, `MultiplyNumber`, `DivideNumber`, `ExponentiateNumber` in `app/commands/calc.py`) for core operations. These remain unchanged from the original calculator app; refer to the [Tiferet README](https://github.com/greatstrength/tiferet?tab=readme-ov-file#defining-base-and-arithmetic-command-classes) for details.
|
97
|
+
|
98
|
+
### Configuring the Calculator API
|
99
|
+
|
100
|
+
Reuse Tiferet’s `container.yml` ([here](https://github.com/greatstrength/tiferet?tab=readme-ov-file#configuring-the-container-in-configscontaineryml)), `error.yml` ([here](https://github.com/greatstrength/tiferet?tab=readme-ov-file#configuring-the-errors-in-configserroryml)), and `feature.yml` ([here](https://github.com/greatstrength/tiferet?tab=readme-ov-file#configuring-the-features-in-configsfeatureyml)) for command mappings, error handling, and feature workflows. Introduce a FastAPI-specific interface in `app.yml` and routing configurations in `fast.yml`.
|
101
|
+
|
102
|
+
#### Configuring the App Interface in `configs/app.yml`
|
103
|
+
|
104
|
+
Enhance `app/configs/app.yml` with the `calc_fast_api` interface:
|
105
|
+
|
106
|
+
```yaml
|
107
|
+
interfaces:
|
108
|
+
calc_fast_api:
|
109
|
+
name: Basic Calculator API
|
110
|
+
description: Perform basic calculator operations via FastAPI
|
111
|
+
module_path: tiferet_fast.contexts.fast
|
112
|
+
class_name: FastApiContext
|
113
|
+
attrs:
|
114
|
+
fast_api_handler:
|
115
|
+
module_path: tiferet_fast.handlers.fast
|
116
|
+
class_name: FastApiHandler
|
117
|
+
fast_repo:
|
118
|
+
module_path: tiferet_fast.proxies.yaml.fast
|
119
|
+
class_name: FastYamlProxy
|
120
|
+
params:
|
121
|
+
fast_config_file: app/configs/fast.yml
|
122
|
+
```
|
123
|
+
|
124
|
+
#### Configuring Routers, Routes, and Error Status Codes in `configs/fast.yml`
|
125
|
+
|
126
|
+
Define FastAPI routers, routes, and error mappings in `app/configs/fast.yml`:
|
127
|
+
|
128
|
+
```yaml
|
129
|
+
fast:
|
130
|
+
routers:
|
131
|
+
calc:
|
132
|
+
name: calc
|
133
|
+
prefix: /calc
|
134
|
+
routes:
|
135
|
+
add:
|
136
|
+
path: /add
|
137
|
+
methods: [POST, GET]
|
138
|
+
status_code: 200
|
139
|
+
subtract:
|
140
|
+
path: /subtract
|
141
|
+
methods: [POST, GET]
|
142
|
+
status_code: 200
|
143
|
+
multiply:
|
144
|
+
path: /multiply
|
145
|
+
methods: [POST, GET]
|
146
|
+
status_code: 200
|
147
|
+
divide:
|
148
|
+
path: /divide
|
149
|
+
methods: [POST, GET]
|
150
|
+
status_code: 200
|
151
|
+
sqrt:
|
152
|
+
path: /sqrt
|
153
|
+
methods: [POST, GET]
|
154
|
+
status_code: 200
|
155
|
+
errors:
|
156
|
+
DIVIDE_BY_ZERO: 400
|
157
|
+
```
|
158
|
+
|
159
|
+
The `prefix` ensures all routes are prefixed with `/calc`. Each route’s endpoint (e.g., `calc.add`) aligns with the corresponding feature ID in `feature.yml`. Routes specify a `path`, supported HTTP `methods`, and a default `status_code` of 200. The `errors` section maps error codes from `error.yml` to HTTP status codes, ensuring proper error handling.
|
160
|
+
|
161
|
+
This configuration enables `FastApiContext` to orchestrate FastAPI operations seamlessly.
|
162
|
+
|
163
|
+
### Initializing and Demonstrating the API in `calc_fast_api.py`
|
164
|
+
|
165
|
+
Create `calc_fast_api.py` to initialize the API and define endpoints:
|
166
|
+
|
167
|
+
```python
|
168
|
+
"""Tiferet Fast Calculator Initialization Script"""
|
169
|
+
|
170
|
+
# *** imports
|
171
|
+
|
172
|
+
# ** infra
|
173
|
+
from tiferet import App
|
174
|
+
from tiferet_fast.contexts.fast import FastApiContext
|
175
|
+
from starlette.requests import Request
|
176
|
+
from starlette.responses import JSONResponse
|
177
|
+
import uvicorn
|
178
|
+
|
179
|
+
# *** functions
|
180
|
+
|
181
|
+
# * function: view_func
|
182
|
+
async def view_func(request: Request):
|
183
|
+
'''
|
184
|
+
Call the view function whenever a route endpoint is invoked.
|
185
|
+
|
186
|
+
:param context: The Fast API context.
|
187
|
+
:type context: FastApiContext
|
188
|
+
:param kwargs: Additional keyword arguments.
|
189
|
+
:type kwargs: dict
|
190
|
+
:return: The result of the view function.
|
191
|
+
:rtype: Any
|
192
|
+
'''
|
193
|
+
|
194
|
+
data = await request.json() if request.headers.get('content-type') == 'application/json' else {}
|
195
|
+
data.update(dict(request.query_params))
|
196
|
+
data.update(dict(request.path_params))
|
197
|
+
|
198
|
+
# Format header data from the request headers.
|
199
|
+
headers = dict(request.headers)
|
200
|
+
|
201
|
+
# Execute the feature from the request endpoint.
|
202
|
+
response, status_code = context.run(
|
203
|
+
feature_id=request.scope['route'].name,
|
204
|
+
headers=headers,
|
205
|
+
data=data,
|
206
|
+
)
|
207
|
+
|
208
|
+
# Return the response.
|
209
|
+
return JSONResponse(response, status_code=status_code)
|
210
|
+
|
211
|
+
# *** exec
|
212
|
+
|
213
|
+
# Create the Fast API context.
|
214
|
+
context: FastApiContext = App().load_interface('calc_fast_api')
|
215
|
+
|
216
|
+
# Build the FastAPI app.
|
217
|
+
context.build_fast_app(view_func=view_func)
|
218
|
+
|
219
|
+
# Define the fast_app for external use (e.g., for FastAPI CLI or ASGI servers).
|
220
|
+
def fast_app():
|
221
|
+
'''
|
222
|
+
Create and return the FastAPI app for testing.
|
223
|
+
|
224
|
+
:return: The FastAPI app.
|
225
|
+
:rtype: FastAPI
|
226
|
+
'''
|
227
|
+
|
228
|
+
return context.fast_app
|
229
|
+
|
230
|
+
# Run the FastAPI app if this script is executed directly.
|
231
|
+
if __name__ == '__main__':
|
232
|
+
uvicorn.run(context.fast_app, host='127.0.0.1', port=8000)
|
233
|
+
```
|
234
|
+
|
235
|
+
This script initializes the Tiferet application, loads the `calc_fast_api` interface, and dynamically handles RESTful endpoints for arithmetic operations using FastAPI’s asynchronous routing.
|
236
|
+
|
237
|
+
### Demonstrating the Calculator API
|
238
|
+
|
239
|
+
Launch the API:
|
240
|
+
|
241
|
+
```bash
|
242
|
+
python3 calc_fast_api.py
|
243
|
+
```
|
244
|
+
|
245
|
+
Test endpoints using curl or tools like Postman:
|
246
|
+
|
247
|
+
```bash
|
248
|
+
# Add two numbers
|
249
|
+
curl -X POST http://127.0.0.1:8000/calc/add -H "Content-Type: application/json" -d '{"a": 1, "b": 2}'
|
250
|
+
# Output: 3
|
251
|
+
|
252
|
+
# Calculate square root
|
253
|
+
curl -X POST http://127.0.0.1:8000/calc/sqrt -H "Content-Type: application/json" -d '{"a": 16}'
|
254
|
+
# Output: 4.0
|
255
|
+
|
256
|
+
# Division by zero
|
257
|
+
curl -X POST http://127.0.0.1:8000/calc/divide -H "Content-Type: application/json" -d '{"a": 5, "b": 0}'
|
258
|
+
# Output: {"error_code": "DIVIDE_BY_ZERO", "text": "Cannot divide by zero"}
|
259
|
+
```
|
260
|
+
|
261
|
+
## Conclusion
|
262
|
+
|
263
|
+
Tiferet Fast empowers developers to craft high-performance, asynchronous FastAPI applications within Tiferet’s DDD framework, as demonstrated in this calculator tutorial. By reusing Tiferet’s commands and configurations and introducing a FastAPI interface, you’ve built a scalable, intuitive API with minimal effort. Expand its capabilities by integrating authentication, advanced features like trigonometric operations, or combining with Tiferet’s CLI or TUI contexts. Explore the [Tiferet documentation](https://github.com/greatstrength/tiferet) for advanced DDD techniques, and experiment with `app/configs/` to customize your API, transforming complex web applications into clear, purposeful solutions.
|
@@ -0,0 +1,47 @@
|
|
1
|
+
[project]
|
2
|
+
name = "tiferet-fast"
|
3
|
+
dynamic = ["version"] # Mark version as dynamic
|
4
|
+
description = "An extension of the Tiferet Framework for the Fast API."
|
5
|
+
authors = [
|
6
|
+
{ name = "Andrew Shatz, Great Strength Systems", email = "andrew@greatstrength.me" }
|
7
|
+
]
|
8
|
+
license = { text = "MIT" }
|
9
|
+
readme = "README.md"
|
10
|
+
requires-python = ">=3.10"
|
11
|
+
dependencies = [
|
12
|
+
"tiferet>=1.1.2",
|
13
|
+
"fastapi>=0.118.0",
|
14
|
+
"starlette-context>=0.4.0"
|
15
|
+
]
|
16
|
+
|
17
|
+
[project.urls]
|
18
|
+
Homepage = "https://github.com/greatstrength/tiferet-fast"
|
19
|
+
Repository = "https://github.com/greatstrength/tiferet-fast"
|
20
|
+
Download = "https://github.com/greatstrength/tiferet-fast"
|
21
|
+
|
22
|
+
[project.optional-dependencies]
|
23
|
+
test = [
|
24
|
+
"pytest>=8.3.3",
|
25
|
+
"pytest_env>=1.1.5"
|
26
|
+
]
|
27
|
+
|
28
|
+
[build-system]
|
29
|
+
requires = ["setuptools>=61.0", "wheel"]
|
30
|
+
build-backend = "setuptools.build_meta"
|
31
|
+
|
32
|
+
[tool.setuptools.packages.find]
|
33
|
+
where = ["."]
|
34
|
+
include = [
|
35
|
+
"tiferet_fast",
|
36
|
+
"tiferet_fast.contexts",
|
37
|
+
"tiferet_fast.contracts",
|
38
|
+
"tiferet_fast.data",
|
39
|
+
"tiferet_fast.handlers",
|
40
|
+
"tiferet_fast.models",
|
41
|
+
"tiferet_fast.proxies",
|
42
|
+
"tiferet_fast.proxies.yaml"
|
43
|
+
]
|
44
|
+
|
45
|
+
[tool.setuptools.dynamic]
|
46
|
+
version = { attr = "tiferet_fast.__version__" }
|
47
|
+
|
@@ -0,0 +1,15 @@
|
|
1
|
+
"""Tiferet Fast - A FastAPI Framework"""
|
2
|
+
|
3
|
+
# *** exports
|
4
|
+
|
5
|
+
# ** app
|
6
|
+
# Export the main application context and related modules.
|
7
|
+
# Use a try-except block to avoid import errors on build systems.
|
8
|
+
try:
|
9
|
+
from .contexts import FastApiContext
|
10
|
+
except:
|
11
|
+
pass
|
12
|
+
|
13
|
+
# *** version
|
14
|
+
|
15
|
+
__version__ = "0.1.0"
|