starport 1.0.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.
Files changed (31) hide show
  1. starport-1.0.0/LICENSE +21 -0
  2. starport-1.0.0/PKG-INFO +278 -0
  3. starport-1.0.0/README.md +252 -0
  4. starport-1.0.0/pyproject.toml +159 -0
  5. starport-1.0.0/src/starport/__init__.py +40 -0
  6. starport-1.0.0/src/starport/__version__.py +3 -0
  7. starport-1.0.0/src/starport/app.py +1054 -0
  8. starport-1.0.0/src/starport/attrdict.py +83 -0
  9. starport-1.0.0/src/starport/config.py +131 -0
  10. starport-1.0.0/src/starport/exceptions/__init__.py +7 -0
  11. starport-1.0.0/src/starport/exceptions/validation.py +40 -0
  12. starport-1.0.0/src/starport/lazy.py +154 -0
  13. starport-1.0.0/src/starport/logging.py +297 -0
  14. starport-1.0.0/src/starport/openapi/__init__.py +17 -0
  15. starport-1.0.0/src/starport/openapi/generator.py +170 -0
  16. starport-1.0.0/src/starport/openapi/swagger.py +76 -0
  17. starport-1.0.0/src/starport/openapi_schema.py +599 -0
  18. starport-1.0.0/src/starport/params/__init__.py +7 -0
  19. starport-1.0.0/src/starport/params/__init__.pyi +12 -0
  20. starport-1.0.0/src/starport/params/basic.py +300 -0
  21. starport-1.0.0/src/starport/params/basic.pyi +97 -0
  22. starport-1.0.0/src/starport/params/custom.py +248 -0
  23. starport-1.0.0/src/starport/params/custom.pyi +40 -0
  24. starport-1.0.0/src/starport/params/jsonbody.py +312 -0
  25. starport-1.0.0/src/starport/params/jsonbody.pyi +29 -0
  26. starport-1.0.0/src/starport/py.typed +0 -0
  27. starport-1.0.0/src/starport/requests.py +4 -0
  28. starport-1.0.0/src/starport/responses.py +384 -0
  29. starport-1.0.0/src/starport/router.py +2196 -0
  30. starport-1.0.0/src/starport/status.py +8 -0
  31. starport-1.0.0/src/starport/validation.py +157 -0
starport-1.0.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 alpine
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,278 @@
1
+ Metadata-Version: 2.4
2
+ Name: starport
3
+ Version: 1.0.0
4
+ Summary: Explicit, AI-Ready Web Framework
5
+ Keywords:
6
+ Author: alpine
7
+ License-Expression: MIT
8
+ License-File: LICENSE
9
+ Classifier: Development Status :: 4 - Beta
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Programming Language :: Python :: 3 :: Only
13
+ Classifier: Programming Language :: Python :: 3.10
14
+ Classifier: Programming Language :: Python :: 3.11
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: Programming Language :: Python :: 3.13
17
+ Classifier: Topic :: Database
18
+ Requires-Dist: starlette>=0.39.0
19
+ Requires-Dist: pyjson5>=2.0.0
20
+ Requires-Dist: python-multipart>=0.0.21
21
+ Requires-Dist: jsonschema>=4 ; extra == 'validate'
22
+ Requires-Dist: openapi-spec-validator>=0.7 ; extra == 'validate'
23
+ Requires-Python: >=3.10
24
+ Provides-Extra: validate
25
+ Description-Content-Type: text/markdown
26
+
27
+ # Starport
28
+
29
+ **Explicit, AI-Ready Web Framework**
30
+
31
+ A minimalist abstraction for Starlette, optimized for the AI era.
32
+
33
+ [![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)
34
+
35
+ ![★Starport](res/logo.svg)
36
+
37
+ ---
38
+
39
+ ## 概要
40
+
41
+ **Starport** は実装者の意図を明示的にし、AIがその意図を正確に汲み取れる構造を第一に考えて設計された、Starlette ベースの Web フレームワークです。
42
+
43
+ ### 設計思想
44
+
45
+ 1. **シンプルさ** - 不要な抽象化を排除、直感的なAPI
46
+ 2. **AI Ready** - サンプル駆動のドキュメント、コードとドキュメントの一体化
47
+ 3. **適切な抽象化** - 隠蔽ではなく、必要に応じて Starlette を活用
48
+
49
+ ### 主な特徴
50
+
51
+ - ✅ **明示的設計 (Explicit)** - 暗黙的な動作を排除、意図が明確なコード
52
+ - ✅ **AI Ready** - JSON5リテラルによるサンプル駆動のドキュメント生成
53
+ - ✅ **軽量** - Pydantic不使用、必要最小限の依存関係
54
+ - ✅ **直感的** - `body.name` のような自然なアクセス、戻り値の型ヒントで動作を制御
55
+ - ✅ **OpenAPI 3.0** - 自動ドキュメント生成と Swagger UI
56
+ - ✅ **Secure by Default** - OpenAPIはデフォルト無効、本番環境での情報露出を防止
57
+
58
+ ---
59
+
60
+ ## クイックスタート
61
+
62
+ ### 基本的な実装
63
+
64
+ ```python
65
+ from starport import Router
66
+
67
+
68
+ app = Router(
69
+ openapi_url="/openapi.json",
70
+ docs_url="/docs",
71
+ )
72
+
73
+ @app.get("/helloworld")
74
+ def helloworld() -> str:
75
+ return "Hello, World!"
76
+
77
+
78
+ @app.get("/users")
79
+ def get_users() -> list:
80
+ return [{"id": "user_001", "name": "海野 彼方"}]
81
+
82
+
83
+ if __name__ == "__main__":
84
+ import uvicorn
85
+ print("Swagger UI is available at http://127.0.0.1:8000/docs")
86
+ uvicorn.run(app, host="127.0.0.1", port=8000)
87
+ ```
88
+
89
+ ### AI Ready のサンプル
90
+
91
+ ```python
92
+ from starport import Router
93
+ from starport.params import JsonBody, Query
94
+
95
+ app = Router(
96
+ openapi_url="/openapi.json",
97
+ docs_url="/docs",
98
+ )
99
+
100
+
101
+ @app.get(
102
+ "/users",
103
+ spec="""[{
104
+ id: "user001", // ユーザーID
105
+ name: "山田太郎", // 表示名
106
+ email: "yamada@example.com", // メールアドレス
107
+ "role?": "admin", // ロール(オプショナル)
108
+ created_at: "2024-01-01T00:00:00Z" // 作成日時
109
+ }]"""
110
+ )
111
+ def list_users(
112
+ page: int = Query(1, ge=1, description="ページ番号"),
113
+ limit: int = Query(100, ge=1, le=1000, description="取得件数"),
114
+ role: str = Query(None, description="ロールでフィルタ")
115
+ ) -> list[dict]:
116
+ """
117
+ ユーザー一覧を取得(最も基本的なパターン)
118
+
119
+ spec: レスポンスの構造を文書化(配列形式)
120
+ Query: パラメータを個別に定義(バリデーション付き)
121
+
122
+ これが最も実用的で、RESTful な API の基本形です。
123
+ """
124
+ # 簡易的な実装
125
+ users = [
126
+ {
127
+ "id": "user001",
128
+ "name": "山田太郎",
129
+ "email": "yamada@example.com",
130
+ "role": "admin",
131
+ "created_at": "2024-01-01T00:00:00Z"
132
+ },
133
+ {
134
+ "id": "user002",
135
+ "name": "佐藤花子",
136
+ "email": "sato@example.com",
137
+ "created_at": "2024-01-02T00:00:00Z"
138
+ },
139
+ {
140
+ "id": "user003",
141
+ "name": "鈴木一郎",
142
+ "email": "suzuki@example.com",
143
+ "role": "user",
144
+ "created_at": "2024-01-03T00:00:00Z"
145
+ }
146
+ ]
147
+
148
+ # ロールでフィルタ
149
+ if role:
150
+ users = [u for u in users if u.get("role") == role]
151
+
152
+ # ページネーション
153
+ start = (page - 1) * limit
154
+ end = start + limit
155
+
156
+ return users[start:end]
157
+
158
+
159
+ if __name__ == "__main__":
160
+ import uvicorn
161
+ print("Swagger UI is available at http://127.0.0.1:8000/docs")
162
+ uvicorn.run(app, host="127.0.0.1", port=8000)
163
+ ```
164
+
165
+ ### uv を使った実行方法
166
+
167
+ ```bash
168
+ # プロジェクト作成
169
+ uv init hello-starport
170
+ cd hello-starport/
171
+
172
+ # Starport と Uvicorn のインストール
173
+ uv add git+https://github.com/kinto-dev/starport.git
174
+ uv add uvicorn
175
+
176
+ # コードを作成
177
+ cat > main.py
178
+ # (上記のサンプルコードをペーストして Ctrl+D)
179
+
180
+ # サーバー起動
181
+ uv run main.py
182
+ ```
183
+
184
+ Swagger UI: http://127.0.0.1:8000/docs
185
+
186
+
187
+ ---
188
+
189
+ ## スケールするための設計 (Scalable by Design)
190
+
191
+ Starport は、小規模なスクリプトから大規模なアプリケーションまで対応可能です。
192
+ App を使って、機能を独立したモジュールとして分割・統合できます。
193
+
194
+
195
+ ```python
196
+ from starport import App, Route
197
+
198
+ app = App(
199
+ routes=[
200
+ Route("/todos", "myapp.todos:router"),
201
+ Route("/auth", "myapp.auth:router"),
202
+ ],
203
+ lazy=True,
204
+ title="My API",
205
+ version="1.0.0",
206
+ openapi_url="/openapi.json",
207
+ docs_url="/docs",
208
+ )
209
+ ```
210
+
211
+ ### 疎結合なマルチ・ルーター構成
212
+
213
+ FastAPI 等で見られる「インポート時に親 App へ登録する」方式ではなく、
214
+ 各ルーターを完全に独立した ASGI アプリとして定義し、後から統合する設計を採用しています。
215
+ これにより、循環参照を防止し、各機能を単体でテスト・実行することが容易になります。
216
+
217
+ ### lazy mount
218
+ App は初回リクエスト時にルーターをロード(import)することで、
219
+ 大規模アプリケーション(100+ routes)での開発体験を改善します。
220
+
221
+ - サーバレス環境(AWS Lambda等)の cold start 最適化
222
+ - 開発時の Hot-swap の高速化
223
+
224
+
225
+ ---
226
+
227
+ ## ドキュメント
228
+
229
+ ### 学習ガイド
230
+ - **[クイックスタート](docs/user/quickstart.md)** - 30分で始める Starport
231
+ - **[開発者ガイド](docs/user/guide.md)** - AI Ready な API 設計と大規模開発
232
+ - **[Spring Boot ユーザー向け入門](docs/user/introduction-for-spring-boot-users.md)** - Spring Boot からの移行ガイド
233
+
234
+ ### リファレンス
235
+ - **[OpenAPI スキーマガイド](docs/user/openapi-schema-guide.md)** - JSON5によるスキーマ定義
236
+
237
+ ### 実装例
238
+ - **[Examples](examples/)** - 実装サンプル集
239
+
240
+ ### 設計資料
241
+ - **[設計原則](docs/dev/design-principles.md)** - Starport の設計思想
242
+ - **[ADR](docs/dev/adr/)** - アーキテクチャ決定記録
243
+
244
+ ---
245
+
246
+ ## 開発
247
+
248
+ ```bash
249
+ # 環境構築
250
+ uv sync
251
+
252
+ # テスト実行
253
+ uv run pytest
254
+
255
+ # サンプル実行
256
+ uv run python -m examples.basics.basic
257
+ ```
258
+
259
+ ---
260
+
261
+ ## インストール
262
+
263
+ ```bash
264
+ # uv を使用する場合
265
+ uv add git+https://github.com/kinto-dev/starport.git
266
+
267
+ # pip を使用する場合
268
+ pip install git+https://github.com/kinto-dev/starport.git
269
+ ```
270
+
271
+ **注意**: Starport は現在開発中のため、PyPI での公開は未定です。
272
+
273
+ ---
274
+
275
+ ## 関連プロジェクト
276
+
277
+ - **[Starlette](https://www.starlette.io/)** - Starport の基盤となる ASGI フレームワーク
278
+ - **[FastAPI](https://fastapi.tiangolo.com/)** - Starport のインスピレーション元
@@ -0,0 +1,252 @@
1
+ # Starport
2
+
3
+ **Explicit, AI-Ready Web Framework**
4
+
5
+ A minimalist abstraction for Starlette, optimized for the AI era.
6
+
7
+ [![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)
8
+
9
+ ![★Starport](res/logo.svg)
10
+
11
+ ---
12
+
13
+ ## 概要
14
+
15
+ **Starport** は実装者の意図を明示的にし、AIがその意図を正確に汲み取れる構造を第一に考えて設計された、Starlette ベースの Web フレームワークです。
16
+
17
+ ### 設計思想
18
+
19
+ 1. **シンプルさ** - 不要な抽象化を排除、直感的なAPI
20
+ 2. **AI Ready** - サンプル駆動のドキュメント、コードとドキュメントの一体化
21
+ 3. **適切な抽象化** - 隠蔽ではなく、必要に応じて Starlette を活用
22
+
23
+ ### 主な特徴
24
+
25
+ - ✅ **明示的設計 (Explicit)** - 暗黙的な動作を排除、意図が明確なコード
26
+ - ✅ **AI Ready** - JSON5リテラルによるサンプル駆動のドキュメント生成
27
+ - ✅ **軽量** - Pydantic不使用、必要最小限の依存関係
28
+ - ✅ **直感的** - `body.name` のような自然なアクセス、戻り値の型ヒントで動作を制御
29
+ - ✅ **OpenAPI 3.0** - 自動ドキュメント生成と Swagger UI
30
+ - ✅ **Secure by Default** - OpenAPIはデフォルト無効、本番環境での情報露出を防止
31
+
32
+ ---
33
+
34
+ ## クイックスタート
35
+
36
+ ### 基本的な実装
37
+
38
+ ```python
39
+ from starport import Router
40
+
41
+
42
+ app = Router(
43
+ openapi_url="/openapi.json",
44
+ docs_url="/docs",
45
+ )
46
+
47
+ @app.get("/helloworld")
48
+ def helloworld() -> str:
49
+ return "Hello, World!"
50
+
51
+
52
+ @app.get("/users")
53
+ def get_users() -> list:
54
+ return [{"id": "user_001", "name": "海野 彼方"}]
55
+
56
+
57
+ if __name__ == "__main__":
58
+ import uvicorn
59
+ print("Swagger UI is available at http://127.0.0.1:8000/docs")
60
+ uvicorn.run(app, host="127.0.0.1", port=8000)
61
+ ```
62
+
63
+ ### AI Ready のサンプル
64
+
65
+ ```python
66
+ from starport import Router
67
+ from starport.params import JsonBody, Query
68
+
69
+ app = Router(
70
+ openapi_url="/openapi.json",
71
+ docs_url="/docs",
72
+ )
73
+
74
+
75
+ @app.get(
76
+ "/users",
77
+ spec="""[{
78
+ id: "user001", // ユーザーID
79
+ name: "山田太郎", // 表示名
80
+ email: "yamada@example.com", // メールアドレス
81
+ "role?": "admin", // ロール(オプショナル)
82
+ created_at: "2024-01-01T00:00:00Z" // 作成日時
83
+ }]"""
84
+ )
85
+ def list_users(
86
+ page: int = Query(1, ge=1, description="ページ番号"),
87
+ limit: int = Query(100, ge=1, le=1000, description="取得件数"),
88
+ role: str = Query(None, description="ロールでフィルタ")
89
+ ) -> list[dict]:
90
+ """
91
+ ユーザー一覧を取得(最も基本的なパターン)
92
+
93
+ spec: レスポンスの構造を文書化(配列形式)
94
+ Query: パラメータを個別に定義(バリデーション付き)
95
+
96
+ これが最も実用的で、RESTful な API の基本形です。
97
+ """
98
+ # 簡易的な実装
99
+ users = [
100
+ {
101
+ "id": "user001",
102
+ "name": "山田太郎",
103
+ "email": "yamada@example.com",
104
+ "role": "admin",
105
+ "created_at": "2024-01-01T00:00:00Z"
106
+ },
107
+ {
108
+ "id": "user002",
109
+ "name": "佐藤花子",
110
+ "email": "sato@example.com",
111
+ "created_at": "2024-01-02T00:00:00Z"
112
+ },
113
+ {
114
+ "id": "user003",
115
+ "name": "鈴木一郎",
116
+ "email": "suzuki@example.com",
117
+ "role": "user",
118
+ "created_at": "2024-01-03T00:00:00Z"
119
+ }
120
+ ]
121
+
122
+ # ロールでフィルタ
123
+ if role:
124
+ users = [u for u in users if u.get("role") == role]
125
+
126
+ # ページネーション
127
+ start = (page - 1) * limit
128
+ end = start + limit
129
+
130
+ return users[start:end]
131
+
132
+
133
+ if __name__ == "__main__":
134
+ import uvicorn
135
+ print("Swagger UI is available at http://127.0.0.1:8000/docs")
136
+ uvicorn.run(app, host="127.0.0.1", port=8000)
137
+ ```
138
+
139
+ ### uv を使った実行方法
140
+
141
+ ```bash
142
+ # プロジェクト作成
143
+ uv init hello-starport
144
+ cd hello-starport/
145
+
146
+ # Starport と Uvicorn のインストール
147
+ uv add git+https://github.com/kinto-dev/starport.git
148
+ uv add uvicorn
149
+
150
+ # コードを作成
151
+ cat > main.py
152
+ # (上記のサンプルコードをペーストして Ctrl+D)
153
+
154
+ # サーバー起動
155
+ uv run main.py
156
+ ```
157
+
158
+ Swagger UI: http://127.0.0.1:8000/docs
159
+
160
+
161
+ ---
162
+
163
+ ## スケールするための設計 (Scalable by Design)
164
+
165
+ Starport は、小規模なスクリプトから大規模なアプリケーションまで対応可能です。
166
+ App を使って、機能を独立したモジュールとして分割・統合できます。
167
+
168
+
169
+ ```python
170
+ from starport import App, Route
171
+
172
+ app = App(
173
+ routes=[
174
+ Route("/todos", "myapp.todos:router"),
175
+ Route("/auth", "myapp.auth:router"),
176
+ ],
177
+ lazy=True,
178
+ title="My API",
179
+ version="1.0.0",
180
+ openapi_url="/openapi.json",
181
+ docs_url="/docs",
182
+ )
183
+ ```
184
+
185
+ ### 疎結合なマルチ・ルーター構成
186
+
187
+ FastAPI 等で見られる「インポート時に親 App へ登録する」方式ではなく、
188
+ 各ルーターを完全に独立した ASGI アプリとして定義し、後から統合する設計を採用しています。
189
+ これにより、循環参照を防止し、各機能を単体でテスト・実行することが容易になります。
190
+
191
+ ### lazy mount
192
+ App は初回リクエスト時にルーターをロード(import)することで、
193
+ 大規模アプリケーション(100+ routes)での開発体験を改善します。
194
+
195
+ - サーバレス環境(AWS Lambda等)の cold start 最適化
196
+ - 開発時の Hot-swap の高速化
197
+
198
+
199
+ ---
200
+
201
+ ## ドキュメント
202
+
203
+ ### 学習ガイド
204
+ - **[クイックスタート](docs/user/quickstart.md)** - 30分で始める Starport
205
+ - **[開発者ガイド](docs/user/guide.md)** - AI Ready な API 設計と大規模開発
206
+ - **[Spring Boot ユーザー向け入門](docs/user/introduction-for-spring-boot-users.md)** - Spring Boot からの移行ガイド
207
+
208
+ ### リファレンス
209
+ - **[OpenAPI スキーマガイド](docs/user/openapi-schema-guide.md)** - JSON5によるスキーマ定義
210
+
211
+ ### 実装例
212
+ - **[Examples](examples/)** - 実装サンプル集
213
+
214
+ ### 設計資料
215
+ - **[設計原則](docs/dev/design-principles.md)** - Starport の設計思想
216
+ - **[ADR](docs/dev/adr/)** - アーキテクチャ決定記録
217
+
218
+ ---
219
+
220
+ ## 開発
221
+
222
+ ```bash
223
+ # 環境構築
224
+ uv sync
225
+
226
+ # テスト実行
227
+ uv run pytest
228
+
229
+ # サンプル実行
230
+ uv run python -m examples.basics.basic
231
+ ```
232
+
233
+ ---
234
+
235
+ ## インストール
236
+
237
+ ```bash
238
+ # uv を使用する場合
239
+ uv add git+https://github.com/kinto-dev/starport.git
240
+
241
+ # pip を使用する場合
242
+ pip install git+https://github.com/kinto-dev/starport.git
243
+ ```
244
+
245
+ **注意**: Starport は現在開発中のため、PyPI での公開は未定です。
246
+
247
+ ---
248
+
249
+ ## 関連プロジェクト
250
+
251
+ - **[Starlette](https://www.starlette.io/)** - Starport の基盤となる ASGI フレームワーク
252
+ - **[FastAPI](https://fastapi.tiangolo.com/)** - Starport のインスピレーション元
@@ -0,0 +1,159 @@
1
+ [build-system]
2
+ requires = ["uv_build>=0.11.15,<0.12"]
3
+ build-backend = "uv_build"
4
+
5
+ [project]
6
+ name = "starport"
7
+ version = "1.0.0"
8
+ description = "Explicit, AI-Ready Web Framework"
9
+ readme = "README.md"
10
+ license = "MIT"
11
+ license-files = ["LICENSE"]
12
+ authors = [
13
+ { name = "alpine" },
14
+ ]
15
+ keywords = []
16
+ classifiers = [
17
+ "Development Status :: 4 - Beta",
18
+ "Intended Audience :: Developers",
19
+ "Programming Language :: Python :: 3",
20
+ "Programming Language :: Python :: 3 :: Only",
21
+ "Programming Language :: Python :: 3.10",
22
+ "Programming Language :: Python :: 3.11",
23
+ "Programming Language :: Python :: 3.12",
24
+ "Programming Language :: Python :: 3.13",
25
+ "Topic :: Database",
26
+ ]
27
+ requires-python = ">=3.10"
28
+ dependencies = [
29
+ "starlette>=0.39.0",
30
+ "pyjson5>=2.0.0",
31
+ "python-multipart>=0.0.21",
32
+ ]
33
+
34
+ [project.optional-dependencies]
35
+ validate = [
36
+ # STARPORT_VALIDATE_SPEC=1
37
+ "jsonschema>=4",
38
+ # STARPORT_VALIDATE_OPENAPI=1
39
+ "openapi-spec-validator>=0.7",
40
+ ]
41
+
42
+ [project.scripts]
43
+ #starport = "starport.cli.main:main"
44
+
45
+ [dependency-groups]
46
+ dev = [
47
+ # validate
48
+ "jsonschema",
49
+ "openapi-spec-validator",
50
+ # Web server
51
+ "uvicorn[standard]>=0.38.0",
52
+ # Linting
53
+ "ruff",
54
+ #-- pytest --
55
+ "pytest>=7.0.0",
56
+ "pytest-cov>=4.0.0",
57
+ "pytest-mock>=3.10.0",
58
+ "pytest-benchmark>=5.2.3",
59
+ "httpx>=0.28.1",
60
+ "fastapi>=0.141.1",
61
+ #-- dev-docs skill --
62
+ "pyyaml>=6.0.3",
63
+ "pytest-env>=1.6.0",
64
+ "pytest-asyncio>=1.4.0",
65
+ ]
66
+
67
+
68
+ [tool.uv]
69
+ package = true
70
+
71
+
72
+ [tool.ruff]
73
+ # https://docs.astral.sh/ruff/configuration/
74
+ include = ["src/**/*.py", "tests/**/*.py", "scripts/**/*.py"]
75
+ cache-dir = "var/.ruff_cache"
76
+ target-version = "py310"
77
+ preview = true
78
+ # unsafe-fixes = true
79
+
80
+
81
+ [tool.ruff.lint]
82
+ # https://docs.astral.sh/ruff/rules/
83
+ select = [
84
+ # pycodestyle (E, W)
85
+ "E2",
86
+ "E4",
87
+ "E7",
88
+ "E9",
89
+ "W",
90
+
91
+ # Pyflakes (F)
92
+ "F",
93
+
94
+ # flake8-no-pep420 (INP)
95
+ "INP",
96
+
97
+ # pep8-naming (N)
98
+ #"N",
99
+ ]
100
+ ignore = [
101
+ "W293", # Blank line contains whitespace
102
+ ]
103
+
104
+ [tool.ruff.lint.per-file-ignores]
105
+ "docker/*.py" = ["INP"]
106
+ "scripts/*.py" = ["INP"]
107
+ "tests/*.py" = ["INP"]
108
+ "var/*.py" = ["INP"]
109
+
110
+ [tool.ruff.lint.pycodestyle]
111
+ max-line-length = 130
112
+
113
+ [tool.pytest.ini_options]
114
+ testpaths = ["tests", "examples"]
115
+ pythonpath = ["src"]
116
+ asyncio_mode = "auto"
117
+ cache_dir = "var/.pytest_cache"
118
+
119
+ log_level = "INFO"
120
+ log_cli = true
121
+ log_cli_level = "INFO"
122
+ log_cli_format = "%(asctime)s.%(msecs)03d [%(levelname)s] %(name)s:%(lineno)d - %(message)s"
123
+ log_file = "var/log/pytest.log"
124
+ log_file_level = "INFO"
125
+ log_file_format = "%(asctime)s [%(levelname)s] <%(threadName)s> %(name)s:%(lineno)d - %(message)s"
126
+
127
+ # pytest-benchmark
128
+ # - https://pytest-benchmark.readthedocs.io/en/latest/usage.html
129
+ #
130
+ # use --benchmark-only to run them. This overrides –-benchmark-skip.
131
+ # ❯ pytest --benchmark-only [-k <test_name>]
132
+ addopts = "--benchmark-skip"
133
+
134
+
135
+ [tool.pytest_env]
136
+ STARPORT_VALIDATE_OPENAPI = 1
137
+ STARPORT_VALIDATE_SPEC = 1
138
+
139
+
140
+ [tool.coverage.run]
141
+ source = ["src"]
142
+ data_file = "var/.coverage"
143
+ omit = [
144
+ "tests/*",
145
+ ]
146
+
147
+ [tool.coverage.report]
148
+ exclude_lines = [
149
+ "pragma: no cover",
150
+ "def __repr__",
151
+ "if self.debug:",
152
+ "if settings.DEBUG",
153
+ "raise AssertionError",
154
+ "raise NotImplementedError",
155
+ "if 0:",
156
+ "if __name__ == .__main__.:",
157
+ "class .*\\bProtocol\\):",
158
+ "@(abc\\.)?abstractmethod",
159
+ ]