lowinger42 / basium Goto Github PK
View Code? Open in Web Editor NEWA small web framework for python with wsgi, templates and db persistence
Home Page: https://github.com/lowinger42/basium/wiki
A small web framework for python with wsgi, templates and db persistence
Home Page: https://github.com/lowinger42/basium/wiki
optparse is deprecated
Increase security by not sending password in cleartext
When a basium driver is loaded and the drivers SQL driver cannot be loaded,
the error is misleading and indicates that the basium_driver_X is not found.
Move most of the code to the basium.py file, driver will just handle low-level operations
Sqlite cannot change/rename/delete columns, so a new database needs to be created and the data copied
To better aid debugging/troubleshooting, return a specific error from the driver if the username/password does not work against the wsgi server.
Each database driver resets the counters
When API changes, handle compability with older versions
Client must inform server of what API version it wants to use, for example with an extension header.
Kind of cool if it works.
Simplify returning JSON formatted data
@JSON
def handlepost():
# do processing, create a dictionary
d = { "error": 0, "data": 23 }
# dictionary will be json encoded and returned using the basium_orm JSON encoder
return d
Better security, explicit declare what functions can be called
file api.py
@url
def _table():
.....
@default_url
def default():
.....
Partially, and incorrect implemented
Some functions, such as LIMIT is different between the databases, so the
database driver needs to be called
Only index today being supported is on the auto-generated ID field. This can affect query performance badly.
Today all classes that basium manages is initialized by basium_orm.start()
Remove the need for this, check when class is used if it is initialized and if not, do it.
Makes the ORM more transparent and easier to use
Today the HTML output is generated by python code.
This is complicated to use, and changes to pages are work intensive to do
By using a template system, logic and HTML code can be separated and
updated independently.
Write as a plugin, so different template system can be used.
Target is Python 3.2+
Currently no verification that the database and the table exist on the server before any API calls are done.
Easy to get started
Insert an underline in front of the functions
_get
_set
_getValues
_getStrValues
_isPrimaryKey
(are all of them used?)
Current router is very limited, and can't even handle a default index.html
The new router must handle .py extensions transparent, and default pages
Byh using different URLs, different functions should be called in the same module
if no matching function exist, default() is called. User can then create static methods, and
the rest is handled by one function, for example to process REST table CRUD
Implement as a pluggable module, so developer can implement custom URL routers
Examples:
/
calls index() in default.py
/main (main.py exist)
calls index() in main.py
/main (main.py DOES NOT exist)
calls main() in default.py
/module1/show (module1.py exist)
calls show() in module1.py
/module1/show (module1.py DOES NOT exist)
error 404, not found
/dir1/module/y
calls y() in /dir1/module.py
If len(url) == 0
/index.py index()
if len(url) == 1
/index.py function url[0]
if len(url) == 2:
if isdir(url[0]):
/url[0]/index.py function url[1]
else:
/url[0].py function url[1]
if len(url) >2:
The query.order() can be be combined with filter, and multiple order() are ok
Usage:
user = User()
query = db.query()
query.filter(user.q.age, ">=", 17)
query.order(user.q.age)
result = db.load(query)
query = db.query()
query.filter(user.q.age, "<", 18)
query.order(user.q.name)
query.order(user.q.age, desc=True)
result = db.load(query)
The status pages "404 Page not found" is very basic,
add support for customized pages.
Point to a directory, in which there are files matching
the status code.
status 404 -> 404.html or 404.py, then just return the content.
Errors in core ends up with a stack trace from the compiled view, which makes it hard to find the error in the source being compiled.
This only needs to be active during development/debug flag, for performance reasons
Possible solutions:
Testissue3
REST/HTTP compliant
Today the unit tests are hacked together, change those over to the standard unittest functionality
Currently there is no Authentication when using the REST API, which makes the feature harder than necessary to use on public computers - need to configure firewalls etc.
More on WSGI auth
http://code.google.com/p/modwsgi/wiki/AccessControlMechanisms
Very often tables has relations between them, a common one is N:M
This can be simulated with python code, but it is much simpler and faster to let
the underlying driver do all work.
To handle the N:M, a separate (hidden) table with the _id from each table must be used.
With current logger the following ends up in log
[Sun Jul 14 06:37:38 2013] [error] 2013-07-14 06:37:38,772 DEBUG Insert one row in table 'protocolparam'
date, time, level is duplicated
Keep documentation in once place, together with the source code
There is no way to automatically detect if a column has been renamed,
this must be manually handled.
Create a table _system and store actual version of each table, and changes (as log lines)
when a modification that cannot be handled automatically should be done, a script is written that handles this.
Script should work on a high level, all low-level database specific items is handled by the driver. If not a script for each driver is needed.
The table used is default the class name, lower cased. There may be situations
where this is less than desired, if for example some characters are not supported by
the driver/underlying backing store.
class BasiumTest(basium_model.Model).
_tableName = 'basium_test'
name = basium_model.VarcharCol()
The encode/decode is purely json specific
Add to basium_wsgihandler
Add to basium_driver_json
Today, if an dynamic loaded module/page is loaded by the wsgi handler, the imported modules are not reloaded if the change. The user needs to restart the wsgi server to force a reload.
A simple approach is to use a Rollback importer, as described here
http://pyunit.sourceforge.net/notes/reloading.html
This should be combined with a debug/release flag, no reloading is needed when running release code.
Today a typical request looks like this:
response=db.load(query)
if response.isError():
print("Could not store object", response.getError())
...error handling...
return
Change this to
try:
data = db.load(query)
except BasiumError e:
print("Could not store object", e)
return
Basium is a library, it should always return errors instead of sys.exit()
It is up to the library user to decide what to do depending on the error.
Used during development. If true and included modules gives an error, show stacktrace
During production, the stack trace can possibly return "secret" information so the debug flag should be set to False
Add a code generator that produces C++ code that can persist C++ objects.
In multiline {% %} blocks, else will always incorrectly indent.
Move most of the code to the basium.py file, driver will just handle low-level operations
Very often tables has relations between them, the most common one is 1:N
This can be simulated with python code, but it is much simpler and faster to let
the underlying driver do all work.
A new list object is defined.
class Groups(basium_model.Model):
name = basium_model.VarcharCol()
flags = basium_model.IntCol()
class Users(basium_model.Model):
name = basium_model.VarcharCol()
password = basium_model.VarcharCol()
groups = basium_model.List(Groups)
Whe loading a object from database, the corresponding List is filled with related objects
result = basium.load(Users(3))
this loads the Users object with _id 3, and all related objects
result.data
name "anders"
password "secret"
groups = [ groups object, groups object ]
todo: where is the relation created/stored? Possibly when a Class is referenced in .List() ?
Makes it simpler to use, when different functions can be called as described in issue #8
Pros:
A model instance is not tied to a specific sql driver, so working with for example a local db and a remote over json gets easier
Example:
customer = remotedb.load(Customer(22))
localdb.store(customer[0])
This is also the reason the model object should not have .load/.store methods, it would lock the instance to a specific database driver.
The mapper can be used in custom code, for example in the wsgi api.py
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.