EchoNext is a lightweight, fast and scalable web framework for Python
Explore the docs Β»
Why Choose pyEchoNext
Β·
Key Features
Β·
Getting Started
Β·
Basic Usage
Β·
Specification
Β·
Documentation
Β·
License
PyEchoNext is a lightweight, high-performance web framework designed for building scalable Python web applications and APIs. With its modular architecture and focus on developer productivity, it combines Flask-like simplicity with FastAPI-inspired performance features. Built for modern web development challenges.
Note
Python 3.12+
Caution
PyEchoNext is currently in active alpha development. While core functionality is stable, some advanced features are still evolving. Production use requires thorough testing.
Note
Versions below 0.7.14a are not recommended for use with gunicorn <23.0 due to the fact that they used an older version of gunicorn (<23.0), which was vulnerable.
Next big update: 0.8.0 - Hybrid Performance Core: async + multithread + multiprocess
You want see hybrid core before release? See DevGuide Specs for HybridCore.
- SQLSymphony - simple and fast ORM in sqlite (and you can add other DBMS)
- Burn-Build - simple and fast build system written in python for C/C++ and other projects. With multiprocessing, project creation and caches!
- OptiArch - shell script for fast optimization of Arch Linux
- libnumerixpp - a Powerful C++ Library for High-Performance Numerical Computing
- pycolor-palette - display beautiful log messages, logging, debugging.
- shegang - powerful command interpreter (shell) for linux written in C
-
π₯ Featherweight Performance: No bloat, just speed! Our framework is designed to optimize performance, making it a breeze to create and scale your applications without the overhead.
-
πΌ Unmatched Scalability: Handle thousands of connections effortlessly! Echonext is built for performance in high-demand environments, making it the perfect choice for startups or enterprise applications.
-
π§ Customizable Architecture: Tailor your framework to suit your unique needs. Whether itβs middleware, routing, or authentication, make it yours with minimal effort!
-
π Cross-Platform Compatibility: Echonext works beautifully on any OS. Whether youβre developing on Windows, macOS, or Linux, youβre covered!
-
π‘ User-Friendly Design: Our intuitive API and comprehensive documentation make it easy for beginners and pros alike. Dive in and start coding right away!
-
π¦ Plug-and-Play Components: Easily integrate with third-party libraries to enhance your application. Donβt reinvent the wheelβleverage existing solutions!
-
π Built-in Authentication: Simplify your user authentication process with our built-in, easy-to-implement features.
-
π Automatic API Documentation: Create RESTful endpoints that are not just powerful but also well-documented, saving you time and effort.
- Intuitive API: Pythonic, object-oriented interface for interacting with routes and views.
- Performance Optimization: Lazy loading, eager loading, and other techniques for efficient web queries.
- Comprehensive Documentation: Detailed usage examples and API reference to help you get started.
- Modular Design: Clean, maintainable codebase that follows best software engineering practices.
- Extensive Test Coverage: Robust test suite to ensure the library's reliability and stability.
graph TD
A[Router] --> B[Middleware]
B --> C[Controllers]
C --> D[Models]
C --> E[Views]
D --> F[Data]
E --> G[Templates]
A --> H[Static Files]
- Trie-based URL dispatch - O(m) lookup complexity
- Dynamic path parameters - Type-annotated parameter handling
- Nested routers - Modular application organization
# Hierarchical routing example
main_router = Router()
admin_router = Router(prefix="/admin")
@admin_router.route_page("/dashboard")
def admin_dashboard(request, response):
return render_template("admin.html")
main_router.include_router(admin_router)
- Multi-layer protection:
- CSRF tokens with session binding
- XSS double-escaping (content + attributes)
- SQL injection pattern filtering
- Rate limiting (sliding window algorithm)
- Cryptographic modules:
- PSPCAlgorithm for lightweight encryption
- SHA3/BLAKE3 hashing support
- Salted password handling
# Security implementation example
token = Security.generate_csrf_token(session_id)
filtered_query = Security.filter_sql_query("SELECT * FROM users; DROP TABLE users")
- Multi-layer caching:
- LRU in-memory cache
- Performance-optimized memoization
- Static file preloading
- JIT-friendly design:
- Numba-compatible critical paths
- Zero-copy request processing
- Async-ready architecture (in development)
# Performance-cached view
@performance_cached(perf_cache)
def compute_intensive_view():
return calculate_fibonacci(1000)
- i18n/l10n localization with hermes-langlib.
- basic project documentation generator
- request/response
- middlewares (with basic session cookie middleware)
- views and routes
- settings and config loader
- built-in template engine and Jinja2
- basic security and hashing
- static files management
- cache response bodies
- performance
- slugger
- permissions
- pyEchoNext Schemas (
pyechonext.schemas
) and pydantic support for validating schemas
pyEchoNext is available on PyPI. Simply install the package into your project environment with PIP:
pip install pyechonext
Once installed, you can start using the library in your Python projects. Check out the documentation for detailed usage examples and API reference.
pyEchoNext is universal, and you are free to use any Dependency-Injection framework. But we recommend using the specially developed echonextdi. It is simple and fast to use.
Install:
pip install echonextdi
Example code:
from echonextdi.containers.container import Container
from echonextdi.depends import Depends
from echonextdi.providers.callable_provider import CallableProvider
def sqrt(a: int, b: int = 2):
return a**b
class SQRT_Dependency:
def __init__(self, sqrt):
self.sqrt = sqrt
container = Container()
container.register("sqrt", CallableProvider(sqrt))
def calculate(number: int, depend: Depends = Depends(container, SQRT_Dependency)):
print(f"{number} ^2 = {depend().sqrt(2)}")
calculate(4) # Output: 16
You can view examples at examples directory.
Prefix Tree data structure (this structure also used in pyechonext routing system)
from pyechonext.utils.trie import PrefixTree
if __name__ == '__main__':
trie = PrefixTree()
trie.insert('apple')
trie.insert('app')
trie.insert('aposematic')
trie.insert('appreciate')
trie.insert('book')
trie.insert('bad')
trie.insert('bear')
trie.insert('bat')
print(trie.starts_with('app'))
router_tree = PrefixTree()
router_tree.insert('index')
router_tree.insert('users')
router_tree.insert('transactions')
router_tree.insert('wallets')
router_tree.insert('wallets/create')
print(router_tree.starts_with('wa'))
Hermes LangLib - a fast and light python library for translating, localizing and internationalizing your applications. The library is aimed at high speed and stability; it can be used in highly loaded projects.
Directory tree:
βββ example.toml
βββ locales
βββ default.json
Example config-file example.toml
:
locale_directory="locales"
default_locale_file="default.json"
default_language="RU_RU"
translator="google"
Example locale file locales/default.json
:
{
"locales": {
"RU": ["RU_RU"],
"EN": ["EN_EN", "EN_US"]
},
"RU": {
"RU_RU": {
"title": "ΠΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠ° Π΄Π»Ρ ΠΈΠ½ΡΠ΅ΡΠ½Π°ΡΠΈΠΎΠ½Π°Π»ΠΈΠ·Π°ΡΠΈΠΈ",
"description": "ΠΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠ°, ΠΊΠΎΡΠΎΡΠ°Ρ ΠΏΠΎΠ·Π²ΠΎΠ»ΠΈΡ ΠΏΠ΅ΡΠ΅Π²ΠΎΠ΄ΠΈΡΡ Π²Π°ΡΠΈ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ",
"mails_message": {
"plural": "count",
"^0$": "Π£ Π²Π°Ρ Π½Π΅Ρ Π½ΠΈ ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΏΠΈΡΡΠΌΠ°",
"11": "Π£ Π²Π°Ρ Π΅ΡΡΡ {count} ΠΏΠΈΡΠ΅ΠΌ",
"1$|1$": "Π£ Π²Π°Ρ Π΅ΡΡΡ {count} ΠΏΠΈΡΡΠΌΠΎ",
"^(2|3|4)$|(2|3|4)$": "Π£ Π²Π°Ρ Π΅ΡΡΡ {count} ΠΏΠΈΡΡΠΌΠ°",
"other": "Π£ Π²Π°Ρ Π΅ΡΡΡ {count} ΠΏΠΈΡΠ΅ΠΌ"
}
}
},
"EN": {
"EN_EN": {
"title": "Library for internationalization",
"description": "A library that will allow you to translate your applications",
"mails_message": {
"plural": "count",
"^0$": "You do not have any mail.",
"^1$": "You have a new mail.",
"other": "You have {count} new mails."
}
},
"EN_US": {
"title": "Library for internationalization",
"description": "A library that will allow you to translate your applications",
"mails_message": {
"plural": "count",
"^0$": "You do not have any mail.",
"^1$": "You have a new mail.",
"other": "You have {count} new mails."
}
}
}
}
Example usage:
from hermes_langlib.locales import LocaleManager
from hermes_langlib.storage import load_config
config = load_config('example.toml')
locale_manager = LocaleManager(config)
print(locale_manager.get('title - {version}', 'default', 'RU_RU', version="0.1.0"))
print(locale_manager.get('title - {version}', 'default', 'RU', version="0.1.0"))
print(locale_manager.get('mails_message.', 'default', 'RU_RU', count=0))
print(locale_manager.get('mails_message', 'default', 'RU_RU', count=1))
print(locale_manager.get('mails_message', 'default', 'RU_RU', count=11))
print(locale_manager.get('mails_message', 'default', 'RU_RU', count=2))
print(locale_manager.get('mails_message', 'default', 'RU_RU', count=22))
print(locale_manager.get('mails_message', 'default', 'RU_RU', count=46))
print(locale_manager.get('mails_message', 'default', 'RU_RU', count=100000001))
print(locale_manager.translate("You have only three mails", "en", 'ru'))
print(locale_manager.translate("Π£ Π²Π°Ρ Π²ΡΠ΅Π³ΠΎ ΡΡΠΈ ΠΏΠΈΡΡΠΌΠ°", "ru", 'en'))
You can read Hermes-Langlib Specification at this link.
import os
from pyechonext.app import ApplicationType, EchoNext
from pyechonext.config import Settings
from pyechonext.middleware import middlewares
from pyechonext.mvc.controllers import PageController
from pyechonext.urls import URL
from echonextdi.containers.container import Container
from echonextdi.depends import Depends
from echonextdi.providers.callable_provider import CallableProvider
class IndexController(PageController):
def get(self, request, response, **kwargs):
return "Hello"
def post(self, request, response, **kwargs):
return "Hello"
def say_hello(name: str, phrase: str = 'Hello'):
return f'{phrase} {name}'
class Hello_Dependency:
def __init__(self, say_hello):
self.say_hello = say_hello
container = Container()
container.register("say_hello", CallableProvider(say_hello))
url_patterns = [URL(path="/", controller=IndexController)]
settings = Settings(
BASE_DIR=os.path.dirname(os.path.abspath(__file__)), TEMPLATES_DIR="templates"
)
echonext = EchoNext(
__name__,
settings,
middlewares,
urls=url_patterns,
application_type=ApplicationType.HTML,
)
@echonext.route_page("/hello/{name}")
def hello(request, response, name: str = "World", depend: Depends = Depends(container, Hello_Dependency)):
response.body = depend().say_hello(name)
import random
from pyechonext.utils.performance import InMemoryPerformanceCache, SingletonPerformanceCache, performance_cached
memorycache = InMemoryPerformanceCache
perf = SingletonPerformanceCache(memorycache)
@performance_cached(perf)
def example_function(a: int = 10 ** 6):
inside_circle = 0
for _ in range(a):
x = random.uniform(-1, 1)
y = random.uniform(-1, 1)
if x ** 2 + y ** 2 <= 1:
inside_circle += 1
return (inside_circle / a) * 4
if __name__ == '__main__':
print('start')
print(f'{example_function()} - Caching')
print(f'{example_function()} - Cached')
print(f'{example_function(10 ** 7)} - Caching new')
from pyechonext.permissions import (
Permission,
Role,
Resource,
AccessControlRule,
Policy,
AgeRestrictionsABP,
User,
DefaultPermissionChecker,
UserController,
)
view_users_perm = Permission("view_users")
edit_users_perm = Permission("edit_users")
admin_role = Role("admin")
admin_role.add_permission(view_users_perm)
admin_role.add_permission(edit_users_perm)
user_role = Role("user")
user_role.add_permission(view_users_perm)
user_resource = Resource("UserResource")
policy = Policy()
policy.add_rule(AccessControlRule(admin_role, view_users_perm, user_resource, True))
policy.add_rule(AccessControlRule(admin_role, edit_users_perm, user_resource, True))
policy.add_rule(AccessControlRule(user_role, view_users_perm, user_resource, True))
policy.add_rule(AccessControlRule(user_role, edit_users_perm, user_resource, False))
age_policy = AgeRestrictionsABP(conditions={"age": 18}, rules=policy.rules)
age_policy.add_rule(AccessControlRule(user_role, view_users_perm, user_resource, True))
admin_user = User("admin", attributes={"age": 30})
admin_user.add_role(admin_role)
young_user = User("john_doe", attributes={"age": 17})
young_user.add_role(user_role)
permission_checker = DefaultPermissionChecker(policy)
user_controller = UserController(permission_checker)
def main():
assert user_controller.view_users(admin_user, user_resource) == (
"200 OK",
"User edit form",
)
assert user_controller.edit_users(admin_user, user_resource) == (
"200 OK",
"User edit form",
)
assert user_controller.edit_users(young_user, user_resource) == (
"403 Forbidden",
"You do not have permission to edit users.",
)
assert age_policy.evaluate(young_user, user_resource, view_users_perm) == False
assert age_policy.evaluate(admin_user, user_resource, view_users_perm) == True
if __name__ == "__main__":
main()
A security module created for hash functions and crypto-algorithms.
Simple crypto-algorithms.
Point Simple Password Crypt Algorithm.
Base: AngryPassword
Crypted: 00778.87999.74379.363401.558001.558001.96058.06107.711601.87999.13309.07469.50075
Decrypted: AngryPassword
Base: S0mesd7623tds@&6^@_
Crypted: 51338.82165.83428.85374.62333.82165.558001.00778.237101.72744.05834.85374.53284.00778.558001.77588.39559.69024.19727
Decrypted: S0mesd7623tds@&6^@_
Base: PassWord
Crypted: 00778.87999.74379.99267.558001.558001.96058.06107
Decrypted: PassWord
Base: Pass
Crypted: 558001.558001.96058.06107
Decrypted: Pass
Example:
from pyechonext.security.crypts import PSPCAlgorithm
pspc = PSPCAlgorithm()
passwords = ['AngryPassword', 'S0mesd7623tds@&6^@_', 'PassWord', 'Pass']
for password in passwords:
print('Base:', password)
print('Crypted:', pspc.crypt(password))
print('Decrypted:', pspc.decrypt(pspc.crypt(password)))
print()
- Module:
pyechonext.security.hashing
Enum class with available hashing algorithms
class HashAlgorithm(Enum):
"""
This class describes a hash algorithms.
"""
SHA256 = auto()
SHA512 = auto()
MD5 = auto()
BLAKE2B = auto()
BLAKE2S = auto()
A simple class for hashing text. Has no 'salting'.
hasher = PlainHasher(HashAlgorithm.BLAKE2S)
old_hash = hasher.hash("TEXT")
new_hash = hasher.hash("TEXT")
if hasher.verify("TEXT", new_hash): # true
print('Yes!')
if hasher.verify("TEXT2", old_hash): # false
print('Yes!')
# Output: one "Yes!"
A simple class for hashing text. Has hash salt.
hasher = SaltedHasher(HashAlgorithm.BLAKE2S, salt='bob')
old_hash = hasher.hash("TEXT")
new_hash = hasher.hash("TEXT")
if hasher.verify("TEXT", new_hash): # true
print('Yes!')
if hasher.verify("TEXT2", old_hash): # false
print('Yes!')
# Output: one "Yes!"
View is an abstract class, with abstract get and post methods (all descendants must create these methods).
class View(ABC):
"""
Page view
"""
@abstractmethod
def get(self, request: Request, response: Response, *args, **kwargs):
"""
Get
:param request: The request
:type request: Request
:param response: The response
:type response: Response
:param args: The arguments
:type args: list
:param kwargs: The keywords arguments
:type kwargs: dictionary
"""
raise NotImplementedError
@abstractmethod
def post(self, request: Request, response: Response, *args, **kwargs):
"""
Post
:param request: The request
:type request: Request
:param response: The response
:type response: Response
:param args: The arguments
:type args: list
:param kwargs: The keywords arguments
:type kwargs: dictionary
"""
raise NotImplementedError
Example of view:
class IndexView(View):
def get(self, request: Request, response: Response, **kwargs):
"""
Get
:param request: The request
:type request: Request
:param response: The response
:type response: Response
:param args: The arguments
:type args: list
:param kwargs: The keywords arguments
:type kwargs: dictionary
"""
return "Hello World!"
def post(self, request: Request, response: Response, **kwargs):
"""
Post
:param request: The request
:type request: Request
:param response: The response
:type response: Response
:param args: The arguments
:type args: list
:param kwargs: The keywords arguments
:type kwargs: dictionary
"""
return "Message has accepted!"
Or you can return response:
class IndexView(View):
def get(self, request: Request, response: Response, **kwargs):
"""
Get
:param request: The request
:type request: Request
:param response: The response
:type response: Response
:param args: The arguments
:type args: list
:param kwargs: The keywords arguments
:type kwargs: dictionary
"""
return Response(request, body="Hello World!")
def post(self, request: Request, response: Response, **kwargs):
"""
Post
:param request: The request
:type request: Request
:param response: The response
:type response: Response
:param args: The arguments
:type args: list
:param kwargs: The keywords arguments
:type kwargs: dictionary
"""
return Response(request, body="Message has accepted!")
To test the web framework, PyTest with the pytest-cov plugin is used. You can look at the tests in tests directory
The main documentation is here.
If you encounter any issues or have questions about pyEchoNext, please:
- Check the documentation for answers
- Open an issue on GitHub
- Reach out to the project maintainers via the mailing list
We welcome contributions from the community! If you'd like to help improve pyEchoNext, please check out the contributing guidelines to get started.
If you find Echonext valuable and want to support the project:
- Star on GitHub β
- Share it with friends and colleagues!
- Donate via cryptocurrency π
Connect with fellow Echonext users: Join our Telegram Chat
- 0.8.0: Hybrid core: async + multithread + multiprocess
- Database ORM integration
- OpenAPI 3.1 schema generation
- Built-in monitoring dashboard
- JWT authentication module
- Websocket support
- Distributed task queue
- GRPC integration
We welcome PRs addressing:
- Security enhancements
- Performance optimization
- Documentation improvements
- Test coverage expansion
- ASGI migration path
Before contributing:
- Review docs
- Maintain 100% test coverage for new code
- Follow PEP8 and SOLID, DRY, KISS principles
- Include type annotations
This project operates under GNU LGPL 2.1 - see LICENSE. For enterprise support, contact alexeev.dev@mail.ru.
PyEchoNext - Build robust web applications with Pythonic elegance.
Explore Documentation | Report Issue | View Examples
EchoNext is a lightweight, fast and scalable web framework for Python Copyright (C) 2024 Alexeev Bronislav (C) 2024
This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA