<center>
![alt text](https://raw.githubusercontent.com/TaqsBlaze/tenori/refs/heads/main/logo/tenori.png)
# Tenori
### Flask Multi Tenant Package
</center>
A lightweight, secure Python package for easily adding multi tenancy to Flask applications using dedicated databases per tenant.
## Features
- 🔐 Secure database creation with SQL injection prevention
- 🎯 Simple integration with existing Flask-SQLAlchemy applications
- ⚡ Automated tenant database management
- 🛠️ Flexible configuration options
- 📝 Type hints for better IDE support
## Installation
```bash
pip install tenori
```
## Quick Start
```python
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from tenori import MultiTenantManager
app = Flask(__name__)
db = SQLAlchemy(app)
# Initialize the multi-tenant manager
tenant_manager = MultiTenantManager(db)
# Create a new tenant database
@app.route('/signup', methods=['POST'])
def create_tenant():
try:
success = tenant_manager.create_tenant(current_user)
if success:
return {"status": "success"}
except Exception as e:
return {"status": "error", "message": str(e)}
```
## Requirements
- Python 3.10+
- Flask
- Flask-SQLAlchemy
- SQLAlchemy
## Configuration
The package requires a properly configured Flask-SQLAlchemy instance. Your database user must have privileges to create new databases.
## API Reference
### MultiTenantManager
The main class for managing multi tenancy.
```python
manager = MultiTenantManager(db_instance)
```
#### Methods
- `create_tenant(user)`: Creates a new database for the specified user
- Parameters:
- `user`: User object (must have an 'id' attribute)
- Returns:
- `bool`: True if successful, False otherwise
- `get_tenant_connection(user)`: Gets the connection string for a tenant's database
- Parameters:
- `user`: User object (must have an 'id' attribute)
- Returns:
- `str`: Database connection string
## Error Handling
The package provides custom exceptions for different scenarios:
- `MultiTenantError`: Base exception class
- `DatabaseCreationError`: Raised when database creation fails
- `InvalidConfigurationError`: Raised when configuration is invalid
## Security Considerations
- Database names are automatically sanitized to prevent SQL injection
- Each tenant gets their own isolated database
- Database credentials are handled securely
- Connection strings are generated dynamically
## Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
1. Fork the repository
2. Create your feature branch (`git checkout -b feature/AmazingFeature`)
3. Commit your changes (`git commit -m 'Add some AmazingFeature'`)
4. Push to the branch (`git push origin feature/AmazingFeature`)
5. Open a Pull Request
## License
This project is licensed under the MIT License - see the LICENSE file for details.
## Support
If you encounter any issues or need support, please open an issue on GitHub.
Raw data
{
"_id": null,
"home_page": "https://github.com/TaqsBlaze/tenori",
"name": "tenori",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.10",
"maintainer_email": null,
"keywords": "flask, multitenant, database, sqlalchemy, tenant, saas",
"author": "Tanaka Chinengundu",
"author_email": "tanakah30@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/62/95/6e8c3caf6027cdf1cf81f13efb40669f84032fea149b6a438b3943ace521/tenori-1.1.0.tar.gz",
"platform": null,
"description": "\n<center>\n\n![alt text](https://raw.githubusercontent.com/TaqsBlaze/tenori/refs/heads/main/logo/tenori.png)\n\n# Tenori\n### Flask Multi Tenant Package\n</center>\nA lightweight, secure Python package for easily adding multi tenancy to Flask applications using dedicated databases per tenant.\n\n## Features\n\n- \ud83d\udd10 Secure database creation with SQL injection prevention\n- \ud83c\udfaf Simple integration with existing Flask-SQLAlchemy applications\n- \u26a1 Automated tenant database management\n- \ud83d\udee0\ufe0f Flexible configuration options\n- \ud83d\udcdd Type hints for better IDE support\n\n## Installation\n\n```bash\npip install tenori\n```\n\n## Quick Start\n\n```python\nfrom flask import Flask\nfrom flask_sqlalchemy import SQLAlchemy\nfrom tenori import MultiTenantManager\n\napp = Flask(__name__)\ndb = SQLAlchemy(app)\n\n# Initialize the multi-tenant manager\ntenant_manager = MultiTenantManager(db)\n\n# Create a new tenant database\n@app.route('/signup', methods=['POST'])\ndef create_tenant():\n try:\n success = tenant_manager.create_tenant(current_user)\n if success:\n return {\"status\": \"success\"}\n except Exception as e:\n return {\"status\": \"error\", \"message\": str(e)}\n```\n\n## Requirements\n\n- Python 3.10+\n- Flask\n- Flask-SQLAlchemy\n- SQLAlchemy\n\n## Configuration\n\nThe package requires a properly configured Flask-SQLAlchemy instance. Your database user must have privileges to create new databases.\n\n\n## API Reference\n\n### MultiTenantManager\n\nThe main class for managing multi tenancy.\n\n```python\nmanager = MultiTenantManager(db_instance)\n```\n\n#### Methods\n\n- `create_tenant(user)`: Creates a new database for the specified user\n - Parameters:\n - `user`: User object (must have an 'id' attribute)\n - Returns:\n - `bool`: True if successful, False otherwise\n\n- `get_tenant_connection(user)`: Gets the connection string for a tenant's database\n - Parameters:\n - `user`: User object (must have an 'id' attribute)\n - Returns:\n - `str`: Database connection string\n\n## Error Handling\n\nThe package provides custom exceptions for different scenarios:\n\n- `MultiTenantError`: Base exception class\n- `DatabaseCreationError`: Raised when database creation fails\n- `InvalidConfigurationError`: Raised when configuration is invalid\n\n## Security Considerations\n\n- Database names are automatically sanitized to prevent SQL injection\n- Each tenant gets their own isolated database\n- Database credentials are handled securely\n- Connection strings are generated dynamically\n\n## Contributing\n\nContributions are welcome! Please feel free to submit a Pull Request.\n\n1. Fork the repository\n2. Create your feature branch (`git checkout -b feature/AmazingFeature`)\n3. Commit your changes (`git commit -m 'Add some AmazingFeature'`)\n4. Push to the branch (`git push origin feature/AmazingFeature`)\n5. Open a Pull Request\n\n## License\n\nThis project is licensed under the MIT License - see the LICENSE file for details.\n\n## Support\n\nIf you encounter any issues or need support, please open an issue on GitHub.\n",
"bugtrack_url": null,
"license": null,
"summary": "A Flask package for easily adding multi-tenancy with dedicated databases",
"version": "1.1.0",
"project_urls": {
"Bug Reports": "https://github.com/TaqsBlaze/tenori/issues",
"Documentation": "https://github.com/TaqsBlaze/tenori#readme",
"Homepage": "https://github.com/TaqsBlaze/tenori",
"Source": "https://github.com/TaqsBlaze/tenori"
},
"split_keywords": [
"flask",
" multitenant",
" database",
" sqlalchemy",
" tenant",
" saas"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "e3c56be22441414287d077d32d61ef32f703a568738db2c4de02fe6a74afef6c",
"md5": "d4d9e65c0edcc2e488dba5c432746600",
"sha256": "e075b9030bf810bf33ec74d60d18b42f9741fe2eaa789d218f661f2328d98b77"
},
"downloads": -1,
"filename": "tenori-1.1.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "d4d9e65c0edcc2e488dba5c432746600",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.10",
"size": 3680,
"upload_time": "2025-01-11T14:05:00",
"upload_time_iso_8601": "2025-01-11T14:05:00.905159Z",
"url": "https://files.pythonhosted.org/packages/e3/c5/6be22441414287d077d32d61ef32f703a568738db2c4de02fe6a74afef6c/tenori-1.1.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "62956e8c3caf6027cdf1cf81f13efb40669f84032fea149b6a438b3943ace521",
"md5": "bd7d89ab28c52987f40130f353c9917b",
"sha256": "30e3fec1377b1257cb1459239f65a077fa5cfdbb167d207a7c6b7f28acd760f4"
},
"downloads": -1,
"filename": "tenori-1.1.0.tar.gz",
"has_sig": false,
"md5_digest": "bd7d89ab28c52987f40130f353c9917b",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.10",
"size": 4134,
"upload_time": "2025-01-11T14:05:03",
"upload_time_iso_8601": "2025-01-11T14:05:03.330914Z",
"url": "https://files.pythonhosted.org/packages/62/95/6e8c3caf6027cdf1cf81f13efb40669f84032fea149b6a438b3943ace521/tenori-1.1.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-01-11 14:05:03",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "TaqsBlaze",
"github_project": "tenori",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"requirements": [
{
"name": "Flask",
"specs": [
[
">=",
"2.0.0"
]
]
},
{
"name": "Flask-SQLAlchemy",
"specs": [
[
">=",
"2.5.0"
]
]
},
{
"name": "SQLAlchemy",
"specs": [
[
">=",
"1.4.0"
]
]
},
{
"name": "PyMySQL",
"specs": [
[
">=",
"1.0.0"
]
]
}
],
"lcname": "tenori"
}