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.
- cloudflare_saas-1.0.0/PKG-INFO +338 -0
- cloudflare_saas-1.0.0/README.md +290 -0
- cloudflare_saas-1.0.0/cloudflare_saas/__init__.py +70 -0
- cloudflare_saas-1.0.0/cloudflare_saas/cloudflare_client.py +135 -0
- cloudflare_saas-1.0.0/cloudflare_saas/config.py +91 -0
- cloudflare_saas-1.0.0/cloudflare_saas/dns_verifier.py +96 -0
- cloudflare_saas-1.0.0/cloudflare_saas/exceptions.py +36 -0
- cloudflare_saas-1.0.0/cloudflare_saas/logging_config.py +156 -0
- cloudflare_saas-1.0.0/cloudflare_saas/models.py +84 -0
- cloudflare_saas-1.0.0/cloudflare_saas/platform.py +357 -0
- cloudflare_saas-1.0.0/cloudflare_saas/postgres_adapter.py +208 -0
- cloudflare_saas-1.0.0/cloudflare_saas/r2_client.py +202 -0
- cloudflare_saas-1.0.0/cloudflare_saas/storage_adapter.py +109 -0
- cloudflare_saas-1.0.0/cloudflare_saas/terraform_deployer.py +201 -0
- cloudflare_saas-1.0.0/cloudflare_saas/worker_template.js +219 -0
- cloudflare_saas-1.0.0/cloudflare_saas.egg-info/PKG-INFO +338 -0
- cloudflare_saas-1.0.0/cloudflare_saas.egg-info/SOURCES.txt +21 -0
- cloudflare_saas-1.0.0/cloudflare_saas.egg-info/dependency_links.txt +1 -0
- cloudflare_saas-1.0.0/cloudflare_saas.egg-info/requires.txt +22 -0
- cloudflare_saas-1.0.0/cloudflare_saas.egg-info/top_level.txt +1 -0
- cloudflare_saas-1.0.0/setup.cfg +4 -0
- cloudflare_saas-1.0.0/setup.py +62 -0
- cloudflare_saas-1.0.0/tests/test_platform.py +203 -0
|
@@ -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
|
+
[](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
|
+
[](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
|
+
]
|