data-connectors-ai 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 (34) hide show
  1. data_connectors_ai-0.1.0/LICENSE +21 -0
  2. data_connectors_ai-0.1.0/PKG-INFO +476 -0
  3. data_connectors_ai-0.1.0/README.md +429 -0
  4. data_connectors_ai-0.1.0/data_connectors_ai.egg-info/PKG-INFO +476 -0
  5. data_connectors_ai-0.1.0/data_connectors_ai.egg-info/SOURCES.txt +32 -0
  6. data_connectors_ai-0.1.0/data_connectors_ai.egg-info/dependency_links.txt +1 -0
  7. data_connectors_ai-0.1.0/data_connectors_ai.egg-info/entry_points.txt +2 -0
  8. data_connectors_ai-0.1.0/data_connectors_ai.egg-info/requires.txt +38 -0
  9. data_connectors_ai-0.1.0/data_connectors_ai.egg-info/top_level.txt +2 -0
  10. data_connectors_ai-0.1.0/mcp_servers/__init__.py +0 -0
  11. data_connectors_ai-0.1.0/mcp_servers/postgres/__init__.py +0 -0
  12. data_connectors_ai-0.1.0/mcp_servers/postgres/server.py +89 -0
  13. data_connectors_ai-0.1.0/modules/__init__.py +1 -0
  14. data_connectors_ai-0.1.0/modules/_common/__init__.py +1 -0
  15. data_connectors_ai-0.1.0/modules/_common/base_connector.py +41 -0
  16. data_connectors_ai-0.1.0/modules/_common/graph_auth.py +43 -0
  17. data_connectors_ai-0.1.0/modules/gcp_bucket/__init__.py +4 -0
  18. data_connectors_ai-0.1.0/modules/gcp_bucket/client.py +180 -0
  19. data_connectors_ai-0.1.0/modules/onedrive/__init__.py +4 -0
  20. data_connectors_ai-0.1.0/modules/onedrive/client.py +115 -0
  21. data_connectors_ai-0.1.0/modules/postgres/__init__.py +4 -0
  22. data_connectors_ai-0.1.0/modules/postgres/client.py +388 -0
  23. data_connectors_ai-0.1.0/modules/rabbitmq/__init__.py +0 -0
  24. data_connectors_ai-0.1.0/modules/rabbitmq/receive_client.py +174 -0
  25. data_connectors_ai-0.1.0/modules/rabbitmq/send_client.py +95 -0
  26. data_connectors_ai-0.1.0/modules/rabbitmq/tests/__init__.py +0 -0
  27. data_connectors_ai-0.1.0/modules/rabbitmq/tests/test_receive_client.py +114 -0
  28. data_connectors_ai-0.1.0/modules/s3_bucket/__init__.py +4 -0
  29. data_connectors_ai-0.1.0/modules/s3_bucket/async_client.py +77 -0
  30. data_connectors_ai-0.1.0/modules/s3_bucket/client.py +188 -0
  31. data_connectors_ai-0.1.0/modules/sharepoint/__init__.py +4 -0
  32. data_connectors_ai-0.1.0/modules/sharepoint/client.py +228 -0
  33. data_connectors_ai-0.1.0/pyproject.toml +153 -0
  34. data_connectors_ai-0.1.0/setup.cfg +4 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Nagarjun Rajendran
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,476 @@
1
+ Metadata-Version: 2.4
2
+ Name: data-connectors-ai
3
+ Version: 0.1.0
4
+ Summary: Production-ready data connector libraries for AI applications and data processing pipelines
5
+ Author-email: Nagarjun Rajendran <nagarjunr@live.in>
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/nagarjunr/data-connectors-for-ai-agents
8
+ Project-URL: Repository, https://github.com/nagarjunr/data-connectors-for-ai-agents
9
+ Project-URL: Issues, https://github.com/nagarjunr/data-connectors-for-ai-agents/issues
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: Programming Language :: Python :: 3.12
12
+ Requires-Python: >=3.12
13
+ Description-Content-Type: text/markdown
14
+ License-File: LICENSE
15
+ Requires-Dist: boto3>=1.26.0
16
+ Requires-Dist: google-cloud-storage>=2.10.0
17
+ Requires-Dist: psycopg2-binary>=2.9.0
18
+ Requires-Dist: sqlalchemy>=2.0.0
19
+ Requires-Dist: requests>=2.31.0
20
+ Requires-Dist: python-dateutil>=2.8.0
21
+ Requires-Dist: pika>=1.3.0
22
+ Provides-Extra: s3
23
+ Requires-Dist: boto3>=1.26.0; extra == "s3"
24
+ Provides-Extra: gcp
25
+ Requires-Dist: google-cloud-storage>=2.10.0; extra == "gcp"
26
+ Provides-Extra: postgres
27
+ Requires-Dist: psycopg2-binary>=2.9.0; extra == "postgres"
28
+ Requires-Dist: sqlalchemy>=2.0.0; extra == "postgres"
29
+ Provides-Extra: sharepoint
30
+ Requires-Dist: requests>=2.31.0; extra == "sharepoint"
31
+ Requires-Dist: msal>=1.20.0; extra == "sharepoint"
32
+ Provides-Extra: onedrive
33
+ Requires-Dist: requests>=2.31.0; extra == "onedrive"
34
+ Requires-Dist: msal>=1.20.0; extra == "onedrive"
35
+ Provides-Extra: mcp
36
+ Requires-Dist: mcp>=1.0.0; extra == "mcp"
37
+ Provides-Extra: all
38
+ Requires-Dist: boto3>=1.26.0; extra == "all"
39
+ Requires-Dist: google-cloud-storage>=2.10.0; extra == "all"
40
+ Requires-Dist: psycopg2-binary>=2.9.0; extra == "all"
41
+ Requires-Dist: sqlalchemy>=2.0.0; extra == "all"
42
+ Requires-Dist: requests>=2.31.0; extra == "all"
43
+ Requires-Dist: msal>=1.20.0; extra == "all"
44
+ Requires-Dist: pika>=1.3.0; extra == "all"
45
+ Requires-Dist: mcp>=1.0.0; extra == "all"
46
+ Dynamic: license-file
47
+
48
+ # Data Connectors
49
+
50
+ Production-ready, reusable data connector libraries for AI applications and data processing pipelines.
51
+
52
+ ![Python](https://img.shields.io/badge/python-3.12%2B-blue.svg)
53
+ ![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)
54
+
55
+ **Key Features:**
56
+ - PostgreSQL, S3-compatible, GCP Storage, SharePoint, OneDrive connectors
57
+ - Enterprise-ready (proxy support, CA certificates)
58
+ - Type-hinted and well-documented
59
+ - Explicit configuration injection (no hidden state)
60
+ - Safe for batch jobs, CI/CD, containers, Airflow
61
+
62
+ ---
63
+
64
+ ## 🚀 Quick Start (5 Minutes)
65
+
66
+ ### 1. Install Package
67
+
68
+ ```bash
69
+ # Local development (editable)
70
+ cd /path/to/your-project
71
+ pip install -e /path/to/data-connectors
72
+
73
+ # Production (git SSH)
74
+ pip install git+ssh://git@github.com/nagarjunr/data-connectors-for-ai-agents.git@v0.1.0
75
+
76
+ # Install specific connectors only
77
+ pip install -e /path/to/data-connectors[postgres,s3]
78
+ ```
79
+
80
+ ### 2. Create Connector Module
81
+
82
+ **File:** `src/connectors/__init__.py`
83
+
84
+ ```python
85
+ """Centralized connector initialization (singleton pattern)."""
86
+ from typing import Optional
87
+ import os
88
+ from dotenv import load_dotenv
89
+
90
+ # Import connectors you need
91
+ from modules.postgres import PostgresClient
92
+ from modules.s3_bucket import S3Client
93
+ from modules.gcp_bucket import GCPBucketClient
94
+ from modules.sharepoint import SharePointClient
95
+ from modules.onedrive import OneDriveClient
96
+
97
+ load_dotenv()
98
+
99
+ # Singleton instances
100
+ _pg_client: Optional[PostgresClient] = None
101
+ _s3_client: Optional[S3Client] = None
102
+ _gcp_client: Optional[GCPBucketClient] = None
103
+ _sharepoint_client: Optional[SharePointClient] = None
104
+ _onedrive_client: Optional[OneDriveClient] = None
105
+
106
+
107
+ def get_postgres_client() -> PostgresClient:
108
+ """Get PostgreSQL client."""
109
+ global _pg_client
110
+ if _pg_client is None:
111
+ _pg_client = PostgresClient(
112
+ host=os.getenv("POSTGRES_HOST", "localhost"),
113
+ port=int(os.getenv("POSTGRES_PORT", "5432")),
114
+ database=os.getenv("POSTGRES_DATABASE", "your_database"),
115
+ user=os.getenv("POSTGRES_USER"),
116
+ password=os.getenv("POSTGRES_PASSWORD"),
117
+ )
118
+ return _pg_client
119
+
120
+
121
+ def get_s3_client() -> S3Client:
122
+ """Get S3-compatible client."""
123
+ global _s3_client
124
+ if _s3_client is None:
125
+ _s3_client = S3Client(
126
+ endpoint_url=os.getenv("S3_ENDPOINT"),
127
+ access_key=os.getenv("AWS_ACCESS_KEY_ID"),
128
+ secret_key=os.getenv("AWS_SECRET_ACCESS_KEY"),
129
+ region=os.getenv("AWS_DEFAULT_REGION", "us-east-1"),
130
+ )
131
+ return _s3_client
132
+
133
+
134
+ def get_gcp_client() -> GCPBucketClient:
135
+ """Get GCP Storage client."""
136
+ global _gcp_client
137
+ if _gcp_client is None:
138
+ _gcp_client = GCPBucketClient(
139
+ bucket_name=os.getenv("GCP_BUCKET_NAME"),
140
+ )
141
+ return _gcp_client
142
+
143
+
144
+ def get_sharepoint_client() -> SharePointClient:
145
+ """Get SharePoint client."""
146
+ global _sharepoint_client
147
+ if _sharepoint_client is None:
148
+ _sharepoint_client = SharePointClient(
149
+ site_id=os.getenv("SITE_ID"),
150
+ client_id=os.getenv("CLIENT_ID"),
151
+ client_secret=os.getenv("CLIENT_SECRET"),
152
+ tenant_id=os.getenv("TENANT_ID"),
153
+ )
154
+ return _sharepoint_client
155
+
156
+
157
+ def get_onedrive_client() -> OneDriveClient:
158
+ """Get OneDrive client."""
159
+ global _onedrive_client
160
+ if _onedrive_client is None:
161
+ _onedrive_client = OneDriveClient(
162
+ client_id=os.getenv("CLIENT_ID"),
163
+ client_secret=os.getenv("CLIENT_SECRET"),
164
+ tenant_id=os.getenv("TENANT_ID"),
165
+ directory=os.getenv("ONEDRIVE_DIRECTORY"), # Optional
166
+ )
167
+ return _onedrive_client
168
+
169
+
170
+ def close_all_connections():
171
+ """Close all connections on shutdown."""
172
+ global _pg_client, _s3_client, _gcp_client, _sharepoint_client, _onedrive_client
173
+ for client in [_pg_client, _s3_client, _gcp_client, _sharepoint_client, _onedrive_client]:
174
+ if client:
175
+ client.close()
176
+ ```
177
+
178
+ ### 3. Add Environment Variables
179
+
180
+ **File:** `.env`
181
+
182
+ ```bash
183
+ # PostgreSQL
184
+ POSTGRES_HOST=localhost
185
+ POSTGRES_PORT=5432
186
+ POSTGRES_DATABASE=your_database
187
+ POSTGRES_USER=your_user
188
+ POSTGRES_PASSWORD=your_password
189
+
190
+ # S3-Compatible Object Storage
191
+ AWS_ACCESS_KEY_ID=your_access_key
192
+ AWS_SECRET_ACCESS_KEY=your_secret_key
193
+ S3_ENDPOINT=https://your-s3-endpoint.example.com:9021
194
+ S3_NAMESPACE=your-namespace # Optional, only needed for some S3-compatible providers
195
+ AWS_DEFAULT_REGION=us-east-1
196
+
197
+ # GCP Storage
198
+ GCP_BUCKET_NAME=your-gcp-bucket-name
199
+
200
+ # Azure AD / Microsoft Graph (for SharePoint & OneDrive)
201
+ CLIENT_ID=your_client_id
202
+ CLIENT_SECRET=your_client_secret
203
+ TENANT_ID=your-tenant-id
204
+
205
+ # SharePoint Specific
206
+ SITE_ID=your-site-id
207
+
208
+ # OneDrive Specific
209
+ ONEDRIVE_DIRECTORY=Documents # Optional: default directory
210
+ ```
211
+
212
+ ### 4. Use in Your Code
213
+
214
+ ```python
215
+ from src.connectors import (
216
+ get_postgres_client,
217
+ get_s3_client,
218
+ get_gcp_client,
219
+ get_sharepoint_client,
220
+ get_onedrive_client,
221
+ close_all_connections,
222
+ )
223
+
224
+ # PostgreSQL
225
+ pg = get_postgres_client()
226
+ results = pg.query("SELECT * FROM users LIMIT 10")
227
+
228
+ # S3-compatible
229
+ s3 = get_s3_client()
230
+ s3.upload_file("local.txt", "bucket-name", "remote/path/file.txt")
231
+ files = s3.list_objects("bucket-name", prefix="documents/")
232
+
233
+ # GCP Storage
234
+ gcp = get_gcp_client()
235
+ gcp.upload("/tmp/report.pdf", "reports/monthly.pdf")
236
+
237
+ # SharePoint
238
+ sp = get_sharepoint_client()
239
+ sp.download("Shared Documents/file.pdf", "/tmp/file.pdf")
240
+
241
+ # OneDrive
242
+ od = get_onedrive_client()
243
+ od.list("Documents")
244
+
245
+ # Cleanup on shutdown (FastAPI example)
246
+ # @app.on_event("shutdown")
247
+ # async def shutdown():
248
+ # close_all_connections()
249
+ ```
250
+
251
+ ---
252
+
253
+ ## 📦 Available Connectors
254
+
255
+ | Connector | Purpose | Environment Variables | Documentation |
256
+ |-----------|---------|----------------------|---------------|
257
+ | **PostgreSQL** | Database connectivity with SQLAlchemy ORM | `POSTGRES_HOST`, `POSTGRES_PORT`, `POSTGRES_DATABASE`, `POSTGRES_USER`, `POSTGRES_PASSWORD` | [README](modules/postgres/README.md) |
258
+ | **S3 Bucket** | S3-compatible object storage (MinIO, AWS, etc.) | `S3_ENDPOINT`, `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, `AWS_DEFAULT_REGION` | [README](modules/s3_bucket/README.md) |
259
+ | **GCP Storage** | Google Cloud Storage | `GCP_BUCKET_NAME` | [README](modules/gcp_bucket/README.md) |
260
+ | **SharePoint** | SharePoint document libraries via Microsoft Graph | `CLIENT_ID`, `CLIENT_SECRET`, `TENANT_ID`, `SITE_ID` | [README](modules/sharepoint/README.md) |
261
+ | **OneDrive** | OneDrive file storage via Microsoft Graph | `CLIENT_ID`, `CLIENT_SECRET`, `TENANT_ID`, `SITE_ID`, `ONEDRIVE_DIRECTORY` | [README](modules/onedrive/README.md) |
262
+ | **RabbitMQ** | Send/receive with a durable quorum queue, auto-reconnect | `CONNECTION_STRING` or `RABBITMQ_HOST`, `RABBITMQ_PORT`, `RABBITMQ_USERNAME`, `RABBITMQ_PASSWORD` | [README](modules/rabbitmq/README.md) |
263
+
264
+ ---
265
+
266
+ ## 📚 Documentation
267
+
268
+ ### For Users
269
+ - **[Deployment Guide](docs/DEPLOYMENT.md)** - Complete deployment guide from local dev to OpenShift/Kubernetes
270
+
271
+ ### For Contributors
272
+ - **[Development Guide](docs/DEVELOPMENT.md)** - Development setup, code quality standards, and contributing guidelines
273
+
274
+ ### Quick Development Commands
275
+
276
+ ```bash
277
+ # Format code
278
+ make format
279
+
280
+ # Lint and auto-fix
281
+ make lint-fix
282
+
283
+ # Type check
284
+ make typecheck
285
+
286
+ # Run all checks
287
+ make check
288
+ ```
289
+
290
+ ---
291
+
292
+ ## 🎯 Common Use Cases
293
+
294
+ ### Use Case 1: Load Documents from S3
295
+
296
+ ```python
297
+ from src.connectors import get_s3_client
298
+ from pathlib import Path
299
+
300
+ def load_documents():
301
+ s3 = get_s3_client()
302
+ bucket = os.getenv("S3_BUCKET_NAME")
303
+ files = s3.list_objects(bucket, prefix="documents/")
304
+
305
+ documents = []
306
+ for file_key in files:
307
+ local_path = f"/tmp/{Path(file_key).name}"
308
+ s3.download_file(bucket, file_key, local_path)
309
+ with open(local_path, 'r') as f:
310
+ documents.append(f.read())
311
+
312
+ return documents
313
+ ```
314
+
315
+ ### Use Case 2: Save Results to PostgreSQL
316
+
317
+ ```python
318
+ from src.connectors import get_postgres_client
319
+
320
+ def save_result(data: dict):
321
+ pg = get_postgres_client()
322
+
323
+ query = """
324
+ INSERT INTO results (category, answer, status)
325
+ VALUES (%s, %s, %s)
326
+ RETURNING id
327
+ """
328
+ result_id = pg.execute(query, (data['category'], data['answer'], data['status']))
329
+ return result_id
330
+ ```
331
+
332
+ ### Use Case 3: Backup to GCP
333
+
334
+ ```python
335
+ from src.connectors import get_gcp_client
336
+ from pathlib import Path
337
+
338
+ def backup_files(source_dir: str):
339
+ gcp = get_gcp_client()
340
+
341
+ for file_path in Path(source_dir).rglob("*"):
342
+ if file_path.is_file():
343
+ gcp_path = f"backups/{file_path.name}"
344
+ gcp.upload(str(file_path), gcp_path)
345
+ ```
346
+
347
+ ---
348
+
349
+ ## 🏗️ Repository Structure
350
+
351
+ ```
352
+ data-connectors/
353
+ ├── README.md # This file - Quick start and overview
354
+ ├── docs/
355
+ │ ├── INTEGRATION.md # Integration guide for using connectors
356
+ │ ├── DEPLOYMENT.md # Complete deployment guide (local to OpenShift)
357
+ │ └── DEVELOPMENT.md # Development setup and guidelines
358
+ ├── pyproject.toml # Python project configuration
359
+ ├── requirements-dev.txt # Development dependencies
360
+ ├── Makefile # Development commands (format, lint, typecheck)
361
+ ├── examples/ # Runnable reference examples
362
+ │ ├── s3_bucket/
363
+ │ ├── sharepoint/
364
+ │ ├── onedrive/
365
+ │ ├── gcp_bucket/
366
+ │ └── postgres/
367
+ └── modules/
368
+ ├── _common/ # Shared base classes and auth helpers
369
+ ├── s3_bucket/ # S3-compatible connector
370
+ ├── sharepoint/ # SharePoint connector
371
+ ├── onedrive/ # OneDrive connector
372
+ ├── gcp_bucket/ # GCP bucket connector
373
+ └── postgres/ # PostgreSQL connector
374
+ ```
375
+
376
+ ---
377
+
378
+ ## 🔐 OpenShift Quick Setup
379
+
380
+ **Note:** Deploy keys may be disabled depending on your Git host policy. Use Personal Access Tokens instead.
381
+
382
+ ### Step 1: Create GitHub Personal Access Token
383
+
384
+ 1. Go to: [GitHub Settings - Personal Access Tokens](https://github.com/settings/tokens)
385
+ 2. Click **"Generate new token (classic)"**
386
+ 3. Select `repo` scope (Full control of private repositories)
387
+ 4. Set expiration (90 days recommended)
388
+ 5. **Copy token immediately** - you won't see it again
389
+
390
+ ### Step 2: Create Secret in OpenShift
391
+
392
+ ```bash
393
+ oc login --server=https://api.your-openshift-cluster.example.com:6443 --token=<your-token>
394
+ oc project your-project
395
+
396
+ oc create secret generic data-connectors-github-pat \
397
+ --from-literal=username=<your-github-username> \
398
+ --from-literal=password=ghp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxx \
399
+ --type=kubernetes.io/basic-auth
400
+
401
+ oc annotate secret data-connectors-github-pat \
402
+ 'build.openshift.io/source-secret-match-uri-1=https://github.com/*'
403
+ ```
404
+
405
+ For complete OpenShift deployment instructions, see [Deployment Guide](docs/DEPLOYMENT.md#production-deployment-openshift).
406
+
407
+ ---
408
+
409
+ ## 🐛 Troubleshooting
410
+
411
+ ### Import Error
412
+ ```bash
413
+ # Problem: ModuleNotFoundError: No module named 'modules'
414
+ # Solution:
415
+ pip install -e /path/to/data-connectors
416
+ pip list | grep data-connectors
417
+ ```
418
+
419
+ ### Connection Error
420
+ ```bash
421
+ # Problem: Connection refused to PostgreSQL/S3
422
+ # Solution:
423
+ # 1. Check .env variables
424
+ # 2. Verify services are running
425
+ # 3. Test connection:
426
+ psql -h localhost -U user -d db_name
427
+ ```
428
+
429
+ ### SSL Certificate Error
430
+ ```bash
431
+ # Problem: SSLError: certificate verify failed
432
+ # Solution:
433
+ export SSL_CERT_FILE=/path/to/ca-bundle.pem
434
+ export REQUESTS_CA_BUNDLE=$SSL_CERT_FILE
435
+ ```
436
+
437
+ For more troubleshooting help, see the [Deployment Guide](docs/DEPLOYMENT.md#troubleshooting).
438
+
439
+ ---
440
+
441
+ ## 🎓 Design Principles
442
+
443
+ - ✅ **Explicit configuration**: All settings injected via constructor parameters
444
+ - ✅ **No hidden state**: No environment variable loading inside modules
445
+ - ✅ **Deterministic behavior**: Same input = same output, always
446
+ - ✅ **Easy testing**: Pure functions, dependency injection, no side effects
447
+ - ✅ **Production-ready**: Designed for batch jobs, CI/CD, containers, Airflow
448
+ - ✅ **Type-safe**: Full type hints for better IDE support and error detection
449
+
450
+ ---
451
+
452
+ ## 🆘 Getting Help
453
+
454
+ - **Issues:** [GitHub Issues](https://github.com/nagarjunr/data-connectors-for-ai-agents/issues)
455
+ - **Integration Guide:** [docs/INTEGRATION.md](docs/INTEGRATION.md)
456
+ - **Deployment Guide:** [docs/DEPLOYMENT.md](docs/DEPLOYMENT.md)
457
+ - **Development Guide:** [docs/DEVELOPMENT.md](docs/DEVELOPMENT.md)
458
+
459
+ ---
460
+
461
+ ## 📋 Checklist for New Projects
462
+
463
+ - [ ] Install data-connectors package
464
+ - [ ] Create `src/connectors/__init__.py`
465
+ - [ ] Add environment variables to `.env`
466
+ - [ ] Test connections locally
467
+ - [ ] Add to `requirements.txt` / `requirements.prod.txt`
468
+ - [ ] For OpenShift: Create PAT and secrets
469
+ - [ ] Test deployment in staging
470
+ - [ ] Deploy to production
471
+
472
+ ---
473
+
474
+ ## License
475
+
476
+ MIT — see [LICENSE](LICENSE).