cloudflare-saas 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,338 @@
1
+ Metadata-Version: 2.4
2
+ Name: cloudflare-saas
3
+ Version: 1.0.0
4
+ Summary: Production-ready async library for multi-tenant SaaS platforms with Cloudflare R2 and Workers
5
+ Home-page: https://github.com/innerkorehq/cloudflare-saas
6
+ Author: innerkore
7
+ Classifier: Development Status :: 4 - Beta
8
+ Classifier: Intended Audience :: Developers
9
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
10
+ Classifier: License :: OSI Approved :: MIT License
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Programming Language :: Python :: 3.8
13
+ Classifier: Programming Language :: Python :: 3.9
14
+ Classifier: Programming Language :: Python :: 3.10
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Requires-Python: >=3.8
18
+ Description-Content-Type: text/markdown
19
+ Requires-Dist: cloudflare>=4.0.0
20
+ Requires-Dist: aioboto3>=12.0.0
21
+ Requires-Dist: aiodns>=3.1.0
22
+ Requires-Dist: pydantic>=2.0.0
23
+ Requires-Dist: python-terraform>=0.10.1
24
+ Requires-Dist: httpx>=0.25.0
25
+ Requires-Dist: tenacity>=8.2.0
26
+ Requires-Dist: asyncpg>=0.29.0
27
+ Requires-Dist: pycares>=4.3.0
28
+ Requires-Dist: botocore>=1.31.0
29
+ Provides-Extra: dev
30
+ Requires-Dist: pytest>=7.4.0; extra == "dev"
31
+ Requires-Dist: pytest-asyncio>=0.21.0; extra == "dev"
32
+ Requires-Dist: pytest-cov>=4.1.0; extra == "dev"
33
+ Requires-Dist: black>=23.0.0; extra == "dev"
34
+ Requires-Dist: mypy>=1.5.0; extra == "dev"
35
+ Requires-Dist: ruff>=0.1.0; extra == "dev"
36
+ Provides-Extra: web
37
+ Requires-Dist: fastapi>=0.104.0; extra == "web"
38
+ Requires-Dist: uvicorn[standard]>=0.24.0; extra == "web"
39
+ Dynamic: author
40
+ Dynamic: classifier
41
+ Dynamic: description
42
+ Dynamic: description-content-type
43
+ Dynamic: home-page
44
+ Dynamic: provides-extra
45
+ Dynamic: requires-dist
46
+ Dynamic: requires-python
47
+ Dynamic: summary
48
+
49
+ # Cloudflare R2 SaaS Platform Library
50
+
51
+ A production-ready Python async library for building multi-tenant SaaS platforms with Cloudflare R2, Workers, and Custom Hostnames.
52
+
53
+ [![Documentation Status](https://readthedocs.org/projects/cloudflare-saas/badge/?version=latest)](https://cloudflare-saas.readthedocs.io/en/latest/?badge=latest)
54
+
55
+ ## Features
56
+
57
+ - ✅ Async R2 bucket operations (upload, delete, list)
58
+ - ✅ Tenant management with namespace isolation
59
+ - ✅ Custom domain onboarding with DNS verification
60
+ - ✅ Cloudflare for SaaS custom hostname provisioning
61
+ - ✅ Worker deployment automation via Terraform
62
+ - ✅ **Configurable logging system** (DEBUG, INFO, WARNING, ERROR, CRITICAL)
63
+ - ✅ **Multiple log formats** (simple, detailed, JSON)
64
+ - ✅ Full error handling and retry logic
65
+ - ✅ Type-safe with Pydantic models
66
+ - ✅ Comprehensive documentation
67
+
68
+ ## Installation
69
+
70
+ ```bash
71
+ pip install cloudflare aiodns aioboto3 pydantic python-terraform httpx tenacity
72
+ ```
73
+
74
+ For PostgreSQL storage:
75
+
76
+ ```bash
77
+ pip install asyncpg
78
+ ```
79
+
80
+ For development:
81
+
82
+ ```bash
83
+ pip install -e ".[dev,web]"
84
+ ```
85
+
86
+ ## Quick Start
87
+
88
+ ### Basic Usage with Logging
89
+
90
+ ```python
91
+ import asyncio
92
+ from cloudflare_saas import (
93
+ CloudflareSaaSPlatform,
94
+ Config,
95
+ configure_logging,
96
+ LogLevel
97
+ )
98
+
99
+ async def main():
100
+ # Configure logging
101
+ configure_logging(level=LogLevel.INFO)
102
+
103
+ # Load config from environment
104
+ config = Config.from_env()
105
+
106
+ # Initialize platform
107
+ platform = CloudflareSaaSPlatform(config)
108
+
109
+ # Create tenant
110
+ tenant = await platform.create_tenant("Acme Inc", "acme-123")
111
+
112
+ # Deploy site
113
+ await platform.deploy_tenant_site(
114
+ tenant.tenant_id,
115
+ local_path="./acme-site"
116
+ )
117
+
118
+ # Add custom domain
119
+ domain_status = await platform.add_custom_domain(
120
+ tenant.tenant_id,
121
+ "www.acme.com"
122
+ )
123
+
124
+ asyncio.run(main())
125
+ ```
126
+
127
+ ## Configuration
128
+
129
+ ### Environment Variables
130
+
131
+ Required:
132
+ - `CLOUDFLARE_API_TOKEN`
133
+ - `CLOUDFLARE_ACCOUNT_ID`
134
+ - `CLOUDFLARE_ZONE_ID`
135
+ - `R2_ACCESS_KEY_ID`
136
+ - `R2_SECRET_ACCESS_KEY`
137
+ - `R2_BUCKET_NAME`
138
+ - `PLATFORM_DOMAIN`
139
+
140
+ Optional - Logging:
141
+ - `LOG_LEVEL` (default: INFO) - DEBUG, INFO, WARNING, ERROR, CRITICAL
142
+ - `LOG_FORMAT` (default: detailed) - simple, detailed, json
143
+ - `LOG_FILE` - Path to log file (optional)
144
+ - `ENABLE_CONSOLE_LOGGING` (default: true) - Enable console output
145
+
146
+ ### Programmatic Configuration
147
+
148
+ ```python
149
+ from cloudflare_saas import Config
150
+
151
+ config = Config(
152
+ cloudflare_api_token="your-token",
153
+ cloudflare_account_id="your-account",
154
+ cloudflare_zone_id="your-zone",
155
+ r2_access_key_id="your-r2-key",
156
+ r2_secret_access_key="your-r2-secret",
157
+ r2_bucket_name="yourplatform-sites",
158
+ platform_domain="yourplatform.com",
159
+ log_level="DEBUG",
160
+ log_format="json",
161
+ log_file="app.log"
162
+ )
163
+ ```
164
+
165
+ ## Logging
166
+
167
+ ### Configure Logging
168
+
169
+ ```python
170
+ from cloudflare_saas import configure_logging, LogLevel, LogFormat
171
+
172
+ # Simple console logging
173
+ configure_logging(level=LogLevel.INFO)
174
+
175
+ # Detailed file logging
176
+ configure_logging(
177
+ level=LogLevel.DEBUG,
178
+ log_format=LogFormat.DETAILED,
179
+ log_file="cloudflare-saas.log"
180
+ )
181
+
182
+ # JSON logging for production
183
+ configure_logging(
184
+ level=LogLevel.WARNING,
185
+ log_format=LogFormat.JSON,
186
+ log_file="/var/log/cloudflare-saas.log",
187
+ enable_console=False
188
+ )
189
+ ```
190
+
191
+ ### Log Levels
192
+
193
+ - **DEBUG**: Detailed diagnostic information
194
+ - **INFO**: General informational messages
195
+ - **WARNING**: Warning messages
196
+ - **ERROR**: Error messages
197
+ - **CRITICAL**: Critical errors
198
+
199
+ ### Log Formats
200
+
201
+ - **simple**: Minimal output `INFO: message`
202
+ - **detailed**: With timestamps and source `2025-12-17 10:30:45 - Module - INFO - [file.py:65] - message`
203
+ - **json**: Structured JSON for log aggregation
204
+
205
+ ### Using Loggers in Your Code
206
+
207
+ ```python
208
+ from cloudflare_saas import get_logger, LoggerMixin
209
+
210
+ # Get a logger
211
+ logger = get_logger(__name__)
212
+ logger.info("Starting operation")
213
+
214
+ # Use in a class
215
+ class MyService(LoggerMixin):
216
+ def do_work(self):
217
+ self.logger.info("Working...")
218
+ ```
219
+
220
+ ## Documentation
221
+
222
+ Comprehensive documentation is available at [Read the Docs](https://cloudflare-saas.readthedocs.io/).
223
+
224
+ ### Build Documentation Locally
225
+
226
+ ```bash
227
+ # Install documentation dependencies
228
+ make install-docs
229
+
230
+ # Build HTML documentation
231
+ make docs
232
+
233
+ # Serve documentation locally
234
+ make docs-serve
235
+ ```
236
+
237
+ Documentation includes:
238
+
239
+ - **Getting Started Guide**: Quick start and installation
240
+ - **Configuration Guide**: All configuration options
241
+ - **Logging Guide**: Comprehensive logging documentation
242
+ - **API Reference**: Complete API documentation
243
+ - **Examples**: Practical code examples
244
+ - **Deployment Guide**: Production deployment
245
+ - **Contributing Guide**: Development guidelines
246
+
247
+ ## Development
248
+
249
+ ### Available Make Commands
250
+
251
+ ```bash
252
+ make help # Show all available commands
253
+
254
+ # Development
255
+ make install # Install package
256
+ make install-dev # Install with dev dependencies
257
+ make install-docs # Install documentation dependencies
258
+
259
+ # Testing
260
+ make test # Run tests
261
+ make test-cov # Run tests with coverage
262
+ make test-watch # Run tests in watch mode
263
+
264
+ # Code Quality
265
+ make lint # Run linters (ruff, mypy)
266
+ make format # Format code (black, ruff)
267
+ make check # Run all checks (lint + test)
268
+
269
+ # Documentation
270
+ make docs # Build documentation
271
+ make docs-serve # Build and serve documentation
272
+ make docs-clean # Clean documentation build
273
+
274
+ # Docker
275
+ make docker-build # Build Docker image
276
+ make docker-run # Run Docker container
277
+ make docker-stop # Stop Docker containers
278
+
279
+ # API
280
+ make run-api # Run FastAPI development server
281
+
282
+ # Utilities
283
+ make clean # Clean build artifacts
284
+ make clean-all # Clean all generated files
285
+ ```
286
+
287
+ ### Running Tests
288
+
289
+ ```bash
290
+ # Run all tests
291
+ make test
292
+
293
+ # Run with coverage
294
+ make test-cov
295
+
296
+ # Run specific test
297
+ pytest tests/test_platform.py::test_create_tenant -v
298
+ ```
299
+
300
+ ### Code Quality
301
+
302
+ ```bash
303
+ # Format code
304
+ make format
305
+
306
+ # Check linting
307
+ make lint
308
+
309
+ # Run all checks
310
+ make check
311
+ ```
312
+
313
+ ## Architecture
314
+
315
+ See [cloudflare_r2_plan.md](./cloudflare_r2_plan.md) for detailed architecture.
316
+
317
+ ## Contributing
318
+
319
+ We welcome contributions! Please see [CONTRIBUTING.md](./docs/source/contributing.rst) for guidelines.
320
+
321
+ ### Development Setup
322
+
323
+ 1. Fork and clone the repository
324
+ 2. Install development dependencies: `make install-dev`
325
+ 3. Create a branch for your feature
326
+ 4. Make your changes with tests
327
+ 5. Run tests and linting: `make check`
328
+ 6. Submit a pull request
329
+
330
+ ## License
331
+
332
+ [Add your license here]
333
+
334
+ ## Support
335
+
336
+ - **Documentation**: https://cloudflare-saas.readthedocs.io/
337
+ - **Issues**: https://github.com/yourusername/cloudflare-saas/issues
338
+ - **Discussions**: https://github.com/yourusername/cloudflare-saas/discussions
@@ -0,0 +1,290 @@
1
+ # Cloudflare R2 SaaS Platform Library
2
+
3
+ A production-ready Python async library for building multi-tenant SaaS platforms with Cloudflare R2, Workers, and Custom Hostnames.
4
+
5
+ [![Documentation Status](https://readthedocs.org/projects/cloudflare-saas/badge/?version=latest)](https://cloudflare-saas.readthedocs.io/en/latest/?badge=latest)
6
+
7
+ ## Features
8
+
9
+ - ✅ Async R2 bucket operations (upload, delete, list)
10
+ - ✅ Tenant management with namespace isolation
11
+ - ✅ Custom domain onboarding with DNS verification
12
+ - ✅ Cloudflare for SaaS custom hostname provisioning
13
+ - ✅ Worker deployment automation via Terraform
14
+ - ✅ **Configurable logging system** (DEBUG, INFO, WARNING, ERROR, CRITICAL)
15
+ - ✅ **Multiple log formats** (simple, detailed, JSON)
16
+ - ✅ Full error handling and retry logic
17
+ - ✅ Type-safe with Pydantic models
18
+ - ✅ Comprehensive documentation
19
+
20
+ ## Installation
21
+
22
+ ```bash
23
+ pip install cloudflare aiodns aioboto3 pydantic python-terraform httpx tenacity
24
+ ```
25
+
26
+ For PostgreSQL storage:
27
+
28
+ ```bash
29
+ pip install asyncpg
30
+ ```
31
+
32
+ For development:
33
+
34
+ ```bash
35
+ pip install -e ".[dev,web]"
36
+ ```
37
+
38
+ ## Quick Start
39
+
40
+ ### Basic Usage with Logging
41
+
42
+ ```python
43
+ import asyncio
44
+ from cloudflare_saas import (
45
+ CloudflareSaaSPlatform,
46
+ Config,
47
+ configure_logging,
48
+ LogLevel
49
+ )
50
+
51
+ async def main():
52
+ # Configure logging
53
+ configure_logging(level=LogLevel.INFO)
54
+
55
+ # Load config from environment
56
+ config = Config.from_env()
57
+
58
+ # Initialize platform
59
+ platform = CloudflareSaaSPlatform(config)
60
+
61
+ # Create tenant
62
+ tenant = await platform.create_tenant("Acme Inc", "acme-123")
63
+
64
+ # Deploy site
65
+ await platform.deploy_tenant_site(
66
+ tenant.tenant_id,
67
+ local_path="./acme-site"
68
+ )
69
+
70
+ # Add custom domain
71
+ domain_status = await platform.add_custom_domain(
72
+ tenant.tenant_id,
73
+ "www.acme.com"
74
+ )
75
+
76
+ asyncio.run(main())
77
+ ```
78
+
79
+ ## Configuration
80
+
81
+ ### Environment Variables
82
+
83
+ Required:
84
+ - `CLOUDFLARE_API_TOKEN`
85
+ - `CLOUDFLARE_ACCOUNT_ID`
86
+ - `CLOUDFLARE_ZONE_ID`
87
+ - `R2_ACCESS_KEY_ID`
88
+ - `R2_SECRET_ACCESS_KEY`
89
+ - `R2_BUCKET_NAME`
90
+ - `PLATFORM_DOMAIN`
91
+
92
+ Optional - Logging:
93
+ - `LOG_LEVEL` (default: INFO) - DEBUG, INFO, WARNING, ERROR, CRITICAL
94
+ - `LOG_FORMAT` (default: detailed) - simple, detailed, json
95
+ - `LOG_FILE` - Path to log file (optional)
96
+ - `ENABLE_CONSOLE_LOGGING` (default: true) - Enable console output
97
+
98
+ ### Programmatic Configuration
99
+
100
+ ```python
101
+ from cloudflare_saas import Config
102
+
103
+ config = Config(
104
+ cloudflare_api_token="your-token",
105
+ cloudflare_account_id="your-account",
106
+ cloudflare_zone_id="your-zone",
107
+ r2_access_key_id="your-r2-key",
108
+ r2_secret_access_key="your-r2-secret",
109
+ r2_bucket_name="yourplatform-sites",
110
+ platform_domain="yourplatform.com",
111
+ log_level="DEBUG",
112
+ log_format="json",
113
+ log_file="app.log"
114
+ )
115
+ ```
116
+
117
+ ## Logging
118
+
119
+ ### Configure Logging
120
+
121
+ ```python
122
+ from cloudflare_saas import configure_logging, LogLevel, LogFormat
123
+
124
+ # Simple console logging
125
+ configure_logging(level=LogLevel.INFO)
126
+
127
+ # Detailed file logging
128
+ configure_logging(
129
+ level=LogLevel.DEBUG,
130
+ log_format=LogFormat.DETAILED,
131
+ log_file="cloudflare-saas.log"
132
+ )
133
+
134
+ # JSON logging for production
135
+ configure_logging(
136
+ level=LogLevel.WARNING,
137
+ log_format=LogFormat.JSON,
138
+ log_file="/var/log/cloudflare-saas.log",
139
+ enable_console=False
140
+ )
141
+ ```
142
+
143
+ ### Log Levels
144
+
145
+ - **DEBUG**: Detailed diagnostic information
146
+ - **INFO**: General informational messages
147
+ - **WARNING**: Warning messages
148
+ - **ERROR**: Error messages
149
+ - **CRITICAL**: Critical errors
150
+
151
+ ### Log Formats
152
+
153
+ - **simple**: Minimal output `INFO: message`
154
+ - **detailed**: With timestamps and source `2025-12-17 10:30:45 - Module - INFO - [file.py:65] - message`
155
+ - **json**: Structured JSON for log aggregation
156
+
157
+ ### Using Loggers in Your Code
158
+
159
+ ```python
160
+ from cloudflare_saas import get_logger, LoggerMixin
161
+
162
+ # Get a logger
163
+ logger = get_logger(__name__)
164
+ logger.info("Starting operation")
165
+
166
+ # Use in a class
167
+ class MyService(LoggerMixin):
168
+ def do_work(self):
169
+ self.logger.info("Working...")
170
+ ```
171
+
172
+ ## Documentation
173
+
174
+ Comprehensive documentation is available at [Read the Docs](https://cloudflare-saas.readthedocs.io/).
175
+
176
+ ### Build Documentation Locally
177
+
178
+ ```bash
179
+ # Install documentation dependencies
180
+ make install-docs
181
+
182
+ # Build HTML documentation
183
+ make docs
184
+
185
+ # Serve documentation locally
186
+ make docs-serve
187
+ ```
188
+
189
+ Documentation includes:
190
+
191
+ - **Getting Started Guide**: Quick start and installation
192
+ - **Configuration Guide**: All configuration options
193
+ - **Logging Guide**: Comprehensive logging documentation
194
+ - **API Reference**: Complete API documentation
195
+ - **Examples**: Practical code examples
196
+ - **Deployment Guide**: Production deployment
197
+ - **Contributing Guide**: Development guidelines
198
+
199
+ ## Development
200
+
201
+ ### Available Make Commands
202
+
203
+ ```bash
204
+ make help # Show all available commands
205
+
206
+ # Development
207
+ make install # Install package
208
+ make install-dev # Install with dev dependencies
209
+ make install-docs # Install documentation dependencies
210
+
211
+ # Testing
212
+ make test # Run tests
213
+ make test-cov # Run tests with coverage
214
+ make test-watch # Run tests in watch mode
215
+
216
+ # Code Quality
217
+ make lint # Run linters (ruff, mypy)
218
+ make format # Format code (black, ruff)
219
+ make check # Run all checks (lint + test)
220
+
221
+ # Documentation
222
+ make docs # Build documentation
223
+ make docs-serve # Build and serve documentation
224
+ make docs-clean # Clean documentation build
225
+
226
+ # Docker
227
+ make docker-build # Build Docker image
228
+ make docker-run # Run Docker container
229
+ make docker-stop # Stop Docker containers
230
+
231
+ # API
232
+ make run-api # Run FastAPI development server
233
+
234
+ # Utilities
235
+ make clean # Clean build artifacts
236
+ make clean-all # Clean all generated files
237
+ ```
238
+
239
+ ### Running Tests
240
+
241
+ ```bash
242
+ # Run all tests
243
+ make test
244
+
245
+ # Run with coverage
246
+ make test-cov
247
+
248
+ # Run specific test
249
+ pytest tests/test_platform.py::test_create_tenant -v
250
+ ```
251
+
252
+ ### Code Quality
253
+
254
+ ```bash
255
+ # Format code
256
+ make format
257
+
258
+ # Check linting
259
+ make lint
260
+
261
+ # Run all checks
262
+ make check
263
+ ```
264
+
265
+ ## Architecture
266
+
267
+ See [cloudflare_r2_plan.md](./cloudflare_r2_plan.md) for detailed architecture.
268
+
269
+ ## Contributing
270
+
271
+ We welcome contributions! Please see [CONTRIBUTING.md](./docs/source/contributing.rst) for guidelines.
272
+
273
+ ### Development Setup
274
+
275
+ 1. Fork and clone the repository
276
+ 2. Install development dependencies: `make install-dev`
277
+ 3. Create a branch for your feature
278
+ 4. Make your changes with tests
279
+ 5. Run tests and linting: `make check`
280
+ 6. Submit a pull request
281
+
282
+ ## License
283
+
284
+ [Add your license here]
285
+
286
+ ## Support
287
+
288
+ - **Documentation**: https://cloudflare-saas.readthedocs.io/
289
+ - **Issues**: https://github.com/yourusername/cloudflare-saas/issues
290
+ - **Discussions**: https://github.com/yourusername/cloudflare-saas/discussions
@@ -0,0 +1,70 @@
1
+ """
2
+ Cloudflare R2 SaaS Platform Library
3
+
4
+ A production-ready async library for multi-tenant SaaS platforms.
5
+ """
6
+
7
+ from .platform import CloudflareSaaSPlatform
8
+ from .config import Config
9
+ from .logging_config import (
10
+ configure_logging,
11
+ get_logger,
12
+ LogLevel,
13
+ LogFormat,
14
+ LoggerMixin,
15
+ )
16
+ from .models import (
17
+ Tenant,
18
+ CustomDomain,
19
+ DomainStatus,
20
+ DeploymentResult,
21
+ VerificationMethod,
22
+ HostnameVerificationInstructions,
23
+ )
24
+ from .exceptions import (
25
+ CloudflareSaaSException,
26
+ TenantNotFoundError,
27
+ DomainVerificationError,
28
+ DeploymentError,
29
+ R2OperationError,
30
+ CustomHostnameError,
31
+ DNSError,
32
+ )
33
+ from .storage_adapter import StorageAdapter, InMemoryStorageAdapter
34
+ from .postgres_adapter import PostgresStorageAdapter
35
+ from .r2_client import R2Client
36
+ from .cloudflare_client import CloudflareClient
37
+ from .dns_verifier import DNSVerifier
38
+ from .terraform_deployer import TerraformDeployer
39
+
40
+ __version__ = "1.0.0"
41
+
42
+ __all__ = [
43
+ "CloudflareSaaSPlatform",
44
+ "Config",
45
+ "configure_logging",
46
+ "get_logger",
47
+ "LogLevel",
48
+ "LogFormat",
49
+ "LoggerMixin",
50
+ "Tenant",
51
+ "CustomDomain",
52
+ "DomainStatus",
53
+ "DeploymentResult",
54
+ "VerificationMethod",
55
+ "HostnameVerificationInstructions",
56
+ "CloudflareSaaSException",
57
+ "TenantNotFoundError",
58
+ "DomainVerificationError",
59
+ "DeploymentError",
60
+ "R2OperationError",
61
+ "CustomHostnameError",
62
+ "DNSError",
63
+ "StorageAdapter",
64
+ "InMemoryStorageAdapter",
65
+ "PostgresStorageAdapter",
66
+ "R2Client",
67
+ "CloudflareClient",
68
+ "DNSVerifier",
69
+ "TerraformDeployer",
70
+ ]