syfthub-sdk 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.
Files changed (33) hide show
  1. syfthub_sdk-0.1.0/.gitignore +197 -0
  2. syfthub_sdk-0.1.0/CHANGELOG.md +43 -0
  3. syfthub_sdk-0.1.0/PKG-INFO +233 -0
  4. syfthub_sdk-0.1.0/README.md +206 -0
  5. syfthub_sdk-0.1.0/examples/demo_workflow.py +440 -0
  6. syfthub_sdk-0.1.0/examples/simple_example.py +79 -0
  7. syfthub_sdk-0.1.0/pyproject.toml +68 -0
  8. syfthub_sdk-0.1.0/src/syfthub_sdk/__init__.py +152 -0
  9. syfthub_sdk-0.1.0/src/syfthub_sdk/_http.py +327 -0
  10. syfthub_sdk-0.1.0/src/syfthub_sdk/_pagination.py +133 -0
  11. syfthub_sdk-0.1.0/src/syfthub_sdk/accounting.py +611 -0
  12. syfthub_sdk-0.1.0/src/syfthub_sdk/auth.py +371 -0
  13. syfthub_sdk-0.1.0/src/syfthub_sdk/chat.py +811 -0
  14. syfthub_sdk-0.1.0/src/syfthub_sdk/client.py +311 -0
  15. syfthub_sdk-0.1.0/src/syfthub_sdk/exceptions.py +255 -0
  16. syfthub_sdk-0.1.0/src/syfthub_sdk/hub.py +239 -0
  17. syfthub_sdk-0.1.0/src/syfthub_sdk/models.py +424 -0
  18. syfthub_sdk-0.1.0/src/syfthub_sdk/my_endpoints.py +330 -0
  19. syfthub_sdk-0.1.0/src/syfthub_sdk/py.typed +0 -0
  20. syfthub_sdk-0.1.0/src/syfthub_sdk/syftai.py +389 -0
  21. syfthub_sdk-0.1.0/src/syfthub_sdk/users.py +138 -0
  22. syfthub_sdk-0.1.0/tests/__init__.py +0 -0
  23. syfthub_sdk-0.1.0/tests/conftest.py +32 -0
  24. syfthub_sdk-0.1.0/tests/integration/__init__.py +1 -0
  25. syfthub_sdk-0.1.0/tests/integration/conftest.py +180 -0
  26. syfthub_sdk-0.1.0/tests/integration/test_auth.py +281 -0
  27. syfthub_sdk-0.1.0/tests/integration/test_hub.py +307 -0
  28. syfthub_sdk-0.1.0/tests/integration/test_my_endpoints.py +438 -0
  29. syfthub_sdk-0.1.0/tests/integration/test_users.py +153 -0
  30. syfthub_sdk-0.1.0/tests/unit/__init__.py +1 -0
  31. syfthub_sdk-0.1.0/tests/unit/test_chat.py +525 -0
  32. syfthub_sdk-0.1.0/tests/unit/test_syftai.py +448 -0
  33. syfthub_sdk-0.1.0/uv.lock +674 -0
@@ -0,0 +1,197 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Distribution / packaging
10
+ .Python
11
+ build/
12
+ develop-eggs/
13
+ dist/
14
+ downloads/
15
+ eggs/
16
+ .eggs/
17
+ # Python lib directories (but not frontend/src/lib/)
18
+ /lib/
19
+ lib64/
20
+ !frontend/src/lib/
21
+ parts/
22
+ sdist/
23
+ var/
24
+ wheels/
25
+ share/python-wheels/
26
+ *.egg-info/
27
+ .installed.cfg
28
+ *.egg
29
+ MANIFEST
30
+
31
+ # PyInstaller
32
+ *.manifest
33
+ *.spec
34
+
35
+ # Installer logs
36
+ pip-log.txt
37
+ pip-delete-this-directory.txt
38
+
39
+ # Unit test / coverage reports
40
+ htmlcov/
41
+ .tox/
42
+ .nox/
43
+ .coverage
44
+ .coverage.*
45
+ .cache
46
+ nosetests.xml
47
+ coverage.xml
48
+ *.cover
49
+ *.py,cover
50
+ .hypothesis/
51
+ .pytest_cache/
52
+ cover/
53
+
54
+ # Translations
55
+ *.mo
56
+ *.pot
57
+
58
+ # Django stuff:
59
+ *.log
60
+ local_settings.py
61
+ db.sqlite3
62
+ db.sqlite3-journal
63
+
64
+ # Flask stuff:
65
+ instance/
66
+ .webassets-cache
67
+
68
+ # Scrapy stuff:
69
+ .scrapy
70
+
71
+ # Sphinx documentation
72
+ docs/_build/
73
+
74
+ # PyBuilder
75
+ .pybuilder/
76
+ target/
77
+
78
+ # Jupyter Notebook
79
+ .ipynb_checkpoints
80
+
81
+ # IPython
82
+ profile_default/
83
+ ipython_config.py
84
+
85
+ # pyenv
86
+ .python-version
87
+
88
+ # pipenv
89
+ Pipfile.lock
90
+
91
+ # poetry
92
+ poetry.lock
93
+
94
+ # pdm
95
+ .pdm.toml
96
+ .pdm-python
97
+ .pdm-build/
98
+
99
+ # PEP 582
100
+ __pypackages__/
101
+
102
+ # Celery stuff
103
+ celerybeat-schedule
104
+ celerybeat.pid
105
+
106
+ # SageMath parsed files
107
+ *.sage.py
108
+
109
+ # Environments
110
+ .env
111
+ .venv
112
+ env/
113
+ venv/
114
+ ENV/
115
+ env.bak/
116
+ venv.bak/
117
+
118
+ # Spyder project settings
119
+ .spyderproject
120
+ .spyproject
121
+
122
+ # Rope project settings
123
+ .ropeproject
124
+
125
+ # mkdocs documentation
126
+ /site
127
+
128
+ # mypy
129
+ .mypy_cache/
130
+ .dmypy.json
131
+ dmypy.json
132
+
133
+ # Pyre type checker
134
+ .pyre/
135
+
136
+ # pytype static type analyzer
137
+ .pytype/
138
+
139
+ # Cython debug symbols
140
+ cython_debug/
141
+
142
+ # PyCharm
143
+ .idea/
144
+
145
+ # VS Code
146
+ .vscode/
147
+
148
+ # macOS
149
+ .DS_Store
150
+
151
+ # Windows
152
+ Thumbs.db
153
+ ehthumbs.db
154
+
155
+ # uv
156
+ backend/uv.lock
157
+
158
+ # ruff
159
+ .ruff_cache/
160
+
161
+ # Local data directory
162
+ data/
163
+ backend/data/
164
+
165
+ # RSA keys (auto-generated for multi-worker support)
166
+ # These should NEVER be committed to version control
167
+ **/rsa_keys/
168
+ *.pem
169
+
170
+ # Backend-specific ignores
171
+ backend/.coverage
172
+ backend/coverage.xml
173
+ backend/htmlcov/
174
+ backend/.pytest_cache/
175
+ backend/.mypy_cache/
176
+ backend/.ruff_cache/
177
+ backend/.venv/
178
+ backend/.env
179
+ backend/*.db
180
+ backend/syfthub.db
181
+
182
+ # Frontend
183
+ frontend/node_modules/
184
+ frontend/dist/
185
+ frontend/build/
186
+ frontend/.env*.local
187
+ frontend/.vite/
188
+ frontend/playwright-report/
189
+ frontend/test-results/
190
+ frontend/coverage/
191
+ frontend/.nyc_output/
192
+ frontend/.eslintcache
193
+ frontend/.next/
194
+ frontend/.nuxt/
195
+ frontend/out/
196
+ frontend/storybook-static/
197
+ frontend/tsconfig.tsbuildinfo
@@ -0,0 +1,43 @@
1
+ # Changelog
2
+
3
+ All notable changes to the SyftHub Python SDK will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+
10
+ ## [0.1.0] - Unreleased
11
+
12
+ ### Added
13
+
14
+ - Initial release of the SyftHub Python SDK
15
+ - `SyftHubClient` class for API interactions
16
+ - Authentication via API key
17
+ - Resource APIs:
18
+ - `auth` - Authentication and token management
19
+ - `users` - User management and profiles
20
+ - `hub` - Endpoint discovery and search
21
+ - `chat` - Chat completions API
22
+ - `accounting` - Usage tracking and billing information
23
+ - `my_endpoints` - Manage user's own endpoints
24
+ - `syftai` - SyftAI-specific features
25
+ - Automatic pagination handling with async iterator support
26
+ - Comprehensive error handling with typed exceptions:
27
+ - `SyftHubError` - Base exception class
28
+ - `AuthenticationError` - Authentication failures
29
+ - `RateLimitError` - Rate limit exceeded
30
+ - `NotFoundError` - Resource not found
31
+ - `ValidationError` - Request validation failures
32
+ - Full type hints for IDE support and type checking
33
+ - Async HTTP client built on `httpx`
34
+ - Pydantic models for request/response validation
35
+
36
+ ### Dependencies
37
+
38
+ - Python 3.10+
39
+ - httpx >= 0.27
40
+ - pydantic >= 2.0
41
+
42
+ [Unreleased]: https://github.com/OpenMined/syfthub/compare/python-sdk/v0.1.0...HEAD
43
+ [0.1.0]: https://github.com/OpenMined/syfthub/releases/tag/python-sdk/v0.1.0
@@ -0,0 +1,233 @@
1
+ Metadata-Version: 2.4
2
+ Name: syfthub-sdk
3
+ Version: 0.1.0
4
+ Summary: Python SDK for interacting with SyftHub API
5
+ Author: SyftHub Team
6
+ License: Apache-2.0
7
+ Keywords: api,client,sdk,syfthub
8
+ Classifier: Development Status :: 3 - Alpha
9
+ Classifier: Intended Audience :: Developers
10
+ Classifier: License :: OSI Approved :: Apache Software License
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Programming Language :: Python :: 3.10
13
+ Classifier: Programming Language :: Python :: 3.11
14
+ Classifier: Programming Language :: Python :: 3.12
15
+ Classifier: Typing :: Typed
16
+ Requires-Python: >=3.10
17
+ Requires-Dist: httpx>=0.27
18
+ Requires-Dist: pydantic>=2.0
19
+ Requires-Dist: typing-extensions>=4.0; python_version < '3.11'
20
+ Provides-Extra: dev
21
+ Requires-Dist: mypy>=1.13; extra == 'dev'
22
+ Requires-Dist: pytest-cov>=4.0; extra == 'dev'
23
+ Requires-Dist: pytest>=8.0; extra == 'dev'
24
+ Requires-Dist: respx>=0.21; extra == 'dev'
25
+ Requires-Dist: ruff>=0.8; extra == 'dev'
26
+ Description-Content-Type: text/markdown
27
+
28
+ # SyftHub SDK
29
+
30
+ Python SDK for interacting with the SyftHub API programmatically.
31
+
32
+ ## Installation
33
+
34
+ ```bash
35
+ # Using pip
36
+ pip install syfthub-sdk
37
+
38
+ # Using uv
39
+ uv add syfthub-sdk
40
+
41
+ # From source
42
+ cd sdk
43
+ uv sync
44
+ ```
45
+
46
+ ## Quick Start
47
+
48
+ ```python
49
+ from syfthub_sdk import SyftHubClient
50
+
51
+ # Initialize client
52
+ client = SyftHubClient(base_url="https://hub.syft.com")
53
+
54
+ # Register a new user
55
+ user = client.auth.register(
56
+ username="john",
57
+ email="john@example.com",
58
+ password="secret123",
59
+ full_name="John Doe"
60
+ )
61
+
62
+ # Login
63
+ user = client.auth.login(username="john", password="secret123")
64
+ print(f"Logged in as {user.username}")
65
+
66
+ # Get current user
67
+ me = client.auth.me()
68
+ ```
69
+
70
+ ## Managing Your Endpoints
71
+
72
+ ```python
73
+ # List your endpoints (with lazy pagination)
74
+ for endpoint in client.my_endpoints.list():
75
+ print(f"{endpoint.name} ({endpoint.visibility})")
76
+
77
+ # Get just the first page
78
+ first_page = client.my_endpoints.list().first_page()
79
+
80
+ # Create an endpoint
81
+ endpoint = client.my_endpoints.create(
82
+ name="My Cool API",
83
+ visibility="public",
84
+ description="A really cool API",
85
+ readme="# My API\n\nThis is my API documentation."
86
+ )
87
+ print(f"Created: {endpoint.slug}")
88
+
89
+ # Update an endpoint
90
+ endpoint = client.my_endpoints.update(
91
+ endpoint_id=endpoint.id,
92
+ description="Updated description"
93
+ )
94
+
95
+ # Delete an endpoint
96
+ client.my_endpoints.delete(endpoint_id=endpoint.id)
97
+ ```
98
+
99
+ ## Browsing the Hub
100
+
101
+ ```python
102
+ # Browse public endpoints
103
+ for endpoint in client.hub.browse():
104
+ print(f"{endpoint.path}: {endpoint.name}")
105
+
106
+ # Get trending endpoints
107
+ for endpoint in client.hub.trending(min_stars=10):
108
+ print(f"{endpoint.name} - {endpoint.stars_count} stars")
109
+
110
+ # Get a specific endpoint by path
111
+ endpoint = client.hub.get("alice/cool-api")
112
+ print(endpoint.readme)
113
+
114
+ # Star/unstar endpoints (requires auth)
115
+ client.hub.star("alice/cool-api")
116
+ client.hub.unstar("alice/cool-api")
117
+
118
+ # Check if you've starred an endpoint
119
+ if client.hub.is_starred("alice/cool-api"):
120
+ print("You've starred this!")
121
+ ```
122
+
123
+ ## User Profile
124
+
125
+ ```python
126
+ # Update profile
127
+ user = client.users.update(
128
+ full_name="John D.",
129
+ avatar_url="https://example.com/avatar.png"
130
+ )
131
+
132
+ # Check username availability
133
+ if client.users.check_username("newusername"):
134
+ print("Username is available!")
135
+
136
+ # Change password
137
+ client.auth.change_password(
138
+ current_password="old123",
139
+ new_password="new456"
140
+ )
141
+ ```
142
+
143
+ ## Accounting
144
+
145
+ ```python
146
+ # Get account balance
147
+ balance = client.accounting.balance()
148
+ print(f"Credits: {balance.credits} {balance.currency}")
149
+
150
+ # List transactions
151
+ for tx in client.accounting.transactions():
152
+ print(f"{tx.created_at}: {tx.amount} - {tx.description}")
153
+ ```
154
+
155
+ ## Token Persistence
156
+
157
+ ```python
158
+ # Get tokens for saving
159
+ tokens = client.get_tokens()
160
+ if tokens:
161
+ # Save to file, database, etc.
162
+ save_tokens(tokens.access_token, tokens.refresh_token)
163
+
164
+ # Later, restore session
165
+ from syfthub_sdk import AuthTokens
166
+
167
+ tokens = AuthTokens(
168
+ access_token=load_access_token(),
169
+ refresh_token=load_refresh_token()
170
+ )
171
+ client.set_tokens(tokens)
172
+ ```
173
+
174
+ ## Environment Variables
175
+
176
+ | Variable | Description |
177
+ |----------|-------------|
178
+ | `SYFTHUB_URL` | SyftHub API base URL |
179
+ | `SYFTHUB_ACCOUNTING_URL` | Accounting service URL |
180
+ | `SYFTHUB_ACCOUNTING_EMAIL` | Accounting auth email |
181
+ | `SYFTHUB_ACCOUNTING_PASSWORD` | Accounting auth password |
182
+
183
+ ## Error Handling
184
+
185
+ ```python
186
+ from syfthub_sdk import (
187
+ SyftHubError,
188
+ AuthenticationError,
189
+ AuthorizationError,
190
+ NotFoundError,
191
+ ValidationError,
192
+ ConfigurationError,
193
+ )
194
+
195
+ try:
196
+ client.auth.login(username="john", password="wrong")
197
+ except AuthenticationError as e:
198
+ print(f"Login failed: {e}")
199
+ except SyftHubError as e:
200
+ print(f"API error [{e.status_code}]: {e.message}")
201
+ ```
202
+
203
+ ## Context Manager
204
+
205
+ ```python
206
+ with SyftHubClient(base_url="https://hub.syft.com") as client:
207
+ client.auth.login(username="john", password="secret123")
208
+ # ... do work ...
209
+ # Client is automatically closed
210
+ ```
211
+
212
+ ## Pagination
213
+
214
+ All list methods return a `PageIterator` for lazy pagination:
215
+
216
+ ```python
217
+ # Iterate through all items (fetches pages as needed)
218
+ for endpoint in client.my_endpoints.list():
219
+ print(endpoint.name)
220
+
221
+ # Get just the first page
222
+ first_page = client.my_endpoints.list().first_page()
223
+
224
+ # Get all items as a list
225
+ all_items = client.my_endpoints.list().all()
226
+
227
+ # Get first N items
228
+ top_10 = client.my_endpoints.list().take(10)
229
+ ```
230
+
231
+ ## License
232
+
233
+ MIT
@@ -0,0 +1,206 @@
1
+ # SyftHub SDK
2
+
3
+ Python SDK for interacting with the SyftHub API programmatically.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ # Using pip
9
+ pip install syfthub-sdk
10
+
11
+ # Using uv
12
+ uv add syfthub-sdk
13
+
14
+ # From source
15
+ cd sdk
16
+ uv sync
17
+ ```
18
+
19
+ ## Quick Start
20
+
21
+ ```python
22
+ from syfthub_sdk import SyftHubClient
23
+
24
+ # Initialize client
25
+ client = SyftHubClient(base_url="https://hub.syft.com")
26
+
27
+ # Register a new user
28
+ user = client.auth.register(
29
+ username="john",
30
+ email="john@example.com",
31
+ password="secret123",
32
+ full_name="John Doe"
33
+ )
34
+
35
+ # Login
36
+ user = client.auth.login(username="john", password="secret123")
37
+ print(f"Logged in as {user.username}")
38
+
39
+ # Get current user
40
+ me = client.auth.me()
41
+ ```
42
+
43
+ ## Managing Your Endpoints
44
+
45
+ ```python
46
+ # List your endpoints (with lazy pagination)
47
+ for endpoint in client.my_endpoints.list():
48
+ print(f"{endpoint.name} ({endpoint.visibility})")
49
+
50
+ # Get just the first page
51
+ first_page = client.my_endpoints.list().first_page()
52
+
53
+ # Create an endpoint
54
+ endpoint = client.my_endpoints.create(
55
+ name="My Cool API",
56
+ visibility="public",
57
+ description="A really cool API",
58
+ readme="# My API\n\nThis is my API documentation."
59
+ )
60
+ print(f"Created: {endpoint.slug}")
61
+
62
+ # Update an endpoint
63
+ endpoint = client.my_endpoints.update(
64
+ endpoint_id=endpoint.id,
65
+ description="Updated description"
66
+ )
67
+
68
+ # Delete an endpoint
69
+ client.my_endpoints.delete(endpoint_id=endpoint.id)
70
+ ```
71
+
72
+ ## Browsing the Hub
73
+
74
+ ```python
75
+ # Browse public endpoints
76
+ for endpoint in client.hub.browse():
77
+ print(f"{endpoint.path}: {endpoint.name}")
78
+
79
+ # Get trending endpoints
80
+ for endpoint in client.hub.trending(min_stars=10):
81
+ print(f"{endpoint.name} - {endpoint.stars_count} stars")
82
+
83
+ # Get a specific endpoint by path
84
+ endpoint = client.hub.get("alice/cool-api")
85
+ print(endpoint.readme)
86
+
87
+ # Star/unstar endpoints (requires auth)
88
+ client.hub.star("alice/cool-api")
89
+ client.hub.unstar("alice/cool-api")
90
+
91
+ # Check if you've starred an endpoint
92
+ if client.hub.is_starred("alice/cool-api"):
93
+ print("You've starred this!")
94
+ ```
95
+
96
+ ## User Profile
97
+
98
+ ```python
99
+ # Update profile
100
+ user = client.users.update(
101
+ full_name="John D.",
102
+ avatar_url="https://example.com/avatar.png"
103
+ )
104
+
105
+ # Check username availability
106
+ if client.users.check_username("newusername"):
107
+ print("Username is available!")
108
+
109
+ # Change password
110
+ client.auth.change_password(
111
+ current_password="old123",
112
+ new_password="new456"
113
+ )
114
+ ```
115
+
116
+ ## Accounting
117
+
118
+ ```python
119
+ # Get account balance
120
+ balance = client.accounting.balance()
121
+ print(f"Credits: {balance.credits} {balance.currency}")
122
+
123
+ # List transactions
124
+ for tx in client.accounting.transactions():
125
+ print(f"{tx.created_at}: {tx.amount} - {tx.description}")
126
+ ```
127
+
128
+ ## Token Persistence
129
+
130
+ ```python
131
+ # Get tokens for saving
132
+ tokens = client.get_tokens()
133
+ if tokens:
134
+ # Save to file, database, etc.
135
+ save_tokens(tokens.access_token, tokens.refresh_token)
136
+
137
+ # Later, restore session
138
+ from syfthub_sdk import AuthTokens
139
+
140
+ tokens = AuthTokens(
141
+ access_token=load_access_token(),
142
+ refresh_token=load_refresh_token()
143
+ )
144
+ client.set_tokens(tokens)
145
+ ```
146
+
147
+ ## Environment Variables
148
+
149
+ | Variable | Description |
150
+ |----------|-------------|
151
+ | `SYFTHUB_URL` | SyftHub API base URL |
152
+ | `SYFTHUB_ACCOUNTING_URL` | Accounting service URL |
153
+ | `SYFTHUB_ACCOUNTING_EMAIL` | Accounting auth email |
154
+ | `SYFTHUB_ACCOUNTING_PASSWORD` | Accounting auth password |
155
+
156
+ ## Error Handling
157
+
158
+ ```python
159
+ from syfthub_sdk import (
160
+ SyftHubError,
161
+ AuthenticationError,
162
+ AuthorizationError,
163
+ NotFoundError,
164
+ ValidationError,
165
+ ConfigurationError,
166
+ )
167
+
168
+ try:
169
+ client.auth.login(username="john", password="wrong")
170
+ except AuthenticationError as e:
171
+ print(f"Login failed: {e}")
172
+ except SyftHubError as e:
173
+ print(f"API error [{e.status_code}]: {e.message}")
174
+ ```
175
+
176
+ ## Context Manager
177
+
178
+ ```python
179
+ with SyftHubClient(base_url="https://hub.syft.com") as client:
180
+ client.auth.login(username="john", password="secret123")
181
+ # ... do work ...
182
+ # Client is automatically closed
183
+ ```
184
+
185
+ ## Pagination
186
+
187
+ All list methods return a `PageIterator` for lazy pagination:
188
+
189
+ ```python
190
+ # Iterate through all items (fetches pages as needed)
191
+ for endpoint in client.my_endpoints.list():
192
+ print(endpoint.name)
193
+
194
+ # Get just the first page
195
+ first_page = client.my_endpoints.list().first_page()
196
+
197
+ # Get all items as a list
198
+ all_items = client.my_endpoints.list().all()
199
+
200
+ # Get first N items
201
+ top_10 = client.my_endpoints.list().take(10)
202
+ ```
203
+
204
+ ## License
205
+
206
+ MIT