Skip to content

Commit f6f5d9d

Browse files
committed
improve settings, improve i18n, improve docs, add openapi docs spec gen
1 parent ece3798 commit f6f5d9d

32 files changed

+331
-184
lines changed

.gitignore

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ cython_debug/
161161
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
162162
#.idea/
163163

164-
*.html
165-
test*.py
164+
ignored/
166165
*.db
167166
*.log
167+
translatedocs.py

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
commit ece3798130409985feab58b683552c7d7821b50f
2+
Author: alexeev-prog <[email protected]>
3+
Date: Sun Nov 10 01:35:30 2024 +0700
4+
5+
feat/fix/docs: improve examples, add i18n support, refactor project docs gen, improve docs
6+
17
commit 4e28ad68cf51d8c8bfe4f1ee235f8e5586a8caa5
28
Author: alexeev-prog <[email protected]>
39
Date: Mon Nov 4 00:41:13 2024 +0700

Doxyfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ PROJECT_NAME = "pyEchoNext"
4848
# could be handy for archiving the generated documentation or if some version
4949
# control system is used.
5050

51-
PROJECT_NUMBER = "0.5.3"
51+
PROJECT_NUMBER = "0.5.4"
5252

5353
# Using the PROJECT_BRIEF tag one can provide an optional one line description
5454
# for a project that appears at the top of each page and should give viewer a

README.md

Lines changed: 123 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,7 @@ Welcome to **EchoNext**, where innovation meets simplicity! Are you tired of the
4141

4242
**Imagine** a lightweight framework that empowers you to create modern web applications with lightning speed and flexibility. With EchoNext, you're not just coding; you're building a masterpiece!
4343

44-
> Last stable version: 0.4.3 alpha
45-
> Last unstable version: 0.5.3 alpha
44+
> Last stable version: 0.5.4 alpha
4645
4746
## 🤔 Why Choose SqlSymphony?
4847

@@ -95,6 +94,18 @@ Welcome to **EchoNext**, where innovation meets simplicity! Are you tired of the
9594

9695
<p align="right">(<a href="#readme-top">back to top</a>)</p>
9796

97+
## ⚙️ Functionality
98+
99+
+ i18n localization
100+
+ basic project documentation generator
101+
+ request/response
102+
+ middlewares (with basic session cookie middleware)
103+
+ views and routes
104+
+ settings and config loader
105+
+ built-in template engine and Jinja2
106+
107+
<p align="right">(<a href="#readme-top">back to top</a>)</p>
108+
98109
## 🚀 Getting Started
99110

100111
pyEchoNext is available on [PyPI](https://pypi.org/project/pyechonext). Simply install the package into your project environment with PIP:
@@ -123,6 +134,113 @@ exampleapp/
123134

124135
## 💻 Usage Examples
125136

137+
### Localization i18n & OpenAPI specification generation & Settings loader from python module
138+
139+
```python
140+
import os
141+
from pyechonext.utils.exceptions import MethodNotAllow
142+
from pyechonext.app import ApplicationType, EchoNext
143+
from pyechonext.views import View
144+
from pyechonext.urls import URL, IndexView
145+
from pyechonext.config import SettingsLoader, SettingsConfigType
146+
from pyechonext.response import Response
147+
from pyechonext.template_engine.jinja import render_template
148+
from pyechonext.middleware import middlewares
149+
from pyechonext.docsgen import ProjDocumentation
150+
from pyechonext.apidoc_ui import APIDocumentation
151+
152+
153+
class UsersView(View):
154+
def get(self, request, response, **kwargs):
155+
return render_template(
156+
request,
157+
"index.html",
158+
user_name="User",
159+
session_id=request.session_id,
160+
friends=["Bob", "Anna", "John"],
161+
)
162+
163+
def post(self, request, response, **kwargs):
164+
raise MethodNotAllow(f"Request {request.path}: method not allow")
165+
166+
167+
url_patterns = [URL(url="/", view=IndexView), URL(url="/users", view=UsersView)]
168+
169+
config_loader = SettingsLoader(SettingsConfigType.PYMODULE, 'el_config.py')
170+
settings = config_loader.get_settings()
171+
echonext = EchoNext(
172+
__name__,
173+
settings,
174+
middlewares,
175+
urls=url_patterns,
176+
application_type=ApplicationType.HTML,
177+
)
178+
apidoc = APIDocumentation(echonext)
179+
projdoc = ProjDocumentation(echonext)
180+
181+
182+
@echonext.route_page('/api-docs')
183+
def api_docs(request, response):
184+
return Response(request, content_type='application/json', body=apidoc.generate_spec())
185+
186+
187+
@echonext.route_page("/book")
188+
@projdoc.documentate_route('/book', str, {}, ['GET', 'POST'])
189+
class BooksResource(View):
190+
"""
191+
This class describes a books resource.
192+
"""
193+
194+
def get(self, request, response, **kwargs):
195+
"""
196+
get queries
197+
198+
:param request: The request
199+
:type request: Request
200+
:param response: The response
201+
:type response: Response
202+
:param kwargs: The keywords arguments
203+
:type kwargs: dictionary
204+
205+
:returns: result
206+
:rtype: str
207+
"""
208+
return Response(request, body="title %{name}", use_i18n=True, name='Localization Site')
209+
210+
def post(self, request, response, **kwargs):
211+
"""
212+
post queries
213+
214+
:param request: The request
215+
:type request: Request
216+
:param response: The response
217+
:type response: Response
218+
:param kwargs: The keywords arguments
219+
:type kwargs: dictionary
220+
221+
:returns: result
222+
:rtype: str
223+
"""
224+
return echonext.locale_loader.get_string('title %{name}', name='Localization Site')
225+
226+
227+
projdoc.generate_documentation()
228+
```
229+
230+
`el_config.py`:
231+
232+
```python
233+
import os
234+
235+
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
236+
TEMPLATES_DIR = 'templates'
237+
SECRET_KEY = 'secret-key'
238+
LOCALE = 'RU_RU'
239+
LOCALE_DIR = 'locales'
240+
VERSION = "0.1.0"
241+
DESCRIPTION = 'Example echonext webapp'
242+
```
243+
126244
### Advanced app with flask-like and django-like routes
127245
Django-line classes with get-post methods and routing pages. And with the built-in template engine!
128246

@@ -357,9 +475,8 @@ Our future goals for pyEchoNext include:
357475

358476
- 📚 Improve middlewares
359477
- 🚀 Add async support
360-
361478
- ✅ Improve logging
362-
- 🌍 Improve auth
479+
- 🌍 Add auth
363480
- 🌐 More stability and scalablity
364481

365482
<p align="right">(<a href="#readme-top">back to top</a>)</p>
@@ -381,6 +498,7 @@ Extended documentation and framework specifications are available at the followi
381498
3. [Creating a web application](./docs/en/webapp_creation.md)
382499
4. [Creating routes (routes&views)](./docs/en/routes_and_views.md)
383500
5. [Request/Response](./docs/en/requests_responses.md)
501+
6. [Localization i18n](./docs/en/i18n_locales.md)
384502

385503
### Russian / Русский
386504

@@ -389,6 +507,7 @@ Extended documentation and framework specifications are available at the followi
389507
3. [Создание веб-приложения](./docs/ru/webapp_creation.md)
390508
4. [Создание маршрутов (routes&views)](./docs/ru/routes_and_views.md)
391509
5. [Request/Response](./docs/ru/requests_responses.md)
510+
6. [Локализация i18n](./docs/ru/i18n_locales.md)
392511

393512
## License
394513
Distributed under the GNU LGPL 2.1 License. See [LICENSE](https://github.com/alexeev-prog/pyEchoNext/blob/main/LICENSE) for more information.

SECURITY.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,11 @@ currently being supported with security updates.
77

88
| Version | Supported |
99
| ------- | ------------------ |
10+
| 0.5.4 | :white_check_mark: |
1011
| 0.5.3 | :white_check_mark: |
1112
| 0.4.3 | :white_check_mark: |
12-
| 0.4.2 | :white_check_mark: |
13-
| 0.4.1 | :white_check_mark: |
13+
| 0.4.2 | :x: |
14+
| 0.4.1 | :x: |
1415
| 0.3.1 | :x: |
1516
| 0.3.1 | :x: |
1617
| 0.2.1 | :x: |

docs/en/webapp_creation.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ This class describes settings.
2929
BASE_DIR: str
3030
TEMPLATES_DIR: str
3131
SECRET_KEY: str
32+
VERSION: str = '1.0.0'
33+
DESCRIPTION: str = 'Echonext webapp'
3234
LOCALE: str = "DEFAULT"
3335
LOCALE_DIR: str = None
3436
```
@@ -90,6 +92,8 @@ PEN_TEMPLATES_DIR=templates
9092
PEN_SECRET_KEY=secret-key
9193
PEN_LOCALE=RU_RU
9294
PEN_LOCALE_DIR=local
95+
PEN_VERSION=1.0.0
96+
PEN_DESCRIPTION=Example
9397
```
9498

9599
### THIS
@@ -107,6 +111,8 @@ BASE_DIR=.
107111
TEMPLATES_DIR=templates
108112
SECRET_KEY=secret-key
109113
LOCALE=DEFAULT
114+
VERSION=1.0.0
115+
DESCRIPTION=Example
110116
```
111117

112118
### PyModule
@@ -124,6 +130,8 @@ import os
124130
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
125131
TEMPLATES_DIR = 'templates'
126132
SECRET_KEY = 'secret-key'
133+
VERSION = '1.0.0'
134+
DESCRIPTION = 'Echonext webapp'
127135
LOCALE = 'DEFAULT'
128136
LOCALE_DIR = None
129137
```

docs/en/webframework_design.md

Lines changed: 0 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -1,84 +0,0 @@
1-
# pyEchoNext / web frameworks device
2-
3-
---
4-
5-
The most important parts of web frameworks are:
6-
7-
+ Routing handlers:
8-
- Simple: `/index`
9-
- Parameterized: `/article/{article_id}`
10-
+ Request handlers (views, handlers).
11-
12-
Basic requirement: the web framework must be supported by a fast, lightweight and efficient server (eg gunicorn). Python has a WSGI guide for this.
13-
14-
## Web server design in Python
15-
16-
```
17-
REQUEST
18-
CLIENT <--------------> [HTTP (80) or HTTPS (443)] Server
19-
ANSWER
20-
21-
> Application with logic
22-
> Data conversion for a python application <-- Web framework's area of interest (ensuring gunicorn works with it)
23-
> Gunicorn
24-
> Converted data
25-
SERVER -> NGINX
26-
> Data routing
27-
```
28-
29-
When developing a web application in python, we encounter the following problems:
30-
31-
+ Many frameworks (ex. django) do not know how to route response requests.
32-
+ Applications are insecure and may be susceptible to DDoS (Distributed Denial of Service) attacks.
33-
+ No load balancing between multiple servers.
34-
+ NGINX solves the problem of load balancing, but it cannot run and communicate with Python applications.
35-
36-
Therefore, there is a need to use a WSGI server (Web Server Gateway Interface) and a proxy server (such as NGINX).
37-
38-
## WSGI
39-
Python currently boasts a wide range of web application frameworks such as Zope, Quixote, Webware, SkunkWeb, PSO and Twisted Web, just to name a few. This wide variety of options can be a challenge for new Python users, as typically their choice of web framework will limit their choice of web servers to use, and vice versa.
40-
41-
In contrast, although Java has as many web application frameworks available, Java's "servlet" API allows applications written with any Java web application framework to run on any web server that supports the servlet API.
42-
43-
The availability and widespread use of such APIs in web servers for Python—whether those servers are written in Python (e.g., Medusa), built-in Python (e.g., mod_python), or call Python through a gateway protocol (e.g., CGI, FastCGI, and etc.) - will separate framework selection from web server selection, allowing users to choose the pairing that suits them, while freeing up framework and server developers to focus on their preferred area specializations.
44-
45-
Thus, this PEP offers a simple and universal interface between web servers and web applications or frameworks: the Python Web Server Gateway Interface (WSGI).
46-
47-
But the mere existence of the WSGI specification does nothing to address the current state of Python web application servers and frameworks. Authors and maintainers of servers and frameworks must actually implement WSGI for it to have any effect.
48-
49-
However, since no existing server or framework supports WSGI, an author who implements WSGI support will not receive immediate rewards. Thus, WSGI must be easy to implement so that the author's initial investment in the interface can be fairly low.
50-
51-
Thus, ease of implementation on both the server side and the interface framework side is absolutely critical to the usefulness of a WSGI interface and is therefore a primary criterion for any design decisions.
52-
53-
However, it should be noted that ease of implementation for a framework author is not the same as ease of use for a web application author. WSGI provides a completely "no frills" interface for the framework author, because bells and whistles like response objects and cookie handling would simply prevent existing frameworks from solving these problems. Again, the goal of WSGI is to facilitate simple interoperability between existing servers and applications or frameworks, not to create a new web framework.
54-
55-
It should also be noted that this target does not allow WSGI to require anything that is not already available in deployed versions of Python. Therefore, new standard library modules are not proposed or required by this specification, and nothing in WSGI requires a Python version greater than 2.2.2. (However, it would be nice if future versions of Python included support for this interface in the web servers provided by the standard library.)
56-
57-
In addition to being easy to implement for existing and future frameworks and servers, it should also be easy to create request preprocessors, response postprocessors, and other WSGI-based "middleware" components that look like an application to its containing server, while also acting as a server to its contained applications. If middleware can be both simple and reliable, and WSGI is widely available in servers and frameworks, this allows for the possibility of an entirely new type of Python web application framework: consisting of loosely coupled WSGI middleware components. Indeed, existing framework authors may even choose to refactor their frameworks' existing services so that they are exposed in a way that becomes more like the libraries used with WSGI and less like monolithic frameworks. This would then allow application developers to select "best-of-breed" components for a specific functionality, rather than committing to all the pros and cons of a single framework.
58-
59-
Of course, as of this writing, that day is undoubtedly quite far away. At the same time, this is a sufficient short-term goal for WSGI to enable the use of any framework with any server.
60-
61-
Finally, it should be mentioned that the current version of WSGI does not prescribe any specific mechanism for "deploying" an application for use with a web server or server gateway. Currently, this is necessarily determined by the server or gateway implementation. Once enough servers and frameworks have implemented WSGI to provide hands-on experience with various deployment requirements, it may make sense to create another PEP describing
62-
63-
## Integer pyEchoNext
64-
pyEchoNext is a universal tool with the ability to make a monolithic web application, or vice versa, a modular web application. Django was too big and clumsy for us, flask or fastapi was too small. Therefore, we decided to take some features from django and flask/fastapi, combine them and make it all symbiotic. So that you can make a large monolithic project or a small service. And turning a small service into a large application or vice versa required a minimum of effort.
65-
66-
Our goals were also to make all this as clear as possible, developer-friendly, and add the ability to integrate third-party libraries.
67-
68-
As a result, the main characteristics of the project are as follows:
69-
70-
1. Goal: Create a universal multi-faceted web framework in python
71-
2. Tasks:
72-
+ Find the good and bad sides of Flask, FastAPI
73-
+ Find the good and bad sides of Django
74-
+ Compare the capabilities of existing frameworks
75-
+ Selection of the best features
76-
+ Symbiosis of features into one whole
77-
+ Build project code according to SOLID and OOP principles, easily extensible, scalable and complementary.
78-
+ Make the code fast and productive, give freedom to the user and developer
79-
3. Problem: at the moment there are very few universal frameworks that allow you to create both a large monolithic application and a fast small service.
80-
4. Relevance: the web sphere is very popular at the moment, the ability to work with web frameworks, abstractions, and know the structure of sites will help everyone.
81-
82-
---
83-
84-
[Contents](./index.md)

docs/ru/i18n_locales.md

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,36 @@ from pyechonext.response import Request, Response
2020
# создаем request ...
2121
# request = ...
2222

23-
response = Response(request, body='title', use_i18n=True)
23+
# ваш view или route
24+
response = Response(request, body='title', use_i18n=True)
2425
```
2526

2627
Это будет сигнализировать приложению о том, что в данном Response следует использовать i18n. И приложение будет переводить вашу фразу.
2728

29+
Также вы можете и не возвращать response:
30+
31+
```python
32+
return echonext.locale_loader.get_string('title')
33+
```
34+
35+
В echonext есть публичный объект locale_loader, он и является загрузчиком локализации. Метод get_string получает строку из словаря локализации. Как их создавать и читать вы можете увидеть в секции "Создание локализаций" под этой.
36+
37+
Также вы можете использовать форматирование через Response:
38+
39+
```python
40+
return Response(request, body="title %{name}", use_i18n=True, name='Localization site')
41+
```
42+
43+
> ЗАПРЕЩЕНЫ следующие аргументы (они заняты): `request: Request, use_i18n: bool = False, status_code: Optional[int] = 200, body: Optional[str] = None, headers: Optional[Dict[str, str]] = {}, content_type: Optional[str] = None, charset: Optional[str] = None, **kwargs`
44+
45+
Но для локализации мы рекомендуем возвращать контент, а не Response, особенно если вам требуется использовать наименования выше.
46+
47+
И вы можете как раз использовать форматирование напрямую:
48+
49+
```python
50+
return echonext.locale_loader.get_string('title %{name}', name='Localization Site')
51+
```
52+
2853
## Создание локализаций
2954
В приложение вы передаете обязательный параметр Settings. В нем есть два поля относящиеся к локализации:
3055

0 commit comments

Comments
 (0)