usfbios 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.
@@ -0,0 +1,67 @@
1
+ # Environment
2
+ .env
3
+ .env.local
4
+ .env.*.local
5
+ !.env.example
6
+
7
+ # Per-service env files (contain secrets)
8
+ services/*/.env
9
+ services/*/.env.local
10
+ platform/*/.env
11
+ platform/*/.env.local
12
+
13
+ # Keep .env.example files tracked
14
+ !services/*/.env.example
15
+ !platform/*/.env.example
16
+
17
+ # Go
18
+ vendor/
19
+ main
20
+ *.exe
21
+ *.exe~
22
+ *.dll
23
+ *.so
24
+ *.dylib
25
+ *.test
26
+ *.out
27
+ go.work
28
+ go.work.sum
29
+
30
+ # Python
31
+ __pycache__/
32
+ *.py[cod]
33
+ *$py.class
34
+ *.so
35
+ .Python
36
+ env/
37
+ venv/
38
+ .venv/
39
+ *.egg-info/
40
+ dist/
41
+ build/
42
+
43
+ # Node
44
+ node_modules/
45
+ .next/
46
+ out/
47
+ .turbo/
48
+
49
+ # IDE
50
+ .idea/
51
+ .vscode/
52
+ *.swp
53
+ *.swo
54
+ *~
55
+ .DS_Store
56
+
57
+ # Docker
58
+ docker-compose.override.yml
59
+
60
+ # Logs
61
+ *.log
62
+ logs/
63
+
64
+ # Coverage
65
+ coverage/
66
+ *.cover
67
+ htmlcov/
usfbios-1.0.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 USF Inc
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.
usfbios-1.0.0/PKG-INFO ADDED
@@ -0,0 +1,297 @@
1
+ Metadata-Version: 2.4
2
+ Name: usfbios
3
+ Version: 1.0.0
4
+ Summary: Official Python SDK for the USF BIOS fine-tuning platform API
5
+ Project-URL: Homepage, https://bios.us.com
6
+ Project-URL: Documentation, https://bios.us.com/docs
7
+ Author-email: USF Inc <bios@us.inc>
8
+ License-Expression: MIT
9
+ License-File: LICENSE
10
+ Keywords: fine-tuning,llm,machine-learning,sdk,usfbios
11
+ Classifier: Development Status :: 5 - Production/Stable
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.8
16
+ Classifier: Programming Language :: Python :: 3.9
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
22
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
23
+ Classifier: Typing :: Typed
24
+ Requires-Python: >=3.8
25
+ Requires-Dist: requests>=2.28.0
26
+ Description-Content-Type: text/markdown
27
+
28
+ # usfbios
29
+
30
+ Official Python SDK for the [USF BIOS](https://bios.us.com) fine-tuning platform API.
31
+
32
+ ## Installation
33
+
34
+ ```bash
35
+ pip install usfbios
36
+ ```
37
+
38
+ ## Quick Start
39
+
40
+ ```python
41
+ from usfbios import USFBios
42
+
43
+ client = USFBios(api_key="sk_live_...")
44
+
45
+ # Search for models
46
+ result = client.models.search(query="llama", type="llm", limit=5)
47
+ for model in result["models"]:
48
+ print(f"{model['id']} -- {model['totalParams']}B params")
49
+
50
+ # Create a training job
51
+ job = client.training.create(
52
+ model="meta-llama/Llama-3.1-8B-Instruct",
53
+ dataset_id="ds_abc123",
54
+ method="sft",
55
+ adapter="lora",
56
+ epochs=3,
57
+ learning_rate=2e-4,
58
+ lora_rank=16,
59
+ )
60
+ print(f"Job {job['id']} created -- status: {job['status']}")
61
+ ```
62
+
63
+ ## Authentication
64
+
65
+ The SDK supports two authentication methods:
66
+
67
+ **API Key** (recommended):
68
+ ```python
69
+ client = USFBios(api_key="sk_live_...")
70
+ ```
71
+
72
+ **JWT Access Token**:
73
+ ```python
74
+ client = USFBios(
75
+ access_token="eyJhbG...",
76
+ org_id="org_abc123",
77
+ )
78
+ ```
79
+
80
+ ## Configuration
81
+
82
+ | Parameter | Type | Default | Description |
83
+ |---|---|---|---|
84
+ | `api_key` | `str` | `None` | API key for authentication (prefix: `sk_live_`) |
85
+ | `access_token` | `str` | `None` | JWT access token (alternative to API key) |
86
+ | `org_id` | `str` | `None` | Organization ID (required for JWT auth) |
87
+ | `workspace_id` | `str` | `None` | Workspace ID (optional, overrides key default) |
88
+ | `base_url` | `str` | `https://api-bios.us.inc` | API base URL |
89
+ | `timeout` | `float` | `30.0` | Request timeout in seconds |
90
+
91
+ ## Resources
92
+
93
+ ### Models
94
+
95
+ Search the HuggingFace model catalog, fetch training configs, and check adapter compatibility.
96
+
97
+ ```python
98
+ # Search models
99
+ result = client.models.search(query="llama", type="llm", limit=10)
100
+
101
+ # Get model config
102
+ config = client.models.get_config("meta-llama/Llama-3.1-8B")
103
+ print(f"{config['totalParams']}B params, MoE: {config['isMoE']}")
104
+
105
+ # Check adapter compatibility
106
+ compat = client.models.get_adapter_compatibility(
107
+ model_type="llama",
108
+ training_method="rlhf",
109
+ rlhf_algorithm="dpo",
110
+ )
111
+ usable = [a for a in compat["adapters"] if a["compatible"]]
112
+ print(f"{len(usable)} compatible adapters")
113
+ ```
114
+
115
+ ### Datasets
116
+
117
+ Upload, import, preview, and manage training datasets.
118
+
119
+ ```python
120
+ # List datasets
121
+ datasets = client.datasets.list()
122
+
123
+ # Upload a dataset
124
+ uploaded = client.datasets.upload(
125
+ file_path="./training_data.jsonl",
126
+ name="My SFT Dataset",
127
+ )
128
+ print(f"Uploaded: {uploaded['id']}")
129
+
130
+ # Import from HuggingFace
131
+ imported = client.datasets.import_from_huggingface(
132
+ repo_id="databricks/dolly-15k",
133
+ integration_id="int_abc123",
134
+ name="Dolly 15k",
135
+ )
136
+
137
+ # Preview dataset rows
138
+ preview = client.datasets.preview("ds_abc123", page=1, page_size=5)
139
+ print(preview["columns"])
140
+
141
+ # Validate before uploading
142
+ result = client.datasets.validate("./data.jsonl")
143
+ if result["valid"]:
144
+ print(f"Valid {result['format']} with {result['row_count']} rows")
145
+ else:
146
+ print("Errors:", result["errors"])
147
+
148
+ # Search HuggingFace Hub
149
+ hub_results = client.datasets.search_hub(query="code instruct")
150
+
151
+ # Preview a Hub dataset
152
+ hub_preview = client.datasets.preview_hub(
153
+ dataset_id="databricks/dolly-15k",
154
+ split="train",
155
+ limit=5,
156
+ )
157
+
158
+ # Get format specs
159
+ specs = client.datasets.get_format_specs()
160
+
161
+ # Get storage usage
162
+ usage = client.datasets.get_storage_usage()
163
+
164
+ # Delete a dataset
165
+ client.datasets.delete("ds_abc123")
166
+ ```
167
+
168
+ ### Training
169
+
170
+ Create, monitor, stop, and resume fine-tuning jobs.
171
+
172
+ ```python
173
+ # Create a training job
174
+ job = client.training.create(
175
+ model="meta-llama/Llama-3.1-8B-Instruct",
176
+ dataset_id="ds_abc123",
177
+ method="sft",
178
+ adapter="lora",
179
+ epochs=3,
180
+ learning_rate=2e-4,
181
+ lora_rank=16,
182
+ lora_alpha=32,
183
+ gpu_type="A100_80GB",
184
+ gpu_count=1,
185
+ )
186
+
187
+ # List jobs
188
+ jobs = client.training.list(status="running")
189
+
190
+ # Get job details
191
+ job = client.training.get("job_abc123")
192
+ print(f"Status: {job['status']}, Progress: {job.get('progress', 0)}%")
193
+
194
+ # Get metrics
195
+ metrics = client.training.get_metrics("job_abc123")
196
+ print(f"Current loss: {metrics.get('current_loss')}")
197
+
198
+ # Get checkpoints
199
+ checkpoints = client.training.get_checkpoints("job_abc123")
200
+ for cp in checkpoints:
201
+ print(f"Step {cp['step']}: loss {cp.get('loss')}")
202
+
203
+ # Get logs
204
+ logs = client.training.get_logs("job_abc123")
205
+ for line in logs["logs"]:
206
+ print(line)
207
+
208
+ # Stop a job
209
+ client.training.stop("job_abc123", keep_data=True)
210
+
211
+ # Resume a stopped job
212
+ client.training.resume("job_abc123")
213
+
214
+ # Delete a checkpoint
215
+ client.training.delete_checkpoint("job_abc123", "cp_xyz789")
216
+ ```
217
+
218
+ ### Wallet
219
+
220
+ View wallet balance and transaction history.
221
+
222
+ ```python
223
+ # Get balance
224
+ balance = client.wallet.get_balance()
225
+ print(f"Balance: ${balance['balance_cents'] / 100:.2f}")
226
+ print(f"Available: ${balance['available_cents'] / 100:.2f}")
227
+
228
+ # List transactions
229
+ txns = client.wallet.get_transactions(limit=20)
230
+ for t in txns:
231
+ print(f"{t['type']}: ${t['amount_cents'] / 100:.2f} -- {t.get('description')}")
232
+
233
+ # Get pricing
234
+ pricing = client.wallet.get_pricing()
235
+ ```
236
+
237
+ ### GPU
238
+
239
+ View GPU pricing and get hardware recommendations.
240
+
241
+ ```python
242
+ # Get all GPU pricing
243
+ pricing = client.gpu.get_pricing()
244
+ for gpu in pricing["gpus"]:
245
+ print(f"{gpu['display_name']}: {gpu['price_display']} -- {gpu['vram_gb']}GB VRAM")
246
+
247
+ # Get recommended GPU for a model
248
+ rec = client.gpu.get_recommended("meta-llama/Llama-3.1-8B-Instruct")
249
+ if rec:
250
+ print(f"Recommended: {rec['display_name']} x{rec['recommended_count']}")
251
+ print(f"Total VRAM: {rec['total_vram_gb']}GB")
252
+ print(f"Cost: ${rec['estimated_cost_per_hour_cents'] / 100:.2f}/hr")
253
+ print(f"Reason: {rec['reason']}")
254
+ ```
255
+
256
+ ### Introspect
257
+
258
+ Discover the permissions and scope of your API key.
259
+
260
+ ```python
261
+ info = client.introspect()
262
+ print(f"Org: {info['org']['name']}")
263
+ print(f"Scopes: {', '.join(info['scopes'])}")
264
+ print(f"Allowed tools: {len(info['allowed_mcp_tools'])}")
265
+ ```
266
+
267
+ ## Error Handling
268
+
269
+ All API errors raise `ApiError` with `status`, `code`, `request_id`, and `message` attributes.
270
+
271
+ ```python
272
+ from usfbios import USFBios, ApiError
273
+
274
+ client = USFBios(api_key="sk_live_...")
275
+
276
+ try:
277
+ job = client.training.get("bad_id")
278
+ except ApiError as e:
279
+ if e.status == 404:
280
+ print("Job not found")
281
+ elif e.status == 401:
282
+ print("Invalid API key")
283
+ elif e.status == 403:
284
+ print("Insufficient permissions")
285
+ else:
286
+ print(f"API error {e.status}: {e.message}")
287
+ if e.request_id:
288
+ print(f"Request ID: {e.request_id}")
289
+ ```
290
+
291
+ ## Python Version Support
292
+
293
+ - Python 3.8+
294
+
295
+ ## License
296
+
297
+ MIT
@@ -0,0 +1,270 @@
1
+ # usfbios
2
+
3
+ Official Python SDK for the [USF BIOS](https://bios.us.com) fine-tuning platform API.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ pip install usfbios
9
+ ```
10
+
11
+ ## Quick Start
12
+
13
+ ```python
14
+ from usfbios import USFBios
15
+
16
+ client = USFBios(api_key="sk_live_...")
17
+
18
+ # Search for models
19
+ result = client.models.search(query="llama", type="llm", limit=5)
20
+ for model in result["models"]:
21
+ print(f"{model['id']} -- {model['totalParams']}B params")
22
+
23
+ # Create a training job
24
+ job = client.training.create(
25
+ model="meta-llama/Llama-3.1-8B-Instruct",
26
+ dataset_id="ds_abc123",
27
+ method="sft",
28
+ adapter="lora",
29
+ epochs=3,
30
+ learning_rate=2e-4,
31
+ lora_rank=16,
32
+ )
33
+ print(f"Job {job['id']} created -- status: {job['status']}")
34
+ ```
35
+
36
+ ## Authentication
37
+
38
+ The SDK supports two authentication methods:
39
+
40
+ **API Key** (recommended):
41
+ ```python
42
+ client = USFBios(api_key="sk_live_...")
43
+ ```
44
+
45
+ **JWT Access Token**:
46
+ ```python
47
+ client = USFBios(
48
+ access_token="eyJhbG...",
49
+ org_id="org_abc123",
50
+ )
51
+ ```
52
+
53
+ ## Configuration
54
+
55
+ | Parameter | Type | Default | Description |
56
+ |---|---|---|---|
57
+ | `api_key` | `str` | `None` | API key for authentication (prefix: `sk_live_`) |
58
+ | `access_token` | `str` | `None` | JWT access token (alternative to API key) |
59
+ | `org_id` | `str` | `None` | Organization ID (required for JWT auth) |
60
+ | `workspace_id` | `str` | `None` | Workspace ID (optional, overrides key default) |
61
+ | `base_url` | `str` | `https://api-bios.us.inc` | API base URL |
62
+ | `timeout` | `float` | `30.0` | Request timeout in seconds |
63
+
64
+ ## Resources
65
+
66
+ ### Models
67
+
68
+ Search the HuggingFace model catalog, fetch training configs, and check adapter compatibility.
69
+
70
+ ```python
71
+ # Search models
72
+ result = client.models.search(query="llama", type="llm", limit=10)
73
+
74
+ # Get model config
75
+ config = client.models.get_config("meta-llama/Llama-3.1-8B")
76
+ print(f"{config['totalParams']}B params, MoE: {config['isMoE']}")
77
+
78
+ # Check adapter compatibility
79
+ compat = client.models.get_adapter_compatibility(
80
+ model_type="llama",
81
+ training_method="rlhf",
82
+ rlhf_algorithm="dpo",
83
+ )
84
+ usable = [a for a in compat["adapters"] if a["compatible"]]
85
+ print(f"{len(usable)} compatible adapters")
86
+ ```
87
+
88
+ ### Datasets
89
+
90
+ Upload, import, preview, and manage training datasets.
91
+
92
+ ```python
93
+ # List datasets
94
+ datasets = client.datasets.list()
95
+
96
+ # Upload a dataset
97
+ uploaded = client.datasets.upload(
98
+ file_path="./training_data.jsonl",
99
+ name="My SFT Dataset",
100
+ )
101
+ print(f"Uploaded: {uploaded['id']}")
102
+
103
+ # Import from HuggingFace
104
+ imported = client.datasets.import_from_huggingface(
105
+ repo_id="databricks/dolly-15k",
106
+ integration_id="int_abc123",
107
+ name="Dolly 15k",
108
+ )
109
+
110
+ # Preview dataset rows
111
+ preview = client.datasets.preview("ds_abc123", page=1, page_size=5)
112
+ print(preview["columns"])
113
+
114
+ # Validate before uploading
115
+ result = client.datasets.validate("./data.jsonl")
116
+ if result["valid"]:
117
+ print(f"Valid {result['format']} with {result['row_count']} rows")
118
+ else:
119
+ print("Errors:", result["errors"])
120
+
121
+ # Search HuggingFace Hub
122
+ hub_results = client.datasets.search_hub(query="code instruct")
123
+
124
+ # Preview a Hub dataset
125
+ hub_preview = client.datasets.preview_hub(
126
+ dataset_id="databricks/dolly-15k",
127
+ split="train",
128
+ limit=5,
129
+ )
130
+
131
+ # Get format specs
132
+ specs = client.datasets.get_format_specs()
133
+
134
+ # Get storage usage
135
+ usage = client.datasets.get_storage_usage()
136
+
137
+ # Delete a dataset
138
+ client.datasets.delete("ds_abc123")
139
+ ```
140
+
141
+ ### Training
142
+
143
+ Create, monitor, stop, and resume fine-tuning jobs.
144
+
145
+ ```python
146
+ # Create a training job
147
+ job = client.training.create(
148
+ model="meta-llama/Llama-3.1-8B-Instruct",
149
+ dataset_id="ds_abc123",
150
+ method="sft",
151
+ adapter="lora",
152
+ epochs=3,
153
+ learning_rate=2e-4,
154
+ lora_rank=16,
155
+ lora_alpha=32,
156
+ gpu_type="A100_80GB",
157
+ gpu_count=1,
158
+ )
159
+
160
+ # List jobs
161
+ jobs = client.training.list(status="running")
162
+
163
+ # Get job details
164
+ job = client.training.get("job_abc123")
165
+ print(f"Status: {job['status']}, Progress: {job.get('progress', 0)}%")
166
+
167
+ # Get metrics
168
+ metrics = client.training.get_metrics("job_abc123")
169
+ print(f"Current loss: {metrics.get('current_loss')}")
170
+
171
+ # Get checkpoints
172
+ checkpoints = client.training.get_checkpoints("job_abc123")
173
+ for cp in checkpoints:
174
+ print(f"Step {cp['step']}: loss {cp.get('loss')}")
175
+
176
+ # Get logs
177
+ logs = client.training.get_logs("job_abc123")
178
+ for line in logs["logs"]:
179
+ print(line)
180
+
181
+ # Stop a job
182
+ client.training.stop("job_abc123", keep_data=True)
183
+
184
+ # Resume a stopped job
185
+ client.training.resume("job_abc123")
186
+
187
+ # Delete a checkpoint
188
+ client.training.delete_checkpoint("job_abc123", "cp_xyz789")
189
+ ```
190
+
191
+ ### Wallet
192
+
193
+ View wallet balance and transaction history.
194
+
195
+ ```python
196
+ # Get balance
197
+ balance = client.wallet.get_balance()
198
+ print(f"Balance: ${balance['balance_cents'] / 100:.2f}")
199
+ print(f"Available: ${balance['available_cents'] / 100:.2f}")
200
+
201
+ # List transactions
202
+ txns = client.wallet.get_transactions(limit=20)
203
+ for t in txns:
204
+ print(f"{t['type']}: ${t['amount_cents'] / 100:.2f} -- {t.get('description')}")
205
+
206
+ # Get pricing
207
+ pricing = client.wallet.get_pricing()
208
+ ```
209
+
210
+ ### GPU
211
+
212
+ View GPU pricing and get hardware recommendations.
213
+
214
+ ```python
215
+ # Get all GPU pricing
216
+ pricing = client.gpu.get_pricing()
217
+ for gpu in pricing["gpus"]:
218
+ print(f"{gpu['display_name']}: {gpu['price_display']} -- {gpu['vram_gb']}GB VRAM")
219
+
220
+ # Get recommended GPU for a model
221
+ rec = client.gpu.get_recommended("meta-llama/Llama-3.1-8B-Instruct")
222
+ if rec:
223
+ print(f"Recommended: {rec['display_name']} x{rec['recommended_count']}")
224
+ print(f"Total VRAM: {rec['total_vram_gb']}GB")
225
+ print(f"Cost: ${rec['estimated_cost_per_hour_cents'] / 100:.2f}/hr")
226
+ print(f"Reason: {rec['reason']}")
227
+ ```
228
+
229
+ ### Introspect
230
+
231
+ Discover the permissions and scope of your API key.
232
+
233
+ ```python
234
+ info = client.introspect()
235
+ print(f"Org: {info['org']['name']}")
236
+ print(f"Scopes: {', '.join(info['scopes'])}")
237
+ print(f"Allowed tools: {len(info['allowed_mcp_tools'])}")
238
+ ```
239
+
240
+ ## Error Handling
241
+
242
+ All API errors raise `ApiError` with `status`, `code`, `request_id`, and `message` attributes.
243
+
244
+ ```python
245
+ from usfbios import USFBios, ApiError
246
+
247
+ client = USFBios(api_key="sk_live_...")
248
+
249
+ try:
250
+ job = client.training.get("bad_id")
251
+ except ApiError as e:
252
+ if e.status == 404:
253
+ print("Job not found")
254
+ elif e.status == 401:
255
+ print("Invalid API key")
256
+ elif e.status == 403:
257
+ print("Insufficient permissions")
258
+ else:
259
+ print(f"API error {e.status}: {e.message}")
260
+ if e.request_id:
261
+ print(f"Request ID: {e.request_id}")
262
+ ```
263
+
264
+ ## Python Version Support
265
+
266
+ - Python 3.8+
267
+
268
+ ## License
269
+
270
+ MIT
@@ -0,0 +1,40 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "usfbios"
7
+ version = "1.0.0"
8
+ description = "Official Python SDK for the USF BIOS fine-tuning platform API"
9
+ readme = "README.md"
10
+ license = "MIT"
11
+ requires-python = ">=3.8"
12
+ authors = [
13
+ { name = "USF Inc", email = "bios@us.inc" },
14
+ ]
15
+ keywords = ["usfbios", "fine-tuning", "llm", "machine-learning", "sdk"]
16
+ classifiers = [
17
+ "Development Status :: 5 - Production/Stable",
18
+ "Intended Audience :: Developers",
19
+ "License :: OSI Approved :: MIT License",
20
+ "Programming Language :: Python :: 3",
21
+ "Programming Language :: Python :: 3.8",
22
+ "Programming Language :: Python :: 3.9",
23
+ "Programming Language :: Python :: 3.10",
24
+ "Programming Language :: Python :: 3.11",
25
+ "Programming Language :: Python :: 3.12",
26
+ "Programming Language :: Python :: 3.13",
27
+ "Topic :: Scientific/Engineering :: Artificial Intelligence",
28
+ "Topic :: Software Development :: Libraries :: Python Modules",
29
+ "Typing :: Typed",
30
+ ]
31
+ dependencies = [
32
+ "requests>=2.28.0",
33
+ ]
34
+
35
+ [project.urls]
36
+ Homepage = "https://bios.us.com"
37
+ Documentation = "https://bios.us.com/docs"
38
+
39
+ [tool.hatch.build.targets.wheel]
40
+ packages = ["src/usfbios"]