commit 9fe5e43f881e39d59f051d93bf0a3725d9177dd0
parent 522339056484160655dba898047c77e56a5af6ae
Author: Jean Schurger <jean@schurger.org>
Date: Sat, 17 Oct 2026 14:41:39 -0400
README : présentation courte, liens vers la documentation et le dépôt
L'ancien README décrivait un setup.py et montait ses exemples au mauvais
endroit ; la documentation à jour est sur https://schurger.org/pages/encadre.html.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NezW9k9RsGdD9Po82BD4Vv
Diffstat:
| M | README.org | | | 349 | ++++--------------------------------------------------------------------------- |
1 file changed, 15 insertions(+), 334 deletions(-)
diff --git a/README.org b/README.org
@@ -1,334 +1,15 @@
-#+TITLE: This is the 'encadre' framework !
-
-This is the encadre framework engine.
-
-* Introduction
-
-It is a simple web framework, without hard dependencies to base web framework.
-Right now, the only implementation of the underlying framework available is 'flask'.
-
-* Things you can do with it
-
-** Install it !
-
-#+begin_example shell
-python setup.py develop
-#+end_example
-
-** Create an App
-
-Your app *MUST* be packaged ! (also your controllers).
-
-*** setup.py
-
-#+begin_example python
-from setuptools import setup
-
-console_scripts = """
-encadre-test-app-serve = encadre_test_app:serve
-encadre-test-app-dump-routes = encadre_test_app:dump_routes
-
-"""
-
-setup(name='encadre_test_app',
- version='0.1.0',
- description="Encadre_Test_App framework",
- author="Ubity Awesome Dev Team",
- author_email='dev@ubity.com',
- packages=['encadre_test_app'],
- install_requires=["Encadre"],
- entry_points={'console_scripts': console_scripts,
- 'encadre_test_app.controllers': [
- 'hello = encadre_test_app_hello']},
- license='GPLv3')
-#+end_example python
-
-*** main (encadre_test_app/__init__.py)
-
-#+begin_example python
-import sys
-from encadre import Encadre
-
-class Encadre_Test_App(Encadre):
- pass
-
-def serve():
- if len(sys.argv) != 2:
- print("Usage: %s config.ini")
- sys.exit(1)
- Encadre_Test_App(sys.argv[1]).serve()
-
-# tool to dump routes
-def dump_routes():
- if len(sys.argv) != 2:
- print("Usage: %s config.ini")
- sys.exit(1)
- Encadre_Test_App(sys.argv[1]).dump_routes()
-#+end_example
-
-*** config.ini
-
-Should contains at least a section telling that we are using /flask/ (as this is the only sub framework implemented.
-The section name is you app name (ie: *encadre_test_app*).
-
-#+begin_example
-[encadre_test_app]
-framework = flask
-#+end_example
-
-Optionnaly a *[flask]* section to give to 'flask'.
-
-#+begin_example
-[flask]
-PORT = 5001
-DEBUG = true
-HOST = 0.0.0.0
-#+end_example
-
-Optionnaly the *loggers* section.
-#+begin_example
-[loggers]
-keys = root, encadre, encadre_flask
-
-[logger_root]
-handlers =
-
-[logger_encadre]
-level = DEBUG
-handlers = console
-qualname = encadre
-
-[logger_encadre_flask]
-level = DEBUG
-handlers = console
-qualname = encadre_flask
-
-[handlers]
-keys = console
-
-[formatters]
-keys = generic
-
-[formatter_generic]
-
-[handler_console]
-class = StreamHandler
-args = (sys.stderr,)
-#+end_example
-
-*** a controller (encadre_test_app_hello/__init__.py)
-
-#+begin_example python
-from encadre import Controller
-
-
-class Hello(Controller):
- """ A very polite controller """
-
- def index__(self):
- """ Says hello ! """
- return "Hello world 0"
-
-
-class Hello_2(Controller):
- """ A very polite controller (version 2) """
-
- def index__(self):
- """ Says hello ! """
- return "Hello world"
-
- def to(self, who):
- """ Says hello to whom ask for """
- return "Hello %s !" % who
-
- def foo(self):
- return "Foo"
-
- def foo_(self):
- return "Foo with an '_' at the end !"
-
- def bar_GET(self):
- return "Bar"
-
- def baz_POST(self):
- return "Baz"
-
- def qux_GET_POST(self):
- return "Qux"
-#+end_example
-
-** Run you app
-
-#+begin_example
-python setup.py develop
-encadre_test_app-serve config.ini
-#+end_example
-
-** Query it
-
-*** Simple query
-
-#+begin_example
-curl http://localhost:5001/hello/
-#+end_example
-
-*** Specific version of a controller
-
-**** Using headers
-#+begin_example
-curl http://localhost:5001/hello/ -H X-encadre_test_app-version:0
-#+end_example
-
-**** Using URL prefix
-
-You can set:
-
-#+begin_example
-versioning = prefix
-#+end_example
-
-In you're application section in the configuration file.
-Doing so will prepend the version as prefix to each routes.
-
-**** First version
-
-By default, without specifying any version number, the first version of a controller is *0*.
-To set a different version number, use the *first_version* keyword in your application's section configuration file.
-
-#+begin_example
-first_version = 1
-#+end_example
-
-*** Parameters
-
-Routes are constructed using the controllers, method names and method args.
-
-In the following example,
-
-#+begin_example
-class Foo(Controller):
-
- def bar(self, baz):
- pass
-#+end_example
-
-The matching route will be: */foo/bar/<baz>*
-
-For example querying */foo/bar/123* would call the *bar()* method with the value *123* for the *baz* parameter.
-
-*** Args
-
-Args are the url-encoded key=value style args after the ? in the URL.
-They are available in requests.args.
-
-#+begin_example
-class Foo(Controller):
-
- def bar(self):
- from encadre import request
- request.args.get('qwe')
-#+end_example
-
-
-*** Headers
-
-#+begin_example
-class Foo(Controller):
-
- def bar(self):
- from encadre import request
- request.headers.get('X-Magic-Header')
-#+end_example
-
-*** Cookies
-
-#+begin_example
-class Foo(Controller):
-
- def bar_needs_cookie(self):
- from encadre import request
- request.cookies.get('my_great_cookie')
-
- def baz_set_cookie(self):
- from encadre import request
- request.cookies.set('my_great_cookie', 'my_great_value')
-#+end_example
-
-
-*** JSON
-
-#+begin_example
-class Foo(Controller):
-
- def bar(self):
- from encadre import request
- request.json # containt an object,
- # mostlikely a dict of the received JSON
-#+end_example
-
-** Dump routes
-
-#+begin_example
-python setup.py develop # if not done already
-encadre_test_app-dump-routes
-#+end_example
-
-** Run with UWSGI
-
-You can use UWSGI to run your app.
-For that, you will need some UWSGI configuration and loader.
-
-*** configuration
-
-Can be added in /config.ini/
-
-#+begin_example
-[uwsgi]
-http = localhost:5001
-file = encadre_test_app.wsgi
-#+end_example
-
-*** loader encadre_test_app.wsgi
-#+begin_example python
-from encadre_test_app import Encadre_Test_App
-application = Encadre_Test_App("config.ini").get_wsgi_app()
-#+end_example
-
-*** start it
-
-#+begin_example
-uwsgi config.ini
-#+end_example
-
-
-* Running 'encadre' tests
-
-#+begin_example shell
-pip install nose coverage
-make tests
-#+end_example
-
-* Nice features (not yet documented)
-
-- Custom error handling
-- *before* and *after* hooks
-- Automatic detection of missing tests
-- Validation of input JSON using decorator
-
-* Things to do as soon as possible
-
-- [X] Send a file
-- [X] Handle query args
-- [X] Return HTTP code on error
-- [X] Get cookie
-- [X] Set cookie
-- [X] Add controllers test and runtime
-- [X] walk sub __subclasses
-- [X] Honor version in the flask routes
-- [X] Raise a +meaningfull+ 405 if method is missing (route existing from another version)
-- [X] Honor the verb
-- [X] Make uwsgi friendly (returning an app)
-- [X] Add a uwsgi example
-- [X] Add __before__ __after__
-- [X] Add json
-- [X] Get and Set cookies
+#+TITLE: encadre
+
+A small Python web framework: controllers are classes, their methods are the
+HTTP routes (=Books.show(self, book_id)= answers on =/books/show/<book_id>=),
+the HTTP verb is a suffix of the method name (=save_POST=), and a new API
+version is a subclass (=Books_1(Books)=), chosen by the client with an
+=X-<application>-Version= header. Controllers are discovered through entry
+points; their tests are their =test_*= methods. The web engine is a plugin;
+Flask is the one implemented.
+
+- Documentation: https://schurger.org/pages/encadre-en.html (English),
+ https://schurger.org/pages/encadre.html (French)
+- Code: https://git.schurger.org/encadre/ (=git clone https://git.schurger.org/encadre.git=)
+- Package: https://pypi.org/project/encadre/ (=pip install encadre=)
+- License: GPLv3, Python >= 3.13